anycoder-6472a9b4 / index.html
Ragab-Adel's picture
Upload folder using huggingface_hub
b7ba088 verified
Raw
History Blame Contribute Delete
32.9 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MediCare SaaS | Appointment Booking</title>
<!-- Google Fonts: Inter for a clean, modern medical look -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
<!-- FontAwesome for Icons -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
:root {
/* Color Palette: Healthcare White & Teal */
--primary-color: #0d9488; /* Teal 600 */
--primary-hover: #0f766e; /* Teal 700 */
--primary-light: #ccfbf1; /* Teal 100 */
--accent-color: #2dd4bf; /* Teal 400 */
--text-dark: #1e293b;
--text-gray: #64748b;
--bg-light: #f8fafc;
--white: #ffffff;
--border-color: #e2e8f0;
--success-color: #10b981;
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
--radius: 12px;
--transition: all 0.3s ease;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Inter', sans-serif;
background-color: var(--bg-light);
color: var(--text-dark);
line-height: 1.6;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
padding: 20px;
}
/* --- Layout Container --- */
.app-container {
width: 100%;
max-width: 1200px;
background: var(--white);
border-radius: var(--radius);
box-shadow: var(--shadow-lg);
overflow: hidden;
display: grid;
grid-template-columns: 1fr 1.5fr; /* Sidebar vs Form */
min-height: 85vh;
}
/* --- Sidebar (Branding & Info) --- */
.sidebar {
background: linear-gradient(135deg, #0f766e 0%, #0d9488 100%);
color: var(--white);
padding: 40px;
display: flex;
flex-direction: column;
justify-content: space-between;
position: relative;
}
.brand-logo {
display: flex;
align-items: center;
gap: 12px;
font-size: 1.5rem;
font-weight: 800;
letter-spacing: -0.5px;
}
.brand-logo i {
font-size: 2rem;
color: var(--white);
}
.clinic-info {
margin-top: 60px;
}
.clinic-info h2 {
font-size: 1.75rem;
margin-bottom: 20px;
font-weight: 600;
}
.info-item {
display: flex;
align-items: center;
gap: 15px;
margin-bottom: 20px;
font-size: 0.95rem;
opacity: 0.9;
}
.info-item i {
background: rgba(255,255,255,0.2);
padding: 8px;
border-radius: 8px;
width: 35px;
height: 35px;
text-align: center;
line-height: 19px;
}
.testimonial {
margin-top: auto;
padding-top: 30px;
border-top: 1px solid rgba(255,255,255,0.2);
font-style: italic;
font-size: 0.9rem;
}
.stars {
color: #fbbf24;
margin-bottom: 10px;
}
/* --- Main Content (Booking Form) --- */
.main-content {
padding: 50px;
overflow-y: auto;
}
.header-section {
margin-bottom: 40px;
}
.header-section h1 {
font-size: 2rem;
font-weight: 700;
color: var(--text-dark);
margin-bottom: 10px;
}
.header-section p {
color: var(--text-gray);
}
/* --- Form Steps Logic --- */
.booking-form {
display: flex;
flex-direction: column;
gap: 35px;
}
.step-container {
animation: fadeIn 0.5s ease;
}
.hidden {
display: none !important;
}
/* Step 1: Service & Doctor */
.form-grid {
display: grid;
grid-template-columns: 1fr;
gap: 25px;
}
@media (min-width: 768px) {
.form-grid {
grid-template-columns: 1fr 1fr;
}
}
.form-group {
display: flex;
flex-direction: column;
gap: 8px;
}
label {
font-size: 0.9rem;
font-weight: 600;
color: var(--text-dark);
}
select, input {
padding: 12px 16px;
border: 1px solid var(--border-color);
border-radius: 8px;
font-family: inherit;
font-size: 1rem;
transition: var(--transition);
background-color: var(--white);
outline: none;
}
select:focus, input:focus {
border-color: var(--primary-color);
box-shadow: 0 0 0 3px var(--primary-light);
}
/* Step 2: Calendar */
.calendar-widget {
background: var(--white);
border: 1px solid var(--border-color);
border-radius: var(--radius);
padding: 20px;
width: 100%;
box-shadow: var(--shadow-sm);
}
.calendar-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
font-weight: 600;
font-size: 1.1rem;
color: var(--text-dark);
}
.nav-btn {
background: none;
border: none;
cursor: pointer;
color: var(--text-gray);
padding: 8px;
border-radius: 6px;
transition: var(--transition);
}
.nav-btn:hover {
background-color: var(--bg-light);
color: var(--primary-color);
}
.weekdays {
display: grid;
grid-template-columns: repeat(7, 1fr);
text-align: center;
font-size: 0.75rem;
color: var(--text-gray);
font-weight: 600;
margin-bottom: 10px;
padding: 0 5px;
}
.days-grid {
display: grid;
grid-template-columns: repeat(7, 1fr);
gap: 5px;
}
.day {
height: 45px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 8px;
font-size: 0.9rem;
cursor: pointer;
transition: var(--transition);
border: 1px solid transparent;
}
.day:hover:not(.empty) {
background-color: var(--primary-light);
color: var(--primary-hover);
}
.day.selected {
background-color: var(--primary-color);
color: var(--white);
font-weight: 600;
}
.day.empty {
cursor: default;
}
.day.disabled {
color: #cbd5e1;
cursor: not-allowed;
}
.day.today {
border: 1px solid var(--primary-color);
color: var(--primary-color);
font-weight: 700;
}
/* Step 3: Time Slots */
.time-slots-container {
background: var(--bg-light);
padding: 25px;
border-radius: var(--radius);
}
.slots-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
gap: 12px;
margin-top: 15px;
}
.time-slot {
padding: 12px 0;
text-align: center;
background: var(--white);
border: 1px solid var(--border-color);
border-radius: 8px;
cursor: pointer;
transition: var(--transition);
font-size: 0.95rem;
color: var(--text-dark);
}
.time-slot:hover {
border-color: var(--primary-color);
color: var(--primary-color);
}
.time-slot.selected {
background-color: var(--primary-color);
color: var(--white);
border-color: var(--primary-color);
box-shadow: var(--shadow-md);
}
.time-slot.full {
background-color: #f1f5f9;
color: #cbd5e1;
cursor: not-allowed;
border-color: #e2e8f0;
}
/* Step 4: Details */
.full-width {
grid-column: 1 / -1;
}
.form-actions {
display: flex;
justify-content: flex-end;
gap: 15px;
margin-top: 30px;
padding-top: 30px;
border-top: 1px solid var(--border-color);
}
.btn {
padding: 14px 28px;
border-radius: 8px;
font-size: 1rem;
font-weight: 600;
cursor: pointer;
transition: var(--transition);
display: flex;
align-items: center;
gap: 10px;
}
.btn-secondary {
background-color: transparent;
color: var(--text-gray);
border: 1px solid var(--border-color);
}
.btn-secondary:hover {
background-color: var(--bg-light);
color: var(--text-dark);
}
.btn-primary {
background-color: var(--primary-color);
color: var(--white);
box-shadow: var(--shadow-md);
}
.btn-primary:hover {
background-color: var(--primary-hover);
transform: translateY(-1px);
box-shadow: var(--shadow-lg);
}
/* Success Modal */
.modal-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
opacity: 0;
visibility: hidden;
transition: var(--transition);
}
.modal-overlay.active {
opacity: 1;
visibility: visible;
}
.modal-content {
background: var(--white);
padding: 40px;
border-radius: var(--radius);
text-align: center;
max-width: 400px;
width: 90%;
box-shadow: var(--shadow-lg);
animation: slideUp 0.4s ease;
}
.success-icon {
width: 80px;
height: 80px;
background: var(--success-color);
color: var(--white);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 2.5rem;
margin: 0 auto 20px;
}
.confirmation-details {
background: var(--bg-light);
padding: 20px;
border-radius: 8px;
margin: 20px 0;
text-align: left;
}
.detail-row {
display: flex;
justify-content: space-between;
margin-bottom: 10px;
font-size: 0.95rem;
border-bottom: 1px dashed var(--border-color);
padding-bottom: 5px;
}
.detail-row:last-child {
border-bottom: none;
margin-bottom: 0;
padding-bottom: 0;
}
.detail-label {
color: var(--text-gray);
}
.detail-value {
font-weight: 600;
color: var(--text-dark);
}
/* Footer Link */
.footer-link {
text-align: center;
margin-top: 30px;
font-size: 0.8rem;
color: var(--text-gray);
}
.footer-link a {
color: var(--primary-color);
text-decoration: none;
font-weight: 600;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes slideUp {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
/* Responsive Mobile */
@media (max-width: 900px) {
.app-container {
grid-template-columns: 1fr;
height: auto;
}
.sidebar {
padding: 30px 20px;
text-align: center;
border-bottom: 1px solid var(--border-color);
}
.clinic-info {
margin-top: 30px;
}
.testimonial {
display: none; /* Hide testimonial on mobile to save space */
}
.main-content {
padding: 30px 20px;
}
}
</style>
</head>
<body>
<!-- Application Container -->
<div class="app-container">
<!-- Sidebar / Branding -->
<aside class="sidebar">
<div>
<div class="brand-logo">
<i class="fa-solid fa-heart-pulse"></i>
<span>MediCare SaaS</span>
</div>
<div class="clinic-info">
<h2>Dr. Sarah Jenkins</h2>
<p style="color: rgba(255,255,255,0.8); margin-bottom: 20px;">General Practitioner & Internal Medicine</p>
<div class="info-item">
<i class="fa-solid fa-location-dot"></i>
<span>123 Health Street, Medical District</span>
</div>
<div class="info-item">
<i class="fa-solid fa-clock"></i>
<span>Mon - Fri: 8:00 AM - 7:00 PM</span>
</div>
<div class="info-item">
<i class="fa-solid fa-phone"></i>
<span>+1 (555) 123-4567</span>
</div>
</div>
</div>
<div class="testimonial">
<div class="stars">
<i class="fa-solid fa-star"></i>
<i class="fa-solid fa-star"></i>
<i class="fa-solid fa-star"></i>
<i class="fa-solid fa-star"></i>
<i class="fa-solid fa-star"></i>
</div>
<p>"The most user-friendly booking system I've used. Quick, clean, and efficient. Highly recommend the clinic."</p>
</div>
</aside>
<!-- Main Booking Interface -->
<main class="main-content">
<div class="header-section">
<h1>Book an Appointment</h1>
<p>Fill in the details below to schedule your visit with Dr. Jenkins.</p>
</div>
<form class="booking-form" id="bookingForm">
<!-- STEP 1: Patient & Service Selection -->
<div class="step-container" id="step1">
<h3 style="margin-bottom: 20px; font-size: 1.2rem; color: var(--primary-color);">Step 1: Patient & Service</h3>
<div class="form-grid">
<div class="form-group">
<label for="fullName">Full Name</label>
<input type="text" id="fullName" placeholder="e.g. John Doe" required>
</div>
<div class="form-group">
<label for="email">Email Address</label>
<input type="email" id="email" placeholder="e.g. john@example.com" required>
</div>
<div class="form-group">
<label for="phone">Phone Number</label>
<input type="tel" id="phone" placeholder="e.g. (555) 123-4567" required>
</div>
<div class="form-group">
<label for="service">Select Service</label>
<select id="service" required>
<option value="" disabled selected>Choose a service</option>
<option value="general">General Consultation</option>
<option value="cardiology">Cardiology Checkup</option>
<option value="dentistry">Dental Inspection</option>
<option value="neurology">Neurology Consultation</option>
<option value="pediatrics">Pediatrics</option>
</select>
</div>
</div>
<div class="form-actions" style="justify-content: flex-end;">
<button type="button" class="btn btn-primary" onclick="nextStep(2)">
Next Step <i class="fa-solid fa-arrow-right"></i>
</button>
</div>
</div>
<!-- STEP 2: Date Selection -->
<div class="step-container hidden" id="step2">
<h3 style="margin-bottom: 20px; font-size: 1.2rem; color: var(--primary-color);">Step 2: Select Date</h3>
<div class="calendar-widget">
<div class="calendar-header">
<button type="button" class="nav-btn" id="prevMonth"><i class="fa-solid fa-chevron-left"></i></button>
<span id="currentDateDisplay">October 2023</span>
<button type="button" class="nav-btn" id="nextMonth"><i class="fa-solid fa-chevron-right"></i></button>
</div>
<div class="weekdays">
<div>Sun</div>
<div>Mon</div>
<div>Tue</div>
<div>Wed</div>
<div>Thu</div>
<div>Fri</div>
<div>Sat</div>
</div>
<div class="days-grid" id="daysContainer">
<!-- Days generated by JS -->
</div>
</div>
<div class="form-actions" style="justify-content: space-between;">
<button type="button" class="btn btn-secondary" onclick="prevStep(1)">
<i class="fa-solid fa-arrow-left"></i> Back
</button>
<button type="button" class="btn btn-primary" id="selectDateBtn" disabled onclick="nextStep(3)">
Select Time <i class="fa-solid fa-clock"></i>
</button>
</div>
</div>
<!-- STEP 3: Time Selection -->
<div class="step-container hidden" id="step3">
<h3 style="margin-bottom: 20px; font-size: 1.2rem; color: var(--primary-color);">Step 3: Select Time</h3>
<div class="time-slots-container">
<p style="margin-bottom: 15px; font-size: 0.9rem; color: var(--text-gray);">Available slots for <span id="selectedDateDisplay" style="font-weight: 700; color: var(--primary-color);">-</span></p>
<div class="slots-grid" id="timeSlotsGrid">
<!-- Time slots generated by JS -->
</div>
</div>
<div class="form-actions" style="justify-content: space-between;">
<button type="button" class="btn btn-secondary" onclick="prevStep(2)">
<i class="fa-solid fa-arrow-left"></i> Back
</button>
<button type="button" class="btn btn-primary" id="confirmBtn" disabled onclick="submitBooking()">
Confirm Booking <i class="fa-solid fa-check"></i>
</button>
</div>
</div>
</form>
<div class="footer-link">
By booking, you agree to our <a href="#">Privacy Policy</a> and <a href="#">Terms of Service</a>.
<br><br>
<a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" style="color: var(--primary-color); text-decoration: none; font-weight: 600;">Built with anycoder</a>
</div>
</main>
</div>
<!-- Success Modal -->
<div class="modal-overlay" id="successModal">
<div class="modal-content">
<div class="success-icon">
<i class="fa-solid fa-check"></i>
</div>
<h2 style="margin-bottom: 15px; color: var(--text-dark);">Appointment Confirmed!</h2>
<p style="color: var(--text-gray); margin-bottom: 20px;">Your appointment has been successfully scheduled.</p>
<div class="confirmation-details">
<div class="detail-row">
<span class="detail-label">Patient Name</span>
<span class="detail-value" id="modalName">-</span>
</div>
<div class="detail-row">
<span class="detail-label">Service</span>
<span class="detail-value" id="modalService">-</span>
</div>
<div class="detail-row">
<span class="detail-label">Date</span>
<span class="detail-value" id="modalDate">-</span>
</div>
<div class="detail-row">
<span class="detail-label">Time</span>
<span class="detail-value" id="modalTime">-</span>
</div>
<div class="detail-row" style="border-bottom: none;">
<span class="detail-label">Booking ID</span>
<span class="detail-value">#MED-8821</span>
</div>
</div>
<p style="font-size: 0.9rem; color: var(--text-gray); margin-bottom: 20px;">
A confirmation email has been sent to <span id="modalEmail" style="font-weight: 600;"></span>.
</p>
<button class="btn btn-primary" onclick="closeModal()">Return to Dashboard</button>
</div>
</div>
<script>
// --- State Management ---
const state = {
currentMonth: 0, // 0 = current month
selectedDate: null,
selectedTime: null,
selectedService: null,
patientInfo: {}
};
const services = {
"general": "General Consultation",
"cardiology": "Cardiology Checkup",
"dentistry": "Dental Inspection",
"neurology": "Neurology Consultation",
"pediatrics": "Pediatrics"
};
// --- Calendar Logic ---
const calendar = {
container: document.getElementById('daysContainer'),
display: document.getElementById('currentDateDisplay'),
prevBtn: document.getElementById('prevMonth'),
nextBtn: document.getElementById('nextMonth'),
init() {
this.render();
this.prevBtn.addEventListener('click', () => this.changeMonth(-1));
this.nextBtn.addEventListener('click', () => this.changeMonth(1));
},
changeMonth(direction) {
state.currentMonth += direction;
this.render();
},
render() {
this.container.innerHTML = '';
const date = new Date();
date.setMonth(date.getMonth() + state.currentMonth);
const year = date.getFullYear();
const month = date.getMonth();
const monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
this.display.textContent = `${monthNames[month]} ${year}`;
// First day of the month (0-6)
const firstDayIndex = new Date(year, month, 1).getDay();
// Total days in current month
const lastDay = new Date(year, month + 1, 0).getDate();
// Add empty slots for previous month
for (let i = 0; i < firstDayIndex; i++) {
const emptyDiv = document.createElement('div');
emptyDiv.className = 'day empty';
this.container.appendChild(emptyDiv);
}
// Add days
const today = new Date();
today.setHours(0,0,0,0);
for (let i = 1; i <= lastDay; i++) {
const dayDiv = document.createElement('div');
dayDiv.className = 'day';
dayDiv.textContent = i;
const currentDayDate = new Date(year, month, i);
currentDayDate.setHours(0,0,0,0);
// Disable past dates
if (currentDayDate < today) {
dayDiv.classList.add('disabled');
} else {
dayDiv.addEventListener('click', () => this.selectDate(dayDiv, currentDayDate));
}
// Highlight today if visible
if (i === today.getDate() && state.currentMonth === 0) {
dayDiv.classList.add('today');
}
this.container.appendChild(dayDiv);
}
},
selectDate(element, dateObj) {
// Remove previous selection
document.querySelectorAll('.day.selected').forEach(el => el.classList.remove('selected'));
// Add new selection
element.classList.add('selected');
state.selectedDate = dateObj;
// Update UI
const options = { weekday: 'short', month: 'short', day: 'numeric' };
document.getElementById('selectedDateDisplay').textContent = dateObj.toLocaleDateString('en-US', options);
// Enable Next Button
document.getElementById('selectDateBtn').disabled = false;
// Reset time selection
state.selectedTime = null;
document.getElementById('confirmBtn').disabled = true;
document.getElementById('timeSlotsGrid').innerHTML = '';
this.renderTimeSlots();
},
renderTimeSlots() {
const grid = document.getElementById('timeSlotsGrid');
const startHour = 9; // 9 AM
const endHour = 17; // 5 PM
const interval = 60; // 60 minutes
for (let hour = startHour; hour < endHour; hour++) {
// Generate 2 slots per hour for demo (e.g., 10:00 and 10:30)
const time1 = `${hour < 10 ? '0' + hour : hour}:00`;
const time2 = `${hour < 10 ? '0' + hour : hour}:30`;
this.createSlot(grid, time1);
this.createSlot(grid, time2);
}
},
createSlot(grid, time) {
const slot = document.createElement('div');
slot.className = 'time-slot';
slot.textContent = time;
// Simulate random full slots
const isFull = Math.random() > 0.8;
if (isFull) {
slot.classList.add('full');
} else {
slot.addEventListener('click', () => {
document.querySelectorAll('.time-slot.selected').forEach(el => el.classList.remove('selected'));
slot.classList.add('selected');
state.selectedTime = time;
document.getElementById('confirmBtn').disabled = false;
});
}
grid.appendChild(slot);
}
};
// --- Form Navigation Logic ---
function nextStep(stepNum) {
// Validation for Step 1
if (stepNum === 2) {
const name = document.getElementById('fullName').value;
const email = document.getElementById('email').value;
const service = document.getElementById('service').value;
if (!name || !email || !service) {
alert("Please fill in all patient details and select a service.");
return;
}
state.selectedService = services[service];
state.patientInfo = { name, email };
// Reset Calendar State
state.currentMonth = 0;
calendar.render();
document.getElementById('selectDateBtn').disabled = true;
document.getElementById('timeSlotsGrid').innerHTML = '';
}
// Hide all steps
document.querySelectorAll('.step-container').forEach(el => el.classList.add('hidden'));
// Show target step
document.getElementById(`step${stepNum}`).classList.remove('hidden');
}
function prevStep(stepNum) {
document.querySelectorAll('.step-container').forEach(el => el.classList.add('hidden'));
document.getElementById(`step${stepNum}`).classList.remove('hidden');
}
// --- Submit Logic ---
function submitBooking() {
if (!state.selectedDate || !state.selectedTime) {
alert("Please select a date and time for your appointment.");
return;
}
// Populate Modal
document.getElementById('modalName').textContent = state.patientInfo.name;
document.getElementById('modalEmail').textContent = state.patientInfo.email;
document.getElementById('modalService').textContent = state.selectedService;
const dateOptions = { weekday: 'long', month: 'long', day: 'numeric', year: 'numeric' };
document.getElementById('modalDate').textContent = state.selectedDate.toLocaleDateString('en-US', dateOptions);
document.getElementById('modalTime').textContent = state.selectedTime;
// Show Modal
document.getElementById('successModal').classList.add('active');
}
function closeModal() {
document.getElementById('successModal').classList.remove('active');
// Reset Form
document.getElementById('bookingForm').reset();
document.querySelectorAll('.step-container').forEach(el => el.classList.add('hidden'));
document.getElementById('step1').classList.remove('hidden');
// Reset Calendar
state.selectedDate = null;
state.selectedTime = null;
document.getElementById('selectDateBtn').disabled = true;
document.getElementById('confirmBtn').disabled = true;
document.getElementById('selectedDateDisplay').textContent = "-";
}
// Initialize Calendar on Load
document.addEventListener('DOMContentLoaded', () => {
calendar.init();
});
</script>
</body>
</html>