mirror of
https://github.com/fsolla/teqo.git
synced 2026-11-14 08:53:11 +00:00
- ~190 findings zerados: knip --fix (grafo corrigido: tests como entries, migrations como consumidores) + delecao guardada dos orfaos (git grep -w antes de deletar) + reparos manuais dos corpos arrow pendurados - pecas nao usadas do kit ui deletadas (PaginationLink/Next/Previous, familias Sidebar/Combobox/Sheet/Drawer/Dialog etc.) - shadcn add recoloca se precisar - acoes mortas removidas (updateCampaignDemandDetails*, *Record orfaos), schemas/tipos mortos (campaignDemandDetailsUpdateSchema, Contact do zod), helpers mortos - tipos de eleicao derivam direto das *_OPTIONS (consts intermediarias eliminadas) - knip.json: rules exports/types/enumMembers=error, duplicates=off (unicos hits: 6 aliases deliberados canUpdateX=canReadX); hints aplicados (payload.config entry redundante, ignores de tsx/sharp/playwright/payload-types desnecessarios) - ledger: linha P2 dos unused exports fechada
60 lines
1.7 KiB
TypeScript
60 lines
1.7 KiB
TypeScript
export const STORAGE_KEY = 'teqo:campaign:recent-visits'
|
|
export const MAX_ENTRIES = 8
|
|
export const RECORD_DWELL_MS = 2000
|
|
|
|
type RecentVisitKind = 'municipality' | 'municipalityList'
|
|
|
|
export type RecentVisitEntry = {
|
|
href: string
|
|
label: string
|
|
kind: RecentVisitKind
|
|
visitedAt: number
|
|
}
|
|
|
|
const isRecentVisitEntry = (value: unknown): value is RecentVisitEntry => {
|
|
if (!value || typeof value !== 'object') return false
|
|
const entry = value as Record<string, unknown>
|
|
return (
|
|
typeof entry.href === 'string' &&
|
|
entry.href.length > 0 &&
|
|
typeof entry.label === 'string' &&
|
|
entry.label.length > 0 &&
|
|
(entry.kind === 'municipality' || entry.kind === 'municipalityList') &&
|
|
typeof entry.visitedAt === 'number' &&
|
|
Number.isFinite(entry.visitedAt)
|
|
)
|
|
}
|
|
|
|
export const listRecentVisits = (): RecentVisitEntry[] => {
|
|
if (typeof window === 'undefined') return []
|
|
try {
|
|
const raw = localStorage.getItem(STORAGE_KEY)
|
|
if (!raw) return []
|
|
const parsed: unknown = JSON.parse(raw)
|
|
if (!Array.isArray(parsed)) return []
|
|
return parsed.filter(isRecentVisitEntry)
|
|
} catch {
|
|
return []
|
|
}
|
|
}
|
|
|
|
export const recordRecentVisit = (entry: RecentVisitEntry): void => {
|
|
if (typeof window === 'undefined') return
|
|
try {
|
|
const existing = listRecentVisits()
|
|
const deduped = existing.filter((item) => item.href !== entry.href)
|
|
const next = [entry, ...deduped].slice(0, MAX_ENTRIES)
|
|
localStorage.setItem(STORAGE_KEY, JSON.stringify(next))
|
|
} catch {
|
|
// Ignore quota / private-mode failures.
|
|
}
|
|
}
|
|
|
|
export const clearRecentVisits = (): void => {
|
|
if (typeof window === 'undefined') return
|
|
try {
|
|
localStorage.removeItem(STORAGE_KEY)
|
|
} catch {
|
|
// Ignore private-mode failures.
|
|
}
|
|
}
|