import React, { useState } from 'react';
import {
Calendar as CalendarIcon,
ChevronLeft,
ChevronRight,
Plus,
LogOut,
User as UserIcon,
Clock,
Trash2,
ShieldAlert,
Mail,
List,
Phone,
CreditCard,
Edit2,
DollarSign
} from 'lucide-react';
export default function App() {
// --- STATE ---
const [currentUser, setCurrentUser] = useState(null);
const [currentDate, setCurrentDate] = useState(new Date());
const [bookings, setBookings] = useState([
{ id: 1, date: new Date().toISOString().split('T')[0], time: '10:00', clientName: 'Acme Corp', clientPhone: '9876543210', clientEmail: 'contact@acme.com', service: 'Pre Wedding', packageType: 'Cinematic Video + Photo', totalAmount: 50000, advance: 20000, balance: 30000, addedBy: 'admin' },
{ id: 2, date: new Date().toISOString().split('T')[0], time: '14:30', clientName: 'Jane Doe', clientPhone: '9123456780', clientEmail: 'jane@example.com', service: 'Maternity', packageType: 'Elegant Gown Session', totalAmount: 15000, advance: 15000, balance: 0, addedBy: 'user' },
]);
// Modals
const [isBookingModalOpen, setIsBookingModalOpen] = useState(false);
const [isEmailDraftOpen, setIsEmailDraftOpen] = useState(false);
const [isPaymentModalOpen, setIsPaymentModalOpen] = useState(false);
// Form/Draft states
const [selectedDate, setSelectedDate] = useState('');
const [selectedService, setSelectedService] = useState('');
const [draftData, setDraftData] = useState(null);
const [paymentEditData, setPaymentEditData] = useState(null);
// UI states
const [currentView, setCurrentView] = useState('calendar');
const [notification, setNotification] = useState('');
// The Studio Clicks - Package Definitions
const packagesData = {
"Pre Birthday": [
"Silver Pre-Birthday Package - ₹4,999",
"Gold Pre-Birthday Package - ₹7,999",
"Platinum Pre-Birthday Package - ₹13,999"
],
"New Born": [
"Silver Newborn Package - ₹5,999",
"Premium Newborn Package - ₹7,999"
],
"Maternity": [
"Silver Maternity Photoshoot - ₹4,999",
"Gold Maternity Photoshoot - ₹8,999",
"Platinum Maternity Photoshoot - ₹14,000"
],
"Pre Wedding": ["1-Day Local Shoot", "Destination Shoot", "Cinematic Video + Photo"],
"Birthday Events": ["Standard Event Coverage", "Premium (Candid + Traditional)", "Luxury (Photo, Video, Drone)"]
};
// --- AUTHENTICATION ---
const handleLogin = (username, password) => {
if (username === 'admin' && password === 'admin') {
setCurrentUser({ username: 'Admin', role: 'admin' });
} else if (username && password) {
setCurrentUser({ username: username, role: 'user' });
} else {
alert("Please enter both username and password.");
}
};
const handleLogout = () => setCurrentUser(null);
// --- CALENDAR LOGIC ---
const getDaysInMonth = (year, month) => new Date(year, month + 1, 0).getDate();
const getFirstDayOfMonth = (year, month) => new Date(year, month, 1).getDay();
const prevMonth = () => setCurrentDate(new Date(currentDate.getFullYear(), currentDate.getMonth() - 1, 1));
const nextMonth = () => setCurrentDate(new Date(currentDate.getFullYear(), currentDate.getMonth() + 1, 1));
const todayMonth = () => setCurrentDate(new Date());
const year = currentDate.getFullYear();
const month = currentDate.getMonth();
const daysInMonth = getDaysInMonth(year, month);
const firstDayIndex = getFirstDayOfMonth(year, month);
const monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
const dayNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
// --- BOOKING LOGIC ---
const openAddModal = (dateStr = '') => {
setSelectedDate(dateStr);
setSelectedService('');
setIsBookingModalOpen(true);
};
const handlePrepareBooking = (e) => {
e.preventDefault();
const formData = new FormData(e.target);
const totalAmount = parseFloat(formData.get('totalAmount')) || 0;
const advance = parseFloat(formData.get('advance')) || 0;
const balance = totalAmount - advance;
const newBooking = {
id: Date.now(),
date: formData.get('date'),
time: formData.get('time'),
clientName: formData.get('clientName'),
clientPhone: formData.get('clientPhone'),
clientEmail: formData.get('clientEmail'),
service: formData.get('service'),
packageType: formData.get('packageType'),
totalAmount: totalAmount,
advance: advance,
balance: balance,
addedBy: currentUser.username
};
// Prepare Email Draft
const emailSubject = `Booking Confirmation - ${newBooking.service} with The Studio Clicks`;
const emailBody = `Dear ${newBooking.clientName},
Thank you for choosing The Studio Clicks! Your booking is confirmed.
Booking Details:
- Date: ${newBooking.date}
- Time: ${newBooking.time}
- Shoot Type: ${newBooking.service}
- Package: ${newBooking.packageType}
Payment Summary:
- Total Amount: ₹${newBooking.totalAmount}
- Advance Paid: ₹${newBooking.advance}
- Balance Due: ₹${newBooking.balance}
We look forward to capturing your special moments!
Best Regards,
The Studio Clicks Team`;
setDraftData({ booking: newBooking, emailSubject, emailBody });
setIsBookingModalOpen(false);
setIsEmailDraftOpen(true); // Open draft instead of saving immediately
};
const handleSaveAndSendEmail = (e) => {
e.preventDefault();
const formData = new FormData(e.target);
const finalSubject = formData.get('emailSubject');
const finalBody = formData.get('emailBody');
// Save booking
setBookings([...bookings, draftData.booking]);
setIsEmailDraftOpen(false);
// Trigger local email client
window.location.href = `mailto:${draftData.booking.clientEmail}?subject=${encodeURIComponent(finalSubject)}&body=${encodeURIComponent(finalBody)}`;
// Show Notification
setNotification(`Booking Saved! Email app opened for ${draftData.booking.clientEmail}`);
setTimeout(() => setNotification(''), 4500);
};
const handleDeleteBooking = (id) => {
setBookings(bookings.filter(b => b.id !== id));
};
// --- PAYMENT UPDATE LOGIC ---
const openPaymentModal = (booking) => {
setPaymentEditData(booking);
setIsPaymentModalOpen(true);
};
const handleUpdatePayment = (e) => {
e.preventDefault();
const formData = new FormData(e.target);
const additionalPayment = parseFloat(formData.get('additionalPayment')) || 0;
setBookings(bookings.map(b => {
if(b.id === paymentEditData.id) {
const newAdvance = b.advance + additionalPayment;
const newBalance = b.totalAmount - newAdvance;
return { ...b, advance: newAdvance, balance: newBalance };
}
return b;
}));
setIsPaymentModalOpen(false);
setNotification('Payment updated successfully!');
setTimeout(() => setNotification(''), 4500);
};
// --- RENDER LOGIN SCREEN ---
if (!currentUser) {
return ;
}
// --- RENDER MAIN APP ---
return (
{/* Navbar */}
The Studio Clicks Portal
Studio Portal
{/* View Toggle */}
{currentUser.role === 'admin' ? : }
{currentUser.username}
{currentUser.role} Account
{/* Main Content */}
{/* Toast Notification */}
{notification && (
{notification}
)}
{/* Header Controls */}
{currentView === 'calendar' ? (
{monthNames[month]} {year}
) : (
Booking Directory & Payments
)}
{currentView === 'calendar' ? (
/* Calendar Grid View */
{dayNames.map(day => (
{day}
))}
{Array.from({ length: firstDayIndex }).map((_, i) => (
))}
{Array.from({ length: daysInMonth }).map((_, i) => {
const day = i + 1;
const dateString = `${year}-${String(month + 1).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
const isToday = dateString === new Date().toISOString().split('T')[0];
const dayBookings = bookings.filter(b => b.date === dateString).sort((a, b) => a.time.localeCompare(b.time));
return (
{day}
{dayBookings.map(booking => (
0 ? 'bg-orange-50 border-orange-200 text-orange-900' : 'bg-emerald-50 border-emerald-200 text-emerald-900'}
`}
>
{booking.time}
0 ? `Balance Due: ₹${booking.balance}` : 'Fully Paid'}>
0 ? 'text-orange-500' : 'text-emerald-500'} />
{booking.clientName}
{booking.service}
))}
);
})}
) : (
/* List View / Data Table */
| Date & Time |
Client Information |
Shoot & Package |
Payment Status |
Actions |
{bookings.sort((a, b) => new Date(`${a.date}T${a.time}`) - new Date(`${b.date}T${b.time}`)).map(booking => (
|
{booking.date}
{booking.time}
|
{booking.clientName}
{booking.clientEmail}
|
{booking.service}
{booking.packageType || 'Custom'}
|
Total: ₹{booking.totalAmount}
Advance: ₹{booking.advance}
Balance:
0 ? 'text-red-500' : 'text-emerald-500'}`}>
₹{booking.balance}
|
{(currentUser.role === 'admin' || currentUser.username === booking.addedBy) && (
)}
|
))}
{bookings.length === 0 && (
| No bookings have been scheduled yet. |
)}
)}
{/* 1. Add Booking Form Modal */}
{isBookingModalOpen && (
New Client Booking
)}
{/* 2. Email Draft Modal */}
{isEmailDraftOpen && draftData && (
Review Email Draft
)}
{/* 3. Update Payment Modal */}
{isPaymentModalOpen && paymentEditData && (
Update Payment
)}
);
}
// --- SEPARATE LOGIN COMPONENT ---
function LoginScreen({ onLogin }) {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
onLogin(username, password);
};
return (
The Studio Clicks Portal
Sign in to manage client bookings & payments
);
}