update header

This commit is contained in:
bagus-arie05
2026-01-21 12:58:50 +07:00
parent fde71116ff
commit 531ca100ac
8 changed files with 626 additions and 411 deletions
+42 -16
View File
@@ -5,31 +5,35 @@
<div class="header-content">
<div class="header-left">
<div class="header-icon">
<v-icon size="32" color="white">mdi-heart-pulse</v-icon>
<v-icon size="28" color="white">mdi-heart-pulse</v-icon>
</div>
<div class="header-text">
<h2 class="page-title">Monitoring Pasien</h2>
<p class="page-subtitle">{{ currentDate }} - Manajemen Data Pasien</p>
</div>
</div>
<div class="header-stats">
<v-chip color="white" variant="flat" class="stat-chip mr-2">
</div>
</div>
<v-container>
<!-- Action Bar -->
<div class="action-bar mb-4">
<div class="action-bar-left">
<v-chip color="primary" variant="tonal" class="stat-chip mr-2">
<v-icon start size="16">mdi-account-group</v-icon>
{{ totalCount }} Total
</v-chip>
<v-chip color="white" variant="flat" class="stat-chip mr-2">
<v-chip color="warning" variant="tonal" class="stat-chip mr-2">
<v-icon start size="16">mdi-clock-outline</v-icon>
{{ waitingCount }} Menunggu
</v-chip>
<v-chip color="white" variant="flat" class="stat-chip">
<v-chip color="success" variant="tonal" class="stat-chip">
<v-icon start size="16">mdi-check-circle</v-icon>
{{ doneCount }} Selesai
</v-chip>
</div>
</div>
</div>
<v-container>
<v-card>
<!-- Status Filter Section -->
<v-card-text class="filter-section-top">
@@ -410,7 +414,8 @@ $font-weight-semibold: 600;
display: flex;
align-items: center;
justify-content: space-between;
padding: 32px;
padding: 16px 28px;
height: 80px;
color: $neutral-100;
}
@@ -421,15 +426,15 @@ $font-weight-semibold: 600;
.header-icon {
background: rgba(255, 255, 255, 0.2);
border-radius: 16px;
padding: 16px;
margin-right: 20px;
border-radius: 12px;
padding: 12px;
margin-right: 16px;
backdrop-filter: blur(10px);
}
.page-title {
font-size: 36px;
line-height: 44px;
font-size: 32px;
line-height: 40px;
font-weight: $font-weight-semibold;
margin: 0;
color: $neutral-100;
@@ -437,10 +442,10 @@ $font-weight-semibold: 600;
}
.page-subtitle {
margin: 4px 0 0 0;
margin: 2px 0 0 0;
opacity: 0.9;
font-size: 16px;
line-height: 24px;
font-size: 15px;
line-height: 22px;
font-weight: $font-weight-regular;
color: $neutral-100;
}
@@ -458,6 +463,27 @@ $font-weight-semibold: 600;
line-height: 20px;
}
// ============================================
// ACTION BAR
// ============================================
.action-bar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px 20px;
background: $neutral-100;
border-radius: 12px;
border: 1px solid $neutral-400;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}
.action-bar-left {
display: flex;
align-items: center;
gap: 8px;
flex-wrap: wrap;
}
// ============================================
// FILTER SECTION TOP
// ============================================
+76 -40
View File
@@ -1,5 +1,21 @@
<template>
<div class="hak-akses-page pa-4">
<div>
<!-- Header -->
<div class="page-header">
<div class="header-content">
<div class="header-left">
<div class="header-icon">
<v-icon size="28" color="white">mdi-shield-lock-outline</v-icon>
</div>
<div class="header-text">
<h2 class="page-title">Hak Akses</h2>
<p class="page-subtitle">{{ new Date().toLocaleDateString('id-ID', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }) }} - Manajemen Hak Akses</p>
</div>
</div>
</div>
</div>
<div class="hak-akses-page pa-4">
<!-- Dialog for Add/Edit Form -->
<v-dialog
v-model="showAddEditDialog"
@@ -479,37 +495,26 @@
<!-- Main Table View - Always visible, dialog overlays it -->
<div>
<v-card class="rounded-xl elevation-2" style="background-color: white;">
<!-- Header -->
<div class="page-header">
<div class="header-content">
<div class="header-left">
<div class="header-icon">
<v-icon size="32" color="white">mdi-shield-lock-outline</v-icon>
</div>
<div class="header-text">
<h2 class="page-title">Hak Akses</h2>
<p class="page-subtitle">{{ new Date().toLocaleDateString('id-ID', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }) }} - Manajemen Hak Akses</p>
</div>
</div>
<div class="header-stats">
<v-chip color="white" variant="flat" class="stat-chip mr-2">
<v-icon start size="16">mdi-account-group</v-icon>
{{ filteredHakAksesData.length }} User
</v-chip>
<v-btn
color="white"
@click="showAddForm"
elevation="0"
class="add-btn"
>
<v-icon left size="20">mdi-plus-circle</v-icon>
Tambah Baru
</v-btn>
</div>
</div>
<!-- Action Bar -->
<div class="action-bar mb-4">
<div class="action-bar-left">
<v-chip color="primary" variant="tonal" class="stat-chip mr-2">
<v-icon start size="16">mdi-account-group</v-icon>
{{ filteredHakAksesData.length }} User
</v-chip>
</div>
<v-btn
color="primary"
@click="showAddForm"
elevation="0"
class="action-btn"
>
<v-icon left size="20">mdi-plus-circle</v-icon>
Tambah Baru
</v-btn>
</div>
<v-card class="rounded-xl elevation-2" style="background-color: white;">
<!-- Table -->
<v-card-text>
<div class="d-flex flex-column flex-sm-row align-center justify-space-between mb-4">
@@ -701,6 +706,7 @@
</v-btn>
</template>
</v-snackbar>
</div>
</div>
</template>
@@ -1722,7 +1728,7 @@ $font-weight-semibold: 600;
// ============================================
.page-header {
background: linear-gradient(135deg, $primary-600 0%, $primary-700 100%);
border-radius: 16px 16px 0 0;
border-radius: 0 !important;
box-shadow: 0 4px 16px rgba(58, 97, 201, 0.2);
}
@@ -1730,7 +1736,8 @@ $font-weight-semibold: 600;
display: flex;
align-items: center;
justify-content: space-between;
padding: 32px;
padding: 16px 28px;
height: 80px;
color: $neutral-100;
}
@@ -1741,15 +1748,15 @@ $font-weight-semibold: 600;
.header-icon {
background: rgba(255, 255, 255, 0.2);
border-radius: 16px;
padding: 16px;
margin-right: 20px;
border-radius: 12px;
padding: 12px;
margin-right: 16px;
backdrop-filter: blur(10px);
}
.page-title {
font-size: 36px;
line-height: 44px;
font-size: 32px;
line-height: 40px;
font-weight: $font-weight-semibold;
margin: 0;
color: $neutral-100;
@@ -1757,10 +1764,10 @@ $font-weight-semibold: 600;
}
.page-subtitle {
margin: 4px 0 0 0;
margin: 2px 0 0 0;
opacity: 0.9;
font-size: 16px;
line-height: 24px;
font-size: 15px;
line-height: 22px;
font-weight: $font-weight-regular;
color: $neutral-100;
}
@@ -1787,6 +1794,35 @@ $font-weight-semibold: 600;
color: $primary-600 !important;
}
// ============================================
// ACTION BAR
// ============================================
.action-bar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px 20px;
background: $neutral-100;
border-radius: 12px;
border: 1px solid $neutral-400;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}
.action-bar-left {
display: flex;
align-items: center;
gap: 8px;
flex-wrap: wrap;
}
.action-btn {
font-weight: $font-weight-semibold;
text-transform: none;
letter-spacing: 0.5px;
font-size: 16px;
line-height: 24px;
}
// ============================================
// DATA TABLE
// ============================================
+38 -10
View File
@@ -4,26 +4,31 @@
<div class="header-content">
<div class="header-left">
<div class="header-icon">
<v-icon size="32" color="white">mdi-monitor-dashboard</v-icon>
<v-icon size="28" color="white">mdi-monitor-dashboard</v-icon>
</div>
<div class="header-text">
<h2 class="page-title">Master Anjungan</h2>
<p class="page-subtitle">Kelola anjungan dan klinik yang ditampilkan</p>
</div>
</div>
</div>
</div>
<v-container>
<!-- Action Bar -->
<div class="action-bar mb-4">
<v-spacer></v-spacer>
<v-btn
color="white"
color="primary"
@click="openTambahDialog"
elevation="0"
class="add-btn"
class="action-btn"
>
<v-icon left size="20">mdi-plus-circle</v-icon>
Tambah Anjungan
</v-btn>
</div>
</div>
<v-container>
<v-card>
<v-card-text>
<v-data-table
@@ -421,7 +426,8 @@ $font-weight-semibold: 600;
display: flex;
align-items: center;
justify-content: space-between;
padding: 32px;
padding: 16px 28px;
height: 80px;
color: $neutral-100;
}
@@ -432,9 +438,9 @@ $font-weight-semibold: 600;
.header-icon {
background: rgba(255, 255, 255, 0.2);
border-radius: 16px;
padding: 16px;
margin-right: 20px;
border-radius: 12px;
padding: 12px;
margin-right: 16px;
backdrop-filter: blur(10px);
}
@@ -447,7 +453,7 @@ $font-weight-semibold: 600;
}
.page-subtitle {
margin: 4px 0 0 0;
margin: 2px 0 0 0;
opacity: 0.9;
font-size: 15px;
line-height: 22px;
@@ -464,6 +470,28 @@ $font-weight-semibold: 600;
color: $secondary-600 !important;
}
// ============================================
// ACTION BAR
// ============================================
.action-bar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px 20px;
background: $neutral-100;
border-radius: 12px;
border: 1px solid $neutral-400;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}
.action-btn {
font-weight: $font-weight-semibold;
text-transform: none;
letter-spacing: 0.5px;
font-size: 16px;
line-height: 24px;
}
.data-table {
font-family: $font-family-base;
}
+42 -14
View File
@@ -6,26 +6,31 @@
<div class="header-content">
<div class="header-left">
<div class="header-icon">
<v-icon size="32" color="white">mdi-hospital-building</v-icon>
<v-icon size="28" color="white">mdi-hospital-building</v-icon>
</div>
<div class="header-text">
<h2 class="page-title">Master Klinik</h2>
<p class="page-subtitle">Rabu, 13 Agustus 2025 - Manajemen Klinik</p>
</div>
</div>
</div>
</div>
<v-container>
<!-- Action Bar -->
<div class="action-bar mb-4">
<v-spacer></v-spacer>
<v-btn
color="white"
color="primary"
elevation="0"
class="add-btn"
class="action-btn"
@click="openTambahDialog"
>
<v-icon left size="20">mdi-plus-circle</v-icon>
Tambah Klinik
</v-btn>
</div>
</div>
<v-container>
<v-card>
<!-- Table -->
<v-card-text>
@@ -722,7 +727,8 @@ $font-weight-bold: 700;
display: flex;
align-items: center;
justify-content: space-between;
padding: 32px;
padding: 16px 28px;
height: 80px;
color: $neutral-100;
}
@@ -733,15 +739,15 @@ $font-weight-bold: 700;
.header-icon {
background: rgba(255, 255, 255, 0.2);
border-radius: 16px;
padding: 16px;
margin-right: 20px;
border-radius: 12px;
padding: 12px;
margin-right: 16px;
backdrop-filter: blur(10px);
}
.page-title {
font-size: 36px;
line-height: 44px;
font-size: 32px;
line-height: 40px;
font-weight: $font-weight-semibold;
margin: 0;
color: $neutral-100;
@@ -749,10 +755,10 @@ $font-weight-bold: 700;
}
.page-subtitle {
margin: 4px 0 0 0;
margin: 2px 0 0 0;
opacity: 0.9;
font-size: 16px;
line-height: 24px;
font-size: 15px;
line-height: 22px;
font-weight: $font-weight-regular;
color: $neutral-100;
}
@@ -766,6 +772,28 @@ $font-weight-bold: 700;
color: $primary-600 !important;
}
// ============================================
// ACTION BAR
// ============================================
.action-bar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px 20px;
background: $neutral-100;
border-radius: 12px;
border: 1px solid $neutral-400;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}
.action-btn {
font-weight: $font-weight-semibold;
text-transform: none;
letter-spacing: 0.5px;
font-size: 16px;
line-height: 24px;
}
// ============================================
// DATA TABLE
// ============================================
+63 -29
View File
@@ -5,36 +5,40 @@
<div class="header-content">
<div class="header-left">
<div class="header-icon">
<v-icon size="32" color="white">mdi-door-open</v-icon>
<v-icon size="28" color="white">mdi-door-open</v-icon>
</div>
<div class="header-text">
<h2 class="page-title">Master Klinik Ruang</h2>
<p class="page-subtitle">Rabu, 13 Agustus 2025 - Manajemen Ruangan</p>
</div>
</div>
<div class="header-stats">
<v-chip color="white" variant="flat" class="stat-chip mr-2">
<v-icon start size="16">mdi-hospital-building</v-icon>
{{ masterStore.totalKlinikRuang }} Klinik
</v-chip>
<v-chip color="white" variant="flat" class="stat-chip mr-2">
<v-icon start size="16">mdi-door</v-icon>
{{ masterStore.totalRuangan }} Ruang
</v-chip>
<v-btn
color="white"
@click="openTambahDialog"
elevation="0"
class="add-btn"
>
<v-icon left size="20">mdi-plus-circle</v-icon>
Tambah Ruang
</v-btn>
</div>
</div>
</div>
<v-container>
<!-- Action Bar -->
<div class="action-bar mb-4">
<div class="action-bar-left">
<v-chip color="primary" variant="tonal" class="stat-chip mr-2">
<v-icon start size="16">mdi-hospital-building</v-icon>
{{ masterStore.totalKlinikRuang }} Klinik
</v-chip>
<v-chip color="primary" variant="tonal" class="stat-chip mr-2">
<v-icon start size="16">mdi-door</v-icon>
{{ masterStore.totalRuangan }} Ruang
</v-chip>
</div>
<v-btn
color="primary"
@click="openTambahDialog"
elevation="0"
class="action-btn"
>
<v-icon left size="20">mdi-plus-circle</v-icon>
Tambah Ruang
</v-btn>
</div>
<v-card>
<!-- Table -->
<v-card-text>
@@ -469,7 +473,8 @@ $font-weight-semibold: 600;
display: flex;
align-items: center;
justify-content: space-between;
padding: 32px;
padding: 16px 28px;
height: 80px;
color: $neutral-100;
}
@@ -480,15 +485,15 @@ $font-weight-semibold: 600;
.header-icon {
background: rgba(255, 255, 255, 0.2);
border-radius: 16px;
padding: 16px;
margin-right: 20px;
border-radius: 12px;
padding: 12px;
margin-right: 16px;
backdrop-filter: blur(10px);
}
.page-title {
font-size: 36px;
line-height: 44px;
font-size: 32px;
line-height: 40px;
font-weight: $font-weight-semibold;
margin: 0;
color: $neutral-100;
@@ -496,10 +501,10 @@ $font-weight-semibold: 600;
}
.page-subtitle {
margin: 4px 0 0 0;
margin: 2px 0 0 0;
opacity: 0.9;
font-size: 16px;
line-height: 24px;
font-size: 15px;
line-height: 22px;
font-weight: $font-weight-regular;
color: $neutral-100;
}
@@ -526,6 +531,35 @@ $font-weight-semibold: 600;
color: $primary-600 !important;
}
// ============================================
// ACTION BAR
// ============================================
.action-bar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px 20px;
background: $neutral-100;
border-radius: 12px;
border: 1px solid $neutral-400;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}
.action-bar-left {
display: flex;
align-items: center;
gap: 8px;
flex-wrap: wrap;
}
.action-btn {
font-weight: $font-weight-semibold;
text-transform: none;
letter-spacing: 0.5px;
font-size: 16px;
line-height: 24px;
}
// ============================================
// DATA TABLE
// ============================================
+42 -14
View File
@@ -6,26 +6,31 @@
<div class="header-content">
<div class="header-left">
<div class="header-icon">
<v-icon size="32" color="white">mdi-view-dashboard</v-icon>
<v-icon size="28" color="white">mdi-view-dashboard</v-icon>
</div>
<div class="header-text">
<h2 class="page-title">Master Loket</h2>
<p class="page-subtitle">Rabu, 13 Agustus 2025 - Pelayanan</p>
</div>
</div>
</div>
</div>
<v-container>
<!-- Action Bar -->
<div class="action-bar mb-4">
<v-spacer></v-spacer>
<v-btn
color="white"
color="primary"
elevation="0"
class="add-btn"
class="action-btn"
@click="openTambahDialog"
>
<v-icon left size="20">mdi-plus-circle</v-icon>
Tambah Loket
</v-btn>
</div>
</div>
<v-container>
<v-card>
<!-- Table -->
<v-card-text>
@@ -406,7 +411,8 @@ $font-weight-semibold: 600;
display: flex;
align-items: center;
justify-content: space-between;
padding: 32px;
padding: 16px 28px;
height: 80px;
color: $neutral-100;
}
@@ -417,15 +423,15 @@ $font-weight-semibold: 600;
.header-icon {
background: rgba(255, 255, 255, 0.2);
border-radius: 16px;
padding: 16px;
margin-right: 20px;
border-radius: 12px;
padding: 12px;
margin-right: 16px;
backdrop-filter: blur(10px);
}
.page-title {
font-size: 36px;
line-height: 44px;
font-size: 32px;
line-height: 40px;
font-weight: $font-weight-semibold;
margin: 0;
color: $neutral-100;
@@ -433,10 +439,10 @@ $font-weight-semibold: 600;
}
.page-subtitle {
margin: 4px 0 0 0;
margin: 2px 0 0 0;
opacity: 0.9;
font-size: 16px;
line-height: 24px;
font-size: 15px;
line-height: 22px;
font-weight: $font-weight-regular;
color: $neutral-100;
}
@@ -450,6 +456,28 @@ $font-weight-semibold: 600;
color: $primary-600 !important;
}
// ============================================
// ACTION BAR
// ============================================
.action-bar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px 20px;
background: $neutral-100;
border-radius: 12px;
border: 1px solid $neutral-400;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}
.action-btn {
font-weight: $font-weight-semibold;
text-transform: none;
letter-spacing: 0.5px;
font-size: 16px;
line-height: 24px;
}
// ============================================
// DATA TABLE
// ============================================
+322 -287
View File
@@ -1,285 +1,289 @@
<template>
<div class="user-login-page pa-4">
<v-alert
v-if="fetchError"
type="error"
variant="tonal"
class="mb-4"
icon="mdi-alert-circle-outline"
>
Failed to load initial data: {{ fetchError.message }}. Check your API connections.
</v-alert>
<!-- Form Dialog Popup -->
<v-dialog v-model="showForm" max-width="950px" :persistent="!readOnly" scrollable>
<v-card class="rounded-lg overflow-hidden elevation-8">
<v-card-title
class="text-h5 font-weight-bold pa-5 text-white dialog-header"
:class="readOnly ? 'bg-blue-darken-3' : isEditMode ? 'bg-orange-darken-2' : 'bg-green-darken-2'"
>
<v-avatar
color="primary-darken-1"
size="48"
class="mr-3 elevation-2"
>
<v-icon :icon="readOnly ? 'mdi-eye' : isEditMode ? 'mdi-pencil' : 'mdi-account-plus'" color="white" size="24"></v-icon>
</v-avatar>
<div>
<div class="text-h5 font-weight-bold">{{ isEditMode ? 'Edit Pengguna' : readOnly ? 'Detail Pengguna' : 'Tambah Pengguna' }}</div>
<div class="text-caption text-white text-opacity-75 mt-1">
{{ readOnly ? 'Lihat informasi detail pengguna' : isEditMode ? 'Ubah data pengguna yang ada' : 'Tambahkan pengguna baru ke sistem' }}
</div>
<div>
<!-- Header -->
<div class="page-header">
<div class="header-content">
<div class="header-left">
<div class="header-icon">
<v-icon size="28" color="white">mdi-account-group</v-icon>
</div>
</v-card-title>
<v-card-text class="pa-6">
<!-- Basic Information Section -->
<div class="mb-4">
<div class="text-subtitle-1 font-weight-bold mb-3 d-flex align-center">
<v-icon icon="mdi-information" size="small" class="mr-2 text-primary"></v-icon>
Informasi Dasar
</div>
<v-row>
<v-col cols="12" md="6">
<v-text-field
v-model="editedItem.namaLengkap"
label="Nama Lengkap"
placeholder="Masukkan Nama Lengkap"
variant="outlined"
density="comfortable"
prepend-inner-icon="mdi-account-outline"
:readonly="readOnly"
hide-details="auto"
class="mb-3"
></v-text-field>
</v-col>
<v-col cols="12" md="6">
<v-text-field
v-model="editedItem.namaUser"
label="Nama User"
placeholder="Masukkan Nama User"
variant="outlined"
density="comfortable"
prepend-inner-icon="mdi-account-circle-outline"
:readonly="readOnly || isEditMode"
:hint="isEditMode ? 'Username tidak dapat diubah' : ''"
persistent-hint
hide-details="auto"
class="mb-3"
></v-text-field>
</v-col>
</v-row>
<v-row>
<v-col cols="12" md="6">
<v-select
v-model="editedItem.tipeUser"
label="Tipe User"
:items="['Super Admin', 'Admin', 'Loket', 'Klinik', 'Admin Barcode', 'INOVA', 'Ranap', 'Report Only', 'Farmasi', 'Manager']"
placeholder="Pilih Tipe User"
variant="outlined"
density="comfortable"
prepend-inner-icon="mdi-account-tie-outline"
:readonly="readOnly"
hide-details="auto"
class="mb-3"
></v-select>
</v-col>
<v-col cols="12" md="6">
<v-text-field
:value="formatLastLogin(editedItem.lastLogin)"
label="Last Access"
placeholder="Last Access Time"
variant="outlined"
density="comfortable"
prepend-inner-icon="mdi-clock-time-four-outline"
readonly
disabled
hide-details="auto"
class="mb-3"
></v-text-field>
</v-col>
</v-row>
</div>
<v-divider class="my-4"></v-divider>
<!-- Roles & Permissions Section -->
<div class="mb-4">
<div class="text-subtitle-1 font-weight-bold mb-3 d-flex align-center">
<v-icon icon="mdi-shield-account" size="small" class="mr-2 text-primary"></v-icon>
Roles & Permissions
</div>
<v-row>
<v-col cols="12" md="4">
<v-select
v-model="editedItem.realmRoles"
label="Realm Roles"
:items="availableRoles"
multiple
chips
placeholder="Pilih Realm Roles"
variant="outlined"
density="comfortable"
prepend-inner-icon="mdi-shield-account-outline"
:readonly="readOnly"
hide-details="auto"
class="mb-3"
></v-select>
</v-col>
<v-col cols="12" md="4">
<v-select
v-model="editedItem.accountRoles"
label="Account Roles"
:items="availableRoles"
multiple
chips
placeholder="Pilih Account Roles"
variant="outlined"
density="comfortable"
prepend-inner-icon="mdi-account-key-outline"
:readonly="readOnly"
hide-details="auto"
class="mb-3"
></v-select>
</v-col>
<v-col cols="12" md="4">
<v-select
v-model="editedItem.resourceRoles"
label="Resource Roles"
:items="availableRoles"
multiple
chips
placeholder="Pilih Resource Roles"
variant="outlined"
density="comfortable"
prepend-inner-icon="mdi-folder-key-outline"
:readonly="readOnly"
hide-details="auto"
class="mb-3"
></v-select>
</v-col>
</v-row>
<v-row>
<v-col cols="12" md="6">
<v-select
v-model="editedItem.groups"
label="Groups"
:items="availableGroups"
multiple
chips
placeholder="Pilih Groups Pengguna"
variant="outlined"
density="comfortable"
prepend-inner-icon="mdi-account-group-outline"
:readonly="readOnly"
hide-details="auto"
class="mb-3"
></v-select>
</v-col>
</v-row>
</div>
<v-divider v-if="!readOnly" class="my-4"></v-divider>
<!-- Security Section -->
<div v-if="!readOnly" class="mb-2">
<div class="text-subtitle-1 font-weight-bold mb-3 d-flex align-center">
<v-icon icon="mdi-lock" size="small" class="mr-2 text-primary"></v-icon>
Keamanan
</div>
<v-row>
<v-col cols="12">
<v-text-field
v-model="editedItem.password"
:label="isEditMode ? 'Ganti Password (Kosongkan jika tidak diubah)' : 'Password'"
placeholder="Masukkan Password"
type="password"
variant="outlined"
density="comfortable"
prepend-inner-icon="mdi-lock-outline"
hide-details="auto"
disabled
class="mb-3"
></v-text-field>
</v-col>
</v-row>
</div>
</v-card-text>
<v-card-actions class="d-flex justify-end pa-5 bg-grey-lighten-4">
<v-btn
color="grey-darken-1"
variant="flat"
class="text-capitalize mr-3 px-6"
rounded="0"
prepend-icon="mdi-close"
@click="cancelForm"
:disabled="isSaving"
size="default"
>
{{ readOnly ? 'Tutup' : 'Batal' }}
</v-btn>
<v-btn
v-if="!readOnly"
:color="isEditMode ? 'orange-darken-2' : 'green-darken-2'"
variant="flat"
class="text-capitalize px-6"
rounded="0"
:prepend-icon="isEditMode ? 'mdi-content-save' : 'mdi-check'"
@click="saveItem"
:loading="isSaving"
:disabled="isSaving"
size="default"
>
{{ isEditMode ? 'Simpan Perubahan' : 'Simpan' }}
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<div>
<v-card class="mb-4">
<!-- Header -->
<div class="page-header">
<div class="header-content">
<div class="header-left">
<div class="header-icon">
<v-icon size="32" color="white">mdi-account-group</v-icon>
</div>
<div class="header-text">
<h2 class="page-title">User Login Management</h2>
<p class="page-subtitle">{{ new Date().toLocaleDateString('id-ID', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }) }} - Manajemen Pengguna</p>
</div>
</div>
<div class="header-stats">
<v-chip color="white" variant="flat" class="stat-chip mr-2">
<v-icon start size="16">mdi-account</v-icon>
{{ filteredUsers.length }} Pengguna
</v-chip>
<v-chip
v-if="autoRefreshInterval"
color="white"
variant="flat"
class="stat-chip mr-2"
>
<v-icon start size="16">mdi-sync</v-icon>
Auto-refresh aktif
</v-chip>
<v-btn
color="white"
@click="refreshAllUsers"
elevation="0"
class="add-btn"
rounded="0"
:disabled="isPending || isSaving"
:loading="isSaving"
>
<v-icon left size="20">mdi-refresh</v-icon>
Sync dari Keycloak
</v-btn>
</div>
<div class="header-text">
<h2 class="page-title">User Login Management</h2>
<p class="page-subtitle">{{ new Date().toLocaleDateString('id-ID', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }) }} - Manajemen Pengguna</p>
</div>
</div>
</div>
</div>
<!-- Table -->
<v-card-text>
<div class="user-login-page pa-4">
<!-- Action Bar -->
<div class="action-bar mb-4">
<div class="action-bar-left">
<v-chip color="primary" variant="tonal" class="stat-chip mr-2">
<v-icon start size="16">mdi-account</v-icon>
{{ filteredUsers.length }} Pengguna
</v-chip>
<v-chip
v-if="autoRefreshInterval"
color="success"
variant="tonal"
class="stat-chip mr-2"
>
<v-icon start size="16">mdi-sync</v-icon>
Auto-refresh aktif
</v-chip>
</div>
<v-btn
color="primary"
@click="refreshAllUsers"
elevation="0"
class="action-btn"
:disabled="isPending || isSaving"
:loading="isSaving"
>
<v-icon left size="20">mdi-refresh</v-icon>
Sync dari Keycloak
</v-btn>
</div>
<v-alert
v-if="fetchError"
type="error"
variant="tonal"
class="mb-4"
icon="mdi-alert-circle-outline"
>
Failed to load initial data: {{ fetchError.message }}. Check your API connections.
</v-alert>
<!-- Form Dialog Popup -->
<v-dialog v-model="showForm" max-width="950px" :persistent="!readOnly" scrollable>
<v-card class="rounded-lg overflow-hidden elevation-8">
<v-card-title
class="text-h5 font-weight-bold pa-5 text-white dialog-header"
:class="readOnly ? 'bg-blue-darken-3' : isEditMode ? 'bg-orange-darken-2' : 'bg-green-darken-2'"
>
<v-avatar
color="primary-darken-1"
size="48"
class="mr-3 elevation-2"
>
<v-icon :icon="readOnly ? 'mdi-eye' : isEditMode ? 'mdi-pencil' : 'mdi-account-plus'" color="white" size="24"></v-icon>
</v-avatar>
<div>
<div class="text-h5 font-weight-bold">{{ isEditMode ? 'Edit Pengguna' : readOnly ? 'Detail Pengguna' : 'Tambah Pengguna' }}</div>
<div class="text-caption text-white text-opacity-75 mt-1">
{{ readOnly ? 'Lihat informasi detail pengguna' : isEditMode ? 'Ubah data pengguna yang ada' : 'Tambahkan pengguna baru ke sistem' }}
</div>
</div>
</v-card-title>
<v-card-text class="pa-6">
<!-- Basic Information Section -->
<div class="mb-4">
<div class="text-subtitle-1 font-weight-bold mb-3 d-flex align-center">
<v-icon icon="mdi-information" size="small" class="mr-2 text-primary"></v-icon>
Informasi Dasar
</div>
<v-row>
<v-col cols="12" md="6">
<v-text-field
v-model="editedItem.namaLengkap"
label="Nama Lengkap"
placeholder="Masukkan Nama Lengkap"
variant="outlined"
density="comfortable"
prepend-inner-icon="mdi-account-outline"
:readonly="readOnly"
hide-details="auto"
class="mb-3"
></v-text-field>
</v-col>
<v-col cols="12" md="6">
<v-text-field
v-model="editedItem.namaUser"
label="Nama User"
placeholder="Masukkan Nama User"
variant="outlined"
density="comfortable"
prepend-inner-icon="mdi-account-circle-outline"
:readonly="readOnly || isEditMode"
:hint="isEditMode ? 'Username tidak dapat diubah' : ''"
persistent-hint
hide-details="auto"
class="mb-3"
></v-text-field>
</v-col>
</v-row>
<v-row>
<v-col cols="12" md="6">
<v-select
v-model="editedItem.tipeUser"
label="Tipe User"
:items="['Super Admin', 'Admin', 'Loket', 'Klinik', 'Admin Barcode', 'INOVA', 'Ranap', 'Report Only', 'Farmasi', 'Manager']"
placeholder="Pilih Tipe User"
variant="outlined"
density="comfortable"
prepend-inner-icon="mdi-account-tie-outline"
:readonly="readOnly"
hide-details="auto"
class="mb-3"
></v-select>
</v-col>
<v-col cols="12" md="6">
<v-text-field
:value="formatLastLogin(editedItem.lastLogin)"
label="Last Access"
placeholder="Last Access Time"
variant="outlined"
density="comfortable"
prepend-inner-icon="mdi-clock-time-four-outline"
readonly
disabled
hide-details="auto"
class="mb-3"
></v-text-field>
</v-col>
</v-row>
</div>
<v-divider class="my-4"></v-divider>
<!-- Roles & Permissions Section -->
<div class="mb-4">
<div class="text-subtitle-1 font-weight-bold mb-3 d-flex align-center">
<v-icon icon="mdi-shield-account" size="small" class="mr-2 text-primary"></v-icon>
Roles & Permissions
</div>
<v-row>
<v-col cols="12" md="4">
<v-select
v-model="editedItem.realmRoles"
label="Realm Roles"
:items="availableRoles"
multiple
chips
placeholder="Pilih Realm Roles"
variant="outlined"
density="comfortable"
prepend-inner-icon="mdi-shield-account-outline"
:readonly="readOnly"
hide-details="auto"
class="mb-3"
></v-select>
</v-col>
<v-col cols="12" md="4">
<v-select
v-model="editedItem.accountRoles"
label="Account Roles"
:items="availableRoles"
multiple
chips
placeholder="Pilih Account Roles"
variant="outlined"
density="comfortable"
prepend-inner-icon="mdi-account-key-outline"
:readonly="readOnly"
hide-details="auto"
class="mb-3"
></v-select>
</v-col>
<v-col cols="12" md="4">
<v-select
v-model="editedItem.resourceRoles"
label="Resource Roles"
:items="availableRoles"
multiple
chips
placeholder="Pilih Resource Roles"
variant="outlined"
density="comfortable"
prepend-inner-icon="mdi-folder-key-outline"
:readonly="readOnly"
hide-details="auto"
class="mb-3"
></v-select>
</v-col>
</v-row>
<v-row>
<v-col cols="12" md="6">
<v-select
v-model="editedItem.groups"
label="Groups"
:items="availableGroups"
multiple
chips
placeholder="Pilih Groups Pengguna"
variant="outlined"
density="comfortable"
prepend-inner-icon="mdi-account-group-outline"
:readonly="readOnly"
hide-details="auto"
class="mb-3"
></v-select>
</v-col>
</v-row>
</div>
<v-divider v-if="!readOnly" class="my-4"></v-divider>
<!-- Security Section -->
<div v-if="!readOnly" class="mb-2">
<div class="text-subtitle-1 font-weight-bold mb-3 d-flex align-center">
<v-icon icon="mdi-lock" size="small" class="mr-2 text-primary"></v-icon>
Keamanan
</div>
<v-row>
<v-col cols="12">
<v-text-field
v-model="editedItem.password"
:label="isEditMode ? 'Ganti Password (Kosongkan jika tidak diubah)' : 'Password'"
placeholder="Masukkan Password"
type="password"
variant="outlined"
density="comfortable"
prepend-inner-icon="mdi-lock-outline"
hide-details="auto"
disabled
class="mb-3"
></v-text-field>
</v-col>
</v-row>
</div>
</v-card-text>
<v-card-actions class="d-flex justify-end pa-5 bg-grey-lighten-4">
<v-btn
color="grey-darken-1"
variant="flat"
class="text-capitalize mr-3 px-6"
rounded="0"
prepend-icon="mdi-close"
@click="cancelForm"
:disabled="isSaving"
size="default"
>
{{ readOnly ? 'Tutup' : 'Batal' }}
</v-btn>
<v-btn
v-if="!readOnly"
:color="isEditMode ? 'orange-darken-2' : 'green-darken-2'"
variant="flat"
class="text-capitalize px-6"
rounded="0"
:prepend-icon="isEditMode ? 'mdi-content-save' : 'mdi-check'"
@click="saveItem"
:loading="isSaving"
:disabled="isSaving"
size="default"
>
{{ isEditMode ? 'Simpan Perubahan' : 'Simpan' }}
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<div>
<v-card class="mb-4">
<!-- Table -->
<v-card-text>
<div class="d-flex flex-wrap align-center justify-space-between mb-4">
<div class="d-flex align-center">
<span class="mr-2 text-subtitle-1">Show</span>
@@ -495,6 +499,7 @@
>
{{ snackbar.message }}
</v-snackbar>
</div>
</div>
</template>
@@ -1113,7 +1118,7 @@ $font-weight-semibold: 600;
// ============================================
.page-header {
background: linear-gradient(135deg, $primary-600 0%, $primary-700 100%);
border-radius: 16px 16px 0 0;
border-radius: 0 !important;
box-shadow: 0 4px 16px rgba(58, 97, 201, 0.2);
}
@@ -1121,7 +1126,8 @@ $font-weight-semibold: 600;
display: flex;
align-items: center;
justify-content: space-between;
padding: 32px;
padding: 16px 28px;
height: 80px;
color: $neutral-100;
}
@@ -1132,15 +1138,15 @@ $font-weight-semibold: 600;
.header-icon {
background: rgba(255, 255, 255, 0.2);
border-radius: 16px;
padding: 16px;
margin-right: 20px;
border-radius: 12px;
padding: 12px;
margin-right: 16px;
backdrop-filter: blur(10px);
}
.page-title {
font-size: 36px;
line-height: 44px;
font-size: 32px;
line-height: 40px;
font-weight: $font-weight-semibold;
margin: 0;
color: $neutral-100;
@@ -1148,10 +1154,10 @@ $font-weight-semibold: 600;
}
.page-subtitle {
margin: 4px 0 0 0;
margin: 2px 0 0 0;
opacity: 0.9;
font-size: 16px;
line-height: 24px;
font-size: 15px;
line-height: 22px;
font-weight: $font-weight-regular;
color: $neutral-100;
}
@@ -1178,6 +1184,35 @@ $font-weight-semibold: 600;
color: $primary-600 !important;
}
// ============================================
// ACTION BAR
// ============================================
.action-bar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px 20px;
background: $neutral-100;
border-radius: 12px;
border: 1px solid $neutral-400;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}
.action-bar-left {
display: flex;
align-items: center;
gap: 8px;
flex-wrap: wrap;
}
.action-btn {
font-weight: $font-weight-semibold;
text-transform: none;
letter-spacing: 0.5px;
font-size: 16px;
line-height: 24px;
}
// ============================================
// CUSTOM TABLE STYLING
// ============================================
+1 -1
View File
@@ -35,7 +35,7 @@ const defaultNavItems: NavItem[] = [
path: "",
children: [
{ id: 10, name: "Anjungan", path: "/anjungan/anjungan", icon: "mdi-circle-small" },
{ id: 11, name: "Klinik", path: "/anjungan/AntrianKlinik", icon: "mdi-circle-small" },
// { id: 11, name: "Klinik", path: "/anjungan/AntrianKlinik", icon: "mdi-circle-small" },
{ id: 12, name: "Klinik Ruang", path: "/anjungan/AntrianKlinikRuang", icon: "mdi-circle-small"},
// { id: 13, name: "Penunjang", path: "/anjungan/AntrianPenunjang", icon: "mdi-circle-small"},
{id: 14, name: "Loket", path: "/anjungan/AntrianLoket", icon: "mdi-circle-small"},