109 lines
3.3 KiB
Vue
109 lines
3.3 KiB
Vue
<script setup lang="ts">
|
|
import { Clock, LogIn, LogOut } from '@lucide/vue';
|
|
import { computed } from 'vue';
|
|
import { Badge } from '@/components/ui/badge';
|
|
import { Button } from '@/components/ui/button';
|
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
|
|
import type { TodayAttendance } from '@/types/attendance';
|
|
|
|
const props = defineProps<{
|
|
todayAttendance: TodayAttendance;
|
|
isOnLeave: boolean;
|
|
canCheckIn: boolean;
|
|
}>();
|
|
|
|
const emit = defineEmits<{
|
|
'check-in': [];
|
|
'check-out': [];
|
|
}>();
|
|
|
|
const canCheckInToday = computed(() => props.canCheckIn && props.todayAttendance === null && !props.isOnLeave);
|
|
const canCheckOutToday = computed(() => (
|
|
props.canCheckIn
|
|
&& !props.isOnLeave
|
|
&& props.todayAttendance !== null
|
|
&& props.todayAttendance.check_out_at === null
|
|
));
|
|
|
|
const todayStatusLabel = computed(() => {
|
|
if (props.isOnLeave) {
|
|
return 'Sedang cuti';
|
|
}
|
|
|
|
if (!props.todayAttendance) {
|
|
return 'Belum presensi';
|
|
}
|
|
|
|
if (props.todayAttendance.check_out_at) {
|
|
return 'Selesai';
|
|
}
|
|
|
|
return 'Sudah masuk';
|
|
});
|
|
|
|
const todayStatusVariant = computed(() => {
|
|
if (props.isOnLeave) {
|
|
return 'secondary' as const;
|
|
}
|
|
|
|
if (!props.todayAttendance) {
|
|
return 'secondary' as const;
|
|
}
|
|
|
|
if (props.todayAttendance.check_out_at) {
|
|
return 'default' as const;
|
|
}
|
|
|
|
return 'outline' as const;
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<Card v-if="canCheckIn">
|
|
<CardHeader>
|
|
<CardTitle class="flex items-center gap-2">
|
|
<Clock class="size-5" />
|
|
Presensi Hari Ini
|
|
</CardTitle>
|
|
<CardDescription>
|
|
Gunakan kamera perangkat untuk presensi masuk dan pulang.
|
|
</CardDescription>
|
|
</CardHeader>
|
|
<CardContent class="space-y-4">
|
|
<div class="flex flex-wrap items-center gap-3">
|
|
<Badge :variant="todayStatusVariant">
|
|
{{ todayStatusLabel }}
|
|
</Badge>
|
|
|
|
<span v-if="isOnLeave" class="text-muted-foreground text-sm">
|
|
Anda sedang dalam masa cuti. Presensi tidak diperlukan.
|
|
</span>
|
|
|
|
<span v-if="todayAttendance?.check_in_at_formatted" class="text-muted-foreground text-sm">
|
|
Masuk: {{ todayAttendance.check_in_at_formatted }}
|
|
</span>
|
|
|
|
<span v-if="todayAttendance?.check_out_at_formatted" class="text-muted-foreground text-sm">
|
|
Pulang: {{ todayAttendance.check_out_at_formatted }}
|
|
</span>
|
|
|
|
<span v-if="todayAttendance?.work_duration_formatted" class="text-muted-foreground text-sm">
|
|
Durasi: {{ todayAttendance.work_duration_formatted }}
|
|
</span>
|
|
</div>
|
|
|
|
<div class="flex flex-wrap gap-2">
|
|
<Button :disabled="!canCheckInToday" @click="emit('check-in')">
|
|
<LogIn class="size-4" />
|
|
Presensi Masuk
|
|
</Button>
|
|
|
|
<Button variant="outline" :disabled="!canCheckOutToday" @click="emit('check-out')">
|
|
<LogOut class="size-4" />
|
|
Presensi Pulang
|
|
</Button>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
</template>
|