monacousa-portal/src/lib/components/documents/CreateFolderModal.svelte

143 lines
3.6 KiB
Svelte

<script lang="ts">
import { X, FolderPlus } from 'lucide-svelte';
import { Button } from '$lib/components/ui/button';
import { Input } from '$lib/components/ui/input';
import { Label } from '$lib/components/ui/label';
import { enhance } from '$app/forms';
import { invalidateAll } from '$app/navigation';
let {
parentFolderId = null,
onClose,
onSuccess
}: {
parentFolderId?: string | null;
onClose: () => void;
onSuccess?: () => void;
} = $props();
let isSubmitting = $state(false);
let folderName = $state('');
let visibility = $state('members');
function handleKeydown(e: KeyboardEvent) {
if (e.key === 'Escape') {
onClose();
}
}
</script>
<svelte:window onkeydown={handleKeydown} />
<!-- Modal Backdrop -->
<div
class="fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm p-4"
role="dialog"
aria-modal="true"
aria-labelledby="create-folder-title"
>
<!-- Modal Content -->
<div class="w-full max-w-md rounded-2xl bg-white shadow-xl">
<!-- Header -->
<div class="flex items-center justify-between border-b border-slate-200 px-6 py-4">
<div class="flex items-center gap-3">
<div class="flex h-10 w-10 items-center justify-center rounded-lg bg-amber-100 text-amber-600">
<FolderPlus class="h-5 w-5" />
</div>
<h2 id="create-folder-title" class="text-lg font-semibold text-slate-900">
Create New Folder
</h2>
</div>
<button
onclick={onClose}
class="rounded-lg p-2 text-slate-400 hover:bg-slate-100 hover:text-slate-600"
aria-label="Close"
>
<X class="h-5 w-5" />
</button>
</div>
<!-- Form -->
<form
method="POST"
action="?/createFolder"
use:enhance={() => {
isSubmitting = true;
return async ({ result, update }) => {
await invalidateAll();
isSubmitting = false;
if (result.type === 'success') {
onClose();
onSuccess?.();
}
await update();
};
}}
class="p-6 space-y-4"
>
{#if parentFolderId}
<input type="hidden" name="parent_id" value={parentFolderId} />
{/if}
<div class="space-y-2">
<Label for="folder-name">Folder Name</Label>
<Input
id="folder-name"
name="name"
type="text"
bind:value={folderName}
placeholder="Enter folder name..."
required
autofocus
disabled={isSubmitting}
class="h-11"
/>
</div>
<div class="space-y-2">
<Label for="folder-visibility">Visibility</Label>
<select
id="folder-visibility"
name="visibility"
bind:value={visibility}
disabled={isSubmitting}
class="w-full h-11 rounded-lg border border-slate-200 bg-white px-3 text-sm focus:border-monaco-500 focus:outline-none focus:ring-2 focus:ring-monaco-500/20"
>
<option value="members">Members Only</option>
<option value="board">Board Only</option>
<option value="admin">Admin Only</option>
<option value="public">Public</option>
</select>
<p class="text-xs text-slate-500">
Who can see this folder and its contents
</p>
</div>
<!-- Actions -->
<div class="flex justify-end gap-3 pt-4">
<Button
type="button"
variant="outline"
onclick={onClose}
disabled={isSubmitting}
>
Cancel
</Button>
<Button
type="submit"
variant="monaco"
disabled={isSubmitting || !folderName.trim()}
>
{#if isSubmitting}
<div class="mr-2 h-4 w-4 animate-spin rounded-full border-2 border-white border-t-transparent"></div>
Creating...
{:else}
<FolderPlus class="mr-2 h-4 w-4" />
Create Folder
{/if}
</Button>
</div>
</form>
</div>
</div>