From 8eb5e19fea8cd8cce34d4bc582cfe76302947271 Mon Sep 17 00:00:00 2001 From: Maurice Date: Thu, 2 Jul 2026 13:47:36 +0200 Subject: [PATCH] fix(join): extract JoinTripPage state into a useJoinTrip hook The page container held useState/useEffect directly, tripping the CI page-pattern check. Move the token preview + accept logic into a co-located useJoinTrip() hook; the page is now a thin presentational shell. --- client/src/pages/JoinTripPage.tsx | 31 +++------------------- client/src/pages/join/useJoinTrip.ts | 39 ++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 27 deletions(-) create mode 100644 client/src/pages/join/useJoinTrip.ts diff --git a/client/src/pages/JoinTripPage.tsx b/client/src/pages/JoinTripPage.tsx index 60b59ca22..eeb2d50a6 100644 --- a/client/src/pages/JoinTripPage.tsx +++ b/client/src/pages/JoinTripPage.tsx @@ -1,8 +1,6 @@ -import { useEffect, useState } from 'react' -import { useNavigate, useParams } from 'react-router-dom' import { Users, Check, X } from 'lucide-react' -import { tripInviteApi } from '../api/client' import { useTranslation } from '../i18n' +import { useJoinTrip } from './join/useJoinTrip' /** * /join/:token — accept a trip invite as an existing, logged-in user (#1143). @@ -14,29 +12,8 @@ import { useTranslation } from '../i18n' * (or the owner) is simply taken straight to the trip. */ export default function JoinTripPage() { - const { token } = useParams<{ token: string }>() - const navigate = useNavigate() const { t } = useTranslation() - - const [state, setState] = useState<'loading' | 'ready' | 'joining' | 'invalid'>('loading') - const [title, setTitle] = useState('') - - useEffect(() => { - let cancelled = false - if (!token) { setState('invalid'); return } - tripInviteApi.preview(token) - .then((data: { title: string }) => { if (!cancelled) { setTitle(data.title); setState('ready') } }) - .catch(() => { if (!cancelled) setState('invalid') }) - return () => { cancelled = true } - }, [token]) - - const accept = () => { - if (!token) return - setState('joining') - tripInviteApi.accept(token) - .then((data: { trip_id: number }) => navigate(`/trips/${data.trip_id}`, { replace: true })) - .catch(() => setState('invalid')) - } + const { state, title, accept, goToDashboard } = useJoinTrip() return (
@@ -58,7 +35,7 @@ export default function JoinTripPage() {

{t('trip.invite.invalidTitle')}

{t('trip.invite.invalid')}