Skip to content

Commit

Permalink
feat(costumes): characters filters
Browse files Browse the repository at this point in the history
  • Loading branch information
KeziahMoselle committed Jan 20, 2023
1 parent 188ab05 commit 6942655
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 7 deletions.
130 changes: 123 additions & 7 deletions src/components/pages/costumes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ interface CharactersPageProps {
costumes: ICostume[];
abilitiesLookup;
charactersLookup;
characters: character[];
}

export const weaponTypesLookup = {
Expand Down Expand Up @@ -93,10 +94,21 @@ function filterCostumesBySkill(costumes: ICostume[], filters) {
return filteredCostumes;
}

function filterCostumesByCharacter(costumes: ICostume[], filters: character[]) {
if (filters.length === 0) return costumes;

const charactersIds = filters.map((character) => character.character_id);

return costumes.filter((costume) =>
charactersIds.includes(costume.character_id)
);
}

export default function CharactersPage({
costumes,
abilitiesLookup,
charactersLookup,
characters,
}: CharactersPageProps): JSX.Element {
const showUnreleasedContent = useSettingsStore(
(state) => state.showUnreleasedContent
Expand All @@ -109,6 +121,7 @@ export default function CharactersPage({
return ownedCostumes.includes(cost.costume_id);
});
const skills = useCostumesFilters((state) => state.skills);
const filteredCharacters = useCostumesFilters((state) => state.characters);

/**
* Using a state and useEffect here because Next.js is
Expand Down Expand Up @@ -144,7 +157,10 @@ export default function CharactersPage({
)}
>
<DatabaseNavbar>
<CostumesFilters />
<div className="flex flex-col items-center md:flex-row gap-2">
<CostumesCharactersFilters characters={characters} />
<CostumesSkillsFilters />
</div>
</DatabaseNavbar>

{showInventory && ownedCostumes.length === 0 && (
Expand All @@ -164,8 +180,17 @@ export default function CharactersPage({
<CostumesTable
costumes={
showInventory
? filterCostumesBySkill(inventoryCostumes, skills)
: filterCostumesBySkill(costumes, skills)
? filterCostumesBySkill(
filterCostumesByCharacter(
inventoryCostumes,
filteredCharacters
),
skills
)
: filterCostumesBySkill(
filterCostumesByCharacter(costumes, filteredCharacters),
skills
)
}
abilitiesLookup={abilitiesLookup}
charactersLookup={charactersLookup}
Expand All @@ -177,8 +202,17 @@ export default function CharactersPage({
<CostumesGrid
costumes={
showInventory
? filterCostumesBySkill(inventoryCostumes, skills)
: filterCostumesBySkill(costumes, skills)
? filterCostumesBySkill(
filterCostumesByCharacter(
inventoryCostumes,
filteredCharacters
),
skills
)
: filterCostumesBySkill(
filterCostumesByCharacter(costumes, filteredCharacters),
skills
)
}
abilitiesLookup={abilitiesLookup}
charactersLookup={charactersLookup}
Expand Down Expand Up @@ -695,7 +729,7 @@ export function CostumesGrid({
);
}

export function CostumesFilters() {
export function CostumesSkillsFilters() {
const [isOpen, setIsOpen] = useState(false);

const skills = useCostumesFilters((state) => state.skills);
Expand All @@ -707,7 +741,12 @@ export function CostumesFilters() {
variant={skills.length > 0 ? "contained" : "outlined"}
onClick={() => setIsOpen(true)}
component="label"
startIcon={<MdFilterAlt size={20} />}
startIcon={
<SVG
src="/decorations/frame-ability.svg"
className="h-4 w-auto transform rotate-45"
/>
}
>
{(skills.length > 0 && (
<span>
Expand Down Expand Up @@ -747,3 +786,80 @@ export function CostumesFilters() {
</div>
);
}

export function CostumesCharactersFilters({
characters,
}: {
characters: character[];
}) {
const [isOpen, setIsOpen] = useState(false);

const filteredCharacters = useCostumesFilters((state) => state.characters);
const toggleCharacter = useCostumesFilters((state) => state.toggleCharacter);

return (
<div>
<Button
variant={filteredCharacters.length > 0 ? "contained" : "outlined"}
onClick={() => setIsOpen(true)}
component="label"
startIcon={
<img
className="h-5 w-auto"
height="20"
src="https://assets.nierrein.guide/ui/actor/ch019001/ch019001_01_actor_icon.png"
alt="Filter by Character"
/>
}
>
{(filteredCharacters.length > 0 && (
<span>
Characters: {filteredCharacters.map((ch) => ch.name).join(", ")}
</span>
)) || <span>Filter by Characters</span>}
</Button>
<Modal
open={isOpen}
onClose={() => setIsOpen(false)}
aria-labelledby="modal-modal-title"
aria-describedby="modal-modal-description"
>
<div className="bg-grey-dark p-8 absolute bordered top-0 left-0 md:top-1/2 md:left-1/2 transform md:-translate-x-1/2 md:-translate-y-1/2 w-full md:max-w-3xl space-y-8 overflow-y-auto pt-12 md:pt-8">
<div className="flex items-center justify-between mb-4">
<div>
<h3 className="flex items-center gap-x-2 text-2xl">
<MdFilterAlt /> Filter costumes by Character
</h3>
</div>
<button className="btn" onClick={() => setIsOpen(false)}>
Close
</button>
</div>
<div className="grid grid-cols-2 md:grid-cols-3 gap-4">
{characters.map((character) => (
<div
key={character.character_id}
className="flex gap-x-2 items-center"
>
<img
height="36"
width="32"
className="h-auto w-8"
src={`${CDN_URL}${character.image_path}`}
alt={character.name}
/>
<Checkbox
label={character.name}
isChecked={filteredCharacters.some(
(ch) => ch.name === character.name
)}
setState={() => toggleCharacter(character)}
/>
</div>
))}
</div>
</div>
</Modal>
</div>
);
}
8 changes: 8 additions & 0 deletions src/pages/characters/[[...costume]].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ export default function CharactersPage({
costumes={costumes}
abilitiesLookup={abilitiesLookup}
charactersLookup={charactersLookup}
characters={characters}
/>
);
}
Expand All @@ -100,6 +101,12 @@ export async function getStaticProps(context) {
},
});

const characters = await prisma.dump.character.findMany({
orderBy: {
character_id: "asc",
},
});

return {
props: JSON.parse(
JSON.stringify({
Expand All @@ -109,6 +116,7 @@ export async function getStaticProps(context) {
costumes,
abilitiesLookup,
charactersLookup,
characters,
})
),
};
Expand Down
16 changes: 16 additions & 0 deletions src/store/costumes-filters.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import produce from 'immer';
import create from 'zustand';

export const useCostumesFilters = create((set) => ({
characters: [],
skills: [],
toggleSkill: (skill) =>
set((state) => {
Expand All @@ -18,4 +19,19 @@ export const useCostumesFilters = create((set) => ({
skills: newSkills
};
}),
toggleCharacter: (character) =>
set((state) => {
const newCharacters = produce(state.characters, (draft) => {
const index = draft.findIndex((ch) => ch.name === character.name)
if (index > -1) {
draft.splice(index, 1);
} else {
draft.push(character);
}
});

return {
characters: newCharacters
};
}),
}));

0 comments on commit 6942655

Please sign in to comment.