Added Notifications
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
<script setup lang="ts">
|
||||
import {Airport, Flight} from '@/Types/types'
|
||||
import BadgeTable from '@/Components/FlightsGoneBy/GenericBadgeTable.vue'
|
||||
import InlineBadge from '@/Components/FlightsGoneBy/InlineBadge.vue'
|
||||
import AirportToolTip from '@/Components/FlightsGoneBy/AirportToolTip.vue'
|
||||
|
||||
type CodeType = 'iata' | 'icao'
|
||||
|
||||
const props = defineProps<{
|
||||
letters: string[]
|
||||
flightsByLetter: Record<string, Flight[]>
|
||||
codeType: CodeType
|
||||
selectedYear: number | null
|
||||
}>()
|
||||
|
||||
function getCode(airport: Airport): string | null {
|
||||
const raw = props.codeType === 'iata' ? airport.iata_code : airport.icao_code
|
||||
return raw?.trim().toUpperCase() ?? null
|
||||
}
|
||||
|
||||
interface AirportEntry {
|
||||
airport: Airport
|
||||
firstYear: number
|
||||
}
|
||||
|
||||
function airportEntriesForLetter(letter: string): AirportEntry[] {
|
||||
const flights = props.flightsByLetter[letter] ?? []
|
||||
const seen = new Map<string, AirportEntry>()
|
||||
|
||||
for (const flight of flights) {
|
||||
const year = new Date(flight.departure_date).getFullYear()
|
||||
|
||||
for (const airport of [flight.departure_airport, flight.arrival_airport]) {
|
||||
const code = getCode(airport)
|
||||
if (!code?.startsWith(letter)) continue
|
||||
|
||||
const existing = seen.get(code)
|
||||
if (!existing || year < existing.firstYear) {
|
||||
seen.set(code, { airport, firstYear: year })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [...seen.entries()]
|
||||
.sort(([a], [b]) => a.localeCompare(b))
|
||||
.map(([, entry]) => entry)
|
||||
}
|
||||
|
||||
function isHighlighted({ firstYear }: AirportEntry): boolean {
|
||||
return props.selectedYear !== null && firstYear === props.selectedYear
|
||||
}
|
||||
|
||||
function toBBCode(): string {
|
||||
return props.letters
|
||||
.map(letter => {
|
||||
const entries = airportEntriesForLetter(letter)
|
||||
if (!entries.length) return letter
|
||||
|
||||
return entries
|
||||
.map(entry => {
|
||||
const code = getCode(entry.airport)!
|
||||
return isHighlighted(entry) ? `[b][color=#00BF00]${code}[/color][/b]` : code
|
||||
})
|
||||
.join(', ')
|
||||
})
|
||||
.join('\n')
|
||||
}
|
||||
|
||||
defineExpose({ toBBCode })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<BadgeTable
|
||||
:rows="letters"
|
||||
:rowKey="letter => letter"
|
||||
:hasItems="letter => !!flightsByLetter[letter]?.length"
|
||||
labelWidth="4em"
|
||||
>
|
||||
<template #label="{ row: letter }">
|
||||
<div style="width:100%;display:flex;justify-content: center; align-items: center" :class="flightsByLetter[letter]?.length ? 'visited' : 'unvisited'">
|
||||
{{ letter }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #items="{ row: letter }">
|
||||
<AirportToolTip
|
||||
v-for="entry in airportEntriesForLetter(letter)"
|
||||
:key="getCode(entry.airport)!"
|
||||
:airport="entry.airport"
|
||||
>
|
||||
<InlineBadge :variant="isHighlighted(entry) ? 'business' : undefined">
|
||||
{{ getCode(entry.airport) }}
|
||||
</InlineBadge>
|
||||
</AirportToolTip>
|
||||
</template>
|
||||
</BadgeTable>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.visited {
|
||||
font-weight: 700;
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
.unvisited {
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.airport-count {
|
||||
font-size: 0.7rem;
|
||||
font-weight: 400;
|
||||
color: var(--muted);
|
||||
margin-left: 0.2em;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user