tasko/components/form/form-popover.tsx

105 lines
2.9 KiB
TypeScript
Raw Permalink Normal View History

2024-02-16 01:49:19 +00:00
'use client';
2024-02-15 02:30:10 +00:00
2024-02-16 01:49:19 +00:00
import { X } from 'lucide-react';
import { toast } from 'sonner';
import { useRef } from 'react';
2024-02-16 01:49:19 +00:00
import { useRouter } from 'next/navigation';
2024-02-15 02:30:10 +00:00
import {
Popover,
PopoverClose,
PopoverContent,
PopoverTrigger,
2024-02-16 01:49:19 +00:00
} from '@/components/ui/popover';
import { useAction } from '@/hooks/use-action';
import { createBoard } from '@/actions/create-board';
import { Button } from '@/components//ui/button';
import { useProModal } from '@/hooks/use-pro-modal';
2024-02-15 02:30:10 +00:00
2024-02-16 01:49:19 +00:00
import { FormInput } from './form-input';
import { FormSubmit } from './form-submit';
import { FormPicker } from './form-picker';
import Link from 'next/link';
2024-02-15 02:30:10 +00:00
interface FormPopoverProps {
children: React.ReactNode;
2024-02-16 01:49:19 +00:00
side?: 'left' | 'right' | 'top' | 'bottom';
align?: 'center' | 'start' | 'end';
2024-02-15 02:30:10 +00:00
sideOffset?: number;
}
export const FormPopover = ({
children,
2024-02-16 01:49:19 +00:00
side = 'bottom',
2024-02-15 02:30:10 +00:00
align,
sideOffset = 0,
}: FormPopoverProps) => {
const proModal = useProModal();
const router = useRouter();
const closeRef = useRef<HTMLButtonElement>(null);
2024-02-15 02:30:10 +00:00
const { execute, fieldErrors } = useAction(createBoard, {
onSuccess: (data) => {
2024-02-16 01:49:19 +00:00
toast.success('Board created');
2024-02-15 02:30:10 +00:00
closeRef.current?.click();
router.push(`/board/${data.id}`);
},
onError: (error) => {
toast.error(error);
proModal.onOpen();
},
});
const onSubmit = (formData: FormData) => {
2024-02-16 01:49:19 +00:00
const title = formData.get('title') as string;
const image = formData.get('image') as string;
2024-02-15 02:30:10 +00:00
execute({ title, image });
};
return (
<Popover>
<PopoverTrigger asChild>{children}</PopoverTrigger>
<PopoverContent
align={align}
2024-02-16 01:49:19 +00:00
className='w-80 pt-3'
2024-02-15 02:30:10 +00:00
side={side}
sideOffset={sideOffset}
>
<div className='pb-4 text-center text-sm font-medium text-neutral-600 dark:text-neutral-300'>
2024-02-15 02:30:10 +00:00
Create board
</div>
<PopoverClose ref={closeRef} asChild>
<Button
className='absolute right-2 top-2 h-auto w-auto p-2 text-neutral-600 dark:text-neutral-300'
2024-02-16 01:49:19 +00:00
variant='ghost'
2024-02-15 02:30:10 +00:00
>
2024-02-16 01:49:19 +00:00
<X className='h-4 w-4' />
2024-02-15 02:30:10 +00:00
</Button>
</PopoverClose>
2024-02-16 01:49:19 +00:00
<form action={onSubmit} className='space-y-4'>
<div className='space-y-4'>
<p className='text-center text-xs font-medium italic text-neutral-700 dark:text-neutral-200'>
Images Provided by{' '}
<Link
className='text-sky-900 underline dark:text-sky-600'
href='https://unsplash.com/'
>
Unsplash
</Link>
</p>
2024-02-16 01:49:19 +00:00
<FormPicker id='image' errors={fieldErrors} />
2024-02-15 02:30:10 +00:00
<FormInput
2024-02-16 01:49:19 +00:00
id='title'
label='Board Title'
type='text'
2024-02-15 02:30:10 +00:00
errors={fieldErrors}
/>
</div>
2024-02-16 01:49:19 +00:00
<FormSubmit className='w-full'>Create</FormSubmit>
2024-02-15 02:30:10 +00:00
</form>
</PopoverContent>
</Popover>
);
};