consolidate series pages into single page with tabs
This commit is contained in:
parent
50ee6b80ff
commit
f429988981
1 changed files with 79 additions and 21 deletions
|
|
@ -3,18 +3,55 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { createQuery } from '@tanstack/svelte-query'
|
import { createQuery } from '@tanstack/svelte-query'
|
||||||
import { entityQueries } from '$lib/api/queries/entity.queries'
|
import { entityQueries } from '$lib/api/queries/entity.queries'
|
||||||
|
import SegmentedControl from '$lib/components/ui/segmented-control/SegmentedControl.svelte'
|
||||||
|
import Segment from '$lib/components/ui/segmented-control/Segment.svelte'
|
||||||
|
|
||||||
// Fetch weapon series list
|
type SeriesType = 'weapons' | 'characters' | 'summons'
|
||||||
const seriesQuery = createQuery(() => entityQueries.weaponSeriesList())
|
|
||||||
|
let activeType = $state<SeriesType>('weapons')
|
||||||
|
|
||||||
|
// Fetch all series lists
|
||||||
|
const weaponSeriesQuery = createQuery(() => entityQueries.weaponSeriesList())
|
||||||
|
const characterSeriesQuery = createQuery(() => entityQueries.characterSeriesList())
|
||||||
|
const summonSeriesQuery = createQuery(() => entityQueries.summonSeriesList())
|
||||||
|
|
||||||
|
// Get active query based on selected type
|
||||||
|
const activeQuery = $derived.by(() => {
|
||||||
|
switch (activeType) {
|
||||||
|
case 'weapons':
|
||||||
|
return weaponSeriesQuery
|
||||||
|
case 'characters':
|
||||||
|
return characterSeriesQuery
|
||||||
|
case 'summons':
|
||||||
|
return summonSeriesQuery
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// Get sorted data
|
||||||
|
const sortedData = $derived.by(() => {
|
||||||
|
if (!activeQuery.data) return []
|
||||||
|
return [...activeQuery.data].sort((a, b) => a.order - b.order)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Check if the current type has flags (only weapons)
|
||||||
|
const hasFlags = $derived(activeType === 'weapons')
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="database-page">
|
<div class="database-page">
|
||||||
<div class="grid-container">
|
<div class="grid-container">
|
||||||
{#if seriesQuery.isPending}
|
<nav class="series-nav" aria-label="Series type">
|
||||||
<div class="loading">Loading weapon series...</div>
|
<SegmentedControl bind:value={activeType} variant="blended" size="small">
|
||||||
{:else if seriesQuery.error}
|
<Segment value="weapons">Weapons</Segment>
|
||||||
<div class="error">Failed to load weapon series</div>
|
<Segment value="characters">Characters</Segment>
|
||||||
{:else if seriesQuery.data}
|
<Segment value="summons">Summons</Segment>
|
||||||
|
</SegmentedControl>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
{#if activeQuery.isPending}
|
||||||
|
<div class="loading">Loading {activeType} series...</div>
|
||||||
|
{:else if activeQuery.error}
|
||||||
|
<div class="error">Failed to load {activeType} series</div>
|
||||||
|
{:else if sortedData.length > 0}
|
||||||
<div class="series-table">
|
<div class="series-table">
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
|
|
@ -23,28 +60,34 @@
|
||||||
<th class="name">Name (EN)</th>
|
<th class="name">Name (EN)</th>
|
||||||
<th class="name-ja">Name (JA)</th>
|
<th class="name-ja">Name (JA)</th>
|
||||||
<th class="slug">Slug</th>
|
<th class="slug">Slug</th>
|
||||||
<th class="flags">Flags</th>
|
{#if hasFlags}
|
||||||
|
<th class="flags">Flags</th>
|
||||||
|
{/if}
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{#each seriesQuery.data.sort((a, b) => a.order - b.order) as series (series.id)}
|
{#each sortedData as series (series.id)}
|
||||||
<tr>
|
<tr>
|
||||||
<td class="order">{series.order}</td>
|
<td class="order">{series.order}</td>
|
||||||
<td class="name">{series.name.en}</td>
|
<td class="name">{series.name.en}</td>
|
||||||
<td class="name-ja">{series.name.ja}</td>
|
<td class="name-ja">{series.name.ja}</td>
|
||||||
<td class="slug"><code>{series.slug}</code></td>
|
<td class="slug"><code>{series.slug}</code></td>
|
||||||
<td class="flags">
|
{#if hasFlags && 'extra' in series}
|
||||||
{#if series.extra}<span class="flag extra">Extra</span>{/if}
|
<td class="flags">
|
||||||
{#if series.elementChangeable}<span class="flag element">Element</span>{/if}
|
{#if series.extra}<span class="flag extra">Extra</span>{/if}
|
||||||
{#if series.hasWeaponKeys}<span class="flag keys">Keys</span>{/if}
|
{#if series.elementChangeable}<span class="flag element">Element</span>{/if}
|
||||||
{#if series.hasAwakening}<span class="flag awaken">Awaken</span>{/if}
|
{#if series.hasWeaponKeys}<span class="flag keys">Keys</span>{/if}
|
||||||
{#if series.hasAxSkills}<span class="flag ax">AX</span>{/if}
|
{#if series.hasAwakening}<span class="flag awaken">Awaken</span>{/if}
|
||||||
</td>
|
{#if series.hasAxSkills}<span class="flag ax">AX</span>{/if}
|
||||||
|
</td>
|
||||||
|
{/if}
|
||||||
</tr>
|
</tr>
|
||||||
{/each}
|
{/each}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
{:else}
|
||||||
|
<div class="empty">No {activeType} series found</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -69,8 +112,17 @@
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.series-nav {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: spacing.$unit-2x;
|
||||||
|
padding: spacing.$unit-2x;
|
||||||
|
border-bottom: 1px solid var(--border-subtle);
|
||||||
|
}
|
||||||
|
|
||||||
.loading,
|
.loading,
|
||||||
.error {
|
.error,
|
||||||
|
.empty {
|
||||||
padding: spacing.$unit-4x;
|
padding: spacing.$unit-4x;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: colors.$grey-50;
|
color: colors.$grey-50;
|
||||||
|
|
@ -100,8 +152,6 @@
|
||||||
font-weight: typography.$medium;
|
font-weight: typography.$medium;
|
||||||
font-size: typography.$font-small;
|
font-size: typography.$font-small;
|
||||||
color: colors.$grey-40;
|
color: colors.$grey-40;
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: 0.5px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
td {
|
td {
|
||||||
|
|
@ -114,7 +164,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.name {
|
.name {
|
||||||
min-width: 280px;
|
min-width: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.name-ja {
|
.name-ja {
|
||||||
|
|
@ -144,7 +194,15 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&.element {
|
&.element {
|
||||||
background: linear-gradient(to right, #fecaca, #fef08a, #bbf7d0, #bfdbfe, #e9d5ff, #fbcfe8);
|
background: linear-gradient(
|
||||||
|
to right,
|
||||||
|
#fecaca,
|
||||||
|
#fef08a,
|
||||||
|
#bbf7d0,
|
||||||
|
#bfdbfe,
|
||||||
|
#e9d5ff,
|
||||||
|
#fbcfe8
|
||||||
|
);
|
||||||
color: #374151;
|
color: #374151;
|
||||||
}
|
}
|
||||||
|
|
||||||
Loading…
Reference in a new issue