Frontend (Vue.js)
Pendahuluan
Frontend aplikasi Absensi GPS dibangun menggunakan Vue.js 3 dengan Inertia.js untuk integrasi dengan Laravel. Frontend menyediakan antarmuka pengguna untuk admin dan guru dalam mengelola data absensi siswa.
Struktur Proyek
resources/js/
├── components/
│ ├── ui/
│ │ ├── button.vue
│ │ ├── card.vue
│ │ ├── input.vue
│ │ ├── select.vue
│ │ └── ...
│ ├── AppLogo.vue
│ ├── AppSidebar.vue
│ └── ...
├── layouts/
│ └── AppLayout.vue
├── pages/
│ ├── Admin/
│ │ ├── Absensi/
│ │ │ ├── Create.vue
│ │ │ ├── Edit.vue
│ │ │ └── Index.vue
│ │ ├── Kelas/
│ │ │ ├── Create.vue
│ │ │ ├── Edit.vue
│ │ │ └── Index.vue
│ │ ├── Laporan/
│ │ │ └── Index.vue
│ │ ├── Siswa/
│ │ │ ├── Create.vue
│ │ │ ├── Edit.vue
│ │ │ └── Index.vue
│ │ └── Users/
│ │ ├── Create.vue
│ │ ├── Edit.vue
│ │ └── Index.vue
│ ├── Auth/
│ │ ├── Login.vue
│ │ └── Register.vue
│ └── Dashboard.vue
└── types/
└── index.ts
Komponen Utama
AppLayout
AppLayout.vue adalah komponen layout utama yang digunakan oleh semua halaman. Komponen ini berisi:
- Sidebar untuk navigasi
- Header dengan informasi pengguna
- Konten utama
<template>
<div class="flex h-screen bg-gray-100">
<AppSidebar />
<div class="flex-1 flex flex-col overflow-hidden">
<header class="bg-white shadow">
<!-- Header content -->
</header>
<main class="flex-1 overflow-x-hidden overflow-y-auto bg-gray-100">
<div class="container mx-auto px-6 py-8">
<!-- Breadcrumbs -->
<div class="mb-6">
<Breadcrumb :items="breadcrumbs" />
</div>
<!-- Page content -->
<slot />
</div>
</main>
</div>
</div>
</template>
AppSidebar
AppSidebar.vue adalah komponen sidebar yang menampilkan menu navigasi. Menu yang ditampilkan berbeda berdasarkan peran pengguna (admin atau guru).
<template>
<Sidebar :collapsed="collapsed">
<SidebarHeader>
<AppLogo />
</SidebarHeader>
<SidebarContent>
<SidebarMenu>
<SidebarMenuItem v-for="item in mainNavItems" :key="item.href" :href="item.href" :icon="item.icon">
{{ item.title }}
</SidebarMenuItem>
</SidebarMenu>
</SidebarContent>
</Sidebar>
</template>
<script setup>
const mainNavItems = [
{
title: 'Dashboard',
href: '/dashboard',
icon: LayoutGrid,
},
{
title: 'Kelola Absensi',
href: '/absensi',
icon: ClipboardCheck,
},
{
title: 'Laporan Absensi',
href: '/laporan',
icon: FileSpreadsheet,
},
// Menu lainnya berdasarkan peran pengguna
];
</script>
Halaman Utama
Dashboard
Dashboard.vue adalah halaman utama yang menampilkan statistik dan grafik absensi siswa. Halaman ini menampilkan:
- Jumlah total absensi
- Grafik absensi per tanggal
- Grafik absensi per kelas
- Grafik status absensi (hadir, sakit, izin, alpha)
<template>
<AppLayout :breadcrumbs="breadcrumbs">
<div class="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
<!-- Statistik -->
<Card>
<CardHeader>
<CardTitle>Total Absensi</CardTitle>
</CardHeader>
<CardContent>
<div class="text-2xl font-bold">{{ stats.totalAbsensi }}</div>
</CardContent>
</Card>
<!-- Statistik lainnya -->
</div>
<!-- Grafik -->
<div class="grid gap-4 md:grid-cols-2 mt-4">
<Card>
<CardHeader>
<CardTitle>Grafik Absensi per Tanggal</CardTitle>
</CardHeader>
<CardContent>
<BarChart :data="chartDataPerTanggal" :options="{ responsive: true }" />
</CardContent>
</Card>
<!-- Grafik lainnya -->
</div>
</AppLayout>
</template>
Kelola Absensi
Admin/Absensi/Index.vue adalah halaman untuk mengelola absensi siswa. Halaman ini menampilkan:
- Filter tanggal dan kelas
- Daftar absensi siswa
- Opsi untuk mengubah status absensi
- Opsi untuk mengedit detail absensi
<template>
<AppLayout :breadcrumbs="breadcrumbs">
<!-- Filter -->
<Card class="mb-6">
<CardHeader>
<CardTitle>Filter Absensi</CardTitle>
</CardHeader>
<CardContent>
<div class="grid grid-cols-1 gap-4 md:grid-cols-3">
<!-- Filter tanggal dan kelas -->
</div>
</CardContent>
</Card>
<!-- Tabel Absensi -->
<Card>
<CardHeader>
<CardTitle>Data Absensi</CardTitle>
</CardHeader>
<CardContent>
<Table>
<TableHeader>
<!-- Header tabel -->
</TableHeader>
<TableBody>
<!-- Data absensi -->
</TableBody>
</Table>
</CardContent>
</Card>
<!-- Dialog untuk mengubah status -->
<Sheet v-model:open="isEditStatusSheetOpen">
<!-- Form ubah status -->
</Sheet>
</AppLayout>
</template>
Komponen UI
Aplikasi menggunakan komponen UI dari Shadcn UI yang telah diadaptasi untuk Vue.js. Komponen-komponen ini memberikan tampilan yang konsisten dan modern.
Button
<Button>Simpan</Button>
<Button variant="outline">Batal</Button>
<Button variant="destructive">Hapus</Button>
Card
<Card>
<CardHeader>
<CardTitle>Judul Card</CardTitle>
<CardDescription>Deskripsi card</CardDescription>
</CardHeader>
<CardContent>
<!-- Konten card -->
</CardContent>
<CardFooter>
<!-- Footer card -->
</CardFooter>
</Card>
Select
<Select v-model="selectedValue">
<SelectTrigger>
<SelectValue placeholder="Pilih opsi" />
</SelectTrigger>
<SelectContent>
<SelectItem value="option1">Opsi 1</SelectItem>
<SelectItem value="option2">Opsi 2</SelectItem>
</SelectContent>
</Select>
Integrasi dengan Backend
Frontend terintegrasi dengan backend menggunakan Inertia.js, yang memungkinkan pengembangan aplikasi Single Page Application (SPA) tanpa perlu membuat API terpisah.
Contoh Request
// Mendapatkan data
router.get(route('absensi.index'), {
tanggal: tanggal.value,
kelas_id: kelasId.value === 'all' ? null : kelasId.value,
}, {
preserveState: true,
replace: true,
});
// Menyimpan data
router.post(route('absensi.store'), {
tanggal: tanggal.value,
siswa_id: siswaId.value,
status: status.value,
}, {
onSuccess: () => {
toast({
title: 'Berhasil',
description: 'Data absensi berhasil ditambahkan',
});
},
});
Chart dan Visualisasi
Aplikasi menggunakan Chart.js dan vue-chartjs untuk menampilkan visualisasi data absensi.
// Data untuk grafik absensi per tanggal
const chartDataPerTanggal = computed(() => {
return {
labels: props.absensiPerTanggal.map(item => {
const date = new Date(item.tanggal);
return date.toLocaleDateString('id-ID', { weekday: 'short', day: 'numeric' });
}),
datasets: [
{
label: 'Hadir',
data: props.absensiPerTanggal.map(item => item.hadir),
backgroundColor: '#4ade80',
},
{
label: 'Sakit',
data: props.absensiPerTanggal.map(item => item.sakit),
backgroundColor: '#facc15',
},
// Dataset lainnya
],
};
});
Kesimpulan
Frontend Vue.js menyediakan antarmuka pengguna yang intuitif dan responsif untuk aplikasi Absensi GPS. Dengan menggunakan Inertia.js, frontend dapat terintegrasi dengan backend Laravel tanpa perlu membuat API terpisah. Komponen UI dari Shadcn UI memberikan tampilan yang konsisten dan modern, sementara Chart.js memungkinkan visualisasi data absensi yang informatif.