- Integração Mapbox GL JS para seleção interativa de localização - Mapa arrastável com pin para localização exata - Geocoding e reverse geocoding automático - Busca de endereços com autocomplete - Campos editáveis que atualizam mapa automaticamente - Token configurado via variável de ambiente (.env.local) - Sistema de upload de fotos de fotógrafos - Upload via input de arquivo (substituiu URL) - Preview automático com FileReader API - Botão para remover foto selecionada - Placeholder com ícone de câmera - Remoção de funcionalidades de uploads/álbuns - Removida página Albums.tsx - Removido sistema de attachments - Removida aba Inspiração para empresas - Criada página Inspiração com galeria de exemplo - Melhorias de responsividade - Cards do mapa adaptados para mobile - Texto e padding reduzidos em telas pequenas - Arquivos de configuração - .env.example criado - vite-env.d.ts para tipagem - MAPBOX_SETUP.md com instruções - Footer atualizado com serviços universitários
633 lines
33 KiB
TypeScript
633 lines
33 KiB
TypeScript
import React, { useState } from 'react';
|
|
import { Users, Camera, Mail, Phone, MapPin, Star, Plus, Search, Filter, User, Upload, X } from 'lucide-react';
|
|
import { Button } from '../components/Button';
|
|
|
|
interface Photographer {
|
|
id: string;
|
|
name: string;
|
|
email: string;
|
|
phone: string;
|
|
location: string;
|
|
specialties: string[];
|
|
rating: number;
|
|
eventsCompleted: number;
|
|
status: 'active' | 'inactive' | 'busy';
|
|
avatar: string;
|
|
joinDate: string;
|
|
}
|
|
|
|
const MOCK_PHOTOGRAPHERS: Photographer[] = [
|
|
{
|
|
id: '1',
|
|
name: 'Carlos Silva',
|
|
email: 'carlos.silva@photum.com',
|
|
phone: '(41) 99999-1111',
|
|
location: 'Curitiba, PR',
|
|
specialties: ['Formaturas', 'Eventos Corporativos'],
|
|
rating: 4.8,
|
|
eventsCompleted: 45,
|
|
status: 'active',
|
|
avatar: 'https://i.pravatar.cc/150?img=12',
|
|
joinDate: '2023-01-15'
|
|
},
|
|
{
|
|
id: '2',
|
|
name: 'Ana Paula Mendes',
|
|
email: 'ana.mendes@photum.com',
|
|
phone: '(41) 99999-2222',
|
|
location: 'Curitiba, PR',
|
|
specialties: ['Casamentos', 'Formaturas'],
|
|
rating: 4.9,
|
|
eventsCompleted: 62,
|
|
status: 'busy',
|
|
avatar: 'https://i.pravatar.cc/150?img=5',
|
|
joinDate: '2022-08-20'
|
|
},
|
|
{
|
|
id: '3',
|
|
name: 'Roberto Costa',
|
|
email: 'roberto.costa@photum.com',
|
|
phone: '(41) 99999-3333',
|
|
location: 'São José dos Pinhais, PR',
|
|
specialties: ['Formaturas', 'Eventos Sociais'],
|
|
rating: 4.7,
|
|
eventsCompleted: 38,
|
|
status: 'active',
|
|
avatar: 'https://i.pravatar.cc/150?img=33',
|
|
joinDate: '2023-03-10'
|
|
},
|
|
{
|
|
id: '4',
|
|
name: 'Juliana Santos',
|
|
email: 'juliana.santos@photum.com',
|
|
phone: '(41) 99999-4444',
|
|
location: 'Curitiba, PR',
|
|
specialties: ['Casamentos', 'Ensaios'],
|
|
rating: 5.0,
|
|
eventsCompleted: 71,
|
|
status: 'active',
|
|
avatar: 'https://i.pravatar.cc/150?img=9',
|
|
joinDate: '2022-05-12'
|
|
},
|
|
{
|
|
id: '5',
|
|
name: 'Fernando Oliveira',
|
|
email: 'fernando.oliveira@photum.com',
|
|
phone: '(41) 99999-5555',
|
|
location: 'Pinhais, PR',
|
|
specialties: ['Eventos Corporativos', 'Formaturas'],
|
|
rating: 4.6,
|
|
eventsCompleted: 29,
|
|
status: 'inactive',
|
|
avatar: 'https://i.pravatar.cc/150?img=15',
|
|
joinDate: '2023-07-01'
|
|
},
|
|
{
|
|
id: '6',
|
|
name: 'Mariana Rodrigues',
|
|
email: 'mariana.rodrigues@photum.com',
|
|
phone: '(41) 99999-6666',
|
|
location: 'Curitiba, PR',
|
|
specialties: ['Formaturas', 'Eventos Sociais', 'Casamentos'],
|
|
rating: 4.9,
|
|
eventsCompleted: 54,
|
|
status: 'busy',
|
|
avatar: 'https://i.pravatar.cc/150?img=10',
|
|
joinDate: '2022-11-05'
|
|
}
|
|
];
|
|
|
|
export const TeamPage: React.FC = () => {
|
|
const [searchTerm, setSearchTerm] = useState('');
|
|
const [statusFilter, setStatusFilter] = useState<'all' | 'active' | 'busy' | 'inactive'>('all');
|
|
const [selectedPhotographer, setSelectedPhotographer] = useState<Photographer | null>(null);
|
|
const [showAddModal, setShowAddModal] = useState(false);
|
|
const [newPhotographer, setNewPhotographer] = useState({
|
|
name: '',
|
|
email: '',
|
|
phone: '',
|
|
location: '',
|
|
specialties: [] as string[],
|
|
avatar: ''
|
|
});
|
|
const [avatarFile, setAvatarFile] = useState<File | null>(null);
|
|
const [avatarPreview, setAvatarPreview] = useState<string>('');
|
|
|
|
const handleAvatarChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
const file = e.target.files?.[0];
|
|
if (file) {
|
|
setAvatarFile(file);
|
|
const reader = new FileReader();
|
|
reader.onloadend = () => {
|
|
setAvatarPreview(reader.result as string);
|
|
};
|
|
reader.readAsDataURL(file);
|
|
}
|
|
};
|
|
|
|
const removeAvatar = () => {
|
|
setAvatarFile(null);
|
|
setAvatarPreview('');
|
|
};
|
|
|
|
const getStatusColor = (status: Photographer['status']) => {
|
|
switch (status) {
|
|
case 'active':
|
|
return 'bg-green-100 text-green-800';
|
|
case 'busy':
|
|
return 'bg-yellow-100 text-yellow-800';
|
|
case 'inactive':
|
|
return 'bg-gray-100 text-gray-800';
|
|
}
|
|
};
|
|
|
|
const getStatusLabel = (status: Photographer['status']) => {
|
|
switch (status) {
|
|
case 'active':
|
|
return 'Disponível';
|
|
case 'busy':
|
|
return 'Em Evento';
|
|
case 'inactive':
|
|
return 'Inativo';
|
|
}
|
|
};
|
|
|
|
const filteredPhotographers = MOCK_PHOTOGRAPHERS.filter(photographer => {
|
|
const matchesSearch = photographer.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
|
photographer.email.toLowerCase().includes(searchTerm.toLowerCase());
|
|
const matchesStatus = statusFilter === 'all' || photographer.status === statusFilter;
|
|
return matchesSearch && matchesStatus;
|
|
});
|
|
|
|
const stats = {
|
|
total: MOCK_PHOTOGRAPHERS.length,
|
|
active: MOCK_PHOTOGRAPHERS.filter(p => p.status === 'active').length,
|
|
busy: MOCK_PHOTOGRAPHERS.filter(p => p.status === 'busy').length,
|
|
avgRating: (MOCK_PHOTOGRAPHERS.reduce((acc, p) => acc + p.rating, 0) / MOCK_PHOTOGRAPHERS.length).toFixed(1)
|
|
};
|
|
|
|
return (
|
|
<div className="min-h-screen bg-gray-50 pt-32 pb-12">
|
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
{/* Header */}
|
|
<div className="mb-8">
|
|
<h1 className="text-3xl font-serif font-bold text-brand-black mb-2">
|
|
Equipe & Fotógrafos
|
|
</h1>
|
|
<p className="text-gray-600">
|
|
Gerencie sua equipe de fotógrafos profissionais
|
|
</p>
|
|
</div>
|
|
|
|
{/* Stats */}
|
|
<div className="grid grid-cols-1 md:grid-cols-4 gap-6 mb-8">
|
|
<div className="bg-white rounded-lg shadow-sm border border-gray-200 p-6">
|
|
<div className="flex items-center justify-between">
|
|
<div>
|
|
<p className="text-sm text-gray-600 mb-1">Total de Fotógrafos</p>
|
|
<p className="text-3xl font-bold text-brand-black">{stats.total}</p>
|
|
</div>
|
|
<Users className="text-brand-gold" size={32} />
|
|
</div>
|
|
</div>
|
|
<div className="bg-white rounded-lg shadow-sm border border-gray-200 p-6">
|
|
<div className="flex items-center justify-between">
|
|
<div>
|
|
<p className="text-sm text-gray-600 mb-1">Disponíveis</p>
|
|
<p className="text-3xl font-bold text-green-600">{stats.active}</p>
|
|
</div>
|
|
<Camera className="text-green-600" size={32} />
|
|
</div>
|
|
</div>
|
|
<div className="bg-white rounded-lg shadow-sm border border-gray-200 p-6">
|
|
<div className="flex items-center justify-between">
|
|
<div>
|
|
<p className="text-sm text-gray-600 mb-1">Em Evento</p>
|
|
<p className="text-3xl font-bold text-yellow-600">{stats.busy}</p>
|
|
</div>
|
|
<Camera className="text-yellow-600" size={32} />
|
|
</div>
|
|
</div>
|
|
<div className="bg-white rounded-lg shadow-sm border border-gray-200 p-6">
|
|
<div className="flex items-center justify-between">
|
|
<div>
|
|
<p className="text-sm text-gray-600 mb-1">Avaliação Média</p>
|
|
<p className="text-3xl font-bold text-brand-gold">{stats.avgRating}</p>
|
|
</div>
|
|
<Star className="text-brand-gold" size={32} fill="#B9CF33" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Filters and Search */}
|
|
<div className="bg-white rounded-lg shadow-sm border border-gray-200 p-6 mb-6">
|
|
<div className="flex flex-col md:flex-row gap-4">
|
|
<div className="flex-1 relative">
|
|
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400" size={20} />
|
|
<input
|
|
type="text"
|
|
placeholder="Buscar por nome ou email..."
|
|
value={searchTerm}
|
|
onChange={(e) => setSearchTerm(e.target.value)}
|
|
className="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-gold"
|
|
/>
|
|
</div>
|
|
<div className="flex gap-2">
|
|
<button
|
|
onClick={() => setStatusFilter('all')}
|
|
className={`px-4 py-2 rounded-md font-medium transition-colors ${statusFilter === 'all'
|
|
? 'bg-brand-gold text-white'
|
|
: 'bg-gray-100 text-gray-700 hover:bg-gray-200'
|
|
}`}
|
|
>
|
|
Todos
|
|
</button>
|
|
<button
|
|
onClick={() => setStatusFilter('active')}
|
|
className={`px-4 py-2 rounded-md font-medium transition-colors ${statusFilter === 'active'
|
|
? 'bg-green-600 text-white'
|
|
: 'bg-gray-100 text-gray-700 hover:bg-gray-200'
|
|
}`}
|
|
>
|
|
Disponíveis
|
|
</button>
|
|
<button
|
|
onClick={() => setStatusFilter('busy')}
|
|
className={`px-4 py-2 rounded-md font-medium transition-colors ${statusFilter === 'busy'
|
|
? 'bg-yellow-600 text-white'
|
|
: 'bg-gray-100 text-gray-700 hover:bg-gray-200'
|
|
}`}
|
|
>
|
|
Em Evento
|
|
</button>
|
|
</div>
|
|
<Button size="md" variant="secondary" onClick={() => setShowAddModal(true)}>
|
|
<Plus size={20} className="mr-2" />
|
|
Adicionar Fotógrafo
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Photographers Grid */}
|
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
|
{filteredPhotographers.map((photographer) => (
|
|
<div
|
|
key={photographer.id}
|
|
className="bg-white rounded-lg shadow-sm border border-gray-200 overflow-hidden hover:shadow-md transition-shadow cursor-pointer"
|
|
onClick={() => setSelectedPhotographer(photographer)}
|
|
>
|
|
<div className="p-6">
|
|
<div className="flex items-start justify-between mb-4">
|
|
<div className="flex items-center gap-3">
|
|
<img
|
|
src={photographer.avatar}
|
|
alt={photographer.name}
|
|
className="w-16 h-16 rounded-full object-cover"
|
|
/>
|
|
<div>
|
|
<h3 className="font-semibold text-lg text-brand-black">{photographer.name}</h3>
|
|
<div className="flex items-center gap-1 mt-1">
|
|
<Star size={14} fill="#B9CF33" className="text-brand-gold" />
|
|
<span className="text-sm font-medium">{photographer.rating}</span>
|
|
<span className="text-xs text-gray-500">({photographer.eventsCompleted} eventos)</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<span className={`px-2 py-1 rounded-full text-xs font-medium ${getStatusColor(photographer.status)}`}>
|
|
{getStatusLabel(photographer.status)}
|
|
</span>
|
|
</div>
|
|
|
|
<div className="space-y-2 mb-4">
|
|
<div className="flex items-center text-sm text-gray-600">
|
|
<Mail size={16} className="mr-2 text-brand-gold" />
|
|
{photographer.email}
|
|
</div>
|
|
<div className="flex items-center text-sm text-gray-600">
|
|
<Phone size={16} className="mr-2 text-brand-gold" />
|
|
{photographer.phone}
|
|
</div>
|
|
<div className="flex items-center text-sm text-gray-600">
|
|
<MapPin size={16} className="mr-2 text-brand-gold" />
|
|
{photographer.location}
|
|
</div>
|
|
</div>
|
|
|
|
<div className="flex flex-wrap gap-2">
|
|
{photographer.specialties.map((specialty, index) => (
|
|
<span
|
|
key={index}
|
|
className="px-2 py-1 bg-gray-100 text-gray-700 rounded-full text-xs font-medium"
|
|
>
|
|
{specialty}
|
|
</span>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
{filteredPhotographers.length === 0 && (
|
|
<div className="text-center py-12">
|
|
<Users size={48} className="mx-auto text-gray-300 mb-4" />
|
|
<p className="text-gray-500">Nenhum fotógrafo encontrado</p>
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
{/* Add Photographer Modal */}
|
|
{showAddModal && (
|
|
<div
|
|
className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4"
|
|
onClick={() => setShowAddModal(false)}
|
|
>
|
|
<div
|
|
className="bg-white rounded-lg max-w-2xl w-full p-8 max-h-[90vh] overflow-y-auto"
|
|
onClick={(e) => e.stopPropagation()}
|
|
>
|
|
<div className="flex items-center justify-between mb-6">
|
|
<h2 className="text-2xl font-serif font-bold text-brand-black">
|
|
Adicionar Novo Fotógrafo
|
|
</h2>
|
|
<button
|
|
onClick={() => setShowAddModal(false)}
|
|
className="text-gray-400 hover:text-gray-600"
|
|
>
|
|
✕
|
|
</button>
|
|
</div>
|
|
|
|
<form className="space-y-6" onSubmit={(e) => {
|
|
e.preventDefault();
|
|
alert('Fotógrafo adicionado com sucesso!\n\n' + JSON.stringify({...newPhotographer, avatarFile: avatarFile?.name}, null, 2));
|
|
setShowAddModal(false);
|
|
setNewPhotographer({
|
|
name: '',
|
|
email: '',
|
|
phone: '',
|
|
location: '',
|
|
specialties: [],
|
|
avatar: ''
|
|
});
|
|
setAvatarFile(null);
|
|
setAvatarPreview('');
|
|
}}>
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
|
Foto de Perfil
|
|
</label>
|
|
<div className="flex items-center gap-4">
|
|
{avatarPreview ? (
|
|
<div className="relative">
|
|
<img
|
|
src={avatarPreview}
|
|
alt="Preview"
|
|
className="w-24 h-24 rounded-full object-cover border-2 border-gray-200"
|
|
/>
|
|
<button
|
|
type="button"
|
|
onClick={removeAvatar}
|
|
className="absolute -top-2 -right-2 bg-red-500 text-white rounded-full p-1 hover:bg-red-600 transition-colors"
|
|
>
|
|
<X size={16} />
|
|
</button>
|
|
</div>
|
|
) : (
|
|
<div className="w-24 h-24 rounded-full bg-gray-100 border-2 border-dashed border-gray-300 flex items-center justify-center">
|
|
<Camera size={32} className="text-gray-400" />
|
|
</div>
|
|
)}
|
|
<div className="flex-1">
|
|
<label className="cursor-pointer">
|
|
<div className="flex items-center gap-2 px-4 py-2 bg-gray-50 border border-gray-300 rounded-md hover:bg-gray-100 transition-colors w-fit">
|
|
<Upload size={18} className="text-gray-600" />
|
|
<span className="text-sm font-medium text-gray-700">
|
|
{avatarFile ? 'Trocar foto' : 'Selecionar foto'}
|
|
</span>
|
|
</div>
|
|
<input
|
|
type="file"
|
|
accept="image/*"
|
|
onChange={handleAvatarChange}
|
|
className="hidden"
|
|
/>
|
|
</label>
|
|
<p className="text-xs text-gray-500 mt-1">JPG, PNG ou GIF (máx. 5MB)</p>
|
|
{avatarFile && (
|
|
<p className="text-xs text-brand-gold mt-1 font-medium">{avatarFile.name}</p>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
|
Nome Completo *
|
|
</label>
|
|
<div className="relative">
|
|
<User className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400" size={20} />
|
|
<input
|
|
type="text"
|
|
required
|
|
value={newPhotographer.name}
|
|
onChange={(e) => setNewPhotographer({ ...newPhotographer, name: e.target.value })}
|
|
placeholder="Ex: João Silva"
|
|
className="w-full pl-10 pr-4 py-3 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-gold"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
|
Email *
|
|
</label>
|
|
<div className="relative">
|
|
<Mail className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400" size={20} />
|
|
<input
|
|
type="email"
|
|
required
|
|
value={newPhotographer.email}
|
|
onChange={(e) => setNewPhotographer({ ...newPhotographer, email: e.target.value })}
|
|
placeholder="joao.silva@photum.com"
|
|
className="w-full pl-10 pr-4 py-3 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-gold"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
|
Telefone *
|
|
</label>
|
|
<div className="relative">
|
|
<Phone className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400" size={20} />
|
|
<input
|
|
type="tel"
|
|
required
|
|
value={newPhotographer.phone}
|
|
onChange={(e) => setNewPhotographer({ ...newPhotographer, phone: e.target.value })}
|
|
placeholder="(41) 99999-0000"
|
|
className="w-full pl-10 pr-4 py-3 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-gold"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
|
Localização *
|
|
</label>
|
|
<div className="relative">
|
|
<MapPin className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400" size={20} />
|
|
<input
|
|
type="text"
|
|
required
|
|
value={newPhotographer.location}
|
|
onChange={(e) => setNewPhotographer({ ...newPhotographer, location: e.target.value })}
|
|
placeholder="Curitiba, PR"
|
|
className="w-full pl-10 pr-4 py-3 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-gold"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
|
Especialidades
|
|
</label>
|
|
<div className="space-y-2">
|
|
{['Formaturas', 'Casamentos', 'Eventos Corporativos', 'Eventos Sociais', 'Ensaios'].map((specialty) => (
|
|
<label key={specialty} className="flex items-center gap-2 cursor-pointer">
|
|
<input
|
|
type="checkbox"
|
|
checked={newPhotographer.specialties.includes(specialty)}
|
|
onChange={(e) => {
|
|
if (e.target.checked) {
|
|
setNewPhotographer({
|
|
...newPhotographer,
|
|
specialties: [...newPhotographer.specialties, specialty]
|
|
});
|
|
} else {
|
|
setNewPhotographer({
|
|
...newPhotographer,
|
|
specialties: newPhotographer.specialties.filter(s => s !== specialty)
|
|
});
|
|
}
|
|
}}
|
|
className="w-4 h-4 text-brand-gold focus:ring-brand-gold border-gray-300 rounded"
|
|
/>
|
|
<span className="text-sm text-gray-700">{specialty}</span>
|
|
</label>
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
<div className="pt-6 border-t border-gray-200 flex gap-3">
|
|
<button
|
|
type="button"
|
|
onClick={() => setShowAddModal(false)}
|
|
className="flex-1 px-6 py-3 bg-gray-100 text-gray-700 rounded-md hover:bg-gray-200 transition-colors font-medium"
|
|
>
|
|
Cancelar
|
|
</button>
|
|
<button
|
|
type="submit"
|
|
className="flex-1 px-6 py-3 bg-brand-gold text-white rounded-md hover:bg-[#a5bd2e] transition-colors font-medium"
|
|
>
|
|
Adicionar Fotógrafo
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Photographer Detail Modal */}
|
|
{selectedPhotographer && (
|
|
<div
|
|
className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4"
|
|
onClick={() => setSelectedPhotographer(null)}
|
|
>
|
|
<div
|
|
className="bg-white rounded-lg max-w-2xl w-full p-8"
|
|
onClick={(e) => e.stopPropagation()}
|
|
>
|
|
<div className="flex items-start gap-4 mb-6">
|
|
<img
|
|
src={selectedPhotographer.avatar}
|
|
alt={selectedPhotographer.name}
|
|
className="w-24 h-24 rounded-full object-cover"
|
|
/>
|
|
<div className="flex-1">
|
|
<div className="flex items-start justify-between">
|
|
<div>
|
|
<h2 className="text-2xl font-serif font-bold text-brand-black mb-1">
|
|
{selectedPhotographer.name}
|
|
</h2>
|
|
<div className="flex items-center gap-2 mb-2">
|
|
<Star size={18} fill="#B9CF33" className="text-brand-gold" />
|
|
<span className="font-semibold">{selectedPhotographer.rating}</span>
|
|
<span className="text-sm text-gray-500">
|
|
({selectedPhotographer.eventsCompleted} eventos concluídos)
|
|
</span>
|
|
</div>
|
|
<span className={`inline-block px-3 py-1 rounded-full text-xs font-medium ${getStatusColor(selectedPhotographer.status)}`}>
|
|
{getStatusLabel(selectedPhotographer.status)}
|
|
</span>
|
|
</div>
|
|
<button
|
|
onClick={() => setSelectedPhotographer(null)}
|
|
className="text-gray-400 hover:text-gray-600"
|
|
>
|
|
✕
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="space-y-4 mb-6">
|
|
<div className="flex items-center text-gray-700">
|
|
<Mail size={20} className="mr-3 text-brand-gold" />
|
|
<span>{selectedPhotographer.email}</span>
|
|
</div>
|
|
<div className="flex items-center text-gray-700">
|
|
<Phone size={20} className="mr-3 text-brand-gold" />
|
|
<span>{selectedPhotographer.phone}</span>
|
|
</div>
|
|
<div className="flex items-center text-gray-700">
|
|
<MapPin size={20} className="mr-3 text-brand-gold" />
|
|
<span>{selectedPhotographer.location}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="mb-6">
|
|
<h3 className="font-semibold mb-2">Especialidades</h3>
|
|
<div className="flex flex-wrap gap-2">
|
|
{selectedPhotographer.specialties.map((specialty, index) => (
|
|
<span
|
|
key={index}
|
|
className="px-3 py-1 bg-brand-gold/10 text-brand-gold rounded-full text-sm font-medium"
|
|
>
|
|
{specialty}
|
|
</span>
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
<div className="pt-6 border-t border-gray-200 flex gap-3">
|
|
<button
|
|
onClick={() => setSelectedPhotographer(null)}
|
|
className="flex-1 px-6 py-3 bg-gray-100 text-gray-700 rounded-md hover:bg-gray-200 transition-colors font-medium"
|
|
>
|
|
Fechar
|
|
</button>
|
|
<button
|
|
className="flex-1 px-6 py-3 bg-brand-gold text-white rounded-md hover:bg-[#a5bd2e] transition-colors font-medium"
|
|
>
|
|
Ver Agenda
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|