190 lines
9.9 KiB
TypeScript
190 lines
9.9 KiB
TypeScript
import React, { useState } from 'react';
|
|
import { Search, Filter, Calendar, MapPin, Image as ImageIcon, ExternalLink, Download, Share2 } from 'lucide-react';
|
|
import { Button } from '../components/Button';
|
|
|
|
interface Album {
|
|
id: string;
|
|
eventName: string;
|
|
clientName: string;
|
|
date: string;
|
|
coverImage: string;
|
|
photoCount: number;
|
|
size: string;
|
|
status: 'delivered' | 'archived';
|
|
link: string;
|
|
}
|
|
|
|
const MOCK_ALBUMS: Album[] = [
|
|
{
|
|
id: '1',
|
|
eventName: 'Casamento Juliana & Marcos',
|
|
clientName: 'Juliana Noiva',
|
|
date: '2024-10-15',
|
|
coverImage: 'https://images.unsplash.com/photo-1511795409834-ef04bbd61622?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80',
|
|
photoCount: 450,
|
|
size: '2.4 GB',
|
|
status: 'delivered',
|
|
link: '#'
|
|
},
|
|
{
|
|
id: '2',
|
|
eventName: 'Formatura Medicina UFPR',
|
|
clientName: 'Comissão de Formatura',
|
|
date: '2024-09-20',
|
|
coverImage: 'https://images.unsplash.com/photo-1523580494863-6f3031224c94?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80',
|
|
photoCount: 1200,
|
|
size: '8.5 GB',
|
|
status: 'delivered',
|
|
link: '#'
|
|
},
|
|
{
|
|
id: '3',
|
|
eventName: 'Aniversário 15 Anos Sofia',
|
|
clientName: 'Ana Paula (Mãe)',
|
|
date: '2024-08-05',
|
|
coverImage: 'https://images.unsplash.com/photo-1530103862676-de3c9a59af57?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80',
|
|
photoCount: 320,
|
|
size: '1.8 GB',
|
|
status: 'archived',
|
|
link: '#'
|
|
},
|
|
{
|
|
id: '4',
|
|
eventName: 'Evento Corporativo TechSummit',
|
|
clientName: 'Tech Solutions Inc.',
|
|
date: '2024-11-01',
|
|
coverImage: 'https://images.unsplash.com/photo-1515187029135-18ee286d815b?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80',
|
|
photoCount: 580,
|
|
size: '3.1 GB',
|
|
status: 'delivered',
|
|
link: '#'
|
|
}
|
|
];
|
|
|
|
export const AlbumsPage: React.FC = () => {
|
|
const [searchTerm, setSearchTerm] = useState('');
|
|
const [filter, setFilter] = useState<'all' | 'delivered' | 'archived'>('all');
|
|
|
|
const filteredAlbums = MOCK_ALBUMS.filter(album => {
|
|
const matchesSearch = album.eventName.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
|
album.clientName.toLowerCase().includes(searchTerm.toLowerCase());
|
|
const matchesFilter = filter === 'all' || album.status === filter;
|
|
return matchesSearch && matchesFilter;
|
|
});
|
|
|
|
return (
|
|
<div className="min-h-screen bg-gray-50 pt-24 pb-12 px-4 sm:px-6 lg:px-8">
|
|
<div className="max-w-7xl mx-auto">
|
|
<div className="flex flex-col md:flex-row md:items-center justify-between mb-8 gap-4">
|
|
<div>
|
|
<h1 className="text-3xl font-serif font-bold text-brand-black">Álbuns Entregues</h1>
|
|
<p className="text-gray-500 mt-1">Gerencie e compartilhe os álbuns finalizados com seus clientes.</p>
|
|
</div>
|
|
{/* Placeholder for future actions if needed */}
|
|
</div>
|
|
|
|
{/* Filters & Search */}
|
|
<div className="bg-white p-4 rounded-lg shadow-sm border border-gray-100 mb-8 flex flex-col md:flex-row gap-4 items-center justify-between">
|
|
<div className="relative flex-1 w-full md:max-w-md">
|
|
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400" size={20} />
|
|
<input
|
|
type="text"
|
|
placeholder="Buscar por evento ou cliente..."
|
|
className="w-full pl-10 pr-4 py-2 border border-gray-200 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-gold"
|
|
value={searchTerm}
|
|
onChange={(e) => setSearchTerm(e.target.value)}
|
|
/>
|
|
</div>
|
|
|
|
<div className="flex gap-2 w-full md:w-auto overflow-x-auto pb-2 md:pb-0">
|
|
<button
|
|
onClick={() => setFilter('all')}
|
|
className={`px-4 py-2 rounded-md text-sm font-medium whitespace-nowrap transition-colors ${filter === 'all' ? 'bg-brand-black text-white' : 'bg-gray-100 text-gray-600 hover:bg-gray-200'
|
|
}`}
|
|
>
|
|
Todos
|
|
</button>
|
|
<button
|
|
onClick={() => setFilter('delivered')}
|
|
className={`px-4 py-2 rounded-md text-sm font-medium whitespace-nowrap transition-colors ${filter === 'delivered' ? 'bg-green-100 text-green-700' : 'bg-gray-100 text-gray-600 hover:bg-gray-200'
|
|
}`}
|
|
>
|
|
Entregues
|
|
</button>
|
|
<button
|
|
onClick={() => setFilter('archived')}
|
|
className={`px-4 py-2 rounded-md text-sm font-medium whitespace-nowrap transition-colors ${filter === 'archived' ? 'bg-gray-200 text-gray-700' : 'bg-gray-100 text-gray-600 hover:bg-gray-200'
|
|
}`}
|
|
>
|
|
Arquivados
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Albums Grid */}
|
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
|
{filteredAlbums.map((album) => (
|
|
<div key={album.id} className="bg-white rounded-lg shadow-sm border border-gray-100 overflow-hidden hover:shadow-md transition-shadow group">
|
|
<div className="relative h-48 overflow-hidden">
|
|
<img
|
|
src={album.coverImage}
|
|
alt={album.eventName}
|
|
className="w-full h-full object-cover transform group-hover:scale-105 transition-transform duration-500"
|
|
/>
|
|
<div className="absolute inset-0 bg-gradient-to-t from-black/60 to-transparent opacity-80"></div>
|
|
<div className="absolute bottom-4 left-4 text-white">
|
|
<h3 className="font-bold text-lg leading-tight mb-1">{album.eventName}</h3>
|
|
<p className="text-xs opacity-90 flex items-center">
|
|
<Calendar size={12} className="mr-1" /> {new Date(album.date).toLocaleDateString()}
|
|
</p>
|
|
</div>
|
|
<div className="absolute top-4 right-4">
|
|
<span className={`px-2 py-1 rounded text-xs font-bold uppercase tracking-wide ${album.status === 'delivered' ? 'bg-green-500 text-white' : 'bg-gray-500 text-white'
|
|
}`}>
|
|
{album.status === 'delivered' ? 'Entregue' : 'Arquivado'}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="p-6">
|
|
<div className="flex justify-between items-start mb-4">
|
|
<div>
|
|
<p className="text-xs text-gray-500 uppercase tracking-wide font-bold mb-1">Cliente</p>
|
|
<p className="text-sm font-medium text-gray-800">{album.clientName}</p>
|
|
</div>
|
|
<div className="text-right">
|
|
<p className="text-xs text-gray-500 uppercase tracking-wide font-bold mb-1">Fotos</p>
|
|
<p className="text-sm font-medium text-gray-800">{album.photoCount}</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="flex items-center justify-between pt-4 border-t border-gray-100">
|
|
<span className="text-xs text-gray-400 font-medium">{album.size}</span>
|
|
<div className="flex gap-2">
|
|
<button className="p-2 text-gray-400 hover:text-brand-gold hover:bg-yellow-50 rounded-full transition-colors" title="Download">
|
|
<Download size={18} />
|
|
</button>
|
|
<button className="p-2 text-gray-400 hover:text-blue-500 hover:bg-blue-50 rounded-full transition-colors" title="Compartilhar Link">
|
|
<Share2 size={18} />
|
|
</button>
|
|
<Button size="sm" variant="outline" className="ml-2">
|
|
Ver Álbum <ExternalLink size={14} className="ml-1" />
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
{filteredAlbums.length === 0 && (
|
|
<div className="text-center py-20 bg-white rounded-lg border border-dashed border-gray-200">
|
|
<ImageIcon className="mx-auto h-12 w-12 text-gray-300 mb-4" />
|
|
<h3 className="text-lg font-medium text-gray-900">Nenhum álbum encontrado</h3>
|
|
<p className="text-gray-500">Tente ajustar seus filtros de busca.</p>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|