Extract common errorBanner style to shared styles

- Added errorBanner to sharedStyles for consistent error display
- Removed duplicate errorBanner definitions from all pages
- Updated appointments, booking, admin/appointments, and admin/availability pages
- Reduced code duplication while maintaining component-specific styles
This commit is contained in:
counterweight 2025-12-21 18:01:30 +01:00
parent 3d83472b97
commit b9f605d7b3
Signed by: counterweight
GPG key ID: 883EDBAA726BD96C
5 changed files with 40 additions and 43 deletions

View file

@ -9,11 +9,12 @@ import { useRequireAuth } from "../../hooks/useRequireAuth";
import { components } from "../../generated/api";
import { formatDateTime } from "../../utils/date";
import { getStatusDisplay } from "../../utils/appointment";
import { sharedStyles } from "../../styles/shared";
type AppointmentResponse = components["schemas"]["AppointmentResponse"];
type PaginatedAppointments = components["schemas"]["PaginatedResponse_AppointmentResponse_"];
const styles: Record<string, React.CSSProperties> = {
const pageStyles: Record<string, React.CSSProperties> = {
main: {
minHeight: "100vh",
background: "linear-gradient(135deg, #0f0f23 0%, #1a1a3e 50%, #2d1b4e 100%)",
@ -48,16 +49,6 @@ const styles: Record<string, React.CSSProperties> = {
fontSize: "0.9rem",
marginBottom: "1.5rem",
},
errorBanner: {
background: "rgba(239, 68, 68, 0.15)",
border: "1px solid rgba(239, 68, 68, 0.3)",
color: "#f87171",
padding: "1rem",
borderRadius: "8px",
marginBottom: "1rem",
fontFamily: "'DM Sans', system-ui, sans-serif",
fontSize: "0.875rem",
},
filterRow: {
display: "flex",
alignItems: "center",
@ -161,6 +152,8 @@ const styles: Record<string, React.CSSProperties> = {
},
};
const styles = { ...sharedStyles, ...pageStyles };
export default function AdminAppointmentsPage() {
const { user, isLoading, isAuthorized } = useRequireAuth({
requiredPermission: Permission.VIEW_ALL_APPOINTMENTS,

View file

@ -431,16 +431,6 @@ const pageStyles: Record<string, React.CSSProperties> = {
borderRadius: "8px",
cursor: "pointer",
},
errorBanner: {
fontFamily: "'DM Sans', system-ui, sans-serif",
fontSize: "0.9rem",
padding: "1rem",
background: "rgba(239, 68, 68, 0.15)",
border: "1px solid rgba(239, 68, 68, 0.3)",
borderRadius: "8px",
color: "#f87171",
marginBottom: "1rem",
},
calendar: {
display: "grid",
gridTemplateColumns: "repeat(auto-fill, minmax(180px, 1fr))",

View file

@ -9,10 +9,11 @@ import { useRequireAuth } from "../hooks/useRequireAuth";
import { components } from "../generated/api";
import { formatDateTime } from "../utils/date";
import { getStatusDisplay } from "../utils/appointment";
import { sharedStyles } from "../styles/shared";
type AppointmentResponse = components["schemas"]["AppointmentResponse"];
const styles: Record<string, React.CSSProperties> = {
const pageStyles: Record<string, React.CSSProperties> = {
main: {
minHeight: "100vh",
background: "linear-gradient(135deg, #0f0f23 0%, #1a1a3e 50%, #2d1b4e 100%)",
@ -47,16 +48,6 @@ const styles: Record<string, React.CSSProperties> = {
fontSize: "0.9rem",
marginBottom: "1.5rem",
},
errorBanner: {
background: "rgba(239, 68, 68, 0.15)",
border: "1px solid rgba(239, 68, 68, 0.3)",
color: "#f87171",
padding: "1rem",
borderRadius: "8px",
marginBottom: "1rem",
fontFamily: "'DM Sans', system-ui, sans-serif",
fontSize: "0.875rem",
},
section: {
marginBottom: "2rem",
},
@ -155,6 +146,8 @@ const styles: Record<string, React.CSSProperties> = {
},
};
const styles = { ...sharedStyles, ...pageStyles };
export default function AppointmentsPage() {
const { user, isLoading, isAuthorized } = useRequireAuth({
requiredPermission: Permission.VIEW_OWN_APPOINTMENTS,

View file

@ -9,6 +9,7 @@ import { useRequireAuth } from "../hooks/useRequireAuth";
import { components } from "../generated/api";
import constants from "../../../shared/constants.json";
import { formatDate, formatTime, getDateRange } from "../utils/date";
import { sharedStyles } from "../styles/shared";
const { slotDurationMinutes, maxAdvanceDays, minAdvanceDays, noteMaxLength } = constants.booking;
@ -16,7 +17,7 @@ type BookableSlot = components["schemas"]["BookableSlot"];
type AvailableSlotsResponse = components["schemas"]["AvailableSlotsResponse"];
type AppointmentResponse = components["schemas"]["AppointmentResponse"];
const styles: Record<string, React.CSSProperties> = {
const pageStyles: Record<string, React.CSSProperties> = {
main: {
minHeight: "100vh",
background: "linear-gradient(135deg, #0f0f23 0%, #1a1a3e 50%, #2d1b4e 100%)",
@ -61,16 +62,6 @@ const styles: Record<string, React.CSSProperties> = {
fontFamily: "'DM Sans', system-ui, sans-serif",
fontSize: "0.875rem",
},
errorBanner: {
background: "rgba(239, 68, 68, 0.15)",
border: "1px solid rgba(239, 68, 68, 0.3)",
color: "#f87171",
padding: "1rem",
borderRadius: "8px",
marginBottom: "1rem",
fontFamily: "'DM Sans', system-ui, sans-serif",
fontSize: "0.875rem",
},
section: {
marginBottom: "2rem",
},
@ -217,6 +208,8 @@ const styles: Record<string, React.CSSProperties> = {
},
};
const styles = { ...sharedStyles, ...pageStyles };
export default function BookingPage() {
const { user, isLoading, isAuthorized } = useRequireAuth({
requiredPermission: Permission.BOOK_APPOINTMENT,

View file

@ -78,4 +78,32 @@ export const sharedStyles: Record<string, React.CSSProperties> = {
justifyContent: "center",
padding: "2rem",
},
// Common UI component styles
errorBanner: {
fontFamily: "'DM Sans', system-ui, sans-serif",
fontSize: "0.875rem",
padding: "1rem",
background: "rgba(239, 68, 68, 0.15)",
border: "1px solid rgba(239, 68, 68, 0.3)",
borderRadius: "8px",
color: "#f87171",
marginBottom: "1rem",
},
cancelButton: {
fontFamily: "'DM Sans', system-ui, sans-serif",
fontSize: "0.85rem",
padding: "0.6rem 1rem",
background: "rgba(255, 255, 255, 0.05)",
color: "rgba(255, 255, 255, 0.7)",
border: "1px solid rgba(255, 255, 255, 0.1)",
borderRadius: "8px",
cursor: "pointer",
transition: "all 0.2s",
},
emptyState: {
fontFamily: "'DM Sans', system-ui, sans-serif",
color: "rgba(255, 255, 255, 0.4)",
textAlign: "center" as const,
padding: "1rem 0",
},
};