diff --git a/index.html b/index.html index 169f4e9..a63d5ee 100644 --- a/index.html +++ b/index.html @@ -2,13 +2,13 @@ - + - Vite + React + Antrian Apps
diff --git a/package-lock.json b/package-lock.json index 9e63105..a1b3cf0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "react": "^19.0.0", "react-bootstrap": "^2.10.9", "react-dom": "^19.0.0", + "react-icons": "^5.5.0", "react-player": "^2.16.0", "react-redux": "^9.2.0", "react-router-dom": "^6.29.0", @@ -4166,6 +4167,15 @@ "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==", "license": "MIT" }, + "node_modules/react-icons": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz", + "integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==", + "license": "MIT", + "peerDependencies": { + "react": "*" + } + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", @@ -7852,6 +7862,12 @@ "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==" }, + "react-icons": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz", + "integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==", + "requires": {} + }, "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", diff --git a/package.json b/package.json index bf239c9..030ff14 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "react": "^19.0.0", "react-bootstrap": "^2.10.9", "react-dom": "^19.0.0", + "react-icons": "^5.5.0", "react-player": "^2.16.0", "react-redux": "^9.2.0", "react-router-dom": "^6.29.0", diff --git a/public/queue-white.svg b/public/queue-white.svg new file mode 100644 index 0000000..aa006a5 --- /dev/null +++ b/public/queue-white.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/public/queue.svg b/public/queue.svg new file mode 100644 index 0000000..3675f73 --- /dev/null +++ b/public/queue.svg @@ -0,0 +1,15 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/components/Admin/AdminFooter.jsx b/src/components/Admin/AdminFooter.jsx new file mode 100644 index 0000000..afa0538 --- /dev/null +++ b/src/components/Admin/AdminFooter.jsx @@ -0,0 +1,13 @@ +import { Container } from "react-bootstrap"; + +const AdminFooter = () => { + return ( + + ); +}; + +export default AdminFooter; \ No newline at end of file diff --git a/src/components/Admin/AdminNavbar.jsx b/src/components/Admin/AdminNavbar.jsx new file mode 100644 index 0000000..d436b74 --- /dev/null +++ b/src/components/Admin/AdminNavbar.jsx @@ -0,0 +1,13 @@ +import { Navbar, Container } from "react-bootstrap"; + +const AdminNavbar = () => { + return ( + + + Admin Dashboard + + + ); +}; + +export default AdminNavbar; \ No newline at end of file diff --git a/src/components/Admin/AdminSidebar.jsx b/src/components/Admin/AdminSidebar.jsx new file mode 100644 index 0000000..5e8a446 --- /dev/null +++ b/src/components/Admin/AdminSidebar.jsx @@ -0,0 +1,77 @@ +/* eslint-disable no-unused-vars */ +import { useState } from "react"; +import { NavLink } from "react-router-dom"; +import { FaList, FaPhone, FaChartBar, FaCog, FaTv, FaThList, FaChevronDown, FaChevronRight, FaTools } from "react-icons/fa"; + +const AdminSidebar = () => { + const [openMenu, setOpenMenu] = useState(null); + + const toggleMenu = (menu) => { + setOpenMenu(openMenu === menu ? null : menu); + }; + + return ( +
+
Admin Menu
+ + {/* Antrian Menu */} +
+ + {openMenu === "antrian" && ( +
+ + Daftar Antrian + + + Panggil Antrian + + {/* + Laporan Antrian + */} + + Pengaturan Layar + + + Pengaturan Menu + +
+ )} +
+ + {/* Monitor Menu */} +
+ + {openMenu === "monitor" && ( +
+ + +
+ )} +
+
+ ); +}; + +export default AdminSidebar; diff --git a/src/components/Admin/QueueActions.jsx b/src/components/Admin/QueueActions.jsx new file mode 100644 index 0000000..25cab5f --- /dev/null +++ b/src/components/Admin/QueueActions.jsx @@ -0,0 +1,119 @@ +const queueData = [ + { id: 1, name: "John Doe", phone: "08123456789", service: "Siap Print", serviceId: "J0001", locket: "01", startAt: "10:30 AM", completedAt: "10:30 AM", queueNumber: "001", status: "Menunggu", called: false, active: true, audio: "Default"}, + { id: 2, name: "Jane Smith", phone: "08234567890", service: "Design", serviceId: "J0002", locket: "04", startAt: "11:15 AM", completedAt: "11:15 AM", queueNumber: "002", status: "Dilayani", called: false, active: true, audio: "Beep"}, + { id: 3, name: "Michael Johnson", phone: "08345678901", service: "FotoCopy", serviceId: "J0003", locket: "08", startAt: "11:50 AM", completedAt: "11:50 AM", queueNumber: "003", status: "Selesai", called: false, active: true, audio: "Bell"}, + { id: 4, name: "Emily Brown", phone: "08456789012", service: "Tamu", serviceId: "J0006", locket: "02", startAt: "12:10 PM", completedAt: "12:10 PM", queueNumber: "004", status: "Menunggu", called: false, active: true, audio: "Chime"}, + { id: 5, name: "David Wilson", phone: "08567890123", service: "Online", serviceId: "J0005", locket: "05", startAt: "12:50 PM", completedAt: "12:50 PM", queueNumber: "005", status: "Dilayani", called: false, active: true, audio: "Ding"}, + { id: 6, name: "Sophia Martinez", phone: "08678901234", service: "Online", serviceId: "J0005", locket: "06", startAt: "01:30 PM", completedAt: "01:30 PM", queueNumber: "006", status: "Selesai", called: false, active: true, audio: "Ping"}, + { id: 7, name: "James Anderson", phone: "08789012345", service: "Siap Print", serviceId: "J0001", locket: "03", startAt: "02:15 PM", completedAt: "02:15 PM", queueNumber: "007", status: "Menunggu", called: false, active: true, audio: "Chirp"}, + { id: 8, name: "Olivia Thomas", phone: "08890123456", service: "Design", serviceId: "J0002", locket: "07", startAt: "02:50 PM", completedAt: "02:50 PM", queueNumber: "008", status: "Dilayani", called: false, active: true, audio: "Ring"}, + { id: 9, name: "Liam White", phone: "08901234567", service: "FotoCopy", serviceId: "J0003", locket: "09", startAt: "03:20 PM", completedAt: "03:20 PM", queueNumber: "009", status: "Selesai", called: false, active: true, audio: "Tone"}, + { id: 10, name: "Emma Harris", phone: "08012345678", service: "Siap Print", serviceId: "J0001", locket: "10", startAt: "03:50 PM", completedAt: "03:50 PM", queueNumber: "010", status: "Menunggu", called: false, active: true, audio: "Alarm" }, + { id: 11, name: "John Doe", phone: "08123456789", service: "Siap Print", serviceId: "J0001", locket: "01", startAt: "10:30 AM", completedAt: "10:30 AM", queueNumber: "001", status: "Menunggu", called: false, active: true, audio: "Default"}, + { id: 12, name: "Jane Smith", phone: "08234567890", service: "Design", serviceId: "J0002", locket: "04", startAt: "11:15 AM", completedAt: "11:15 AM", queueNumber: "002", status: "Dilayani", called: false, active: true, audio: "Beep"}, + { id: 13, name: "Michael Johnson", phone: "08345678901", service: "FotoCopy", serviceId: "J0003", locket: "08", startAt: "11:50 AM", completedAt: "11:50 AM", queueNumber: "003", status: "Selesai", called: false, active: true, audio: "Bell"}, + { id: 14, name: "Emily Brown", phone: "08456789012", service: "Online", serviceId: "J0005", locket: "02", startAt: "12:10 PM", completedAt: "12:10 PM", queueNumber: "004", status: "Menunggu", called: false, active: true, audio: "Chime"}, + { id: 15, name: "David Wilson", phone: "08567890123", service: "Design", serviceId: "J0002", locket: "05", startAt: "12:50 PM", completedAt: "12:50 PM", queueNumber: "005", status: "Dilayani", called: false, active: true, audio: "Ding"}, + { id: 16, name: "John Doe", phone: "08123456789", service: "Online", serviceId: "J0005", locket: "01", startAt: "10:30 AM", completedAt: "10:30 AM", queueNumber: "001", status: "Menunggu", called: false, active: true, audio: "Default"}, + { id: 17, name: "Jane Smith", phone: "08234567890", service: "Design", serviceId: "J0002", locket: "04", startAt: "11:15 AM", completedAt: "11:15 AM", queueNumber: "002", status: "Dilayani", called: false, active: true, audio: "Beep"}, + { id: 18, name: "Michael Johnson", phone: "08345678901", service: "Retur", serviceId: "J0004", locket: "08", startAt: "11:50 AM", completedAt: "11:50 AM", queueNumber: "003", status: "Selesai", called: false, active: true, audio: "Bell"}, + { id: 19, name: "Emily Brown", phone: "08456789012", service: "Online", serviceId: "J0005", locket: "02", startAt: "12:10 PM", completedAt: "12:10 PM", queueNumber: "004", status: "Menunggu", called: false, active: true, audio: "Chime"}, + { id: 20, name: "David Wilson", phone: "08567890123", service: "Design", serviceId: "J0002", locket: "05", startAt: "12:50 PM", completedAt: "12:50 PM", queueNumber: "005", status: "Dilayani", called: false, active: true, audio: "Ding"}, + { id: 21, name: "Sophia Martinez", phone: "08678901234", service: "Retur", serviceId: "J0004", locket: "06", startAt: "01:30 PM", completedAt: "01:30 PM", queueNumber: "006", status: "Selesai", called: false, active: true, audio: "Ping"}, + { id: 22, name: "James Anderson", phone: "08789012345", service: "Online", serviceId: "J0005", locket: "03", startAt: "02:15 PM", completedAt: "02:15 PM", queueNumber: "007", status: "Menunggu", called: false, active: true, audio: "Chirp"}, + { id: 23, name: "Olivia Thomas", phone: "08890123456", service: "Design", serviceId: "J0002", locket: "07", startAt: "02:50 PM", completedAt: "02:50 PM", queueNumber: "008", status: "Dilayani", called: false, active: true, audio: "Ring"}, + { id: 24, name: "Liam White", phone: "08901234567", service: "Tamu", serviceId: "J0006", locket: "09", startAt: "03:20 PM", completedAt: "03:20 PM", queueNumber: "009", status: "Selesai", called: false, active: true, audio: "Tone"}, + { id: 25, name: "Emma Harris", phone: "08012345678", service: "Siap Print", serviceId: "J0001", locket: "10", startAt: "03:50 PM", completedAt: "03:50 PM", queueNumber: "010", status: "Menunggu", called: false, active: true, audio: "Alarm"}, +]; + +export const getQueueSettingsData = () => { + return queueData.slice(0, 6).map(({ service, serviceId, active, id }) => ({ + id, + service, + serviceId, + active, + })); +}; + +export const handleCall = (id) => { + const index = queueData.findIndex((item) => item.id === id); + if (index !== -1) { + queueData[index].called = true; + } +}; + +export const handleEdit = (id) => { + console.log("Edit data dengan ID:", id); +}; + +export const handleDelete = (id) => { + const index = queueData.findIndex((item) => item.id === id); + if (index !== -1) { + queueData.splice(index, 1); + } +}; + +export const toggleServiceStatus = (id) => { + const index = queueData.findIndex((item) => item.id === id); + if (index !== -1) { + queueData[index].active = !queueData[index].active; + } +}; + +export const getFilteredQueueData = (callQueueView = false) => { + if (callQueueView) { + return queueData.filter((item) => item.status === "Menunggu"); + } + return queueData; +}; + +export const getQueueDisplayData = () => { + const queueData = getFilteredQueueData(false) || []; + + // Ambil maksimal 25 data untuk animasi berjalan + const displayedQueue = queueData.slice(0, 25); + + return displayedQueue.map(({ queueNumber, locket }) => ({ + number: queueNumber, + counter: locket || "-", + })); +}; + + + +// QueueActions.js +import { useState } from "react"; + +export const useQueueData = (settingsView, callQueueView) => { + const [currentPage, setCurrentPage] = useState(1); + const [searchQuery, setSearchQuery] = useState(""); + const itemsPerPage = 10; + + // Mengambil data berdasarkan kondisi tampilan + const queueData = settingsView ? getQueueSettingsData() || [] : getFilteredQueueData(callQueueView) || []; + + // Filter berdasarkan pencarian + const filteredData = searchQuery + ? queueData.filter((item) => + (item.name?.toLowerCase() || "").includes(searchQuery.toLowerCase()) || + (item.service?.toLowerCase() || "").includes(searchQuery.toLowerCase()) + ) + : queueData; + + // Pagination logic + const totalPages = Math.ceil(filteredData.length / itemsPerPage); + const indexOfLastItem = currentPage * itemsPerPage; + const indexOfFirstItem = indexOfLastItem - itemsPerPage; + const currentItems = filteredData.slice(indexOfFirstItem, indexOfLastItem); + + return { + currentItems, + currentPage, + totalPages, + searchQuery, + setSearchQuery, + setCurrentPage, + indexOfFirstItem, // ✅ Tambahkan ini + }; +}; + diff --git a/src/components/Admin/QueueTable.jsx b/src/components/Admin/QueueTable.jsx new file mode 100644 index 0000000..4e221d8 --- /dev/null +++ b/src/components/Admin/QueueTable.jsx @@ -0,0 +1,144 @@ +import { Table, Button, Form, Pagination, InputGroup, FormControl } from "react-bootstrap"; +import { FaSearch } from "react-icons/fa"; +import { handleCall, toggleServiceStatus, handleDelete, handleEdit, useQueueData } from "./QueueActions"; + +// eslint-disable-next-line react/prop-types +const QueueTable = ({ showActions = true, reportView = false, settingsView = false, displayView = false, callQueueView = false }) => { + + const { currentItems, currentPage, totalPages, searchQuery, setSearchQuery, setCurrentPage, indexOfFirstItem } = useQueueData(settingsView, callQueueView); + + return ( + <> + {(callQueueView || reportView || (!settingsView && !displayView)) && ( + + + + + setSearchQuery(e.target.value)} + /> + + )} + + + + + {displayView ? ( + <> + + + + + ) : settingsView ? ( + <> + + + + + + ) : reportView ? ( + <> + + + + + + + + + ) : ( + <> + + + + + + + {showActions && } + + )} + + + + {currentItems.map((item, index) => ( + + + {displayView ? ( + <> + + + + + ) : settingsView ? ( + <> + + + + + + ) : reportView ? ( + <> + + + + + + + + + ) : ( + <> + + + + + + + {showActions && ( + + )} + + )} + + ))} + +
#Pengaturan SuaraVideo KomersilAksiNama LayananID LayananStatusAksiNamaNo. TeleponLayananLoketCetak AntrianSelesai AntrianAksiNamaLayananKode LayananNomor AntrianLoketStatusAksi
{index + 1 + indexOfFirstItem} + + + + + + {item.video} + + + + {item.service}{item.serviceId}{item.active ? "Aktif" : "Nonaktif"} + + {item.name}{item.phone}{item.service}{item.locket}{item.startAt}{item.completedAt} + + + {item.name}{item.service}{item.serviceId}{item.queueNumber}{item.status === "Dilayani" ? item.locket : "-"}{item.status} + + +
+ + setCurrentPage(prev => Math.max(prev - 1, 1))} disabled={currentPage === 1} /> + {[...Array(totalPages)].map((_, index) => ( + setCurrentPage(index + 1)}> + {index + 1} + + ))} + setCurrentPage(prev => Math.min(prev + 1, totalPages))} disabled={currentPage === totalPages} /> + + + ); +}; + +export default QueueTable; diff --git a/src/components/AdminPage/ListQueue.jsx b/src/components/AdminPage/ListQueue.jsx deleted file mode 100644 index e69de29..0000000 diff --git a/src/components/Display/QueueDisplay.jsx b/src/components/Display/QueueDisplay.jsx index 6ad9aec..d85cb23 100644 --- a/src/components/Display/QueueDisplay.jsx +++ b/src/components/Display/QueueDisplay.jsx @@ -1,35 +1,65 @@ +import { useState, useEffect } from "react"; import { Container, Row, Col, Card } from "react-bootstrap"; import ReactPlayer from "react-player"; - -const sampleTickets = [ - { number: "A1", counter: "1" }, - { number: "A2", counter: "2" }, - { number: "A3", counter: "3" }, - { number: "A4", counter: "4" }, - { number: "A5", counter: "5" }, - { number: "A6", counter: "6" }, - { number: "A7", counter: "7" }, - { number: "A8", counter: "8" }, - { number: "A9", counter: "9" }, - { number: "A10", counter: "10" }, -]; +import { getQueueDisplayData } from "../Admin/QueueActions"; const QueueDisplay = () => { + const [queueData, setQueueData] = useState([]); + const [startIndex, setStartIndex] = useState(0); + const [currentTime, setCurrentTime] = useState(new Date()); + + useEffect(() => { + const interval = setInterval(() => { + setCurrentTime(new Date()); + }, 1000); + + return () => clearInterval(interval); + }, []); + + useEffect(() => { + setQueueData(getQueueDisplayData()); + }, []); + + // Pindah data setiap 5 detik + useEffect(() => { + const interval = setInterval(() => { + setStartIndex((prevIndex) => (prevIndex + 1) % queueData.length); + }, 5000); + + return () => clearInterval(interval); + }, [queueData]); + + // Data antrian yang akan ditampilkan (5 antrian dari total 25) + const currentTicket = queueData[startIndex] || { number: "-", counter: "-" }; + return ( {/* Informasi Bisnis & Nomor Antrian Utama */} -
-

Jagowebdev.com

-

Jl. Zebra III No. 32, Pedurungan Kidul, Semarang

-

Telp: 08561363962

+
+
+

Pandawa24Jam

+

Call Center: 081234567891

+
+
+

{currentTime.toLocaleTimeString()}

+
+ + style={{ borderRadius: "10px", padding: "30px", width: "100%", minHeight: "250px" }}>
NOMOR ANTRIAN
-

A0

+

+ {currentTicket.number} +

+
+ Menuju Loket: {currentTicket.counter} +
@@ -50,20 +80,23 @@ const QueueDisplay = () => { {/* Loket Antrian */} - - {sampleTickets.map((ticket, index) => ( - - - - Nomor Antrian -

{ticket.number}

-
-
- - ))} + + + + List Antrian Layanan + + + + List Antrian Layanan +

+
+ +
+
+
- + ); }; diff --git a/src/components/Display/ServiceSelection.jsx b/src/components/Display/ServiceSelection.jsx index bcb86ca..f7a5f45 100644 --- a/src/components/Display/ServiceSelection.jsx +++ b/src/components/Display/ServiceSelection.jsx @@ -1,135 +1,162 @@ -import { Container, Card, Button, Row, Col, Form, } from 'react-bootstrap'; +import { Container, Card, Button, Row, Col, Form, Carousel } from 'react-bootstrap'; import { useState } from 'react'; -import ReactPlayer from 'react-player'; +import { FaPrint, FaPalette, FaFileAlt, FaUndo, FaTruck, FaUser } from 'react-icons/fa'; const services = [ - {id: "TSP1", name: "test1"}, - {id: "TSP2", name: "test2"}, - {id: "TSP3", name: "test3"}, - {id: "TSP4", name: "test4"}, - {id: "TSP5", name: "test5"}, - {id: "TSP6", name: "test6"} + { id: "j0001", name: "Siap Print", icon: }, + { id: "j0002", name: "Design/Edit/Kreatif", icon: }, + { id: "j0003", name: "FotoCopy/Jilid/Scan", icon: }, + { id: "j0004", name: "Retur Penjualan", icon: }, + { id: "j0005", name: "Online Pickup", icon: }, + { id: "j0006", name: "Tamu", icon: } ]; const ServiceSelection = () => { - - const [selectedService, setSelectedService] = useState (null); + const [selectedService, setSelectedService] = useState(null); const [name, setName] = useState(""); const [phone, setPhone] = useState(""); - const [ticket, setTicket] = useState (null); + const [ticket, setTicket] = useState(null); + const [enableForm, setEnableForm] = useState(false); const handleServiceSelect = (serviceId) => { setSelectedService(services.find(service => service.id === serviceId)); - } + }; const handleSubmit = (e) => { e.preventDefault(); - if (selectedService && name && phone) { + if (selectedService) { const queueNumber = `${selectedService.id}-${Math.floor(1000 + Math.random() * 9000)}`; const newTicket = { - number : queueNumber, - serviceId : selectedService.id, - service : selectedService.name, - name, - phone + number: queueNumber, + serviceId: selectedService.id, + service: selectedService.name, + name: enableForm ? name : "-", + phone: enableForm ? phone : "-", }; setTicket(newTicket); setTimeout(() => window.print(), 500); } - } + }; return ( - - {!ticket ? ( - - -

Pilih Layanan

- + + {!ticket ? ( + + +

Pilih Layanan

+ {services.map(service => { const isSelected = selectedService?.id === service.id; return ( - - - - {service.name} - - - - - ) + + { + handleServiceSelect(service.id); + if (!enableForm) { + handleSubmit(new Event("submit")); + } + }} + > + + {service.icon} + +
{service.name}
+
+
+
+ + ); })}
- -

Masukan Data Diri

- - -
- - Nama - setName(e.target.value)} - required - /> - - - No Telepon - setPhone(e.target.value)} - required - /> - - -
-
-
-
- -
- + +
+

Data Diri

+ setEnableForm(!enableForm)} + style={{ transform: "scale(1.5)" }} + /> +

