Feature: user upload artwork

This commit is contained in:
2025-10-25 02:22:39 -04:00
parent 28d0443f44
commit d376b48d5e
23 changed files with 1288 additions and 177 deletions

View File

@@ -1,81 +1,107 @@
import {useState, useEffect} from 'react';
import type {Artwork} from '@/types';
const SAMPLE_ARTWORKS: Artwork[] = [
{
id: '1',
title: 'Dragon 1',
description: '',
imageUrl: '/gallery/ArtFixture_2.jpg?inline',
},
{
id: '2',
title: 'Dragon 2',
description: '',
imageUrl: '/gallery/ArtFixture_3.jpg?inline',
},
{
id: '3',
title: 'Dragon 3',
description: '',
imageUrl: '/gallery/ArtFixture_4.jpg?inline',
},
{
id: '4',
title: 'Abstract Emotions',
description: '',
imageUrl: '/gallery/ArtFixture_5.jpg?inline',
},
{
id: '5',
title: 'Humorous',
description: '',
imageUrl: '/gallery/ArtFixture_6.png?inline',
},
{
id: '6',
title: 'Rainbows',
description: '',
imageUrl: '/gallery/ArtFixture_7.jpg?inline',
}
];
interface ArtworkResponse {
id: string;
title: string;
filename: string;
mimetype: string;
size: number;
created_at: string;
updated_at: string;
}
export const useArtwork = () => {
const [artworks, setArtworks] = useState<Artwork[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
// Load from localStorage or use sample data
const stored = localStorage.getItem('artworks');
if (stored) {
setArtworks(JSON.parse(stored));
} else {
setArtworks(SAMPLE_ARTWORKS);
localStorage.setItem('artworks', JSON.stringify(SAMPLE_ARTWORKS));
const fetchArtworks = async () => {
setLoading(true);
setError(null);
try {
const response = await fetch('/api/artworks');
if (!response.ok) {
throw new Error('Failed to fetch artworks');
}
const data: ArtworkResponse[] = await response.json();
// Transform backend data to frontend format
const transformedArtworks: Artwork[] = data.map(artwork => ({
id: artwork.id,
title: artwork.title,
imageUrl: `/api/artworks/${artwork.id}/image`
}));
setArtworks(transformedArtworks);
} catch (err) {
console.error('Error fetching artworks:', err);
setError(err instanceof Error ? err.message : 'Failed to load artworks');
setArtworks([]);
} finally {
setLoading(false);
}
setLoading(false);
}, []);
const addArtwork = (artwork: Omit<Artwork, 'id'>) => {
const newArtwork: Artwork = {
...artwork,
id: Date.now().toString()
};
const updated = [...artworks, newArtwork];
setArtworks(updated);
localStorage.setItem('artworks', JSON.stringify(updated));
};
const deleteArtwork = (id: string) => {
const updated = artworks.filter(art => art.id !== id);
setArtworks(updated);
localStorage.setItem('artworks', JSON.stringify(updated));
useEffect(() => {
fetchArtworks();
}, []);
const addArtwork = async (artwork: Omit<Artwork, 'id'>, file: File) => {
try {
const formData = new FormData();
formData.append('title', artwork.title);
formData.append('image', file);
const response = await fetch('/api/artworks', {
method: 'POST',
body: formData
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(errorData.message || 'Failed to upload artwork');
}
const newArtworkData: ArtworkResponse = await response.json();
const newArtwork: Artwork = {
id: newArtworkData.id,
title: newArtworkData.title,
imageUrl: `/api/artworks/${newArtworkData.id}/image`
};
setArtworks(prev => [...prev, newArtwork]);
return newArtwork;
} catch (err) {
console.error('Error adding artwork:', err);
throw err;
}
};
const deleteArtwork = async (id: string) => {
try {
const response = await fetch(`/api/artworks/${id}`, {
method: 'DELETE'
});
if (!response.ok) {
throw new Error('Failed to delete artwork');
}
setArtworks(prev => prev.filter(art => art.id !== id));
} catch (err) {
console.error('Error deleting artwork:', err);
throw err;
}
};
return {
artworks,
loading,
error,
addArtwork,
deleteArtwork
deleteArtwork,
refetch: fetchArtworks
};
};

View File

@@ -19,12 +19,12 @@ export const useAuth = () => {
const response = await fetch('/api/users/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
username,
password,
}),
password
})
});
if (!response.ok) {
@@ -32,7 +32,7 @@ export const useAuth = () => {
}
const responseData = await response.json();
if (responseData.status === 'ok') {
setUser({username, isAuthenticated: true});
localStorage.setItem('user', JSON.stringify({username, isAuthenticated: true}));