task-p.6 migrate

This commit is contained in:
phaichayon
2026-06-30 11:50:50 +07:00
parent b0081c7031
commit 9ab254ef0d
27 changed files with 3170 additions and 32 deletions

View File

@@ -15,6 +15,14 @@ import {
DialogTitle
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import {
Sheet,
SheetContent,
SheetDescription,
SheetFooter,
SheetHeader,
SheetTitle
} from '@/components/ui/sheet';
import { Switch } from '@/components/ui/switch';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { Textarea } from '@/components/ui/textarea';
@@ -290,7 +298,7 @@ function TemplateDialog({
);
}
function VersionDialog({
function VersionSheet({
open,
onOpenChange,
templateId,
@@ -340,45 +348,67 @@ function VersionDialog({
const isPending = createMutation.isPending || updateMutation.isPending;
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className='sm:max-w-3xl'>
<DialogHeader>
<DialogTitle>{version ? 'Edit Version' : 'Create Version'}</DialogTitle>
<DialogDescription>Schema JSON is accepted as raw JSON in this admin release.</DialogDescription>
</DialogHeader>
<form onSubmit={onSubmit} className='grid gap-4'>
<Sheet open={open} onOpenChange={onOpenChange}>
<SheetContent side='right' className='w-full sm:max-w-3xl'>
<SheetHeader>
<SheetTitle>{version ? 'Edit Version' : 'Create Version'}</SheetTitle>
<SheetDescription>
Schema JSON is accepted as raw JSON in this admin release.
</SheetDescription>
</SheetHeader>
<form onSubmit={onSubmit} className='flex h-full flex-col gap-4 overflow-y-auto pb-6'>
<div className='grid gap-4 md:grid-cols-2'>
<Field label='Version'>
<Input value={state.version} onChange={(e) => setState((current) => ({ ...current, version: e.target.value }))} />
<Input
value={state.version}
onChange={(e) => setState((current) => ({ ...current, version: e.target.value }))}
/>
</Field>
<Field label='File Path'>
<Input value={state.filePath} onChange={(e) => setState((current) => ({ ...current, filePath: e.target.value }))} />
<Input
value={state.filePath}
onChange={(e) => setState((current) => ({ ...current, filePath: e.target.value }))}
/>
</Field>
</div>
<Field label='Preview Image URL'>
<Input value={state.previewImageUrl} onChange={(e) => setState((current) => ({ ...current, previewImageUrl: e.target.value }))} />
<Input
value={state.previewImageUrl}
onChange={(e) =>
setState((current) => ({ ...current, previewImageUrl: e.target.value }))
}
/>
</Field>
<Field label='Schema JSON'>
<Textarea className='min-h-64 font-mono text-xs' value={state.schemaJson} onChange={(e) => setState((current) => ({ ...current, schemaJson: e.target.value }))} />
<Textarea
className='min-h-64 font-mono text-xs'
value={state.schemaJson}
onChange={(e) => setState((current) => ({ ...current, schemaJson: e.target.value }))}
/>
</Field>
<div className='flex items-center justify-between rounded-lg border px-4 py-3'>
<div>
<div className='font-medium'>Active Version</div>
<div className='text-muted-foreground text-sm'>Inactive versions remain stored for traceability.</div>
<div className='text-muted-foreground text-sm'>
Inactive versions remain stored for traceability.
</div>
</div>
<Switch checked={state.isActive} onCheckedChange={(checked) => setState((current) => ({ ...current, isActive: checked }))} />
<Switch
checked={state.isActive}
onCheckedChange={(checked) => setState((current) => ({ ...current, isActive: checked }))}
/>
</div>
<DialogFooter>
<SheetFooter className='mt-auto sm:flex-row sm:justify-end'>
<Button type='button' variant='outline' onClick={() => onOpenChange(false)}>
Cancel
</Button>
<Button type='submit' isLoading={isPending}>
{version ? 'Save Version' : 'Create Version'}
</Button>
</DialogFooter>
</SheetFooter>
</form>
</DialogContent>
</Dialog>
</SheetContent>
</Sheet>
);
}
@@ -715,7 +745,7 @@ function TemplateDetailCard({ templateId }: { templateId: string }) {
))}
</Tabs>
<VersionDialog
<VersionSheet
open={versionDialogState.open}
onOpenChange={(open) =>
setVersionDialogState((current) => ({ ...current, open }))