182 lines
4.6 KiB
Vue
182 lines
4.6 KiB
Vue
<script setup lang="ts">
|
|
import { Calendar, Hospital, UserCheck, UsersRound } from 'lucide-vue-next'
|
|
|
|
const dataCard = ref({
|
|
totalRevenue: 0,
|
|
totalRevenueDesc: 0,
|
|
subscriptions: 0,
|
|
subscriptionsDesc: 0,
|
|
sales: 0,
|
|
salesDesc: 0,
|
|
activeNow: 0,
|
|
activeNowDesc: 0,
|
|
})
|
|
|
|
const dataRecentSales = [
|
|
{
|
|
name: 'Olivia Martin',
|
|
email: 'olivia.martin@email.com',
|
|
amount: 1999,
|
|
},
|
|
{
|
|
name: 'Jackson Lee',
|
|
email: 'jackson.lee@email.com',
|
|
amount: 39,
|
|
},
|
|
{
|
|
name: 'Isabella Nguyen',
|
|
email: 'isabella.nguyen@email.com',
|
|
amount: 299,
|
|
},
|
|
{
|
|
name: 'William Kim',
|
|
email: 'will@email.com',
|
|
amount: 99,
|
|
},
|
|
{
|
|
name: 'Sofia Davis',
|
|
email: 'sofia.davis@email.com',
|
|
amount: 39,
|
|
},
|
|
]
|
|
|
|
const summaryData: any[] = [
|
|
{
|
|
title: 'Total Pasien Hari Ini',
|
|
icon: UsersRound,
|
|
metric: 23,
|
|
trend: 15,
|
|
timeframe: 'daily',
|
|
},
|
|
{
|
|
title: 'Rehabilitasi Medik',
|
|
icon: UserCheck,
|
|
metric: 100,
|
|
trend: 9,
|
|
timeframe: 'daily',
|
|
},
|
|
{
|
|
title: 'VClaim BPJS',
|
|
icon: Calendar,
|
|
metric: 52,
|
|
trend: 1,
|
|
timeframe: 'daily',
|
|
},
|
|
{
|
|
title: 'SATUSEHAT Sync',
|
|
icon: Hospital,
|
|
metric: 71,
|
|
trend: -3,
|
|
timeframe: 'daily',
|
|
},
|
|
]
|
|
|
|
const linkItems = [
|
|
{
|
|
title: 'Daftar Pasien',
|
|
link: '/patient',
|
|
icon: 'i-lucide-users',
|
|
},
|
|
{
|
|
title: 'Rawat Jalan',
|
|
link: '/outpatient/registration-queue',
|
|
icon: 'i-lucide-stethoscope',
|
|
},
|
|
{
|
|
title: 'Rawat Inap',
|
|
link: '/outpatient/registration-queue',
|
|
icon: 'i-lucide-hospital',
|
|
},
|
|
{
|
|
title: 'Rehabilitasi',
|
|
link: '/patient',
|
|
icon: 'i-lucide-heart',
|
|
},
|
|
]
|
|
|
|
onMounted(() => {
|
|
dataCard.value = {
|
|
totalRevenue: 45231.89,
|
|
totalRevenueDesc: 20.1 / 100,
|
|
subscriptions: 2350,
|
|
subscriptionsDesc: 180.5 / 100,
|
|
sales: 12234,
|
|
salesDesc: 45 / 100,
|
|
activeNow: 573,
|
|
activeNowDesc: 201,
|
|
}
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<div class="flex w-full flex-col gap-4">
|
|
<div class="mt-4 flex flex-wrap items-center justify-between gap-2">
|
|
<h2 class="text-2xl font-bold tracking-tight">Dashboard SIMRS</h2>
|
|
<div class="flex items-center gap-4 space-x-2">
|
|
<div class="rounded-xl border bg-primary p-1 text-white">Status: Aktif</div>
|
|
<Button class="bg-primary p-2 text-white" size="lg">
|
|
<Icon name="i-lucide-refresh-ccw" class="h-6 w-6" />
|
|
Sinkronisasi
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
<main class="my-6 flex flex-1 flex-col gap-4 md:gap-8">
|
|
<div class="dashboard-grid">
|
|
<PubBaseSummaryCard v-for="card in summaryData" :key="card.title" :stat="card" />
|
|
</div>
|
|
<div class="dashboard-grid">
|
|
<Card v-for="n in 3" :key="n">
|
|
<CardHeader>
|
|
<CardTitle>Recent Sales</CardTitle>
|
|
</CardHeader>
|
|
<CardContent class="grid gap-8">
|
|
<div v-for="recentSales in dataRecentSales" :key="recentSales.name" class="flex items-center gap-4">
|
|
<Avatar class="hidden h-9 w-9 sm:flex">
|
|
<AvatarFallback>{{
|
|
recentSales.name
|
|
.split(' ')
|
|
.map((n) => n[0])
|
|
.join('')
|
|
}}</AvatarFallback>
|
|
</Avatar>
|
|
<div class="grid gap-1">
|
|
<p class="text-sm font-medium leading-none">
|
|
{{ recentSales.name }}
|
|
</p>
|
|
<p class="text-sm text-muted-foreground">
|
|
{{ recentSales.email }}
|
|
</p>
|
|
</div>
|
|
<div class="ml-auto font-medium"></div>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
<div>
|
|
<Card>
|
|
<CardHeader>
|
|
<div class="flex flex-wrap items-center gap-2">
|
|
<Icon name="i-lucide-activity" class="me-2 h-6 w-6 text-primary" />
|
|
<h2 class="text-xl font-semibold tracking-tight">Aksi Cepat</h2>
|
|
</div>
|
|
</CardHeader>
|
|
<CardContent class="grid cursor-pointer gap-4 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 xl:gap-5">
|
|
<Card
|
|
v-for="item in linkItems"
|
|
:key="item.title"
|
|
class="my-2 h-32 border border-primary transition-colors duration-200 hover:bg-gray-200 hover:bg-primary"
|
|
>
|
|
<NuxtLink :to="item.link">
|
|
<CardContent class="my-2 grid h-full grid-rows-2 place-items-center">
|
|
<Icon :name="item.icon" class="h-9 w-[60px] text-primary" />
|
|
<h1>{{ item.title }}</h1>
|
|
</CardContent>
|
|
</NuxtLink>
|
|
</Card>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
</template>
|