diff --git a/assets/css/colors.css b/assets/css/colors.css new file mode 100644 index 0000000..03824ca --- /dev/null +++ b/assets/css/colors.css @@ -0,0 +1,116 @@ +:root { + /* Neutral Colors */ + --neutral-900: #212121; + --neutral-800: #4D4D4D; + --neutral-700: #717171; + --neutral-600: #89939E; + --neutral-500: #ABBED1; + --neutral-400: #E5F7FA; + --neutral-300: #F5F7FA; + --neutral-100: #FFFFFF; + + /* Primary Colors (Orange) */ + --primary-700: #0053AD; + --primary-600: #0663C7; + --primary-500: #0671E0; + --primary-400: #4196F0; + --primary-300: #DBEDFF; + --primary-200: #EEF5FC; + --primary-100: #EEF5FC; + + /* Secondary Colors (Blue) */ + --secondary-700: #0053AD; + --secondary-600: #0671E0; + --secondary-500: #0663C7; + --secondary-400: #4196F0; + --secondary-300: #DBEDFF; + --secondary-200: #EEF5FC; + --secondary-100: #0053AD; + + /* Success Colors (Green) */ + --success-700: #1B6E53; + --success-600: #009262; + --success-500: #115B43; + --success-400: #32C997; + --success-300: #84DFC1; + --success-200: #F1FBF8; + + /* Danger Colors (Red) */ + --danger-700: #E01507; + --danger-600: #E02B1D; + --danger-500: #C33025; + --danger-400: #FF5A4F; + --danger-300: #F0857D; + --danger-200: #FFF1F0; +} + +/* Utility Classes untuk Background */ +.bg-neutral-900 { background-color: var(--neutral-900); } +.bg-neutral-800 { background-color: var(--neutral-800); } +.bg-neutral-700 { background-color: var(--neutral-700); } +.bg-neutral-600 { background-color: var(--neutral-600); } +.bg-neutral-500 { background-color: var(--neutral-500); } +.bg-neutral-400 { background-color: var(--neutral-400); } +.bg-neutral-300 { background-color: var(--neutral-300); } +.bg-neutral-100 { background-color: var(--neutral-100); } + +.bg-primary-700 { background-color: var(--primary-700); } +.bg-primary-600 { background-color: var(--primary-600); } +.bg-primary-500 { background-color: var(--primary-500); } +.bg-primary-400 { background-color: var(--primary-400); } +.bg-primary-300 { background-color: var(--primary-300); } +.bg-primary-200 { background-color: var(--primary-200); } +.bg-primary-100 { background-color: var(--primary-100); } + +.bg-secondary-700 { background-color: var(--secondary-700); } +.bg-secondary-600 { background-color: var(--secondary-600); } +.bg-secondary-500 { background-color: var(--secondary-500); } +.bg-secondary-400 { background-color: var(--secondary-400); } +.bg-secondary-300 { background-color: var(--secondary-300); } +.bg-secondary-200 { background-color: var(--secondary-200); } + +.bg-success-700 { background-color: var(--success-700); } +.bg-success-600 { background-color: var(--success-600); } +.bg-success-500 { background-color: var(--success-500); } +.bg-success-400 { background-color: var(--success-400); } +.bg-success-300 { background-color: var(--success-300); } +.bg-success-200 { background-color: var(--success-200); } + +.bg-danger-700 { background-color: var(--danger-700); } +.bg-danger-600 { background-color: var(--danger-600); } +.bg-danger-500 { background-color: var(--danger-500); } +.bg-danger-400 { background-color: var(--danger-400); } +.bg-danger-300 { background-color: var(--danger-300); } +.bg-danger-200 { background-color: var(--danger-200); } + +/* Utility Classes untuk Text Color */ +.text-neutral-900 { color: var(--neutral-900); } +.text-neutral-800 { color: var(--neutral-800); } +.text-neutral-700 { color: var(--neutral-700); } +.text-neutral-600 { color: var(--neutral-600); } +.text-neutral-500 { color: var(--neutral-500); } +.text-neutral-100 { color: var(--neutral-100); } + +.text-primary-700 { color: var(--primary-700); } +.text-primary-600 { color: var(--primary-600); } +.text-primary-500 { color: var(--primary-500); } +.text-primary-400 { color: var(--primary-400); } + +.text-secondary-700 { color: var(--secondary-700); } +.text-secondary-600 { color: var(--secondary-600); } +.text-secondary-500 { color: var(--secondary-500); } + +.text-success-700 { color: var(--success-700); } +.text-success-600 { color: var(--success-600); } +.text-success-500 { color: var(--success-500); } + +.text-danger-700 { color: var(--danger-700); } +.text-danger-600 { color: var(--danger-600); } +.text-danger-500 { color: var(--danger-500); } + +/* Utility Classes untuk Border */ +.border-primary-500 { border-color: var(--primary-500); } +.border-secondary-500 { border-color: var(--secondary-500); } +.border-success-500 { border-color: var(--success-500); } +.border-danger-500 { border-color: var(--danger-500); } +.border-neutral-500 { border-color: var(--neutral-500); } \ No newline at end of file diff --git a/assets/css/typography.css b/assets/css/typography.css new file mode 100644 index 0000000..ba6caac --- /dev/null +++ b/assets/css/typography.css @@ -0,0 +1,109 @@ +/* Base Font */ +* { + font-family: 'Inter', sans-serif; +} + +/* Headlines - Desktop */ +.headline-1 { + font-family: 'Inter', sans-serif; + font-weight: 600; /* Semi Bold */ + font-size: 64px; + line-height: 76px; +} + +.headline-2 { + font-family: 'Inter', sans-serif; + font-weight: 600; /* Semi Bold */ + font-size: 36px; + line-height: 44px; +} + +.headline-3 { + font-family: 'Inter', sans-serif; + font-weight: 600; /* Semi Bold */ + font-size: 28px; + line-height: 36px; +} + +.headline-4 { + font-family: 'Inter', sans-serif; + font-weight: 600; /* Semi Bold */ + font-size: 20px; + line-height: 28px; +} + +/* Body - Desktop */ +.body-1 { + font-family: 'Inter', sans-serif; + font-weight: 400; /* Regular */ + font-size: 18px; + line-height: 28px; +} + +.body-2 { + font-family: 'Inter', sans-serif; + font-weight: 400; /* Regular */ + font-size: 16px; + line-height: 24px; +} + +.body-3 { + font-family: 'Inter', sans-serif; + font-weight: 400; /* Regular */ + font-size: 14px; + line-height: 20px; +} + +/* Caption - Desktop */ +.text-1 { + font-family: 'Inter', sans-serif; + font-weight: 400; /* Regular */ + font-size: 16px; + line-height: 24px; +} + +.text-2 { + font-family: 'Inter', sans-serif; + font-weight: 400; /* Regular */ + font-size: 12px; + line-height: 16px; +} + +/* Mobile Typography */ +@media (max-width: 768px) { + .headline-1 { + font-weight: 700; /* Bold */ + font-size: 28px; + line-height: 36px; + } + + .headline-2 { + font-weight: 600; /* Semi Bold */ + font-size: 20px; + line-height: 28px; + } + + .headline-3 { + font-weight: 600; /* Semi Bold */ + font-size: 18px; + line-height: 24px; + } + + .headline-4 { + font-weight: 600; /* Semi Bold */ + font-size: 18px; + line-height: 24px; + } + + .body { + font-weight: 500; /* Medium */ + font-size: 16px; + line-height: 24px; + } + + .caption { + font-weight: 400; /* Regular */ + font-size: 14px; + line-height: 20px; + } +} \ No newline at end of file diff --git a/assets/scss/_colors.scss b/assets/scss/_colors.scss new file mode 100644 index 0000000..d68de2e --- /dev/null +++ b/assets/scss/_colors.scss @@ -0,0 +1,166 @@ +@use 'sass:map'; + +// Color Palette Variables +$neutral-900: #212121; +$neutral-800: #4D4D4D; +$neutral-700: #717171; +$neutral-600: #89939E; +$neutral-500: #ABBED1; +$neutral-400: #E5F7FA; +$neutral-300: #F5F7FA; +$neutral-100: #FFFFFF; + +$primary-700: #0053AD; +$primary-600: #0663C7; +$primary-500: #0671E0; +$primary-400: #4196F0; +$primary-300: #DBEDFF; +$primary-200: #EEF5FC; +$primary-100: #EEF5FC; + +$secondary-700: #0053AD; +$secondary-600: #0671E0; +$secondary-500: #0663C7; +$secondary-400: #4196F0; +$secondary-300: #DBEDFF; +$secondary-200: #EEF5FC; + +$success-700: #1B6E53; +$success-600: #009262; +$success-500: #115B43; +$success-400: #32C997; +$success-300: #84DFC1; +$success-200: #F1FBF8; + +$danger-700: #E01507; +$danger-600: #E02B1D; +$danger-500: #C33025; +$danger-400: #FF5A4F; +$danger-300: #F0857D; +$danger-200: #FFF1F0; + +// CSS Variables untuk dynamic theming +:root { + // Neutral + --color-neutral-900: #{$neutral-900}; + --color-neutral-800: #{$neutral-800}; + --color-neutral-700: #{$neutral-700}; + --color-neutral-600: #{$neutral-600}; + --color-neutral-500: #{$neutral-500}; + --color-neutral-400: #{$neutral-400}; + --color-neutral-300: #{$neutral-300}; + --color-neutral-100: #{$neutral-100}; + + // Primary + --color-primary-700: #{$primary-700}; + --color-primary-600: #{$primary-600}; + --color-primary-500: #{$primary-500}; + --color-primary-400: #{$primary-400}; + --color-primary-300: #{$primary-300}; + --color-primary-200: #{$primary-200}; + --color-primary-100: #{$primary-100}; + + // Secondary + --color-secondary-700: #{$secondary-700}; + --color-secondary-600: #{$secondary-600}; + --color-secondary-500: #{$secondary-500}; + --color-secondary-400: #{$secondary-400}; + --color-secondary-300: #{$secondary-300}; + --color-secondary-200: #{$secondary-200}; + + // Success + --color-success-700: #{$success-700}; + --color-success-600: #{$success-600}; + --color-success-500: #{$success-500}; + --color-success-400: #{$success-400}; + --color-success-300: #{$success-300}; + --color-success-200: #{$success-200}; + + // Danger + --color-danger-700: #{$danger-700}; + --color-danger-600: #{$danger-600}; + --color-danger-500: #{$danger-500}; + --color-danger-400: #{$danger-400}; + --color-danger-300: #{$danger-300}; + --color-danger-200: #{$danger-200}; + + // Theme colors (akan di-override oleh theme system) + --color-primary: #{$primary-500}; + --color-secondary: #{$secondary-500}; + --color-success: #{$success-600}; + --color-danger: #{$danger-600}; + --color-background: #{$neutral-300}; + --color-surface: #{$neutral-100}; + --color-textPrimary: #{$neutral-900}; + --color-textSecondary: #{$neutral-700}; + --color-borderColor: #{$neutral-500}; +} + +// Dark mode base +.dark { + --color-background: #1a1a1a; + --color-surface: #{$neutral-900}; + --color-textPrimary: #{$neutral-100}; + --color-textSecondary: #{$neutral-500}; + --color-borderColor: #{$neutral-800}; +} + +// Mixin untuk generate color utilities +@mixin color-utilities($prefix, $color) { + .text-#{$prefix} { + color: $color; + } + + .bg-#{$prefix} { + background-color: $color; + } + + .border-#{$prefix} { + border-color: $color; + } +} + +// Generate color utilities +$colors: ( + 'neutral-900': $neutral-900, + 'neutral-800': $neutral-800, + 'neutral-700': $neutral-700, + 'neutral-600': $neutral-600, + 'neutral-500': $neutral-500, + 'neutral-400': $neutral-400, + 'neutral-300': $neutral-300, + 'neutral-100': $neutral-100, + 'primary-700': $primary-700, + 'primary-600': $primary-600, + 'primary-500': $primary-500, + 'primary-400': $primary-400, + 'primary-300': $primary-300, + 'primary-200': $primary-200, + 'secondary-700': $secondary-700, + 'secondary-600': $secondary-600, + 'secondary-500': $secondary-500, + 'success-700': $success-700, + 'success-600': $success-600, + 'success-500': $success-500, + 'danger-700': $danger-700, + 'danger-600': $danger-600, + 'danger-500': $danger-500 +); + +@each $name, $color in $colors { + @include color-utilities($name, $color); +} + +// Shorthand semantic colors +.text-primary { color: $primary-500; } +.text-secondary { color: $secondary-500; } +.text-success { color: $success-600; } +.text-danger { color: $danger-600; } +.text-muted { color: $neutral-600; } + +.bg-primary { background-color: $primary-500; } +.bg-secondary { background-color: $secondary-500; } +.bg-success { background-color: $success-600; } +.bg-danger { background-color: $danger-600; } +.bg-light { background-color: $neutral-300; } +.bg-white { background-color: $neutral-100; } \ No newline at end of file diff --git a/assets/scss/_typography.scss b/assets/scss/_typography.scss new file mode 100644 index 0000000..32bc67a --- /dev/null +++ b/assets/scss/_typography.scss @@ -0,0 +1,121 @@ +@use 'sass:map'; +@use './variables' as *; + +// Mixin untuk generate typography classes +@mixin typography($name, $size, $line-height, $weight) { + .#{$name} { + font-family: $font-family-base; + font-size: $size; + line-height: $line-height; + font-weight: $weight; + margin: 0; + } +} + +// Base typography +* { + font-family: $font-family-base; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +body { + font-family: $font-family-base; + font-size: 16px; + line-height: 24px; + font-weight: $font-weight-regular; + margin: 0; + padding: 0; +} + +// Generate desktop typography classes - Gunakan map.get +@each $name, $props in $font-sizes { + @include typography( + $name, + map.get($props, 'size'), + map.get($props, 'line-height'), + map.get($props, 'weight') + ); +} + +// Generate mobile typography classes - Gunakan map.get +@media (max-width: $breakpoint-mobile) { + @each $name, $props in $font-sizes-mobile { + @include typography( + $name, + map.get($props, 'size'), + map.get($props, 'line-height'), + map.get($props, 'weight') + ); + } +} + +// HTML semantic tags +h1 { + @extend .headline-1; +} + +h2 { + @extend .headline-2; +} + +h3 { + @extend .headline-3; +} + +h4 { + @extend .headline-4; +} + +p { + @extend .body-1; +} + +small { + @extend .caption-2; +} + +// Utility classes +.text-regular { + font-weight: $font-weight-regular !important; +} + +.text-medium { + font-weight: $font-weight-medium !important; +} + +.text-semibold { + font-weight: $font-weight-semibold !important; +} + +.text-bold { + font-weight: $font-weight-bold !important; +} + +.text-uppercase { + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.text-center { + text-align: center; +} + +.text-left { + text-align: left; +} + +.text-right { + text-align: right; +} + +// Line clamp utilities +@for $i from 1 through 5 { + .line-clamp-#{$i} { + display: -webkit-box; + -webkit-line-clamp: $i; + -webkit-box-orient: vertical; + overflow: hidden; + text-overflow: ellipsis; + } +} \ No newline at end of file diff --git a/assets/scss/_variables.scss b/assets/scss/_variables.scss new file mode 100644 index 0000000..64e4ebb --- /dev/null +++ b/assets/scss/_variables.scss @@ -0,0 +1,117 @@ +@use 'sass:map'; +@use 'sass:math'; + +// Font Family +$font-family-base: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; + +// Font Weights +$font-weight-regular: 400; +$font-weight-medium: 500; +$font-weight-semibold: 600; +$font-weight-bold: 700; + +// Font Sizes & Line Heights - Desktop +$font-sizes: ( + 'headline-1': ( + 'size': 64px, + 'line-height': 76px, + 'weight': $font-weight-semibold + ), + 'headline-2': ( + 'size': 36px, + 'line-height': 44px, + 'weight': $font-weight-semibold + ), + 'headline-3': ( + 'size': 28px, + 'line-height': 36px, + 'weight': $font-weight-semibold + ), + 'headline-4': ( + 'size': 20px, + 'line-height': 28px, + 'weight': $font-weight-semibold + ), + 'body-1': ( + 'size': 18px, + 'line-height': 28px, + 'weight': $font-weight-regular + ), + 'body-2': ( + 'size': 16px, + 'line-height': 24px, + 'weight': $font-weight-regular + ), + 'body-3': ( + 'size': 14px, + 'line-height': 20px, + 'weight': $font-weight-regular + ), + 'caption-1': ( + 'size': 16px, + 'line-height': 24px, + 'weight': $font-weight-regular + ), + 'caption-2': ( + 'size': 12px, + 'line-height': 16px, + 'weight': $font-weight-regular + ) +); + +// Font Sizes - Mobile +$font-sizes-mobile: ( + 'headline-1': ( + 'size': 28px, + 'line-height': 36px, + 'weight': $font-weight-bold + ), + 'headline-2': ( + 'size': 20px, + 'line-height': 28px, + 'weight': $font-weight-semibold + ), + 'headline-3': ( + 'size': 18px, + 'line-height': 24px, + 'weight': $font-weight-semibold + ), + 'headline-4': ( + 'size': 18px, + 'line-height': 24px, + 'weight': $font-weight-semibold + ), + 'body': ( + 'size': 16px, + 'line-height': 24px, + 'weight': $font-weight-medium + ), + 'caption': ( + 'size': 14px, + 'line-height': 20px, + 'weight': $font-weight-regular + ) +); + +// Breakpoints +$breakpoint-mobile: 768px; +$breakpoint-tablet: 1024px; +$breakpoint-desktop: 1280px; + +// Mixins +@mixin heading($level) { + @if map.has-key($font-sizes, $level) { + $props: map.get($font-sizes, $level); + font-size: map.get($props, 'size'); + line-height: map.get($props, 'line-height'); + font-weight: map.get($props, 'weight'); + font-family: $font-family-base; + } +} + +@mixin responsive-text { + @media (max-width: $breakpoint-mobile) { + font-size: 14px; + line-height: 20px; + } +} \ No newline at end of file diff --git a/assets/scss/main.scss b/assets/scss/main.scss new file mode 100644 index 0000000..e1b27fc --- /dev/null +++ b/assets/scss/main.scss @@ -0,0 +1,71 @@ +// Gunakan @use daripada @import +@use './variables' as *; +@use './colors' as *; +@use './typography' as *; + +// Global styles +*, +*::before, +*::after { + box-sizing: border-box; +} + +html { + scroll-behavior: smooth; +} + +body { + margin: 0; + padding: 0; + background-color: var(--color-background); + color: var(--color-textPrimary); + transition: background-color 0.3s ease, color 0.3s ease; +} + +// Selection color +::selection { + background-color: var(--color-primary-300); + color: var(--color-primary-700); +} + +// Focus styles +:focus-visible { + outline: 2px solid var(--color-primary-500); + outline-offset: 2px; +} + +// Responsive images +img { + max-width: 100%; + height: auto; + display: block; +} + +// Links +a { + color: var(--color-primary-500); + text-decoration: none; + transition: color 0.2s ease; + + &:hover { + color: var(--color-primary-600); + } + + &:active { + color: var(--color-primary-700); + } +} + +// Buttons base +button { + font-family: $font-family-base; + cursor: pointer; + border: none; + outline: none; + transition: all 0.2s ease; + + &:disabled { + opacity: 0.5; + cursor: not-allowed; + } +} \ No newline at end of file diff --git a/assets/styles/loginpage/login.css b/assets/styles/loginpage/login.css index 8e0acbe..9ee2aa8 100644 --- a/assets/styles/loginpage/login.css +++ b/assets/styles/loginpage/login.css @@ -110,7 +110,7 @@ } .hospital-logo { - height: 64px; + height: 232px; width: auto; filter: drop-shadow(2px 2px 4px rgba(0, 0, 0, 0.1)); } diff --git a/components/ProfilePopup1.vue b/components/ProfilePopup2.txt similarity index 100% rename from components/ProfilePopup1.vue rename to components/ProfilePopup2.txt diff --git a/components/SideBar.vue b/components/SideBar.vue new file mode 100644 index 0000000..3ed19d3 --- /dev/null +++ b/components/SideBar.vue @@ -0,0 +1,180 @@ + + + + diff --git a/components/SideBar1.vue b/components/SideBar1.vue deleted file mode 100644 index 85f0aa8..0000000 --- a/components/SideBar1.vue +++ /dev/null @@ -1,210 +0,0 @@ - \ No newline at end of file + diff --git a/pages/Anjungan/AntrianKlinik.vue b/pages/Anjungan/AntrianKlinik.vue index 025b544..921b1b8 100644 --- a/pages/Anjungan/AntrianKlinik.vue +++ b/pages/Anjungan/AntrianKlinik.vue @@ -1,713 +1,544 @@ \ No newline at end of file + diff --git a/pages/Anjungan/AntrianKlinikRuang.vue b/pages/Anjungan/AntrianKlinikRuang.vue new file mode 100644 index 0000000..15358b8 --- /dev/null +++ b/pages/Anjungan/AntrianKlinikRuang.vue @@ -0,0 +1,521 @@ + + + + + + \ No newline at end of file diff --git a/pages/Anjungan/AntrianPenunjang.vue b/pages/Anjungan/AntrianPenunjang.vue new file mode 100644 index 0000000..454bf7f --- /dev/null +++ b/pages/Anjungan/AntrianPenunjang.vue @@ -0,0 +1,520 @@ + + + + + + \ No newline at end of file diff --git a/pages/Anjungan/klinik b/pages/Anjungan/klinik new file mode 100644 index 0000000..7d8ba5a --- /dev/null +++ b/pages/Anjungan/klinik @@ -0,0 +1,543 @@ + + + + + + \ No newline at end of file diff --git a/pages/BuatAntrean.vue b/pages/BuatAntrean.vue new file mode 100644 index 0000000..bdbc95e --- /dev/null +++ b/pages/BuatAntrean.vue @@ -0,0 +1,698 @@ + + + + + + \ No newline at end of file diff --git a/pages/Dashboard.vue b/pages/Dashboard.vue index c64c596..c1ce88e 100644 --- a/pages/Dashboard.vue +++ b/pages/Dashboard.vue @@ -101,14 +101,11 @@ - - - Grafik Jumlah Antrean - - Hari - Minggu - Bulan - Tahun + + + Registration Trend + + Day @@ -159,9 +156,15 @@ - - Realtime Ticket Queue - + + + Realtime Check-in Velocity + + mdi-circle + Live + + + { console.log('Navigating to', path); }; +// Mock user for demo purposes - replace with your actual auth +const user = ref({ name: 'Admin User', preferred_username: 'admin' }); +const isLoading = ref(false); +const checkAuth = async () => user.value; +const navigateTo = (path) => console.log('Navigate to:', path); +// --------------------------------- -// Dashboard data +// --- EXPORT STATE --- +const exportType = ref('JSON'); +const exportOptions = ref([ + { title: 'JSON (.json)', type: 'json', icon: 'mdi-code-json' }, + { title: 'CSV (.csv)', type: 'csv', icon: 'mdi-file-delimited' }, + { title: 'Excel (.xlsx) - Server Only', type: 'excel', icon: 'mdi-file-excel' }, + { title: 'PDF (.pdf) - Placeholder', type: 'pdf', icon: 'mdi-file-pdf' }, +]); +// -------------------- + +// Dashboard state const currentDate = ref(''); const activeYear = ref('2025'); const queueTimePeriod = ref('day'); @@ -243,74 +261,69 @@ const mockQueueData = ref([ { date: '2025-10-18', registrants: 435, attendees: 380 }, ]); -// --- REFACTORED REALTIME LOGIC --- -const realtimeChart = ref(null); // Ref untuk mengakses komponen Line +// --- REALTIME CHART LOGIC - FIXED --- +const realtimeChart = ref(null); const maxDataPoints = 10; let realtimeInterval = null; -// Initial data structure (non-reactive for update function) -const initialLineData = { - labels: Array.from({ length: maxDataPoints }, (_, i) => - dayjs().subtract((maxDataPoints - 1 - i) * 5, 'second').format('HH:mm:ss') - ), - datasets: [ - { - label: 'Tickets Processed', - backgroundColor: '#FF5722', - borderColor: '#FF5722', - data: Array.from({ length: maxDataPoints }, () => Math.floor(Math.random() * 50) + 100), - fill: false, - tension: 0.1, - }, - ], -}; +const realtimeLineData = ref({ + labels: Array.from({ length: maxDataPoints }, (_, i) => + dayjs().subtract((maxDataPoints - 1 - i) * 5, 'second').format('HH:mm:ss') + ), + datasets: [ + { + label: 'Check-ins/min', + backgroundColor: 'rgba(74, 95, 122, 0.15)', + borderColor: '#5FB7FF', + data: Array.from({ length: maxDataPoints }, () => Math.floor(Math.random() * 20) + 40), + fill: true, + tension: 0.3, + borderWidth: 3, + pointRadius: 4, + pointHoverRadius: 6, + pointBackgroundColor: '#4A5F7A', + }, + ], +}); const lineOptions = ref({ - responsive: true, - maintainAspectRatio: false, - animation: { - duration: 0 // Crucial: Disable animation for smooth realtime scrolling + responsive: true, + maintainAspectRatio: false, + animation: { duration: 300 }, + plugins: { + legend: { display: true }, + title: { display: false } + }, + scales: { + y: { + beginAtZero: true, + suggestedMax: 80, + title: { display: true, text: 'Check-ins per Minute' }, + grid: { color: 'rgba(0, 0, 0, 0.05)' } }, - plugins: { - legend: { display: true }, - title: { display: false } - }, - scales: { - y: { - beginAtZero: true, - suggestedMax: 200, - title: { display: true, text: 'Count' }, - grid: { display: true } - }, - x: { - title: { display: true, text: 'Time (HH:MM:SS)' }, - grid: { display: false } - } + x: { + title: { display: true, text: 'Time (HH:MM:SS)' }, + grid: { display: false } } + } }); const updateRealtimeData = () => { - const chart = realtimeChart.value?.chart; - if (!chart) return; - - // 1. Get the current data arrays - const dataArray = chart.data.datasets[0].data; - const labelArray = chart.data.labels; - - // 2. Shift (remove) the oldest data point and label - dataArray.shift(); - labelArray.shift(); - - // 3. Generate new data point and time label - const newDataPoint = Math.floor(Math.random() * 50) + 100; - const newTimeLabel = dayjs().format('HH:mm:ss'); - - // 4. Push the new data and label - dataArray.push(newDataPoint); - labelArray.push(newTimeLabel); - - // 5. CRUCIAL: Tell Chart.js to redraw itself without destroying the instance - chart.update(); + const data = realtimeLineData.value.datasets[0].data; + const labels = realtimeLineData.value.labels; + + // Remove first data point + data.shift(); + labels.shift(); + + // Add new data point + const newDataPoint = Math.floor(Math.random() * 20) + 40; + const newTimeLabel = dayjs().format('HH:mm:ss'); + + data.push(newDataPoint); + labels.push(newTimeLabel); + + console.log('Realtime chart updated:', newTimeLabel, newDataPoint); }; // --- END REALTIME CHART LOGIC --- @@ -318,13 +331,13 @@ onMounted(async () => { try { const sessionUser = await checkAuth() if (sessionUser) { - // Set current date - const options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }; - currentDate.value = new Date().toLocaleDateString('id-ID', options); - - // Start realtime data update interval - // Pastikan chart instance sudah siap sebelum memulai interval - realtimeInterval = setInterval(updateRealtimeData, 5000); + // Set date with Indonesian locale + currentDate.value = dayjs().format('dddd, DD MMMM YYYY'); + console.log('Current date set:', currentDate.value); + + // Start realtime updates every 5 seconds + realtimeInterval = setInterval(updateRealtimeData, 5000); + console.log('Realtime interval started'); } else { await navigateTo('/LoginPage'); } @@ -337,25 +350,10 @@ onMounted(async () => { onUnmounted(() => { if (realtimeInterval) { clearInterval(realtimeInterval); + console.log('Realtime interval cleared'); } }); -// Updated logout handler (Tetap) -const handleLogout = async () => { - if (isLoggingOut.value) return - - try { - isLoggingOut.value = true - console.log('🚪 Dashboard logout initiated...') - await logout() - } catch (error) { - console.error('❌ Dashboard logout error:', error) - } finally { - isLoggingOut.value = false - } -}; - -// Function to change the active year (Tetap) const changeYear = (year) => { activeYear.value = year; }; diff --git a/pages/List-Pasien.vue b/pages/List-Pasien.vue deleted file mode 100644 index 055a766..0000000 --- a/pages/List-Pasien.vue +++ /dev/null @@ -1,635 +0,0 @@ - - - - - \ No newline at end of file diff --git a/pages/Setting/Master-Klinik.txt b/pages/Setting/Master-Klinik.txt deleted file mode 100644 index 0d02d36..0000000 --- a/pages/Setting/Master-Klinik.txt +++ /dev/null @@ -1,491 +0,0 @@ - - - - - diff --git a/pages/Setting/Master-KlinikRuang.txt b/pages/Setting/Master-KlinikRuang.txt deleted file mode 100644 index b96d569..0000000 --- a/pages/Setting/Master-KlinikRuang.txt +++ /dev/null @@ -1,376 +0,0 @@ - - - - - diff --git a/pages/Setting/Master-Loket.vue b/pages/Setting/Master-Loket.vue deleted file mode 100644 index 51c95cf..0000000 --- a/pages/Setting/Master-Loket.vue +++ /dev/null @@ -1,156 +0,0 @@ - - - - diff --git a/pages/Setting/MasterKlinik.vue b/pages/Setting/MasterKlinik.vue index c8cebd0..b3c144c 100644 --- a/pages/Setting/MasterKlinik.vue +++ b/pages/Setting/MasterKlinik.vue @@ -46,9 +46,9 @@