feat: add adult content filter and display in manga components #32

Merged
rov merged 1 commits from feat/adult into main 2026-04-09 17:54:39 -03:00
5 changed files with 30 additions and 2 deletions

View File

@ -222,9 +222,9 @@ export interface PageMangaImportJobDTO {
export interface PageableObject { export interface PageableObject {
offset?: number; offset?: number;
paged?: boolean;
pageNumber?: number; pageNumber?: number;
pageSize?: number; pageSize?: number;
paged?: boolean;
unpaged?: boolean; unpaged?: boolean;
sort?: SortObject; sort?: SortObject;
} }
@ -266,6 +266,7 @@ export interface MangaListDTO {
authors: string[]; authors: string[];
score: number; score: number;
favorite: boolean; favorite: boolean;
adult: boolean;
} }
export interface PageMangaListDTO { export interface PageMangaListDTO {
@ -318,6 +319,7 @@ export interface MangaDTO {
chapterCount: number; chapterCount: number;
favorite: boolean; favorite: boolean;
following: boolean; following: boolean;
adult: boolean;
} }
export interface MangaProviderDTO { export interface MangaProviderDTO {
@ -419,6 +421,7 @@ genreIds?: number[];
statuses?: string[]; statuses?: string[];
userFavorites?: boolean; userFavorites?: boolean;
score?: number; score?: number;
adult?: boolean;
/** /**
* Zero-based page index (0..N) * Zero-based page index (0..N)
* @minimum 0 * @minimum 0

View File

@ -3,10 +3,12 @@ import {
type ReactNode, type ReactNode,
useCallback, useCallback,
useContext, useContext,
useEffect,
useMemo, useMemo,
useState, useState,
} from "react"; } from "react";
import type { SortOption } from "@/features/home/components/SortDropdown.tsx"; import type { SortOption } from "@/features/home/components/SortDropdown.tsx";
import { useAuth } from "./AuthContext.tsx";
interface UIStateContextType { interface UIStateContextType {
/* Home Filter State */ /* Home Filter State */
@ -42,6 +44,8 @@ interface UIStateContextType {
const UIStateContext = createContext<UIStateContextType | undefined>(undefined); const UIStateContext = createContext<UIStateContextType | undefined>(undefined);
export const UIStateProvider = ({ children }: { children: ReactNode }) => { export const UIStateProvider = ({ children }: { children: ReactNode }) => {
const { isAuthenticated } = useAuth();
/* Home Filter State */ /* Home Filter State */
const [currentPage, setCurrentPage] = useState(1); const [currentPage, setCurrentPage] = useState(1);
const [selectedGenres, setSelectedGenres] = useState<number[]>([]); const [selectedGenres, setSelectedGenres] = useState<number[]>([]);
@ -53,6 +57,10 @@ export const UIStateProvider = ({ children }: { children: ReactNode }) => {
const [searchText, setSearchText] = useState(""); const [searchText, setSearchText] = useState("");
const [isSidebarOpen, setIsSidebarOpen] = useState(true); const [isSidebarOpen, setIsSidebarOpen] = useState(true);
useEffect(() => {
setShowAdultContent(isAuthenticated);
}, [isAuthenticated]);
/* Manga Provider Card State */ /* Manga Provider Card State */
const [expandedProviderIds, setExpandedProviderIds] = useState<number[]>([]); const [expandedProviderIds, setExpandedProviderIds] = useState<number[]>([]);

View File

@ -102,13 +102,21 @@ export const MangaCard = ({ manga, queryKey }: MangaCardProps) => {
isImageLoading ? "opacity-0" : "opacity-100", isImageLoading ? "opacity-0" : "opacity-100",
)} )}
/> />
<div className="absolute right-2 top-2"> <div className="absolute right-2 top-2 flex flex-col items-end gap-1">
<Badge <Badge
variant="secondary" variant="secondary"
className="border border-border/50 bg-background/80 text-foreground backdrop-blur-sm" className="border border-border/50 bg-background/80 text-foreground backdrop-blur-sm"
> >
{manga.status} {manga.status}
</Badge> </Badge>
{manga.adult && (
<Badge
variant="outline"
className="border-red-500/50 bg-red-500/10 text-red-500 text-[10px] px-1.5 py-0 backdrop-blur-sm"
>
18+
</Badge>
)}
</div> </div>
</Link> </Link>

View File

@ -56,6 +56,7 @@ const Home = () => {
genreIds: selectedGenres, genreIds: selectedGenres,
userFavorites, userFavorites,
score: minRating, score: minRating,
adult: showAdultContent,
}); });
const isFiltersDisabled = isFetching; const isFiltersDisabled = isFetching;

View File

@ -277,6 +277,14 @@ const Manga = () => {
> >
{mangaData.data?.status} {mangaData.data?.status}
</Badge> </Badge>
{mangaData.data?.adult && (
<Badge
variant="outline"
className="border-red-500/50 bg-red-500/10 text-red-500"
>
18+
</Badge>
)}
{isAuthenticated && ( {isAuthenticated && (
<> <>