diff --git a/Proxy_Documentation.md b/Proxy_Documentation.md new file mode 100644 index 0000000..9257d21 --- /dev/null +++ b/Proxy_Documentation.md @@ -0,0 +1,66 @@ +# Dokumentasi Implementasi Proxy API (Nuxt 3) + +Dokumen ini menjelaskan cara menggunakan dan menambah proxy API di file `nuxt.config.ts` untuk menangani masalah CORS dan menyederhanakan pemanggilan endpoint backend. + +## 1. Menambah Proxy Baru di `nuxt.config.ts` + +Jika Anda memiliki API backend lain (misalnya departemen berbeda atau IP berbeda), Anda cukup menambah baris baru di dalam objek `routeRules`. + +### Contoh Konfigurasi: + +```typescript +// nuxt.config.ts +export default defineNuxtConfig({ + routeRules: { + // Proxy untuk Statistik (yang sudah ada) + "/stats-api/**": { + proxy: "http://10.10.150.100:8084/api/v1/**", + }, + + // Proxy untuk API Pasien (Contoh Tambahan) + "/patient-api/**": { + proxy: "http://10.10.150.101:8000/api/v2/**", + }, + + // Proxy untuk API Antrean (IP sama, prefix path berbeda) + "/queue-api/**": { + proxy: "http://10.10.150.100:8084/api/v1/queue/**", + }, + }, +}); +``` + +--- + +## 2. Cara Menggunakan di Composable + +Setelah didaftarkan di `nuxt.config.ts`, Anda tidak perlu lagi menulis IP Address di dalam kode Vue/TypeScript Anda. Gunakan path prefix yang sudah didefinisikan. + +### Contoh File: `composables/usePatientAPI.ts` + +```typescript +export const usePatientAPI = () => { + const fetchPatient = async (id: string) => { + // Alamat asli: http://10.10.150.101:8000/api/v2/patient/123 + // Cukup panggil seperti ini: + return await $fetch(`/patient-api/patient/${id}`); + }; + + return { fetchPatient }; +}; +``` + +--- + +## 3. Keuntungan Menggunakan Proxy + +1. **Menghindari CORS**: Browser tidak akan memblokir request karena seolah-olah request dikirim ke server yang sama dengan frontend. +2. **Keamanan**: IP backend asli tidak terekspos secara langsung di kode frontend (Client-side). +3. **Kemudahan Maintenance**: Jika IP Server backend berubah, Anda hanya perlu mengubah satu baris di `nuxt.config.ts` tanpa harus mencari dan mengganti di seluruh file `.vue` atau `.ts`. + +--- + +## 4. Tips Debugging Proxy + +- Jika menggunakan **Vite Dev Server**, pastikan Anda menjalankan ulang `npm run dev` setelah mengubah `nuxt.config.ts`. +- Cek tab **Network** di Developer Tools (F12). Anda akan melihat request ke `localhost:3000/stats-api/...` dan server Nuxt akan meneruskannya ke IP backend secara otomatis. diff --git a/app.vue b/app.vue index d53be0e..587c79d 100644 --- a/app.vue +++ b/app.vue @@ -1,7 +1,7 @@ \ No newline at end of file diff --git a/assets/styles/loginpage/login.scss b/assets/styles/loginpage/login.scss index a55a957..a836c90 100644 --- a/assets/styles/loginpage/login.scss +++ b/assets/styles/loginpage/login.scss @@ -1,17 +1,17 @@ /* assets/styles/loginpage/login.scss */ -@use '~/assets/scss/_colors.scss' as *; +@use "~/assets/scss/_colors.scss" as *; /* Main Background - Using Primary Color */ .login-background { background: $primary-500; /* Primary-500: #567EE7 */ - min-height: 100vh; + height: 100dvh; position: relative; overflow: hidden; } .login-background::before { /* No radial gradients */ - content: ''; + content: ""; position: absolute; top: 0; left: 0; @@ -40,16 +40,39 @@ } .floating-medical-icon .v-icon { - color: rgba(255, 255, 255, 0.15) !important; /* Light white for icons on primary background */ + color: rgba( + 255, + 255, + 255, + 0.15 + ) !important; /* Light white for icons on primary background */ } /* 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 { + 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%; +} /* Main Card - White */ .main-card { @@ -122,8 +145,8 @@ color: $neutral-100 !important; /* White text on primary button */ border: none; box-shadow: - 0 8px 25px rgba(86, 126, 231, 0.3), /* Primary shadow */ - 0 4px 12px rgba(86, 126, 231, 0.2); + 0 8px 25px rgba(86, 126, 231, 0.3), + /* Primary shadow */ 0 4px 12px rgba(86, 126, 231, 0.2); transition: all 0.3s ease; text-transform: none; font-size: 1rem; @@ -148,7 +171,12 @@ } .register-btn-dark:hover { - background: rgba(86, 126, 231, 0.05) !important; /* Light primary hover background */ + background: rgba( + 86, + 126, + 231, + 0.05 + ) !important; /* Light primary hover background */ border-color: $primary-600 !important; /* Primary-600 border on hover */ transform: translateY(-1px); } @@ -191,27 +219,26 @@ /* Dialog Accents */ .v-card-title .v-icon, .v-list-item .v-icon { - color: $primary-500 !important; /* Primary accents */ + color: $primary-500 !important; /* Primary accents */ } .v-btn[color="#FF9B1B"] { - background-color: $primary-500 !important; - color: $neutral-100 !important; + background-color: $primary-500 !important; + color: $neutral-100 !important; } .v-alert[color="orange"] { - border-left: 8px solid $primary-500 !important; - color: $neutral-900 !important; + border-left: 8px solid $primary-500 !important; + color: $neutral-900 !important; } /* Responsive Design Adjustments for single column */ @media (max-width: 960px) { - .main-card { margin: 1rem; max-width: 450px !important; /* Enforce max-width on smaller screens */ } - + .login-section-box { min-height: auto; padding: 2rem !important; @@ -219,11 +246,10 @@ } @media (max-width: 600px) { - .main-card { margin: 0.5rem; } - + .login-section-box { padding: 1.5rem !important; } diff --git a/components/layout/SideBar.vue b/components/layout/SideBar.vue index b799bc1..44eecd7 100644 --- a/components/layout/SideBar.vue +++ b/components/layout/SideBar.vue @@ -18,6 +18,9 @@ alt="Antrean Logo" class="sidebar-logo" :class="{ 'sidebar-logo-rail': rail }" + width="32" + height="32" + style="width: 32px; height: 32px; object-fit: contain;" />