Files
diplom-frontend/app/components/modals/create-server-channel-modal.tsx
2025-05-21 08:46:12 +03:00

167 lines
6.1 KiB
TypeScript

import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { ChannelType } from "~/lib/api/types";
import {
ModalType,
useModalStore,
type CreateServerChannelModalData,
} from "~/stores/modal-store";
import { Button } from "../ui/button";
import {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
} from "../ui/dialog";
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "../ui/form";
import { Input } from "../ui/input";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "../ui/select";
const schema = z.object({
name: z.string().min(1).max(32),
type: z.nativeEnum(ChannelType),
});
export default function CreateServerChannelModal() {
const { type, data, isOpen, onClose } = useModalStore();
const isModalOpen = type === ModalType.CREATE_SERVER_CHANNEL && isOpen;
let form = useForm<z.infer<typeof schema>>({
resolver: zodResolver(schema),
defaultValues: {
type: ChannelType.SERVER_TEXT,
},
});
const onOpenChange = () => {
form.reset();
onClose();
};
const onSubmit = async (values: z.infer<typeof schema>) => {
const response = await import("~/lib/api/client/server").then((m) =>
m.default.createChannel(
(data as CreateServerChannelModalData["data"]).serverId,
values,
),
);
form.reset();
onClose();
};
return (
<Dialog open={isModalOpen} onOpenChange={onOpenChange}>
<DialogContent className="sm:max-w-md">
<DialogHeader>
<DialogTitle>Create channel</DialogTitle>
<DialogDescription>
Give your channel a name and choose a channel type.
</DialogDescription>
</DialogHeader>
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}
className="space-y-4"
>
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel
required={
!schema.shape.name.isOptional()
}
>
Name
</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="type"
render={({ field }) => (
<FormItem>
<FormLabel
required={
!schema.shape.type.isOptional()
}
>
Type
</FormLabel>
<Select
defaultValue={field.value}
onValueChange={field.onChange}
>
<FormControl>
<SelectTrigger className="w-full">
<SelectValue placeholder="Select a channel type" />
</SelectTrigger>
</FormControl>
<SelectContent>
{Object.entries({
[ChannelType.SERVER_TEXT]:
"Text",
[ChannelType.SERVER_VOICE]:
"Voice",
}).map(([type, label]) => (
<SelectItem
key={type}
value={type}
>
{label}
</SelectItem>
))}
</SelectContent>
</Select>
<FormMessage />
</FormItem>
)}
/>
<DialogFooter className=" justify-between">
<DialogClose asChild>
<Button type="button" variant="secondary">
Close
</Button>
</DialogClose>
<Button
type="submit"
disabled={form.formState.isSubmitting}
>
{form.formState.isSubmitting
? "Creating..."
: "Create"}
</Button>
</DialogFooter>
</form>
</Form>
</DialogContent>
</Dialog>
);
}