Fetch images client side for admin page

This commit is contained in:
2025-10-09 18:03:06 +02:00
parent af90528cfc
commit 3ca3b5fdce
2 changed files with 14 additions and 48 deletions

View File

@@ -1,6 +1,5 @@
import ImageManager from '@/components/ImageManager';
import ImageUpload from '@/components/ImageUpload';
import { ImagesResponse, TagsResponse } from '@/interfaces/api';
import { getSession } from '@/lib/session';
import styles from '@/styles/AdminPage.module.scss';
import { redirect } from 'next/navigation';
@@ -12,33 +11,10 @@ export default async function AdminPage() {
redirect('/login');
}
const fetchImages = async () => {
const apiUrl = new URL(
'/api/images?imagesPerPage=-1}',
process.env.NEXT_PUBLIC_SITE_URL || 'http://localhost:3000',
);
const response = await fetch(apiUrl.toString());
if (!response.ok) {
throw new Error(`Network response was not ok: ${response.statusText}`);
}
return (await response.json()) as ImagesResponse;
};
const fetchTags = async () => {
const apiUrl = new URL('/api/tags', process.env.NEXT_PUBLIC_SITE_URL || 'http://localhost:3000');
const response = await fetch(apiUrl.toString());
if (!response.ok) {
throw new Error(`Network response was not ok: ${response.statusText}`);
}
return (await response.json()) as TagsResponse;
};
return (
<div className={styles.container}>
<ImageUpload />
<ImageManager tags={await fetchTags()} images={(await fetchImages()).images} />
<ImageManager />
</div>
);
}

View File

@@ -1,3 +1,4 @@
/* eslint-disable react-hooks/exhaustive-deps */
'use client';
import Button from '@/components/Button';
@@ -5,19 +6,14 @@ import InputField from '@/components/InputField';
import { ImageMeta } from '@/interfaces/image';
import styles from '@/styles/ImageManager.module.scss';
import Image from 'next/image';
import { redirect, useSearchParams } from 'next/navigation';
import { useSearchParams } from 'next/navigation';
import React, { useEffect, useState } from 'react';
import Tags from './Tags';
interface ImageManagerProps {
images: ImageMeta[];
tags: string[];
}
export default function ImageManager({ images: initialImages, tags: initialTags }: ImageManagerProps) {
const [images, setImages] = useState<ImageMeta[]>(initialImages);
export default function ImageManager() {
const [images, setImages] = useState<ImageMeta[]>([]);
const [error, setError] = useState<string>();
const [tags, setTags] = useState<string[]>(initialTags);
const [tags, setTags] = useState<string[]>([]);
const [activeTag, setActiveTag] = useState<string>('all');
const searchParams = useSearchParams();
@@ -92,23 +88,17 @@ export default function ImageManager({ images: initialImages, tags: initialTags
};
useEffect(() => {
setActiveTag(searchParams.get('tag') ?? 'all');
}, [searchParams, tags]);
fetchTags();
fetchImages();
}, []);
useEffect(() => {
const filterImages = () => {
if (activeTag === 'all') {
setImages(initialImages);
return;
} else if (activeTag && !tags.includes(activeTag)) {
redirect('/admin');
} else {
setImages(initialImages.filter((image) => image.tags.includes(activeTag)));
}
};
fetchImages();
}, [activeTag]);
filterImages();
}, [activeTag, initialImages, tags]);
useEffect(() => {
setActiveTag(searchParams.get('tag') ?? 'all');
}, [searchParams, tags]);
return (
<div className={styles.container}>