src/components/change-category-dialog.tsx 4.1 K raw
1
import * as React from "react";
2
import {
3
	Dialog,
4
	DialogContent,
5
	DialogDescription,
6
	DialogFooter,
7
	DialogHeader,
8
	DialogTitle,
9
} from "@/components/ui/dialog";
10
import { Button } from "@/components/ui/button";
11
import { Input } from "@/components/ui/input";
12
import { Label } from "@/components/ui/label";
13
import {
14
	Select,
15
	SelectContent,
16
	SelectItem,
17
	SelectTrigger,
18
	SelectValue,
19
} from "@/components/ui/select";
20
21
interface ChangeCategoryDialogProps {
22
	open: boolean;
23
	onOpenChange: (open: boolean) => void;
24
	currentCategory: string | null;
25
	existingCategories: string[];
26
	onChangeCategory: (newCategory: string | null) => void;
27
}
28
29
export function ChangeCategoryDialog({
30
	open,
31
	onOpenChange,
32
	currentCategory,
33
	existingCategories,
34
	onChangeCategory,
35
}: ChangeCategoryDialogProps) {
36
	const [mode, setMode] = React.useState<"existing" | "new">("existing");
37
	const [selectedCategory, setSelectedCategory] = React.useState<string>(
38
		currentCategory || "",
39
	);
40
	const [newCategory, setNewCategory] = React.useState("");
41
42
	React.useEffect(() => {
43
		if (open) {
44
			setMode("existing");
45
			setSelectedCategory(currentCategory || "");
46
			setNewCategory("");
47
		}
48
	}, [open, currentCategory]);
49
50
	const handleSubmit = (e: React.FormEvent) => {
51
		e.preventDefault();
52
53
		if (mode === "new") {
54
			if (newCategory.trim()) {
55
				onChangeCategory(newCategory.trim());
56
				onOpenChange(false);
57
			}
58
		} else {
59
			if (selectedCategory === "uncategorized") {
60
				onChangeCategory(null);
61
			} else if (selectedCategory) {
62
				onChangeCategory(selectedCategory);
63
			}
64
			onOpenChange(false);
65
		}
66
	};
67
68
	// Filter out current category and "Uncategorized" from the list
69
	const availableCategories = existingCategories.filter(
70
		(cat) => cat !== "Uncategorized",
71
	);
72
73
	return (
74
		<Dialog open={open} onOpenChange={onOpenChange}>
75
			<DialogContent className="sm:max-w-[425px]">
76
				<DialogHeader>
77
					<DialogTitle>Change Category</DialogTitle>
78
					<DialogDescription>
79
						Move this feed to a different category or create a new one.
80
					</DialogDescription>
81
				</DialogHeader>
82
				<form onSubmit={handleSubmit}>
83
					<div className="grid gap-4 py-4">
84
						<div className="grid gap-2">
85
							<Label>Choose an option</Label>
86
							<div className="flex gap-2">
87
								<Button
88
									type="button"
89
									variant={mode === "existing" ? "default" : "outline"}
90
									onClick={() => setMode("existing")}
91
									className="flex-1"
92
								>
93
									Existing Category
94
								</Button>
95
								<Button
96
									type="button"
97
									variant={mode === "new" ? "default" : "outline"}
98
									onClick={() => setMode("new")}
99
									className="flex-1"
100
								>
101
									New Category
102
								</Button>
103
							</div>
104
						</div>
105
106
						{mode === "existing" ? (
107
							<div className="grid gap-2">
108
								<Label htmlFor="category-select">Select Category</Label>
109
								<Select
110
									value={selectedCategory}
111
									onValueChange={setSelectedCategory}
112
								>
113
									<SelectTrigger id="category-select">
114
										<SelectValue placeholder="Select a category" />
115
									</SelectTrigger>
116
									<SelectContent>
117
										<SelectItem value="uncategorized">Uncategorized</SelectItem>
118
										{availableCategories.map((cat) => (
119
											<SelectItem key={cat} value={cat}>
120
												{cat}
121
											</SelectItem>
122
										))}
123
									</SelectContent>
124
								</Select>
125
							</div>
126
						) : (
127
							<div className="grid gap-2">
128
								<Label htmlFor="new-category">New Category Name</Label>
129
								<Input
130
									id="new-category"
131
									value={newCategory}
132
									onChange={(e) => setNewCategory(e.target.value)}
133
									placeholder="Enter category name"
134
									maxLength={50}
135
									autoFocus
136
								/>
137
							</div>
138
						)}
139
					</div>
140
					<DialogFooter>
141
						<Button
142
							type="button"
143
							variant="outline"
144
							onClick={() => onOpenChange(false)}
145
						>
146
							Cancel
147
						</Button>
148
						<Button
149
							type="submit"
150
							disabled={
151
								mode === "new" ? !newCategory.trim() : !selectedCategory
152
							}
153
						>
154
							Change Category
155
						</Button>
156
					</DialogFooter>
157
				</form>
158
			</DialogContent>
159
		</Dialog>
160
	);
161
}