anix/feat: add studio and source filters. add select all buttons to filters modal

This commit is contained in:
Kentai Radiquum 2025-08-28 04:47:51 +05:00
parent 777fb5b82b
commit 819d336540
Signed by: Radiquum
GPG key ID: 858E8EE696525EED
4 changed files with 136 additions and 24 deletions

View file

@ -398,7 +398,6 @@ export const FilterProfileListIdToString: Record<number, string> = {
5: "Брошено",
};
export const FilterStudio = [
"Неважно",
"A-1 Pictures",
"A.C.G.T",
"ACTAS, Inc",
@ -672,7 +671,7 @@ export type Filter = {
is_genres_exclude_mode_enabled: boolean;
profile_list_exclusions: number[];
types: number[]; // fetched from /type/all
studio: string[];
studio: null | string;
source: null | string;
start_year: null | number;
end_year: null | number;

View file

@ -30,6 +30,11 @@ export const FiltersGenreModal = ({
const [newGenres, setNewGenres] = useState(genres);
const [newExclusionMode, setNewExclusionMode] = useState(exclusionMode);
const genresLength =
FilterGenre.uncategorized.genres.length +
FilterGenre.audience.genres.length +
FilterGenre.theme.genres.length;
function toggleGenre(string: string) {
if (newGenres.includes(string)) {
setNewGenres(newGenres.filter((genre) => genre != string));
@ -44,7 +49,7 @@ export const FiltersGenreModal = ({
}, [genres, exclusionMode]);
return (
<Modal show={isOpen} onClose={() => setIsOpen(false)} dismissible>
<Modal show={isOpen} onClose={() => setIsOpen(false)} dismissible size="6xl">
<ModalHeader>Жанры</ModalHeader>
<ModalBody>
<div>
@ -116,6 +121,18 @@ export const FiltersGenreModal = ({
>
Применить
</Button>
<Button
onClick={() => {
if (newGenres.length != genresLength) {
setNewGenres(Object.entries(FilterGenre).map(([key, value]) => value.genres.map((genre) => genre)).flat());
} else {
setNewGenres([]);
}
}}
color="light"
>
{newGenres.length >= genresLength ? "Снять все" : "Выбрать все"}
</Button>
</div>
</div>
</ModalFooter>

View file

@ -8,7 +8,7 @@ import {
Modal,
ModalBody,
ModalFooter,
ModalHeader
ModalHeader,
} from "flowbite-react";
import { useEffect, useState } from "react";
@ -81,7 +81,27 @@ export const FiltersListExcludeModal = ({
>
Применить
</Button>
<Button
onClick={() => {
if (
newList.length != Object.keys(FilterProfileListIdToString).length
) {
setNewList(
Object.keys(FilterProfileListIdToString).map((key) =>
Number(key)
)
);
} else {
setNewList([]);
}
}}
color="light"
>
{newList.length >= Object.keys(FilterProfileListIdToString).length ?
"Снять все"
: "Выбрать все"}
</Button>
</ModalFooter>
</Modal>
);
}
};

View file

@ -6,6 +6,8 @@ import {
FilterCountry,
FilterDefault,
FilterProfileListIdToString,
FilterSource,
FilterStudio,
} from "#/api/utils";
import {
Button,
@ -131,23 +133,97 @@ export const FiltersModal = ({ isOpen, setIsOpen, filter }: ModalProps) => {
Рекомендуется выбирать не более 3 жанров
</p>
</div>
{userStore.isAuth ? <div className="space-y-2">
<p>Исключить закладки</p>
{userStore.isAuth ?
<div className="space-y-2">
<p>Исключить закладки</p>
<Button
color={"blue"}
className="w-full min-h-10 h-fit"
onClick={() => setIsListExcludeModalOpen(true)}
>
{newFilter.profile_list_exclusions.length > 0 ?
newFilter.profile_list_exclusions
.map((id) => FilterProfileListIdToString[id])
.join(", ")
: "Неважно"}
</Button>
<p className="text-sm">
Исключит из выдачи релизы, входящие в указанные закладки
</p>
</div>
: ""}
<div className="space-y-2">
<p>Варианты озвучек</p>
<Button
color={"blue"}
className="w-full min-h-10 h-fit"
onClick={() => setIsListExcludeModalOpen(true)}
// onClick={() => setIsGenreModalOpen(true)}
>
{newFilter.profile_list_exclusions.length > 0 ?
newFilter.profile_list_exclusions
.map((id) => FilterProfileListIdToString[id])
.join(", ")
: "Неважно"}
{/* {newFilter.genres.length > 0 ? */}
{/* newFilter.genres.join(", ") */}
{/* : "Неважно"} */}
</Button>
<p className="text-sm">
Исключит из выдачи релизы, входящие в указанные закладки
</p>
</div> : ""}
</div>
<div className="space-y-2">
<p>Студия</p>
<Dropdown
label={newFilter.studio ? newFilter.studio : "Неважно"}
color="blue"
className="w-full overflow-y-auto max-h-64"
>
<DropdownItem
key={`filter-modal-studio-none`}
onClick={() => setNewFilter({ ...newFilter, studio: null })}
>
Неважно
</DropdownItem>
{FilterStudio.map((value) => {
return (
<DropdownItem
key={`filter-modal-studio-${value}`}
onClick={() =>
setNewFilter({
...newFilter,
studio: value,
})
}
>
{value}
</DropdownItem>
);
})}
</Dropdown>
</div>
<div className="space-y-2">
<p>Первоисточник</p>
<Dropdown
label={newFilter.source ? newFilter.source : "Неважно"}
color="blue"
className="w-full overflow-y-auto max-h-64"
>
<DropdownItem
key={`filter-modal-source-none`}
onClick={() => setNewFilter({ ...newFilter, source: null })}
>
Неважно
</DropdownItem>
{FilterSource.map((value) => {
return (
<DropdownItem
key={`filter-modal-source-${value}`}
onClick={() =>
setNewFilter({
...newFilter,
source: value,
})
}
>
{value}
</DropdownItem>
);
})}
</Dropdown>
</div>
</div>
</ModalBody>
<ModalFooter></ModalFooter>
@ -160,13 +236,13 @@ export const FiltersModal = ({ isOpen, setIsOpen, filter }: ModalProps) => {
save={saveGenres}
/>
<FiltersListExcludeModal
isOpen={isListExcludeModalOpen}
setIsOpen={setIsListExcludeModalOpen}
lists={newFilter.profile_list_exclusions}
setLists={(profile_list_exclusions) =>
setNewFilter({ ...newFilter, profile_list_exclusions })
}
/>
isOpen={isListExcludeModalOpen}
setIsOpen={setIsListExcludeModalOpen}
lists={newFilter.profile_list_exclusions}
setLists={(profile_list_exclusions) =>
setNewFilter({ ...newFilter, profile_list_exclusions })
}
/>
</>
);
};