From 2ebe01e0704986daf6bd86ec0deaf544e6b70e0b Mon Sep 17 00:00:00 2001 From: bender Date: Tue, 10 Mar 2026 16:42:22 +0000 Subject: [PATCH] Add src/app/booking/page.tsx --- src/app/booking/page.tsx | 391 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 391 insertions(+) create mode 100644 src/app/booking/page.tsx diff --git a/src/app/booking/page.tsx b/src/app/booking/page.tsx new file mode 100644 index 0000000..3ff2a87 --- /dev/null +++ b/src/app/booking/page.tsx @@ -0,0 +1,391 @@ +"use client"; + +import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider"; +import NavbarStyleApple from "@/components/navbar/NavbarStyleApple/NavbarStyleApple"; +import HeroOverlay from "@/components/sections/hero/HeroOverlay"; +import FooterBase from "@/components/sections/footer/FooterBase"; +import { useState } from "react"; +import { MapPin, Calendar, Users, Search, Heart, Clock, Users2 } from "lucide-react"; + +interface SearchFormData { + departure: string; + arrival: string; + date: string; + passengers: number; +} + +interface Bus { + id: string; + name: string; + departure: string; + arrival: string; + departureTime: string; + arrivalTime: string; + duration: string; + price: number; + availableSeats: number; + totalSeats: number; + amenities: string[]; + image?: string; +} + +interface Seat { + id: string; + number: number; + isAvailable: boolean; + isSelected: boolean; +} + +const mockBuses: Bus[] = [ + { + id: "1", name: "Premium Express", departure: "Cairo", arrival: "Alexandria", departureTime: "08:00 AM", arrivalTime: "11:00 AM", duration: "3h", price: 100, + availableSeats: 12, + totalSeats: 40, + amenities: ["WiFi", "Air Conditioning", "USB Charging"], + image: "http://img.b2bpic.net/free-photo/most-comfortable-means-transportation-business-people_329181-2791.jpg" + }, + { + id: "2", name: "Comfort Deluxe", departure: "Cairo", arrival: "Alexandria", departureTime: "10:30 AM", arrivalTime: "01:30 PM", duration: "3h", price: 150, + availableSeats: 8, + totalSeats: 30, + amenities: ["WiFi", "Air Conditioning", "USB Charging", "Snacks"], + image: "http://img.b2bpic.net/free-photo/empty-subway-train-barcelona-spain_1268-17854.jpg" + }, + { + id: "3", name: "Economy Max", departure: "Cairo", arrival: "Alexandria", departureTime: "02:00 PM", arrivalTime: "05:00 PM", duration: "3h", price: 80, + availableSeats: 25, + totalSeats: 50, + amenities: ["Air Conditioning"], + image: "http://img.b2bpic.net/free-photo/hand-with-credit-card-laptop_1232-619.jpg" + } +]; + +const generateSeats = (totalSeats: number): Seat[] => { + return Array.from({ length: totalSeats }, (_, i) => ({ + id: `seat-${i + 1}`, + number: i + 1, + isAvailable: Math.random() > 0.3, + isSelected: false + })); +}; + +export default function BookingPage() { + const [searchData, setSearchData] = useState({ + departure: "", arrival: "", date: "", passengers: 1 + }); + const [searchResults, setSearchResults] = useState([]); + const [hasSearched, setHasSearched] = useState(false); + const [selectedBus, setSelectedBus] = useState(null); + const [seats, setSeats] = useState([]); + const [selectedSeats, setSelectedSeats] = useState([]); + + const handleSearch = (e: React.FormEvent) => { + e.preventDefault(); + if (searchData.departure && searchData.arrival && searchData.date) { + setSearchResults(mockBuses); + setHasSearched(true); + setSelectedBus(null); + setSeats([]); + setSelectedSeats([]); + } + }; + + const handleSelectBus = (bus: Bus) => { + setSelectedBus(bus); + setSeats(generateSeats(bus.totalSeats)); + setSelectedSeats([]); + }; + + const handleSeatToggle = (seatId: string) => { + const seat = seats.find(s => s.id === seatId); + if (!seat || !seat.isAvailable) return; + + if (selectedSeats.includes(seatId)) { + setSelectedSeats(selectedSeats.filter(s => s !== seatId)); + } else if (selectedSeats.length < searchData.passengers) { + setSelectedSeats([...selectedSeats, seatId]); + } + }; + + const handleInputChange = (e: React.ChangeEvent) => { + const { name, value } = e.target; + setSearchData(prev => ({ + ...prev, + [name]: name === "passengers" ? parseInt(value) : value + })); + }; + + const totalPrice = selectedBus ? selectedBus.price * selectedSeats.length : 0; + + return ( + + + +
+ +
+ + + + {hasSearched && !selectedBus && ( +
+
+

Available Buses

+
+ {searchResults.map(bus => ( +
handleSelectBus(bus)} + > +
+
+

{bus.name}

+

{bus.departure} → {bus.arrival}

+
+
+

{bus.departureTime}

+

{bus.duration}

+
+
+

{bus.arrivalTime}

+

Arrival

+
+
+

Seats Available

+

{bus.availableSeats}/{bus.totalSeats}

+
+ {bus.amenities.map((amenity, i) => ( + + {amenity} + + ))} +
+
+
+

{bus.price} EGP

+

per seat

+
+
+
+ ))} +
+
+
+ )} + + {selectedBus && ( +
+
+ + +
+
+

{selectedBus.name}

+

{selectedBus.departure} → {selectedBus.arrival} | {selectedBus.departureTime}

+
+ +
+

Select Your Seats

+
+

Select {searchData.passengers} seat{searchData.passengers !== 1 ? 's' : ''}

+ +
+ {seats.map(seat => ( + + ))} +
+
+ +
+
+
+ Available +
+
+
+ Selected +
+
+
+ Booked +
+
+
+ + {selectedSeats.length > 0 && ( +
+
+

Selected Seats:

+
+ {selectedSeats.map(seatId => { + const seat = seats.find(s => s.id === seatId); + return ( + + Seat {seat?.number} + + ); + })} +
+
+
+
+

Total Price:

+

{totalPrice} EGP

+
+ +
+
+ )} +
+
+
+ )} + + +
+ ); +}