feat: add arc filter functionality to character selection
All checks were successful
Build Docker Image / build (push) Successful in 1m12s
All checks were successful
Build Docker Image / build (push) Successful in 1m12s
This commit is contained in:
@@ -31,7 +31,8 @@
|
|||||||
hasDevilFruit: null as boolean | null, // null = all, true = with fruit, false = without fruit
|
hasDevilFruit: null as boolean | null, // null = all, true = with fruit, false = without fruit
|
||||||
status: [] as string[],
|
status: [] as string[],
|
||||||
hasHeight: false,
|
hasHeight: false,
|
||||||
hasOrigin: false
|
hasOrigin: false,
|
||||||
|
arcs: [] as string[]
|
||||||
};
|
};
|
||||||
|
|
||||||
let wasOriginAvailable = false;
|
let wasOriginAvailable = false;
|
||||||
@@ -66,6 +67,10 @@
|
|||||||
if (storedFilters) {
|
if (storedFilters) {
|
||||||
try {
|
try {
|
||||||
characterFilters = JSON.parse(storedFilters);
|
characterFilters = JSON.parse(storedFilters);
|
||||||
|
// Ensure all filter properties exist
|
||||||
|
if (!characterFilters.arcs) {
|
||||||
|
characterFilters.arcs = [];
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Failed to parse filters', e);
|
console.error('Failed to parse filters', e);
|
||||||
}
|
}
|
||||||
@@ -131,6 +136,16 @@
|
|||||||
|
|
||||||
$: allCharacters = data.characters || [];
|
$: allCharacters = data.characters || [];
|
||||||
|
|
||||||
|
// Extract unique arcs from all characters
|
||||||
|
$: availableArcs = [
|
||||||
|
...new Map(
|
||||||
|
allCharacters
|
||||||
|
.filter((char: any) => char.arcId && char.arcName)
|
||||||
|
.map((char: any) => [char.arcId, { id: char.arcId, name: char.arcName }])
|
||||||
|
).values()
|
||||||
|
]
|
||||||
|
.sort((a: any, b: any) => (a.name || '').localeCompare(b.name || ''));
|
||||||
|
|
||||||
// Filter characters based on selected filters
|
// Filter characters based on selected filters
|
||||||
$: characters = allCharacters.filter((char: any) => {
|
$: characters = allCharacters.filter((char: any) => {
|
||||||
// Gender filter
|
// Gender filter
|
||||||
@@ -166,6 +181,11 @@
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Arc filter
|
||||||
|
if (characterFilters.arcs.length > 0 && !characterFilters.arcs.includes(char.arcId)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
$: hasWon = currentCharacter && selectedCharacters.some(char => char.id === currentCharacter.id);
|
$: hasWon = currentCharacter && selectedCharacters.some(char => char.id === currentCharacter.id);
|
||||||
@@ -310,6 +330,18 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toggleArcFilter(arcId: string) {
|
||||||
|
if (characterFilters.arcs.includes(arcId)) {
|
||||||
|
characterFilters.arcs = characterFilters.arcs.filter(a => a !== arcId);
|
||||||
|
} else {
|
||||||
|
characterFilters.arcs = [...characterFilters.arcs, arcId];
|
||||||
|
}
|
||||||
|
// Regenerate character with new filters
|
||||||
|
if (!hasWon) {
|
||||||
|
generateNewCharacter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function clearAllFilters() {
|
function clearAllFilters() {
|
||||||
characterFilters = {
|
characterFilters = {
|
||||||
gender: [],
|
gender: [],
|
||||||
@@ -317,7 +349,8 @@
|
|||||||
hasDevilFruit: null,
|
hasDevilFruit: null,
|
||||||
status: [],
|
status: [],
|
||||||
hasHeight: false,
|
hasHeight: false,
|
||||||
hasOrigin: false
|
hasOrigin: false,
|
||||||
|
arcs: []
|
||||||
};
|
};
|
||||||
// Regenerate character with new filters
|
// Regenerate character with new filters
|
||||||
if (!hasWon) {
|
if (!hasWon) {
|
||||||
@@ -488,7 +521,7 @@
|
|||||||
<div class="rounded-2xl border border-white/10 bg-white/5 p-3 sm:p-4 backdrop-blur">
|
<div class="rounded-2xl border border-white/10 bg-white/5 p-3 sm:p-4 backdrop-blur">
|
||||||
<div class="mb-3 flex items-center justify-between gap-3">
|
<div class="mb-3 flex items-center justify-between gap-3">
|
||||||
<h3 class="text-xs font-semibold uppercase tracking-[0.2em] text-amber-200">Filtres de personnages</h3>
|
<h3 class="text-xs font-semibold uppercase tracking-[0.2em] text-amber-200">Filtres de personnages</h3>
|
||||||
{#if characterFilters.gender.length > 0 || characterFilters.hasHaki || characterFilters.hasDevilFruit !== null || characterFilters.status.length > 0 || characterFilters.hasHeight || characterFilters.hasOrigin}
|
{#if characterFilters.gender.length > 0 || characterFilters.hasHaki || characterFilters.hasDevilFruit !== null || characterFilters.status.length > 0 || characterFilters.hasHeight || characterFilters.hasOrigin || characterFilters.arcs.length > 0}
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onclick={clearAllFilters}
|
onclick={clearAllFilters}
|
||||||
@@ -588,6 +621,24 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Arc Filter -->
|
||||||
|
<div>
|
||||||
|
<p class="text-xs text-slate-400 mb-2">Arcs</p>
|
||||||
|
<div class="flex flex-wrap gap-2">
|
||||||
|
{#each availableArcs as arc (arc.id)}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onclick={() => toggleArcFilter(arc.id)}
|
||||||
|
class="rounded-full border px-2.5 py-1 text-xs font-medium transition-colors {characterFilters.arcs.includes(arc.id)
|
||||||
|
? 'border-amber-300/50 bg-amber-300/10 text-amber-100 hover:bg-amber-300/20'
|
||||||
|
: 'border-white/20 bg-slate-900/40 text-slate-400 hover:bg-slate-900/60'}"
|
||||||
|
>
|
||||||
|
{arc.name}
|
||||||
|
</button>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<p class="text-xs text-slate-500 mt-2">
|
<p class="text-xs text-slate-500 mt-2">
|
||||||
{characters.length} personnage{characters.length > 1 ? 's' : ''} disponible{characters.length > 1 ? 's' : ''}
|
{characters.length} personnage{characters.length > 1 ? 's' : ''} disponible{characters.length > 1 ? 's' : ''}
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
Reference in New Issue
Block a user