Add src/app/admin/page.tsx
This commit is contained in:
289
src/app/admin/page.tsx
Normal file
289
src/app/admin/page.tsx
Normal file
@@ -0,0 +1,289 @@
|
||||
"use client";
|
||||
|
||||
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||
import NavbarStyleApple from "@/components/navbar/NavbarStyleApple/NavbarStyleApple";
|
||||
import FooterBase from "@/components/sections/footer/FooterBase";
|
||||
import { useState } from "react";
|
||||
import { Plus, Edit2, Trash2, Save, X } from "lucide-react";
|
||||
|
||||
interface BusRoute {
|
||||
id: string;
|
||||
name: string;
|
||||
departure: string;
|
||||
arrival: string;
|
||||
price: number;
|
||||
capacity: number;
|
||||
status: "active" | "inactive";
|
||||
}
|
||||
|
||||
interface Ticket {
|
||||
id: string;
|
||||
routeId: string;
|
||||
passengerName: string;
|
||||
seatNumber: string;
|
||||
bookingDate: string;
|
||||
status: "booked" | "cancelled" | "completed";
|
||||
}
|
||||
|
||||
export default function AdminDashboard() {
|
||||
const [routes, setRoutes] = useState<BusRoute[]>([
|
||||
{ id: "1", name: "Cairo to Alexandria", departure: "06:00", arrival: "09:00", price: 100, capacity: 50, status: "active" },
|
||||
{ id: "2", name: "Cairo to Giza", departure: "07:30", arrival: "08:30", price: 50, capacity: 40, status: "active" },
|
||||
]);
|
||||
|
||||
const [tickets, setTickets] = useState<Ticket[]>([
|
||||
{ id: "1", routeId: "1", passengerName: "Ahmed Hassan", seatNumber: "A1", bookingDate: "2025-01-15", status: "booked" },
|
||||
{ id: "2", routeId: "1", passengerName: "Fatima Mohamed", seatNumber: "A2", bookingDate: "2025-01-15", status: "booked" },
|
||||
]);
|
||||
|
||||
const [editingRoute, setEditingRoute] = useState<BusRoute | null>(null);
|
||||
const [editingTicket, setEditingTicket] = useState<Ticket | null>(null);
|
||||
const [showRouteForm, setShowRouteForm] = useState(false);
|
||||
const [showTicketForm, setShowTicketForm] = useState(false);
|
||||
|
||||
const handleDeleteRoute = (id: string) => {
|
||||
setRoutes(routes.filter(r => r.id !== id));
|
||||
};
|
||||
|
||||
const handleDeleteTicket = (id: string) => {
|
||||
setTickets(tickets.filter(t => t.id !== id));
|
||||
};
|
||||
|
||||
const handleSaveRoute = (route: BusRoute) => {
|
||||
if (editingRoute) {
|
||||
setRoutes(routes.map(r => r.id === route.id ? route : r));
|
||||
setEditingRoute(null);
|
||||
} else {
|
||||
setRoutes([...routes, { ...route, id: String(Date.now()) }]);
|
||||
}
|
||||
setShowRouteForm(false);
|
||||
};
|
||||
|
||||
const handleSaveTicket = (ticket: Ticket) => {
|
||||
if (editingTicket) {
|
||||
setTickets(tickets.map(t => t.id === ticket.id ? ticket : t));
|
||||
setEditingTicket(null);
|
||||
} else {
|
||||
setTickets([...tickets, { ...ticket, id: String(Date.now()) }]);
|
||||
}
|
||||
setShowTicketForm(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<ThemeProvider
|
||||
defaultButtonVariant="directional-hover"
|
||||
defaultTextAnimation="reveal-blur"
|
||||
borderRadius="pill"
|
||||
contentWidth="compact"
|
||||
sizing="mediumLargeSizeLargeTitles"
|
||||
background="aurora"
|
||||
cardStyle="inset"
|
||||
primaryButtonStyle="gradient"
|
||||
secondaryButtonStyle="glass"
|
||||
headingFontWeight="medium"
|
||||
>
|
||||
<div id="nav" data-section="nav">
|
||||
<NavbarStyleApple
|
||||
brandName="BusTicket"
|
||||
navItems={[
|
||||
{ name: "Book Now", id: "pricing" },
|
||||
{ name: "How It Works", id: "features" },
|
||||
{ name: "FAQ", id: "faq" },
|
||||
{ name: "Contact", id: "contact" },
|
||||
{ name: "Admin", id: "admin" }
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="min-h-screen bg-gradient-to-br from-slate-50 to-slate-100 py-12">
|
||||
<div className="max-w-7xl mx-auto px-4">
|
||||
<h1 className="text-4xl font-bold text-slate-900 mb-12">Admin Dashboard</h1>
|
||||
|
||||
{/* Bus Routes Management */}
|
||||
<div className="mb-12">
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<h2 className="text-2xl font-bold text-slate-800">Bus Routes Management</h2>
|
||||
<button
|
||||
onClick={() => {
|
||||
setEditingRoute(null);
|
||||
setShowRouteForm(true);
|
||||
}}
|
||||
className="flex items-center gap-2 bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg transition"
|
||||
>
|
||||
<Plus size={20} />
|
||||
Add Route
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="bg-white rounded-lg shadow overflow-hidden">
|
||||
<table className="w-full">
|
||||
<thead className="bg-slate-100 border-b">
|
||||
<tr>
|
||||
<th className="px-6 py-3 text-left text-sm font-semibold text-slate-700">Route Name</th>
|
||||
<th className="px-6 py-3 text-left text-sm font-semibold text-slate-700">Departure</th>
|
||||
<th className="px-6 py-3 text-left text-sm font-semibold text-slate-700">Arrival</th>
|
||||
<th className="px-6 py-3 text-left text-sm font-semibold text-slate-700">Price (EGP)</th>
|
||||
<th className="px-6 py-3 text-left text-sm font-semibold text-slate-700">Capacity</th>
|
||||
<th className="px-6 py-3 text-left text-sm font-semibold text-slate-700">Status</th>
|
||||
<th className="px-6 py-3 text-left text-sm font-semibold text-slate-700">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y">
|
||||
{routes.map(route => (
|
||||
<tr key={route.id} className="hover:bg-slate-50">
|
||||
<td className="px-6 py-3 text-slate-900">{route.name}</td>
|
||||
<td className="px-6 py-3 text-slate-900">{route.departure}</td>
|
||||
<td className="px-6 py-3 text-slate-900">{route.arrival}</td>
|
||||
<td className="px-6 py-3 text-slate-900">{route.price}</td>
|
||||
<td className="px-6 py-3 text-slate-900">{route.capacity}</td>
|
||||
<td className="px-6 py-3">
|
||||
<span className={`px-3 py-1 rounded-full text-xs font-semibold ${
|
||||
route.status === "active"
|
||||
? "bg-green-100 text-green-700"
|
||||
: "bg-red-100 text-red-700"
|
||||
}`}>
|
||||
{route.status}
|
||||
</span>
|
||||
</td>
|
||||
<td className="px-6 py-3 flex gap-2">
|
||||
<button
|
||||
onClick={() => {
|
||||
setEditingRoute(route);
|
||||
setShowRouteForm(true);
|
||||
}}
|
||||
className="p-2 text-blue-600 hover:bg-blue-50 rounded transition"
|
||||
>
|
||||
<Edit2 size={18} />
|
||||
</button>
|
||||
<button
|
||||
onClick={() => handleDeleteRoute(route.id)}
|
||||
className="p-2 text-red-600 hover:bg-red-50 rounded transition"
|
||||
>
|
||||
<Trash2 size={18} />
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Ticket Management */}
|
||||
<div className="mb-12">
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<h2 className="text-2xl font-bold text-slate-800">Ticket Management</h2>
|
||||
<button
|
||||
onClick={() => {
|
||||
setEditingTicket(null);
|
||||
setShowTicketForm(true);
|
||||
}}
|
||||
className="flex items-center gap-2 bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg transition"
|
||||
>
|
||||
<Plus size={20} />
|
||||
Add Ticket
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="bg-white rounded-lg shadow overflow-hidden">
|
||||
<table className="w-full">
|
||||
<thead className="bg-slate-100 border-b">
|
||||
<tr>
|
||||
<th className="px-6 py-3 text-left text-sm font-semibold text-slate-700">Passenger Name</th>
|
||||
<th className="px-6 py-3 text-left text-sm font-semibold text-slate-700">Route</th>
|
||||
<th className="px-6 py-3 text-left text-sm font-semibold text-slate-700">Seat Number</th>
|
||||
<th className="px-6 py-3 text-left text-sm font-semibold text-slate-700">Booking Date</th>
|
||||
<th className="px-6 py-3 text-left text-sm font-semibold text-slate-700">Status</th>
|
||||
<th className="px-6 py-3 text-left text-sm font-semibold text-slate-700">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y">
|
||||
{tickets.map(ticket => {
|
||||
const route = routes.find(r => r.id === ticket.routeId);
|
||||
return (
|
||||
<tr key={ticket.id} className="hover:bg-slate-50">
|
||||
<td className="px-6 py-3 text-slate-900">{ticket.passengerName}</td>
|
||||
<td className="px-6 py-3 text-slate-900">{route?.name || 'N/A'}</td>
|
||||
<td className="px-6 py-3 text-slate-900">{ticket.seatNumber}</td>
|
||||
<td className="px-6 py-3 text-slate-900">{ticket.bookingDate}</td>
|
||||
<td className="px-6 py-3">
|
||||
<span className={`px-3 py-1 rounded-full text-xs font-semibold ${
|
||||
ticket.status === "booked"
|
||||
? "bg-blue-100 text-blue-700"
|
||||
: ticket.status === "completed"
|
||||
? "bg-green-100 text-green-700"
|
||||
: "bg-red-100 text-red-700"
|
||||
}`}>
|
||||
{ticket.status}
|
||||
</span>
|
||||
</td>
|
||||
<td className="px-6 py-3 flex gap-2">
|
||||
<button
|
||||
onClick={() => {
|
||||
setEditingTicket(ticket);
|
||||
setShowTicketForm(true);
|
||||
}}
|
||||
className="p-2 text-blue-600 hover:bg-blue-50 rounded transition"
|
||||
>
|
||||
<Edit2 size={18} />
|
||||
</button>
|
||||
<button
|
||||
onClick={() => handleDeleteTicket(ticket.id)}
|
||||
className="p-2 text-red-600 hover:bg-red-50 rounded transition"
|
||||
>
|
||||
<Trash2 size={18} />
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="footer" data-section="footer">
|
||||
<FooterBase
|
||||
logoText="BusTicket"
|
||||
copyrightText="© 2025 | BusTicket Egypt. All rights reserved."
|
||||
columns={[
|
||||
{
|
||||
title: "Quick Links", items: [
|
||||
{ label: "Book Tickets", href: "pricing" },
|
||||
{ label: "Track Bus", href: "#" },
|
||||
{ label: "Routes", href: "#" },
|
||||
{ label: "Promotions", href: "#" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Company", items: [
|
||||
{ label: "About Us", href: "#" },
|
||||
{ label: "Careers", href: "#" },
|
||||
{ label: "Blog", href: "#" },
|
||||
{ label: "Contact", href: "#" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Support", items: [
|
||||
{ label: "Help Center", href: "faq" },
|
||||
{ label: "Safety", href: "#" },
|
||||
{ label: "Terms & Conditions", href: "#" },
|
||||
{ label: "Privacy Policy", href: "#" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Bus Company Info", items: [
|
||||
{ label: "Fleet Details", href: "#" },
|
||||
{ label: "Driver Qualifications", href: "#" },
|
||||
{ label: "Maintenance Schedule", href: "#" },
|
||||
{ label: "Safety Records", href: "#" }
|
||||
]
|
||||
}
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user