From 9be78c3c3483cbb4c4f1202d63b54f9ebfeef652 Mon Sep 17 00:00:00 2001 From: joshua Date: Wed, 21 Oct 2026 13:25:04 +0200 Subject: [PATCH] Use one back link style across the dashboards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every dashboard page now uses the shared BackLink, the small "← Back to dashboard" link above the page title that the Waitlist page already had, instead of a mix of grey Back buttons in different places. Pages that had no way back (site settings, profile, donate, manual registration) get one too. Co-Authored-By: Claude Opus 5.5 --- .../src/app/dashboard/admin/audit-log/page.tsx | 3 ++- frontend/src/app/dashboard/admin/cashup/page.tsx | 9 +++------ .../src/app/dashboard/admin/registrations/page.tsx | 5 +++-- frontend/src/app/dashboard/admin/settings/page.tsx | 13 ++++--------- frontend/src/app/dashboard/admin/users/page.tsx | 5 +++-- .../src/app/dashboard/staff/event-tickets/page.tsx | 12 +++++------- .../src/app/dashboard/staff/my-groups/page.tsx | 5 ++--- .../app/dashboard/staff/ticket-scanning/page.tsx | 9 +++++---- .../app/dashboard/supervisor/allocations/page.tsx | 3 ++- .../src/app/dashboard/supervisor/consent/page.tsx | 3 ++- .../src/app/dashboard/supervisor/coupons/page.tsx | 3 ++- .../dashboard/supervisor/email-attendees/page.tsx | 9 +++++---- .../dashboard/supervisor/event-options/page.tsx | 7 +++++-- .../src/app/dashboard/supervisor/events/page.tsx | 5 +++-- .../src/app/dashboard/supervisor/forms/page.tsx | 7 +++++-- .../supervisor/manual-registration/page.tsx | 6 +++++- .../src/app/dashboard/supervisor/manual/page.tsx | 7 +++++-- .../dashboard/supervisor/offline-scans/page.tsx | 3 ++- .../src/app/dashboard/supervisor/payments/page.tsx | 7 +++++-- .../src/app/dashboard/supervisor/waitlist/page.tsx | 3 ++- .../supervisor/whatsapp-attendees/page.tsx | 9 +++++---- frontend/src/app/dashboard/user/donate/page.tsx | 4 +++- frontend/src/app/dashboard/user/forms/page.tsx | 7 +++++-- frontend/src/app/dashboard/user/payments/page.tsx | 10 +++++----- frontend/src/app/dashboard/user/profile/page.tsx | 4 +++- .../src/app/dashboard/user/reset-password/page.tsx | 10 +++++----- frontend/src/components/shared/BackLink.tsx | 14 ++++++++++++++ 27 files changed, 110 insertions(+), 72 deletions(-) create mode 100644 frontend/src/components/shared/BackLink.tsx diff --git a/frontend/src/app/dashboard/admin/audit-log/page.tsx b/frontend/src/app/dashboard/admin/audit-log/page.tsx index 3dc6d09..9a3c331 100644 --- a/frontend/src/app/dashboard/admin/audit-log/page.tsx +++ b/frontend/src/app/dashboard/admin/audit-log/page.tsx @@ -8,6 +8,7 @@ import { useDismissingState } from "@/hooks/useDismissingState"; import { History } from "lucide-react"; import { Table, TableHeader, TableBody, TableRow, TableHead, TableCell } from "@/components/ui/table"; import { errorMessage } from "@/lib/utils"; +import { BackLink } from "@/components/shared/BackLink"; const ACTIONS = [ "refund_created", @@ -192,7 +193,7 @@ export default function AdminAuditLogPage() {
- +

Admin Audit Log

{total} action{total !== 1 ? "s" : ""} recorded

diff --git a/frontend/src/app/dashboard/admin/cashup/page.tsx b/frontend/src/app/dashboard/admin/cashup/page.tsx index 036f769..8b932e1 100644 --- a/frontend/src/app/dashboard/admin/cashup/page.tsx +++ b/frontend/src/app/dashboard/admin/cashup/page.tsx @@ -8,6 +8,7 @@ import { useDismissingState } from "@/hooks/useDismissingState"; import { Wallet } from "lucide-react"; import { errorMessage } from "@/lib/utils"; import type { Event } from "@/types"; +import { BackLink } from "@/components/shared/BackLink"; export default function CashupLandingPage() { const { token } = useAuth(); @@ -55,15 +56,11 @@ export default function CashupLandingPage() {
-

Post-event Cashup

+ +

Post-event Cashup

Set costs, reconcile takings, and close out an event. Admin only.

- {error &&
{error}
} diff --git a/frontend/src/app/dashboard/admin/registrations/page.tsx b/frontend/src/app/dashboard/admin/registrations/page.tsx index 9bd901f..39eade3 100644 --- a/frontend/src/app/dashboard/admin/registrations/page.tsx +++ b/frontend/src/app/dashboard/admin/registrations/page.tsx @@ -8,6 +8,7 @@ import { useDismissingState } from "@/hooks/useDismissingState"; import { ClipboardList } from "lucide-react"; import { errorMessage } from "@/lib/utils"; import type { Event, FormResponse, Registration } from "@/types"; +import { BackLink } from "@/components/shared/BackLink"; const STATUS_OPTIONS = ["pending", "confirmed", "partial_paid", "paid", "cancelled"] as const; @@ -197,11 +198,11 @@ export default function AdminRegistrationsPage() {
-

Manage Registrations

+ +

Manage Registrations

{registrations.length} registration{registrations.length !== 1 ? "s" : ""} total

- {!isAdmin && ( diff --git a/frontend/src/app/dashboard/admin/settings/page.tsx b/frontend/src/app/dashboard/admin/settings/page.tsx index b738983..a2369c9 100644 --- a/frontend/src/app/dashboard/admin/settings/page.tsx +++ b/frontend/src/app/dashboard/admin/settings/page.tsx @@ -2,7 +2,7 @@ import React, { Suspense, useCallback, useEffect, useRef, useState } from "react"; import { useAuth } from "@/hooks/useAuth"; -import { useRouter, useSearchParams } from "next/navigation"; +import { useSearchParams } from "next/navigation"; import { apiFetch, ApiError, API_BASE, resolveToApiOrigin } from "@/lib/api"; import { useSiteSettings } from "@/contexts/SiteSettingsContext"; import { useDismissingState } from "@/hooks/useDismissingState"; @@ -14,6 +14,7 @@ import { YocoTab } from "@/components/admin/YocoTab"; import { extractDominantColors } from "@/lib/extractColors"; import { mapsSearchUrl } from "@/lib/maps"; import { errorMessage } from "@/lib/utils"; +import { BackLink } from "@/components/shared/BackLink"; type TabId = "organisation" | "branding" | "notifications" | "email" | "legal" | "whatsapp" | "yoco" | "backups"; @@ -85,7 +86,6 @@ export default function SiteSettingsPage() { function SiteSettingsPageInner() { const { token } = useAuth(); - const router = useRouter(); const searchParams = useSearchParams(); const { reload: reloadSettings } = useSiteSettings(); @@ -366,15 +366,10 @@ function SiteSettingsPageInner() { {/* Header */}
-

Site Settings

+ +

Site Settings

Configure your organisation, branding, email, and legal pages.

-
{/* Tab bar */} diff --git a/frontend/src/app/dashboard/admin/users/page.tsx b/frontend/src/app/dashboard/admin/users/page.tsx index 24322a9..6e08dfd 100644 --- a/frontend/src/app/dashboard/admin/users/page.tsx +++ b/frontend/src/app/dashboard/admin/users/page.tsx @@ -10,6 +10,7 @@ import { Users as UsersIcon } from "lucide-react"; import { RoleBadge, type Role as RoleBadgeRole } from "@/components/shared/RoleBadge"; import { errorMessage } from "@/lib/utils"; import type { Paginated } from "@/types"; +import { BackLink } from "@/components/shared/BackLink"; interface UserItem { id: string; @@ -259,12 +260,12 @@ export default function AdminUsersPage() {
-

User Management

+ +

User Management

{total} user{total !== 1 ? "s" : ""} total

- diff --git a/frontend/src/app/dashboard/staff/event-tickets/page.tsx b/frontend/src/app/dashboard/staff/event-tickets/page.tsx index 1050d19..c57d2fc 100644 --- a/frontend/src/app/dashboard/staff/event-tickets/page.tsx +++ b/frontend/src/app/dashboard/staff/event-tickets/page.tsx @@ -10,6 +10,7 @@ import { QrImage } from "@/components/shared/QrImage"; import { Ticket } from "lucide-react"; import { errorMessage } from "@/lib/utils"; import type { Event, Ticket as TicketRecord } from "@/types"; +import { BackLink } from "@/components/shared/BackLink"; function EventTicketsContent() { const { token, user } = useAuth(); @@ -239,14 +240,11 @@ function EventTicketsContent() {
-

Event Tickets

+
+ +

Event Tickets

+
-

View and print tickets for an event. diff --git a/frontend/src/app/dashboard/staff/my-groups/page.tsx b/frontend/src/app/dashboard/staff/my-groups/page.tsx index 14b04bd..6b08c6f 100644 --- a/frontend/src/app/dashboard/staff/my-groups/page.tsx +++ b/frontend/src/app/dashboard/staff/my-groups/page.tsx @@ -2,10 +2,10 @@ import React, { useEffect, useState } from "react"; import { useAuth } from "@/hooks/useAuth"; -import { useRouter } from "next/navigation"; import { apiFetch } from "@/lib/api"; import { formatDate } from "@/lib/date"; import { Users } from "lucide-react"; +import { BackLink } from "@/components/shared/BackLink"; type Member = { id: string; name: string; gender: string | null; dateOfBirth: string | null; phone: string | null; @@ -25,7 +25,6 @@ const ageOn = (dob: string | null, on: string) => { /** Groups the signed-in staff member leads (rooms, small groups, buses) and who's in them. */ export default function MyGroupsPage() { const { token } = useAuth(); - const router = useRouter(); const [data, setData] = useState<{ medicalShown: boolean; groups: MyGroup[] } | null>(null); const [error, setError] = useState(null); @@ -42,7 +41,7 @@ export default function MyGroupsPage() {

- +

My groups

Rooms, small groups and buses you lead

diff --git a/frontend/src/app/dashboard/staff/ticket-scanning/page.tsx b/frontend/src/app/dashboard/staff/ticket-scanning/page.tsx index 6c0162b..2700d55 100644 --- a/frontend/src/app/dashboard/staff/ticket-scanning/page.tsx +++ b/frontend/src/app/dashboard/staff/ticket-scanning/page.tsx @@ -5,13 +5,13 @@ import { QRScanner, QRScannerHandle } from "@/components/qr/QRScanner"; import { useAuth } from "@/hooks/useAuth"; import { apiFetch } from "@/lib/api"; import { useDismissingState } from "@/hooks/useDismissingState"; -import { useRouter } from "next/navigation"; import { QrCode } from "lucide-react"; import { useOfflineScanning } from "@/components/scanner/useOfflineScanning"; import { OfflineScanPanel } from "@/components/scanner/OfflineScanPanel"; import type { SnapshotTicket } from "@/lib/offlineScan"; import { errorMessage } from "@/lib/utils"; import type { Event, RecentScan, ScanStats, Section } from "@/types"; +import { BackLink } from "@/components/shared/BackLink"; // GET /api/tickets/scan-preview/:qr — just the fields the confirm step needs. Offline // scans build the same shape from the downloaded ticket list. @@ -33,7 +33,6 @@ type ScanTicket = { }; export default function TicketScanningPage() { - const router = useRouter(); const scannerRef = useRef(null); const [scanInfo, setScanInfo] = useDismissingState(null); const [error, setError] = useDismissingState(null); @@ -330,9 +329,11 @@ export default function TicketScanningPage() {
-

Ticket Scanning

+
+ +

Ticket Scanning

+
-

Use the button to start/stop scanning. The back camera will be used when available. diff --git a/frontend/src/app/dashboard/supervisor/allocations/page.tsx b/frontend/src/app/dashboard/supervisor/allocations/page.tsx index ec85282..aff84c2 100644 --- a/frontend/src/app/dashboard/supervisor/allocations/page.tsx +++ b/frontend/src/app/dashboard/supervisor/allocations/page.tsx @@ -10,6 +10,7 @@ import { useDismissingState } from "@/hooks/useDismissingState"; import { BedDouble, Plus, Wand2, Printer, Trash2, Pencil, Eraser } from "lucide-react"; import { errorMessage } from "@/lib/utils"; import type { Event } from "@/types"; +import { BackLink } from "@/components/shared/BackLink"; type Group = { id: string; name: string; capacity: number | null; gender: "male" | "female" | null; leaderUserId: string | null; leader?: { id: string; name: string } | null }; type AllocSet = { id: string; name: string; showOnTicket: boolean; groups: Group[]; assignments: { attendeeId: string; groupId: string }[] }; @@ -207,7 +208,7 @@ export default function AllocationsPage() {

- +

Rooms & groups

Put attendees into rooms, small groups, teams or buses

diff --git a/frontend/src/app/dashboard/supervisor/consent/page.tsx b/frontend/src/app/dashboard/supervisor/consent/page.tsx index a774ac0..90ac0b1 100644 --- a/frontend/src/app/dashboard/supervisor/consent/page.tsx +++ b/frontend/src/app/dashboard/supervisor/consent/page.tsx @@ -10,6 +10,7 @@ import { ShieldCheck, Send, RefreshCw, HeartPulse, Printer } from "lucide-react" import { Table, TableHeader, TableBody, TableRow, TableHead, TableCell } from "@/components/ui/table"; import { errorMessage } from "@/lib/utils"; import type { Event, ConsentRow, MedicalRow } from "@/types"; +import { BackLink } from "@/components/shared/BackLink"; const STATUS_STYLE: Record = { @@ -134,7 +135,7 @@ export default function ConsentTrackerPage() {
- +

Parental consent

Youth events: who still needs a parent's consent before check-in

diff --git a/frontend/src/app/dashboard/supervisor/coupons/page.tsx b/frontend/src/app/dashboard/supervisor/coupons/page.tsx index ad8533e..5cbfa8a 100644 --- a/frontend/src/app/dashboard/supervisor/coupons/page.tsx +++ b/frontend/src/app/dashboard/supervisor/coupons/page.tsx @@ -8,6 +8,7 @@ import { useDismissingState } from "@/hooks/useDismissingState"; import { TicketPercent, Plus, X, Search } from "lucide-react"; import { Table, TableHeader, TableBody, TableRow, TableHead, TableCell } from "@/components/ui/table"; import { errorMessage } from "@/lib/utils"; +import { BackLink } from "@/components/shared/BackLink"; type CouponType = "percent" | "fixed" | "comp"; type Role = "user" | "staff" | "supervisor" | "admin"; @@ -206,7 +207,7 @@ export default function CouponsPage() {
- +

Coupon codes

Discounts for staff, leaders, volunteers and promotions

diff --git a/frontend/src/app/dashboard/supervisor/email-attendees/page.tsx b/frontend/src/app/dashboard/supervisor/email-attendees/page.tsx index 25549e1..ca08500 100644 --- a/frontend/src/app/dashboard/supervisor/email-attendees/page.tsx +++ b/frontend/src/app/dashboard/supervisor/email-attendees/page.tsx @@ -9,6 +9,7 @@ import { Mail, Users, Zap, Clock } from "lucide-react"; import { AllocationGroupFilter } from "@/components/shared/AllocationGroupFilter"; import { errorMessage } from "@/lib/utils"; import type { Event, MessageSendResult, Registration, User } from "@/types"; +import { BackLink } from "@/components/shared/BackLink"; type Attendee = { id: string; name: string; email: string; pref: string }; type TemplateKey = 'custom'|'payment_reminder'|'event_reminder'|'tickets'; @@ -489,10 +490,10 @@ function EmailAttendeesPageInner() {
-

Email Attendees

- -
- +
+ +

Email Attendees

+
diff --git a/frontend/src/app/dashboard/supervisor/event-options/page.tsx b/frontend/src/app/dashboard/supervisor/event-options/page.tsx index 8b5aaa2..7956187 100644 --- a/frontend/src/app/dashboard/supervisor/event-options/page.tsx +++ b/frontend/src/app/dashboard/supervisor/event-options/page.tsx @@ -8,6 +8,7 @@ import { useDismissingState } from "@/hooks/useDismissingState"; import { Ticket } from "lucide-react"; import { errorMessage } from "@/lib/utils"; import type { Event, EventOption } from "@/types"; +import { BackLink } from "@/components/shared/BackLink"; // Format a Date (or date-like input) to the value expected by // This returns local time (browser timezone) as YYYY-MM-DDTHH:mm @@ -209,9 +210,11 @@ function EventOptionsContent() {
-

Event options

+
+ +

Event options

+
- {!canView && ( diff --git a/frontend/src/app/dashboard/supervisor/events/page.tsx b/frontend/src/app/dashboard/supervisor/events/page.tsx index a2b88ec..ba3296f 100644 --- a/frontend/src/app/dashboard/supervisor/events/page.tsx +++ b/frontend/src/app/dashboard/supervisor/events/page.tsx @@ -12,6 +12,7 @@ import { Calendar } from "lucide-react"; import { ChoicesEditor } from "@/components/shared/FormFieldExtras"; import { errorMessage } from "@/lib/utils"; import type { Event, EventAttachment, EventFormField, EventOption, Paginated, Section } from "@/types"; +import { BackLink } from "@/components/shared/BackLink"; // ─── helpers ──────────────────────────────────────────────────────────────── @@ -1792,13 +1793,13 @@ export default function ManageEventsPage() {
-

Events

+ +

Events

Manage and create events

-
diff --git a/frontend/src/app/dashboard/supervisor/forms/page.tsx b/frontend/src/app/dashboard/supervisor/forms/page.tsx index f5e067e..07609c9 100644 --- a/frontend/src/app/dashboard/supervisor/forms/page.tsx +++ b/frontend/src/app/dashboard/supervisor/forms/page.tsx @@ -9,6 +9,7 @@ import { useDismissingState } from "@/hooks/useDismissingState"; import { FileText } from "lucide-react"; import { errorMessage } from "@/lib/utils"; import type { Event, EventForm, FormResponse, Registration, User } from "@/types"; +import { BackLink } from "@/components/shared/BackLink"; type FormFieldType = 'yes_no' | 'text' | 'date' | 'numeric' | 'statement' | 'paragraph' | 'rating' | 'multiple_choice'; @@ -452,10 +453,12 @@ export default function FormsBrowserPage() {
-

Forms

+
+ +

Forms

+
- {mode === 'view' && (
diff --git a/frontend/src/app/dashboard/supervisor/manual/page.tsx b/frontend/src/app/dashboard/supervisor/manual/page.tsx index a949fad..1981d30 100644 --- a/frontend/src/app/dashboard/supervisor/manual/page.tsx +++ b/frontend/src/app/dashboard/supervisor/manual/page.tsx @@ -12,6 +12,7 @@ import { UserPlus, CreditCard } from "lucide-react"; import { errorMessage } from "@/lib/utils"; import { optionUnitNow, variantUnitNow } from "@/lib/pricing"; import type { Event, EventOption, Registration, RegistrationOption, User } from "@/types"; +import { BackLink } from "@/components/shared/BackLink"; // ─── Pricing helpers ───────────────────────────────────────────────────────── @@ -348,9 +349,11 @@ export default function ManualRegistrationPage() {
-

Manual registration

+
+ +

Manual registration

+
- {!canView && ( diff --git a/frontend/src/app/dashboard/supervisor/offline-scans/page.tsx b/frontend/src/app/dashboard/supervisor/offline-scans/page.tsx index 17d4abc..c4474f5 100644 --- a/frontend/src/app/dashboard/supervisor/offline-scans/page.tsx +++ b/frontend/src/app/dashboard/supervisor/offline-scans/page.tsx @@ -9,6 +9,7 @@ import { useDismissingState } from "@/hooks/useDismissingState"; import { WifiOff, Unlock, CheckCircle2 } from "lucide-react"; import { errorMessage } from "@/lib/utils"; import type { Event } from "@/types"; +import { BackLink } from "@/components/shared/BackLink"; type Lock = { id: string; sectionName: string | null; deviceName: string | null; user: { name: string }; lockedAt: string; snapshotAt: string | null; lastSyncAt: string | null }; type Report = { @@ -86,7 +87,7 @@ export default function OfflineScansPage() {
- +

Offline scanning

Devices scanning without a connection, and their synced scans

diff --git a/frontend/src/app/dashboard/supervisor/payments/page.tsx b/frontend/src/app/dashboard/supervisor/payments/page.tsx index be2c908..eab36a9 100644 --- a/frontend/src/app/dashboard/supervisor/payments/page.tsx +++ b/frontend/src/app/dashboard/supervisor/payments/page.tsx @@ -10,6 +10,7 @@ import { Wallet, RotateCcw, HandHeart, ScanLine, Link2 } from "lucide-react"; import { errorMessage } from "@/lib/utils"; import { registrationOptionUnitPrice } from "@/lib/pricing"; import type { Event, Payment, Registration, User } from "@/types"; +import { BackLink } from "@/components/shared/BackLink"; // A donation is never mutated once created — assigning it to a registration creates a separate // "leg" Payment row (isDonation:false, originalPaymentId -> the donation, amount > 0) instead. @@ -499,9 +500,11 @@ function PaymentsContent() {
-

Payments

+
+ +

Payments

+
- {!canView && ( diff --git a/frontend/src/app/dashboard/supervisor/waitlist/page.tsx b/frontend/src/app/dashboard/supervisor/waitlist/page.tsx index 8bfce8c..fdc95a4 100644 --- a/frontend/src/app/dashboard/supervisor/waitlist/page.tsx +++ b/frontend/src/app/dashboard/supervisor/waitlist/page.tsx @@ -10,6 +10,7 @@ import { ListChecks, ArrowUp, ArrowDown } from "lucide-react"; import { Table, TableHeader, TableBody, TableRow, TableHead, TableCell } from "@/components/ui/table"; import { errorMessage } from "@/lib/utils"; import type { Event } from "@/types"; +import { BackLink } from "@/components/shared/BackLink"; type Entry = { id: string; @@ -100,7 +101,7 @@ export default function WaitlistPage() {
- +

Waitlist

People waiting for sold-out tickets

diff --git a/frontend/src/app/dashboard/supervisor/whatsapp-attendees/page.tsx b/frontend/src/app/dashboard/supervisor/whatsapp-attendees/page.tsx index 8d98cc0..bdf68da 100644 --- a/frontend/src/app/dashboard/supervisor/whatsapp-attendees/page.tsx +++ b/frontend/src/app/dashboard/supervisor/whatsapp-attendees/page.tsx @@ -9,6 +9,7 @@ import { MessageCircle, Users, Zap, Send, Clock, type LucideIcon } from "lucide- import { AllocationGroupFilter } from "@/components/shared/AllocationGroupFilter"; import { errorMessage } from "@/lib/utils"; import type { Event, MessageSendResult, Registration, User } from "@/types"; +import { BackLink } from "@/components/shared/BackLink"; // Attendee with preference info type Attendee = { id: string; name: string; phone: string; pref: string }; @@ -608,11 +609,11 @@ function WhatsAppAttendeesPageInner() {
-

WhatsApp Attendees

+
+ +

WhatsApp Attendees

+
- {!canView && ( diff --git a/frontend/src/app/dashboard/user/donate/page.tsx b/frontend/src/app/dashboard/user/donate/page.tsx index 3ee06c8..9ceaf2b 100644 --- a/frontend/src/app/dashboard/user/donate/page.tsx +++ b/frontend/src/app/dashboard/user/donate/page.tsx @@ -6,6 +6,7 @@ import { useDismissingState } from "@/hooks/useDismissingState"; import { HandHeart } from "lucide-react"; import { errorMessage } from "@/lib/utils"; import type { Event } from "@/types"; +import { BackLink } from "@/components/shared/BackLink"; export default function DonatePage() { const { token } = useAuth(); @@ -65,7 +66,8 @@ export default function DonatePage() {
-

Make a donation

+ +

Make a donation

Support an event or the ministry directly.

diff --git a/frontend/src/app/dashboard/user/forms/page.tsx b/frontend/src/app/dashboard/user/forms/page.tsx index 5f8dad8..8df2046 100644 --- a/frontend/src/app/dashboard/user/forms/page.tsx +++ b/frontend/src/app/dashboard/user/forms/page.tsx @@ -8,6 +8,7 @@ import { useDismissingState } from "@/hooks/useDismissingState"; import { FileText } from "lucide-react"; import { errorMessage } from "@/lib/utils"; import type { Registration } from "@/types"; +import { BackLink } from "@/components/shared/BackLink"; // Types for form fields type FormField = { id: string; type: 'yes_no'|'text'|'date'|'numeric'|'statement'|'paragraph'|'rating'|'multiple_choice'; label: string; isRequired?: boolean; helpText?: string|null; options?: unknown }; @@ -139,9 +140,11 @@ function FormsContent() {
-

Attendee forms

+
+ +

Attendee forms

+
- {loading &&
Loading…
} diff --git a/frontend/src/app/dashboard/user/payments/page.tsx b/frontend/src/app/dashboard/user/payments/page.tsx index 0acd7cb..3b0c6c1 100644 --- a/frontend/src/app/dashboard/user/payments/page.tsx +++ b/frontend/src/app/dashboard/user/payments/page.tsx @@ -9,6 +9,7 @@ import { formatPaymentMethod } from "@/lib/paymentMethod"; import { Receipt } from "lucide-react"; import { errorMessage } from "@/lib/utils"; import type { Paginated } from "@/types"; +import { BackLink } from "@/components/shared/BackLink"; interface PaymentItem { id: string; @@ -108,12 +109,11 @@ export default function UserPaymentsPage() {
-

My Payments

+
+ +

My Payments

+
- {error &&

{error}

} diff --git a/frontend/src/app/dashboard/user/profile/page.tsx b/frontend/src/app/dashboard/user/profile/page.tsx index 35a1054..1677fb5 100644 --- a/frontend/src/app/dashboard/user/profile/page.tsx +++ b/frontend/src/app/dashboard/user/profile/page.tsx @@ -9,6 +9,7 @@ import { useDismissingState } from "@/hooks/useDismissingState"; import { TwoFactorChallenge, TwoFactorMethod } from "@/lib/auth"; import { User, Lock, ShieldAlert, ShieldCheck, ShieldOff, Trash2, Clock, LogIn, KeyRound, RotateCcw } from "lucide-react"; import { errorMessage } from "@/lib/utils"; +import { BackLink } from "@/components/shared/BackLink"; type ActivityEvent = { id: string; type: "login" | "password_changed" | "password_reset" | "two_factor_enabled" | "two_factor_disabled"; device: string | null; createdAt: string }; @@ -309,7 +310,8 @@ export default function UserProfilePage() { return (
-

Profile & Security

+ +

Profile & Security

Manage your personal information and keep your account secure.

diff --git a/frontend/src/app/dashboard/user/reset-password/page.tsx b/frontend/src/app/dashboard/user/reset-password/page.tsx index 81236ed..1348fe0 100644 --- a/frontend/src/app/dashboard/user/reset-password/page.tsx +++ b/frontend/src/app/dashboard/user/reset-password/page.tsx @@ -6,6 +6,7 @@ import { useDismissingState } from "@/hooks/useDismissingState"; import { useRouter } from "next/navigation"; import { KeyRound } from "lucide-react"; import { errorMessage } from "@/lib/utils"; +import { BackLink } from "@/components/shared/BackLink"; export default function ResetPasswordPage() { const { token } = useAuth(); @@ -50,12 +51,11 @@ export default function ResetPasswordPage() {
-

Reset password

+
+ +

Reset password

+
- {error &&

{error}

} diff --git a/frontend/src/components/shared/BackLink.tsx b/frontend/src/components/shared/BackLink.tsx new file mode 100644 index 0000000..27b5671 --- /dev/null +++ b/frontend/src/components/shared/BackLink.tsx @@ -0,0 +1,14 @@ +import React from "react"; +import Link from "next/link"; + +/** + * The site-wide "← Back to …" link, shown above a page's title (next to its icon tile). + * Every dashboard page uses this one so back navigation looks and sits the same everywhere. + */ +export function BackLink({ href, label = "Back to dashboard" }: { href: string; label?: string }) { + return ( + + ← {label} + + ); +}