+ Beri tanda centang untuk mengisi form +

+
+ + +
+ + Nama + setName(e.target.value)} + disabled={!enableForm} + className={`border ${enableForm ? "border-primary" : "border-secondary"} ${enableForm ? "" : "bg-light text-secondary"}`} + /> + + + No Telepon + setPhone(e.target.value)} + disabled={!enableForm} + className={`border ${enableForm ? "border-primary" : "border-secondary"} ${enableForm ? "" : "bg-light text-secondary"}`} + /> + + +
+
+
+
+ + + First slide + +

First Slide Label

+

Nulla vitae elit libero, a pharetra augue mollis interdum.

+
+
+ + Second slide + +

Second Slide Label

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

+
+
+ + Third slide + +

Third Slide Label

+

Praesent commodo cursus magna, vel scelerisque nisl consectetur.

+
+
+
+
+
- ) : ( - - - - Tiket Antrian -
- - {ticket.number} - - - Layanan : {ticket.service} - - - Nama : {ticket.name} - - - No Telepon : {ticket.phone} - - -
-
-
- )} -
- ) -} + ) : ( + + + + Tiket Antrian +
+ {ticket.number} + Layanan : {ticket.service} + Nama : {ticket.name} + No Telepon : {ticket.phone} + +
+
+
+ )} +
+ ); +}; -export default ServiceSelection +export default ServiceSelection; diff --git a/src/layouts/AdminLayout.jsx b/src/layouts/AdminLayout.jsx new file mode 100644 index 0000000..c714567 --- /dev/null +++ b/src/layouts/AdminLayout.jsx @@ -0,0 +1,21 @@ +import Sidebar from "../components/Admin/AdminSidebar"; +import { Outlet } from "react-router-dom"; +import AdminNavbar from "../components/Admin/AdminNavbar"; +import AdminFooter from "../components/Admin/AdminFooter"; + +const AdminLayout = () => { + return ( +
+ +
+ +
+ {/* Ini akan menampilkan halaman konten admin */} +
+
+ +
+ ); +}; + +export default AdminLayout; diff --git a/src/pages/Admin/CallQueuePage.jsx b/src/pages/Admin/CallQueuePage.jsx new file mode 100644 index 0000000..1dbb1b1 --- /dev/null +++ b/src/pages/Admin/CallQueuePage.jsx @@ -0,0 +1,12 @@ +import QueueTable from "../../components/Admin/QueueTable"; + +const CallQueuePage = () => { + return ( +
+

Panggil Atrian Page

+ +
+ ) +} + +export default CallQueuePage diff --git a/src/pages/Admin/QueueListPage.jsx b/src/pages/Admin/QueueListPage.jsx new file mode 100644 index 0000000..b6419cc --- /dev/null +++ b/src/pages/Admin/QueueListPage.jsx @@ -0,0 +1,13 @@ +import QueueTable from "../../components/Admin/QueueTable"; + +const QueueListPage = () => { + + return ( +
+

Daftar Antrian

+ +
+ ); +}; + +export default QueueListPage; diff --git a/src/pages/Admin/QueueReportPage.jsx b/src/pages/Admin/QueueReportPage.jsx new file mode 100644 index 0000000..fa3ded9 --- /dev/null +++ b/src/pages/Admin/QueueReportPage.jsx @@ -0,0 +1,12 @@ +import QueueTable from "../../components/Admin/QueueTable" + +const QueueReportPage = () => { + return ( +
+

Report Antrian Page

+ +
+ ) +} + +export default QueueReportPage diff --git a/src/pages/Admin/QueueSettingsDisplayPage.jsx b/src/pages/Admin/QueueSettingsDisplayPage.jsx new file mode 100644 index 0000000..fc144a6 --- /dev/null +++ b/src/pages/Admin/QueueSettingsDisplayPage.jsx @@ -0,0 +1,12 @@ +import QueueTable from "../../components/Admin/QueueTable" + +const QueueSettingsDisplayPage = () => { + return ( +
+

Setting Display Antrian Page

+ +
+ ) +} + +export default QueueSettingsDisplayPage diff --git a/src/pages/Admin/QueueSettingsMenuPage.jsx b/src/pages/Admin/QueueSettingsMenuPage.jsx new file mode 100644 index 0000000..c96677f --- /dev/null +++ b/src/pages/Admin/QueueSettingsMenuPage.jsx @@ -0,0 +1,12 @@ +import QueueTable from "../../components/Admin/QueueTable" + +const QueueSettingsMenuPage = () => { + return ( +
+

Settings Menu Layanan Page

+ +
+ ) +} + +export default QueueSettingsMenuPage diff --git a/src/pages/Display/QueueSettingsDisplayPage.jsx b/src/pages/Display/QueueSettingsDisplayPage.jsx deleted file mode 100644 index e7ccc92..0000000 --- a/src/pages/Display/QueueSettingsDisplayPage.jsx +++ /dev/null @@ -1,10 +0,0 @@ - -const QueueSettingsDisplayPage = () => { - return ( -
- -
- ) -} - -export default QueueSettingsDisplayPage diff --git a/src/pages/Display/QueueSettingsMenuPage.jsx b/src/pages/Display/QueueSettingsMenuPage.jsx deleted file mode 100644 index d073441..0000000 --- a/src/pages/Display/QueueSettingsMenuPage.jsx +++ /dev/null @@ -1,10 +0,0 @@ - -const QueueSettingsMenuPage = () => { - return ( -
- -
- ) -} - -export default QueueSettingsMenuPage diff --git a/src/pages/Queue/CallQueuePage.jsx b/src/pages/Queue/CallQueuePage.jsx deleted file mode 100644 index 1a060a0..0000000 --- a/src/pages/Queue/CallQueuePage.jsx +++ /dev/null @@ -1,10 +0,0 @@ - -const CallQueuePage = () => { - return ( -
- -
- ) -} - -export default CallQueuePage diff --git a/src/pages/Queue/QueueListPage.jsx b/src/pages/Queue/QueueListPage.jsx deleted file mode 100644 index 6ef3c0d..0000000 --- a/src/pages/Queue/QueueListPage.jsx +++ /dev/null @@ -1,10 +0,0 @@ - -const QueueListPage = () => { - return ( -
- -
- ) -} - -export default QueueListPage diff --git a/src/pages/Queue/QueueReportPage.jsx b/src/pages/Queue/QueueReportPage.jsx deleted file mode 100644 index 72ce00b..0000000 --- a/src/pages/Queue/QueueReportPage.jsx +++ /dev/null @@ -1,10 +0,0 @@ - -const QueueReportPage = () => { - return ( -
- -
- ) -} - -export default QueueReportPage diff --git a/src/routes/AppRoutes.jsx b/src/routes/AppRoutes.jsx index b0f1cb5..bccf1ae 100644 --- a/src/routes/AppRoutes.jsx +++ b/src/routes/AppRoutes.jsx @@ -1,29 +1,35 @@ -import { BrowserRouter as Router, Routes, Route } from "react-router-dom" -import QueueDisplayPage from "../pages/Display/QueueDisplayPage" -import QueueSettingsDisplayPage from "../pages/Display/QueueSettingsDisplayPage" -import QueueSettingsMenuPage from "../pages/Display/QueueSettingsMenuPage" -import QueueMenuPage from "../pages/Display/QueueMenuPage" -import CallQueuePage from "../pages/Queue/CallQueuePage" -import QueueListPage from "../pages/Queue/QueueListPage" -import QueueReportPage from "../pages/Queue/QueueReportPage" +import { BrowserRouter as Router, Routes, Route, Navigate } from "react-router-dom"; +import AdminLayout from "../layouts/AdminLayout"; +import QueueListPage from "../pages/admin/QueueListPage"; +import CallQueuePage from "../pages/admin/CallQueuePage"; +import QueueReportPage from "../pages/admin/QueueReportPage"; +import QueueSettingsDisplayPage from "../pages/admin/QueueSettingsDisplayPage"; +import QueueSettingsMenuPage from "../pages/admin/QueueSettingsMenuPage"; +import QueueDisplayPage from "../pages/display/QueueDisplayPage"; +import QueueMenuPage from "../pages/display/QueueMenuPage"; const AppRoutes = () => { return ( - {/* Queue Pages */} - }/> - }/> - }/> - }/> - {/* Display Pages */} - }/> - }/> - }/> - }/> + {/* Redirect default ke queue-list */} + } /> + + {/* Rute untuk Admin */} + }> + } /> + } /> + } /> + } /> + } /> + + + {/* Rute untuk Customer */} + } /> + } /> - ) -} + ); +}; -export default AppRoutes +export default AppRoutes; diff --git a/src/styles/style.css b/src/styles/style.css index 444b543..c3fcd77 100644 --- a/src/styles/style.css +++ b/src/styles/style.css @@ -1,3 +1,16 @@ :root { --bs-body-font-family: 'Poppins', sans-serif; } + +.close-btn { + position: absolute; + top: 10px; + right: 10px; + /* opacity: 0; */ + transition: opacity 0.3s ease-in-out; + border-radius: 50%; +} + +.mb-3.p-3.text-white.bg-dark:hover .close-btn { + opacity: 1; +} diff --git a/txt b/txt new file mode 100644 index 0000000..2969fb0 --- /dev/null +++ b/txt @@ -0,0 +1,25 @@ +{ id: 1, name: "John Doe", phone: "08123456789", service: "Konsultasi", serviceId: "KS", locket: "01", startAt: "10:30 AM", completedAt: "10:30 AM", queueNumber: "001", status: "Menunggu", called: false, active: true, audio: "Default", video: "Video1.mp4" }, + { id: 2, name: "Jane Smith", phone: "08234567890", service: "Pendaftaran", serviceId: "PF", locket: "04", startAt: "11:15 AM", completedAt: "11:15 AM", queueNumber: "002", status: "Dilayani", called: false, active: true, audio: "Beep", video: "Video2.mp4" }, + { id: 3, name: "Michael Johnson", phone: "08345678901", service: "Pembayaran", serviceId: "PY", locket: "08", startAt: "11:50 AM", completedAt: "11:50 AM", queueNumber: "003", status: "Selesai", called: false, active: true, audio: "Bell", video: "Video3.mp4" }, + { id: 4, name: "Emily Brown", phone: "08456789012", service: "Konsultasi", serviceId: "KS", locket: "02", startAt: "12:10 PM", completedAt: "12:10 PM", queueNumber: "004", status: "Menunggu", called: false, active: true, audio: "Chime", video: "Video4.mp4" }, + { id: 5, name: "David Wilson", phone: "08567890123", service: "Pendaftaran", serviceId: "PF", locket: "05", startAt: "12:50 PM", completedAt: "12:50 PM", queueNumber: "005", status: "Dilayani", called: false, active: true, audio: "Ding", video: "Video5.mp4" }, + { id: 6, name: "Sophia Martinez", phone: "08678901234", service: "Pembayaran", serviceId: "PY", locket: "06", startAt: "01:30 PM", completedAt: "01:30 PM", queueNumber: "006", status: "Selesai", called: false, active: true, audio: "Ping", video: "Video6.mp4" }, + { id: 7, name: "James Anderson", phone: "08789012345", service: "Konsultasi", serviceId: "KS", locket: "03", startAt: "02:15 PM", completedAt: "02:15 PM", queueNumber: "007", status: "Menunggu", called: false, active: true, audio: "Chirp", video: "Video7.mp4" }, + { id: 8, name: "Olivia Thomas", phone: "08890123456", service: "Pendaftaran", serviceId: "PF", locket: "07", startAt: "02:50 PM", completedAt: "02:50 PM", queueNumber: "008", status: "Dilayani", called: false, active: true, audio: "Ring", video: "Video8.mp4" }, + { id: 9, name: "Liam White", phone: "08901234567", service: "Pembayaran", serviceId: "PY", locket: "09", startAt: "03:20 PM", completedAt: "03:20 PM", queueNumber: "009", status: "Selesai", called: false, active: true, audio: "Tone", video: "Video9.mp4" }, + { id: 10, name: "Emma Harris", phone: "08012345678", service: "Konsultasi", serviceId: "KS", locket: "10", startAt: "03:50 PM", completedAt: "03:50 PM", queueNumber: "010", status: "Menunggu", called: false, active: true, audio: "Alarm", video: "Video10.mp4" }, + { id: 11, name: "John Doe", phone: "08123456789", service: "Konsultasi", serviceId: "KS", locket: "01", startAt: "10:30 AM", completedAt: "10:30 AM", queueNumber: "001", status: "Menunggu", called: false, active: true, audio: "Default", video: "Video1.mp4" }, + { id: 12, name: "Jane Smith", phone: "08234567890", service: "Pendaftaran", serviceId: "PF", locket: "04", startAt: "11:15 AM", completedAt: "11:15 AM", queueNumber: "002", status: "Dilayani", called: false, active: true, audio: "Beep", video: "Video2.mp4" }, + { id: 13, name: "Michael Johnson", phone: "08345678901", service: "Pembayaran", serviceId: "PY", locket: "08", startAt: "11:50 AM", completedAt: "11:50 AM", queueNumber: "003", status: "Selesai", called: false, active: true, audio: "Bell", video: "Video3.mp4" }, + { id: 14, name: "Emily Brown", phone: "08456789012", service: "Konsultasi", serviceId: "KS", locket: "02", startAt: "12:10 PM", completedAt: "12:10 PM", queueNumber: "004", status: "Menunggu", called: false, active: true, audio: "Chime", video: "Video4.mp4" }, + { id: 15, name: "David Wilson", phone: "08567890123", service: "Pendaftaran", serviceId: "PF", locket: "05", startAt: "12:50 PM", completedAt: "12:50 PM", queueNumber: "005", status: "Dilayani", called: false, active: true, audio: "Ding", video: "Video5.mp4" }, + { id: 16, name: "John Doe", phone: "08123456789", service: "Konsultasi", serviceId: "KS", locket: "01", startAt: "10:30 AM", completedAt: "10:30 AM", queueNumber: "001", status: "Menunggu", called: false, active: true, audio: "Default", video: "Video1.mp4" }, + { id: 17, name: "Jane Smith", phone: "08234567890", service: "Pendaftaran", serviceId: "PF", locket: "04", startAt: "11:15 AM", completedAt: "11:15 AM", queueNumber: "002", status: "Dilayani", called: false, active: true, audio: "Beep", video: "Video2.mp4" }, + { id: 18, name: "Michael Johnson", phone: "08345678901", service: "Pembayaran", serviceId: "PY", locket: "08", startAt: "11:50 AM", completedAt: "11:50 AM", queueNumber: "003", status: "Selesai", called: false, active: true, audio: "Bell", video: "Video3.mp4" }, + { id: 19, name: "Emily Brown", phone: "08456789012", service: "Konsultasi", serviceId: "KS", locket: "02", startAt: "12:10 PM", completedAt: "12:10 PM", queueNumber: "004", status: "Menunggu", called: false, active: true, audio: "Chime", video: "Video4.mp4" }, + { id: 20, name: "David Wilson", phone: "08567890123", service: "Pendaftaran", serviceId: "PF", locket: "05", startAt: "12:50 PM", completedAt: "12:50 PM", queueNumber: "005", status: "Dilayani", called: false, active: true, audio: "Ding", video: "Video5.mp4" }, + { id: 21, name: "Sophia Martinez", phone: "08678901234", service: "Pembayaran", serviceId: "PY", locket: "06", startAt: "01:30 PM", completedAt: "01:30 PM", queueNumber: "006", status: "Selesai", called: false, active: true, audio: "Ping", video: "Video6.mp4" }, + { id: 22, name: "James Anderson", phone: "08789012345", service: "Konsultasi", serviceId: "KS", locket: "03", startAt: "02:15 PM", completedAt: "02:15 PM", queueNumber: "007", status: "Menunggu", called: false, active: true, audio: "Chirp", video: "Video7.mp4" }, + { id: 23, name: "Olivia Thomas", phone: "08890123456", service: "Pendaftaran", serviceId: "PF", locket: "07", startAt: "02:50 PM", completedAt: "02:50 PM", queueNumber: "008", status: "Dilayani", called: false, active: true, audio: "Ring", video: "Video8.mp4" }, + { id: 24, name: "Liam White", phone: "08901234567", service: "Pembayaran", serviceId: "PY", locket: "09", startAt: "03:20 PM", completedAt: "03:20 PM", queueNumber: "009", status: "Selesai", called: false, active: true, audio: "Tone", video: "Video9.mp4" }, + { id: 25, name: "Emma Harris", phone: "08012345678", service: "Konsultasi", serviceId: "KS", locket: "10", startAt: "03:50 PM", completedAt: "03:50 PM", queueNumber: "010", status: "Menunggu", called: false, active: true, audio: "Alarm", video: "Video10.mp4" }, \ No newline at end of file