Refactor AttendanceCalendar component for improved UI and code clarity. Remove unused status markup, streamline button components, and enhance badge styling for attendance statuses. Update CSS for better responsiveness and maintainability.

This commit is contained in:
Yoga Pangestu 2026-06-11 19:37:06 +07:00
parent f8322566da
commit f01a8a11a4

View File

@ -94,16 +94,11 @@ function renderEventContent(arg: EventContentArg) {
? `<span class="attendance-event__name">${escapeHtml(attendance.employee_name)}</span>` ? `<span class="attendance-event__name">${escapeHtml(attendance.employee_name)}</span>`
: ''; : '';
const statusMarkup = isComplete
? ''
: '<span class="attendance-event__status">Belum pulang</span>';
return { return {
html: ` html: `
<div class="attendance-event__inner"> <div class="attendance-event__inner">
${nameMarkup} ${nameMarkup}
<span class="attendance-event__time">${escapeHtml(timeLabel)}</span> <span class="attendance-event__time">${escapeHtml(timeLabel)}</span>
${statusMarkup}
</div> </div>
`, `,
}; };
@ -212,39 +207,21 @@ watch(
<div class="flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between"> <div class="flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
<div class="flex flex-wrap items-center gap-2"> <div class="flex flex-wrap items-center gap-2">
<div class="bg-muted/50 flex items-center rounded-lg border p-1 shadow-xs"> <div class="bg-muted/50 flex items-center rounded-lg border p-1 shadow-xs">
<Button <Button variant="ghost" size="icon-sm" aria-label="Bulan sebelumnya" @click="navigatePrev">
variant="ghost"
size="icon-sm"
aria-label="Bulan sebelumnya"
@click="navigatePrev"
>
<ChevronLeft class="size-4" /> <ChevronLeft class="size-4" />
</Button> </Button>
<Button <Button variant="ghost" size="sm" class="px-3" @click="navigateToday">
variant="ghost"
size="sm"
class="px-3"
@click="navigateToday"
>
Hari ini Hari ini
</Button> </Button>
<Button <Button variant="ghost" size="icon-sm" aria-label="Bulan berikutnya" @click="navigateNext">
variant="ghost"
size="icon-sm"
aria-label="Bulan berikutnya"
@click="navigateNext"
>
<ChevronRight class="size-4" /> <ChevronRight class="size-4" />
</Button> </Button>
</div> </div>
<DatePicker <DatePicker v-model="pickerDate" class="w-auto min-w-[13rem] sm:min-w-[15rem]"
v-model="pickerDate" placeholder="Pilih bulan" />
class="w-auto min-w-[13rem] sm:min-w-[15rem]"
placeholder="Pilih bulan"
/>
</div> </div>
<div class="flex flex-wrap items-center gap-2"> <div class="flex flex-wrap items-center gap-2">
@ -252,29 +229,25 @@ watch(
{{ calendarTitle }} {{ calendarTitle }}
</span> </span>
<Badge variant="outline" class="border-chart-2/50 bg-chart-2/15 text-chart-2 font-normal dark:text-chart-2"> <Badge variant="outline"
class="border-emerald-600/50 bg-emerald-500/15 font-normal text-emerald-700 dark:text-emerald-400">
Selesai Selesai
</Badge> </Badge>
<Badge variant="outline" class="border-amber-500/50 bg-amber-400 font-normal text-amber-950"> <Badge variant="outline" class="border-primary/50 bg-primary/20 font-normal text-primary-foreground">
Belum pulang Belum pulang
</Badge> </Badge>
</div> </div>
</div> </div>
<div <div :class="cn(
:class="cn( 'overflow-hidden rounded-xl border bg-background shadow-xs transition-opacity',
'overflow-hidden rounded-xl border bg-background shadow-xs transition-opacity', isNavigating && 'pointer-events-none opacity-60',
isNavigating && 'pointer-events-none opacity-60', )">
)"
>
<FullCalendar ref="calendarRef" :options="calendarOptions" /> <FullCalendar ref="calendarRef" :options="calendarOptions" />
</div> </div>
</div> </div>
<AttendanceDetailDialog <AttendanceDetailDialog v-model:open="detailOpen" :attendance="selectedAttendance" />
v-model:open="detailOpen"
:attendance="selectedAttendance"
/>
</template> </template>
<style> <style>
@ -293,7 +266,7 @@ watch(
border-radius: 0; border-radius: 0;
} }
.attendance-calendar .fc .fc-scrollgrid-section > td { .attendance-calendar .fc .fc-scrollgrid-section>td {
border: 0; border: 0;
} }
@ -406,16 +379,16 @@ watch(
.attendance-calendar .fc .attendance-event--complete, .attendance-calendar .fc .attendance-event--complete,
.attendance-calendar .fc .attendance-event--complete .fc-event-main { .attendance-calendar .fc .attendance-event--complete .fc-event-main {
background-color: var(--chart-2) !important; background-color: oklch(0.59 0.14 152) !important;
border-color: color-mix(in oklch, var(--chart-2) 70%, var(--foreground)) !important; border-color: oklch(0.52 0.12 152) !important;
color: oklch(0.99 0 0) !important; color: oklch(0.99 0 0) !important;
} }
.attendance-calendar .fc .attendance-event--active, .attendance-calendar .fc .attendance-event--active,
.attendance-calendar .fc .attendance-event--active .fc-event-main { .attendance-calendar .fc .attendance-event--active .fc-event-main {
background-color: oklch(0.79 0.16 75) !important; background-color: var(--primary) !important;
border-color: oklch(0.7 0.14 70) !important; border-color: color-mix(in oklch, var(--primary) 80%, var(--foreground)) !important;
color: oklch(0.32 0.07 55) !important; color: var(--primary-foreground) !important;
} }
.attendance-calendar .fc .attendance-event__inner { .attendance-calendar .fc .attendance-event__inner {
@ -460,21 +433,27 @@ watch(
.attendance-calendar .fc .attendance-event--active .attendance-event__time, .attendance-calendar .fc .attendance-event--active .attendance-event__time,
.attendance-calendar .fc .attendance-event--active .attendance-event__name, .attendance-calendar .fc .attendance-event--active .attendance-event__name,
.attendance-calendar .fc .attendance-event--active .attendance-event__status { .attendance-calendar .fc .attendance-event--active .attendance-event__status {
color: oklch(0.32 0.07 55); color: var(--primary-foreground);
opacity: 0.95; opacity: 0.95;
} }
.dark .attendance-calendar .fc .attendance-event--complete,
.dark .attendance-calendar .fc .attendance-event--complete .fc-event-main {
background-color: oklch(0.55 0.13 152) !important;
border-color: oklch(0.48 0.11 152) !important;
}
.dark .attendance-calendar .fc .attendance-event--active, .dark .attendance-calendar .fc .attendance-event--active,
.dark .attendance-calendar .fc .attendance-event--active .fc-event-main { .dark .attendance-calendar .fc .attendance-event--active .fc-event-main {
background-color: oklch(0.72 0.14 75) !important; background-color: var(--primary) !important;
border-color: oklch(0.64 0.12 70) !important; border-color: color-mix(in oklch, var(--primary) 75%, var(--foreground)) !important;
color: oklch(0.28 0.06 55) !important; color: var(--primary-foreground) !important;
} }
.dark .attendance-calendar .fc .attendance-event--active .attendance-event__time, .dark .attendance-calendar .fc .attendance-event--active .attendance-event__time,
.dark .attendance-calendar .fc .attendance-event--active .attendance-event__name, .dark .attendance-calendar .fc .attendance-event--active .attendance-event__name,
.dark .attendance-calendar .fc .attendance-event--active .attendance-event__status { .dark .attendance-calendar .fc .attendance-event--active .attendance-event__status {
color: oklch(0.28 0.06 55); color: var(--primary-foreground);
} }
@media (max-width: 640px) { @media (max-width: 640px) {