Files
ipad/src/components/booking/BookingSection.tsx
2025-11-26 10:11:39 +08:00

112 lines
4.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { BOOKING_DOCTORS } from '../../data/mockData';
import { Card, CardContent, CardHeader } from '../ui';
import { BookingModal } from './BookingModal';
import { cls } from '../../utils/cls';
interface BookingSectionProps {
selectedDay: number;
onSelectDay: (day: number) => void;
bookingDoctor: (typeof BOOKING_DOCTORS)[number] | null;
onSelectDoctor: (doctor: (typeof BOOKING_DOCTORS)[number]) => void;
onCloseModal: () => void;
}
export const BookingSection = ({
selectedDay,
onSelectDay,
bookingDoctor,
onSelectDoctor,
onCloseModal,
}: BookingSectionProps) => (
<div className='grid grid-cols-12 gap-6'>
<div className='col-span-4 space-y-4'>
<Card>
<CardHeader></CardHeader>
<CardContent>
<div className='grid grid-cols-6 gap-2 text-sm'>
{Array.from({ length: 30 }, (_, i) => i + 1).map((day) => (
<button
key={day}
onClick={() => onSelectDay(day)}
className={cls(
'h-9 rounded-2xl border flex items-center justify-center',
selectedDay === day ? 'bg-gray-900 text-white border-gray-900' : 'bg-white hover:bg-gray-50',
)}
>
{day}
</button>
))}
</div>
</CardContent>
</Card>
<Card>
<CardContent>
<div className='flex items-center justify-between text-sm'>
<span></span>
<span className='text-lg font-semibold'>{BOOKING_DOCTORS.length}</span>
</div>
</CardContent>
</Card>
</div>
<div className='col-span-8 space-y-4'>
<Card>
<CardHeader>
<span> · {selectedDay} </span>
<div className='flex items-center gap-2 text-xs'>
<span className='text-gray-500'></span>
<div className='relative inline-block'>
<select className='border border-gray-200 rounded-2xl px-4 py-1.5 pr-8 bg-white outline-none text-xs text-gray-700 hover:border-gray-300 focus:border-gray-900 focus:ring-2 focus:ring-gray-900/10 transition-all cursor-pointer appearance-none shadow-sm'>
<option value='all'></option>
<option value='internal'></option>
<option value='surgery'></option>
</select>
<div className='absolute right-3 top-1/2 -translate-y-1/2 pointer-events-none'>
<svg className='w-4 h-4 text-gray-500' fill='none' stroke='currentColor' viewBox='0 0 24 24'>
<path strokeLinecap='round' strokeLinejoin='round' strokeWidth={2} d='M19 9l-7 7-7-7' />
</svg>
</div>
</div>
</div>
</CardHeader>
</Card>
<div className='grid grid-cols-2 gap-4'>
{BOOKING_DOCTORS.map((doctor) => {
const ratio = doctor.total ? (doctor.total - doctor.remain) / doctor.total : 0;
const percent = Math.round(Math.max(0, Math.min(1, ratio)) * 100);
return (
<button key={doctor.id} onClick={() => onSelectDoctor(doctor)} className='text-left w-full'>
<Card className='bg-gray-50/40'>
<CardContent>
<div className='flex items-start justify-between mb-3'>
<div>
<div className='font-semibold mb-1'>{doctor.name}</div>
<div className='text-xs text-gray-500'>{doctor.dept}</div>
</div>
<span className='px-3 py-1 rounded-2xl border text-xs text-gray-600 bg-white'>{doctor.period}</span>
</div>
<div className='text-xs text-gray-600 space-y-1 mb-2'>
<div>{doctor.total} </div>
<div>
<span className='font-semibold text-gray-900'>{doctor.remain}</span>
</div>
</div>
<div className='h-2 rounded-full bg-gray-200 overflow-hidden'>
<div className='h-full bg-gray-900' style={{ width: `${percent}%` }} />
</div>
</CardContent>
</Card>
</button>
);
})}
</div>
</div>
{bookingDoctor && <BookingModal doctor={bookingDoctor} onClose={onCloseModal} />}
</div >
);