98 lines
3.2 KiB
Vue
98 lines
3.2 KiB
Vue
<script setup lang="ts">
|
|
import { toTypedSchema } from "@vee-validate/zod"
|
|
import { useForm } from "vee-validate"
|
|
import * as z from "zod"
|
|
|
|
import {
|
|
Dialog,
|
|
DialogContent,
|
|
DialogDescription,
|
|
DialogFooter,
|
|
DialogHeader,
|
|
DialogTitle,
|
|
DialogTrigger,
|
|
} from '@/components/ui/dialog'
|
|
import Button from '~/components/ui/button/Button.vue';
|
|
import Input from '~/components/ui/input/Input.vue';
|
|
import { toast } from "vue-sonner"
|
|
import { FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from "~/components/ui/form"
|
|
import { getPlaylistsQueryKey, useCreatePlaylist } from "~/composeables/api/playlist-controller/playlist-controller"
|
|
import { useQueryClient } from "@tanstack/vue-query";
|
|
|
|
const formSchema = toTypedSchema(z.object({
|
|
playlistName: z.string().min(2).max(50).default(''),
|
|
}))
|
|
|
|
const { isFieldDirty, handleSubmit, resetForm } = useForm({
|
|
validationSchema: formSchema,
|
|
})
|
|
|
|
const queryClient = useQueryClient();
|
|
const { mutate: createPlaylistMutation } = useCreatePlaylist({
|
|
mutation: {
|
|
onSuccess: () => {
|
|
queryClient.invalidateQueries({ queryKey: getPlaylistsQueryKey() });
|
|
toast('Successfully created playlist', {
|
|
description: `Playlist created successfully`,
|
|
});
|
|
},
|
|
onError: () => {
|
|
toast.error('Cannot create playlist', {
|
|
description: 'Error occurred during playlist creation, please try again later.',
|
|
});
|
|
},
|
|
},
|
|
});
|
|
|
|
const onSubmit = handleSubmit(async (values) => {
|
|
const playlistName = values['playlistName'];
|
|
open.value = false;
|
|
createPlaylistMutation({
|
|
data: {
|
|
title: playlistName,
|
|
},
|
|
});
|
|
})
|
|
|
|
const open = ref(false)
|
|
</script>
|
|
|
|
<template>
|
|
<Dialog v-model:open="open">
|
|
<DialogTrigger as-child>
|
|
<slot name="trigger">
|
|
Create playlist
|
|
</slot>
|
|
</DialogTrigger>
|
|
<DialogContent class="sm:max-w-[425px]">
|
|
<form @submit.prevent="onSubmit">
|
|
<DialogHeader>
|
|
<DialogTitle>Edit profile</DialogTitle>
|
|
<DialogDescription>
|
|
Create name for your playlist.
|
|
</DialogDescription>
|
|
</DialogHeader>
|
|
<div class="py-4">
|
|
<FormField v-slot="{ componentField }" name="playlistName" :validate-on-blur="!isFieldDirty">
|
|
<FormItem>
|
|
<FormLabel>Name</FormLabel>
|
|
<FormControl>
|
|
<Input type="text" placeholder="shadcn" v-bind="componentField" />
|
|
</FormControl>
|
|
<FormDescription>
|
|
This is your public display name.
|
|
</FormDescription>
|
|
<FormMessage />
|
|
</FormItem>
|
|
</FormField>
|
|
</div>
|
|
<DialogFooter>
|
|
<Button type="submit">
|
|
Create
|
|
</Button>
|
|
</DialogFooter>
|
|
</form>
|
|
</DialogContent>
|
|
</Dialog>
|
|
</template>
|