| import { useState, useEffect } from "react"; | |
| import { Folder } from "@/hooks/useChatFolders"; | |
| interface FolderEditModalProps { | |
| initialFolder: Partial<Folder>; | |
| onSave: (folder: Partial<Folder>) => void; | |
| onClose: () => void; | |
| } | |
| export function FolderEditModal({ initialFolder, onSave, onClose }: FolderEditModalProps) { | |
| const [name, setName] = useState(initialFolder.name || ""); | |
| const [icon, setIcon] = useState(initialFolder.icon || "๐"); | |
| const [type, setType] = useState<"all" | "unread" | "groups" | "personal">("all"); | |
| useEffect(() => { | |
| if (initialFolder.filter?.unreadOnly) setType("unread"); | |
| else if (initialFolder.filter?.types?.includes("group")) setType("groups"); | |
| else if (initialFolder.filter?.types?.includes("private")) setType("personal"); | |
| else setType("all"); | |
| }, [initialFolder]); | |
| const handleSave = () => { | |
| if (!name.trim()) return; | |
| const filter: Folder["filter"] = {}; | |
| if (type === "unread") filter.unreadOnly = true; | |
| if (type === "groups") filter.types = ["group"]; | |
| if (type === "personal") filter.types = ["private"]; | |
| onSave({ ...initialFolder, name: name.trim(), icon, filter }); | |
| }; | |
| const handleKeyDown = (e: React.KeyboardEvent) => { | |
| if (e.key === "Enter") handleSave(); | |
| if (e.key === "Escape") onClose(); | |
| }; | |
| return ( | |
| <div | |
| className="fixed inset-0 bg-black/50 flex items-center justify-center z-50" | |
| onClick={onClose} | |
| onKeyDown={handleKeyDown} | |
| > | |
| <div | |
| className="bg-white dark:bg-gray-800 rounded-2xl p-6 w-80 shadow-xl" | |
| onClick={(e) => e.stopPropagation()} | |
| tabIndex={-1} | |
| > | |
| <h3 className="text-lg font-bold mb-4 text-gray-800 dark:text-gray-100"> | |
| {initialFolder.id ? "Edit Folder" : "New Folder"} | |
| </h3> | |
| <input | |
| type="text" | |
| placeholder="Folder name" | |
| value={name} | |
| onChange={(e) => setName(e.target.value)} | |
| className="w-full px-3 py-2 border rounded-lg mb-3 dark:bg-gray-700 dark:text-gray-100" | |
| autoFocus | |
| /> | |
| <div className="flex gap-2 mb-3"> | |
| {["๐", "๐ฌ", "๐ฅ", "๐ต", "โญ"].map((i) => ( | |
| <button | |
| key={i} | |
| type="button" | |
| onClick={() => setIcon(i)} | |
| className={`text-xl p-1 rounded transition ${ | |
| icon === i ? "bg-primary/20 ring-2 ring-primary" : "hover:bg-gray-100 dark:hover:bg-gray-700" | |
| }`} | |
| > | |
| {i} | |
| </button> | |
| ))} | |
| </div> | |
| <select | |
| value={type} | |
| onChange={(e) => setType(e.target.value as any)} | |
| className="w-full px-3 py-2 border rounded-lg mb-4 dark:bg-gray-700 dark:text-gray-100" | |
| > | |
| <option value="all">All chats</option> | |
| <option value="unread">Unread</option> | |
| <option value="groups">Groups</option> | |
| <option value="personal">Personal</option> | |
| </select> | |
| <div className="flex gap-2 justify-end"> | |
| <button onClick={onClose} className="btn btn-secondary btn-sm rounded-full">Cancel</button> | |
| <button | |
| onClick={handleSave} | |
| disabled={!name.trim()} | |
| className="btn btn-primary btn-sm rounded-full disabled:opacity-50" | |
| > | |
| {initialFolder.id ? "Save" : "Create"} | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| ); | |
| } |
Xet Storage Details
- Size:
- 3.43 kB
- Xet hash:
- 7a85cd1bff62308191d0254fd7c827fcc199db1b2fe21862bce28a6a0381fb99
ยท
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.