From c5d10dfd6fb5229e2113286d5ff3eca461293527 Mon Sep 17 00:00:00 2001 From: Maurice Date: Wed, 2 Sep 2026 19:33:54 +0200 Subject: [PATCH] fix(client): settle the two findings Sonar raised on the audit branch The farthest-stop reduce gets its explicit seed (the guard above already refuses an empty list, the seed makes that local), and the toast pill moves into its own component so the host stays below the complexity ceiling. --- client/src/mobile/components/MToastHost.tsx | 43 +++++++++++---------- client/src/utils/dayOrder.ts | 2 +- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/client/src/mobile/components/MToastHost.tsx b/client/src/mobile/components/MToastHost.tsx index 316c99d20..0d29b7b31 100644 --- a/client/src/mobile/components/MToastHost.tsx +++ b/client/src/mobile/components/MToastHost.tsx @@ -27,6 +27,26 @@ const TYPE_DOT: Partial> = { warning: 'pending', } +function MToastPill({ toast, onDismiss }: { toast: MToast; onDismiss: (id: number) => void }) { + const dot = TYPE_DOT[toast.type] + const wraps = toast.message.length > PILL_CHARS + return ( +
onDismiss(toast.id) : undefined} + onKeyDown={toast.sticky ? (e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onDismiss(toast.id) } } : undefined} + className={`flex max-w-full gap-2 bg-m-act px-4 py-2 text-[0.75rem] font-semibold text-m-actfg shadow-[0_10px_30px_-8px_rgba(0,0,0,.5)] ${ + wraps ? 'items-start rounded-2xl' : 'items-center rounded-full' + } ${toast.sticky ? 'pointer-events-auto cursor-pointer' : ''} ${toast.removing ? 'm-toast-out' : 'm-toast-in'}`} + > + {dot && } + {/* No display utility next to line-clamp: Tailwind emits it later and kills the clamp. */} + {toast.message} +
+ ) +} + /** * Mobile toast presenter. Takes over the global `window.__addToast` bridge * (fed by useToast / store/notify) while the mobile shell is mounted, so every @@ -78,26 +98,9 @@ export default function MToastHost() { return (
- {toasts.map((toast) => { - const dot = TYPE_DOT[toast.type] - const wraps = toast.message.length > PILL_CHARS - return ( -
dismissToast(toast.id) : undefined} - onKeyDown={toast.sticky ? (e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); dismissToast(toast.id) } } : undefined} - className={`flex max-w-full gap-2 bg-m-act px-4 py-2 text-[0.75rem] font-semibold text-m-actfg shadow-[0_10px_30px_-8px_rgba(0,0,0,.5)] ${ - wraps ? 'items-start rounded-2xl' : 'items-center rounded-full' - } ${toast.sticky ? 'pointer-events-auto cursor-pointer' : ''} ${toast.removing ? 'm-toast-out' : 'm-toast-in'}`} - > - {dot && } - {/* No display utility next to line-clamp: Tailwind emits it later and kills the clamp. */} - {toast.message} -
- ) - })} + {toasts.map((toast) => ( + + ))}
) } diff --git a/client/src/utils/dayOrder.ts b/client/src/utils/dayOrder.ts index 0b6f465be..f02e3fad5 100644 --- a/client/src/utils/dayOrder.ts +++ b/client/src/utils/dayOrder.ts @@ -95,7 +95,7 @@ export const getAccommodationAnchors = ( const farthestFrom = (h: Accommodation): EdgeStop | undefined => { if (!stops?.length) return undefined const from = at(h) - const far = stops.reduce((a, b) => (haversineKm(from, b) > haversineKm(from, a) ? b : a)) + const far = stops.reduce((a, b) => (haversineKm(from, b) > haversineKm(from, a) ? b : a), stops[0]) return { isPlace: true, time: null, lat: far.lat, lng: far.lng } } const hasStops = !!stops?.length