Build a hospital appointment scheduling interface that displays doctor appointments in day and week calendar views.
Time: 3-4 hours Focus: Architecture, design patterns, calendar rendering Framework: Next.js 14 + TypeScript
You're building an internal hospital scheduling system. The hospital has:
- 3 Doctors with different specialties and working hours
- 50 Patients with various appointments
- Appointments scheduled throughout the week
User Roles:
- Front Desk Staff: Can view all doctors' schedules
- Doctors: Can view only their own schedule
We've set up the foundation so you can focus on architecture and implementation:
- β Next.js 14 project with TypeScript
- β
Complete type definitions (
types/index.ts) - β
Mock data for 3 doctors, 50 patients, and appointments (
data/mockData.ts) - β Basic project structure
- β Component skeletons (TO BE IMPLEMENTED)
Demonstrate clean architecture patterns:
- Separation of concerns (domain, services, UI)
- Reusable, composable components
- Headless logic (hooks) separated from presentation
- Service layer for data access
Display appointments for a selected doctor on a selected date:
- Time slots from 8 AM to 6 PM (30-minute intervals)
- Show appointments in their correct time slots
- Display patient name, appointment type, and duration
- Color-coded by appointment type
- Handle overlapping appointments gracefully
Display appointments for a selected doctor across 7 days:
- Monday through Sunday
- Same time range (8 AM - 6 PM)
- Appointments positioned correctly by day and time
- Responsive layout
- Dropdown to select doctor (for front desk staff view)
- Display doctor's name, specialty, and working hours
- Filter appointments by selected doctor
We're evaluating your ability to structure frontend code following modern patterns:
-
Headless Components / Custom Hooks
// Separate business logic from UI function useAppointmentScheduler(doctorId: string, date: Date) { // Logic here return { appointments, timeSlots, loading, error }; }
-
Service Layer
// Abstract data access class AppointmentService { getAppointmentsByDoctorAndDate(doctorId: string, date: Date): Appointment[] }
-
Composable Components
<ScheduleView> <ScheduleHeader /> <TimelineGrid /> <AppointmentList /> </ScheduleView>
-
Domain Models (Optional but Encouraged)
class TimeSlot { constructor(public start: Date, public end: Date) {} overlaps(other: TimeSlot): boolean { } }
app/
βββ page.tsx # Main page (minimal, provided)
βββ schedule/
β βββ page.tsx # Schedule page (TO BE IMPLEMENTED)
βββ components/
β βββ ScheduleView.tsx # Main schedule component (SKELETON)
β βββ DayView.tsx # Day calendar view (TO BE IMPLEMENTED)
β βββ WeekView.tsx # Week calendar view (TO BE IMPLEMENTED)
β βββ DoctorSelector.tsx # Doctor dropdown (TO BE IMPLEMENTED)
β βββ ui/ # Reusable UI components
βββ hooks/
β βββ useAppointments.ts # Custom hooks (TO BE IMPLEMENTED)
βββ services/
β βββ appointmentService.ts # Data service (TO BE IMPLEMENTED)
βββ domain/ # Domain models (OPTIONAL)
β βββ Appointment.ts
β βββ TimeSlot.ts
βββ types/
β βββ index.ts # β
Type definitions (PROVIDED)
βββ data/
βββ mockData.ts # β
Mock data (PROVIDED)
βββββββββββββββββββββββββββββββββββββββββββ
β Dr. Sarah Chen - Cardiology β
β [Date Picker] [Week View Button] β
βββββββββββ¬ββββββββββββββββββββββββββββββββ€
β 8:00 β β
β 8:30 β [John Doe - Checkup] β
β 9:00 β [30 min] β
β 9:30 β β
β 10:00 β [Jane Smith - Consultation] β
β 10:30 β [60 min] β
β 11:00 β β
β 11:30 β β
β ... β β
βββββββββββ΄ββββββββββββββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Dr. Sarah Chen - Cardiology β
β Oct 14-20, 2024 [Day View Button] β
ββββββββ¬ββββββββ¬ββββββββ¬ββββββββ¬ββββββββ¬ββββββββ¬ββββββββ€
β Time β Mon β Tue β Wed β Thu β Fri β Sat β
ββββββββΌββββββββΌββββββββΌββββββββΌββββββββΌββββββββΌββββββββ€
β 8:00 β β β β β β β
β 9:00 β [Apt] β β [Apt] β β β β
β10:00 β β [Apt] β β [Apt] β β β
β11:00 β β β β β β β
β ... β β β β β β β
ββββββββ΄ββββββββ΄ββββββββ΄ββββββββ΄ββββββββ΄ββββββββ΄ββββββββ
- Use color coding for appointment types:
- Checkup: Blue (#3b82f6)
- Consultation: Green (#10b981)
- Follow-up: Orange (#f59e0b)
- Procedure: Purple (#8b5cf6)
- Show loading states while fetching data
- Handle empty states (no appointments)
- Responsive design (works on mobile and desktop)
Total: 3-4 hours
- 30 min - Review requirements, understand mock data, plan architecture
- 30 min - Set up services, hooks, domain models (architecture)
- 60 min - Implement Day View calendar
- 60 min - Implement Week View calendar
- 30 min - Polish, testing, documentation
| Criterion | Weight | What We're Looking For |
|---|---|---|
| Architecture & Design | 35% | - Clean separation of concerns - Service layer implementation - Headless hooks pattern - Reusable components |
| Day View Implementation | 25% | - Correct time slot rendering - Accurate appointment positioning - Handles overlaps - Visual clarity |
| Week View Implementation | 20% | - 7-day grid layout - Correct date/time positioning - Responsive design |
| Code Quality | 20% | - TypeScript usage - Clean, readable code - Component composition - No anti-patterns |
npm installnpm run devVisit http://localhost:3000
Start here:
types/index.ts- Understand the data modelsdata/mockData.ts- See the available dataapp/schedule/page.tsx- Your main entry point
Follow this order:
- Create
appointmentService.ts- Data access layer - Create
useAppointments.tshook - Business logic - Implement
DayView.tsx- Day calendar - Implement
WeekView.tsx- Week calendar - Implement
DoctorSelector.tsx- Doctor filter - Polish
ScheduleView.tsx- Main composition
-
Working Application
- All core features functional
- No console errors
- Runs with
npm run dev
-
Clean Code
- TypeScript (no
anytypes) - Consistent formatting
- Meaningful variable names
- TypeScript (no
-
Architecture
- Service layer implemented
- Custom hooks for business logic
- Components are composable
-
README Updates Add to this README:
- Architecture Decisions: Explain your key design choices
- Component Structure: Describe your component hierarchy
- Trade-offs: What would you improve with more time?
// Generate 30-minute time slots from 8 AM to 6 PM
function generateTimeSlots(date: Date): TimeSlot[] {
const slots = [];
for (let hour = 8; hour < 18; hour++) {
for (let minute of [0, 30]) {
const start = new Date(date);
start.setHours(hour, minute, 0, 0);
// ...
}
}
return slots;
}// Find appointments that fit in a specific time slot
function getAppointmentsForSlot(
appointments: Appointment[],
slotStart: Date
): Appointment[] {
return appointments.filter(apt => {
const aptStart = new Date(apt.startTime);
const aptEnd = new Date(apt.endTime);
// Does appointment overlap with this slot?
});
}Consider using date-fns (already in package.json):
import { format, addDays, isSameDay } from 'date-fns';- β Calendar/Date Libraries: react-big-calendar, FullCalendar, @tanstack/react-table, etc.
- β UI Component Libraries: shadcn/ui, Radix UI, Headless UI, etc.
- β Utility Libraries: lodash, ramda, date-fns (already included), etc.
- β AI Coding Assistants: GitHub Copilot, ChatGPT, Claude, etc.
What We're Evaluating:
- Understanding of library APIs and integration
- Ability to customize and adapt libraries to requirements
- Clean integration with your architecture
- Proper TypeScript usage with third-party libraries
We understand AI tools are part of modern development. Feel free to use them! What matters is:
- β You understand the code AI generates
- β You can explain your architectural decisions
- β You adapt and customize AI-generated code appropriately
- β Please mention in SUBMISSION.md which AI tools you used and how
Pro tip: Using a well-integrated calendar library with clean architecture often demonstrates better engineering judgment than building from scratch under time pressure.
- β Don't build drag-and-drop (out of scope)
- β Don't implement appointment creation/editing
- β Don't add authentication/authorization
- β Don't build a backend API
- Current time indicator (red line showing current time)
- Appointment search/filter
- Multiple doctor view (side-by-side comparison)
- Print-friendly view
- Dark mode
- Accessibility improvements (ARIA labels, keyboard navigation)
If requirements are unclear, make reasonable assumptions and document them in your README.
Remember: We value quality over quantity. A well-architected partial solution is better than a rushed complete one.
If you encounter setup issues:
- Check Node version (18+)
- Try
rm -rf node_modules && npm install - Check console for errors
Good luck! π