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">
|
||||
import { createQuery } from '@tanstack/svelte-query'
|
||||
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
|
||||
const seriesQuery = createQuery(() => entityQueries.weaponSeriesList())
|
||||
type SeriesType = 'weapons' | 'characters' | 'summons'
|
||||
|
||||
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>
|
||||
|
||||
<div class="database-page">
|
||||
<div class="grid-container">
|
||||
{#if seriesQuery.isPending}
|
||||
<div class="loading">Loading weapon series...</div>
|
||||
{:else if seriesQuery.error}
|
||||
<div class="error">Failed to load weapon series</div>
|
||||
{:else if seriesQuery.data}
|
||||
<nav class="series-nav" aria-label="Series type">
|
||||
<SegmentedControl bind:value={activeType} variant="blended" size="small">
|
||||
<Segment value="weapons">Weapons</Segment>
|
||||
<Segment value="characters">Characters</Segment>
|
||||
<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">
|
||||
<table>
|
||||
<thead>
|
||||
|
|
@ -23,28 +60,34 @@
|
|||
<th class="name">Name (EN)</th>
|
||||
<th class="name-ja">Name (JA)</th>
|
||||
<th class="slug">Slug</th>
|
||||
<th class="flags">Flags</th>
|
||||
{#if hasFlags}
|
||||
<th class="flags">Flags</th>
|
||||
{/if}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each seriesQuery.data.sort((a, b) => a.order - b.order) as series (series.id)}
|
||||
{#each sortedData as series (series.id)}
|
||||
<tr>
|
||||
<td class="order">{series.order}</td>
|
||||
<td class="name">{series.name.en}</td>
|
||||
<td class="name-ja">{series.name.ja}</td>
|
||||
<td class="slug"><code>{series.slug}</code></td>
|
||||
<td class="flags">
|
||||
{#if series.extra}<span class="flag extra">Extra</span>{/if}
|
||||
{#if series.elementChangeable}<span class="flag element">Element</span>{/if}
|
||||
{#if series.hasWeaponKeys}<span class="flag keys">Keys</span>{/if}
|
||||
{#if series.hasAwakening}<span class="flag awaken">Awaken</span>{/if}
|
||||
{#if series.hasAxSkills}<span class="flag ax">AX</span>{/if}
|
||||
</td>
|
||||
{#if hasFlags && 'extra' in series}
|
||||
<td class="flags">
|
||||
{#if series.extra}<span class="flag extra">Extra</span>{/if}
|
||||
{#if series.elementChangeable}<span class="flag element">Element</span>{/if}
|
||||
{#if series.hasWeaponKeys}<span class="flag keys">Keys</span>{/if}
|
||||
{#if series.hasAwakening}<span class="flag awaken">Awaken</span>{/if}
|
||||
{#if series.hasAxSkills}<span class="flag ax">AX</span>{/if}
|
||||
</td>
|
||||
{/if}
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="empty">No {activeType} series found</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -69,8 +112,17 @@
|
|||
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,
|
||||
.error {
|
||||
.error,
|
||||
.empty {
|
||||
padding: spacing.$unit-4x;
|
||||
text-align: center;
|
||||
color: colors.$grey-50;
|
||||
|
|
@ -100,8 +152,6 @@
|
|||
font-weight: typography.$medium;
|
||||
font-size: typography.$font-small;
|
||||
color: colors.$grey-40;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
td {
|
||||
|
|
@ -114,7 +164,7 @@
|
|||
}
|
||||
|
||||
.name {
|
||||
min-width: 280px;
|
||||
min-width: 200px;
|
||||
}
|
||||
|
||||
.name-ja {
|
||||
|
|
@ -144,7 +194,15 @@
|
|||
}
|
||||
|
||||
&.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;
|
||||
}
|
||||
|
||||
Loading…
Reference in a new issue