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.
This commit is contained in:
Maurice
2026-09-02 19:33:54 +02:00
committed by Maurice
parent ed3216f65d
commit c5d10dfd6f
2 changed files with 24 additions and 21 deletions
+23 -20
View File
@@ -27,6 +27,26 @@ const TYPE_DOT: Partial<Record<ToastType, MStatus>> = {
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 (
<div
role={toast.sticky ? 'button' : undefined}
tabIndex={toast.sticky ? 0 : undefined}
onClick={toast.sticky ? () => 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 && <MStatusDot status={dot} size={6} className={wraps ? 'mt-[0.45rem]' : ''} />}
{/* No display utility next to line-clamp: Tailwind emits it later and kills the clamp. */}
<span className={`min-w-0 ${wraps ? 'line-clamp-4 leading-[1.45]' : 'truncate'}`}>{toast.message}</span>
</div>
)
}
/**
* 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 (
<div className="pointer-events-none fixed inset-x-0 bottom-[calc(var(--bottom-nav-h,84px)+16px)] z-[90] flex flex-col-reverse items-center gap-2 px-6">
{toasts.map((toast) => {
const dot = TYPE_DOT[toast.type]
const wraps = toast.message.length > PILL_CHARS
return (
<div
key={toast.id}
role={toast.sticky ? 'button' : undefined}
tabIndex={toast.sticky ? 0 : undefined}
onClick={toast.sticky ? () => 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 && <MStatusDot status={dot} size={6} className={wraps ? 'mt-[0.45rem]' : ''} />}
{/* No display utility next to line-clamp: Tailwind emits it later and kills the clamp. */}
<span className={`min-w-0 ${wraps ? 'line-clamp-4 leading-[1.45]' : 'truncate'}`}>{toast.message}</span>
</div>
)
})}
{toasts.map((toast) => (
<MToastPill key={toast.id} toast={toast} onDismiss={dismissToast} />
))}
</div>
)
}
+1 -1
View File
@@ -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