Corrected Korea
This commit is contained in:
@@ -0,0 +1,188 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from "vue";
|
||||
import { Flight } from "@/Types/types";
|
||||
import BoardingPass from "@/Components/FlightsGoneBy/BoardingPass.vue";
|
||||
|
||||
const props = defineProps<{
|
||||
flights: Flight[]
|
||||
}>()
|
||||
|
||||
const today = new Date()
|
||||
today.setHours(0, 0, 0, 0)
|
||||
|
||||
const upcomingFlights = computed(() =>
|
||||
props.flights
|
||||
.filter(f => new Date(f.departure_date) >= today)
|
||||
.sort((a, b) => new Date(a.departure_date).getTime() - new Date(b.departure_date).getTime())
|
||||
)
|
||||
|
||||
const departedFlights = computed(() =>
|
||||
props.flights
|
||||
.filter(f => new Date(f.departure_date) < today)
|
||||
.sort((a, b) => new Date(b.departure_date).getTime() - new Date(a.departure_date).getTime())
|
||||
)
|
||||
|
||||
const allFlights = computed(() => [...upcomingFlights.value, ...departedFlights.value])
|
||||
|
||||
function isFirstDeparted(flight: Flight, pageItems: Flight[]): boolean {
|
||||
const firstDeparted = pageItems.find(f => departedFlights.value.includes(f))
|
||||
return flight === firstDeparted
|
||||
}
|
||||
|
||||
function isUpcoming(flight: Flight): boolean {
|
||||
return upcomingFlights.value.includes(flight)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-data-iterator :items="allFlights" :items-per-page="25">
|
||||
<template #default="{ items }">
|
||||
<div class="passes-root">
|
||||
<template v-if="items.some(i => isUpcoming(i.raw))">
|
||||
<div class="section-header upcoming">
|
||||
<span class="section-icon">◈</span>
|
||||
<span class="section-label">UPCOMING FLIGHTS</span>
|
||||
<span class="section-count">{{ upcomingFlights.length }} scheduled</span>
|
||||
<div class="section-line" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div class="passes-grid">
|
||||
<template v-for="{ raw: flight } in items" :key="flight.id">
|
||||
<template v-if="isFirstDeparted(flight, items.map(i => i.raw))">
|
||||
<div class="section-header departed grid-span-full">
|
||||
<span class="section-icon">◉</span>
|
||||
<span class="section-label">DEPARTED FLIGHTS</span>
|
||||
<span class="section-count">{{ departedFlights.length }} logged</span>
|
||||
<div class="section-line" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<BoardingPass :flight="flight" />
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<template v-if="!items.some(i => isUpcoming(i.raw)) && items[0]?.raw === departedFlights[0]">
|
||||
<div class="section-header departed departed-only">
|
||||
<span class="section-icon">◉</span>
|
||||
<span class="section-label">DEPARTED FLIGHTS</span>
|
||||
<span class="section-count">{{ departedFlights.length }} logged</span>
|
||||
<div class="section-line" />
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #footer="{ page, pageCount, prevPage, nextPage }">
|
||||
<div class="iterator-footer">
|
||||
<span class="footer-info">Page {{ page }} of {{ pageCount }}</span>
|
||||
<div class="footer-nav">
|
||||
<button class="nav-btn" :disabled="page === 1" @click="prevPage">‹</button>
|
||||
<button class="nav-btn" :disabled="page === pageCount" @click="nextPage">›</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</v-data-iterator>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.passes-root {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.departed-only {
|
||||
order: -1;
|
||||
}
|
||||
|
||||
.section-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
padding: 1.5rem 0 0.75rem;
|
||||
}
|
||||
.section-icon { font-size: 0.7rem; flex-shrink: 0; }
|
||||
.section-label {
|
||||
font-family: 'Share Tech Mono', monospace;
|
||||
font-size: 0.72rem;
|
||||
letter-spacing: 0.22em;
|
||||
font-weight: 400;
|
||||
flex-shrink: 0;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.section-count {
|
||||
font-family: 'Share Tech Mono', monospace;
|
||||
font-size: 0.65rem;
|
||||
letter-spacing: 0.1em;
|
||||
color: #445566;
|
||||
flex-shrink: 0;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.section-line { flex: 1; height: 1px; min-width: 2rem; }
|
||||
|
||||
.section-header.upcoming .section-icon,
|
||||
.section-header.upcoming .section-label { color: #ffc107; }
|
||||
.section-header.upcoming .section-line { background: linear-gradient(to right, rgba(255,193,7,0.4), transparent); }
|
||||
.section-header.departed .section-icon,
|
||||
.section-header.departed .section-label { color: #778899; }
|
||||
.section-header.departed .section-line { background: linear-gradient(to right, rgba(119,136,153,0.35), transparent); }
|
||||
|
||||
.passes-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(360px, 1fr));
|
||||
gap: 1.25rem;
|
||||
padding-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.grid-span-full {
|
||||
grid-column: 1 / -1;
|
||||
padding: 0.75rem 0 0;
|
||||
}
|
||||
|
||||
.iterator-footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 1rem;
|
||||
padding: 1rem 0 2rem;
|
||||
border-top: 1px solid rgba(255,255,255,0.06);
|
||||
}
|
||||
|
||||
.footer-info {
|
||||
font-family: 'Share Tech Mono', monospace;
|
||||
font-size: 0.72rem;
|
||||
letter-spacing: 0.08em;
|
||||
color: #445566;
|
||||
}
|
||||
|
||||
.footer-nav {
|
||||
display: flex;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
.nav-btn {
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
background: transparent;
|
||||
border: 1px solid rgba(255,255,255,0.08);
|
||||
border-radius: 2px;
|
||||
color: #778;
|
||||
font-size: 1rem;
|
||||
cursor: pointer;
|
||||
transition: background 0.15s, color 0.15s, border-color 0.15s;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.nav-btn:hover:not(:disabled) {
|
||||
background: rgba(255,193,7,0.05);
|
||||
border-color: rgba(255,193,7,0.2);
|
||||
color: #ffc107;
|
||||
}
|
||||
|
||||
.nav-btn:disabled {
|
||||
opacity: 0.25;
|
||||
cursor: default;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user