feat: front update

This commit is contained in:
ext.jeremy.guillot@maxicoffee.domains
2025-03-22 15:38:05 +01:00
parent 7303d63198
commit 4f4f86fb91
5 changed files with 44 additions and 34 deletions

View File

@@ -1,7 +1,5 @@
import React from 'react';
import { useNavigate } from 'react-router-dom';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faStar } from '@fortawesome/free-solid-svg-icons';
export function MangaCard({ manga }) {
const navigate = useNavigate();
@@ -10,39 +8,34 @@ export function MangaCard({ manga }) {
navigate(`/manga/${manga.slug}`);
};
const formatDate = (dateString) => {
const date = new Date(dateString);
return date.toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric'
});
};
return (
<div
className="bg-white rounded-lg shadow-md overflow-hidden cursor-pointer transition-transform hover:scale-105"
onClick={handleClick}
>
<div className="relative h-64">
<div className="relative pb-[150%]">
<img
src={manga.imageUrl || 'https://via.placeholder.com/300x400'}
alt={manga.title}
className="w-full h-full object-cover"
className="absolute inset-0 w-full h-full object-contain bg-gray-100"
/>
</div>
<div className="p-4">
<h3 className="text-lg font-semibold text-gray-800 mb-2">{manga.title}</h3>
<p className="text-sm text-gray-600 mb-2">By {manga.author}</p>
<div className="flex items-center justify-between">
<div className="p-2">
<h3 className="text-lg font-semibold text-gray-800 mb-1">{manga.title}</h3>
<div className="flex items-center">
<span className="text-sm text-gray-500">{manga.publicationYear}</span>
{manga.rating && (
<span className="flex items-center text-yellow-500">
<FontAwesomeIcon icon={faStar} className="mr-1" />
{manga.rating}
</span>
)}
</div>
<div className="mt-2 flex flex-wrap gap-1">
{manga.genres.map((genre, index) => (
<span
key={index}
className="px-2 py-1 text-xs bg-green-100 text-green-800 rounded-full"
>
{genre}
</span>
))}
<div className="mt-1 text-sm text-gray-500">
Added: {formatDate(manga.createdAt)}
</div>
</div>
</div>

View File

@@ -47,7 +47,11 @@ function mangaReducer(state, action) {
...state.collection,
items: state.collection.items.map(manga =>
manga.slug === action.payload.slug
? { ...manga, ...action.payload }
? {
...manga,
...action.payload,
createdAt: manga.createdAt || action.payload.createdAt
}
: manga
)
} : state.collection;
@@ -57,7 +61,10 @@ function mangaReducer(state, action) {
collection: updatedCollection,
detailedMangas: {
...state.detailedMangas,
[action.payload.slug]: action.payload
[action.payload.slug]: {
...action.payload,
createdAt: state.collection?.items.find(m => m.slug === action.payload.slug)?.createdAt || action.payload.createdAt
}
},
loading: false,
error: null
@@ -98,11 +105,11 @@ export function MangaProvider({ children }) {
const loadCollection = useCallback(async () => {
// Si nous avons déjà des données, les afficher immédiatement
if (state.collection) {
// Rafraîchir en arrière-plan si les données sont vieilles de plus de 1 minute
// Rafraîchir en arrière-plan si les données sont vieilles de plus de 30 secondes
const isStale = state.lastCollectionUpdate &&
(Date.now() - state.lastCollectionUpdate) > 60 * 1000;
(Date.now() - state.lastCollectionUpdate) > 30 * 1000;
if (isStale) {
if (isStale && !state.isBackgroundLoading) {
refreshCollectionInBackground();
}
return;
@@ -116,7 +123,7 @@ export function MangaProvider({ children }) {
dispatch({ type: 'SET_ERROR', payload: 'Failed to load manga collection' });
console.error(error);
}
}, [state.collection, state.lastCollectionUpdate, refreshCollectionInBackground]);
}, [state.collection, state.lastCollectionUpdate, state.isBackgroundLoading, refreshCollectionInBackground]);
const loadMangaDetail = useCallback(async (slug) => {
// Retourner les données en cache si disponibles