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}
))}
); })}
Fully Paid
Balance Pending
) : ( /* List View / Data Table */
{bookings.sort((a, b) => new Date(`${a.date}T${a.time}`) - new Date(`${b.date}T${b.time}`)).map(booking => ( ))} {bookings.length === 0 && ( )}
Date & Time Client Information Shoot & Package Payment Status Actions
{booking.date}
{booking.time}
{booking.clientName}
{booking.clientPhone}
{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) && ( )}
No bookings have been scheduled yet.
)}
{/* 1. Add Booking Form Modal */} {isBookingModalOpen && (

New Client Booking

{/* Date & Time */}
{/* Client Info */}
{/* Shoot & Package */}
{/* Payments */}
)} {/* 2. Email Draft Modal */} {isEmailDraftOpen && draftData && (

Review Email Draft

{draftData.booking.clientEmail}

You can edit the message above before sending. Clicking send will open your default mail app.

)} {/* 3. Update Payment Modal */} {isPaymentModalOpen && paymentEditData && (

Update Payment

Client: {paymentEditData.clientName}

Total Amount: ₹{paymentEditData.totalAmount}

Currently Paid: ₹{paymentEditData.advance}

Balance Pending: ₹{paymentEditData.balance}
{paymentEditData.balance > 0 ? (
) : (
Booking is fully paid!
)}
{paymentEditData.balance > 0 && ( )}
)}
); } // --- 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

setUsername(e.target.value)} className="w-full px-4 py-3 rounded-lg border border-gray-300 focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 transition-colors" placeholder="Enter username" required />
setPassword(e.target.value)} className="w-full px-4 py-3 rounded-lg border border-gray-300 focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 transition-colors" placeholder="Enter password" required />

Demo Credentials:

  • admin / admin
  • user / user
); }