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

View File

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

View File

@ -102,13 +102,21 @@ export const MangaCard = ({ manga, queryKey }: MangaCardProps) => {
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
variant="secondary"
className="border border-border/50 bg-background/80 text-foreground backdrop-blur-sm"
>
{manga.status}
</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>
</Link>

View File

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

View File

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