Commit 5bc2eb55 authored by Irvan Alfian Adi N's avatar Irvan Alfian Adi N
Browse files

Update

parent a93e655c
No related merge requests found
Showing with 343 additions and 107 deletions
+343 -107
......@@ -22,10 +22,12 @@ declare module 'vue' {
NDropdown: typeof import('naive-ui')['NDropdown']
NForm: typeof import('naive-ui')['NForm']
NFormItem: typeof import('naive-ui')['NFormItem']
NFormNumber: typeof import('naive-ui')['NFormNumber']
NH2: typeof import('naive-ui')['NH2']
NIcon: typeof import('naive-ui')['NIcon']
NImage: typeof import('naive-ui')['NImage']
NInput: typeof import('naive-ui')['NInput']
NInputNumber: typeof import('naive-ui')['NInputNumber']
NLayout: typeof import('naive-ui')['NLayout']
NLayoutSider: typeof import('naive-ui')['NLayoutSider']
NMenu: typeof import('naive-ui')['NMenu']
......
......@@ -17,27 +17,25 @@ const { mutate, isPending } = useHttpMutation(computed(() => `/kelas-bahaya/${ro
queryOptions: {
onSuccess(data,) {
message.success(data.message)
router.push('/report-types')
router.push('/danger-level')
},
onError(error) {
message.error(error.data.message)
}
}
})
const rules: FormRules = {
name: [
level: [
{
required: true,
message: 'Fakultas harus diisi',
message: 'Kelas Bahaya Harus di isi',
}
]
}
type FormType = {
name?: string
level?: string
}
const form = ref<FormType>({
......@@ -58,14 +56,14 @@ const onSubmit = () => {
<div>
<n-form @submit.prevent="onSubmit" :model="form" :rules="rules">
<n-form-item label="Kelas Bahaya" path="name">
<n-input v-model:value="form.name" />
<n-input v-model:value="form.level" />
</n-form-item>
<div class="flex gap-3">
<n-button :loading="isPending" attr-type="submit" type="primary">
Submit
Edit
</n-button>
<n-button type="tertiary" @click="router.back()">
Cancel
Batal
</n-button>
</div>
</n-form>
......
......@@ -25,16 +25,16 @@ const { mutate, isPending } = useHttpMutation('/kelas-bahaya', {
})
const rules: FormRules = {
name: [
level: [
{
required: true,
message: 'Fakultas harus diisi',
message: 'Kelas Bahaya harus di isi',
}
]
}
type FormType = {
name?: string
level?: string
}
const form = ref<FormType>({
......@@ -55,14 +55,14 @@ const onSubmit = () => {
<div>
<n-form @submit.prevent="onSubmit" :model="form" :rules="rules">
<n-form-item label="Kelas Bahaya" path="name">
<n-input v-model:value="form.name" />
<n-input v-model:value="form.level" />
</n-form-item>
<div class="flex gap-3">
<n-button :loading="isPending" attr-type="submit" type="primary">
Submit
Tambahkan
</n-button>
<n-button type="tertiary">
Cancel
Batal
</n-button>
</div>
</n-form>
......
......@@ -75,9 +75,9 @@ const data = computed(() => dangerLevel.value?.data)
<div>
<div class="flex flex-col md:flex-row gap-5 mb-10">
<n-button type="primary" @click="$router.push('/danger-level/create')">
Create
Tambah
</n-button>
<n-input placeholder="Cari"></n-input>
<!-- <n-input placeholder="Cari"></n-input> -->
</div>
<div class="w-full whitespace-pre overflow-auto">
<n-data-table :loading="isLoading" :columns="columns" :data="(data as any)" />
......@@ -100,8 +100,8 @@ const data = computed(() => dangerLevel.value?.data)
class="max-w-lg">
<template #action>
<div class="flex justify-end gap-5">
<n-button @click="showDeleteModal = false">Cancel</n-button>
<n-button :loading="isPending" type="primary" @click="onDelete(selectedId)">Delete</n-button>
<n-button @click="showDeleteModal = false">Hapus</n-button>
<n-button :loading="isPending" type="primary" @click="onDelete(selectedId)">Batal</n-button>
</div>
</template>
</n-modal>
......
<script setup lang="ts">
import { useHttp } from '@/composables/http/http';
import type { ProfileResponse } from '@/types/profile';
const { data: profile } = useHttp<ProfileResponse>('/profile')
defineProps<{
status: 'laporan-ditolak' |
'laporan-ditangani' |
'laporan-masuk' |
'laporan-tertangani' | string
}>()
defineEmits<{
(e: 'review'): void
(e: 'detail'): void
(e: 'approval'): void
}>()
</script>
<template>
<div class="flex gap-2">
<n-tooltip >
<template #trigger>
<n-button @click="$emit('detail')" type="tertiary">
Detail
</n-button>
</template>
Detail
</n-tooltip>
<template v-if="['admin', 'operator'].includes(profile?.data.role as string)">
<n-tooltip v-if="status == 'laporan-ditolak'">
<template #trigger>
<n-button @click="$emit('review')" type="error"> Tinjau Ulang </n-button>
</template>
Tinjau
</n-tooltip>
<n-tooltip v-if="status == 'laporan-masuk'">
<template #trigger>
<n-button @click="$emit('approval')" type="success"> Terima </n-button>
</template>
Terima
</n-tooltip>
</template>
</div>
</template>
\ No newline at end of file
......@@ -10,11 +10,13 @@ import { DateTime } from 'luxon'
import { useHttp, useHttpMutation } from '@/composables/http/http'
import { REPORT_STATUSES } from '@/constants/report'
import { NImage, useMessage } from 'naive-ui'
import Action from './_components/action.vue'
import L, { Marker } from 'leaflet'
import 'leaflet/dist/leaflet.css'
import icon from 'leaflet/dist/images/marker-icon.png'
import iconShadow from 'leaflet/dist/images/marker-shadow.png'
import type { ProfileResponse } from '@/types/profile'
type Data = {
id: string
......@@ -22,6 +24,7 @@ type Data = {
detail_id: any
fakultas_id: string
jenislaporan_id: string
custom_jenislaporan: string
email_pelapor: string
no_hp: string
keterangan_pelapor: string
......@@ -60,6 +63,9 @@ const showReview = ref<boolean>(false)
const selectedId = ref<string>()
const router = useRouter()
const { data: laporan } = useHttp<R<{ status: string; count: string }[]>>('/dashboard')
const { data: profile } = useHttp<ProfileResponse>('/profile')
const { data: detail } = useHttp<R<Data>>(
computed(() => `/laporan/${selectedId.value}`),
{
......@@ -72,6 +78,7 @@ const { data: detail } = useHttp<R<Data>>(
const { data: reportType, isLoading: isLoadingReportType } =
useHttp<R<{ id: string; name: string }[]>>('/jenis-laporan')
const reportTypeOptions = computed(() => {
return reportType.value?.data.map((v) => {
return { label: v.name, value: v.id }
......@@ -84,6 +91,7 @@ const { mutate: approval, isPending } = useHttpMutation(
method: 'POST',
queryOptions: {
onSuccess: (data) => {
console.log(data)
refetch()
showApproval.value = false
showReview.value = false
......@@ -105,8 +113,8 @@ const onReject = () => {
})
}
const createColumns = (): { key: string | keyof Data; title: string }[] & RowData[] => {
return [
const columns = computed(() =>
[
{
title: 'Tanggal dan Waktu',
key: 'created_at',
......@@ -123,7 +131,10 @@ const createColumns = (): { key: string | keyof Data; title: string }[] & RowDat
},
{
title: 'Tipe Pengaduan',
key: 'jenis_laporan'
key: 'jenis_laporan',
render: (item: Data) => (
item?.jenis_laporan || item?.custom_jenislaporan
)
},
{
title: 'Status',
......@@ -144,11 +155,33 @@ const createColumns = (): { key: string | keyof Data; title: string }[] & RowDat
height: '30px'
}
})
},
{
title: 'Action',
key: 'action',
render: (v: { id: string; status: string }) =>
h(Action, {
status: v.status,
onReview: () => {
showReview.value = true
selectedId.value = v.id
},
onDetail: () => {
router.push(`/report/${v.id}`)
},
onApproval: () => {
selectedId.value = v.id
showApproval.value = true
}
})
}
]
}
const columns = createColumns()
].filter((item) => {
if (['petugas', 'admin_unit'].includes(profile.value?.data?.role as string)) {
return item.key != 'action'
}
return true
})
)
const data = computed(() => {
return report.value?.data
......@@ -176,27 +209,32 @@ watchEffect(() => {
}
})
const capitalize = (str: string) => {
return str.split(' ').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(" ")
}
const reportStatusOpt = REPORT_STATUSES.map((v) => ({ label: v, value: v }))
const { data: user } = useHttp<R<{ id: string; name: string }[]>>('/user')
const { data: user } = useHttp<R<{ id: string; name: string, role: string,fakultas_name:string }[]>>('/user')
const users = computed(() => {
return user.value?.data.map((v) => {
return { label: v.name, value: v.id }
const role =capitalize(v?.role?.split('_')?.join(' ') || '')
return { label: `${v.name} - ${role} - ${v.fakultas_name}`, value: v.id }
})
})
const { data: profile } = useHttp('/profile')
</script>
<template>
<div class="mb-5">
<n-h2>
Hai {{ profile?.data?.name }}
</n-h2>
<p> Selamat Datang Halaman Laporan Sistem SIGAP </p>
<div>
<n-h2> Selamat Datang Halaman Laporan Sistem SIGAP </n-h2>
</div>
<div>
<div class="flex flex-col md:flex-row gap-5 mb-10">
<n-card v-for="item in laporan?.data">
<n-card> {{ item.status }} : {{ item.count }} </n-card>
</n-card>
</div>
<div class="flex flex-col md:flex-row gap-5 mb-10">
<n-select
v-model:value="params.status"
......@@ -258,7 +296,7 @@ const { data: profile } = useHttp('/profile')
<n-tr>
<n-td> Jenis Laporan </n-td>
<n-td>
{{ detail?.data.jenis_laporan }}
{{ detail?.data.jenis_laporan || detail?.data?.custom_jenislaporan }}
</n-td>
</n-tr>
<n-tr>
......
......@@ -133,7 +133,7 @@ const reportStatusOpt = REPORT_STATUSES.map((v) => ({ label: v, value: v }))
<div>
<div class="text-center text-2xl font-semibold">
Data Laporan Kejadian di Lingkungan UNS
Data Tahun 2025
Data Tahun 2024
</div>
</div>
<div>
......
......@@ -23,8 +23,6 @@ const { mutate, isPending } = useHttpMutation(computed(() => `/fakultas/${route.
message.error(error.data.message)
}
}
})
const rules: FormRules = {
......@@ -52,7 +50,7 @@ const onSubmit = () => {
<template>
<div>
<n-h2>
Selamat Datang Halaman Edit Jenis Pengaduan Sistem SIGAP
Selamat Datang Halaman Edit Fakultas Sistem SIGAP
</n-h2>
</div>
<div>
......@@ -62,10 +60,10 @@ const onSubmit = () => {
</n-form-item>
<div class="flex gap-3">
<n-button :loading="isPending" attr-type="submit" type="primary">
Submit
Edit
</n-button>
<n-button type="tertiary" @click="router.back()">
Cancel
Batal
</n-button>
</div>
</n-form>
......
......@@ -22,8 +22,6 @@ const { mutate, isPending } = useHttpMutation('/fakultas', {
message.error(error.data.message)
}
}
})
const rules: FormRules = {
......@@ -61,10 +59,10 @@ const onSubmit = () => {
</n-form-item>
<div class="flex gap-3">
<n-button :loading="isPending" attr-type="submit" type="primary">
Submit
Tambahkan
</n-button>
<n-button type="tertiary">
Cancel
Batal
</n-button>
</div>
</n-form>
......
......@@ -15,7 +15,9 @@ const params = ref<{
size?: number
search?: string
}>({
page: 1,
size: 10,
search: ''
})
const createColumns = () => {
......@@ -86,9 +88,9 @@ const data = computed(() => faculty.value?.data)
<div>
<div class="flex flex-col md:flex-row gap-5 mb-10">
<n-button type="primary" @click="$router.push('/faculty/create')">
Create
Tambah
</n-button>
<n-input v-model:value="params.search" placeholder="Cari"></n-input>
<!-- <n-input v-model:value="params.search" placeholder="Cari"></n-input> -->
</div>
<div class="w-full whitespace-pre overflow-auto">
<n-data-table :loading="isLoading" :columns="columns" :data="(data as any)" />
......@@ -111,8 +113,8 @@ const data = computed(() => faculty.value?.data)
class="max-w-lg">
<template #action>
<div class="flex justify-end gap-5">
<n-button @click="showDeleteModal = false">Cancel</n-button>
<n-button :loading="isPending" type="primary" @click="onDelete(selectedId)">Delete</n-button>
<n-button @click="showDeleteModal = false">Batal</n-button>
<n-button :loading="isPending" type="primary" @click="onDelete(selectedId)">Hapus</n-button>
</div>
</template>
</n-modal>
......
......@@ -4,35 +4,88 @@
</route>
<script setup lang="ts">
import { useHttp, useHttpMutation } from '@/composables/http/http';
import { roleOptions } from '@/app/management/_constants/role'
import { useMessage } from 'naive-ui';
type Form = {
name?: string
email?: string
role?: 'admin' | 'user' | 'petugas' | 'admin_unit' | ''
phone?: string
address?: string
gender?: string
facultyId?: string
}
const message = useMessage()
const { data: faculty, isLoading: isLoadingFaculty } = useHttp<R<{ id: string, name: string }[]>>('/fakultas')
const facultyOptions = computed(() => {
return faculty.value?.data.map((v) => {
return { label: v.name, value: v.id }
})
})
const router = useRouter()
const form = ref<Form>({
})
const { mutate, isPending, } = useHttpMutation('/user', {
method: 'POST',
queryOptions: {
onSuccess(data) {
router.push('/management/admin-unit')
message.success(data.message)
},
onError(error) {
message.error(error.data.message)
}
}
})
const onSubmit = () => {
mutate({
"name": form.value?.name,
"email": form.value?.email,
"role": form.value?.role,
// "gender": form.value?.gender,
"fakultas_id": form.value?.facultyId,
"phone": form.value?.phone,
// "address": form.value?.address
})
}
</script>
<template>
<div>
<n-h2>
Management Pengguna
Selamat Datang Halaman Manajemen Sistem SIGAP
</n-h2>
</div>
<div>
<n-form>
<n-form-item label="Name">
<n-input />
<n-form :model="form" @submit.prevent="onSubmit">
<n-form-item label="Nama">
<n-input v-model:value="form.name"/>
</n-form-item>
<n-form-item label="Email">
<n-input />
<n-input v-model:value="form.email"/>
</n-form-item>
<n-form-item label="Role">
<n-select></n-select>
<n-select v-model:value="form.role" :options="roleOptions"></n-select>
</n-form-item>
<n-form-item label="Nomor HP">
<n-input v-model:value="form.phone" />
</n-form-item>
<n-form-item label="Phone">
<n-input />
<n-form-item label="Fakultas">
<n-select v-model:value="form.facultyId" :options="facultyOptions" :loading="isLoadingFaculty"></n-select>
</n-form-item>
<div class="flex gap-3">
<n-button type="primary">
Save
<n-button type="primary" :loading="isPending" attr-type="submit">
Tambahkan
</n-button>
<n-button type="tertiary">
Cancel
Batal
</n-button>
</div>
</n-form>
......
......@@ -107,7 +107,7 @@ const data = computed(() => {
</div>
<div>
<div class="flex justify-between mb-5">
<n-button type="primary" @click="$router.push('/management/admin-unit/create')">Create</n-button>
<n-button type="primary" @click="$router.push('/management/admin-unit/create')">Tambah</n-button>
<div>
<n-input v-model:value="params.search" placeholder="Cari"></n-input>
</div>
......@@ -133,8 +133,8 @@ const data = computed(() => {
class="max-w-lg">
<template #action>
<div class="flex justify-end gap-5">
<n-button @click="showDeleteModal = false">Cancel</n-button>
<n-button :loading="isPending" type="primary" @click="onDelete()">Delete</n-button>
<n-button @click="showDeleteModal = false">Batal</n-button>
<n-button :loading="isPending" type="primary" @click="onDelete()">Hapus</n-button>
</div>
</template>
</n-modal>
......
......@@ -62,7 +62,7 @@ const onSubmit = () => {
</div>
<div>
<n-form @submit.prevent="onSubmit">
<n-form-item label="Name">
<n-form-item label="Nama">
<n-input v-model:value="formData.name" />
</n-form-item>
<n-form-item label="Email">
......@@ -75,12 +75,12 @@ const onSubmit = () => {
:options="ROLES.map((v) => ({ label: v, value: v }))"
></n-select>
</n-form-item>
<n-form-item label="Phone">
<n-form-item label="Nomor Hp">
<n-input v-model:value="formData.phone" />
</n-form-item>
<div class="flex gap-3">
<n-button type="primary" attr-type="submit" :loading="isPending"> Update </n-button>
<n-button type="tertiary"> Cancel </n-button>
<n-button type="primary" attr-type="submit" :loading="isPending"> Edit </n-button>
<n-button type="tertiary"> Batal </n-button>
</div>
</n-form>
</div>
......
......@@ -49,10 +49,8 @@ const onSubmit = () => {
"name": form.value?.name,
"email": form.value?.email,
"role": form.value?.role,
"gender": form.value?.gender,
"fakultas_id": form.value?.facultyId,
"phone": form.value?.phone,
"address": form.value?.address
})
}
......@@ -66,7 +64,7 @@ const onSubmit = () => {
</div>
<div>
<n-form :model="form" @submit.prevent="onSubmit">
<n-form-item label="Name">
<n-form-item label="Nama">
<n-input v-model:value="form.name" />
</n-form-item>
<n-form-item label="Email">
......@@ -75,12 +73,9 @@ const onSubmit = () => {
<n-form-item label="Role">
<n-select v-model:value="form.role" :options="roleOptions"></n-select>
</n-form-item>
<n-form-item label="Phone">
<n-form-item label="Nomor Hp">
<n-input v-model:value="form.phone" />
</n-form-item>
<n-form-item label="Address">
<n-input type="textarea" v-model:value="form.address" />
</n-form-item>
<n-form-item label="Fakultas">
<n-select v-model:value="form.facultyId" :options="facultyOptions" :loading="isLoadingFaculty"></n-select>
</n-form-item>
......
......@@ -111,7 +111,7 @@ const { data: profile } = useHttp<ProfileResponse>('/profile')
<div>
<div class="flex justify-between mb-5">
<n-button v-if="profile?.data.role == 'admin'" type="primary"
@click="$router.push('/management/admin/create')">Create</n-button>
@click="$router.push('/management/admin/create')">Tambah</n-button>
<div>
<n-input v-model:value="params.search" placeholder="Cari"></n-input>
</div>
......@@ -137,8 +137,8 @@ const { data: profile } = useHttp<ProfileResponse>('/profile')
class="max-w-lg">
<template #action>
<div class="flex justify-end gap-5">
<n-button @click="showDeleteModal = false">Cancel</n-button>
<n-button :loading="isPending" type="primary" @click="onDelete()">Delete</n-button>
<n-button @click="showDeleteModal = false">Batal</n-button>
<n-button :loading="isPending" type="primary" @click="onDelete()">Hapus</n-button>
</div>
</template>
</n-modal>
......
......@@ -79,8 +79,8 @@ const onSubmit = () => {
<n-input v-model:value="formData.phone" />
</n-form-item>
<div class="flex gap-3">
<n-button type="primary" attr-type="submit" :loading="isPending"> Update </n-button>
<n-button type="tertiary"> Cancel </n-button>
<n-button type="primary" attr-type="submit" :loading="isPending"> Edit </n-button>
<n-button type="tertiary"> Batal </n-button>
</div>
</n-form>
</div>
......
......@@ -4,35 +4,88 @@
</route>
<script setup lang="ts">
import { useHttp, useHttpMutation } from '@/composables/http/http';
import { roleOptions } from '@/app/management/_constants/role'
import { useMessage } from 'naive-ui';
type Form = {
name?: string
email?: string
role?: 'admin' | 'user' | 'petugas' | 'admin_unit' | ''
phone?: string
address?: string
gender?: string
facultyId?: string
}
const message = useMessage()
const { data: faculty, isLoading: isLoadingFaculty } = useHttp<R<{ id: string, name: string }[]>>('/fakultas')
const facultyOptions = computed(() => {
return faculty.value?.data.map((v) => {
return { label: v.name, value: v.id }
})
})
const router = useRouter()
const form = ref<Form>({
})
const { mutate, isPending, } = useHttpMutation('/user', {
method: 'POST',
queryOptions: {
onSuccess(data) {
router.push('/management/operator')
message.success(data.message)
},
onError(error) {
message.error(error.data.message)
}
}
})
const onSubmit = () => {
mutate({
"name": form.value?.name,
"email": form.value?.email,
"role": form.value?.role,
// "gender": form.value?.gender,
"fakultas_id": form.value?.facultyId,
"phone": form.value?.phone,
// "address": form.value?.address
})
}
</script>
<template>
<div>
<n-h2>
Management Pengguna
Selamat Datang Halaman Manajemen Sistem SIGAP
</n-h2>
</div>
<div>
<n-form>
<n-form-item label="Name">
<n-input />
<n-form :model="form" @submit.prevent="onSubmit">
<n-form-item label="Nama">
<n-input v-model:value="form.name"/>
</n-form-item>
<n-form-item label="Email">
<n-input />
<n-input v-model:value="form.email"/>
</n-form-item>
<n-form-item label="Role">
<n-select></n-select>
<n-select v-model:value="form.role" :options="roleOptions"></n-select>
</n-form-item>
<n-form-item label="Nomor HP">
<n-input v-model:value="form.phone" />
</n-form-item>
<n-form-item label="Phone">
<n-input />
<n-form-item label="Fakultas">
<n-select v-model:value="form.facultyId" :options="facultyOptions" :loading="isLoadingFaculty"></n-select>
</n-form-item>
<div class="flex gap-3">
<n-button type="primary">
Save
<n-button type="primary" :loading="isPending" attr-type="submit">
Tambahkan
</n-button>
<n-button type="tertiary">
Cancel
Batal
</n-button>
</div>
</n-form>
......
......@@ -107,7 +107,7 @@ const data = computed(() => {
</div>
<div>
<div class="flex justify-between mb-5">
<n-button type="primary" @click="$router.push('/management/operator/create')">Create</n-button>
<n-button type="primary" @click="$router.push('/management/operator/create')">Tambah</n-button>
<div>
<n-input v-model:value="params.search" placeholder="Cari"></n-input>
</div>
......@@ -133,8 +133,8 @@ const data = computed(() => {
class="max-w-lg">
<template #action>
<div class="flex justify-end gap-5">
<n-button @click="showDeleteModal = false">Cancel</n-button>
<n-button :loading="isPending" type="primary" @click="onDelete()">Delete</n-button>
<n-button @click="showDeleteModal = false">Batal</n-button>
<n-button :loading="isPending" type="primary" @click="onDelete()">Hapus</n-button>
</div>
</template>
</n-modal>
......
......@@ -45,7 +45,7 @@ const { mutate: updateUser, isPending } = useHttpMutation(
queryOptions: {
onSuccess(data) {
message.success(data.message)
router.push('/management/admin')
router.push('/management/staff')
}
}
}
......
......@@ -4,35 +4,88 @@
</route>
<script setup lang="ts">
import { useHttp, useHttpMutation } from '@/composables/http/http';
import { roleOptions } from '@/app/management/_constants/role'
import { useMessage } from 'naive-ui';
type Form = {
name?: string
email?: string
role?: 'admin' | 'user' | 'petugas' | 'admin_unit' | ''
phone?: string
address?: string
gender?: string
facultyId?: string
}
const message = useMessage()
const { data: faculty, isLoading: isLoadingFaculty } = useHttp<R<{ id: string, name: string }[]>>('/fakultas')
const facultyOptions = computed(() => {
return faculty.value?.data.map((v) => {
return { label: v.name, value: v.id }
})
})
const router = useRouter()
const form = ref<Form>({
})
const { mutate, isPending, } = useHttpMutation('/user', {
method: 'POST',
queryOptions: {
onSuccess(data) {
router.push('/management/staff')
message.success(data.message)
},
onError(error) {
message.error(error.data.message)
}
}
})
const onSubmit = () => {
mutate({
"name": form.value?.name,
"email": form.value?.email,
"role": form.value?.role,
// "gender": form.value?.gender,
"fakultas_id": form.value?.facultyId,
"phone": form.value?.phone,
// "address": form.value?.address
})
}
</script>
<template>
<div>
<n-h2>
Management Pengguna
Selamat Datang Halaman Manajemen Sistem SIGAP
</n-h2>
</div>
<div>
<n-form>
<n-form-item label="Name">
<n-input />
<n-form :model="form" @submit.prevent="onSubmit">
<n-form-item label="Nama">
<n-input v-model:value="form.name"/>
</n-form-item>
<n-form-item label="Email">
<n-input />
<n-input v-model:value="form.email"/>
</n-form-item>
<n-form-item label="Role">
<n-select></n-select>
<n-select v-model:value="form.role" :options="roleOptions"></n-select>
</n-form-item>
<n-form-item label="Nomor HP">
<n-input v-model:value="form.phone" />
</n-form-item>
<n-form-item label="Phone">
<n-input />
<n-form-item label="Fakultas">
<n-select v-model:value="form.facultyId" :options="facultyOptions" :loading="isLoadingFaculty"></n-select>
</n-form-item>
<div class="flex gap-3">
<n-button type="primary">
Save
<n-button type="primary" :loading="isPending" attr-type="submit">
Tambahkan
</n-button>
<n-button type="tertiary">
Cancel
Batal
</n-button>
</div>
</n-form>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment