From c2fe66ba0afb7015f556532bc4c9a07f42ad64a3 Mon Sep 17 00:00:00 2001 From: MRoyhanF Date: Fri, 20 Dec 2024 21:48:48 +0700 Subject: [PATCH 01/14] fix : filght | fix add 7 our for date UTC --- .github/workflows/ci.yml | 4 ++-- src/resources/views/pages/flight/create.edge | 10 ++++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 989b48c..a112e92 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,5 +34,5 @@ jobs: run: npm install # Step 4: Lint code - # - name: Lint code - # run: npm run lint \ No newline at end of file + - name: Lint code + run: npm run lint \ No newline at end of file diff --git a/src/resources/views/pages/flight/create.edge b/src/resources/views/pages/flight/create.edge index fd301fe..ffbd93b 100644 --- a/src/resources/views/pages/flight/create.edge +++ b/src/resources/views/pages/flight/create.edge @@ -175,8 +175,8 @@ const formData = { routeId: parseInt($('#routeId').val()), airplaneId: parseInt($('#airplaneId').val()), - departureTime: formatToISOString($('#departureTime').val()), - arrivalTime: formatToISOString($('#arrivalTime').val()), + departureTime: formatToISOString($('#departureTime').val(), 7), + arrivalTime: formatToISOString($('#arrivalTime').val(), 7), class: $('#classId').val(), isActive: true, baggage: parseInt($('#baggage').val()) || 20, // Default ke 20 jika kosong @@ -184,7 +184,7 @@ entertainment: $('#entertainment').is(':checked'), departureTerminalId: parseInt($('#departureTerminalId').val()), arrivalTerminalId: parseInt($('#arrivalTerminalId').val()), - discountId: $('#discountId').val() || null, + discountId: parseInt($('#discountId').val()) || null, }; console.log("Form Data:", formData); @@ -222,10 +222,12 @@ }); // Format waktu ke ISO string - function formatToISOString(dateTime) { + function formatToISOString(dateTime, hoursToAdd) { const date = new Date(dateTime); + date.setHours(date.getHours() + hoursToAdd); return date.toISOString(); } + }); From 18279d6431e1d75af2605eb931eb9aa4d7b3420b Mon Sep 17 00:00:00 2001 From: MRoyhanF Date: Sat, 21 Dec 2024 10:37:36 +0700 Subject: [PATCH 02/14] fix : ticket | create ticket --- public/css/app.css | 4 + src/resources/views/pages/ticket/create.edge | 216 +++++++++---------- 2 files changed, 101 insertions(+), 119 deletions(-) diff --git a/public/css/app.css b/public/css/app.css index 898d688..3d6bf51 100644 --- a/public/css/app.css +++ b/public/css/app.css @@ -1077,6 +1077,10 @@ video { border-inline-start-width: 1px; } +.border-t-2 { + border-top-width: 2px; +} + .border-none { border-style: none; } diff --git a/src/resources/views/pages/ticket/create.edge b/src/resources/views/pages/ticket/create.edge index 053157d..4bcf68e 100644 --- a/src/resources/views/pages/ticket/create.edge +++ b/src/resources/views/pages/ticket/create.edge @@ -52,102 +52,119 @@ -{{-- Selected Flights Display --}} - @@ -87,6 +105,39 @@ + + @endslot @end \ No newline at end of file From 5974a3dda573b333a40f188953b8a6184c166ef8 Mon Sep 17 00:00:00 2001 From: MRoyhanF Date: Sat, 21 Dec 2024 11:57:30 +0700 Subject: [PATCH 06/14] feat: ticket | validation delete ticket --- src/resources/views/pages/ticket/index.edge | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/resources/views/pages/ticket/index.edge b/src/resources/views/pages/ticket/index.edge index af22abe..7d3a066 100644 --- a/src/resources/views/pages/ticket/index.edge +++ b/src/resources/views/pages/ticket/index.edge @@ -116,7 +116,25 @@ Detail - + @component('components/ui/modal', { + title: 'Delete Ticket', + buttonClass: 'shadow-md py-1 px-3 inline-flex items-center gap-x-2 text-xs font-medium rounded-lg border border-transparent bg-red-300 text-red-800 hover:bg-red-400 focus:outline-none focus:bg-red-200 disabled:opacity-50 disabled:pointer-events-none', + }) + @slot('header') + Delete + @end + @slot('content') +
+

