mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-24 16:03:02 +00:00
add roadtrip warning areas and tidy driving settings
This commit is contained in:
@@ -3,6 +3,7 @@ import { Sunrise, Sunset } from 'lucide-react'
|
||||
import { useTranslation } from '../../i18n/TranslationContext'
|
||||
import { dayWindow } from './dayWindow'
|
||||
import CustomTimePicker from '../shared/CustomTimePicker'
|
||||
import SettingsHint from './SettingsHint'
|
||||
|
||||
export default function DayWindowFields({ start, end, endMode = 'route', onSave }: {
|
||||
start?: string
|
||||
@@ -25,7 +26,7 @@ export default function DayWindowFields({ start, end, endMode = 'route', onSave
|
||||
}
|
||||
}
|
||||
return (
|
||||
<fieldset className="flex flex-col gap-3">
|
||||
<fieldset className="flex min-w-0 flex-col gap-3">
|
||||
<legend className="sr-only">{t('roadtrip.window.title')}</legend>
|
||||
{(['start', 'end'] as const).map(field => {
|
||||
const Icon = field === 'start' ? Sunrise : Sunset
|
||||
@@ -45,10 +46,10 @@ export default function DayWindowFields({ start, end, endMode = 'route', onSave
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
<p id="roadtrip-window-hint" role={invalid ? 'alert' : undefined} className={`text-caption ${invalid ? 'text-danger' : 'text-content-faint'}`}>
|
||||
{t(invalid ? 'roadtrip.window.invalid' : 'roadtrip.window.hint')}
|
||||
</p>
|
||||
<fieldset className="flex flex-col gap-2 border-t border-edge-faint pt-3">
|
||||
{invalid
|
||||
? <p id="roadtrip-window-hint" role="alert" className="text-caption text-danger">{t('roadtrip.window.invalid')}</p>
|
||||
: <SettingsHint id="roadtrip-window-hint">{t('roadtrip.window.hint')}</SettingsHint>}
|
||||
<fieldset className="flex min-w-0 flex-col gap-2 border-t border-edge-faint pt-3">
|
||||
<legend className="sr-only">{t('roadtrip.window.endAt')}</legend>
|
||||
<span className="text-body text-content-secondary">{t('roadtrip.window.endAt')}</span>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
@@ -61,7 +62,7 @@ export default function DayWindowFields({ start, end, endMode = 'route', onSave
|
||||
</label>
|
||||
))}
|
||||
</div>
|
||||
<p id="roadtrip-end-mode-hint" className="text-caption text-content-faint">{t(`roadtrip.window.${endMode === 'stop' ? 'stopHint' : 'routeHint'}`)}</p>
|
||||
<SettingsHint id="roadtrip-end-mode-hint">{t(`roadtrip.window.${endMode === 'stop' ? 'stopHint' : 'routeHint'}`)}</SettingsHint>
|
||||
</fieldset>
|
||||
</fieldset>
|
||||
)
|
||||
|
||||
@@ -16,6 +16,7 @@ import ToggleSwitch from '../Settings/ToggleSwitch'
|
||||
import type { DistanceUnit, RouteAvoidClass } from '../../types'
|
||||
import { FS } from './typeScale'
|
||||
import DayWindowFields from './DayWindowFields'
|
||||
import SettingsHint from './SettingsHint'
|
||||
import { dayWindow } from './dayWindow'
|
||||
|
||||
/**
|
||||
@@ -193,10 +194,10 @@ function Panel({ icon: Icon, title, note, children }: {
|
||||
children: React.ReactNode
|
||||
}): React.ReactElement {
|
||||
return (
|
||||
<section className="flex flex-col gap-3 rounded-xl border border-edge-faint bg-surface-secondary px-4 py-3.5">
|
||||
<section className="flex min-w-0 flex-col gap-3 rounded-xl border border-edge-faint bg-surface-secondary px-4 py-3.5">
|
||||
<SectionTitle icon={Icon}>{title}</SectionTitle>
|
||||
{children}
|
||||
{note ? <p className="text-caption leading-snug text-content-faint">{note}</p> : null}
|
||||
{note ? <SettingsHint>{note}</SettingsHint> : null}
|
||||
</section>
|
||||
)
|
||||
}
|
||||
@@ -429,7 +430,7 @@ export default function RoadtripLimitsCard({ onSave, onResetDayBoundaries, loadi
|
||||
{t('roadtrip.limit.title')}
|
||||
</span>
|
||||
}>
|
||||
<div className="flex flex-col gap-4">
|
||||
<div className="flex min-w-0 flex-col gap-4">
|
||||
{/* Two columns, kept. One column reads more tidily but turns the dialog into
|
||||
something that has to be scrolled, and a setting you cannot see while you
|
||||
change another is worse than a seam down the middle.
|
||||
@@ -439,7 +440,7 @@ export default function RoadtripLimitsCard({ onSave, onResetDayBoundaries, loadi
|
||||
ends on the same right edge, and the panels are stacked to one rhythm. The
|
||||
left column holds trip settings, the right holds the car and route appearance. */}
|
||||
<div className="grid items-start gap-4 sm:grid-cols-2">
|
||||
<div className="flex flex-col gap-4">
|
||||
<div className="flex min-w-0 flex-col gap-4">
|
||||
<Panel icon={Clock} title={t('roadtrip.limit.sectionDriving')} note={t('roadtrip.limit.hint')}>
|
||||
<LimitRow
|
||||
icon={Clock}
|
||||
@@ -484,7 +485,7 @@ export default function RoadtripLimitsCard({ onSave, onResetDayBoundaries, loadi
|
||||
</Panel>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-4">
|
||||
<div className="flex min-w-0 flex-col gap-4">
|
||||
<Panel
|
||||
icon={Car}
|
||||
title={t('roadtrip.limit.sectionVehicle')}
|
||||
@@ -641,6 +642,10 @@ export default function RoadtripLimitsCard({ onSave, onResetDayBoundaries, loadi
|
||||
onToggle={() => onSave?.('roadtrip_day_colors', !settings.roadtrip_day_colors)}
|
||||
/>
|
||||
</Panel>
|
||||
<Panel icon={Signpost} title={t('roadtrip.hazards.current')} note={t('roadtrip.hazards.note')}>
|
||||
<AvoidRow icon={Signpost} label={t('roadtrip.hazards.show')} on={settings.roadtrip_show_hazards === true} disabled={!onSave}
|
||||
onToggle={() => onSave?.('roadtrip_show_hazards', !settings.roadtrip_show_hazards)} />
|
||||
</Panel>
|
||||
<Panel icon={Signpost} title={t('roadtrip.stops.section')} note={t('roadtrip.stops.daysHint')}>
|
||||
<AvoidRow icon={Link2} label={t('roadtrip.stops.inDays')}
|
||||
on={settings.roadtrip_service_stops_in_days !== false}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import { Tooltip } from '../shared/Tooltip'
|
||||
|
||||
export default function SettingsHint({ children, id }: { children: string; id?: string }) {
|
||||
return <Tooltip label={children} placement="top">
|
||||
<p id={id} tabIndex={0} className="min-w-0 truncate text-caption leading-snug text-content-faint">{children}</p>
|
||||
</Tooltip>
|
||||
}
|
||||
Reference in New Issue
Block a user