From 35024b479754e5746a98d3a9d4a5c3be328bbd01 Mon Sep 17 00:00:00 2001 From: Fanrouver Date: Tue, 28 Oct 2025 10:14:00 +0700 Subject: [PATCH] update akbar tampilan login dashboard dan verifikasi --- assets/styles/loginpage/login.css | 326 ++---- components/MonitorPasien/ticketCard.vue | 130 +++ components/ProfilePopup.vue | 404 +++++-- components/ReorderMenuDialog.vue | 75 -- components/SideBar.vue | 44 +- composables/usePermissions.ts | 1 + nuxt.config.ts | 8 +- package-lock.json | 18 + package.json | 5 +- pages/CheckInPasien/checkIn.vue | 1068 ++++++++++++++++++ pages/Dashboard.vue | 520 ++++++--- pages/LoginPage.vue | 207 ++-- pages/MonitoringPasien/monitoringPasien.vue | 252 +++++ pages/MonitoringPasien/pasien/[id].vue | 298 +++++ pages/Profile/Pengaturan.vue.txt | 1126 +++++++++++++++++++ pages/Profile/Profil.vue | 800 +++++++++++++ pages/verifikasiAkun/VerifikasiAkun.vue | 425 +++++-- public/AntreanLogo.png | Bin 0 -> 18525 bytes public/AntreanLogobg.png | Bin 0 -> 47421 bytes stores/navItems.ts | 81 +- 20 files changed, 4922 insertions(+), 866 deletions(-) create mode 100644 components/MonitorPasien/ticketCard.vue delete mode 100644 components/ReorderMenuDialog.vue create mode 100644 pages/CheckInPasien/checkIn.vue create mode 100644 pages/MonitoringPasien/monitoringPasien.vue create mode 100644 pages/MonitoringPasien/pasien/[id].vue create mode 100644 pages/Profile/Pengaturan.vue.txt create mode 100644 pages/Profile/Profil.vue create mode 100644 public/AntreanLogo.png create mode 100644 public/AntreanLogobg.png diff --git a/assets/styles/loginpage/login.css b/assets/styles/loginpage/login.css index e435343..3d2671c 100644 --- a/assets/styles/loginpage/login.css +++ b/assets/styles/loginpage/login.css @@ -1,60 +1,47 @@ /* assets/styles/loginpage/login.css */ -/* Main Background */ +/* --- COLOR DEFINITIONS --- */ +/* Base Orange: #FF9B1B (New) */ +/* Hover/Darker Orange: #E68A00 (Calculated darker shade for hover effect) */ +/* --- END COLOR DEFINITIONS --- */ + + +/* Main Background - Now Orange */ .login-background { - background: linear-gradient(135deg, #FFC857 0%, #FF9B1B 25%, #FF8F00 50%, #FF6F00 75%, #E65100 100%); + background: #FF9B1B; /* Solid Orange Background: #FF9B1B */ min-height: 100vh; position: relative; overflow: hidden; - padding-top: 64px; + /* padding-top: 64px; - REMOVED */ } .login-background::before { + /* No radial gradients */ content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; - background: - radial-gradient(circle at 10% 20%, rgba(255, 200, 87, 0.4) 0%, transparent 50%), - radial-gradient(circle at 90% 80%, rgba(255, 155, 27, 0.4) 0%, transparent 50%), - radial-gradient(circle at 50% 50%, rgba(230, 81, 0, 0.3) 0%, transparent 70%); pointer-events: none; + background: none; } -/* Navigation Bar */ -.navbar { - background: rgba(255, 255, 255, 0.1) !important; - backdrop-filter: blur(50px); - border-bottom: 1px solid rgba(255, 255, 255, 0.2); - position: fixed !important; - top: 0; - left: 0; - right: 0; - z-index: 1000; -} +/* Navigation Bar Styles - REMOVED */ -.brand-logo { - color: white; - font-size: 1.2rem; -} -.nav-link { - color: white !important; - text-transform: none; - font-weight: 500; -} - -/* Floating Medical Icons */ +/* Floating Medical Icons - Subtle on Orange Background */ .floating-medical-icon { position: absolute; - animation: dvdBounce 20s linear infinite; opacity: 0.8; transition: opacity 0.3s ease; z-index: 1; width: fit-content; height: fit-content; + top: auto; + left: auto; + bottom: auto; + right: auto; } .floating-medical-icon:hover { @@ -62,141 +49,18 @@ } .floating-medical-icon .v-icon { - color: rgba(255, 255, 255, 0.15) !important; + color: rgba(255, 255, 255, 0.15) !important; /* Light white for icons on orange background */ } -.icon-1 { - top: 0%; - left: 0%; - animation-delay: 0s; - animation-duration: 25s; - animation-name: dvdBounce1; -} +/* Specific icon positioning - now static */ +.icon-1 { top: 15%; left: 5%; } +.icon-2 { top: 20%; right: 10%; } +.icon-3 { bottom: 10%; left: 15%; } +.icon-4 { top: 60%; left: 10%; } +.icon-5 { bottom: 20%; right: 5%; } +.icon-6 { top: 35%; left: 20%; } -.icon-1 .v-icon { - color: rgba(6, 37, 83, 0.15) !important; -} - -.icon-2 { - top: 0%; - right: 0%; - animation-delay: 0s; - animation-duration: 30s; - animation-name: dvdBounce2; -} - -.icon-2 .v-icon { - color: rgba(15, 180, 70, 0.12) !important; -} - -.icon-3 { - bottom: 0%; - left: 0%; - animation-delay: 0s; - animation-duration: 22s; - animation-name: dvdBounce3; -} - -.icon-3 .v-icon { - color: rgba(23, 178, 206, 0.18) !important; -} - -.icon-4 { - top: 50%; - left: 0%; - animation-delay: 0s; - animation-duration: 28s; - animation-name: dvdBounce4; -} - -.icon-4 .v-icon { - color: rgba(223, 8, 8, 0.14) !important; -} - -.icon-5 { - bottom: 0%; - right: 0%; - animation-delay: 0s; - animation-duration: 26s; - animation-name: dvdBounce5; -} - -.icon-5 .v-icon { - color: rgba(148, 15, 236, 0.16) !important; -} - -.icon-6 { - top: 25%; - left: 0%; - animation-delay: 0s; - animation-duration: 24s; - animation-name: dvdBounce6; -} - -.icon-6 .v-icon { - color: rgba(87, 48, 5, 0.13) !important; -} - -/* DVD Bounce Animation 1 - Top Left to Bottom Right */ -@keyframes dvdBounce1 { - 0% { transform: translate(0, 0); } - 25% { transform: translate(80vw, 70vh); } - 50% { transform: translate(20vw, 10vh); } - 75% { transform: translate(70vw, 80vh); } - 100% { transform: translate(0, 0); } -} - -/* DVD Bounce Animation 2 - Top Right to Bottom Left */ -@keyframes dvdBounce2 { - 0% { transform: translate(0, 0); } - 25% { transform: translate(-75vw, 60vh); } - 50% { transform: translate(-30vw, 20vh); } - 75% { transform: translate(-85vw, 75vh); } - 100% { transform: translate(0, 0); } -} - -/* DVD Bounce Animation 3 - Bottom Left to Top Right */ -@keyframes dvdBounce3 { - 0% { transform: translate(0, 0); } - 25% { transform: translate(70vw, -60vh); } - 50% { transform: translate(40vw, -80vh); } - 75% { transform: translate(90vw, -30vh); } - 100% { transform: translate(0, 0); } -} - -/* DVD Bounce Animation 4 - Middle Left across screen */ -@keyframes dvdBounce4 { - 0% { transform: translate(0, 0); } - 16.6% { transform: translate(60vw, -30vh); } - 33.3% { transform: translate(90vw, 20vh); } - 50% { transform: translate(50vw, 40vh); } - 66.6% { transform: translate(10vw, -20vh); } - 83.3% { transform: translate(80vw, -40vh); } - 100% { transform: translate(0, 0); } -} - -/* DVD Bounce Animation 5 - Bottom Right to Top Left */ -@keyframes dvdBounce5 { - 0% { transform: translate(0, 0); } - 25% { transform: translate(-60vw, -70vh); } - 50% { transform: translate(-90vw, -20vh); } - 75% { transform: translate(-40vw, -80vh); } - 100% { transform: translate(0, 0); } -} - -/* DVD Bounce Animation 6 - Complex zigzag pattern */ -@keyframes dvdBounce6 { - 0% { transform: translate(0, 0); } - 14.3% { transform: translate(50vw, 30vh); } - 28.6% { transform: translate(85vw, -20vh); } - 42.9% { transform: translate(30vw, 60vh); } - 57.1% { transform: translate(70vw, 10vh); } - 71.4% { transform: translate(15vw, 70vh); } - 85.7% { transform: translate(80vw, 40vh); } - 100% { transform: translate(0, 0); } -} - -/* Main Card - Contains Both Sections */ +/* Main Card - White */ .main-card { z-index: 3; max-width: 1100px; @@ -205,16 +69,14 @@ } .white-card { - background: white !important; + background: white !important; /* Main card background is white */ border: 1px solid rgba(0, 0, 0, 0.1); - box-shadow: - 0 20px 50px rgba(0, 0, 0, 0.15), - 0 8px 25px rgba(0, 0, 0, 0.1); + box-shadow: none; /* No shadow for the main white card */ } -/* Left Section Styling */ +/* Left Section Styling (White) */ .text-section-box { - background: linear-gradient(135deg, #61cbdd 0%, #4194c4 50%, #2089b9 100%); + background: white; /* Kept as white */ min-height: 600px; position: relative; overflow: hidden; @@ -227,9 +89,7 @@ left: 0; right: 0; bottom: 0; - background: - radial-gradient(circle at 20% 30%, rgba(255, 255, 255, 0.15) 0%, transparent 50%), - radial-gradient(circle at 80% 70%, rgba(255, 255, 255, 0.1) 0%, transparent 50%); + background: none; pointer-events: none; } @@ -240,31 +100,31 @@ } .hero-title-box { - color: white; + color: #FF9B1B; /* Orange title on white background: #FF9B1B */ font-size: 2.5rem; font-weight: 900; line-height: 1.1; margin-bottom: 0.5rem; - text-shadow: 2px 2px 8px rgba(0, 0, 0, 0.2); + text-shadow: none; } .hero-description-box { - color: rgba(255, 255, 255, 0.95); + color: #555; /* Darker text for readability on white */ font-size: 1rem; line-height: 1.6; margin-top: 2rem; - text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.2); + text-shadow: none; } .hospital-logo-large { height: 80px; width: auto; - filter: drop-shadow(2px 2px 6px rgba(0, 0, 0, 0.3)); + filter: drop-shadow(2px 2px 6px rgba(0, 0, 0, 0.1)); } -/* Right Section Styling */ +/* Right Login Section (White) */ .login-section-box { - background: white; + background: white; /* Changed to white */ min-height: 600px; } @@ -279,9 +139,9 @@ box-shadow: 0 20px 50px rgba(0, 0, 0, 0.2); } -/* Card Header - Dark Text */ +/* Card Header - Dark Text for white background */ .welcome-title-dark { - color: #37474F; + color: #333; /* Dark text on white background */ font-size: 1.1rem; font-weight: 700; letter-spacing: 1px; @@ -289,14 +149,14 @@ } .login-instruction-dark { - color: #546E7A; + color: #777; /* Grey text for instruction on white background */ font-size: 0.8rem; letter-spacing: 0.3px; } -/* App Title - Dark */ +/* App Title - Dark for white background */ .app-title-dark { - color: #0053AD; + color: #FF9B1B; /* Orange app title: #FF9B1B */ text-shadow: none; } @@ -307,19 +167,19 @@ } .sso-text-dark { - color: #546E7A; + color: #555; /* Dark grey for SSO text */ font-size: 0.95rem; font-weight: 500; } -/* Buttons */ +/* Buttons (Orange theme) */ .login-btn { - background: linear-gradient(135deg, #0053AD 0%, #0663C7 50%, #0671E0 100%) !important; - color: white !important; + background: #FF9B1B !important; /* Solid Orange button: #FF9B1B */ + color: white !important; /* White text on orange button */ border: none; - box-shadow: - 0 8px 25px rgba(0, 83, 173, 0.3), - 0 4px 12px rgba(0, 83, 173, 0.2); + box-shadow: + 0 8px 25px rgba(255, 155, 27, 0.3), /* Orange shadow: #FF9B1B */ + 0 4px 12px rgba(255, 155, 27, 0.2); transition: all 0.3s ease; text-transform: none; font-size: 1rem; @@ -328,15 +188,15 @@ .login-btn:hover { transform: translateY(-2px); - background: linear-gradient(135deg, #004A9B 0%, #0558B0 50%, #0661CA 100%) !important; - box-shadow: - 0 12px 30px rgba(0, 83, 173, 0.4), - 0 6px 15px rgba(0, 83, 173, 0.3); + background: #E68A00 !important; /* Slightly darker orange on hover */ + box-shadow: + 0 12px 30px rgba(255, 155, 27, 0.4), + 0 6px 15px rgba(255, 155, 27, 0.3); } .register-btn-dark { - color: #0053AD !important; - border: 2px solid #0053AD !important; + color: #FF9B1B !important; /* Orange text for register button: #FF9B1B */ + border: 2px solid #FF9B1B !important; /* Orange border: #FF9B1B */ background: transparent !important; transition: all 0.3s ease; text-transform: none; @@ -344,39 +204,39 @@ } .register-btn-dark:hover { - background: rgba(0, 83, 173, 0.05) !important; - border-color: #0663C7 !important; + background: rgba(255, 155, 27, 0.05) !important; /* Light orange hover background */ + border-color: #E68A00 !important; /* Darker orange border on hover */ transform: translateY(-1px); } -/* Custom Divider - Dark */ +/* Custom Divider - Dark for white background */ .custom-divider-dark { - border-color: rgba(0, 0, 0, 0.12) !important; + border-color: rgba(0, 0, 0, 0.1) !important; /* Light grey divider */ opacity: 1 !important; } -/* Help Text and Links - Dark */ +/* Help Text and Links - Dark for white background */ .help-text-dark { - color: #546E7A; + color: #555; /* Dark grey help text */ font-size: 0.9rem; } .contact-link-dark { - color: #0053AD !important; + color: #FF9B1B !important; /* Orange link: #FF9B1B */ text-decoration: underline; text-transform: none; font-size: 0.9rem; } .help-link-dark { - color: #78909C; + color: #777; /* Grey link */ font-size: 0.85rem; text-decoration: underline; cursor: pointer; } .help-link-dark:hover { - color: #0053AD; + color: #FF9B1B; /* Orange on hover: #FF9B1B */ } /* Transparent Background */ @@ -384,53 +244,27 @@ background: transparent !important; } -/* Navigation Dropdown Styles */ -.nav-dropdown { - background: rgba(255, 255, 255, 0.95); - backdrop-filter: blur(20px); - border-radius: 12px; - box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2); - min-width: 220px; - border: 1px solid rgba(255, 255, 255, 0.2); +/* Navigation Dropdown Styles - REMOVED */ + +/* Dialog Accents */ +.v-card-title .v-icon, +.v-list-item .v-icon { + color: #FF9B1B !important; /* Orange accents: #FF9B1B */ } -.dropdown-item { - color: #FF9B1B; - transition: all 0.3s ease; - border-radius: 8px; - margin: 4px 8px; - padding: 8px 12px; +.v-btn[color="#FF9B1B"] { + background-color: #FF9B1B !important; + color: white !important; } -.dropdown-item:hover { - background: linear-gradient(135deg, #FF9B1B 0%, #FF8F00 100%); - color: white; - transform: translateX(4px); -} - -.dropdown-item .v-icon { - transition: all 0.3s ease; -} - -.dropdown-item:hover .v-icon { - transform: scale(1.1); -} - -.nav-link { - text-transform: none; - font-weight: 500; - transition: all 0.3s ease; -} - -.nav-link:hover { - background: rgba(255, 255, 255, 0.1); +.v-alert[color="orange"] { + border-left: 8px solid #FF9B1B !important; + color: #333 !important; } /* Responsive Design */ @media (max-width: 960px) { - .login-background { - padding-top: 56px; - } + /* .login-background padding adjustment REMOVED */ .main-card { margin: 1rem; @@ -455,9 +289,7 @@ } @media (max-width: 600px) { - .login-background { - padding-top: 56px; - } + /* .login-background padding adjustment REMOVED */ .main-card { margin: 0.5rem; diff --git a/components/MonitorPasien/ticketCard.vue b/components/MonitorPasien/ticketCard.vue new file mode 100644 index 0000000..51098bd --- /dev/null +++ b/components/MonitorPasien/ticketCard.vue @@ -0,0 +1,130 @@ + + + + + \ No newline at end of file diff --git a/components/ProfilePopup.vue b/components/ProfilePopup.vue index 3426985..8727b93 100644 --- a/components/ProfilePopup.vue +++ b/components/ProfilePopup.vue @@ -4,7 +4,7 @@ :close-on-content-click="false" location="top end" origin="bottom right" - transition="slide-y-transition" + transition="scale-transition" open-on-hover > - -
- - - -
-
+ + +
+
+
+
+ + + +
+ mdi-check +
+
+

{{ user?.name || user?.preferred_username || 'User' }} -

-
+ +

{{ user?.email || 'No email' }} -

-
- ID: {{ user?.id?.substring(0, 8) }}... -
+

+ + {{ user?.id?.substring(0, 10) }}... +
- - - - - Pengaturan Akun - + + + - + - +
+ + + + Notifikasi + + + + + + + + Bantuan & Dukungan + + +
+ + + + + - - - {{ isLoggingOut ? 'Logging out...' : 'Keluar' }} - -
-
+ {{ isLoggingOut ? 'Keluar...' : 'Keluar' }} + + @@ -146,7 +203,6 @@ const signOut = async () => { menu.value = false; try { - // 🚨 Emits event up to SideBar to trigger useAuth().logout() emit('logout'); } finally { isLoggingOut.value = false; @@ -156,21 +212,205 @@ const signOut = async () => { const handleAction = (action) => { switch(action) { case 'account': - navigateTo('/settings/account') + navigateTo('/Profile/Pengaturan') break; case 'profile': - navigateTo('/profile') + navigateTo('/Profile/Profil') break; + case 'notifications': + navigateTo('/notifications') + break; + case 'help': + navigateTo('/help') + break; + case 'darkMode': + darkMode.value = !darkMode.value; + return; } - if (action !== 'darkMode') { - menu.value = false; - } + menu.value = false; }; \ No newline at end of file diff --git a/components/ReorderMenuDialog.vue b/components/ReorderMenuDialog.vue deleted file mode 100644 index 4c75f83..0000000 --- a/components/ReorderMenuDialog.vue +++ /dev/null @@ -1,75 +0,0 @@ - \ No newline at end of file diff --git a/components/SideBar.vue b/components/SideBar.vue index 7267487..50de1ac 100644 --- a/components/SideBar.vue +++ b/components/SideBar.vue @@ -23,7 +23,8 @@ - Tunggu proses verifikasi dan aktivasi akun - + mdi-phone Hubungi Admin @@ -282,24 +192,20 @@ - - - mdi-account-tie - Kontak Administrator + + mdi-account-tie Kontak Administrator - +
- mdi-phone-settings -
- + mdi-phone-settings
+ + mdi-office-building
IT Support RSSA @@ -309,11 +215,10 @@
- + + mdi-phone
(0341) 343343 ext. 1234 @@ -323,11 +228,10 @@
- + + mdi-email
it-support@rssa.malang.go.id @@ -337,11 +241,10 @@
- + + mdi-clock
Senin - Jumat: 07:00 - 15:00 @@ -352,19 +255,18 @@
- + + color="orange" >
Catatan: Pendaftaran akun memerlukan verifikasi dokumen dan dapat memakan waktu 1-2 hari kerja.
- + mdi-content-copy Salin Info @@ -406,6 +307,15 @@ const successMessage = ref('') const showRegistrationDialog = ref(false) const showAdminContact = ref(false) +// Hospital Profile URL +const HOSPITAL_PROFILE_URL = 'https://rsusaifulanwar.jatimprov.go.id/v2/' + +// Function to navigate to external hospital profile site +// NOTE: This function is no longer called in the template since the menu item was removed. +const goToHospitalProfile = (): void => { + window.open(HOSPITAL_PROFILE_URL, '_blank') +} + // Check URL parameters for errors const route = useRoute() onMounted(() => { @@ -414,7 +324,7 @@ onMounted(() => { } }) -// Custom login handler +// Custom login handler (pointing to Keycloak SSO logic) const handleLogin = async (): Promise => { isLoading.value = true errorMessage.value = '' @@ -422,7 +332,8 @@ const handleLogin = async (): Promise => { try { console.log('Starting login process...') - + + // Call API route to initiate Keycloak login process const response = await $fetch('/api/auth/keycloak-login', { method: 'POST' }) @@ -430,7 +341,8 @@ const handleLogin = async (): Promise => { if (response?.success && response?.data?.authUrl) { console.log('Redirecting to Keycloak...') successMessage.value = 'Redirecting to Keycloak...' - + + // Redirect the user to the Keycloak authorization URL setTimeout(() => { window.location.href = response.data!.authUrl }, 500) @@ -439,31 +351,44 @@ const handleLogin = async (): Promise => { } } catch (error: any) { console.error('Login error:', error) + // Display the error message errorMessage.value = `Login failed: ${error.message || 'Please try again.'}` } finally { - isLoading.value = false + // Only set isLoading back to false if no redirect is happening + if (!successMessage.value.includes('Redirecting')) { + isLoading.value = false + } } } // Copy contact information to clipboard const copyContactInfo = async (): Promise => { + // Updated contact info block from user's provided code const contactInfo = ` IT Support RSSA Telepon: (0341) 343343 ext. 1234 Email: it-support@rssa.malang.go.id -Jam Operasional: Senin - Jumat, 08:00 - 16:00 +Jam Operasional: Senin - Jumat, 07:00 - 15:00 `.trim() - + try { + // Use the Clipboard API await navigator.clipboard.writeText(contactInfo) successMessage.value = 'Informasi kontak berhasil disalin!' showAdminContact.value = false - + + // Clear the success message after a short delay setTimeout(() => { successMessage.value = '' }, 3000) } catch (error) { console.error('Failed to copy contact info:', error) + // Fallback or simple alert for error + errorMessage.value = 'Gagal menyalin informasi kontak. Silakan coba salin manual.' + + setTimeout(() => { + errorMessage.value = '' + }, 3000) } } diff --git a/pages/MonitoringPasien/monitoringPasien.vue b/pages/MonitoringPasien/monitoringPasien.vue new file mode 100644 index 0000000..6dea9b0 --- /dev/null +++ b/pages/MonitoringPasien/monitoringPasien.vue @@ -0,0 +1,252 @@ + + + + + \ No newline at end of file diff --git a/pages/MonitoringPasien/pasien/[id].vue b/pages/MonitoringPasien/pasien/[id].vue new file mode 100644 index 0000000..695df6d --- /dev/null +++ b/pages/MonitoringPasien/pasien/[id].vue @@ -0,0 +1,298 @@ + + + + + \ No newline at end of file diff --git a/pages/Profile/Pengaturan.vue.txt b/pages/Profile/Pengaturan.vue.txt new file mode 100644 index 0000000..6332cc7 --- /dev/null +++ b/pages/Profile/Pengaturan.vue.txt @@ -0,0 +1,1126 @@ + + + + + \ No newline at end of file diff --git a/pages/Profile/Profil.vue b/pages/Profile/Profil.vue new file mode 100644 index 0000000..2bcbd45 --- /dev/null +++ b/pages/Profile/Profil.vue @@ -0,0 +1,800 @@ + + + + + \ No newline at end of file diff --git a/pages/verifikasiAkun/VerifikasiAkun.vue b/pages/verifikasiAkun/VerifikasiAkun.vue index 3113121..ccbf554 100644 --- a/pages/verifikasiAkun/VerifikasiAkun.vue +++ b/pages/verifikasiAkun/VerifikasiAkun.vue @@ -1,115 +1,138 @@