From 13f3c24c7b789438a46ffc5d4420d14745689386 Mon Sep 17 00:00:00 2001 From: Efraim Munthe Date: Sat, 1 Feb 2025 07:04:15 +0700 Subject: [PATCH 1/8] feat: validate profil edit form --- pages/profil/edit.vue | 60 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 7 deletions(-) diff --git a/pages/profil/edit.vue b/pages/profil/edit.vue index dc84e3b..864162d 100644 --- a/pages/profil/edit.vue +++ b/pages/profil/edit.vue @@ -6,6 +6,8 @@ import Toast from "primevue/toast" import type { Pengguna } from "@/types" import { useToast } from "primevue/usetoast" import IconArrowLeft from "~icons/mdi/arrow-left" +import { zodResolver } from "@primevue/forms/resolvers/zod" +import { z } from "zod" useHead({ title: "Edit profil", @@ -24,9 +26,19 @@ const { data: userProfile } = await useAsyncData(async () => { return false }) +const formSchema = z.object({ + nama: z.string().nonempty("nama kamu gak mungkin kosong."), + kelas: z.enum(["X", "XI", "XII"], { message: "kelasnya gak valid." }), + jurusan: z.string().nonempty("jurusan kamu gak mungkin kosong."), +}) + +const resolver = zodResolver(formSchema) + const toast = useToast() -async function updateProfile() { +async function updateProfile({ valid }: { valid: boolean }) { + if (!valid) return + try { await authStore.handleUpdateProfile(userProfile.value as Pengguna) @@ -58,27 +70,61 @@ async function updateProfile() {
- Foto kamu disini + Foto kamu disini
-
+ - + + + + {{ $form.nama?.error.message }} + + + + {{ $form.kategori_id?.error.message }} + {{ errDialog.message }}

- +

Sukses!

{{ dialog.message }}

+ + From 09a14e3a487da5b3c84dc6a19f0d056679b639f7 Mon Sep 17 00:00:00 2001 From: Efraim Munthe Date: Sat, 1 Feb 2025 05:20:39 +0000 Subject: [PATCH 4/8] export to lib for reuse --- lib/buku.ts | 22 ++++++++++++++++++++++ pages/admin/buku/tambah.vue | 23 +---------------------- 2 files changed, 23 insertions(+), 22 deletions(-) create mode 100644 lib/buku.ts diff --git a/lib/buku.ts b/lib/buku.ts new file mode 100644 index 0000000..59f9459 --- /dev/null +++ b/lib/buku.ts @@ -0,0 +1,22 @@ +import { zodResolver } from "@primevue/forms/resolvers/zod" +import { z } from "zod" + +export const schema = z.object({ + judul: z.string().nonempty("judul tidak boleh kosong."), + no_isbn: z.string().nonempty("isbn tidak boleh kosong."), + image: z.string().optional().nullable().default(null), + kategori_id: z.number({ message: "buku harus memiliki kategori." }), + asal: z.string().default("-"), + jumlah_exspl: z + .number({ message: "jumlah harus berupa angka." }) + .min(0, "jumlah harus 0 atau lebih.") + .max(10000, "banyak amat sih ga mungkin lah bukunya segitu."), + penerbit: z.string().nonempty("penerbit tidak boleh kosong."), + alamat_terbit: z.string().nonempty("alamat penerbit tidak boleh kosong."), + tahun_terbit: z + .string() + .regex(/^\d{0,4}$/, { message: "tahun terbit harus berupa angka 0 sampai 4 digit." }), + penulis: z.string().nonempty("penulis tidak boleh kosong"), +}) + +export const resolver = zodResolver(schema) diff --git a/pages/admin/buku/tambah.vue b/pages/admin/buku/tambah.vue index e9ec1ac..80386b1 100644 --- a/pages/admin/buku/tambah.vue +++ b/pages/admin/buku/tambah.vue @@ -6,9 +6,8 @@ import type { PostgrestError } from "@supabase/supabase-js" import IconArrowLeft from "~icons/mdi/arrow-left" import type { Database } from "~/types/database.types.ts" import { InputText, InputNumber, FileUpload } from "primevue" -import { zodResolver } from "@primevue/forms/resolvers/zod" -import { z } from "zod" import type { FormSubmitEvent } from "@primevue/forms" +import { schema, resolver } from "~/lib/buku" useHead({ title: "Tambah Buku", @@ -37,26 +36,6 @@ async function uploadBookImage(isbn: string, file: File) { return error } -const schema = z.object({ - judul: z.string().nonempty("judul tidak boleh kosong."), - no_isbn: z.string().nonempty("isbn tidak boleh kosong."), - image: z.string().nullable(), - kategori_id: z.number({ message: "buku harus memiliki kategori." }), - asal: z.string().default("-"), - jumlah_exspl: z - .number({ message: "jumlah harus berupa angka." }) - .min(0, "jumlah harus 0 atau lebih.") - .max(10000, "banyak amat sih ga mungkin lah bukunya segitu."), - penerbit: z.string().nonempty("penerbit tidak boleh kosong."), - alamat_terbit: z.string().nonempty("alamat penerbit tidak boleh kosong."), - tahun_terbit: z - .string() - .regex(/^\d{0,4}$/, { message: "tahun terbit harus berupa angka 0 sampai 4 digit." }), - penulis: z.string().nonempty("penulis tidak boleh kosong"), -}) - -const resolver = zodResolver(schema) - async function addNewBook({ valid, values }: FormSubmitEvent) { if (!valid) return From 8ad63952c55e6d6551108b869c5970e69afacfcf Mon Sep 17 00:00:00 2001 From: Efraim Munthe Date: Sat, 1 Feb 2025 05:46:04 +0000 Subject: [PATCH 5/8] fix: image upload not working --- pages/admin/buku/tambah.vue | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/pages/admin/buku/tambah.vue b/pages/admin/buku/tambah.vue index 80386b1..a4ad1cf 100644 --- a/pages/admin/buku/tambah.vue +++ b/pages/admin/buku/tambah.vue @@ -29,8 +29,7 @@ const { newImage, previewURL, previewImage } = usePreviewImage() async function uploadBookImage(isbn: string, file: File) { if (!formData.value) return console.trace("buku gak ada????") - formData.value.image = `public/${isbn}` - const { error } = await supabase.storage.from("Buku").upload(formData.value.image, file, { + const { error } = await supabase.storage.from("Buku").upload(`public/${isbn}`, file, { upsert: true, }) return error @@ -42,10 +41,10 @@ async function addNewBook({ valid, values }: FormSubmitEvent) { isLoading.value = true const { data: buku, success, error } = schema.safeParse(values) - if (!buku || !success) { + if (!buku || (buku && !success)) { isLoading.value = false - console.log(buku, success, error) + console.log(error) return toast.add({ severity: "error", @@ -55,16 +54,14 @@ async function addNewBook({ valid, values }: FormSubmitEvent) { }) } - const { no_isbn } = buku - try { // upload image if admin puts an image if (newImage.value) { - const uploadError = await uploadBookImage(no_isbn, newImage.value) + const uploadError = await uploadBookImage(buku.no_isbn, newImage.value) if (uploadError) throw uploadError } - const insertError = await insertBookData(buku) + const insertError = await insertBookData({ ...buku, image: `public/${buku.no_isbn}` }) if (insertError) throw insertError dialog.value.open("Buku berhasil ditambahkan!") From 9911ba8d0ddcd0d698ed350329c01e7e5ac85997 Mon Sep 17 00:00:00 2001 From: Efraim Munthe Date: Sun, 2 Feb 2025 08:06:00 +0000 Subject: [PATCH 6/8] feat: add validation on buku edit form --- pages/admin/buku/[isbn].vue | 136 ++++++++++++++++++++++++------------ 1 file changed, 93 insertions(+), 43 deletions(-) diff --git a/pages/admin/buku/[isbn].vue b/pages/admin/buku/[isbn].vue index 2948b37..fa06416 100644 --- a/pages/admin/buku/[isbn].vue +++ b/pages/admin/buku/[isbn].vue @@ -9,6 +9,8 @@ import Select from "primevue/select" import type { Database } from "~/types/database.types.ts" import IconArrowLeft from "~icons/mdi/arrow-left" import type { Buku } from "~/types" +import { schema, resolver } from "~/lib/buku" +import type { FormSubmitEvent } from "@primevue/forms" definePageMeta({ layout: "admin", @@ -41,21 +43,26 @@ const { data: availableCategories } = await useLazyAsyncData( async () => await getAllAvailableCategories() ) -async function editBook(buku: Buku) { +async function editBook({ valid, values }: FormSubmitEvent) { + if (!valid) return + + const { data: buku, success, error } = schema.safeParse(values) + + if (!buku || !success) { + console.log(error) + + return toast.add({ + severity: "error", + summary: "gagal menyunting data buku.", + detail: "gagal menyunting data buku. Silahkan coba lagi dalam beberapa saat", + life: 10000, + }) + } + try { const { error } = await supabase .from("buku") - .update({ - judul: buku.judul, - no_isbn: buku.no_isbn, - penulis: buku.penulis, - asal: buku.asal, - kategori_id: buku.kategori_id, - jumlah_exspl: buku.jumlah_exspl, - penerbit: buku.penerbit, - alamat_terbit: buku.alamat_terbit, - tahun_terbit: buku.tahun_terbit, - }) + .update({ ...buku, image: `public/${buku.no_isbn}` }) .eq("no_isbn", isbn) if (error) throw error @@ -85,7 +92,7 @@ async function deleteBook(isbn: string) { const { error } = await supabase.from("buku").delete().eq("no_isbn", isbn) if (error) throw error - const response = await supabase.storage.from("Buku").remove([`${isbn}/${isbn}`]) + const response = await supabase.storage.from("Buku").remove([`public/${isbn}`]) if (response.error) throw response.error if (error) throw error @@ -153,9 +160,15 @@ const imgURL = ref(getBukuImage(buku.value?.image))

-