feat: implement dynamic greeting and current time display in Dashboard component for enhanced user experience

This commit is contained in:
Yoga Pangestu 2026-06-20 13:33:41 +07:00
parent fec7cca207
commit 5108490f9d
2 changed files with 95 additions and 7 deletions

View File

@ -36,7 +36,7 @@ const menuGroups: MenuGroup[] = [
{
label: 'Menu',
items: [
{ title: 'Dashboard', href: '/admin/dashboard', icon: LayoutDashboard },
{ title: 'Dasbor', href: '/admin/dashboard', icon: LayoutDashboard },
],
},
{

View File

@ -1,17 +1,105 @@
<script setup lang="ts">
import { Head } from '@inertiajs/vue3';
import { Head, usePage } from '@inertiajs/vue3';
import { Clock, Sun, Sunrise, Moon } from '@lucide/vue';
import { computed, onMounted, onUnmounted, ref } from 'vue';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import AdminLayout from '@/layouts/AdminLayout.vue';
const page = usePage();
const user = computed(() => page.props.auth.user);
const currentTime = ref(new Date());
let timer: ReturnType<typeof setInterval>;
onMounted(() => {
timer = setInterval(() => {
currentTime.value = new Date();
}, 1000);
});
onUnmounted(() => {
clearInterval(timer);
});
const timeStr = computed(() => {
return currentTime.value.toLocaleTimeString('id-ID', {
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false,
});
});
const dateStr = computed(() => {
return currentTime.value.toLocaleDateString('id-ID', {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric',
});
});
const greeting = computed(() => {
const hour = currentTime.value.getHours();
if (hour >= 4 && hour < 11) {
return { text: 'Selamat Pagi', icon: Sunrise };
}
if (hour >= 11 && hour < 15) {
return { text: 'Selamat Siang', icon: Sun };
}
if (hour >= 15 && hour < 18) {
return { text: 'Selamat Sore', icon: Sun };
}
return { text: 'Selamat Malam', icon: Moon };
});
</script>
<template>
<Head title="Dashboard" />
<AdminLayout>
<div class="grid auto-rows-min gap-4 md:grid-cols-3">
<div class="bg-muted/50 aspect-video rounded-xl" />
<div class="bg-muted/50 aspect-video rounded-xl" />
<div class="bg-muted/50 aspect-video rounded-xl" />
<div class="flex flex-1 flex-col gap-4">
<!-- Welcome Card -->
<Card class="relative overflow-hidden">
<div class="from-primary/5 to-background absolute inset-0 bg-linear-to-br" />
<CardHeader class="relative">
<div class="flex items-center gap-3">
<div class="bg-primary/10 flex size-12 items-center justify-center rounded-full">
<component :is="greeting.icon" class="text-primary size-6" />
</div>
<div>
<CardTitle class="text-2xl font-bold">
{{ greeting.text }}, {{ user?.username }}!
</CardTitle>
<CardDescription class="mt-1">
Selamat datang di dasbor aplikasi.
</CardDescription>
</div>
</div>
</CardHeader>
<CardContent class="relative">
<div class="text-muted-foreground flex items-center gap-2 text-sm">
<span>{{ dateStr }}</span>
<span></span>
<span class="flex items-center gap-1">
<Clock class="size-3.5" />
{{ timeStr }}
</span>
</div>
</CardContent>
</Card>
<!-- Placeholder for future content -->
<div class="grid auto-rows-min gap-4 md:grid-cols-3">
<div class="bg-muted/50 aspect-video rounded-xl" />
<div class="bg-muted/50 aspect-video rounded-xl" />
<div class="bg-muted/50 aspect-video rounded-xl" />
</div>
</div>
<div class="bg-muted/50 min-h-[50vh] flex-1 rounded-xl" />
</AdminLayout>
</template>