import React, { useState, useEffect } from 'react';
import { Calendar, Clock, Users, CheckCircle, XCircle, Phone, Euro, LogIn, UserPlus, AlertCircle, Menu, X } from 'lucide-react';
const BookingApp = () => {
const [currentUser, setCurrentUser] = useState(null);
const [isDriver, setIsDriver] = useState(false);
const [view, setView] = useState('welcome');
const [selectedDate, setSelectedDate] = useState(new Date().toISOString().split('T')[0]);
const [passengers, setPassengers] = useState([]);
const [bookings, setBookings] = useState([]);
const [showMenu, setShowMenu] = useState(false);
const [confirmBooking, setConfirmBooking] = useState(null);
const schedules = [
{ id: 1, time: '05:30', shift: 'Mañana', type: 'IDA', maxSeats: 4 },
{ id: 2, time: '14:10', shift: 'Mañana', type: 'VUELTA', maxSeats: 4 },
{ id: 3, time: '13:30', shift: 'Tarde', type: 'IDA', maxSeats: 4 },
{ id: 4, time: '22:10', shift: 'Tarde', type: 'VUELTA', maxSeats: 4 },
{ id: 5, time: '21:30', shift: 'Noche', type: 'IDA', maxSeats: 4 },
{ id: 6, time: '06:10', shift: 'Noche', type: 'VUELTA', maxSeats: 4 },
];
useEffect(() => {
const saved = localStorage.getItem('appData');
if (saved) {
const data = JSON.parse(saved);
setPassengers(data.passengers || []);
setBookings(data.bookings || []);
setCurrentUser(data.currentUser);
setIsDriver(data.isDriver || false);
}
}, []);
useEffect(() => {
localStorage.setItem('appData', JSON.stringify({
passengers,
bookings,
currentUser,
isDriver
}));
}, [passengers, bookings, currentUser, isDriver]);
const getBookingsForSchedule = (scheduleId, date) => {
return bookings.filter(b => b.scheduleId === scheduleId && b.date === date && !b.cancelled);
};
const getAvailableSeats = (scheduleId, date) => {
return 4 - getBookingsForSchedule(scheduleId, date).length;
};
const formatDate = (dateStr) => {
const date = new Date(dateStr);
return date.toLocaleDateString('es-ES', { weekday: 'long', day: 'numeric', month: 'long' });
};
const changeDate = (days) => {
const current = new Date(selectedDate);
current.setDate(current.getDate() + days);
setSelectedDate(current.toISOString().split('T')[0]);
};
if (view === 'welcome') {
return (
🚗
Seseña-Illescas Express
Tu transporte diario
💡 Debes estar aprobado para reservar
);
}
if (view === 'login') {
return setView('welcome')}
onLogin={(user, driver) => {
setCurrentUser(user);
setIsDriver(driver);
setView('main');
}}
passengers={passengers}
/>;
}
if (view === 'register') {
return setView('welcome')}
onRegister={(newPass) => {
setPassengers([...passengers, newPass]);
alert('Solicitud enviada. Te contactaremos pronto.');
setView('welcome');
}}
/>;
}
if (isDriver) {
const today = new Date().toISOString().split('T')[0];
const todayBookings = bookings.filter(b => b.date === today && !b.cancelled);
const paid = todayBookings.filter(b => b.paid).length * 15;
const pending = todayBookings.filter(b => !b.paid).length * 15;
const pendingPassengers = passengers.filter(p => p.status === 'pending');
return (
👨✈️ Panel Conductor
{formatDate(selectedDate)}
{showMenu && (
)}
Viajes
{todayBookings.length}
{pendingPassengers.length > 0 && (
Solicitudes Pendientes: {pendingPassengers.length}
{pendingPassengers.map(p => (
{p.name}
{p.phone}
{p.company}
))}
)}
{schedules.map(schedule => {
const tripBookings = getBookingsForSchedule(schedule.id, selectedDate);
const available = getAvailableSeats(schedule.id, selectedDate);
return (
{schedule.time}
{schedule.shift}
{schedule.type === 'IDA' ? '📍 → Illescas' : '🏠 → Seseña'}
{4 - available}/4
{tripBookings.length > 0 ? (
{tripBookings.map(booking => (
{booking.passengerName}
{booking.company}
))}
) : (
Sin reservas
)}
);
})}
);
}
const myBookings = bookings.filter(b =>
b.passengerId === currentUser.id &&
b.date >= new Date().toISOString().split('T')[0] &&
!b.cancelled
);
return (
🚗 Seseña-Illescas
Hola, {currentUser.name.split(' ')[0]}
{showMenu && (
Tu empresa
{currentUser.company}
)}
{myBookings.length > 0 && (
Mis Próximas Reservas
{myBookings.map(booking => {
const schedule = schedules.find(s => s.id === booking.scheduleId);
return (
{formatDate(booking.date)}
{schedule.time} - {schedule.type}
{booking.confirmed ? (
✅ Confirmado
) : (
⏳ Pendiente
)}
);
})}
)}
{schedules.map(schedule => {
const available = getAvailableSeats(schedule.id, selectedDate);
const myBooking = bookings.find(b =>
b.passengerId === currentUser.id &&
b.scheduleId === schedule.id &&
b.date === selectedDate &&
!b.cancelled
);
return (
{schedule.time}
{schedule.shift}
{schedule.type === 'IDA' ? '📍 → Illescas' : '🏠 → Seseña'}
0 ? 'bg-green-100 text-green-800' : 'bg-red-100 text-red-800'
}`}>
{available}/4
{myBooking ? (
✅ Ya reservaste este horario
) : available > 0 ? (
) : (
Completo
)}
);
})}
{confirmBooking && (
Confirmar Reserva
📅 {formatDate(selectedDate)}
🕐 {schedules.find(s => s.id === confirmBooking)?.time}
🏢 {currentUser.company}
💰 15€
)}
);
};
const LoginScreen = ({ onBack, onLogin, passengers }) => {
const [loginType, setLoginType] = useState('passenger');
const [phone, setPhone] = useState('');
const [password, setPassword] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
if (loginType === 'driver') {
if (password === '1234') {
onLogin({ id: 'driver', name: 'Conductor' }, true);
} else {
alert('Contraseña incorrecta');
}
} else {
const pass = passengers.find(p => p.phone === phone && p.status === 'active');
if (pass) {
onLogin(pass, false);
} else {
alert('Teléfono no encontrado o no aprobado');
}
}
};
return (
);
};
const RegisterScreen = ({ onBack, onRegister }) => {
const [formData, setFormData] = useState({
name: '',
phone: '',
company: '',
shift: ''
});
const handleSubmit = (e) => {
e.preventDefault();
if (!formData.name || !formData.phone || !formData.company || !formData.shift) {
alert('Completa todos los campos');
return;
}
const newPass = {
id: Date.now(),
...formData,
status: 'pending',
totalTrips: 0,
cancellations: 0
};
onRegister(newPass);
};
return (
);
};
export default BookingApp;