Improve mobile responsiveness and add scroll-to-top functionality
- Fix header layout to stack vertically on mobile and prevent text overflow - Reduce table padding on mobile screens for better space utilization - Make color swatches and text smaller on mobile devices - Hide bullet separator on mobile for cleaner layout - Add scroll-to-top when editing or adding filaments in admin - Ensure all UI elements fit properly on iPhone screens
This commit is contained in:
14
app/page.tsx
14
app/page.tsx
@@ -89,19 +89,19 @@ export default function Home() {
|
|||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-gray-50 dark:bg-gray-900 transition-colors">
|
<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">
|
<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="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-3 sm:py-4">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex flex-col sm:flex-row items-center justify-between gap-3 sm:gap-0">
|
||||||
<div className="flex-1 flex justify-center gap-3 text-lg">
|
<div className="flex-1 flex flex-col sm:flex-row justify-center items-center gap-1 sm:gap-3 text-sm sm:text-lg">
|
||||||
<span className="text-blue-700 dark:text-blue-300 font-medium animate-pulse whitespace-nowrap">
|
<span className="text-blue-700 dark:text-blue-300 font-medium animate-pulse text-center">
|
||||||
Kupovina po gramu dostupna
|
Kupovina po gramu dostupna
|
||||||
</span>
|
</span>
|
||||||
<span className="text-gray-400 dark:text-gray-600">•</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">
|
<span className="text-orange-700 dark:text-orange-300 font-medium animate-pulse text-center">
|
||||||
Popust za 5+ komada
|
Popust za 5+ komada
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex-shrink-0 ml-4">
|
<div className="flex-shrink-0">
|
||||||
{mounted ? (
|
{mounted ? (
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
|||||||
@@ -322,7 +322,10 @@ export default function AdminDashboard() {
|
|||||||
<div className="flex flex-wrap gap-2 sm:gap-4 w-full sm:w-auto">
|
<div className="flex flex-wrap gap-2 sm:gap-4 w-full sm:w-auto">
|
||||||
{!showAddForm && !editingFilament && (
|
{!showAddForm && !editingFilament && (
|
||||||
<button
|
<button
|
||||||
onClick={() => setShowAddForm(true)}
|
onClick={() => {
|
||||||
|
setShowAddForm(true);
|
||||||
|
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||||
|
}}
|
||||||
className="flex-1 sm:flex-initial px-3 sm:px-4 py-2 bg-green-500 text-white rounded hover:bg-green-600 text-sm sm:text-base"
|
className="flex-1 sm:flex-initial px-3 sm:px-4 py-2 bg-green-500 text-white rounded hover:bg-green-600 text-sm sm:text-base"
|
||||||
>
|
>
|
||||||
Dodaj novi
|
Dodaj novi
|
||||||
@@ -567,6 +570,7 @@ export default function AdminDashboard() {
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
setEditingFilament(filament);
|
setEditingFilament(filament);
|
||||||
setShowAddForm(false);
|
setShowAddForm(false);
|
||||||
|
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||||
}}
|
}}
|
||||||
className="text-blue-600 dark:text-blue-400 hover:text-blue-900 dark:hover:text-blue-300 mr-3"
|
className="text-blue-600 dark:text-blue-400 hover:text-blue-900 dark:hover:text-blue-300 mr-3"
|
||||||
title="Izmeni"
|
title="Izmeni"
|
||||||
|
|||||||
@@ -153,25 +153,25 @@ const FilamentTableV2: React.FC<FilamentTableV2Props> = ({ filaments }) => {
|
|||||||
<table className="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
|
<table className="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
|
||||||
<thead className="bg-gray-50 dark:bg-gray-900">
|
<thead className="bg-gray-50 dark:bg-gray-900">
|
||||||
<tr>
|
<tr>
|
||||||
<th onClick={() => handleSort('tip')} className="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800">
|
<th onClick={() => handleSort('tip')} className="px-2 sm:px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800">
|
||||||
Tip {sortField === 'tip' && (sortOrder === 'asc' ? '↑' : '↓')}
|
Tip {sortField === 'tip' && (sortOrder === 'asc' ? '↑' : '↓')}
|
||||||
</th>
|
</th>
|
||||||
<th onClick={() => handleSort('finish')} className="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800">
|
<th onClick={() => handleSort('finish')} className="px-2 sm:px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800">
|
||||||
Finish {sortField === 'finish' && (sortOrder === 'asc' ? '↑' : '↓')}
|
Finish {sortField === 'finish' && (sortOrder === 'asc' ? '↑' : '↓')}
|
||||||
</th>
|
</th>
|
||||||
<th onClick={() => handleSort('boja')} className="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800">
|
<th onClick={() => handleSort('boja')} className="px-2 sm:px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800">
|
||||||
Boja {sortField === 'boja' && (sortOrder === 'asc' ? '↑' : '↓')}
|
Boja {sortField === 'boja' && (sortOrder === 'asc' ? '↑' : '↓')}
|
||||||
</th>
|
</th>
|
||||||
<th onClick={() => handleSort('refill')} className="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800">
|
<th onClick={() => handleSort('refill')} className="px-2 sm:px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800">
|
||||||
Refill {sortField === 'refill' && (sortOrder === 'asc' ? '↑' : '↓')}
|
Refill {sortField === 'refill' && (sortOrder === 'asc' ? '↑' : '↓')}
|
||||||
</th>
|
</th>
|
||||||
<th onClick={() => handleSort('spulna')} className="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800">
|
<th onClick={() => handleSort('spulna')} className="px-2 sm:px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800">
|
||||||
Spulna {sortField === 'spulna' && (sortOrder === 'asc' ? '↑' : '↓')}
|
Spulna {sortField === 'spulna' && (sortOrder === 'asc' ? '↑' : '↓')}
|
||||||
</th>
|
</th>
|
||||||
<th onClick={() => handleSort('kolicina')} className="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800">
|
<th onClick={() => handleSort('kolicina')} className="px-2 sm:px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800">
|
||||||
Količina {sortField === 'kolicina' && (sortOrder === 'asc' ? '↑' : '↓')}
|
Količina {sortField === 'kolicina' && (sortOrder === 'asc' ? '↑' : '↓')}
|
||||||
</th>
|
</th>
|
||||||
<th onClick={() => handleSort('cena')} className="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800">
|
<th onClick={() => handleSort('cena')} className="px-2 sm:px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800">
|
||||||
Cena {sortField === 'cena' && (sortOrder === 'asc' ? '↑' : '↓')}
|
Cena {sortField === 'cena' && (sortOrder === 'asc' ? '↑' : '↓')}
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -180,42 +180,42 @@ const FilamentTableV2: React.FC<FilamentTableV2Props> = ({ filaments }) => {
|
|||||||
{filteredAndSortedFilaments.map(filament => {
|
{filteredAndSortedFilaments.map(filament => {
|
||||||
return (
|
return (
|
||||||
<tr key={filament.id} className="hover:bg-gray-50 dark:hover:bg-gray-700">
|
<tr key={filament.id} className="hover:bg-gray-50 dark:hover:bg-gray-700">
|
||||||
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100">
|
<td className="px-2 sm:px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100">
|
||||||
{filament.tip}
|
{filament.tip}
|
||||||
</td>
|
</td>
|
||||||
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100">
|
<td className="px-2 sm:px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100">
|
||||||
{filament.finish}
|
{filament.finish}
|
||||||
</td>
|
</td>
|
||||||
<td className="px-6 py-4 whitespace-nowrap">
|
<td className="px-2 sm:px-6 py-4 whitespace-nowrap">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-1 sm:gap-2">
|
||||||
{filament.boja_hex && (
|
{filament.boja_hex && (
|
||||||
<div
|
<div
|
||||||
className="w-7 h-7 rounded border border-gray-300 dark:border-gray-600"
|
className="w-5 h-5 sm:w-7 sm:h-7 rounded border border-gray-300 dark:border-gray-600"
|
||||||
style={{ backgroundColor: filament.boja_hex }}
|
style={{ backgroundColor: filament.boja_hex }}
|
||||||
title={filament.boja_hex}
|
title={filament.boja_hex}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<span className="text-sm text-gray-900 dark:text-gray-100">{filament.boja}</span>
|
<span className="text-xs sm:text-sm text-gray-900 dark:text-gray-100">{filament.boja}</span>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100">
|
<td className="px-2 sm:px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100">
|
||||||
{filament.refill > 0 ? (
|
{filament.refill > 0 ? (
|
||||||
<span className="text-green-600 dark:text-green-400 font-bold">{filament.refill}</span>
|
<span className="text-green-600 dark:text-green-400 font-bold">{filament.refill}</span>
|
||||||
) : (
|
) : (
|
||||||
<span className="text-gray-400 dark:text-gray-500">0</span>
|
<span className="text-gray-400 dark:text-gray-500">0</span>
|
||||||
)}
|
)}
|
||||||
</td>
|
</td>
|
||||||
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100">
|
<td className="px-2 sm:px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100">
|
||||||
{filament.spulna > 0 ? (
|
{filament.spulna > 0 ? (
|
||||||
<span className="text-blue-500 dark:text-blue-400 font-bold">{filament.spulna}</span>
|
<span className="text-blue-500 dark:text-blue-400 font-bold">{filament.spulna}</span>
|
||||||
) : (
|
) : (
|
||||||
<span className="text-gray-400 dark:text-gray-500">0</span>
|
<span className="text-gray-400 dark:text-gray-500">0</span>
|
||||||
)}
|
)}
|
||||||
</td>
|
</td>
|
||||||
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100">
|
<td className="px-2 sm:px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100">
|
||||||
{filament.kolicina}
|
{filament.kolicina}
|
||||||
</td>
|
</td>
|
||||||
<td className="px-6 py-4 whitespace-nowrap text-sm font-bold text-gray-900 dark:text-white">
|
<td className="px-2 sm:px-6 py-4 whitespace-nowrap text-sm font-bold text-gray-900 dark:text-white">
|
||||||
{(() => {
|
{(() => {
|
||||||
// First check if filament has custom prices stored
|
// First check if filament has custom prices stored
|
||||||
const hasRefill = filament.refill > 0;
|
const hasRefill = filament.refill > 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user