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:
parent
3d83472b97
commit
b9f605d7b3
5 changed files with 40 additions and 43 deletions
|
|
@ -9,11 +9,12 @@ import { useRequireAuth } from "../../hooks/useRequireAuth";
|
||||||
import { components } from "../../generated/api";
|
import { components } from "../../generated/api";
|
||||||
import { formatDateTime } from "../../utils/date";
|
import { formatDateTime } from "../../utils/date";
|
||||||
import { getStatusDisplay } from "../../utils/appointment";
|
import { getStatusDisplay } from "../../utils/appointment";
|
||||||
|
import { sharedStyles } from "../../styles/shared";
|
||||||
|
|
||||||
type AppointmentResponse = components["schemas"]["AppointmentResponse"];
|
type AppointmentResponse = components["schemas"]["AppointmentResponse"];
|
||||||
type PaginatedAppointments = components["schemas"]["PaginatedResponse_AppointmentResponse_"];
|
type PaginatedAppointments = components["schemas"]["PaginatedResponse_AppointmentResponse_"];
|
||||||
|
|
||||||
const styles: Record<string, React.CSSProperties> = {
|
const pageStyles: Record<string, React.CSSProperties> = {
|
||||||
main: {
|
main: {
|
||||||
minHeight: "100vh",
|
minHeight: "100vh",
|
||||||
background: "linear-gradient(135deg, #0f0f23 0%, #1a1a3e 50%, #2d1b4e 100%)",
|
background: "linear-gradient(135deg, #0f0f23 0%, #1a1a3e 50%, #2d1b4e 100%)",
|
||||||
|
|
@ -48,16 +49,6 @@ const styles: Record<string, React.CSSProperties> = {
|
||||||
fontSize: "0.9rem",
|
fontSize: "0.9rem",
|
||||||
marginBottom: "1.5rem",
|
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: {
|
filterRow: {
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
|
|
@ -161,6 +152,8 @@ const styles: Record<string, React.CSSProperties> = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const styles = { ...sharedStyles, ...pageStyles };
|
||||||
|
|
||||||
export default function AdminAppointmentsPage() {
|
export default function AdminAppointmentsPage() {
|
||||||
const { user, isLoading, isAuthorized } = useRequireAuth({
|
const { user, isLoading, isAuthorized } = useRequireAuth({
|
||||||
requiredPermission: Permission.VIEW_ALL_APPOINTMENTS,
|
requiredPermission: Permission.VIEW_ALL_APPOINTMENTS,
|
||||||
|
|
|
||||||
|
|
@ -431,16 +431,6 @@ const pageStyles: Record<string, React.CSSProperties> = {
|
||||||
borderRadius: "8px",
|
borderRadius: "8px",
|
||||||
cursor: "pointer",
|
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: {
|
calendar: {
|
||||||
display: "grid",
|
display: "grid",
|
||||||
gridTemplateColumns: "repeat(auto-fill, minmax(180px, 1fr))",
|
gridTemplateColumns: "repeat(auto-fill, minmax(180px, 1fr))",
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,11 @@ import { useRequireAuth } from "../hooks/useRequireAuth";
|
||||||
import { components } from "../generated/api";
|
import { components } from "../generated/api";
|
||||||
import { formatDateTime } from "../utils/date";
|
import { formatDateTime } from "../utils/date";
|
||||||
import { getStatusDisplay } from "../utils/appointment";
|
import { getStatusDisplay } from "../utils/appointment";
|
||||||
|
import { sharedStyles } from "../styles/shared";
|
||||||
|
|
||||||
type AppointmentResponse = components["schemas"]["AppointmentResponse"];
|
type AppointmentResponse = components["schemas"]["AppointmentResponse"];
|
||||||
|
|
||||||
const styles: Record<string, React.CSSProperties> = {
|
const pageStyles: Record<string, React.CSSProperties> = {
|
||||||
main: {
|
main: {
|
||||||
minHeight: "100vh",
|
minHeight: "100vh",
|
||||||
background: "linear-gradient(135deg, #0f0f23 0%, #1a1a3e 50%, #2d1b4e 100%)",
|
background: "linear-gradient(135deg, #0f0f23 0%, #1a1a3e 50%, #2d1b4e 100%)",
|
||||||
|
|
@ -47,16 +48,6 @@ const styles: Record<string, React.CSSProperties> = {
|
||||||
fontSize: "0.9rem",
|
fontSize: "0.9rem",
|
||||||
marginBottom: "1.5rem",
|
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: {
|
section: {
|
||||||
marginBottom: "2rem",
|
marginBottom: "2rem",
|
||||||
},
|
},
|
||||||
|
|
@ -155,6 +146,8 @@ const styles: Record<string, React.CSSProperties> = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const styles = { ...sharedStyles, ...pageStyles };
|
||||||
|
|
||||||
export default function AppointmentsPage() {
|
export default function AppointmentsPage() {
|
||||||
const { user, isLoading, isAuthorized } = useRequireAuth({
|
const { user, isLoading, isAuthorized } = useRequireAuth({
|
||||||
requiredPermission: Permission.VIEW_OWN_APPOINTMENTS,
|
requiredPermission: Permission.VIEW_OWN_APPOINTMENTS,
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import { useRequireAuth } from "../hooks/useRequireAuth";
|
||||||
import { components } from "../generated/api";
|
import { components } from "../generated/api";
|
||||||
import constants from "../../../shared/constants.json";
|
import constants from "../../../shared/constants.json";
|
||||||
import { formatDate, formatTime, getDateRange } from "../utils/date";
|
import { formatDate, formatTime, getDateRange } from "../utils/date";
|
||||||
|
import { sharedStyles } from "../styles/shared";
|
||||||
|
|
||||||
const { slotDurationMinutes, maxAdvanceDays, minAdvanceDays, noteMaxLength } = constants.booking;
|
const { slotDurationMinutes, maxAdvanceDays, minAdvanceDays, noteMaxLength } = constants.booking;
|
||||||
|
|
||||||
|
|
@ -16,7 +17,7 @@ type BookableSlot = components["schemas"]["BookableSlot"];
|
||||||
type AvailableSlotsResponse = components["schemas"]["AvailableSlotsResponse"];
|
type AvailableSlotsResponse = components["schemas"]["AvailableSlotsResponse"];
|
||||||
type AppointmentResponse = components["schemas"]["AppointmentResponse"];
|
type AppointmentResponse = components["schemas"]["AppointmentResponse"];
|
||||||
|
|
||||||
const styles: Record<string, React.CSSProperties> = {
|
const pageStyles: Record<string, React.CSSProperties> = {
|
||||||
main: {
|
main: {
|
||||||
minHeight: "100vh",
|
minHeight: "100vh",
|
||||||
background: "linear-gradient(135deg, #0f0f23 0%, #1a1a3e 50%, #2d1b4e 100%)",
|
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",
|
fontFamily: "'DM Sans', system-ui, sans-serif",
|
||||||
fontSize: "0.875rem",
|
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: {
|
section: {
|
||||||
marginBottom: "2rem",
|
marginBottom: "2rem",
|
||||||
},
|
},
|
||||||
|
|
@ -217,6 +208,8 @@ const styles: Record<string, React.CSSProperties> = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const styles = { ...sharedStyles, ...pageStyles };
|
||||||
|
|
||||||
export default function BookingPage() {
|
export default function BookingPage() {
|
||||||
const { user, isLoading, isAuthorized } = useRequireAuth({
|
const { user, isLoading, isAuthorized } = useRequireAuth({
|
||||||
requiredPermission: Permission.BOOK_APPOINTMENT,
|
requiredPermission: Permission.BOOK_APPOINTMENT,
|
||||||
|
|
|
||||||
|
|
@ -78,4 +78,32 @@ export const sharedStyles: Record<string, React.CSSProperties> = {
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
padding: "2rem",
|
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",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue