xtablo-source/apps/main/src/components/CreateTabloModal.tsx
2025-10-23 11:54:45 +02:00

109 lines
4 KiB
TypeScript

import { Database } from "@xtablo/shared/types/database.types";
import { useState } from "react";
import { ClickOutside } from "./ClickOutside";
import { ImageColorPicker } from "./ImageColorPicker";
import { StatusPicker } from "./StatusPicker";
type Tablo = Database["public"]["Tables"]["tablos"]["Row"];
type StatusType = "todo" | "in_progress" | "done";
interface CreateTabloModalProps {
onClose: () => void;
onCreate: (tabloData: Pick<Tablo, "name" | "color" | "image" | "status">) => void;
}
export const CreateTabloModal = ({ onClose, onCreate }: CreateTabloModalProps) => {
const [newTabloName, setNewTabloName] = useState("");
const [creationMode, setCreationMode] = useState<"image" | "color">("color");
const [selectedImage, setSelectedImage] = useState(
"https://images.unsplash.com/photo-1553877522-43269d4ea984?w=400&h=250&fit=crop&crop=center"
);
const [selectedColor, setSelectedColor] = useState("bg-blue-500");
const [selectedStatus, setSelectedStatus] = useState<StatusType>("todo");
const resetForm = () => {
setNewTabloName("");
setCreationMode("color");
setSelectedImage(
"https://images.unsplash.com/photo-1553877522-43269d4ea984?w=400&h=250&fit=crop&crop=center"
);
setSelectedColor("bg-blue-500");
setSelectedStatus("todo");
};
const handleClose = () => {
resetForm();
onClose();
};
const handleCreate = () => {
if (newTabloName.trim()) {
const tabloData = {
name: newTabloName.trim(),
status: selectedStatus,
...(creationMode === "image"
? { image: selectedImage, color: null }
: { image: null, color: selectedColor }),
};
onCreate(tabloData);
resetForm();
}
};
return (
<div className="fixed inset-0 bg-black/80 flex items-center justify-center z-50">
<ClickOutside onClickOutside={handleClose}>
<div className="bg-white dark:bg-gray-800 rounded-lg shadow-xl p-6 w-full max-w-4xl min-w-96 mx-4">
<h2 className="text-xl font-bold text-gray-900 dark:text-white mb-4">
Créer un nouveau tablo
</h2>
<div className="space-y-4">
{/* Name Input */}
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Nom du tablo
</label>
<input
type="text"
value={newTabloName}
onChange={(e) => setNewTabloName(e.target.value)}
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:text-white"
placeholder="Entrez le nom du tablo"
autoFocus
/>
</div>
<StatusPicker selectedStatus={selectedStatus} setSelectedStatus={setSelectedStatus} />
<ImageColorPicker
creationMode={creationMode}
setCreationMode={setCreationMode}
selectedColor={selectedColor}
setSelectedColor={setSelectedColor}
/>
</div>
{/* Modal Actions */}
<div className="flex justify-end space-x-3 mt-6">
<button
type="button"
className="px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 bg-gray-100 dark:bg-gray-700 hover:bg-gray-200 dark:hover:bg-gray-600 rounded-md"
onClick={handleClose}
>
Annuler
</button>
<button
type="button"
className="px-4 py-2 text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 rounded-md disabled:opacity-50 disabled:cursor-not-allowed"
onClick={handleCreate}
disabled={!newTabloName.trim() || creationMode === "image"}
>
Créer
</button>
</div>
</div>
</ClickOutside>
</div>
);
};