Are you sure you want to delete this Ticket?

+ +
+ + +
+
+ + @end + @end From 6aafc24117eed801e72d77fa538ca28235298ef0 Mon Sep 17 00:00:00 2001 From: MRoyhanF Date: Sat, 21 Dec 2024 12:21:53 +0700 Subject: [PATCH 07/14] feat: airlines | delete airlines --- src/resources/views/pages/airline/index.edge | 75 ++++++++++++++++++-- 1 file changed, 71 insertions(+), 4 deletions(-) diff --git a/src/resources/views/pages/airline/index.edge b/src/resources/views/pages/airline/index.edge index d1b081e..6d66de2 100644 --- a/src/resources/views/pages/airline/index.edge +++ b/src/resources/views/pages/airline/index.edge @@ -56,10 +56,47 @@ {{ airline.name }} {{ airline._count.Airplanes }} - {{-- Edit --}} - +
+ @component('components/ui/modal', { + title: 'Edit Airline', + buttonClass: 'shadow-md py-2 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-transparent bg-yellow-300 text-yellow-800 hover:bg-yellow-400 focus:outline-none focus:bg-yellow-200 disabled:opacity-50 disabled:pointer-events-none', + }) + @slot('header') + Edit + @end + @slot('content') +
+

Edit Airline

+ {{ airline.iataCode }} + +
+ {{-- --}} + +
+
+ + @end + @end + @component('components/ui/modal', { + title: 'Delete Airline', + buttonClass: 'shadow-md py-2 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-transparent bg-red-300 text-red-800 hover:bg-red-400 focus:outline-none focus:bg-red-200 disabled:opacity-50 disabled:pointer-events-none', + }) + @slot('header') + Delete + @end + @slot('content') +
+

Are you sure you want to delete this Airline?

