- Update all environment files to use new PostgreSQL API endpoint - Fix CORS configuration in API server - Import 35 filaments and 29 colors from PDF data - Fix TypeScript type error in dashboard - Add back emoji icons for dark mode toggle - Remove debugging code and test buttons - Clean up error handling
123 lines
4.5 KiB
TypeScript
123 lines
4.5 KiB
TypeScript
'use client'
|
|
|
|
import { useState, useEffect, useRef } from 'react';
|
|
import { FilamentTableV2 } from '../src/components/FilamentTableV2';
|
|
import { Filament } from '../src/types/filament';
|
|
import { filamentService } from '../src/services/api';
|
|
|
|
export default function Home() {
|
|
const [filaments, setFilaments] = useState<Filament[]>([]);
|
|
const [loading, setLoading] = useState(true);
|
|
const [error, setError] = useState<string | null>(null);
|
|
const [darkMode, setDarkMode] = useState(false);
|
|
const [mounted, setMounted] = useState(false);
|
|
const [resetKey, setResetKey] = useState(0);
|
|
// Removed V1/V2 toggle - now only using V2
|
|
|
|
// Initialize dark mode from localStorage after mounting
|
|
useEffect(() => {
|
|
setMounted(true);
|
|
const saved = localStorage.getItem('darkMode');
|
|
if (saved) {
|
|
setDarkMode(JSON.parse(saved));
|
|
}
|
|
}, []);
|
|
|
|
// Update dark mode
|
|
useEffect(() => {
|
|
if (!mounted) return;
|
|
|
|
localStorage.setItem('darkMode', JSON.stringify(darkMode));
|
|
if (darkMode) {
|
|
document.documentElement.classList.add('dark');
|
|
} else {
|
|
document.documentElement.classList.remove('dark');
|
|
}
|
|
}, [darkMode, mounted]);
|
|
|
|
const fetchFilaments = async () => {
|
|
try {
|
|
setLoading(true);
|
|
setError(null);
|
|
|
|
const filaments = await filamentService.getAll();
|
|
setFilaments(filaments);
|
|
} catch (err: any) {
|
|
console.error('API Error:', err);
|
|
|
|
// More descriptive error messages
|
|
if (err.code === 'ERR_NETWORK') {
|
|
setError('Network Error - Unable to connect to API');
|
|
} else if (err.response) {
|
|
setError(`Server error: ${err.response.status} - ${err.response.statusText}`);
|
|
} else if (err.request) {
|
|
setError('No response from server - check if API is running');
|
|
} else {
|
|
setError(err.message || 'Greška pri učitavanju filamenata');
|
|
}
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
fetchFilaments();
|
|
}, []);
|
|
|
|
const handleLogoClick = () => {
|
|
setResetKey(prev => prev + 1);
|
|
window.scrollTo({ top: 0, behavior: 'smooth' });
|
|
};
|
|
|
|
return (
|
|
<div className="min-h-screen bg-gray-50 dark:bg-gray-900 transition-colors">
|
|
<header className="bg-gradient-to-r from-blue-50 to-orange-50 dark:from-gray-800 dark:to-gray-900 shadow-lg transition-all duration-300">
|
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4">
|
|
<div className="flex flex-col sm:flex-row justify-between items-center gap-4">
|
|
<button
|
|
onClick={handleLogoClick}
|
|
className="group hover:scale-105 transition-transform duration-200"
|
|
title="Klikni za reset"
|
|
>
|
|
<h1 className="text-3xl font-bold bg-gradient-to-r from-blue-600 to-orange-600 dark:from-blue-400 dark:to-orange-400 bg-clip-text text-transparent group-hover:from-blue-700 group-hover:to-orange-700 dark:group-hover:from-blue-300 dark:group-hover:to-orange-300 transition-all">
|
|
Filamenteka
|
|
</h1>
|
|
</button>
|
|
|
|
<div className="flex flex-col sm:flex-row items-center gap-3 text-sm">
|
|
<div className="flex flex-col sm:flex-row gap-3 text-center">
|
|
<span className="text-blue-700 dark:text-blue-300 font-medium animate-pulse whitespace-nowrap">
|
|
Kupovina po gramu dostupna
|
|
</span>
|
|
<span className="hidden sm:inline text-gray-400 dark:text-gray-600">•</span>
|
|
<span className="text-orange-700 dark:text-orange-300 font-medium animate-pulse whitespace-nowrap">
|
|
Popust za 5+ komada
|
|
</span>
|
|
</div>
|
|
|
|
{mounted && (
|
|
<button
|
|
onClick={() => setDarkMode(!darkMode)}
|
|
className="p-2 bg-white/50 dark:bg-gray-700/50 backdrop-blur text-gray-800 dark:text-gray-200 rounded-full hover:bg-white/80 dark:hover:bg-gray-600/80 transition-all duration-200 hover:scale-110 shadow-md ml-2"
|
|
title={darkMode ? 'Svetla tema' : 'Tamna tema'}
|
|
>
|
|
{darkMode ? '☀️' : '🌙'}
|
|
</button>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
<main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
|
<FilamentTableV2
|
|
key={resetKey}
|
|
filaments={filaments}
|
|
loading={loading}
|
|
error={error || undefined}
|
|
/>
|
|
</main>
|
|
|
|
</div>
|
|
);
|
|
} |