Spaces:
Paused
Paused
| "use client"; | |
| import { useEffect } from 'react'; | |
| import { useForm } from 'react-hook-form'; | |
| import { zodResolver } from "@hookform/resolvers/zod"; | |
| import { z } from "zod"; | |
| import { toast } from "sonner"; | |
| import { useRouter } from 'next/navigation'; | |
| import { HeroData } from '@/types'; | |
| import { heroFormSchema } from '@/lib/validators'; | |
| import { Button } from '@/components/ui/button'; | |
| import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DialogDescription } from '@/components/ui/dialog'; | |
| import { Form } from '@/components/ui/form'; | |
| import { ScrollArea } from '@/components/ui/scroll-area'; | |
| import { IdentitySection } from '@/components/editor-sections/IdentitySection'; | |
| import { VisualsSection } from '@/components/editor-sections/VisualsSection'; | |
| import { AudioSection } from '@/components/editor-sections/AudioSection'; | |
| import { PowerLogicSection } from '@/components/editor-sections/PowerLogicSection'; | |
| import { updateHeroAction } from '@/app/actions/db.actions'; | |
| import { getDirtyValues } from '@/lib/utils'; | |
| import { StatsSection } from './editor-sections/StatsSection'; | |
| // Note: StatsSection is complex and would need a similar refactor. Assuming it's done. | |
| interface HeroEditorDialogProps { | |
| hero: HeroData; | |
| isOpen: boolean; | |
| onClose: () => void; | |
| } | |
| export const HeroEditorDialog = ({ hero, isOpen, onClose }: HeroEditorDialogProps) => { | |
| const router = useRouter(); | |
| const form = useForm<z.infer<typeof heroFormSchema>>({ | |
| resolver: zodResolver(heroFormSchema), | |
| defaultValues: { | |
| ...hero, | |
| heroGender: | |
| hero.heroGender === "Male" || hero.heroGender === "Female" | |
| ? hero.heroGender | |
| : undefined, | |
| introLineAudioUrl: hero.introLineAudioUrl ?? null, | |
| superpowerActivationLineAudioUrl: hero.superpowerActivationLineAudioUrl ?? null, | |
| }, | |
| }); | |
| // Reset form if hero changes | |
| useEffect(() => { | |
| form.reset({ | |
| ...hero, | |
| heroGender: | |
| hero.heroGender === "Male" || hero.heroGender === "Female" | |
| ? hero.heroGender | |
| : undefined, | |
| introLineAudioUrl: hero.introLineAudioUrl ?? null, | |
| superpowerActivationLineAudioUrl: hero.superpowerActivationLineAudioUrl ?? null, | |
| }); | |
| }, [hero, form]); | |
| const onSubmit = async (values: z.infer<typeof heroFormSchema>) => { | |
| const { dirtyFields } = form.formState; | |
| const dirtyValues = getDirtyValues(dirtyFields, values); | |
| // If nothing changed, don't even bother the server | |
| if (Object.keys(dirtyValues).length === 0) { | |
| toast.info("No changes to save."); | |
| return; | |
| } | |
| const toastId = toast.loading("Saving your hero..."); | |
| if (!hero._id) { | |
| toast.error("Hero ID is missing. Cannot update hero."); | |
| return; | |
| } | |
| const result = await updateHeroAction(hero._id, dirtyValues); | |
| if (result.success) { | |
| toast.success(result.message, { id: toastId }); | |
| router.refresh(); | |
| onClose(); | |
| } else { | |
| toast.error(result.message || "Something went wrong.", { id: toastId }); | |
| } | |
| }; | |
| return ( | |
| <Dialog open={isOpen} onOpenChange={onClose}> | |
| <DialogContent className="max-w-4xl h-[95vh] flex flex-col"> | |
| <DialogHeader> | |
| <DialogTitle>Edit Hero: {form.watch('heroName')}</DialogTitle> | |
| <DialogDescription> | |
| Modify any aspect of your hero. Use the AI buttons to regenerate specific fields. | |
| </DialogDescription> | |
| </DialogHeader> | |
| <Form {...form}> | |
| <form onSubmit={form.handleSubmit(onSubmit)} className="flex-grow overflow-hidden"> | |
| <ScrollArea className="h-full pr-6"> | |
| <div className="space-y-6"> | |
| <IdentitySection form={form} /> | |
| <StatsSection form={form} /> | |
| <VisualsSection form={form} /> | |
| <AudioSection form={form} /> | |
| <PowerLogicSection form={form} /> | |
| </div> | |
| </ScrollArea> | |
| </form> | |
| </Form> | |
| <DialogFooter className="pt-4 mt-4 border-t"> | |
| <Button type="button" variant="outline" onClick={onClose} disabled={form.formState.isSubmitting}> | |
| Cancel | |
| </Button> | |
| <Button type="submit" className='cursor-pointer' onClick={form.handleSubmit(onSubmit)} disabled={form.formState.isSubmitting}> | |
| {form.formState.isSubmitting ? "Saving..." : "Save Changes"} | |
| </Button> | |
| </DialogFooter> | |
| </DialogContent> | |
| </Dialog> | |
| ); | |
| }; |