chore: update various components and services for improved functionality and consistency, including formatting adjustments and minor refactors
This commit is contained in:
@@ -4,7 +4,7 @@ import { UserService } from "@/lib/services/user.service";
|
||||
import { redirect } from "next/navigation";
|
||||
import logger from "@/lib/logger";
|
||||
|
||||
export const dynamic = 'force-dynamic';
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
export default async function AccountPage() {
|
||||
try {
|
||||
|
||||
@@ -4,12 +4,12 @@ import { isAdmin } from "@/lib/auth-utils";
|
||||
import { AdminContent } from "@/components/admin/AdminContent";
|
||||
import logger from "@/lib/logger";
|
||||
|
||||
export const dynamic = 'force-dynamic';
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
export default async function AdminPage() {
|
||||
try {
|
||||
const hasAdminAccess = await isAdmin();
|
||||
|
||||
|
||||
if (!hasAdminAccess) {
|
||||
redirect("/");
|
||||
}
|
||||
|
||||
@@ -13,9 +13,13 @@ export async function GET() {
|
||||
if (error instanceof AppError) {
|
||||
return NextResponse.json(
|
||||
{ error: error.message, code: error.code },
|
||||
{
|
||||
status: error.code === "AUTH_FORBIDDEN" ? 403 :
|
||||
error.code === "AUTH_UNAUTHENTICATED" ? 401 : 500
|
||||
{
|
||||
status:
|
||||
error.code === "AUTH_FORBIDDEN"
|
||||
? 403
|
||||
: error.code === "AUTH_UNAUTHENTICATED"
|
||||
? 401
|
||||
: 500,
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -26,4 +30,3 @@ export async function GET() {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,17 +14,14 @@ export async function PUT(
|
||||
const { newPassword } = body;
|
||||
|
||||
if (!newPassword) {
|
||||
return NextResponse.json(
|
||||
{ error: "Nouveau mot de passe manquant" },
|
||||
{ status: 400 }
|
||||
);
|
||||
return NextResponse.json({ error: "Nouveau mot de passe manquant" }, { status: 400 });
|
||||
}
|
||||
|
||||
// Vérifier que le mot de passe est fort
|
||||
if (!AuthServerService.isPasswordStrong(newPassword)) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: "Le mot de passe doit contenir au moins 8 caractères, une majuscule et un chiffre"
|
||||
{
|
||||
error: "Le mot de passe doit contenir au moins 8 caractères, une majuscule et un chiffre",
|
||||
},
|
||||
{ status: 400 }
|
||||
);
|
||||
@@ -39,11 +36,17 @@ export async function PUT(
|
||||
if (error instanceof AppError) {
|
||||
return NextResponse.json(
|
||||
{ error: error.message, code: error.code },
|
||||
{
|
||||
status: error.code === "AUTH_FORBIDDEN" ? 403 :
|
||||
error.code === "AUTH_UNAUTHENTICATED" ? 401 :
|
||||
error.code === "AUTH_USER_NOT_FOUND" ? 404 :
|
||||
error.code === "ADMIN_CANNOT_RESET_OWN_PASSWORD" ? 400 : 500
|
||||
{
|
||||
status:
|
||||
error.code === "AUTH_FORBIDDEN"
|
||||
? 403
|
||||
: error.code === "AUTH_UNAUTHENTICATED"
|
||||
? 401
|
||||
: error.code === "AUTH_USER_NOT_FOUND"
|
||||
? 404
|
||||
: error.code === "ADMIN_CANNOT_RESET_OWN_PASSWORD"
|
||||
? 400
|
||||
: 500,
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -54,4 +57,3 @@ export async function PUT(
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,10 +13,7 @@ export async function PATCH(
|
||||
const { roles } = body;
|
||||
|
||||
if (!roles || !Array.isArray(roles)) {
|
||||
return NextResponse.json(
|
||||
{ error: "Rôles invalides" },
|
||||
{ status: 400 }
|
||||
);
|
||||
return NextResponse.json({ error: "Rôles invalides" }, { status: 400 });
|
||||
}
|
||||
|
||||
await AdminService.updateUserRoles(userId, roles);
|
||||
@@ -28,10 +25,15 @@ export async function PATCH(
|
||||
if (error instanceof AppError) {
|
||||
return NextResponse.json(
|
||||
{ error: error.message, code: error.code },
|
||||
{
|
||||
status: error.code === "AUTH_FORBIDDEN" ? 403 :
|
||||
error.code === "AUTH_UNAUTHENTICATED" ? 401 :
|
||||
error.code === "AUTH_USER_NOT_FOUND" ? 404 : 500
|
||||
{
|
||||
status:
|
||||
error.code === "AUTH_FORBIDDEN"
|
||||
? 403
|
||||
: error.code === "AUTH_UNAUTHENTICATED"
|
||||
? 401
|
||||
: error.code === "AUTH_USER_NOT_FOUND"
|
||||
? 404
|
||||
: 500,
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -58,11 +60,17 @@ export async function DELETE(
|
||||
if (error instanceof AppError) {
|
||||
return NextResponse.json(
|
||||
{ error: error.message, code: error.code },
|
||||
{
|
||||
status: error.code === "AUTH_FORBIDDEN" ? 403 :
|
||||
error.code === "AUTH_UNAUTHENTICATED" ? 401 :
|
||||
error.code === "AUTH_USER_NOT_FOUND" ? 404 :
|
||||
error.code === "ADMIN_CANNOT_DELETE_SELF" ? 400 : 500
|
||||
{
|
||||
status:
|
||||
error.code === "AUTH_FORBIDDEN"
|
||||
? 403
|
||||
: error.code === "AUTH_UNAUTHENTICATED"
|
||||
? 401
|
||||
: error.code === "AUTH_USER_NOT_FOUND"
|
||||
? 404
|
||||
: error.code === "ADMIN_CANNOT_DELETE_SELF"
|
||||
? 400
|
||||
: 500,
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -73,4 +81,3 @@ export async function DELETE(
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,9 +13,13 @@ export async function GET() {
|
||||
if (error instanceof AppError) {
|
||||
return NextResponse.json(
|
||||
{ error: error.message, code: error.code },
|
||||
{
|
||||
status: error.code === "AUTH_FORBIDDEN" ? 403 :
|
||||
error.code === "AUTH_UNAUTHENTICATED" ? 401 : 500
|
||||
{
|
||||
status:
|
||||
error.code === "AUTH_FORBIDDEN"
|
||||
? 403
|
||||
: error.code === "AUTH_UNAUTHENTICATED"
|
||||
? 401
|
||||
: 500,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
import { handlers } from "@/lib/auth";
|
||||
|
||||
export const { GET, POST } = handlers;
|
||||
export const { GET, POST } = handlers;
|
||||
|
||||
@@ -44,10 +44,10 @@ export async function GET(
|
||||
return { buffer, contentType };
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
// Cloner le buffer pour cette requête pour éviter tout partage de référence
|
||||
const clonedBuffer = buffer.slice(0);
|
||||
|
||||
|
||||
const headers = new Headers();
|
||||
headers.set("Content-Type", contentType);
|
||||
headers.set("Cache-Control", "public, max-age=31536000"); // Cache for 1 year
|
||||
|
||||
@@ -16,7 +16,7 @@ export async function GET(
|
||||
|
||||
const data: KomgaBookWithPages = await BookService.getBook(bookId);
|
||||
const nextBook = await BookService.getNextBook(bookId, data.book.seriesId);
|
||||
|
||||
|
||||
return NextResponse.json({ ...data, nextBook });
|
||||
} catch (error) {
|
||||
logger.error({ err: error }, "API Books - Erreur:");
|
||||
|
||||
4
src/app/api/komga/cache/clear/route.ts
vendored
4
src/app/api/komga/cache/clear/route.ts
vendored
@@ -10,13 +10,13 @@ export async function POST() {
|
||||
try {
|
||||
const cacheService: ServerCacheService = await getServerCacheService();
|
||||
await cacheService.clear();
|
||||
|
||||
|
||||
// Revalider toutes les pages importantes après le vidage du cache
|
||||
revalidatePath("/");
|
||||
revalidatePath("/libraries");
|
||||
revalidatePath("/series");
|
||||
revalidatePath("/books");
|
||||
|
||||
|
||||
return NextResponse.json({ message: "🧹 Cache vidé avec succès" });
|
||||
} catch (error) {
|
||||
logger.error({ err: error }, "Erreur lors de la suppression du cache:");
|
||||
|
||||
3
src/app/api/komga/cache/entries/route.ts
vendored
3
src/app/api/komga/cache/entries/route.ts
vendored
@@ -9,7 +9,7 @@ export async function GET() {
|
||||
try {
|
||||
const cacheService: ServerCacheService = await getServerCacheService();
|
||||
const entries = await cacheService.getCacheEntries();
|
||||
|
||||
|
||||
return NextResponse.json({ entries });
|
||||
} catch (error) {
|
||||
logger.error({ err: error }, "Erreur lors de la récupération des entrées du cache");
|
||||
@@ -25,4 +25,3 @@ export async function GET() {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
9
src/app/api/komga/cache/size/route.ts
vendored
9
src/app/api/komga/cache/size/route.ts
vendored
@@ -9,11 +9,11 @@ export async function GET() {
|
||||
try {
|
||||
const cacheService: ServerCacheService = await getServerCacheService();
|
||||
const { sizeInBytes, itemCount } = await cacheService.getCacheSize();
|
||||
|
||||
return NextResponse.json({
|
||||
sizeInBytes,
|
||||
|
||||
return NextResponse.json({
|
||||
sizeInBytes,
|
||||
itemCount,
|
||||
mode: cacheService.getCacheMode()
|
||||
mode: cacheService.getCacheMode(),
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error({ err: error }, "Erreur lors de la récupération de la taille du cache:");
|
||||
@@ -29,4 +29,3 @@ export async function GET() {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,10 +10,10 @@ import logger from "@/lib/logger";
|
||||
export async function GET() {
|
||||
try {
|
||||
const favoriteIds: string[] = await FavoriteService.getAllFavoriteIds();
|
||||
|
||||
|
||||
// Valider que chaque série existe encore dans Komga
|
||||
const validFavoriteIds: string[] = [];
|
||||
|
||||
|
||||
for (const seriesId of favoriteIds) {
|
||||
try {
|
||||
await SeriesService.getSeries(seriesId);
|
||||
@@ -27,7 +27,7 @@ export async function GET() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return NextResponse.json(validFavoriteIds);
|
||||
} catch (error) {
|
||||
if (error instanceof AppError) {
|
||||
|
||||
@@ -67,4 +67,3 @@ export async function DELETE() {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,10 +20,10 @@ export async function GET(
|
||||
return response;
|
||||
} catch (error) {
|
||||
logger.error({ err: error }, "Erreur lors de la récupération de la page du livre:");
|
||||
|
||||
|
||||
// Chercher un status HTTP 404 dans la chaîne d'erreurs
|
||||
const httpStatus = findHttpStatus(error);
|
||||
|
||||
|
||||
if (httpStatus === 404) {
|
||||
const { bookId, pageNumber } = await params;
|
||||
// eslint-disable-next-line no-console
|
||||
@@ -39,7 +39,7 @@ export async function GET(
|
||||
{ status: 404 }
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
if (error instanceof AppError) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
|
||||
@@ -34,10 +34,10 @@ export async function GET(
|
||||
return response;
|
||||
} catch (error) {
|
||||
logger.error({ err: error }, "Erreur lors de la récupération de la miniature de la page:");
|
||||
|
||||
|
||||
// Chercher un status HTTP 404 dans la chaîne d'erreurs
|
||||
const httpStatus = findHttpStatus(error);
|
||||
|
||||
|
||||
if (httpStatus === 404) {
|
||||
const { bookId, pageNumber: pageNumberParam } = await params;
|
||||
const pageNumber: number = parseInt(pageNumberParam);
|
||||
@@ -54,7 +54,7 @@ export async function GET(
|
||||
{ status: 404 }
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
if (error instanceof AppError) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
|
||||
@@ -18,10 +18,10 @@ export async function GET(
|
||||
return response;
|
||||
} catch (error) {
|
||||
logger.error({ err: error }, "Erreur lors de la récupération de la miniature du livre:");
|
||||
|
||||
|
||||
// Chercher un status HTTP 404 dans la chaîne d'erreurs
|
||||
const httpStatus = findHttpStatus(error);
|
||||
|
||||
|
||||
if (httpStatus === 404) {
|
||||
const bookId: string = (await params).bookId;
|
||||
// eslint-disable-next-line no-console
|
||||
@@ -37,7 +37,7 @@ export async function GET(
|
||||
{ status: 404 }
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
if (error instanceof AppError) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
|
||||
@@ -20,10 +20,10 @@ export async function GET(
|
||||
return response;
|
||||
} catch (error) {
|
||||
logger.error({ err: error }, "Erreur lors de la récupération de la couverture de la série:");
|
||||
|
||||
|
||||
// Chercher un status HTTP 404 dans la chaîne d'erreurs
|
||||
const httpStatus = findHttpStatus(error);
|
||||
|
||||
|
||||
if (httpStatus === 404) {
|
||||
const seriesId: string = (await params).seriesId;
|
||||
// eslint-disable-next-line no-console
|
||||
@@ -39,7 +39,7 @@ export async function GET(
|
||||
{ status: 404 }
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
if (error instanceof AppError) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
|
||||
@@ -17,10 +17,10 @@ export async function GET(
|
||||
return response;
|
||||
} catch (error) {
|
||||
logger.error({ err: error }, "Erreur lors de la récupération de la miniature de la série");
|
||||
|
||||
|
||||
// Chercher un status HTTP 404 dans la chaîne d'erreurs
|
||||
const httpStatus = findHttpStatus(error);
|
||||
|
||||
|
||||
if (httpStatus === 404) {
|
||||
const seriesId: string = (await params).seriesId;
|
||||
logger.info(`📷 Image not found for series: ${seriesId}`);
|
||||
@@ -35,7 +35,7 @@ export async function GET(
|
||||
{ status: 404 }
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
if (error instanceof AppError) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
|
||||
@@ -12,7 +12,7 @@ export async function POST(
|
||||
) {
|
||||
try {
|
||||
const libraryId: string = (await params).libraryId;
|
||||
|
||||
|
||||
// Scan library with deep=false
|
||||
await LibraryService.scanLibrary(libraryId, false);
|
||||
|
||||
@@ -43,4 +43,3 @@ export async function POST(
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ export async function GET(
|
||||
try {
|
||||
const libraryId: string = (await params).libraryId;
|
||||
const searchParams = request.nextUrl.searchParams;
|
||||
|
||||
|
||||
const page = parseInt(searchParams.get("page") || "0");
|
||||
const size = parseInt(searchParams.get("size") || String(DEFAULT_PAGE_SIZE));
|
||||
const unreadOnly = searchParams.get("unread") === "true";
|
||||
@@ -24,15 +24,15 @@ export async function GET(
|
||||
|
||||
const [series, library] = await Promise.all([
|
||||
LibraryService.getLibrarySeries(libraryId, page, size, unreadOnly, search),
|
||||
LibraryService.getLibrary(libraryId)
|
||||
LibraryService.getLibrary(libraryId),
|
||||
]);
|
||||
|
||||
return NextResponse.json(
|
||||
{ series, library },
|
||||
{
|
||||
headers: {
|
||||
'Cache-Control': 'public, s-maxage=60, stale-while-revalidate=120'
|
||||
}
|
||||
"Cache-Control": "public, s-maxage=60, stale-while-revalidate=120",
|
||||
},
|
||||
}
|
||||
);
|
||||
} catch (error) {
|
||||
@@ -68,7 +68,7 @@ export async function DELETE(
|
||||
) {
|
||||
try {
|
||||
const libraryId: string = (await params).libraryId;
|
||||
|
||||
|
||||
await LibraryService.invalidateLibrarySeriesCache(libraryId);
|
||||
|
||||
return NextResponse.json({ success: true });
|
||||
@@ -98,4 +98,3 @@ export async function DELETE(
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -51,4 +51,3 @@ export async function GET(request: NextRequest) {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,22 +16,22 @@ export async function GET(
|
||||
try {
|
||||
const seriesId: string = (await params).seriesId;
|
||||
const searchParams = request.nextUrl.searchParams;
|
||||
|
||||
|
||||
const page = parseInt(searchParams.get("page") || "0");
|
||||
const size = parseInt(searchParams.get("size") || String(DEFAULT_PAGE_SIZE));
|
||||
const unreadOnly = searchParams.get("unread") === "true";
|
||||
|
||||
const [books, series] = await Promise.all([
|
||||
SeriesService.getSeriesBooks(seriesId, page, size, unreadOnly),
|
||||
SeriesService.getSeries(seriesId)
|
||||
SeriesService.getSeries(seriesId),
|
||||
]);
|
||||
|
||||
return NextResponse.json(
|
||||
{ books, series },
|
||||
{
|
||||
headers: {
|
||||
'Cache-Control': 'public, s-maxage=60, stale-while-revalidate=120'
|
||||
}
|
||||
"Cache-Control": "public, s-maxage=60, stale-while-revalidate=120",
|
||||
},
|
||||
}
|
||||
);
|
||||
} catch (error) {
|
||||
@@ -67,10 +67,10 @@ export async function DELETE(
|
||||
) {
|
||||
try {
|
||||
const seriesId: string = (await params).seriesId;
|
||||
|
||||
|
||||
await Promise.all([
|
||||
SeriesService.invalidateSeriesBooksCache(seriesId),
|
||||
SeriesService.invalidateSeriesCache(seriesId)
|
||||
SeriesService.invalidateSeriesCache(seriesId),
|
||||
]);
|
||||
|
||||
return NextResponse.json({ success: true });
|
||||
@@ -100,4 +100,3 @@ export async function DELETE(
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,8 +18,8 @@ export async function GET(
|
||||
const series: KomgaSeries = await SeriesService.getSeries(seriesId);
|
||||
return NextResponse.json(series, {
|
||||
headers: {
|
||||
'Cache-Control': 'public, s-maxage=60, stale-while-revalidate=120'
|
||||
}
|
||||
"Cache-Control": "public, s-maxage=60, stale-while-revalidate=120",
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error({ err: error }, "API Series - Erreur:");
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { NextRequest} from "next/server";
|
||||
import type { NextRequest } from "next/server";
|
||||
import { NextResponse } from "next/server";
|
||||
import { PreferencesService } from "@/lib/services/preferences.service";
|
||||
import { ERROR_CODES } from "@/constants/errorCodes";
|
||||
@@ -41,9 +41,8 @@ export async function GET() {
|
||||
export async function PUT(request: NextRequest) {
|
||||
try {
|
||||
const preferences: UserPreferences = await request.json();
|
||||
const updatedPreferences: UserPreferences = await PreferencesService.updatePreferences(
|
||||
preferences
|
||||
);
|
||||
const updatedPreferences: UserPreferences =
|
||||
await PreferencesService.updatePreferences(preferences);
|
||||
return NextResponse.json(updatedPreferences);
|
||||
} catch (error) {
|
||||
logger.error({ err: error }, "Erreur lors de la mise à jour des préférences:");
|
||||
|
||||
@@ -10,17 +10,15 @@ export async function PUT(request: NextRequest) {
|
||||
const { currentPassword, newPassword } = body;
|
||||
|
||||
if (!currentPassword || !newPassword) {
|
||||
return NextResponse.json(
|
||||
{ error: "Mots de passe manquants" },
|
||||
{ status: 400 }
|
||||
);
|
||||
return NextResponse.json({ error: "Mots de passe manquants" }, { status: 400 });
|
||||
}
|
||||
|
||||
// Vérifier que le nouveau mot de passe est fort
|
||||
if (!AuthServerService.isPasswordStrong(newPassword)) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: "Le nouveau mot de passe doit contenir au moins 8 caractères, une majuscule et un chiffre"
|
||||
{
|
||||
error:
|
||||
"Le nouveau mot de passe doit contenir au moins 8 caractères, une majuscule et un chiffre",
|
||||
},
|
||||
{ status: 400 }
|
||||
);
|
||||
@@ -35,9 +33,13 @@ export async function PUT(request: NextRequest) {
|
||||
if (error instanceof AppError) {
|
||||
return NextResponse.json(
|
||||
{ error: error.message, code: error.code },
|
||||
{
|
||||
status: error.code === "AUTH_INVALID_PASSWORD" ? 400 :
|
||||
error.code === "AUTH_UNAUTHENTICATED" ? 401 : 500
|
||||
{
|
||||
status:
|
||||
error.code === "AUTH_INVALID_PASSWORD"
|
||||
? 400
|
||||
: error.code === "AUTH_UNAUTHENTICATED"
|
||||
? 401
|
||||
: 500,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
export default function BookReaderLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
export default function BookReaderLayout({ children }: { children: React.ReactNode }) {
|
||||
return <>{children}</>;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import { BookSkeleton } from "@/components/skeletons/BookSkeleton";
|
||||
|
||||
export default async function BookPage({ params }: { params: Promise<{ bookId: string }> }) {
|
||||
const { bookId } = await params;
|
||||
|
||||
|
||||
return (
|
||||
<Suspense fallback={<BookSkeleton />}>
|
||||
<ClientBookPage bookId={bookId} />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { DownloadManager } from "@/components/downloads/DownloadManager";
|
||||
|
||||
export const dynamic = 'force-dynamic';
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
export default function DownloadsPage() {
|
||||
return (
|
||||
|
||||
@@ -12,7 +12,12 @@ import { defaultPreferences } from "@/types/preferences";
|
||||
import type { UserPreferences } from "@/types/preferences";
|
||||
import logger from "@/lib/logger";
|
||||
|
||||
const inter = Inter({ subsets: ["latin"], display: "swap", adjustFontFallback: false, preload: false });
|
||||
const inter = Inter({
|
||||
subsets: ["latin"],
|
||||
display: "swap",
|
||||
adjustFontFallback: false,
|
||||
preload: false,
|
||||
});
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: {
|
||||
@@ -90,10 +95,7 @@ export default async function RootLayout({ children }: { children: React.ReactNo
|
||||
return (
|
||||
<html lang={locale} suppressHydrationWarning className="h-full">
|
||||
<head>
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1, viewport-fit=cover"
|
||||
/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||
<meta name="apple-touch-fullscreen" content="yes" />
|
||||
@@ -145,16 +147,15 @@ export default async function RootLayout({ children }: { children: React.ReactNo
|
||||
/>
|
||||
</head>
|
||||
<body
|
||||
className={cn("min-h-screen bg-background font-sans antialiased h-full no-pinch-zoom", inter.className)}
|
||||
className={cn(
|
||||
"min-h-screen bg-background font-sans antialiased h-full no-pinch-zoom",
|
||||
inter.className
|
||||
)}
|
||||
>
|
||||
<AuthProvider>
|
||||
<I18nProvider locale={locale}>
|
||||
<PreferencesProvider initialPreferences={preferences}>
|
||||
<ClientLayout
|
||||
initialLibraries={[]}
|
||||
initialFavorites={[]}
|
||||
userIsAdmin={userIsAdmin}
|
||||
>
|
||||
<ClientLayout initialLibraries={[]} initialFavorites={[]} userIsAdmin={userIsAdmin}>
|
||||
{children}
|
||||
</ClientLayout>
|
||||
</PreferencesProvider>
|
||||
|
||||
@@ -47,22 +47,22 @@ export function ClientLibraryPage({
|
||||
const fetchData = async () => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
|
||||
try {
|
||||
const params = new URLSearchParams({
|
||||
page: String(currentPage - 1),
|
||||
size: String(effectivePageSize),
|
||||
unread: String(unreadOnly),
|
||||
});
|
||||
|
||||
|
||||
if (search) {
|
||||
params.append("search", search);
|
||||
}
|
||||
|
||||
const response = await fetch(`/api/komga/libraries/${libraryId}/series?${params}`, {
|
||||
cache: 'default' // Utilise le cache HTTP du navigateur
|
||||
cache: "default", // Utilise le cache HTTP du navigateur
|
||||
});
|
||||
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json();
|
||||
throw new Error(errorData.error?.code || "SERIES_FETCH_ERROR");
|
||||
@@ -86,28 +86,28 @@ export function ClientLibraryPage({
|
||||
try {
|
||||
// Invalidate cache via API
|
||||
const cacheResponse = await fetch(`/api/komga/libraries/${libraryId}/series`, {
|
||||
method: 'DELETE',
|
||||
method: "DELETE",
|
||||
});
|
||||
|
||||
if (!cacheResponse.ok) {
|
||||
throw new Error("Error invalidating cache");
|
||||
}
|
||||
|
||||
|
||||
// Recharger les données
|
||||
const params = new URLSearchParams({
|
||||
page: String(currentPage - 1),
|
||||
size: String(effectivePageSize),
|
||||
unread: String(unreadOnly),
|
||||
});
|
||||
|
||||
|
||||
if (search) {
|
||||
params.append("search", search);
|
||||
}
|
||||
|
||||
const response = await fetch(`/api/komga/libraries/${libraryId}/series?${params}`, {
|
||||
cache: 'reload' // Force un nouveau fetch après invalidation
|
||||
cache: "reload", // Force un nouveau fetch après invalidation
|
||||
});
|
||||
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Error refreshing library");
|
||||
}
|
||||
@@ -115,7 +115,7 @@ export function ClientLibraryPage({
|
||||
const data = await response.json();
|
||||
setLibrary(data.library);
|
||||
setSeries(data.series);
|
||||
|
||||
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
logger.error({ err: error }, "Error during refresh:");
|
||||
@@ -133,15 +133,15 @@ export function ClientLibraryPage({
|
||||
size: String(effectivePageSize),
|
||||
unread: String(unreadOnly),
|
||||
});
|
||||
|
||||
|
||||
if (search) {
|
||||
params.append("search", search);
|
||||
}
|
||||
|
||||
const response = await fetch(`/api/komga/libraries/${libraryId}/series?${params}`, {
|
||||
cache: 'reload' // Force un nouveau fetch lors du retry
|
||||
cache: "reload", // Force un nouveau fetch lors du retry
|
||||
});
|
||||
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json();
|
||||
throw new Error(errorData.error?.code || "SERIES_FETCH_ERROR");
|
||||
|
||||
@@ -50,7 +50,7 @@ export function ClientSeriesPage({
|
||||
});
|
||||
|
||||
const response = await fetch(`/api/komga/series/${seriesId}/books?${params}`, {
|
||||
cache: 'default' // Utilise le cache HTTP du navigateur
|
||||
cache: "default", // Utilise le cache HTTP du navigateur
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
@@ -76,7 +76,7 @@ export function ClientSeriesPage({
|
||||
try {
|
||||
// Invalidate cache via API
|
||||
const cacheResponse = await fetch(`/api/komga/series/${seriesId}/books`, {
|
||||
method: 'DELETE',
|
||||
method: "DELETE",
|
||||
});
|
||||
|
||||
if (!cacheResponse.ok) {
|
||||
@@ -91,7 +91,7 @@ export function ClientSeriesPage({
|
||||
});
|
||||
|
||||
const response = await fetch(`/api/komga/series/${seriesId}/books?${params}`, {
|
||||
cache: 'reload' // Force un nouveau fetch après invalidation
|
||||
cache: "reload", // Force un nouveau fetch après invalidation
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
@@ -121,7 +121,7 @@ export function ClientSeriesPage({
|
||||
});
|
||||
|
||||
const response = await fetch(`/api/komga/series/${seriesId}/books?${params}`, {
|
||||
cache: 'reload' // Force un nouveau fetch lors du retry
|
||||
cache: "reload", // Force un nouveau fetch lors du retry
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
@@ -204,4 +204,3 @@ export function ClientSeriesPage({
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -53,4 +53,3 @@ export default function SeriesLoading() {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import type { Metadata } from "next";
|
||||
import type { KomgaConfig, TTLConfig } from "@/types/komga";
|
||||
import logger from "@/lib/logger";
|
||||
|
||||
export const dynamic = 'force-dynamic';
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Préférences",
|
||||
|
||||
Reference in New Issue
Block a user