365 lines
8.0 KiB
Vue
365 lines
8.0 KiB
Vue
<template>
|
|
<v-card-text class="pa-0 bg-white">
|
|
<v-table class="patient-table">
|
|
<!-- Table Body -->
|
|
<tbody>
|
|
<tr
|
|
v-for="patient in patients"
|
|
:key="patient.rm"
|
|
class="table-row"
|
|
:class="{ 'verified-row': patient.status === 'Terverifikasi' }"
|
|
>
|
|
<!-- Status Avatar -->
|
|
<td class="table-cell status-cell">
|
|
<div class="status-wrapper">
|
|
<v-avatar
|
|
:color="patient.status === 'Terverifikasi' ? 'secondary-600' : 'primary-600'"
|
|
size="48"
|
|
class="patient-avatar"
|
|
>
|
|
<v-icon size="24" color="white">
|
|
{{ patient.status === 'Terverifikasi' ? 'mdi-check-decagram' : 'mdi-clock-alert' }}
|
|
</v-icon>
|
|
</v-avatar>
|
|
</div>
|
|
</td>
|
|
|
|
<!-- Nama -->
|
|
<td class="table-cell">
|
|
<span class="patient-name">{{ patient.nama }}</span>
|
|
</td>
|
|
|
|
<!-- RM -->
|
|
<td class="table-cell">
|
|
<v-chip size="small" color="primary-200" class="chip-rm" variant="flat">
|
|
<v-icon start size="14" color="secondary-600">mdi-file-document</v-icon>
|
|
<span class="chip-rm-text">{{ patient.rm }}</span>
|
|
</v-chip>
|
|
</td>
|
|
|
|
<!-- Alamat -->
|
|
<td class="table-cell">
|
|
<div class="info-item">
|
|
<v-icon size="14" class="mr-2" color="neutral-600">mdi-map-marker</v-icon>
|
|
<span>{{ patient.alamat }}</span>
|
|
</div>
|
|
</td>
|
|
|
|
<!-- Nomor Telepon -->
|
|
<td class="table-cell">
|
|
<div class="info-item">
|
|
<v-icon size="14" class="mr-2" color="neutral-600">mdi-phone</v-icon>
|
|
<span>{{ patient.telepon || 'Belum diisi' }}</span>
|
|
</div>
|
|
</td>
|
|
|
|
<!-- Aksi -->
|
|
<td class="table-cell action-col">
|
|
<div class="action-wrapper">
|
|
<v-btn
|
|
v-if="patient.status === 'Belum Terverifikasi'"
|
|
variant="flat"
|
|
class="action-btn"
|
|
@click="$emit('verify', patient)"
|
|
>
|
|
<v-icon start size="16">mdi-qrcode-scan</v-icon>
|
|
VERIFIKASI
|
|
</v-btn>
|
|
|
|
<v-btn
|
|
v-else
|
|
color="secondary-600"
|
|
variant="flat"
|
|
class="verified-btn"
|
|
disabled
|
|
>
|
|
<v-icon start size="16">mdi-shield-check</v-icon>
|
|
VERIFIED
|
|
</v-btn>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
|
|
<!-- Empty State -->
|
|
<tr v-if="patients.length === 0">
|
|
<td colspan="6" class="empty-state-cell">
|
|
<div class="empty-state">{{ emptyMessage }}</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</v-table>
|
|
</v-card-text>
|
|
</template>
|
|
|
|
<script setup>
|
|
defineProps({
|
|
patients: {
|
|
type: Array,
|
|
required: true
|
|
},
|
|
emptyMessage: {
|
|
type: String,
|
|
default: 'Tidak ada data pasien'
|
|
}
|
|
});
|
|
|
|
defineEmits(['verify']);
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
$neutral-100: #FFFFFF;
|
|
$neutral-400: #E5F7FA;
|
|
$neutral-500: #ABBED1;
|
|
$neutral-600: #89939E;
|
|
$neutral-700: #717171;
|
|
$neutral-900: #212121;
|
|
$primary-100: #FFE8CC;
|
|
$primary-200: #FFDCAF;
|
|
$primary-600: #FFA532;
|
|
$primary-700: #FF9B1B;
|
|
$secondary-200: #EDF5FF;
|
|
$secondary-300: #DBEDFF;
|
|
$secondary-400: #B3D9FF;
|
|
$secondary-600: #0671E0;
|
|
$secondary-700: #0053AD;
|
|
$font-family-base: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
$font-weight-regular: 400;
|
|
$font-weight-semibold: 600;
|
|
$font-weight-bold: 700;
|
|
$font-weight-extra-bold: 800;
|
|
|
|
.patient-table {
|
|
font-family: $font-family-base;
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
table-layout: auto;
|
|
|
|
:deep(thead),
|
|
:deep(tbody),
|
|
:deep(tr) {
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
}
|
|
|
|
// ============================================
|
|
// TABLE HEADER
|
|
// ============================================
|
|
.table-header {
|
|
background-color: $neutral-400;
|
|
}
|
|
|
|
.header-cell {
|
|
padding: 16px 24px !important;
|
|
text-align: left;
|
|
font-weight: $font-weight-bold;
|
|
font-size: 14px;
|
|
color: $neutral-900;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.5px;
|
|
font-family: $font-family-base;
|
|
border-bottom: 2px solid $neutral-500;
|
|
vertical-align: middle;
|
|
|
|
&.status-header-hidden {
|
|
padding: 16px 24px !important;
|
|
width: 96px;
|
|
min-width: 96px;
|
|
max-width: 96px;
|
|
}
|
|
|
|
&.action-col {
|
|
text-align: right;
|
|
padding-right: 24px !important;
|
|
}
|
|
}
|
|
|
|
// ============================================
|
|
// TABLE BODY
|
|
// ============================================
|
|
.table-row {
|
|
transition: all 0.3s ease;
|
|
position: relative;
|
|
|
|
&:hover {
|
|
background-color: $primary-100 !important;
|
|
|
|
&::before {
|
|
transform: scaleY(1);
|
|
}
|
|
}
|
|
|
|
&::before {
|
|
content: '';
|
|
position: absolute;
|
|
left: 0;
|
|
top: 0;
|
|
height: 100%;
|
|
width: 4px;
|
|
background: $primary-600;
|
|
transform: scaleY(0);
|
|
transition: transform 0.3s ease;
|
|
}
|
|
}
|
|
|
|
.verified-row {
|
|
background-color: $secondary-200 !important;
|
|
|
|
&::before {
|
|
background: $secondary-600 !important;
|
|
}
|
|
|
|
&:hover {
|
|
background-color: $secondary-300 !important;
|
|
}
|
|
}
|
|
|
|
.table-cell {
|
|
padding: 16px 24px !important;
|
|
vertical-align: middle;
|
|
font-family: $font-family-base;
|
|
border-bottom: 1px solid $neutral-400;
|
|
|
|
&.status-cell {
|
|
text-align: center;
|
|
padding: 16px 24px !important;
|
|
width: 96px;
|
|
min-width: 96px;
|
|
max-width: 96px;
|
|
}
|
|
|
|
&.action-col {
|
|
text-align: right;
|
|
padding-right: 24px !important;
|
|
}
|
|
}
|
|
|
|
.status-wrapper {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
width: 100%;
|
|
}
|
|
|
|
.patient-avatar {
|
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
border: 3px solid $neutral-100;
|
|
margin: 0 auto;
|
|
}
|
|
|
|
.patient-name {
|
|
font-size: 18px;
|
|
font-weight: $font-weight-extra-bold;
|
|
color: $neutral-900;
|
|
font-family: $font-family-base;
|
|
}
|
|
|
|
.chip-rm {
|
|
border: 1px solid $secondary-400;
|
|
font-weight: $font-weight-bold;
|
|
}
|
|
|
|
.chip-rm-text {
|
|
color: $secondary-700;
|
|
font-weight: $font-weight-bold;
|
|
font-family: $font-family-base;
|
|
}
|
|
|
|
.info-item {
|
|
color: $neutral-700;
|
|
display: flex;
|
|
align-items: center;
|
|
font-size: 14px;
|
|
font-family: $font-family-base;
|
|
}
|
|
|
|
.action-wrapper {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: flex-end;
|
|
}
|
|
|
|
.action-btn {
|
|
background-color: $primary-700 !important;
|
|
text-transform: none;
|
|
letter-spacing: 0.5px;
|
|
font-weight: $font-weight-extra-bold;
|
|
font-size: 14px;
|
|
color: $neutral-100 !important;
|
|
padding: 8px 24px !important;
|
|
height: 40px !important;
|
|
min-width: 150px;
|
|
box-shadow: 0 4px 12px rgba(255, 155, 27, 0.4), 0 2px 6px rgba(255, 155, 27, 0.3);
|
|
font-family: $font-family-base;
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.action-btn:hover {
|
|
background-color: #E68A00 !important;
|
|
box-shadow: 0 6px 16px rgba(255, 155, 27, 0.5), 0 3px 8px rgba(255, 155, 27, 0.4);
|
|
transform: translateY(-2px);
|
|
}
|
|
|
|
.verified-btn {
|
|
text-transform: none;
|
|
letter-spacing: 0.5px;
|
|
font-weight: $font-weight-extra-bold;
|
|
font-size: 14px;
|
|
color: $neutral-100 !important;
|
|
padding: 8px 24px !important;
|
|
height: 40px !important;
|
|
min-width: 150px;
|
|
font-family: $font-family-base;
|
|
opacity: 1 !important;
|
|
}
|
|
|
|
.empty-state-cell {
|
|
padding: 40px 24px;
|
|
text-align: center;
|
|
}
|
|
|
|
.empty-state {
|
|
font-size: 18px;
|
|
color: $neutral-600;
|
|
font-weight: $font-weight-semibold;
|
|
font-family: $font-family-base;
|
|
}
|
|
|
|
// ============================================
|
|
// RESPONSIVE
|
|
// ============================================
|
|
@media (max-width: 960px) {
|
|
.patient-table {
|
|
display: block;
|
|
overflow-x: auto;
|
|
}
|
|
|
|
.table-cell {
|
|
padding: 20px 16px;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.header-cell {
|
|
padding: 12px 16px;
|
|
font-size: 12px;
|
|
}
|
|
|
|
.action-btn,
|
|
.verified-btn {
|
|
font-size: 12px;
|
|
}
|
|
|
|
.patient-avatar {
|
|
width: 44px !important;
|
|
height: 44px !important;
|
|
}
|
|
|
|
.patient-name {
|
|
font-size: 16px;
|
|
}
|
|
|
|
.info-item {
|
|
font-size: 12px;
|
|
}
|
|
}
|
|
</style> |