Extract admin dashboard from ghabilee-frontend2 into a dedicated Next.js app for backoffice.ghabilee.ir (no SEO indexing / Clarity).
34 lines
1.4 KiB
TypeScript
34 lines
1.4 KiB
TypeScript
/**
|
|
* Shared "which cities currently have events" derivation used by both the
|
|
* `/city` hub page and `sitemap.ts`. Both previously re-implemented this
|
|
* `Set` + filter independently after fetching discovery events; extracted
|
|
* here so there's one place computing it.
|
|
*
|
|
* NOTE: there's no dedicated "cities with active events" aggregation
|
|
* endpoint yet — this only reflects whatever discovery events the caller
|
|
* passes in. `/city` intentionally samples just the first page of public
|
|
* discovery events (backend max pageSize 100) to derive this cheaply; that
|
|
* remains a stub, revisit with a real aggregation once saza1's foundation
|
|
* lands if event volume grows past one page. `sitemap.ts` instead passes
|
|
* every page (via `fetchAllSeoDiscoveryEvents`), so it isn't subject to
|
|
* that same page-1 limit.
|
|
*/
|
|
|
|
interface ActiveCityEventCandidate {
|
|
cityId: number
|
|
}
|
|
|
|
interface ActiveCityCandidate {
|
|
id: number
|
|
}
|
|
|
|
/** Derives the set of city ids present among the given discovery events. */
|
|
export function getActiveCityIds(events: ActiveCityEventCandidate[]): Set<number> {
|
|
return new Set(events.map((event) => event.cityId))
|
|
}
|
|
|
|
/** Filters `cities` down to those whose id is in `activeCityIds`. */
|
|
export function filterActiveCities<T extends ActiveCityCandidate>(cities: T[], activeCityIds: Set<number>): T[] {
|
|
return cities.filter((city) => activeCityIds.has(city.id))
|
|
}
|