Files
swag-shop/frontend/src/pages/users/components/users-invite-dialog.tsx
T

152 lines
3.8 KiB
TypeScript

import { z } from "zod";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { IconMailPlus, IconSend } from "@tabler/icons-react";
import { toast } from "@/hooks/use-toast";
import { Button } from "@/components/ui/button";
import {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle
} from "@/components/ui/dialog";
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { SelectDropdown } from "@/components/select-dropdown";
import { userTypes } from "../data/data";
const formSchema = z.object({
email: z
.string()
.min(1, { message: "Email is required." })
.email({ message: "Email is invalid." }),
role: z.string().min(1, { message: "Role is required." }),
desc: z.string().optional()
});
type UserInviteForm = z.infer<typeof formSchema>;
interface Props {
open: boolean;
onOpenChange: (open: boolean) => void;
}
export function UsersInviteDialog({ open, onOpenChange }: Props) {
const form = useForm<UserInviteForm>({
resolver: zodResolver(formSchema),
defaultValues: { email: "", role: "", desc: "" }
});
const onSubmit = (values: UserInviteForm) => {
form.reset();
toast({
title: "You submitted the following values:",
description: (
<pre className="mt-2 w-[340px] rounded-md bg-slate-950 p-4">
<code className="text-white">{JSON.stringify(values, null, 2)}</code>
</pre>
)
});
onOpenChange(false);
};
return (
<Dialog
open={open}
onOpenChange={(state) => {
form.reset();
onOpenChange(state);
}}>
<DialogContent className="sm:max-w-md">
<DialogHeader className="text-left">
<DialogTitle className="flex items-center gap-2">
<IconMailPlus /> Invite User
</DialogTitle>
<DialogDescription>
Invite new user to join your team by sending them an email
invitation. Assign a role to define their access level.
</DialogDescription>
</DialogHeader>
<Form {...form}>
<form
id="user-invite-form"
onSubmit={form.handleSubmit(onSubmit)}
className="space-y-4">
<FormField
control={form.control}
name="email"
render={({ field }) => (
<FormItem>
<FormLabel>Email</FormLabel>
<FormControl>
<Input
type="email"
placeholder="eg: john.doe@gmail.com"
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="role"
render={({ field }) => (
<FormItem className="space-y-1">
<FormLabel>Role</FormLabel>
<SelectDropdown
defaultValue={field.value}
onValueChange={field.onChange}
placeholder="Select a role"
items={userTypes.map(({ label, value }) => ({
label,
value
}))}
/>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="desc"
render={({ field }) => (
<FormItem className="">
<FormLabel>Description (optional)</FormLabel>
<FormControl>
<Textarea
className="resize-none"
placeholder="Add a personal note to your invitation (optional)"
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</form>
</Form>
<DialogFooter className="gap-y-2">
<DialogClose asChild>
<Button variant="outline">Cancel</Button>
</DialogClose>
<Button type="submit" form="user-invite-form">
Invite <IconSend />
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
}