Add src/app/admin/page.tsx

This commit is contained in:
2026-03-10 16:42:21 +00:00
parent 9fa6f9aeea
commit da90d43339

289
src/app/admin/page.tsx Normal file
View 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>
);
}