diff --git a/frontend/app/admin/availability/page.tsx b/frontend/app/admin/availability/page.tsx index 255b657..390b939 100644 --- a/frontend/app/admin/availability/page.tsx +++ b/frontend/app/admin/availability/page.tsx @@ -3,7 +3,6 @@ import { useEffect, useState, useCallback } from "react"; import { Permission } from "../../auth-context"; import { api } from "../../api"; -import { sharedStyles } from "../../styles/shared"; import { Header } from "../../components/Header"; import { useRequireAuth } from "../../hooks/useRequireAuth"; import { components } from "../../generated/api"; @@ -15,6 +14,13 @@ import { formatTimeString, isWeekend, } from "../../utils/date"; +import { + layoutStyles, + typographyStyles, + bannerStyles, + buttonStyles, + modalStyles, +} from "../../styles/shared"; const { slotDurationMinutes, maxAdvanceDays, minAdvanceDays } = constants.booking; @@ -217,8 +223,8 @@ export default function AdminAvailabilityPage() { if (isLoading) { return ( -
-
Loading...
+
+
Loading...
); } @@ -228,15 +234,15 @@ export default function AdminAvailabilityPage() { } return ( -
+
-
+
-

Availability

-

+

Availability

+

Configure your available time slots for the next {maxAdvanceDays} days

@@ -246,18 +252,18 @@ export default function AdminAvailabilityPage() { -
)}
- {error && !selectedDate &&
{error}
} + {error && !selectedDate &&
{error}
}
{dates.map((date) => { @@ -322,11 +328,13 @@ export default function AdminAvailabilityPage() { {/* Edit Modal */} {selectedDate && ( -
-
e.stopPropagation()}> -

Edit Availability - {formatDisplayDate(selectedDate)}

+
+
e.stopPropagation()}> +

+ Edit Availability - {formatDisplayDate(selectedDate)} +

- {error &&
{error}
} + {error &&
{error}
}
{editSlots.map((slot, index) => ( @@ -368,15 +376,19 @@ export default function AdminAvailabilityPage() {
-
+
-
- -
@@ -388,12 +400,8 @@ export default function AdminAvailabilityPage() { ); } -const pageStyles: Record = { - content: { - flex: 1, - padding: "2rem", - overflowY: "auto", - }, +// Page-specific styles +const styles: Record = { pageContainer: { maxWidth: "1200px", margin: "0 auto", @@ -406,19 +414,6 @@ const pageStyles: Record = { flexWrap: "wrap", gap: "1rem", }, - pageTitle: { - fontFamily: "'Instrument Serif', Georgia, serif", - fontSize: "2rem", - fontWeight: 400, - color: "#fff", - margin: 0, - }, - pageSubtitle: { - fontFamily: "'DM Sans', system-ui, sans-serif", - color: "rgba(255, 255, 255, 0.5)", - marginTop: "0.5rem", - fontSize: "0.95rem", - }, copyActions: { display: "flex", alignItems: "center", @@ -429,16 +424,6 @@ const pageStyles: Record = { fontSize: "0.85rem", color: "rgba(255, 255, 255, 0.6)", }, - copyButton: { - fontFamily: "'DM Sans', system-ui, sans-serif", - fontSize: "0.85rem", - padding: "0.5rem 1rem", - background: "rgba(99, 102, 241, 0.3)", - color: "#fff", - border: "1px solid rgba(99, 102, 241, 0.5)", - borderRadius: "8px", - cursor: "pointer", - }, calendar: { display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(180px, 1fr))", @@ -506,44 +491,6 @@ const pageStyles: Record = { borderRadius: "4px", color: "rgba(129, 140, 248, 0.9)", }, - modalOverlay: { - position: "fixed", - top: 0, - left: 0, - right: 0, - bottom: 0, - background: "rgba(0, 0, 0, 0.7)", - display: "flex", - alignItems: "center", - justifyContent: "center", - zIndex: 1000, - }, - modal: { - background: "#1a1a3e", - border: "1px solid rgba(255, 255, 255, 0.1)", - borderRadius: "16px", - padding: "2rem", - width: "90%", - maxWidth: "400px", - boxShadow: "0 25px 50px -12px rgba(0, 0, 0, 0.5)", - }, - modalTitle: { - fontFamily: "'Instrument Serif', Georgia, serif", - fontSize: "1.5rem", - fontWeight: 400, - color: "#fff", - margin: "0 0 1.5rem 0", - }, - modalError: { - fontFamily: "'DM Sans', system-ui, sans-serif", - fontSize: "0.85rem", - padding: "0.75rem", - background: "rgba(239, 68, 68, 0.15)", - border: "1px solid rgba(239, 68, 68, 0.3)", - borderRadius: "8px", - color: "#f87171", - marginBottom: "1rem", - }, slotsEditor: { display: "flex", flexDirection: "column", @@ -593,16 +540,6 @@ const pageStyles: Record = { borderRadius: "6px", cursor: "pointer", }, - modalActions: { - display: "flex", - justifyContent: "space-between", - alignItems: "center", - gap: "1rem", - }, - modalActionsRight: { - display: "flex", - gap: "0.75rem", - }, clearButton: { fontFamily: "'DM Sans', system-ui, sans-serif", fontSize: "0.85rem", @@ -613,27 +550,4 @@ const pageStyles: Record = { borderRadius: "8px", cursor: "pointer", }, - 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", - }, - saveButton: { - fontFamily: "'DM Sans', system-ui, sans-serif", - fontSize: "0.85rem", - fontWeight: 500, - padding: "0.6rem 1.5rem", - background: "rgba(99, 102, 241, 0.3)", - color: "#fff", - border: "1px solid rgba(99, 102, 241, 0.5)", - borderRadius: "8px", - cursor: "pointer", - }, }; - -const styles = { ...sharedStyles, ...pageStyles }; diff --git a/frontend/app/admin/invites/page.tsx b/frontend/app/admin/invites/page.tsx index f7393dc..4f30ba2 100644 --- a/frontend/app/admin/invites/page.tsx +++ b/frontend/app/admin/invites/page.tsx @@ -3,11 +3,20 @@ import { useEffect, useState, useCallback } from "react"; import { Permission } from "../../auth-context"; import { api } from "../../api"; -import { sharedStyles } from "../../styles/shared"; import { Header } from "../../components/Header"; import { useRequireAuth } from "../../hooks/useRequireAuth"; import { components } from "../../generated/api"; import constants from "../../../../shared/constants.json"; +import { + layoutStyles, + cardStyles, + tableStyles, + paginationStyles, + formStyles, + buttonStyles, + badgeStyles, + utilityStyles, +} from "../../styles/shared"; const { READY, SPENT, REVOKED } = constants.inviteStatuses; @@ -101,11 +110,11 @@ export default function AdminInvitesPage() { const getStatusBadgeStyle = (status: string) => { switch (status) { case READY: - return styles.statusReady; + return badgeStyles.badgeReady; case SPENT: - return styles.statusSpent; + return badgeStyles.badgeSuccess; case REVOKED: - return styles.statusRevoked; + return badgeStyles.badgeError; default: return {}; } @@ -113,8 +122,8 @@ export default function AdminInvitesPage() { if (isLoading) { return ( -
-
Loading...
+
+
Loading...
); } @@ -124,21 +133,21 @@ export default function AdminInvitesPage() { } return ( -
+
-
+
{/* Create Invite Section */}

Create Invite

-
+
{users.length === 0 && ( - + No users loaded yet. Create at least one invite to populate the list. )} @@ -158,8 +167,9 @@ export default function AdminInvitesPage() { onClick={handleCreateInvite} disabled={isCreating || !newGodfatherId} style={{ - ...styles.createButton, - ...(!newGodfatherId ? styles.createButtonDisabled : {}), + ...buttonStyles.accentButton, + alignSelf: "flex-start", + ...(!newGodfatherId ? buttonStyles.buttonDisabled : {}), }} > {isCreating ? "Creating..." : "Create Invite"} @@ -168,10 +178,10 @@ export default function AdminInvitesPage() {
{/* Invites Table */} -
-
-

All Invites

-
+
+
+

All Invites

+
- {data?.total ?? 0} invites + {data?.total ?? 0} invites
-
- +
+
- - - - - - + + + + + + {error && ( - )} {!error && data?.records.map((record) => ( - - - - + + + - - - + + - @@ -247,21 +257,21 @@ export default function AdminInvitesPage() { {data && data.total_pages > 1 && ( -
+
- + {page} / {data.total_pages} @@ -274,12 +284,8 @@ export default function AdminInvitesPage() { ); } -const pageStyles: Record = { - content: { - flex: 1, - padding: "2rem", - overflowY: "auto", - }, +// Page-specific styles +const styles: Record = { pageContainer: { display: "flex", flexDirection: "column", @@ -305,82 +311,16 @@ const pageStyles: Record = { flexDirection: "column", gap: "1rem", }, - inputGroup: { - display: "flex", - flexDirection: "column", - gap: "0.5rem", - }, inputLabel: { fontFamily: "'DM Sans', system-ui, sans-serif", fontSize: "0.8rem", color: "rgba(255, 255, 255, 0.5)", }, - select: { - fontFamily: "'DM Sans', system-ui, sans-serif", - fontSize: "0.9rem", - padding: "0.75rem", - background: "rgba(255, 255, 255, 0.05)", - border: "1px solid rgba(255, 255, 255, 0.1)", - borderRadius: "8px", - color: "#fff", - maxWidth: "400px", - cursor: "pointer", - }, createError: { fontFamily: "'DM Sans', system-ui, sans-serif", fontSize: "0.85rem", color: "#f87171", }, - createButton: { - fontFamily: "'DM Sans', system-ui, sans-serif", - fontSize: "0.9rem", - fontWeight: 500, - padding: "0.75rem 1.5rem", - background: "rgba(99, 102, 241, 0.3)", - color: "#fff", - border: "1px solid rgba(99, 102, 241, 0.5)", - borderRadius: "8px", - cursor: "pointer", - alignSelf: "flex-start", - }, - createButtonDisabled: { - opacity: 0.5, - cursor: "not-allowed", - }, - inputHint: { - fontFamily: "'DM Sans', system-ui, sans-serif", - fontSize: "0.75rem", - color: "rgba(255, 255, 255, 0.4)", - fontStyle: "italic", - }, - tableCard: { - background: "rgba(255, 255, 255, 0.03)", - backdropFilter: "blur(10px)", - border: "1px solid rgba(255, 255, 255, 0.08)", - borderRadius: "20px", - padding: "1.5rem", - boxShadow: "0 25px 50px -12px rgba(0, 0, 0, 0.5)", - }, - tableHeader: { - display: "flex", - justifyContent: "space-between", - alignItems: "center", - marginBottom: "1rem", - flexWrap: "wrap", - gap: "1rem", - }, - tableTitle: { - fontFamily: "'Instrument Serif', Georgia, serif", - fontSize: "1.5rem", - fontWeight: 400, - color: "#fff", - margin: 0, - }, - filterGroup: { - display: "flex", - alignItems: "center", - gap: "1rem", - }, filterSelect: { fontFamily: "'DM Sans', system-ui, sans-serif", fontSize: "0.85rem", @@ -391,115 +331,4 @@ const pageStyles: Record = { color: "#fff", cursor: "pointer", }, - totalCount: { - fontFamily: "'DM Sans', system-ui, sans-serif", - fontSize: "0.875rem", - color: "rgba(255, 255, 255, 0.4)", - }, - tableWrapper: { - overflowX: "auto", - }, - table: { - width: "100%", - borderCollapse: "collapse", - fontFamily: "'DM Sans', system-ui, sans-serif", - }, - th: { - textAlign: "left", - padding: "0.75rem 1rem", - fontSize: "0.75rem", - fontWeight: 600, - color: "rgba(255, 255, 255, 0.4)", - textTransform: "uppercase", - letterSpacing: "0.05em", - borderBottom: "1px solid rgba(255, 255, 255, 0.08)", - }, - tr: { - borderBottom: "1px solid rgba(255, 255, 255, 0.04)", - }, - td: { - padding: "0.875rem 1rem", - fontSize: "0.875rem", - color: "rgba(255, 255, 255, 0.7)", - }, - tdCode: { - padding: "0.875rem 1rem", - fontSize: "0.875rem", - color: "#fff", - fontFamily: "'DM Mono', monospace", - }, - tdDate: { - padding: "0.875rem 1rem", - fontSize: "0.75rem", - color: "rgba(255, 255, 255, 0.4)", - }, - statusBadge: { - fontFamily: "'DM Sans', system-ui, sans-serif", - fontSize: "0.7rem", - fontWeight: 500, - padding: "0.25rem 0.5rem", - borderRadius: "4px", - textTransform: "uppercase", - }, - statusReady: { - background: "rgba(99, 102, 241, 0.2)", - color: "rgba(129, 140, 248, 0.9)", - }, - statusSpent: { - background: "rgba(34, 197, 94, 0.2)", - color: "rgba(34, 197, 94, 0.9)", - }, - statusRevoked: { - background: "rgba(239, 68, 68, 0.2)", - color: "rgba(239, 68, 68, 0.9)", - }, - revokeButton: { - fontFamily: "'DM Sans', system-ui, sans-serif", - fontSize: "0.75rem", - padding: "0.4rem 0.75rem", - background: "rgba(239, 68, 68, 0.15)", - color: "rgba(239, 68, 68, 0.9)", - border: "1px solid rgba(239, 68, 68, 0.3)", - borderRadius: "6px", - cursor: "pointer", - }, - emptyRow: { - padding: "2rem 1rem", - textAlign: "center", - color: "rgba(255, 255, 255, 0.3)", - fontSize: "0.875rem", - }, - errorRow: { - padding: "2rem 1rem", - textAlign: "center", - color: "#f87171", - fontSize: "0.875rem", - }, - pagination: { - display: "flex", - justifyContent: "center", - alignItems: "center", - gap: "1rem", - marginTop: "1rem", - paddingTop: "1rem", - borderTop: "1px solid rgba(255, 255, 255, 0.06)", - }, - pageBtn: { - fontFamily: "'DM Sans', system-ui, sans-serif", - padding: "0.5rem 1rem", - fontSize: "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", - }, - pageInfo: { - fontFamily: "'DM Sans', system-ui, sans-serif", - fontSize: "0.875rem", - color: "rgba(255, 255, 255, 0.5)", - }, }; - -const styles = { ...sharedStyles, ...pageStyles }; diff --git a/frontend/app/appointments/page.tsx b/frontend/app/appointments/page.tsx index 5d4341b..38a6136 100644 --- a/frontend/app/appointments/page.tsx +++ b/frontend/app/appointments/page.tsx @@ -9,145 +9,16 @@ 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"; +import { + layoutStyles, + typographyStyles, + bannerStyles, + badgeStyles, + buttonStyles, +} from "../styles/shared"; type AppointmentResponse = components["schemas"]["AppointmentResponse"]; -const pageStyles: Record = { - main: { - minHeight: "100vh", - background: "linear-gradient(135deg, #0f0f23 0%, #1a1a3e 50%, #2d1b4e 100%)", - display: "flex", - flexDirection: "column", - }, - loader: { - flex: 1, - display: "flex", - alignItems: "center", - justifyContent: "center", - fontFamily: "'DM Sans', system-ui, sans-serif", - color: "rgba(255, 255, 255, 0.5)", - }, - content: { - flex: 1, - padding: "2rem", - maxWidth: "800px", - margin: "0 auto", - width: "100%", - }, - pageTitle: { - fontFamily: "'DM Sans', system-ui, sans-serif", - fontSize: "1.75rem", - fontWeight: 600, - color: "#fff", - marginBottom: "0.5rem", - }, - pageSubtitle: { - fontFamily: "'DM Sans', system-ui, sans-serif", - color: "rgba(255, 255, 255, 0.5)", - fontSize: "0.9rem", - marginBottom: "1.5rem", - }, - section: { - marginBottom: "2rem", - }, - sectionTitle: { - fontFamily: "'DM Sans', system-ui, sans-serif", - fontSize: "1.1rem", - fontWeight: 500, - color: "#fff", - marginBottom: "1rem", - }, - sectionTitleMuted: { - fontFamily: "'DM Sans', system-ui, sans-serif", - fontSize: "1.1rem", - fontWeight: 500, - color: "rgba(255, 255, 255, 0.5)", - marginBottom: "1rem", - }, - appointmentList: { - display: "flex", - flexDirection: "column", - gap: "0.75rem", - }, - appointmentCard: { - background: "rgba(255, 255, 255, 0.03)", - border: "1px solid rgba(255, 255, 255, 0.08)", - borderRadius: "12px", - padding: "1.25rem", - transition: "all 0.2s", - }, - appointmentCardPast: { - opacity: 0.6, - background: "rgba(255, 255, 255, 0.01)", - }, - appointmentHeader: { - display: "flex", - justifyContent: "space-between", - alignItems: "flex-start", - gap: "1rem", - }, - appointmentTime: { - fontFamily: "'DM Sans', system-ui, sans-serif", - fontSize: "1rem", - fontWeight: 500, - color: "#fff", - marginBottom: "0.25rem", - }, - appointmentNote: { - fontFamily: "'DM Sans', system-ui, sans-serif", - fontSize: "0.875rem", - color: "rgba(255, 255, 255, 0.5)", - marginBottom: "0.5rem", - }, - statusBadge: { - fontFamily: "'DM Sans', system-ui, sans-serif", - fontSize: "0.75rem", - fontWeight: 500, - padding: "0.25rem 0.75rem", - borderRadius: "9999px", - display: "inline-block", - }, - buttonGroup: { - display: "flex", - gap: "0.5rem", - }, - cancelButton: { - fontFamily: "'DM Sans', system-ui, sans-serif", - padding: "0.35rem 0.75rem", - fontSize: "0.75rem", - background: "rgba(255, 255, 255, 0.05)", - border: "1px solid rgba(255, 255, 255, 0.1)", - borderRadius: "6px", - color: "rgba(255, 255, 255, 0.7)", - cursor: "pointer", - transition: "all 0.2s", - }, - confirmButton: { - fontFamily: "'DM Sans', system-ui, sans-serif", - padding: "0.35rem 0.75rem", - fontSize: "0.75rem", - background: "rgba(239, 68, 68, 0.2)", - border: "1px solid rgba(239, 68, 68, 0.3)", - borderRadius: "6px", - color: "#f87171", - cursor: "pointer", - transition: "all 0.2s", - }, - emptyState: { - fontFamily: "'DM Sans', system-ui, sans-serif", - color: "rgba(255, 255, 255, 0.4)", - textAlign: "center", - padding: "3rem", - }, - emptyStateLink: { - color: "#a78bfa", - textDecoration: "none", - }, -}; - -const styles = { ...sharedStyles, ...pageStyles }; - export default function AppointmentsPage() { const { user, isLoading, isAuthorized } = useRequireAuth({ requiredPermission: Permission.VIEW_OWN_APPOINTMENTS, @@ -195,8 +66,8 @@ export default function AppointmentsPage() { if (isLoading) { return ( -
-
Loading...
+
+
Loading...
); } @@ -213,13 +84,13 @@ export default function AppointmentsPage() { ); return ( -
+
-

My Appointments

-

View and manage your booked appointments

+

My Appointments

+

View and manage your booked appointments

- {error &&
{error}
} + {error &&
{error}
} {isLoadingAppointments ? (
Loading appointments...
@@ -249,7 +120,7 @@ export default function AppointmentsPage() { {apt.note &&
{apt.note}
} @@ -279,7 +150,7 @@ export default function AppointmentsPage() { ) : ( @@ -297,7 +168,7 @@ export default function AppointmentsPage() { {/* Past/Cancelled Appointments */} {pastOrCancelledAppointments.length > 0 && (
-

+

Past & Cancelled ({pastOrCancelledAppointments.length})

@@ -312,7 +183,7 @@ export default function AppointmentsPage() { {apt.note &&
{apt.note}
} ); } + +// Page-specific styles +const styles: Record = { + content: { + flex: 1, + padding: "2rem", + maxWidth: "800px", + margin: "0 auto", + width: "100%", + }, + section: { + marginBottom: "2rem", + }, + sectionTitle: { + fontFamily: "'DM Sans', system-ui, sans-serif", + fontSize: "1.1rem", + fontWeight: 500, + color: "#fff", + marginBottom: "1rem", + }, + appointmentList: { + display: "flex", + flexDirection: "column", + gap: "0.75rem", + }, + appointmentCard: { + background: "rgba(255, 255, 255, 0.03)", + border: "1px solid rgba(255, 255, 255, 0.08)", + borderRadius: "12px", + padding: "1.25rem", + transition: "all 0.2s", + }, + appointmentCardPast: { + opacity: 0.6, + background: "rgba(255, 255, 255, 0.01)", + }, + appointmentHeader: { + display: "flex", + justifyContent: "space-between", + alignItems: "flex-start", + gap: "1rem", + }, + appointmentTime: { + fontFamily: "'DM Sans', system-ui, sans-serif", + fontSize: "1rem", + fontWeight: 500, + color: "#fff", + marginBottom: "0.25rem", + }, + appointmentNote: { + fontFamily: "'DM Sans', system-ui, sans-serif", + fontSize: "0.875rem", + color: "rgba(255, 255, 255, 0.5)", + marginBottom: "0.5rem", + }, + buttonGroup: { + display: "flex", + gap: "0.5rem", + }, + confirmButton: { + fontFamily: "'DM Sans', system-ui, sans-serif", + padding: "0.35rem 0.75rem", + fontSize: "0.75rem", + background: "rgba(239, 68, 68, 0.2)", + border: "1px solid rgba(239, 68, 68, 0.3)", + borderRadius: "6px", + color: "#f87171", + cursor: "pointer", + transition: "all 0.2s", + }, + emptyState: { + fontFamily: "'DM Sans', system-ui, sans-serif", + color: "rgba(255, 255, 255, 0.4)", + textAlign: "center", + padding: "3rem", + }, + emptyStateLink: { + color: "#a78bfa", + textDecoration: "none", + }, +}; diff --git a/frontend/app/audit/page.tsx b/frontend/app/audit/page.tsx index 5b556b7..9747f2c 100644 --- a/frontend/app/audit/page.tsx +++ b/frontend/app/audit/page.tsx @@ -3,7 +3,7 @@ import { useEffect, useState, useCallback } from "react"; import { Permission } from "../auth-context"; import { api } from "../api"; -import { sharedStyles } from "../styles/shared"; +import { layoutStyles, cardStyles, tableStyles, paginationStyles } from "../styles/shared"; import { Header } from "../components/Header"; import { useRequireAuth } from "../hooks/useRequireAuth"; import { components } from "../generated/api"; @@ -68,8 +68,8 @@ export default function AuditPage() { if (isLoading) { return ( -
-
Loading...
+
+
Loading...
); } @@ -79,47 +79,47 @@ export default function AuditPage() { } return ( -
+
-
+
{/* Counter Records Table */} -
-
-

Counter Activity

- {counterData?.total ?? 0} records +
+
+

Counter Activity

+ {counterData?.total ?? 0} records
-
-
CodeGodfatherStatusUsed ByCreatedActionsCodeGodfatherStatusUsed ByCreatedActions
+ {error}
{record.identifier}{record.godfather_email} +
{record.identifier}{record.godfather_email} {record.status} {record.used_by_email || "-"}{formatDate(record.created_at)} + {record.used_by_email || "-"}{formatDate(record.created_at)} {record.status === READY && ( @@ -237,7 +247,7 @@ export default function AdminInvitesPage() { ))} {!error && (!data || data.records.length === 0) && (
+ No invites yet
+
+
- - - - + + + + {counterError && ( - )} {!counterError && counterData?.records.map((record) => ( - - - - - + + + + + ))} {!counterError && (!counterData || counterData.records.length === 0) && ( - @@ -128,21 +128,21 @@ export default function AuditPage() {
UserBeforeAfterDateUserBeforeAfterDate
+ {counterError}
{record.user_email}{record.value_before}{record.value_after}{formatDate(record.created_at)}
{record.user_email}{record.value_before}{record.value_after}{formatDate(record.created_at)}
+ No records yet
{counterData && counterData.total_pages > 1 && ( -
+
- + {counterPage} / {counterData.total_pages} @@ -151,43 +151,43 @@ export default function AuditPage() {
{/* Sum Records Table */} -
-
-

Sum Activity

- {sumData?.total ?? 0} records +
+
+

Sum Activity

+ {sumData?.total ?? 0} records
-
- +
+
- - - - - + + + + + {sumError && ( - )} {!sumError && sumData?.records.map((record) => ( - - - - + + + + - + ))} {!sumError && (!sumData || sumData.records.length === 0) && ( - @@ -196,21 +196,21 @@ export default function AuditPage() {
UserABResultDateUserABResultDate
+ {sumError}
{record.user_email}{record.a}{record.b}
{record.user_email}{record.a}{record.b} {record.result}{formatDate(record.created_at)}{formatDate(record.created_at)}
+ No records yet
{sumData && sumData.total_pages > 1 && ( -
+
- + {sumPage} / {sumData.total_pages} @@ -223,13 +223,8 @@ export default function AuditPage() { ); } -const pageStyles: Record = { - // Override content for audit-specific layout - content: { - flex: 1, - padding: "2rem", - overflowY: "auto", - }, +// Page-specific styles only +const styles: Record = { tablesContainer: { display: "flex", flexDirection: "column", @@ -237,64 +232,6 @@ const pageStyles: Record = { maxWidth: "1200px", margin: "0 auto", }, - tableCard: { - background: "rgba(255, 255, 255, 0.03)", - backdropFilter: "blur(10px)", - border: "1px solid rgba(255, 255, 255, 0.08)", - borderRadius: "20px", - padding: "1.5rem", - boxShadow: "0 25px 50px -12px rgba(0, 0, 0, 0.5)", - }, - tableHeader: { - display: "flex", - justifyContent: "space-between", - alignItems: "center", - marginBottom: "1rem", - }, - tableTitle: { - fontFamily: "'Instrument Serif', Georgia, serif", - fontSize: "1.5rem", - fontWeight: 400, - color: "#fff", - margin: 0, - }, - totalCount: { - fontFamily: "'DM Sans', system-ui, sans-serif", - fontSize: "0.875rem", - color: "rgba(255, 255, 255, 0.4)", - }, - tableWrapper: { - overflowX: "auto", - }, - table: { - width: "100%", - borderCollapse: "collapse", - fontFamily: "'DM Sans', system-ui, sans-serif", - }, - th: { - textAlign: "left", - padding: "0.75rem 1rem", - fontSize: "0.75rem", - fontWeight: 600, - color: "rgba(255, 255, 255, 0.4)", - textTransform: "uppercase", - letterSpacing: "0.05em", - borderBottom: "1px solid rgba(255, 255, 255, 0.08)", - }, - tr: { - borderBottom: "1px solid rgba(255, 255, 255, 0.04)", - }, - td: { - padding: "0.875rem 1rem", - fontSize: "0.875rem", - color: "rgba(255, 255, 255, 0.7)", - }, - tdNum: { - padding: "0.875rem 1rem", - fontSize: "0.875rem", - color: "rgba(255, 255, 255, 0.9)", - fontFamily: "'DM Sans', monospace", - }, tdResult: { padding: "0.875rem 1rem", fontSize: "0.875rem", @@ -302,48 +239,4 @@ const pageStyles: Record = { fontWeight: 600, fontFamily: "'DM Sans', monospace", }, - tdDate: { - padding: "0.875rem 1rem", - fontSize: "0.75rem", - color: "rgba(255, 255, 255, 0.4)", - }, - emptyRow: { - padding: "2rem 1rem", - textAlign: "center", - color: "rgba(255, 255, 255, 0.3)", - fontSize: "0.875rem", - }, - errorRow: { - padding: "2rem 1rem", - textAlign: "center", - color: "#f87171", - fontSize: "0.875rem", - }, - pagination: { - display: "flex", - justifyContent: "center", - alignItems: "center", - gap: "1rem", - marginTop: "1rem", - paddingTop: "1rem", - borderTop: "1px solid rgba(255, 255, 255, 0.06)", - }, - pageBtn: { - fontFamily: "'DM Sans', system-ui, sans-serif", - padding: "0.5rem 1rem", - fontSize: "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", - }, - pageInfo: { - fontFamily: "'DM Sans', system-ui, sans-serif", - fontSize: "0.875rem", - color: "rgba(255, 255, 255, 0.5)", - }, }; - -const styles = { ...sharedStyles, ...pageStyles }; diff --git a/frontend/app/booking/page.tsx b/frontend/app/booking/page.tsx index cc60f10..49fa872 100644 --- a/frontend/app/booking/page.tsx +++ b/frontend/app/booking/page.tsx @@ -9,7 +9,13 @@ 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"; +import { + layoutStyles, + typographyStyles, + bannerStyles, + formStyles, + buttonStyles, +} from "../styles/shared"; const { slotDurationMinutes, maxAdvanceDays, minAdvanceDays, noteMaxLength } = constants.booking; @@ -17,205 +23,6 @@ type BookableSlot = components["schemas"]["BookableSlot"]; type AvailableSlotsResponse = components["schemas"]["AvailableSlotsResponse"]; type AppointmentResponse = components["schemas"]["AppointmentResponse"]; -const pageStyles: Record = { - main: { - minHeight: "100vh", - background: "linear-gradient(135deg, #0f0f23 0%, #1a1a3e 50%, #2d1b4e 100%)", - display: "flex", - flexDirection: "column", - }, - loader: { - flex: 1, - display: "flex", - alignItems: "center", - justifyContent: "center", - fontFamily: "'DM Sans', system-ui, sans-serif", - color: "rgba(255, 255, 255, 0.5)", - }, - content: { - flex: 1, - padding: "2rem", - maxWidth: "900px", - margin: "0 auto", - width: "100%", - }, - pageTitle: { - fontFamily: "'DM Sans', system-ui, sans-serif", - fontSize: "1.75rem", - fontWeight: 600, - color: "#fff", - marginBottom: "0.5rem", - }, - pageSubtitle: { - fontFamily: "'DM Sans', system-ui, sans-serif", - color: "rgba(255, 255, 255, 0.5)", - fontSize: "0.9rem", - marginBottom: "1.5rem", - }, - successBanner: { - background: "rgba(34, 197, 94, 0.15)", - border: "1px solid rgba(34, 197, 94, 0.3)", - color: "#4ade80", - padding: "1rem", - borderRadius: "8px", - marginBottom: "1rem", - fontFamily: "'DM Sans', system-ui, sans-serif", - fontSize: "0.875rem", - }, - section: { - marginBottom: "2rem", - }, - sectionTitle: { - fontFamily: "'DM Sans', system-ui, sans-serif", - fontSize: "1.1rem", - fontWeight: 500, - color: "#fff", - marginBottom: "1rem", - }, - dateGrid: { - display: "flex", - flexWrap: "wrap", - gap: "0.5rem", - }, - dateButton: { - fontFamily: "'DM Sans', system-ui, sans-serif", - padding: "0.75rem 1rem", - background: "rgba(255, 255, 255, 0.03)", - border: "1px solid rgba(255, 255, 255, 0.08)", - borderRadius: "10px", - cursor: "pointer", - minWidth: "90px", - textAlign: "center" as const, - transition: "all 0.2s", - }, - dateButtonSelected: { - background: "rgba(167, 139, 250, 0.15)", - border: "1px solid #a78bfa", - }, - dateButtonDisabled: { - opacity: 0.4, - cursor: "not-allowed", - background: "rgba(255, 255, 255, 0.01)", - border: "1px solid rgba(255, 255, 255, 0.04)", - }, - dateWeekday: { - color: "#fff", - fontWeight: 500, - fontSize: "0.875rem", - marginBottom: "0.25rem", - }, - dateDay: { - color: "rgba(255, 255, 255, 0.5)", - fontSize: "0.8rem", - }, - slotGrid: { - display: "flex", - flexWrap: "wrap", - gap: "0.5rem", - }, - slotButton: { - fontFamily: "'DM Sans', system-ui, sans-serif", - padding: "0.6rem 1.25rem", - background: "rgba(255, 255, 255, 0.03)", - border: "1px solid rgba(255, 255, 255, 0.08)", - borderRadius: "8px", - color: "#fff", - cursor: "pointer", - fontSize: "0.9rem", - transition: "all 0.2s", - }, - slotButtonSelected: { - background: "rgba(167, 139, 250, 0.15)", - border: "1px solid #a78bfa", - }, - emptyState: { - fontFamily: "'DM Sans', system-ui, sans-serif", - color: "rgba(255, 255, 255, 0.4)", - padding: "1rem 0", - }, - confirmCard: { - background: "rgba(255, 255, 255, 0.03)", - border: "1px solid rgba(255, 255, 255, 0.08)", - borderRadius: "12px", - padding: "1.5rem", - maxWidth: "400px", - }, - confirmTitle: { - fontFamily: "'DM Sans', system-ui, sans-serif", - fontSize: "1.1rem", - fontWeight: 500, - color: "#fff", - marginBottom: "1rem", - }, - confirmTime: { - fontFamily: "'DM Sans', system-ui, sans-serif", - color: "rgba(255, 255, 255, 0.7)", - marginBottom: "1rem", - }, - inputLabel: { - fontFamily: "'DM Sans', system-ui, sans-serif", - display: "block", - color: "rgba(255, 255, 255, 0.7)", - fontSize: "0.875rem", - marginBottom: "0.5rem", - }, - textarea: { - fontFamily: "'DM Sans', system-ui, sans-serif", - width: "100%", - padding: "0.75rem", - background: "rgba(255, 255, 255, 0.05)", - border: "1px solid rgba(255, 255, 255, 0.1)", - borderRadius: "8px", - color: "#fff", - fontSize: "0.875rem", - minHeight: "80px", - resize: "vertical" as const, - }, - charCount: { - fontFamily: "'DM Sans', system-ui, sans-serif", - fontSize: "0.75rem", - color: "rgba(255, 255, 255, 0.4)", - textAlign: "right" as const, - marginTop: "0.25rem", - }, - charCountWarning: { - color: "#f87171", - }, - buttonRow: { - display: "flex", - gap: "0.75rem", - marginTop: "1.5rem", - }, - bookButton: { - fontFamily: "'DM Sans', system-ui, sans-serif", - flex: 1, - padding: "0.75rem", - background: "linear-gradient(135deg, #a78bfa 0%, #7c3aed 100%)", - border: "none", - borderRadius: "8px", - color: "#fff", - fontWeight: 500, - cursor: "pointer", - transition: "all 0.2s", - }, - bookButtonDisabled: { - opacity: 0.5, - cursor: "not-allowed", - }, - cancelButton: { - fontFamily: "'DM Sans', system-ui, sans-serif", - padding: "0.75rem 1.25rem", - background: "rgba(255, 255, 255, 0.05)", - border: "1px solid rgba(255, 255, 255, 0.1)", - borderRadius: "8px", - color: "rgba(255, 255, 255, 0.7)", - cursor: "pointer", - transition: "all 0.2s", - }, -}; - -const styles = { ...sharedStyles, ...pageStyles }; - export default function BookingPage() { const { user, isLoading, isAuthorized } = useRequireAuth({ requiredPermission: Permission.BOOK_APPOINTMENT, @@ -345,8 +152,8 @@ export default function BookingPage() { if (isLoading) { return ( -
-
Loading...
+
+
Loading...
); } @@ -356,17 +163,17 @@ export default function BookingPage() { } return ( -
+
-

Book an Appointment

-

+

Book an Appointment

+

Select a date to see available {slotDurationMinutes}-minute slots

- {successMessage &&
{successMessage}
} + {successMessage &&
{successMessage}
} - {error &&
{error}
} + {error &&
{error}
} {/* Date Selection */}
@@ -449,17 +256,17 @@ export default function BookingPage() {

- +