diff options
Diffstat (limited to 'components/file-manager/CreateSubfolderForm.tsx')
| -rw-r--r-- | components/file-manager/CreateSubfolderForm.tsx | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/components/file-manager/CreateSubfolderForm.tsx b/components/file-manager/CreateSubfolderForm.tsx new file mode 100644 index 00000000..0afdf755 --- /dev/null +++ b/components/file-manager/CreateSubfolderForm.tsx @@ -0,0 +1,127 @@ +// CreateSubfolderForm component - English version + +import { useState } from "react"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { Loader2 } from "lucide-react"; + +interface CreateSubfolderFormProps { + parentFolder: any; + onSubmit: (name: string, category: string) => Promise<void>; + onCancel: () => void; +} + +export function CreateSubfolderForm({ + parentFolder, + onSubmit, + onCancel +}: CreateSubfolderFormProps) { + const [folderName, setFolderName] = useState(""); + const [category, setCategory] = useState(parentFolder?.category || "general"); + const [isCreating, setIsCreating] = useState(false); + const [error, setError] = useState(""); + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + + if (!folderName.trim()) { + setError("Please enter a folder name"); + return; + } + + // Special character validation + const invalidChars = /[<>:"|?*\/\\]/; + if (invalidChars.test(folderName)) { + setError("Folder name contains invalid characters"); + return; + } + + setIsCreating(true); + setError(""); + + try { + await onSubmit(folderName, category); + setFolderName(""); + setCategory(parentFolder?.category || "general"); + } catch (error: any) { + setError(error.message || "Failed to create folder"); + } finally { + setIsCreating(false); + } + }; + + return ( + <form onSubmit={handleSubmit} className="space-y-4 py-4"> + <div className="space-y-2"> + <Label htmlFor="folder-name">Folder Name</Label> + <Input + id="folder-name" + value={folderName} + onChange={(e) => { + setFolderName(e.target.value); + setError(""); + }} + placeholder="Enter folder name" + disabled={isCreating} + autoFocus + /> + {error && ( + <p className="text-sm text-destructive">{error}</p> + )} + </div> + + <div className="space-y-2"> + <Label htmlFor="folder-category">Security Category</Label> + <Select + value={category} + onValueChange={setCategory} + disabled={isCreating} + > + <SelectTrigger id="folder-category"> + <SelectValue placeholder="Select category" /> + </SelectTrigger> + <SelectContent> + <SelectItem value="general">General</SelectItem> + <SelectItem value="confidential">Confidential</SelectItem> + <SelectItem value="internal">Internal</SelectItem> + </SelectContent> + </Select> + <p className="text-xs text-muted-foreground"> + Sub-folders inherit the security category from their parent folder by default + </p> + </div> + + <div className="flex justify-end gap-2"> + <Button + type="button" + variant="outline" + onClick={onCancel} + disabled={isCreating} + > + Cancel + </Button> + <Button + type="submit" + disabled={isCreating || !folderName.trim()} + > + {isCreating ? ( + <> + <Loader2 className="mr-2 h-4 w-4 animate-spin" /> + Creating... + </> + ) : ( + "Create Folder" + )} + </Button> + </div> + </form> + ); +}
\ No newline at end of file |
