Add Prettier for TypeScript formatting

- Install prettier
- Configure .prettierrc.json and .prettierignore
- Add npm scripts: format, format:check
- Add Makefile target: format-frontend
- Format all frontend files
This commit is contained in:
counterweight 2025-12-21 21:59:26 +01:00
parent 4b394b0698
commit 37de6f70e0
Signed by: counterweight
GPG key ID: 883EDBAA726BD96C
44 changed files with 906 additions and 856 deletions

View file

@ -181,7 +181,7 @@ export default function AppointmentsPage() {
const handleCancel = async (appointmentId: number) => {
setCancellingId(appointmentId);
setError(null);
try {
await api.post<AppointmentResponse>(`/api/appointments/${appointmentId}/cancel`, {});
await fetchAppointments();
@ -217,29 +217,25 @@ export default function AppointmentsPage() {
<Header currentPage="appointments" />
<div style={styles.content}>
<h1 style={styles.pageTitle}>My Appointments</h1>
<p style={styles.pageSubtitle}>
View and manage your booked appointments
</p>
<p style={styles.pageSubtitle}>View and manage your booked appointments</p>
{error && (
<div style={styles.errorBanner}>{error}</div>
)}
{error && <div style={styles.errorBanner}>{error}</div>}
{isLoadingAppointments ? (
<div style={styles.emptyState}>Loading appointments...</div>
) : appointments.length === 0 ? (
<div style={styles.emptyState}>
<p>You don&apos;t have any appointments yet.</p>
<a href="/booking" style={styles.emptyStateLink}>Book an appointment</a>
<a href="/booking" style={styles.emptyStateLink}>
Book an appointment
</a>
</div>
) : (
<>
{/* Upcoming Appointments */}
{upcomingAppointments.length > 0 && (
<div style={styles.section}>
<h2 style={styles.sectionTitle}>
Upcoming ({upcomingAppointments.length})
</h2>
<h2 style={styles.sectionTitle}>Upcoming ({upcomingAppointments.length})</h2>
<div style={styles.appointmentList}>
{upcomingAppointments.map((apt) => {
const status = getStatusDisplay(apt.status, true);
@ -250,20 +246,18 @@ export default function AppointmentsPage() {
<div style={styles.appointmentTime}>
{formatDateTime(apt.slot_start)}
</div>
{apt.note && (
<div style={styles.appointmentNote}>
{apt.note}
</div>
)}
<span style={{
...styles.statusBadge,
background: status.bgColor,
color: status.textColor,
}}>
{apt.note && <div style={styles.appointmentNote}>{apt.note}</div>}
<span
style={{
...styles.statusBadge,
background: status.bgColor,
color: status.textColor,
}}
>
{status.text}
</span>
</div>
{apt.status === "booked" && (
<div style={styles.buttonGroup}>
{confirmCancelId === apt.id ? (
@ -310,20 +304,19 @@ export default function AppointmentsPage() {
{pastOrCancelledAppointments.map((apt) => {
const status = getStatusDisplay(apt.status, true);
return (
<div key={apt.id} style={{...styles.appointmentCard, ...styles.appointmentCardPast}}>
<div style={styles.appointmentTime}>
{formatDateTime(apt.slot_start)}
</div>
{apt.note && (
<div style={styles.appointmentNote}>
{apt.note}
</div>
)}
<span style={{
...styles.statusBadge,
background: status.bgColor,
color: status.textColor,
}}>
<div
key={apt.id}
style={{ ...styles.appointmentCard, ...styles.appointmentCardPast }}
>
<div style={styles.appointmentTime}>{formatDateTime(apt.slot_start)}</div>
{apt.note && <div style={styles.appointmentNote}>{apt.note}</div>}
<span
style={{
...styles.statusBadge,
background: status.bgColor,
color: status.textColor,
}}
>
{status.text}
</span>
</div>
@ -338,4 +331,3 @@ export default function AppointmentsPage() {
</main>
);
}