Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

membuat halaman form request #88

Merged
merged 12 commits into from
Jan 21, 2025
7 changes: 6 additions & 1 deletion components/TheNavbar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ const isAdmin = computed(() =>
</button>
</li>
<li>
<ThemeToggle class="nav-link text-lg" />
<ClientOnly fallback-tag="span" fallback="memuat tema...">
<ThemeToggle class="nav-link text-lg block" />
</ClientOnly>
</li>
<li>
<NuxtLink class="nav-link" to="/"> Beranda </NuxtLink>
Expand All @@ -57,6 +59,9 @@ const isAdmin = computed(() =>
<li>
<NuxtLink class="nav-link" to="/wishlist"> Wishlist </NuxtLink>
</li>
<li>
<NuxtLink class="nav-link" to="/request"> Request Buku </NuxtLink>
</li>

<template v-if="user">
<li v-if="!isAdmin">
Expand Down
11 changes: 5 additions & 6 deletions components/ThemeToggle.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@ function toggleTheme(theme: Theme) {
</script>

<template>
<ClientOnly fallback-tag="span" fallback="memuat tema...">
<button :title="`mode ${themeStore.theme}`" @click="toggleTheme(themeStore.theme ?? 'light')">
<IconMoonCrescent v-if="themeStore.theme === 'dark'" />
<IconSun v-else />
</button>
</ClientOnly>

<button :title="`mode ${themeStore.theme}`" @click="toggleTheme(themeStore.theme ?? 'light')">
<IconMoonCrescent v-if="themeStore.theme === 'dark'" />
<IconSun v-else />
</button>
</template>
4 changes: 4 additions & 0 deletions components/admin/AdminSidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ const sidebarLinks = ref<SidebarLink[]>([
},
],
},
{
label: "Request",
route: "request",
},
])

const popover = ref()
Expand Down
48 changes: 48 additions & 0 deletions pages/admin/request.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<script setup lang="ts">
import Toast from "primevue/toast"

useHead({
title: "request",
})

definePageMeta({
layout: "admin",
})

const toast = useToast()

const { data, error } = await useAsyncData(async () => {
const supabase = useSupabaseClient()
const query = supabase.from("book_requests").select()

const { data, error } = await query
if (error) throw error
return data
})

if (error) {
toast.add({
severity: "error",
summary: "gagal mengambil data request!",
detail: "gagal mengambil data request, silahkan coba lagi nanti.",
life: 10000,
})
}
</script>

<template>
<h1>request</h1>

<DataTable :value="data">
<Column field="created_at" header="Tanggal request" sortable>
<template #body="{ data }">

Check warning on line 38 in pages/admin/request.vue

View workflow job for this annotation

GitHub Actions / Run linters (20)

Variable 'data' is already declared in the upper scope
{{ formatDate(new Date(data.created_at)) }}
</template>
</Column>

<Column field="isbn" header="ISBN" />
<Column field="title" header="Judul" />
</DataTable>

<Toast />
</template>
120 changes: 120 additions & 0 deletions pages/request.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<script setup lang="ts">
import { Toast } from "primevue"
import type { Database } from "~/types/database.types"

const toast = useToast()

const { data } = await useAsyncData(() => getAllAvailableCategories())

const user = useSupabaseUser()

const { data: latestRequest } = await useAsyncData(async () => {
const supabase = useSupabaseClient<Database>()

const { data, error } = await supabase
.from("book_requests")
.select("*")
.eq("user_id", user.value!.id)
.order("created_at", { ascending: false })
.limit(1)
.single()

if (error) console.log(error)
return data
})

const canRequest = computed(() => {
console.log(latestRequest.value)
if (latestRequest.value === null) return true

const SecondDate = new Date().getTime() - new Date(latestRequest.value.created_at).getTime()
const aDayInMs = 24 * 60 * 60 * 1000

const canRequest = Math.floor(SecondDate / aDayInMs) > 30
return canRequest
})

const requestData = ref({
title: "",
isbn: "",
category: "",
})

async function insertRequest() {
const supabase = useSupabaseClient<Database>()

try {
const { error } = await supabase.from("book_requests").insert({
title: requestData.value.title,
isbn: requestData.value.isbn,
category: requestData.value.category,
})

if (error) throw error

toast.add({
severity: "success",
summary: "menanbahkan request",
detail: "sukses menanbahkan request buku, mohon ditunggu ya",
life: 10000,
})
} catch (error) {
console.log(error)

toast.add({
severity: "error",
summary: "gagal menambahkan buku",
detail: "gagal menanbahkan request buku, silahkan coba lagi nanti",
life: 10000,
})
}
}
</script>

<template>
<section class="max-w-xl m-auto">
<header class="mb-4">
<h1 class="font-bold">Formulir permintaan buku</h1>
<p>
Isi form berikut untuk mengbuat request buku baru yang akan ditambahkan ke metscoo library.
</p>
<p>
kamu hanya bisa merequest satu buku perbulan dan request kamu akan diproses selama 14 hari
kerja.
</p>
</header>

<form
v-if="canRequest"
class="flex flex-col gap-2 main-section"
@submit.prevent="insertRequest"
>
<label for="judul"> Judul </label>
<InputText id="judul" v-model="requestData.title" type="text" placeholder="judul" required />

<label for="isbn"> ISBN </label>

<InputText id="isbn" v-model="requestData.isbn" type="text" placeholder="isbn" required />

<label for="Kategori"> kategori </label>
<Select
v-if="data"
v-model="requestData.category"
:options="data"
option-label="kategori"
option-value="kategori"
variant="filled"
placeholder="Pilih kategori"
class="w-full"
></Select>

<Button type="submit"> Request </Button>
</form>

<p v-else>
Mohon maaf anda belum bisa request buku karena requets kamu dibuat dalam 30 hari terakhir
</p>
</section>

<Toast />
</template>
41 changes: 40 additions & 1 deletion types/database.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,44 @@ export type Json =
export type Database = {
public: {
Tables: {
book_requests: {
Row: {
category: string
created_at: string
id: number
is_accepted: Database["public"]["Enums"]["request status"] | null
isbn: string
title: string
user_id: string | null
}
Insert: {
category?: string
created_at?: string
id?: number
is_accepted?: Database["public"]["Enums"]["request status"] | null
isbn: string
title: string
user_id?: string | null
}
Update: {
category?: string
created_at?: string
id?: number
is_accepted?: Database["public"]["Enums"]["request status"] | null
isbn?: string
title?: string
user_id?: string | null
}
Relationships: [
{
foreignKeyName: "book_requests_user_id_fkey"
columns: ["user_id"]
isOneToOne: false
referencedRelation: "pengguna"
referencedColumns: ["user_id"]
},
]
}
buku: {
Row: {
alamat_terbit: string
Expand Down Expand Up @@ -328,7 +366,7 @@ export type Database = {
Functions: {
check_out_users: {
Args: Record<PropertyKey, never>
Returns: string
Returns: boolean
}
is_super_admin: {
Args: Record<PropertyKey, never>
Expand All @@ -337,6 +375,7 @@ export type Database = {
}
Enums: {
"event type": "check_in" | "check_out"
"request status": "processing" | "accepted" | "rejected"
}
CompositeTypes: {
[_ in never]: never
Expand Down
Loading