BookingDetails.jsx
import React, { useState } from 'react';
import { useNavigate, useLocation } from 'react-router-dom';
import '../styles/BookingDetails.css';
export default function BookingDetails() {
const navigate = useNavigate();
const location = useLocation();
// Selected slot fallback parameters to prevent workspace crashes if accessed directly
const slot = location.state?.slot || {
slotNumber: 'A1',
floor: 1,
type: 'SUV, Compact',
pricePerHour: 20.00,
status: 'Available',
description: 'Near elevator lobby'
};
// State handles matching layout selections inside 37a2cf5f-4311-41fc-9ec1-cc681ada9259_2.png
const [selectedDuration, setSelectedDuration] = useState(4); // Default to 4 Hours button active border
const [startDate, setStartDate] = useState('2025-05-18');
const [startTime, setStartTime] = useState('09:00');
const [endDate, setEndDate] = useState('2025-05-18');
const [endTime, setEndTime] = useState('13:00');
const hourlyPrice = slot.pricePerHour || 20.00;
const totalCost = selectedDuration * hourlyPrice;
// Handles quick select clicks to instantly update totals
const handleQuickSelect = (hours) => {
setSelectedDuration(hours);
// Simulates changing end time option fields dynamically based on 9:00 AM start
const calculableEndHour = 9 + hours;
const formattedEndStr = calculableEndHour < 12
? `${calculableEndHour.toString().padStart(2, '0')}:00 AM`
: `${(calculableEndHour === 12 ? 12 : calculableEndHour - 12).toString().padStart(2, '0')}:00 PM`;
if (hours === 4) setEndTime('13:00');
};
return (
<div className="booking-wizard-layout-container">
{/* Breadcrumb Header Nav Tracker */}
<div className="wizard-breadcrumb-trail">
<span>Dashboard</span> <span className="trail-arrow">></span> <span className="trail-current">Booking Details</span>
</div>
<div className="wizard-split-columns-grid">
{/* Left Interactive Configuration Lane Container */}
<div className="wizard-main-config-stream">
<div className="card core-wizard-card">
<h2 className="wizard-main-heading">Booking Details</h2>
<p className="wizard-main-subheading">Select duration to book your parking slot</p>
{/* Step Progress Tracker Bar Component Map */}
<div className="wizard-steps-progress-bar-container">
<div className="step-node completed-active">
<div className="node-circle">1</div>
<span className="node-label">Select Slot</span>
</div>
<div className="step-progress-connector fill-active"></div>
<div className="step-node active-current">
<div className="node-circle">2</div>
<span className="node-label">Duration</span>
</div>
<div className="step-progress-connector"></div>
<div className="step-node pending">
<div className="node-circle">3</div>
<span className="node-label">Payment</span>
</div>
</div>
{/* Slot Specification Ribbon Bar */}
<div className="wizard-slot-specification-ribbon">
<div className="ribbon-big-badge">{slot.slotNumber}</div>
<div className="ribbon-spec-item">
<span className="ribbon-spec-label">Slot ID</span>
<strong className="ribbon-spec-val">{slot.slotNumber}</strong>
</div>
<div className="ribbon-spec-item">
<span className="ribbon-spec-label">Floor</span>
<strong className="ribbon-spec-val">Floor {slot.floor}</strong>
</div>
<div className="ribbon-spec-item">
<span className="ribbon-spec-label">Vehicle Type</span>
<strong className="ribbon-spec-val">{slot.type}</strong>
</div>
<div className="ribbon-spec-item">
<span className="ribbon-spec-label">Price per hour</span>
<strong className="ribbon-spec-val highlight-green">${hourlyPrice.toFixed(2)}</strong>
</div>
</div>
<div className="ribbon-sub-details-notice">
<span className="location-pin-icon">📍</span> {slot.description}
<span className="status-badge-green-flat">Available</span>
</div>
{/* Time Picker Parameters Controls Wrapper Section */}
<h4 className="section-block-title">Select Duration</h4>
<div className="time-picker-inputs-flex-row">
<div className="picker-input-group flex-1">
<label className="picker-field-label">Start Time</label>
<div className="picker-dual-fields-wrapper">
<input type="date" value={startDate} onChange={(e) => setStartDate(e.target.value)} className="picker-input-control-box" />
<input type="time" value={startTime} onChange={(e) => setStartTime(e.target.value)} className="picker-input-control-box" />
</div>
</div>
<div className="picker-input-group flex-1">
<label className="picker-field-label">End Time</label>
<div className="picker-dual-fields-wrapper">
<input type="date" value={endDate} onChange={(e) => setEndDate(e.target.value)} className="picker-input-control-box" />
<select value={endTime} onChange={(e) => setEndTime(e.target.value)} className="picker-input-control-box selector-dropdown">
<option value="13:00">01:00 PM</option>
<option value="14:00">02:00 PM</option>
<option value="15:00">03:00 PM</option>
</select>
</div>
</div>
</div>
{/* Quick Select Buttons Grid Options Block */}
<h5 className="section-sub-block-title">Quick Select Duration</h5>
<div className="quick-select-duration-buttons-grid">
{[
{ label: '1 Hour', value: 1 },
{ label: '2 Hours', value: 2 },
{ label: '3 Hours', value: 3 },
{ label: '4 Hours', value: 4 },
{ label: '6 Hours', value: 6 },
{ label: '12 Hours', value: 12 }
].map((opt) => (
<button
key={opt.value}
onClick={() => handleQuickSelect(opt.value)}
className={`quick-duration-option-card-btn ${selectedDuration === opt.value ? 'is-btn-state-active' : ''}`}
>
<div className="option-duration-lbl">{opt.label}</div>
<div className="option-cost-subtext">${(opt.value * hourlyPrice).toFixed(2)}</div>
</button>
))}
</div>
{/* Highlight Selected Text String Status Display */}
<div className="highlighted-running-duration-output-row">
Duration <span className="green-highlight-text">{selectedDuration} Hours</span>
</div>
{/* Cost Breakdown Summary Container Frame */}
<div className="wizard-inner-cost-summary-container">
<h5 className="cost-summary-inner-heading">Cost Summary</h5>
<div className="cost-summary-split-row">
<span className="cost-summary-lbl">Price per hour</span>
<span className="cost-summary-val-bold">${hourlyPrice.toFixed(2)}</span>
</div>
<div className="cost-summary-split-row padding-bottom-border">
<span className="cost-summary-lbl">Duration</span>
<span className="cost-summary-val-bold">{selectedDuration} Hours</span>
</div>
<div className="cost-summary-split-row master-total-cost-row">
<span className="total-cost-label">Total Cost</span>
<span className="total-cost-value-green">${totalCost.toFixed(2)}</span>
</div>
</div>
{/* Action Footer Button Controls Row */}
<div className="wizard-action-footer-buttons-row">
<button onClick={() => navigate(-1)} className="btn-wizard-nav-back">
← Back
</button>
<button
onClick={() => navigate('/payment', { state: { slot, duration: selectedDuration, totalCost } })}
className="btn-wizard-nav-proceed-blue"
>
Proceed to Payment →
</button>
</div>
</div>
</div>
{/* Right Side Pinned Summary Panel Column Card Container */}
<div className="wizard-right-sticky-summary-sidebar-card card">
<h4 className="sidebar-summary-card-title">Your Booking Summary</h4>
<div className="sidebar-summary-slot-horizontal-badge-row">
<div className="summary-slot-square-box-green">{slot.slotNumber}</div>
<div>
<strong className="summary-slot-title-text">Slot {slot.slotNumber}</strong>
<div className="summary-slot-floor-subtext">Floor {slot.floor}</div>
</div>
<span className="summary-status-badge-green-flat-right">Available</span>
</div>
<div className="sidebar-summary-spec-list-rows-stack">
<div className="summary-spec-item-row">
<div className="summary-spec-left-lbl">🚗 Vehicle Type</div>
<strong className="summary-spec-right-val">{slot.type}</strong>
</div>
<div className="summary-spec-item-row">
<div className="summary-spec-left-lbl">📅 Start Time</div>
<strong className="summary-spec-right-val">18 May 2025, 09:00 AM</strong>
</div>
<div className="summary-spec-item-row">
<div className="summary-spec-left-lbl">📅 End Time</div>
<strong className="summary-spec-right-val">18 May 2025, 01:00 PM</strong>
</div>
<div className="summary-spec-item-row">
<div className="summary-spec-left-lbl">🕒 Duration</div>
<strong className="summary-spec-right-val">{selectedDuration} Hours</strong>
</div>
<div className="summary-spec-item-row border-none">
<div className="summary-spec-left-lbl">💰 Price per hour</div>
<strong className="summary-spec-right-val">${hourlyPrice.toFixed(2)}</strong>
</div>
</div>
<div className="sidebar-summary-total-cost-split-row">
<span className="summary-total-cost-label">Total Cost</span>
<span className="summary-total-cost-value-green">${totalCost.toFixed(2)}</span>
</div>
{/* Golden Yellow Alert Advisory Information Box Component */}
<div className="sidebar-summary-cancellation-advisory-alert-box">
<span className="alert-info-icon-orange">ℹ️</span>
<p className="alert-advisory-text-para">
You can cancel your booking up to 30 minutes before the start time.
</p>
</div>
{/* Secure Transact Shield Trust Card Anchor Wrapper */}
<div className="sidebar-summary-secure-trust-shield-box-blue">
<span className="trust-shield-icon-blue">🛡️</span>
<div>
<strong className="trust-title-text">Secure Booking</strong>
<p className="trust-subtext-para">Your payment details are safe and encrypted.</p>
</div>
</div>
</div>
</div>
</div>
);
}
dashboard.jsx
import React, { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import '../styles/Dashboard.css';
export default function Dashboard() {
const navigate = useNavigate();
// Custom 32-element structured mock coordinates map layout logic array
const initialGridData = [
{ id: 'A1', row: 'A', status: 'available', icon: '🚗' },
{ id: 'A2', row: 'A', status: 'booked', icon: '🚗' },
{ id: 'A3', row: 'A', status: 'reserved', icon: '🚗' },
{ id: 'A4', row: 'A', status: 'available', icon: '🚗' },
{ id: 'A5', row: 'A', status: 'available', icon: '🚗' },
{ id: 'A6', row: 'A', status: 'out-of-service', icon: '✕' },
{ id: 'A7', row: 'A', status: 'booked', icon: '🚗' },
{ id: 'A8', row: 'A', status: 'available', icon: '🚗' },
{ id: 'B1', row: 'B', status: 'available', icon: '🚗' },
{ id: 'B2', row: 'B', status: 'available', icon: '🚗' },
{ id: 'B3', row: 'B', status: 'booked', icon: '🚗' },
{ id: 'B4', row: 'B', status: 'reserved', icon: '🚗' },
{ id: 'B5', row: 'B', status: 'available', icon: '🚗' },
{ id: 'B6', row: 'B', status: 'available', icon: '🚗' },
{ id: 'B7', row: 'B', status: 'booked', icon: '🚗' },
{ id: 'B8', row: 'B', status: 'available', icon: '🚗' },
{ id: 'C1', row: 'C', status: 'available', icon: '🚗' },
{ id: 'C2', row: 'C', status: 'out-of-service', icon: '✕' },
{ id: 'C3', row: 'C', status: 'available', icon: '🚗' },
{ id: 'C4', row: 'C', status: 'available', icon: '🚗' },
{ id: 'C5', row: 'C', status: 'booked', icon: '🚗' },
{ id: 'C6', row: 'C', status: 'reserved', icon: '🚗' },
{ id: 'C7', row: 'C', status: 'available', icon: '🚗' },
{ id: 'C8', row: 'C', status: 'available', icon: '🚗' },
{ id: 'D1', row: 'D', status: 'available', icon: '🚗' },
{ id: 'D2', row: 'D', status: 'available', icon: '🚗' },
{ id: 'D3', row: 'D', status: 'reserved', icon: '🚗' },
{ id: 'D4', row: 'D', status: 'available', icon: '🚗' },
{ id: 'D5', row: 'D', status: 'booked', icon: '🚗' },
{ id: 'D6', row: 'D', status: 'out-of-service', icon: '✕' },
{ id: 'D7', row: 'D', status: 'available', icon: '🚗' },
{ id: 'D8', row: 'D', status: 'available', icon: '🚗' }
];
const [selectedSlot, setSelectedSlot] = useState(null);
return (
<div className="user-dashboard-split-layout">
{/* Central Viewport Stream Column */}
<div className="dashboard-scrollable-main-stream">
<div className="user-welcome-header-ribbon">
<h2>Welcome back, John! 👋</h2>
<p>Here's what's happening with your parking today.</p>
</div>
{/* Top Analytics Metrics Row Cards */}
<div className="dashboard-metrics-summary-row">
<div className="metric-box-card">
<div className="metric-icon-avatar color-accent-blue">📅</div>
<div>
<span className="metric-lbl">Active Bookings</span>
<h3 className="metric-val">2</h3>
<span className="metric-link text-blue">View all bookings →</span>
</div>
</div>
<div className="metric-box-card">
<div className="metric-icon-avatar color-accent-green">🕒</div>
<div>
<span className="metric-lbl">Total Hours Parked</span>
<h3 className="metric-val">120 hrs</h3>
<span className="metric-link text-green">View summary →</span>
</div>
</div>
<div className="metric-box-card">
<div className="metric-icon-avatar color-accent-purple">💳</div>
<div>
<span className="metric-lbl">Wallet Balance</span>
<h3 className="metric-val">$450.00</h3>
<span className="metric-link text-purple">Add money →</span>
</div>
</div>
</div>
{/* Interactive Matrix Core Map Container Panel */}
<div className="card customer-parking-map-panel-card">
<div className="map-header-inline-flex">
<h3>Parking Map</h3>
<div className="map-legends-row-stack">
<div className="legend-item"><span className="dot bg-green"></span> Available</div>
<div className="legend-item"><span className="dot bg-yellow"></span> Reserved</div>
<div className="legend-item"><span className="dot bg-red"></span> Booked</div>
<div className="legend-item"><span className="dot bg-gray"></span> Out of Service</div>
</div>
</div>
<div className="map-rows-vertical-stack">
{['A', 'B', 'C', 'D'].map((rowLetter, idx) => (
<div key={rowLetter} className="map-row-strip-wrapper">
<div className="row-indicator-label-sub">
<strong>Row {rowLetter}</strong>
<span>(Floor {idx + 1})</span>
</div>
<div className="row-slots-eight-columns-grid">
{initialGridData
.filter((item) => item.row === rowLetter)
.map((slot) => (
<button
key={slot.id}
onClick={() => slot.status !== 'out-of-service' && setSelectedSlot(slot)}
className={`parking-slot-box-cell cell-status-${slot.status} ${selectedSlot?.id === slot.id ? 'cell-state-active-border' : ''}`}
>
<span className="slot-cell-id">{slot.id}</span>
<span className="slot-cell-icon">{slot.icon}</span>
</button>
))}
</div>
</div>
))}
</div>
<div className="map-footer-guideline-notice">ℹ️ Click on an available slot to book</div>
</div>
{/* Recent Transactions Footer Panel Logs */}
<div className="dashboard-bottom-history-tickets-section">
<div className="history-section-header-flex">
<h4>Your Recent Bookings</h4>
<span className="btn-text-link-view-all">View all →</span>
</div>
<div className="history-tickets-flex-row">
<div className="booking-ticket-horizontal-card">
<div className="ticket-badge-box bg-green-light">A1</div>
<div className="ticket-details-mid-stack">
<span className="status-pill active-badge">Active</span>
<strong className="ticket-datetime-str">18 May 2025, 09:00 AM</strong>
<span className="ticket-duration-lbl">🕒 4 Hours</span>
</div>
<div className="ticket-right-price-action-stack">
<span className="ticket-price-val">$80.00</span>
<button className="btn-ticket-secondary-action">View Details</button>
</div>
</div>
<div className="booking-ticket-horizontal-card">
<div className="ticket-badge-box bg-orange-light">B4</div>
<div className="ticket-details-mid-stack">
<span className="status-pill completed-badge">Completed</span>
<strong className="ticket-datetime-str">16 May 2025, 06:00 PM</strong>
<span className="ticket-duration-lbl">🕒 3 Hours</span>
</div>
<div className="ticket-right-price-action-stack">
<span className="ticket-price-val">$60.00</span>
<button className="btn-ticket-secondary-action">View Details</button>
</div>
</div>
</div>
</div>
</div>
{/* Right Side Inspection Panel Component Block */}
<div className="dashboard-right-inspection-sidebar-panel card">
{selectedSlot ? (
<div className="inspection-active-view-container">
<h4 className="inspection-title-label">Slot Details</h4>
<div className={`inspection-slot-giant-badge badge-color-${selectedSlot.status}`}>{selectedSlot.id}</div>
<span className={`inspection-status-tag-text tag-color-${selectedSlot.status}`}>{selectedSlot.status.replace('-', ' ')}</span>
<div className="inspection-spec-rows-list">
<div className="spec-item-line"><span className="lbl">Slot ID</span><strong>{selectedSlot.id}</strong></div>
<div className="spec-item-line"><span className="lbl">Floor</span><strong>Floor {selectedSlot.row === 'A' ? 1 : selectedSlot.row === 'B' ? 2 : selectedSlot.row === 'C' ? 3 : 4}</strong></div>
<div className="spec-item-line"><span className="lbl">Vehicle Type</span><strong>SUV, Compact</strong></div>
<div className="spec-item-line"><span className="lbl">Price per hour</span><strong>$20.00</strong></div>
<div className="spec-item-line"><span className="lbl">Description</span><strong>Near elevator lobby</strong></div>
</div>
<div className="inspection-shield-notice-box-green">
<span className="shield-icon">🛡️</span>
<div>
<strong>CCTV Monitored</strong>
<p>24/7 Security Coverage Active</p>
</div>
</div>
{selectedSlot.status === 'available' && (
<button
onClick={() => navigate('/booking-details', { state: { slot: { slotNumber: selectedSlot.id, floor: selectedSlot.row === 'A' ? 1 : selectedSlot.row === 'B' ? 2 : selectedSlot.row === 'C' ? 3 : 4, type: 'SUV, Compact', pricePerHour: 20.00, description: 'Near elevator lobby' } } })}
className="btn-inspection-primary-book-now"
>
📅 Book Now
</button>
)}
</div>
) : (
<div className="inspection-fallback-empty-view">
<div className="fallback-avatar-circle">🅿️</div>
<p>Select a parking slot from the map layout to inspect detail structures or commit reservations.</p>
</div>
)}
</div>
</div>
);
}
[18/06, 11:22 pm] Mauli Tcs: header.css
/* Header global tracking frame structural logic controls */
.app-header-navigation-bar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px 32px;
background-color: #ffffff;
border-bottom: 1px solid #e2e8f0;
height: 80px;
width: 100%;
box-sizing: border-box;
}
.header-search-bar-wrapper {
position: relative;
width: 300px;
}
.header-search-input {
width: 100%;
padding: 10px 16px 10px 40px;
border: 1px solid #e2e8f0;
border-radius: 8px;
font-size: 13px;
background-color: #f8fafc;
color: #0f172a;
outline: none;
transition: all 0.2s;
}
.header-search-input:focus {
border-color: #2563eb;
background-color: #ffffff;
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);
}
.header-search-icon {
position: absolute;
left: 14px;
top: 50%;
transform: translateY(-50%);
color: #94a3b8;
font-size: 14px;
}
.header-right-actions-cluster {
display: flex;
align-items: center;
gap: 24px;
}
.header-notification-bell-btn {
background: none;
border: none;
font-size: 20px;
cursor: pointer;
position: relative;
color: #64748b;
padding: 4px;
display: flex;
align-items: center;
justify-content: center;
transition: color 0.2s;
}
.header-notification-bell-btn:hover {
color: #0f172a;
}
.bell-badge-count-dot {
position: absolute;
top: 2px;
right: 2px;
background-color: #ef4444;
color: #ffffff;
font-size: 10px;
font-weight: 700;
width: 16px;
height: 16px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
border: 2px solid #ffffff;
}
.header-user-profile-dropdown-trigger {
display: flex;
align-items: center;
gap: 12px;
cursor: pointer;
padding: 4px 8px;
border-radius: 8px;
transition: background-color 0.2s;
}
.header-user-profile-dropdown-trigger:hover {
background-color: #f1f5f9;
}
.header-user-meta-stack {
display: flex;
flex-direction: column;
align-items: flex-end;
}
.header-profile-display-name {
font-size: 14px;
font-weight: 600;
color: #1e293b;
}
.header-profile-role-subtag {
font-size: 11px;
font-weight: 700;
color: #2563eb;
text-transform: uppercase;
letter-spacing: 0.5px;
margin-top: 2px;
}
.header-avatar-circle-frame {
width: 36px;
height: 36px;
border-radius: 50%;
background-color: #e2e8f0;
color: #2563eb;
font-weight: 700;
font-size: 14px;
display: flex;
align-items: center;
justify-content: center;
border: 2px solid #eff6ff;
}
[18/06, 11:22 pm] Mauli Tcs: login.css
/* Login Screen Master Wrapper Layout */
.login-screen-wrapper {
display: flex;
height: 100vh;
width: 100vw;
align-items: center;
justify-content: center;
background-color: #f8fafc;
position: fixed;
top: 0;
left: 0;
z-index: 9999;
}
/* Double-Pane Container Framework */
.login-card-container {
display: flex;
background: #ffffff;
border-radius: 20px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.04);
width: 920px;
min-height: 540px;
overflow: hidden;
border: 1px solid #f1f5f9;
}
/* Left Graphic Brand Panel View styling */
.login-brand-side {
flex: 1.1;
background-color: #fcfdfe;
padding: 48px;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: flex-start;
position: relative;
}
.brand-text-header {
width: 100%;
}
.brand-title {
color: #1e40af;
font-weight: 800;
font-size: 32px;
letter-spacing: -0.5px;
margin-bottom: 4px;
}
.brand-subtitle {
color: #64748b;
font-size: 16px;
font-weight: 500;
}
.brand-illustration-container {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
margin-top: auto;
}
.brand-vector-svg {
width: 100%;
max-width: 360px;
height: auto;
}
/* Right Core Credentials Panel Form Styling */
.login-form-side {
flex: 1;
padding: 56px;
display: flex;
flex-direction: column;
justify-content: center;
background: #ffffff;
}
.form-welcome-title {
font-size: 26px;
font-weight: 700;
color: #0f172a;
margin-bottom: 6px;
}
.form-welcome-subtitle {
color: #64748b;
font-size: 14px;
margin-bottom: 32px;
}
.form-input-group {
display: flex;
flex-direction: column;
margin-bottom: 20px;
}
.form-field-label {
font-size: 13px;
font-weight: 600;
color: #475569;
margin-bottom: 8px;
}
.form-text-input {
padding: 14px 16px;
border: 1px solid #cbd5e1;
border-radius: 10px;
font-size: 14px;
color: #0f172a;
background-color: #ffffff;
transition: border-color 0.2s;
width: 100%;
}
.form-text-input:focus {
outline: none;
border-color: #2563eb;
}
/* Password Input Wrapper with Icon position features */
.password-input-wrapper {
position: relative;
display: flex;
align-items: center;
}
.form-text-input-password {
padding: 14px 44px 14px 16px;
border: 1px solid #cbd5e1;
border-radius: 10px;
font-size: 14px;
color: #0f172a;
width: 100%;
}
.form-text-input-password:focus {
outline: none;
border-color: #2563eb;
}
.password-visibility-icon {
position: absolute;
right: 16px;
color: #94a3b8;
cursor: pointer;
user-select: none;
}
/* Forgot Password Section Position alignment rules */
.forgot-password-link-wrapper {
display: flex;
justify-content: flex-end;
margin-top: -8px;
margin-bottom: 28px;
}
.forgot-password-anchor {
font-size: 13px;
color: #2563eb;
text-decoration: none;
font-weight: 600;
}
.forgot-password-anchor:hover {
text-decoration: underline;
}
/* Unified Action Controls Button Layout stack definitions */
.login-action-buttons-stack {
display: flex;
flex-direction: column;
gap: 14px;
}
.btn-login-customer, .btn-login-admin {
width: 100%;
padding: 15px;
border: none;
border-radius: 10px;
font-size: 15px;
font-weight: 700;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
transition: transform 0.1s, filter 0.2s;
}
.btn-login-customer {
background: linear-gradient(135deg, #2563eb 0%, #1d4ed8 100%);
color: #ffffff;
box-shadow: 0 4px 12px rgba(37, 99, 235, 0.2);
}
.btn-login-admin {
background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%);
color: #ffffff;
box-shadow: 0 4px 12px rgba(15, 23, 42, 0.2);
}
.btn-login-customer:hover, .btn-login-admin:hover {
filter: brightness(1.05);
}
.btn-login-customer:active, .btn-login-admin:active {
transform: scale(0.99);
}
.btn-icon {
font-size: 16px;
}
/* Responsive Handling Collapse rule views */
@media (max-width: 960px) {
.login-card-container {
width: 90%;
flex-direction: column;
}
.login-brand-side {
padding: 32px;
align-items: center;
text-align: center;
}
.login-form-side {
padding: 32px;
}
}
[18/06, 11:23 pm] Mauli Tcs: app.css /* 1. Prevent global page spilling and manage system margins */
html, body, #root {
margin: 0;
padding: 0;
width: 100%;
height: 100vh;
background-color: #f8fafc;
overflow: hidden; /* Stops the entire browser window from spilling or scrolling sideways */
}
/* 2. Master App Layout Component Wrapper */
.app-master-layout {
display: flex;
width: 100vw;
height: 100vh;
overflow: hidden;
}
/* 3. The Central Scrollable Dashboard Flow View Component */
.app-viewport-content-flow {
flex: 1;
display: flex;
flex-direction: column;
height: 100vh;
min-width: 0; /* Important: prevents child components from over-stretching flex containers */
}
/* 4. Global Root Variables & Reset Options */
:root {
--primary-color: #2563eb;
--bg-dark: #0f172a;
--bg-light: #f8fafc;
--text-main: #1e293b;
--border-color: #e2e8f0;
--available: #e6f4ea;
--available-text: #137333;
--booked: #fce8e6;
--booked-text: #c5221f;
--reserved: #fef7e0;
--reserved-text: #b06000;
--out-of-service: #f1f3f4;
--out-of-service-text: #5f6368;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}
body {
background-color: var(--bg-light);
color: var(--text-main);
}
.app-container {
display: flex;
min-height: 100vh;
}
.main-content {
flex: 1;
padding: 24px;
background-color: #f8fafc;
overflow-y: auto;
}
/* Layout Cards */
.card {
background: white;
border-radius: 12px;
border: 1px solid var(--border-color);
padding: 24px;
margin-bottom: 24px;
}
/* Responsive Breakpoints */
@media (max-width: 1024px) {
.dashboard-grid {
grid-template-columns: 1fr !important;
}
}
@media (max-width: 768px) {
.app-container {
flex-direction: column;
}
}
/* Responsive render field padding block layout */
.main-render-view-area {
flex: 1;
padding: 32px;
overflow-y: auto;
}