145 lines
5.7 KiB
Vue
145 lines
5.7 KiB
Vue
<script setup lang="ts">
|
|
import { getAntrianPerSpesialis } from '~/services/antrean';
|
|
import LoadingState from '@/components/shared/LoadingState.vue';
|
|
import { numberFormat } from '~/utils/helpers';
|
|
|
|
definePageMeta({
|
|
middleware: 'auth',
|
|
pageTitle: 'Antrean Operasi per Spesialis'
|
|
});
|
|
|
|
interface SubSpesialisData {
|
|
IdSubSpesialis: number;
|
|
SubSpesialis: string;
|
|
JmlAntrian: number;
|
|
}
|
|
|
|
interface SpesialisData {
|
|
IdSpesialis: number;
|
|
Spesialis: string;
|
|
JmlAntrian: number;
|
|
SubSpesialis: SubSpesialisData[];
|
|
}
|
|
|
|
const loading = ref(true);
|
|
const spesialisList = ref<SpesialisData[]>([]);
|
|
const expandedItems = ref<Set<number>>(new Set());
|
|
|
|
// Toggle expand/collapse for subspecialist details
|
|
const toggleExpand = (idSpesialis: number) => {
|
|
if (expandedItems.value.has(idSpesialis)) {
|
|
expandedItems.value.delete(idSpesialis);
|
|
} else {
|
|
expandedItems.value.add(idSpesialis);
|
|
}
|
|
};
|
|
|
|
const isExpanded = (idSpesialis: number) => {
|
|
return expandedItems.value.has(idSpesialis);
|
|
};
|
|
|
|
// Fetch data from API
|
|
const fetchData = async () => {
|
|
try {
|
|
loading.value = true;
|
|
const response = await getAntrianPerSpesialis();
|
|
|
|
if (response.success && response.data) {
|
|
spesialisList.value = response.data;
|
|
}
|
|
} catch (error) {
|
|
console.error('Error fetching antrian per spesialis:', error);
|
|
} finally {
|
|
loading.value = false;
|
|
}
|
|
};
|
|
|
|
// Load data on mount
|
|
onMounted(() => {
|
|
fetchData();
|
|
});
|
|
|
|
</script>
|
|
<template>
|
|
<LoadingState
|
|
:loading="loading"
|
|
:empty="spesialisList.length === 0 && !loading"
|
|
loading-text="Memuat data spesialis..."
|
|
empty-text="Tidak ada data antrian per spesialis"
|
|
>
|
|
<v-row>
|
|
<v-col
|
|
v-for="spesialis in spesialisList"
|
|
:key="spesialis.IdSpesialis"
|
|
cols="12"
|
|
md="4"
|
|
>
|
|
<v-card elevation="10" class="h-100">
|
|
<NuxtLink :to="`/antrean/spesialis/${spesialis.IdSpesialis}?spesialis=${encodeURIComponent(spesialis.Spesialis)}`" style="text-decoration: none; color: inherit;">
|
|
<v-card-item style="cursor: pointer;" class="v-card-item--link pa-5">
|
|
<div class="d-flex align-center justify-space-between">
|
|
<h5 class="text-h6 font-weight-bold">{{ spesialis.Spesialis }}</h5>
|
|
<v-icon size="large" color="primary">mdi-chevron-right</v-icon>
|
|
</div>
|
|
<v-chip class="mt-3 mb-0" color="primary" size="small">
|
|
{{ numberFormat(spesialis.JmlAntrian) }} Antrean
|
|
</v-chip>
|
|
</v-card-item>
|
|
</NuxtLink>
|
|
<v-divider></v-divider>
|
|
|
|
<!-- Collapsible Header -->
|
|
<div
|
|
@click="toggleExpand(spesialis.IdSpesialis)"
|
|
style="cursor: pointer;"
|
|
class="pa-5 d-flex align-center justify-space-between"
|
|
>
|
|
<v-label class="font-weight-medium text-subtitle-2">Sub Spesialis:</v-label>
|
|
<v-icon :class="{ 'rotate-180': isExpanded(spesialis.IdSpesialis) }" style="transition: transform 0.3s;">
|
|
mdi-chevron-down
|
|
</v-icon>
|
|
</div>
|
|
|
|
<!-- Collapsible Content -->
|
|
<v-expand-transition>
|
|
<v-card-text v-show="isExpanded(spesialis.IdSpesialis)" class="pa-5 pt-0 ">
|
|
<v-list density="compact" class="py-0">
|
|
<v-list-item
|
|
v-for="subSpesialis in spesialis.SubSpesialis"
|
|
:key="subSpesialis.IdSubSpesialis"
|
|
class="px-0"
|
|
:to="`/antrean/subspesialis/${subSpesialis.IdSubSpesialis}?subspecialis=${encodeURIComponent(subSpesialis.SubSpesialis || '')}&spesialis_id=${spesialis.IdSpesialis}`"
|
|
style="text-decoration: none; color: inherit;"
|
|
>
|
|
<template #prepend>
|
|
<v-icon size="small" color="primary">mdi-chevron-right</v-icon>
|
|
</template>
|
|
<v-list-item-title class="text-body-2">
|
|
{{ subSpesialis.SubSpesialis }}
|
|
</v-list-item-title>
|
|
<template #append>
|
|
<v-chip size="x-small" variant="outlined" color="primary">
|
|
{{ numberFormat(subSpesialis.JmlAntrian) }} Antrean
|
|
</v-chip>
|
|
</template>
|
|
</v-list-item>
|
|
|
|
<v-list-item v-if="!spesialis.SubSpesialis || spesialis.SubSpesialis.length === 0" class="px-0">
|
|
<v-list-item-title class="text-body-2 text-medium-emphasis">
|
|
Tidak ada sub spesialis
|
|
</v-list-item-title>
|
|
</v-list-item>
|
|
</v-list>
|
|
</v-card-text>
|
|
</v-expand-transition>
|
|
</v-card>
|
|
</v-col>
|
|
</v-row>
|
|
</LoadingState>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.rotate-180 {
|
|
transform: rotate(180deg);
|
|
}
|
|
</style> |