Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | import { useState, useEffect } from "react";
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
DialogFooter,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { Label } from "@/components/ui/label";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { categories, type Resolution, type Category, type InsertResolution } from "@shared/schema";
import { Loader2 } from "lucide-react";
interface AddResolutionDialogProps {
open: boolean;
onOpenChange: (open: boolean) => void;
onSubmit: (data: InsertResolution) => void;
editingResolution?: Resolution | null;
isSubmitting?: boolean;
}
export function AddResolutionDialog({
open,
onOpenChange,
onSubmit,
editingResolution,
isSubmitting = false,
}: AddResolutionDialogProps) {
const [title, setTitle] = useState("");
const [description, setDescription] = useState("");
const [category, setCategory] = useState<Category>("Personal Growth");
const [targetDate, setTargetDate] = useState("");
useEffect(() => {
if (editingResolution) {
setTitle(editingResolution.title);
setDescription(editingResolution.description || "");
setCategory(editingResolution.category as Category);
setTargetDate(editingResolution.targetDate || "");
} else {
setTitle("");
setDescription("");
setCategory("Personal Growth");
setTargetDate("");
}
}, [editingResolution, open]);
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
if (!title.trim()) return;
onSubmit({
title: title.trim(),
description: description.trim() || undefined,
category,
targetDate: targetDate || undefined,
});
};
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="sm:max-w-lg">
<DialogHeader>
<DialogTitle className="text-xl">
{editingResolution ? "Edit Resolution" : "Add New Resolution"}
</DialogTitle>
</DialogHeader>
<form onSubmit={handleSubmit} className="space-y-4">
<div className="space-y-2">
<Label htmlFor="title">Title</Label>
<Input
id="title"
placeholder="e.g., Run a marathon"
value={title}
onChange={(e) => setTitle(e.target.value)}
data-testid="input-resolution-title"
/>
</div>
<div className="space-y-2">
<Label htmlFor="description">Description</Label>
<Textarea
id="description"
placeholder="What does success look like for this resolution?"
value={description}
onChange={(e) => setDescription(e.target.value)}
rows={3}
data-testid="input-resolution-description"
/>
</div>
<div className="grid grid-cols-2 gap-4">
<div className="space-y-2">
<Label htmlFor="category">Category</Label>
<Select value={category} onValueChange={(v) => setCategory(v as Category)}>
<SelectTrigger data-testid="select-category">
<SelectValue placeholder="Select category" />
</SelectTrigger>
<SelectContent>
{categories.map((cat) => (
<SelectItem key={cat} value={cat} data-testid={`select-item-${cat.toLowerCase().replace(/\s+/g, '-')}`}>
{cat}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<div className="space-y-2">
<Label htmlFor="targetDate">Target Date</Label>
<Input
id="targetDate"
type="date"
value={targetDate}
onChange={(e) => setTargetDate(e.target.value)}
data-testid="input-target-date"
/>
</div>
</div>
<DialogFooter>
<Button
type="button"
variant="outline"
onClick={() => onOpenChange(false)}
data-testid="button-cancel"
>
Cancel
</Button>
<Button
type="submit"
disabled={!title.trim() || isSubmitting}
data-testid="button-submit-resolution"
>
{isSubmitting && <Loader2 className="h-4 w-4 mr-2 animate-spin" />}
{editingResolution ? "Save Changes" : "Add Resolution"}
</Button>
</DialogFooter>
</form>
</DialogContent>
</Dialog>
);
}
|