hensei-web/src/lib/components/raid/RaidGroupList.svelte

95 lines
2.4 KiB
Svelte

<script lang="ts">
/**
* RaidGroupList - Scrollable list of raid groups
*
* Filters and displays raid groups with search support.
* Each group is rendered using RaidGroupItem.
*/
import type { RaidGroupFull, RaidFull } from '$lib/types/api/raid'
import RaidGroupItem from './RaidGroupItem.svelte'
interface Props {
groups: RaidGroupFull[]
selectedRaidId?: string
onSelect: (raid: RaidFull) => void
searchQuery?: string
}
let { groups, selectedRaidId, onSelect, searchQuery = '' }: Props = $props()
function getRaidName(raid: RaidFull): string {
if (typeof raid.name === 'string') return raid.name
const en = raid.name?.en || ''
const ja = raid.name?.ja || ''
return `${en} ${ja}`.toLowerCase()
}
function getGroupName(group: RaidGroupFull): string {
if (typeof group.name === 'string') return group.name
const en = group.name?.en || ''
const ja = group.name?.ja || ''
return `${en} ${ja}`.toLowerCase()
}
// Filter groups and their raids based on search query
const filteredGroups = $derived(() => {
if (!searchQuery.trim()) return groups
const query = searchQuery.toLowerCase().trim()
return groups
.map((group) => {
// Check if group name matches
const groupMatches = getGroupName(group).includes(query)
// Filter raids within the group
const matchingRaids = group.raids.filter((raid) => getRaidName(raid).includes(query))
// Include group if it matches or has matching raids
if (groupMatches) {
return group // Return full group if group name matches
} else if (matchingRaids.length > 0) {
return { ...group, raids: matchingRaids }
}
return null
})
.filter((group): group is RaidGroupFull => group !== null)
})
const hasResults = $derived(filteredGroups().length > 0)
</script>
<div class="raid-group-list">
{#if hasResults}
{#each filteredGroups() as group (group.id)}
<RaidGroupItem {group} {selectedRaidId} {onSelect} />
{/each}
{:else}
<div class="empty-state">
<span class="empty-text">No raids found</span>
</div>
{/if}
</div>
<style lang="scss">
@use '$src/themes/spacing' as *;
@use '$src/themes/typography' as *;
.raid-group-list {
display: flex;
flex-direction: column;
}
.empty-state {
display: flex;
align-items: center;
justify-content: center;
padding: $unit-4x;
}
.empty-text {
font-size: $font-regular;
color: var(--text-tertiary);
font-style: italic;
}
</style>