change color theme
This commit is contained in:
@@ -5,8 +5,15 @@ import sidebarItems from "~/components/layout/full/vertical-sidebar/sidebarItem"
|
||||
import Customizer from "~/components/layout/full/customizer/Customizer.vue";
|
||||
import { Menu2Icon } from "vue-tabler-icons";
|
||||
import { useCustomizerStore } from "~/store/customizer";
|
||||
import { usePendaftaranStore } from "~/store/pendaftaran";
|
||||
import { storeToRefs } from 'pinia';
|
||||
|
||||
const sidebarMenu = shallowRef(sidebarItems);
|
||||
const customizer = useCustomizerStore();
|
||||
const pendaftaranStore = usePendaftaranStore();
|
||||
|
||||
const { snackbar, snackbarMessage, snackbarColor } = storeToRefs(pendaftaranStore);
|
||||
|
||||
const { mdAndDown } = useDisplay();
|
||||
const sDrawer = ref(true);
|
||||
onMounted(() => {
|
||||
@@ -66,6 +73,24 @@ watch(mdAndDown, (val) => {
|
||||
<p class="text-caption textSecondary">© 2026 RSUD Dr. Saiful Anwar Provinsi Jawa Timur. All rights reserved.</p>
|
||||
</v-container>
|
||||
</v-main>
|
||||
|
||||
<!-- Global Snackbar -->
|
||||
<v-snackbar
|
||||
v-model="snackbar"
|
||||
:color="snackbarColor"
|
||||
:timeout="3000"
|
||||
location="top"
|
||||
>
|
||||
{{ snackbarMessage }}
|
||||
<template #actions>
|
||||
<v-btn
|
||||
variant="text"
|
||||
@click="pendaftaranStore.closeSnackbar()"
|
||||
>
|
||||
Close
|
||||
</v-btn>
|
||||
</template>
|
||||
</v-snackbar>
|
||||
</v-app>
|
||||
</v-locale-provider>
|
||||
</template>
|
||||
|
||||
@@ -59,7 +59,7 @@ const kategoriOperasiOptions = computed(() => {
|
||||
const fetchSubSpesialis = async (idSpesialis: number) => {
|
||||
try {
|
||||
isLoadingSubSpesialis.value = true;
|
||||
const response = await api.get(`/sub-spesialis?id_spesialis=${idSpesialis}`);
|
||||
const response = await api.get(`/reference/sub-spesialis?id_spesialis=${idSpesialis}`);
|
||||
|
||||
if (response.data.success && response.data.data) {
|
||||
subSpesialisList.value = response.data.data;
|
||||
@@ -86,7 +86,7 @@ watch(() => rencanaOperasiData.value.spesialis, (newSpesialis) => {
|
||||
const fetchSpesialis = async () => {
|
||||
try {
|
||||
isLoadingSpesialis.value = true;
|
||||
const response = await api.get('/spesialis');
|
||||
const response = await api.get('/reference/spesialis');
|
||||
|
||||
if (response.data.success && response.data.data) {
|
||||
spesialisList.value = response.data.data;
|
||||
@@ -103,7 +103,7 @@ const fetchSpesialis = async () => {
|
||||
const fetchKategoriOperasi = async () => {
|
||||
try {
|
||||
isLoadingKategori.value = true;
|
||||
const response = await api.get('/kategori');
|
||||
const response = await api.get('/reference/kategori');
|
||||
|
||||
if (response.data.success && response.data.data) {
|
||||
kategoriOperasiList.value = response.data.data;
|
||||
@@ -145,7 +145,7 @@ const fetchDokter = async () => {
|
||||
offset: offset.toString()
|
||||
});
|
||||
|
||||
const response = await api.get(`/dokter?${params}`);
|
||||
const response = await api.get(`/reference/dokter?${params}`);
|
||||
|
||||
if (response.data.success && response.data.data) {
|
||||
dokterList.value = response.data.data;
|
||||
|
||||
@@ -72,78 +72,143 @@ watch(itemsPerPageLocal, (newVal) => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="table-wrapper">
|
||||
<v-data-table-server
|
||||
:headers="headers"
|
||||
:items="items"
|
||||
:items-length="serverSide ? totalItems : 0"
|
||||
v-model:page="page"
|
||||
v-model:items-per-page="itemsPerPageLocal"
|
||||
:search="serverSide ? undefined : search"
|
||||
class="elevation-1"
|
||||
item-value="id"
|
||||
>
|
||||
<!-- Pass through all slots to parent -->
|
||||
<template v-for="(_, name) in $slots" v-slot:[name]="slotData">
|
||||
<slot :name="name" v-bind="slotData" />
|
||||
</template>
|
||||
|
||||
<!-- Default slot for Jenis Kelamin if not provided -->
|
||||
<template #item.JenisKelamin="{ item }">
|
||||
<slot name="item.JenisKelamin" :item="item">
|
||||
<v-chip
|
||||
:color="item.JenisKelamin === 'L' ? 'primary' : 'error'"
|
||||
size="small"
|
||||
>
|
||||
{{ item.JenisKelamin }}
|
||||
</v-chip>
|
||||
</slot>
|
||||
</template>
|
||||
|
||||
<!-- Default slot for Status if not provided -->
|
||||
<template #item.StatusOperasi="{ item }">
|
||||
<slot name="item.StatusOperasi" :item="item">
|
||||
<v-chip
|
||||
:color="getStatusColor(item.StatusOperasi)"
|
||||
size="small"
|
||||
>
|
||||
{{ getStatusText(item.StatusOperasi) }}
|
||||
</v-chip>
|
||||
</slot>
|
||||
</template>
|
||||
|
||||
<!-- Action slot if enabled -->
|
||||
<template v-if="actions && actions.length > 0" #item.actions="{ item }">
|
||||
<slot name="item.actions" :item="item">
|
||||
<div class="d-flex ga-2">
|
||||
<v-btn
|
||||
v-for="(action, index) in actions"
|
||||
:key="index"
|
||||
icon
|
||||
<div class="table-container">
|
||||
<div class="table-wrapper">
|
||||
<v-data-table-server
|
||||
:headers="headers"
|
||||
:items="items"
|
||||
:items-length="serverSide ? totalItems : 0"
|
||||
v-model:page="page"
|
||||
v-model:items-per-page="itemsPerPageLocal"
|
||||
:search="serverSide ? undefined : search"
|
||||
class="elevation-1"
|
||||
item-value="id"
|
||||
hide-default-footer
|
||||
>
|
||||
<!-- Pass through all slots to parent -->
|
||||
<template v-for="(_, name) in $slots" v-slot:[name]="slotData">
|
||||
<slot :name="name" v-bind="slotData" />
|
||||
</template>
|
||||
|
||||
<!-- Default slot for Jenis Kelamin if not provided -->
|
||||
<template #item.JenisKelamin="{ item }">
|
||||
<slot name="item.JenisKelamin" :item="item">
|
||||
<v-chip
|
||||
:color="item.JenisKelamin === 'L' ? 'primary' : 'error'"
|
||||
size="small"
|
||||
variant="text"
|
||||
:color="action.color || 'primary'"
|
||||
@click="handleAction(action.event, item)"
|
||||
>
|
||||
<v-icon>{{ action.icon }}</v-icon>
|
||||
<v-tooltip v-if="action.tooltip" activator="parent" location="top">
|
||||
{{ action.tooltip }}
|
||||
</v-tooltip>
|
||||
</v-btn>
|
||||
</div>
|
||||
</slot>
|
||||
</template>
|
||||
</v-data-table-server>
|
||||
{{ item.JenisKelamin }}
|
||||
</v-chip>
|
||||
</slot>
|
||||
</template>
|
||||
|
||||
<!-- Default slot for Status if not provided -->
|
||||
<template #item.StatusOperasi="{ item }">
|
||||
<slot name="item.StatusOperasi" :item="item">
|
||||
<v-chip
|
||||
:color="getStatusColor(item.StatusOperasi)"
|
||||
size="small"
|
||||
>
|
||||
{{ getStatusText(item.StatusOperasi) }}
|
||||
</v-chip>
|
||||
</slot>
|
||||
</template>
|
||||
|
||||
<!-- Action slot if enabled -->
|
||||
<template v-if="actions && actions.length > 0" #item.actions="{ item }">
|
||||
<slot name="item.actions" :item="item">
|
||||
<div class="d-flex ga-2">
|
||||
<v-btn
|
||||
v-for="(action, index) in actions"
|
||||
:key="index"
|
||||
icon
|
||||
size="small"
|
||||
variant="text"
|
||||
:color="action.color || 'primary'"
|
||||
@click="handleAction(action.event, item)"
|
||||
>
|
||||
<v-icon>{{ action.icon }}</v-icon>
|
||||
<v-tooltip v-if="action.tooltip" activator="parent" location="top">
|
||||
{{ action.tooltip }}
|
||||
</v-tooltip>
|
||||
</v-btn>
|
||||
</div>
|
||||
</slot>
|
||||
</template>
|
||||
</v-data-table-server>
|
||||
</div>
|
||||
|
||||
<!-- Custom pagination footer - fixed and on the left -->
|
||||
<div class="pagination-footer">
|
||||
<div class="pagination-info">
|
||||
<span class="text-caption">
|
||||
Showing {{ ((page - 1) * itemsPerPageLocal) + 1 }} to {{ Math.min(page * itemsPerPageLocal, serverSide ? totalItems : items.length) }} of {{ serverSide ? totalItems : items.length }} entries
|
||||
</span>
|
||||
</div>
|
||||
<div class="pagination-controls">
|
||||
<v-select
|
||||
v-model="itemsPerPageLocal"
|
||||
:items="[10, 25, 50, 100]"
|
||||
density="compact"
|
||||
variant="outlined"
|
||||
hide-details
|
||||
style="max-width: 100px;"
|
||||
label="Rows"
|
||||
></v-select>
|
||||
<v-pagination
|
||||
v-model="page"
|
||||
:length="Math.ceil((serverSide ? totalItems : items.length) / itemsPerPageLocal)"
|
||||
:total-visible="5"
|
||||
density="comfortable"
|
||||
></v-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.table-container {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.table-wrapper {
|
||||
overflow-x: auto;
|
||||
width: 100%;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.table-wrapper :deep(.v-data-table) {
|
||||
min-width: v-bind(minWidth);
|
||||
}
|
||||
|
||||
.pagination-footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 12px 16px;
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.12);
|
||||
background-color: white;
|
||||
position: sticky;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.pagination-info {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.pagination-controls {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
/* Dark theme support */
|
||||
:deep(.v-theme--dark) .pagination-footer {
|
||||
border-top-color: rgba(255, 255, 255, 0.12);
|
||||
background-color: rgb(30, 30, 30);
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user