update header dan card dialog

This commit is contained in:
bagus-arie05
2026-01-21 09:56:07 +07:00
parent 08750087b1
commit fde71116ff
8 changed files with 195 additions and 223 deletions
+46 -31
View File
@@ -172,19 +172,17 @@
</v-expansion-panel-title>
<v-expansion-panel-text>
<div class="ruang-list">
<div class="ruang-card-grid">
<div
v-for="ruang in klinikRuang.ruangList"
:key="ruang.nomorRuang"
class="ruang-item"
class="ruang-card-item"
@click="buatAntreanKlinikRuang(klinikRuang, ruang)"
>
<v-icon color="warning" size="20">mdi-door</v-icon>
<div class="ruang-info">
<span class="body-3 text-semibold">Ruang {{ ruang.nomorRuang }} - {{ ruang.namaRuang }}</span>
<span class="caption-2 text-muted">Screen: {{ ruang.nomorScreen }}</span>
</div>
<v-icon size="20" color="grey">mdi-chevron-right</v-icon>
<v-icon color="warning" size="24" class="mb-2">mdi-door</v-icon>
<div class="ruang-card-name">Ruang {{ ruang.nomorRuang }}</div>
<div class="ruang-card-detail">{{ ruang.namaRuang }}</div>
<div class="ruang-card-screen">Screen: {{ ruang.nomorScreen }}</div>
</div>
</div>
</v-expansion-panel-text>
@@ -747,43 +745,60 @@ const buatAntreanKlinikRuang = async (klinikRuang, ruang) => {
align-items: center;
}
.ruang-list {
display: flex;
flex-direction: column;
gap: 8px;
.ruang-card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
gap: 12px;
padding: 8px 0;
}
.ruang-item {
.ruang-card-item {
display: flex;
flex-direction: column;
align-items: center;
gap: 12px;
padding: 12px 16px;
background: var(--color-neutral-300);
justify-content: center;
padding: 16px 12px;
background: var(--color-neutral-100);
border: 1px solid var(--color-neutral-400);
border-radius: 8px;
cursor: pointer;
transition: all 0.2s ease;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}
.ruang-item:hover {
border-color: var(--color-warning-600);
background: rgba(255, 185, 95, 0.15);
transform: translateY(-1px);
text-align: center;
min-height: 120px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.ruang-item:active {
transform: translateY(0);
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
.ruang-card-item:hover {
border-color: var(--color-warning-600);
background: var(--color-neutral-200);
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
}
.ruang-info {
flex: 1;
display: flex;
flex-direction: column;
gap: 2px;
.ruang-card-item:active {
transform: translateY(0);
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}
.ruang-card-name {
font-size: 14px;
line-height: 20px;
font-weight: 600;
color: var(--color-neutral-900);
margin-bottom: 4px;
}
.ruang-card-detail {
font-size: 12px;
line-height: 16px;
color: var(--color-neutral-700);
margin-bottom: 4px;
}
.ruang-card-screen {
font-size: 11px;
line-height: 14px;
color: var(--color-neutral-600);
}
@media (max-width: 960px) {
+2 -2
View File
@@ -234,8 +234,8 @@ const items = ref([
}
.header-logo {
width: 48px;
height: 48px;
width: 28px;
height: 28px;
object-fit: contain;
padding: 4px;
}
+76 -144
View File
@@ -1,45 +1,26 @@
<template>
<div class="anjungan-container" v-if="anjunganData">
<div v-if="anjunganData">
<div class="page-header">
<div class="header-icon">
<img
src="/Rumah_Sakit_Umum_Daerah_Dr._Saiful_Anwar.webp"
alt="RSUD Logo"
class="header-logo"
/>
</div>
<div class="header-content">
<div class="header-left">
<div class="header-icon">
<img
src="/Rumah_Sakit_Umum_Daerah_Dr._Saiful_Anwar.webp"
alt="RSUD Logo"
class="header-logo"
/>
</div>
<div class="header-text">
<h1 class="page-title">{{ anjunganData.namaAnjungan }}</h1>
<p class="page-subtitle">
Pilih Klinik untuk Pendaftaran - {{ anjunganData.jenisPasien }}
</p>
</div>
</div>
<div class="header-right">
<div class="info-guide">
<div class="guide-item">
<span class="guide-number">1</span>
<span class="guide-text"
>Pilih Poli (Hijau = Buka, Merah = Tutup)</span
>
</div>
<div class="guide-item">
<span class="guide-number">2</span>
<span class="guide-text"
>Pilih jenis pembayaran dan buat nomor antrian</span
>
</div>
</div>
</div>
<h1 class="page-title">{{ anjunganData.namaAnjungan }}</h1>
<p class="page-subtitle">
Pilih Klinik untuk Pendaftaran - {{ anjunganData.jenisPasien }}
</p>
</div>
</div>
<v-card elevation="0" class="main-content-card">
<v-card-text class="pa-6">
<v-row>
<v-col
<div class="anjungan-container">
<v-card elevation="0" class="main-content-card">
<v-card-text class="pa-6">
<v-row>
<v-col
v-for="clinic in filteredClinics"
:key="clinic.id"
cols="12"
@@ -65,7 +46,7 @@
<div class="doctor-info">
<v-icon
size="16"
size="14"
:color="
clinic.available
? 'var(--color-primary-600)'
@@ -79,7 +60,7 @@
<div class="schedule-info">
<v-icon
size="14"
size="12"
:color="
clinic.available
? 'var(--color-success-600)'
@@ -94,7 +75,7 @@
<div class="clinic-icon-wrapper">
<v-icon
:icon="clinic.icon"
size="40"
size="28"
:color="
clinic.available
? 'var(--color-success-600)'
@@ -108,7 +89,7 @@
</v-row>
<div v-if="filteredClinics.length === 0" class="empty-state">
<v-icon size="64" color="grey-lighten-1"
<v-icon size="48" color="grey-lighten-1"
>mdi-hospital-marker-outline</v-icon
>
<h3 class="empty-title">Tidak ada klinik yang sesuai</h3>
@@ -127,7 +108,7 @@
>
<v-card class="dialog-card">
<v-card-title class="dialog-header">
<v-icon class="mr-2">mdi-check-circle</v-icon>
<v-icon size="20" class="mr-2">mdi-check-circle</v-icon>
Konfirmasi Pilihan
</v-card-title>
@@ -136,7 +117,7 @@
<div class="dialog-icon mb-3">
<v-icon
:icon="selectedClinic.icon"
size="48"
size="32"
color="primary-600"
></v-icon>
</div>
@@ -167,17 +148,17 @@
block
@click="selectedDoctor = doctor"
>
<v-icon
v-if="selectedDoctor === doctor"
size="18"
<v-icon
v-if="selectedDoctor === doctor"
size="16"
color="success-600"
class="doctor-icon"
>
mdi-check-circle
</v-icon>
<v-icon
v-else
size="18"
<v-icon
v-else
size="16"
color="neutral-600"
class="doctor-icon"
>
@@ -202,7 +183,7 @@
class="doctor-info-item"
>
<div class="doctor-info-card">
<v-icon size="18" color="primary-600" class="doctor-info-icon">
<v-icon size="16" color="primary-600" class="doctor-info-icon">
mdi-doctor
</v-icon>
<span class="doctor-info-name">{{ doctor }}</span>
@@ -480,7 +461,7 @@
class="mb-3"
>
<template v-slot:prepend-inner>
<v-icon size="20" color="success-600">mdi-check-circle</v-icon>
<v-icon size="16" color="success-600">mdi-check-circle</v-icon>
</template>
</v-text-field>
</v-form>
@@ -594,7 +575,7 @@
<v-card-text class="pa-6">
<div v-if="lastRegisteredPatient" class="dialog-content">
<div class="text-center mb-4">
<v-icon size="64" color="primary-600" class="mb-3">mdi-ticket-confirmation</v-icon>
<v-icon size="48" color="primary-600" class="mb-3">mdi-ticket-confirmation</v-icon>
<h3 class="dialog-clinic-name mb-2">Tiket Berhasil Dibuat</h3>
<p class="text-body-2 text-grey mb-4">
Nomor antrean Anda: <strong>{{ lastRegisteredPatient.noAntrian?.split(" |")[0] || lastRegisteredPatient.noAntrian || 'N/A' }}</strong>
@@ -629,7 +610,7 @@
density="compact"
>
<template v-slot:prepend>
<v-icon>mdi-information</v-icon>
<v-icon size="20">mdi-information</v-icon>
</template>
<div class="text-body-2">
Cetak tiket ini untuk digunakan saat check-in. QR Code pada tiket dapat di-scan untuk proses check-in.
@@ -675,12 +656,13 @@
{{ snackbarText }}
<template v-slot:actions>
<v-btn icon @click="snackbar = false">
<v-icon>mdi-close</v-icon>
<v-icon size="20">mdi-close</v-icon>
</v-btn>
</template>
</v-snackbar>
</div>
</div>
<div v-else class="not-found">
<div v-if="!anjunganData" class="not-found">
<v-icon size="64" color="grey">mdi-alert-circle-outline</v-icon>
<p>Anjungan tidak ditemukan</p>
<v-btn color="primary" variant="flat" @click="backToList">Kembali</v-btn>
@@ -1349,116 +1331,66 @@ watch(lastRegisteredPatient, (newVal) => {
</script>
<style scoped lang="scss">
.page-header {
background: linear-gradient(135deg, var(--color-primary-600) 0%, var(--color-primary-700) 100%);
border-radius: 0 !important;
padding: 16px 28px;
margin-bottom: 0;
display: flex;
align-items: center;
gap: 16px;
height: 80px;
box-shadow: 0 4px 16px rgba(33, 150, 243, 0.2);
}
.anjungan-container {
background: var(--color-neutral-300);
min-height: 100vh;
min-height: calc(100vh - 80px);
padding: 16px;
overflow-y: auto;
}
.page-header {
background: linear-gradient(
135deg,
var(--color-primary-600) 0%,
var(--color-primary-700) 100%
);
border-radius: 12px;
margin-bottom: 16px;
box-shadow: 0 4px 16px rgba(255, 155, 27, 0.25);
}
.header-content {
display: flex;
align-items: center;
justify-content: space-between;
padding: 24px 40px;
flex: 1;
color: var(--color-neutral-100);
gap: 32px;
}
.header-left {
display: flex;
align-items: center;
gap: 24px;
}
.header-icon {
background: rgba(255, 255, 255, 0.95);
background: rgba(255, 255, 255, 0.9);
border-radius: 50%;
width: 80px;
height: 80px;
backdrop-filter: blur(10px);
padding: 6px;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
width: 40px;
height: 40px;
backdrop-filter: blur(10px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
.header-logo {
width: 64px;
height: 64px;
width: 28px;
height: 28px;
object-fit: contain;
padding: 4px;
}
.header-text {
flex: 1;
}
.page-title {
font-size: 48px;
font-weight: 800;
font-size: 32px;
font-weight: 600;
margin: 0;
color: var(--color-neutral-100);
letter-spacing: 2px;
text-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
line-height: 1;
line-height: 40px;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.page-subtitle {
margin: 6px 0 0 0;
opacity: 0.95;
font-size: 20px;
font-weight: 600;
font-size: 15px;
font-weight: 400;
margin: 2px 0 0 0;
color: var(--color-neutral-100);
}
.header-right {
display: flex;
align-items: center;
}
.info-guide {
display: flex;
flex-direction: column;
gap: 8px;
}
.guide-item {
display: flex;
align-items: center;
gap: 10px;
font-size: 14px;
line-height: 1.5;
}
.guide-number {
display: flex;
align-items: center;
justify-content: center;
width: 26px;
height: 26px;
background: rgba(255, 255, 255, 0.3);
border-radius: 50%;
font-weight: 700;
font-size: 14px;
flex-shrink: 0;
}
.guide-text {
color: var(--color-neutral-100);
font-weight: 600;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
opacity: 0.9;
line-height: 22px;
}
.main-content-card {
@@ -2005,13 +1937,13 @@ watch(lastRegisteredPatient, (newVal) => {
}
.header-icon {
width: 64px;
height: 64px;
width: 36px;
height: 36px;
}
.header-logo {
width: 52px;
height: 52px;
width: 24px;
height: 24px;
}
.clinic-card {
@@ -2042,13 +1974,13 @@ watch(lastRegisteredPatient, (newVal) => {
}
.header-icon {
width: 56px;
height: 56px;
width: 32px;
height: 32px;
}
.header-logo {
width: 44px;
height: 44px;
width: 20px;
height: 20px;
}
.clinic-card {
@@ -2065,7 +1997,7 @@ watch(lastRegisteredPatient, (newVal) => {
}
.clinic-icon-wrapper .v-icon {
font-size: 32px !important;
font-size: 24px !important;
}
.doctor-info,
+21 -16
View File
@@ -24,7 +24,7 @@
@click="navigateToAnjungan(anj.id)"
>
<div class="anjungan-card-header">
<v-icon size="32" color="primary">mdi-monitor</v-icon>
<v-icon size="28" color="primary">mdi-monitor</v-icon>
<div class="anjungan-info">
<h3 class="anjungan-name">{{ anj.namaAnjungan }}</h3>
<p class="anjungan-type">{{ anj.jenisPasien }}</p>
@@ -33,7 +33,7 @@
<div class="anjungan-klinik-preview">
<div class="klinik-count">
<v-icon size="18" color="secondary">mdi-hospital-box</v-icon>
<v-icon size="16" color="secondary">mdi-hospital-box</v-icon>
<span>{{ anj.klinik.length }} Klinik</span>
</div>
<div class="klinik-tags">
@@ -63,7 +63,7 @@
block
class="btn-view"
>
<v-icon left>mdi-eye</v-icon>
<v-icon left size="20">mdi-eye</v-icon>
Tampilkan
</v-btn>
</div>
@@ -71,7 +71,7 @@
</div>
<div v-if="anjunganList.length === 0" class="empty-state">
<v-icon size="64" color="grey-lighten-1">mdi-monitor-off</v-icon>
<v-icon size="48" color="grey-lighten-1">mdi-monitor-off</v-icon>
<h3>Tidak Ada Anjungan Tersedia</h3>
<p>Silakan tambah anjungan terlebih dahulu di halaman master</p>
<v-btn
@@ -80,7 +80,7 @@
@click="navigateToSettings"
class="mt-4"
>
<v-icon left>mdi-cog</v-icon>
<v-icon left size="20">mdi-cog</v-icon>
Ke Halaman Master Anjungan
</v-btn>
</div>
@@ -172,18 +172,21 @@ const navigateToSettings = () => {
}
.header-icon {
background: rgba(255, 255, 255, 0.2);
border-radius: 12px;
padding: 12px;
background: rgba(255, 255, 255, 0.9);
border-radius: 50%;
padding: 6px;
display: flex;
align-items: center;
justify-content: center;
width: 40px;
height: 40px;
backdrop-filter: blur(10px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
.header-logo {
width: 52px;
height: 52px;
width: 28px;
height: 28px;
object-fit: contain;
}
@@ -352,13 +355,15 @@ const navigateToSettings = () => {
}
.header-icon {
padding: 8px;
}
padding: 6px;
width: 40px;
height: 40px;
}
.header-logo {
width: 40px;
height: 40px;
}
.header-logo {
width: 24px;
height: 24px;
}
.main-title {
font-size: 20px;
+15 -10
View File
@@ -3,7 +3,7 @@
<div>
<div class="selection-header">
<div class="header-icon">
<v-icon size="64" color="white">mdi-ticket-account</v-icon>
<v-icon size="28" color="white">mdi-ticket-account</v-icon>
</div>
<div class="header-content">
<h1 class="main-title">Pilih Layar Antrean Masuk</h1>
@@ -20,7 +20,7 @@
@click="navigateToScreen(screen.id)"
>
<div class="screen-card-header">
<v-icon size="32" color="primary">mdi-monitor</v-icon>
<v-icon size="28" color="primary">mdi-monitor</v-icon>
<div class="screen-info">
<h3 class="screen-name">{{ screen.namaScreen }}</h3>
<p class="screen-details">{{ screen.nomorScreen }}</p>
@@ -29,7 +29,7 @@
<div class="screen-preview">
<div class="screen-loket-count">
<v-icon size="18" color="primary">mdi-view-dashboard</v-icon>
<v-icon size="16" color="primary">mdi-view-dashboard</v-icon>
<span>{{ screen.loket?.length || 0 }} Loket</span>
</div>
<div class="screen-tags">
@@ -59,7 +59,7 @@
block
class="btn-view text-white"
>
<v-icon left>mdi-eye</v-icon>
<v-icon left size="20">mdi-eye</v-icon>
Tampilkan
</v-btn>
</div>
@@ -67,7 +67,7 @@
</div>
<div v-else class="empty-state">
<v-icon size="64" color="grey-lighten-1">mdi-monitor-off</v-icon>
<v-icon size="48" color="grey-lighten-1">mdi-monitor-off</v-icon>
<h3>Tidak Ada Layar Tersedia</h3>
<p>Silakan tambah layar terlebih dahulu di halaman master</p>
<v-btn
@@ -76,7 +76,7 @@
class="mt-4"
@click="navigateToSettings"
>
<v-icon left>mdi-cog</v-icon>
<v-icon left size="20">mdi-cog</v-icon>
Ke Halaman Master
</v-btn>
</div>
@@ -167,13 +167,16 @@ const navigateToSettings = () => {
}
.header-icon {
background: rgba(255, 255, 255, 0.2);
border-radius: 12px;
padding: 12px;
background: rgba(255, 255, 255, 0.9);
border-radius: 50%;
padding: 6px;
display: flex;
align-items: center;
justify-content: center;
width: 40px;
height: 40px;
backdrop-filter: blur(10px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
.header-content {
@@ -341,7 +344,9 @@ const navigateToSettings = () => {
}
.header-icon {
padding: 8px;
padding: 6px;
width: 36px;
height: 36px;
}
.main-title {
+9 -4
View File
@@ -170,13 +170,16 @@ const navigateToSettings = () => {
}
.header-icon {
background: rgba(255, 255, 255, 0.2);
border-radius: 12px;
padding: 12px;
background: rgba(255, 255, 255, 0.9);
border-radius: 50%;
padding: 6px;
display: flex;
align-items: center;
justify-content: center;
width: 40px;
height: 40px;
backdrop-filter: blur(10px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
.header-content {
@@ -344,7 +347,9 @@ const navigateToSettings = () => {
}
.header-icon {
padding: 8px;
padding: 4px;
width: 36px;
height: 36px;
}
.main-title {
+13 -8
View File
@@ -199,18 +199,21 @@ const navigateToSettings = () => {
}
.header-icon {
background: rgba(255, 255, 255, 0.2);
border-radius: 12px;
padding: 12px;
background: rgba(255, 255, 255, 0.9);
border-radius: 50%;
padding: 6px;
display: flex;
align-items: center;
justify-content: center;
width: 40px;
height: 40px;
backdrop-filter: blur(10px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
.header-logo {
width: 52px;
height: 52px;
width: 28px;
height: 28px;
object-fit: contain;
}
@@ -379,12 +382,14 @@ const navigateToSettings = () => {
}
.header-icon {
padding: 8px;
padding: 4px;
width: 36px;
height: 36px;
}
.header-logo {
width: 40px;
height: 40px;
width: 24px;
height: 24px;
}
.main-title {
+13 -8
View File
@@ -181,18 +181,21 @@ const getKlinikName = (kode) => {
}
.header-icon {
background: rgba(255, 255, 255, 0.2);
border-radius: 12px;
padding: 12px;
background: rgba(255, 255, 255, 0.9);
border-radius: 50%;
padding: 6px;
display: flex;
align-items: center;
justify-content: center;
width: 40px;
height: 40px;
backdrop-filter: blur(10px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
.header-logo {
width: 52px;
height: 52px;
width: 28px;
height: 28px;
object-fit: contain;
}
@@ -361,12 +364,14 @@ const getKlinikName = (kode) => {
}
.header-icon {
padding: 8px;
padding: 4px;
width: 36px;
height: 36px;
}
.header-logo {
width: 40px;
height: 40px;
width: 24px;
height: 24px;
}
.main-title {