feat(ui): copy logistics header/theme one-to-one

This commit is contained in:
Ruslan Bakiev
2026-04-21 10:34:54 +07:00
parent 670e9b7fd1
commit d3183bf6ad
11 changed files with 1052 additions and 236 deletions

View File

@@ -0,0 +1,86 @@
type CalcSearchDraft = {
from: string
to: string
cargo: string
fromLat: number | null
fromLng: number | null
toLat: number | null
toLng: number | null
}
type CalcSearchDraftPatch = Partial<CalcSearchDraft>
const initialCalcSearchDraft = (): CalcSearchDraft => ({
from: '',
to: '',
cargo: '',
fromLat: null,
fromLng: null,
toLat: null,
toLng: null,
})
function stringParam(value: unknown) {
return typeof value === 'string' ? value.trim() : ''
}
function numberParam(value: unknown) {
const num = Number(value)
return Number.isFinite(num) ? num : null
}
export function useCalcSearchDraft() {
const draft = useState<CalcSearchDraft>('calc-search-draft', initialCalcSearchDraft)
function hydrateFromQuery(query: Record<string, unknown>) {
const nextDraft = { ...draft.value }
const from = stringParam(query.from)
const to = stringParam(query.to)
const cargo = stringParam(query.cargo)
const fromLat = numberParam(query.fromLat)
const fromLng = numberParam(query.fromLng)
const toLat = numberParam(query.toLat)
const toLng = numberParam(query.toLng)
if (from) nextDraft.from = from
if (to) nextDraft.to = to
if (cargo) nextDraft.cargo = cargo
if (fromLat !== null) nextDraft.fromLat = fromLat
if (fromLng !== null) nextDraft.fromLng = fromLng
if (toLat !== null) nextDraft.toLat = toLat
if (toLng !== null) nextDraft.toLng = toLng
draft.value = nextDraft
}
function patchDraft(patch: CalcSearchDraftPatch) {
draft.value = {
...draft.value,
...patch,
}
}
function buildQuery(patch: CalcSearchDraftPatch = {}) {
const nextDraft = {
...draft.value,
...patch,
}
return {
...(nextDraft.from.trim() ? { from: nextDraft.from.trim() } : {}),
...(nextDraft.to.trim() ? { to: nextDraft.to.trim() } : {}),
...(nextDraft.cargo.trim() ? { cargo: nextDraft.cargo.trim() } : {}),
...(nextDraft.fromLat !== null ? { fromLat: String(nextDraft.fromLat) } : {}),
...(nextDraft.fromLng !== null ? { fromLng: String(nextDraft.fromLng) } : {}),
...(nextDraft.toLat !== null ? { toLat: String(nextDraft.toLat) } : {}),
...(nextDraft.toLng !== null ? { toLng: String(nextDraft.toLng) } : {}),
}
}
return {
draft,
hydrateFromQuery,
patchDraft,
buildQuery,
}
}