+ +
+ + +
+
+ + @end + @end +
@end @@ -116,8 +153,38 @@ } }); }); + + }); + function deleteAirline(iataCode) { + $.ajax({ + url: '{{ api }}/api/v1/airlines/' + iataCode, + method: 'DELETE', + headers: { + 'Authorization': `Bearer ${token}` + }, + success: function (response) { + showToast("success", "Success", "Airline deleted successfully!"); + setTimeout(() => { + window.location.reload(); + }, 1000); + }, + error: function (xhr) { + if (xhr.responseJSON && xhr.responseJSON.errors) { + const errors = xhr.responseJSON.errors; + let errorMessages = ''; + errors.forEach(error => { + errorMessages += `${error.field}: ${error.message}\n`; + }); + showToast("error", "Error", errorMessages); + } else { + showToast("error", "Error", "An error occurred. Please try again."); + } + }, + }); + } + @endslot From 231bdc158abe9c0b2000d9cc71d38419f40dc2c6 Mon Sep 17 00:00:00 2001 From: MRoyhanF Date: Sat, 21 Dec 2024 12:44:34 +0700 Subject: [PATCH 08/14] feat: airplane | delete item --- src/modules/airline/airline.controller.js | 2 +- .../views/pages/airline/listAirplanes.edge | 76 +++++++++++++++++-- 2 files changed, 71 insertions(+), 7 deletions(-) diff --git a/src/modules/airline/airline.controller.js b/src/modules/airline/airline.controller.js index f48d430..c713d83 100644 --- a/src/modules/airline/airline.controller.js +++ b/src/modules/airline/airline.controller.js @@ -28,7 +28,7 @@ export const listAirplanes = async (req, res, next) => { const { token } = req; const airlinesResponse = await axios.get(`${api}/api/v1/airlines/${code}`); - + const data = { api: api, token: token, diff --git a/src/resources/views/pages/airline/listAirplanes.edge b/src/resources/views/pages/airline/listAirplanes.edge index 5dccddd..6274124 100644 --- a/src/resources/views/pages/airline/listAirplanes.edge +++ b/src/resources/views/pages/airline/listAirplanes.edge @@ -55,7 +55,6 @@ Name Type Price Per KM - Total Flights Action @@ -66,11 +65,48 @@ {{ data.name }} {{ data.type }} {{ data.pricePerKm }} - --- - - + +
+ @component('components/ui/modal', { + title: 'Edit AirPlane', + buttonClass: 'shadow-md py-2 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-transparent bg-yellow-300 text-yellow-800 hover:bg-yellow-400 focus:outline-none focus:bg-yellow-200 disabled:opacity-50 disabled:pointer-events-none', + }) + @slot('header') + Edit + @end + @slot('content') +
+

Edit Airplane

+ {{ data.id }} + +
+ {{-- --}} + +
+
+ + @end + @end + @component('components/ui/modal', { + title: 'Delete AirPlane', + buttonClass: 'shadow-md py-2 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-transparent bg-red-300 text-red-800 hover:bg-red-400 focus:outline-none focus:bg-red-200 disabled:opacity-50 disabled:pointer-events-none', + }) + @slot('header') + Delete + @end + @slot('content') +
+

Are you sure you want to delete this Airplane?

+ +
+ + +
+
+ + @end + @end +
@end @@ -134,6 +170,34 @@ }); }); + function deleteAirplane(id) { + $.ajax({ + url: '{{ api }}/api/v1/airplanes/' + id, + method: 'DELETE', + headers: { + 'Authorization': `Bearer ${token}` + }, + success: function (response) { + showToast("success", "Success", "Airplane deleted successfully!"); + setTimeout(() => { + window.location.reload(); + }, 1000); + }, + error: function (xhr) { + if (xhr.responseJSON && xhr.responseJSON.errors) { + const errors = xhr.responseJSON.errors; + let errorMessages = ''; + errors.forEach(error => { + errorMessages += `${error.field}: ${error.message}\n`; + }); + showToast("error", "Error", errorMessages); + } else { + showToast("error", "Error", "An error occurred. Please try again."); + } + }, + }); + } + @endslot From f54990727f5e00dd1a2f81909893669dbd64f97e Mon Sep 17 00:00:00 2001 From: MRoyhanF Date: Sat, 21 Dec 2024 12:51:50 +0700 Subject: [PATCH 09/14] feat: route | delete route --- src/resources/views/pages/route/index.edge | 75 ++++++++++++++++++++-- 1 file changed, 70 insertions(+), 5 deletions(-) diff --git a/src/resources/views/pages/route/index.edge b/src/resources/views/pages/route/index.edge index 82815e5..d056912 100644 --- a/src/resources/views/pages/route/index.edge +++ b/src/resources/views/pages/route/index.edge @@ -38,7 +38,7 @@ @end -
+
@@ -59,9 +59,47 @@ @else @@ -121,8 +159,35 @@ }, }); }); -}); + }); + function deleteRoute(id) { + $.ajax({ + url: '{{ api }}/api/v1/routes/' + id, + method: 'DELETE', + headers: { + 'Authorization': `Bearer ${token}` + }, + success: function (response) { + showToast("success", "Success", "Route deleted successfully!"); + setTimeout(() => { + window.location.reload(); + }, 1000); + }, + error: function (xhr) { + if (xhr.responseJSON && xhr.responseJSON.errors) { + const errors = xhr.responseJSON.errors; + let errorMessages = ''; + errors.forEach(error => { + errorMessages += `${error.field}: ${error.message}\n`; + }); + showToast("error", "Error", errorMessages); + } else { + showToast("error", "Error", "An error occurred. Please try again."); + } + }, + }); + } @endslot From 24554ad67c4b704b3bdded5162627ef2edb71a79 Mon Sep 17 00:00:00 2001 From: MRoyhanF Date: Sat, 21 Dec 2024 12:57:30 +0700 Subject: [PATCH 10/14] feat: airport | delete airport --- src/resources/views/pages/airport/index.edge | 74 +++++++++++++++++++- 1 file changed, 71 insertions(+), 3 deletions(-) diff --git a/src/resources/views/pages/airport/index.edge b/src/resources/views/pages/airport/index.edge index 509d358..57a780c 100644 --- a/src/resources/views/pages/airport/index.edge +++ b/src/resources/views/pages/airport/index.edge @@ -81,9 +81,48 @@ @else @@ -145,6 +184,35 @@ }); }); + + function deleteAirport(iataCode) { + $.ajax({ + url: '{{ api }}/api/v1/airports/' + iataCode, + method: 'DELETE', + headers: { + 'Authorization': `Bearer ${token}` + }, + success: function (response) { + showToast("success", "Success", "Airport deleted successfully!"); + setTimeout(() => { + window.location.reload(); + }, 1000); + }, + error: function (xhr) { + if (xhr.responseJSON && xhr.responseJSON.errors) { + const errors = xhr.responseJSON.errors; + let errorMessages = ''; + errors.forEach(error => { + errorMessages += `${error.field}: ${error.message}\n`; + }); + showToast("error", "Error", errorMessages); + } else { + showToast("error", "Error", "An error occurred. Please try again."); + } + }, + }); + } + @endslot From 2d07eaf90f7f8dfa6494823454a212b3d59bb4a6 Mon Sep 17 00:00:00 2001 From: MRoyhanF Date: Sat, 21 Dec 2024 13:03:49 +0700 Subject: [PATCH 11/14] feat: account | delete account --- public/css/app.css | 5 ++ src/modules/user/user.controller.js | 3 + src/resources/views/pages/user/index.edge | 83 +++++++++++++++++++---- 3 files changed, 77 insertions(+), 14 deletions(-) diff --git a/public/css/app.css b/public/css/app.css index 8a6035e..9f98dc7 100644 --- a/public/css/app.css +++ b/public/css/app.css @@ -1575,6 +1575,11 @@ video { color: rgb(21 128 61 / var(--tw-text-opacity, 1)); } +.text-red-700 { + --tw-text-opacity: 1; + color: rgb(185 28 28 / var(--tw-text-opacity, 1)); +} + .underline { text-decoration-line: underline; } diff --git a/src/modules/user/user.controller.js b/src/modules/user/user.controller.js index 88e795c..54718aa 100644 --- a/src/modules/user/user.controller.js +++ b/src/modules/user/user.controller.js @@ -11,6 +11,9 @@ export const index = async (req, res, next) => { }, }); + const userData = usersResponse.data.data || []; + console.log({userData}); + const data = { token : token, api : api, diff --git a/src/resources/views/pages/user/index.edge b/src/resources/views/pages/user/index.edge index ca2304e..c26f627 100644 --- a/src/resources/views/pages/user/index.edge +++ b/src/resources/views/pages/user/index.edge @@ -37,6 +37,7 @@ + @@ -93,6 +94,29 @@ Inactive @endif + @else @@ -106,6 +130,9 @@ From 6dfefbdb18f48ef9a2d20859503578227fe22648 Mon Sep 17 00:00:00 2001 From: MRoyhanF Date: Sat, 21 Dec 2024 13:07:25 +0700 Subject: [PATCH 12/14] update: logout | update modal validation --- src/resources/views/components/ui/sidebar.edge | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/resources/views/components/ui/sidebar.edge b/src/resources/views/components/ui/sidebar.edge index 2fe7976..735352f 100644 --- a/src/resources/views/components/ui/sidebar.edge +++ b/src/resources/views/components/ui/sidebar.edge @@ -95,13 +95,13 @@ Logout @end @slot('content') -
-

Apakah yakin mau keluar?

-
- - +
+

Are you sure you want to logout?

+
+ +
-
+
@end @end
From f226e4dd39c08a2539ce7dd6ca90a4f93fef9e2a Mon Sep 17 00:00:00 2001 From: MRoyhanF Date: Sat, 21 Dec 2024 13:21:37 +0700 Subject: [PATCH 13/14] udpate : readme --- README.md | 83 ++++++++++++++++++++++- src/resources/views/pages/auth/login.edge | 2 +- 2 files changed, 83 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d5464d6..c857e67 100644 --- a/README.md +++ b/README.md @@ -1 +1,82 @@ -# admin-Panel + +# 🎛️ AirHopper Admin Panel + +AirHopper Admin Panel adalah aplikasi web yang dirancang untuk membantu administrator dalam mengelola data dan fitur sistem pemesanan tiket pesawat AirHopper. Panel ini memberikan antarmuka yang intuitif untuk mengelola maskapai penerbangan, rute, pengguna, dan laporan transaksi. + +## 🌟 Fitur Utama + +- **Manajemen Maskapai Penerbangan**: Tambah, ubah, dan hapus data maskapai penerbangan dengan mudah. +- **Manajemen Penerbangan**: Kelola rute dan jadwal penerbangan. +- **Manajemen Pengguna**: Atur pengguna, termasuk otorisasi dan peran. +- **Laporan dan Statistik**: Pantau performa dan statistik melalui laporan interaktif. +- **Media Upload**: Dukungan untuk mengunggah gambar maskapai dengan integrasi ImageKit. +- **Autentikasi Aman**: Menggunakan JWT untuk akses dan manajemen keamanan. + +## 🛠️ Teknologi yang Digunakan + +- **Frontend Framework**: TailwindCSS untuk styling. +- **View Engine**: Edge.js untuk rendering halaman dinamis. +- **JavaScript**: Menggunakan Alpine.js untuk interaktivitas ringan. +- **Express.js**: Framework backend untuk mendukung API dan server-side rendering. +- **DataTable.js**: Membuat tabel data yang responsif dan interaktif. +- **Axios dan jQuery**: Untuk konsumsi API dan interaksi DOM. +- **Multer & ImageKit**: Mendukung upload file dan manajemen media. + +## 🚀 Cara Menggunakan + +### Prasyarat + +1. Node.js (minimal versi 18.x). +2. Server backend API sudah berjalan (lihat [AirHopper Backend](https://github.com/AirHopper/BackEnd)). +3. Alat manajemen API (Postman atau browser). + +### Langkah Instalasi + +1. Clone repositori ini: + ```bash + git clone https://github.com/AirHopper/AdminPanel.git + ``` +2. Masuk ke direktori proyek: + ```bash + cd AdminPanel + ``` +3. Instal dependensi: + ```bash + npm install + ``` +4. Konfigurasikan file lingkungan `.env`: + ```env + API_URL="your-backend-api-url" + PORT=333 + HOST="0.0.0.0" + NODE_ENV=development + ``` +5. Jalankan server: + ```bash + npm start + ``` +6. Akses Admin Panel di: + ```bash + http://localhost:3333 + ``` +## 📄 Dokumentasi API + +Admin Panel ini bergantung pada API backend untuk pengelolaan data. Pastikan API backend Anda sudah tersedia dan berjalan. Dokumentasi API tersedia di: + +1. **Postman**: [Link Postman Collection](https://documenter.getpostman.com/view/33280373/2sAYBbf9a7) +2. **Swagger**: [Swagger API Docs](https://air-hopper-api.padek.tech/api-docs) + +## 👥 Tim Pengembang + +Admin Panel ini dikembangkan oleh tim AirHopper dari program Studi Independen Kampus Merdeka - Binar Academy. + +- **Backend**: + - **Juan Verrel Tanuwijaya** + - **Muhamad Royhan Fadhli** + - **Ahmad Subhan Daryhadi** + - **Bima Rizqy Ramadhan** +- **Frontend dan Admin Panel**: + - **Ridhwan Tsalasah Putra** + - **Ryan Nicholas Purba** + - **M. Zaky Pria Maulana** + - **Joe Ferdinan** diff --git a/src/resources/views/pages/auth/login.edge b/src/resources/views/pages/auth/login.edge index ad86f80..e26ca89 100644 --- a/src/resources/views/pages/auth/login.edge +++ b/src/resources/views/pages/auth/login.edge @@ -135,7 +135,7 @@ setTimeout(() => { window.location.href = '/admin/dashboard'; - }, 2000); + }, 1000); }, error: function (xhr) { showToast("error", "Error", "Login failed. Please try again."); From 099029ed20ebaf3bd871cb1ba58c6b58fda900c2 Mon Sep 17 00:00:00 2001 From: MRoyhanF Date: Sat, 21 Dec 2024 13:23:40 +0700 Subject: [PATCH 14/14] validate Eslint --- src/modules/auth/auth.controller.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/auth/auth.controller.js b/src/modules/auth/auth.controller.js index c4f2385..bcdf95c 100644 --- a/src/modules/auth/auth.controller.js +++ b/src/modules/auth/auth.controller.js @@ -1,6 +1,6 @@ import axios from 'axios'; -export const loginPage = async (req, res, next) => { +export const loginPage = async ( res, next) => { try { const api = process.env.API_URL; @@ -17,7 +17,7 @@ export const loginPage = async (req, res, next) => { } }; -export const login = async (req, res, next) => { +export const login = async (req, res) => { try { const api = process.env.API_URL;
{{ data.ArrivalAirport.name }} {{ data.distance }} - +
+ @component('components/ui/modal', { + title: 'Edit Route', + buttonClass: 'shadow-md py-1 px-4 inline-flex items-center gap-x-2 font-medium rounded-lg border border-transparent bg-yellow-300 text-yellow-800 hover:bg-yellow-400 focus:outline-none focus:bg-yellow-200 disabled:opacity-50 disabled:pointer-events-none', + }) + @slot('header') + Edit + @end + @slot('content') +
+

Edit Route

+ {{ data.id }} + +
+ {{-- --}} + +
+
+ + @end + @end + @component('components/ui/modal', { + title: 'Delete Route', + buttonClass: 'shadow-md py-1 px-4 inline-flex items-center gap-x-2 font-medium rounded-lg border border-transparent bg-red-300 text-red-800 hover:bg-red-400 focus:outline-none focus:bg-red-200 disabled:opacity-50 disabled:pointer-events-none', + }) + @slot('header') + Delete + @end + @slot('content') +
+

Are you sure you want to delete this Route?

+ +
+ + +
+
+ + @end + @end +
{{ airport.City ? airport.City.name : '-' }} {{ airport.City ? airport.City.country : '-' }} - +
+ @component('components/ui/modal', { + title: 'Edit Airport', + buttonClass: 'shadow-md py-2 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-transparent bg-yellow-300 text-yellow-800 hover:bg-yellow-400 focus:outline-none focus:bg-yellow-200 disabled:opacity-50 disabled:pointer-events-none', + }) + @slot('header') + Edit + @end + @slot('content') +
+

Edit Airport

+ {{ airport.iataCode }} + +
+ {{-- --}} + +
+
+ + @end + @end + @component('components/ui/modal', { + title: 'Delete Airport', + buttonClass: 'shadow-md py-2 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-transparent bg-red-300 text-red-800 hover:bg-red-400 focus:outline-none focus:bg-red-200 disabled:opacity-50 disabled:pointer-events-none', + }) + @slot('header') + Delete + @end + @slot('content') +
+

Are you sure you want to delete this Airport?

+

{{ airport.name }}

+ +
+ + +
+
+ + @end + @end +
Email Role StatusAction
+
+ @component('components/ui/modal', { + title: 'Delete Account', + buttonClass: 'shadow-md py-2 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-transparent bg-red-300 text-red-800 hover:bg-red-400 focus:outline-none focus:bg-red-200 disabled:opacity-50 disabled:pointer-events-none', + }) + @slot('header') + Delete + @end + @slot('content') +
+

Are you sure you want to delete this Account?

+

{{ user.email }}

+
+ + +
+
+ + @end + @end +
+