managarten/packages/help/src/components/FAQSection.svelte
Till JS da03fac722 fix(mana/web+packages): clear all 270 warnings to zero
Comprehensive warning sweep across 128 files that brings svelte-check
from 270 warnings → 0 (plus 3 new errors from concurrent upstream
changes fixed inline).

Final state: 6473 files, 0 errors, 0 warnings, 0 files with problems.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 17:34:49 +02:00

109 lines
3.4 KiB
Svelte

<script lang="ts">
import type { FAQItem, FAQCategory } from '../content';
import type { FAQSectionProps } from '../ui-types';
import FAQItemComponent from './FAQItem.svelte';
let {
items,
translations,
showCategories = true,
maxItems,
expandFirst = false,
}: FAQSectionProps = $props();
// svelte-ignore state_referenced_locally
let expandedId = $state<string | null>(expandFirst && items.length > 0 ? items[0].id : null);
let selectedCategory = $state<FAQCategory | 'all'>('all');
let showAll = $state(false);
// Derive categories from actual items instead of hardcoding
const categories = $derived([...new Set(items.map((item) => item.category))] as FAQCategory[]);
const filteredItems = $derived(() => {
let result = items;
if (selectedCategory !== 'all') {
result = result.filter((item) => item.category === selectedCategory);
}
if (maxItems && !showAll) {
result = result.slice(0, maxItems);
}
return result;
});
const hasMore = $derived(maxItems ? items.length > maxItems && !showAll : false);
function toggleItem(id: string) {
expandedId = expandedId === id ? null : id;
}
function getCategoryLabel(category: FAQCategory): string {
return translations.faq.categories[category] ?? category;
}
</script>
<div class="space-y-4">
{#if showCategories && items.length > 0}
<div class="flex flex-wrap gap-2">
<button
type="button"
class="rounded-full px-3 py-1.5 text-sm font-medium transition-colors"
class:bg-primary-100={selectedCategory === 'all'}
class:text-primary-700={selectedCategory === 'all'}
class:dark:bg-primary-900={selectedCategory === 'all'}
class:dark:text-primary-300={selectedCategory === 'all'}
class:bg-gray-100={selectedCategory !== 'all'}
class:text-gray-600={selectedCategory !== 'all'}
class:dark:bg-gray-800={selectedCategory !== 'all'}
class:dark:text-gray-400={selectedCategory !== 'all'}
onclick={() => (selectedCategory = 'all')}
>
{translations.faq.allCategories}
</button>
{#each categories as category}
<button
type="button"
class="rounded-full px-3 py-1.5 text-sm font-medium transition-colors"
class:bg-primary-100={selectedCategory === category}
class:text-primary-700={selectedCategory === category}
class:dark:bg-primary-900={selectedCategory === category}
class:dark:text-primary-300={selectedCategory === category}
class:bg-gray-100={selectedCategory !== category}
class:text-gray-600={selectedCategory !== category}
class:dark:bg-gray-800={selectedCategory !== category}
class:dark:text-gray-400={selectedCategory !== category}
onclick={() => (selectedCategory = category)}
>
{getCategoryLabel(category)}
</button>
{/each}
</div>
{/if}
{#if filteredItems().length === 0}
<p class="py-8 text-center text-gray-500 dark:text-gray-400">
{translations.faq.noItems}
</p>
{:else}
<div class="divide-y divide-gray-200 dark:divide-gray-700">
{#each filteredItems() as item (item.id)}
<FAQItemComponent
{item}
expanded={expandedId === item.id}
onToggle={() => toggleItem(item.id)}
/>
{/each}
</div>
{/if}
{#if hasMore}
<div class="pt-4 text-center">
<button
type="button"
class="text-primary-600 dark:text-primary-400 text-sm font-medium hover:underline"
onclick={() => (showAll = true)}
>
{translations.common.showMore}
</button>
</div>
{/if}
</div>