- Renomear 'Equipe & Fotógrafos' para 'Equipe' no título e navbar - Adicionar suporte para 3 tipos de profissionais: Fotógrafo, Cinegrafista, Recepcionista - Implementar cards estatísticos separados por função profissional - Adicionar filtros por função (Fotógrafos, Cinegrafistas, Recepcionistas) - Adicionar filtros por status (Disponível, Em Evento, Inativo) - Transformar cards em tabela responsiva com colunas: Nome, Função Profissional, Disponibilidade - Expandir interface Professional com campos completos do Excel: * Endereço completo (rua, número, complemento, bairro, cidade, UF) * Dados bancários (banco, agência, conta/pix, tipo cartão, titular) * Recursos (carro disponível, possui estúdio, quantidade) * Sistema de avaliações detalhado (6 critérios + média) * Valores (tabela free, extra no cachê) * Observações - Redesenhar modal 'Adicionar Profissional' com formulário extenso organizado em seções - Atualizar modal de detalhes com todas as novas informações - Adicionar ícones específicos por função (Camera, Video, UserCheck) - Remover fotos da tabela mantendo apenas informações essenciais
1343 lines
52 KiB
TypeScript
1343 lines
52 KiB
TypeScript
import React, { useState } from "react";
|
|
import {
|
|
Users,
|
|
Camera,
|
|
Mail,
|
|
Phone,
|
|
MapPin,
|
|
Star,
|
|
Plus,
|
|
Search,
|
|
Filter,
|
|
User,
|
|
Upload,
|
|
X,
|
|
Video,
|
|
UserCheck,
|
|
Car,
|
|
Building,
|
|
CreditCard,
|
|
TrendingUp,
|
|
} from "lucide-react";
|
|
import { Button } from "../components/Button";
|
|
|
|
type ProfessionalRole = "Fotógrafo" | "Cinegrafista" | "Recepcionista";
|
|
|
|
interface Professional {
|
|
id: string;
|
|
name: string;
|
|
role: ProfessionalRole;
|
|
address: {
|
|
street: string;
|
|
number: string;
|
|
complement?: string;
|
|
neighborhood: string;
|
|
city: string;
|
|
state: string;
|
|
};
|
|
whatsapp: string;
|
|
cpfCnpj: string;
|
|
bankInfo: {
|
|
bank: string;
|
|
agency: string;
|
|
accountPix: string;
|
|
};
|
|
hasCar: boolean;
|
|
hasStudio: boolean;
|
|
studioQuantity?: number;
|
|
cardType: string;
|
|
accountHolder: string;
|
|
observations?: string;
|
|
ratings: {
|
|
technicalQuality: number;
|
|
appearance: number;
|
|
education: number;
|
|
sympathy: number;
|
|
eventPerformance: number;
|
|
scheduleAvailability: number;
|
|
average: number;
|
|
};
|
|
freeTable: string;
|
|
extraFee: string;
|
|
email: string;
|
|
specialties: string[];
|
|
eventsCompleted: number;
|
|
status: "active" | "inactive" | "busy";
|
|
avatar: string;
|
|
joinDate: string;
|
|
}
|
|
|
|
const MOCK_PROFESSIONALS: Professional[] = [
|
|
{
|
|
id: "1",
|
|
name: "Carlos Silva",
|
|
role: "Fotógrafo",
|
|
address: {
|
|
street: "Rua das Flores",
|
|
number: "123",
|
|
complement: "Apto 301",
|
|
neighborhood: "Centro",
|
|
city: "Curitiba",
|
|
state: "PR",
|
|
},
|
|
whatsapp: "(41) 99999-1111",
|
|
cpfCnpj: "123.456.789-00",
|
|
bankInfo: {
|
|
bank: "Banco do Brasil",
|
|
agency: "1234-5",
|
|
accountPix: "carlos.silva@email.com",
|
|
},
|
|
hasCar: true,
|
|
hasStudio: false,
|
|
cardType: "Débito/Crédito",
|
|
accountHolder: "Carlos Silva",
|
|
ratings: {
|
|
technicalQuality: 4.8,
|
|
appearance: 4.7,
|
|
education: 4.9,
|
|
sympathy: 4.8,
|
|
eventPerformance: 4.9,
|
|
scheduleAvailability: 4.6,
|
|
average: 4.8,
|
|
},
|
|
freeTable: "R$ 800,00",
|
|
extraFee: "R$ 150,00 por equipamento extra",
|
|
email: "carlos.silva@photum.com",
|
|
specialties: ["Formaturas", "Eventos Corporativos"],
|
|
eventsCompleted: 45,
|
|
status: "active",
|
|
avatar: "https://i.pravatar.cc/150?img=12",
|
|
joinDate: "2023-01-15",
|
|
},
|
|
{
|
|
id: "2",
|
|
name: "Ana Paula Mendes",
|
|
role: "Cinegrafista",
|
|
address: {
|
|
street: "Av. Sete de Setembro",
|
|
number: "456",
|
|
neighborhood: "Batel",
|
|
city: "Curitiba",
|
|
state: "PR",
|
|
},
|
|
whatsapp: "(41) 99999-2222",
|
|
cpfCnpj: "987.654.321-00",
|
|
bankInfo: {
|
|
bank: "Caixa Econômica",
|
|
agency: "0987",
|
|
accountPix: "(41) 99999-2222",
|
|
},
|
|
hasCar: true,
|
|
hasStudio: true,
|
|
studioQuantity: 1,
|
|
cardType: "Crédito",
|
|
accountHolder: "Ana Paula Mendes",
|
|
ratings: {
|
|
technicalQuality: 4.9,
|
|
appearance: 5.0,
|
|
education: 4.8,
|
|
sympathy: 4.9,
|
|
eventPerformance: 4.9,
|
|
scheduleAvailability: 4.7,
|
|
average: 4.9,
|
|
},
|
|
freeTable: "R$ 1.200,00",
|
|
extraFee: "R$ 200,00 por hora extra",
|
|
email: "ana.mendes@photum.com",
|
|
specialties: ["Casamentos", "Formaturas"],
|
|
eventsCompleted: 62,
|
|
status: "busy",
|
|
avatar: "https://i.pravatar.cc/150?img=5",
|
|
joinDate: "2022-08-20",
|
|
},
|
|
{
|
|
id: "3",
|
|
name: "Mariana Alves",
|
|
role: "Recepcionista",
|
|
address: {
|
|
street: "Rua Comendador Araújo",
|
|
number: "321",
|
|
complement: "Sala 12",
|
|
neighborhood: "Centro",
|
|
city: "Curitiba",
|
|
state: "PR",
|
|
},
|
|
whatsapp: "(41) 99999-4444",
|
|
cpfCnpj: "321.654.987-00",
|
|
bankInfo: {
|
|
bank: "Bradesco",
|
|
agency: "4321",
|
|
accountPix: "mariana.alves@email.com",
|
|
},
|
|
hasCar: false,
|
|
hasStudio: false,
|
|
cardType: "Débito",
|
|
accountHolder: "Mariana Alves Santos",
|
|
ratings: {
|
|
technicalQuality: 0,
|
|
appearance: 4.9,
|
|
education: 5.0,
|
|
sympathy: 5.0,
|
|
eventPerformance: 4.8,
|
|
scheduleAvailability: 4.9,
|
|
average: 4.9,
|
|
},
|
|
freeTable: "R$ 400,00",
|
|
extraFee: "R$ 50,00 por hora extra",
|
|
email: "mariana.alves@photum.com",
|
|
specialties: ["Recepção", "Atendimento"],
|
|
eventsCompleted: 71,
|
|
status: "active",
|
|
avatar: "https://i.pravatar.cc/150?img=9",
|
|
joinDate: "2022-05-12",
|
|
},
|
|
];
|
|
|
|
export const TeamPage: React.FC = () => {
|
|
const [searchTerm, setSearchTerm] = useState("");
|
|
const [roleFilter, setRoleFilter] = useState<ProfessionalRole | "all">("all");
|
|
const [statusFilter, setStatusFilter] = useState<
|
|
"all" | "active" | "busy" | "inactive"
|
|
>("all");
|
|
const [selectedProfessional, setSelectedProfessional] =
|
|
useState<Professional | null>(null);
|
|
const [showAddModal, setShowAddModal] = useState(false);
|
|
|
|
const [newProfessional, setNewProfessional] = useState<Partial<Professional>>({
|
|
name: "",
|
|
role: "Fotógrafo",
|
|
address: {
|
|
street: "",
|
|
number: "",
|
|
complement: "",
|
|
neighborhood: "",
|
|
city: "",
|
|
state: "",
|
|
},
|
|
whatsapp: "",
|
|
cpfCnpj: "",
|
|
bankInfo: {
|
|
bank: "",
|
|
agency: "",
|
|
accountPix: "",
|
|
},
|
|
hasCar: false,
|
|
hasStudio: false,
|
|
studioQuantity: 0,
|
|
cardType: "",
|
|
accountHolder: "",
|
|
observations: "",
|
|
ratings: {
|
|
technicalQuality: 0,
|
|
appearance: 0,
|
|
education: 0,
|
|
sympathy: 0,
|
|
eventPerformance: 0,
|
|
scheduleAvailability: 0,
|
|
average: 0,
|
|
},
|
|
freeTable: "",
|
|
extraFee: "",
|
|
email: "",
|
|
specialties: [],
|
|
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: Professional["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: Professional["status"]) => {
|
|
switch (status) {
|
|
case "active":
|
|
return "Disponível";
|
|
case "busy":
|
|
return "Em Evento";
|
|
case "inactive":
|
|
return "Inativo";
|
|
}
|
|
};
|
|
|
|
const getRoleIcon = (role: ProfessionalRole) => {
|
|
switch (role) {
|
|
case "Fotógrafo":
|
|
return Camera;
|
|
case "Cinegrafista":
|
|
return Video;
|
|
case "Recepcionista":
|
|
return UserCheck;
|
|
}
|
|
};
|
|
|
|
const filteredProfessionals = MOCK_PROFESSIONALS.filter((professional) => {
|
|
const matchesSearch =
|
|
professional.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
|
professional.email.toLowerCase().includes(searchTerm.toLowerCase());
|
|
const matchesRole = roleFilter === "all" || professional.role === roleFilter;
|
|
const matchesStatus =
|
|
statusFilter === "all" || professional.status === statusFilter;
|
|
return matchesSearch && matchesRole && matchesStatus;
|
|
});
|
|
|
|
const stats = {
|
|
photographers: MOCK_PROFESSIONALS.filter((p) => p.role === "Fotógrafo").length,
|
|
cinematographers: MOCK_PROFESSIONALS.filter((p) => p.role === "Cinegrafista").length,
|
|
receptionists: MOCK_PROFESSIONALS.filter((p) => p.role === "Recepcionista").length,
|
|
total: MOCK_PROFESSIONALS.length,
|
|
};
|
|
|
|
return (
|
|
<div className="min-h-screen bg-gray-50 pt-20 sm:pt-24 md:pt-28 lg:pt-32 pb-8 sm:pb-12">
|
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
{/* Header */}
|
|
<div className="mb-6 sm:mb-8">
|
|
<h1 className="text-2xl sm:text-3xl font-serif font-bold text-brand-black mb-2">
|
|
Equipe
|
|
</h1>
|
|
<p className="text-sm sm:text-base text-gray-600">
|
|
Gerencie sua equipe de profissionais
|
|
</p>
|
|
</div>
|
|
|
|
{/* Stats */}
|
|
<div className="grid grid-cols-1 sm:grid-cols-3 gap-3 sm:gap-4 md:gap-6 mb-6 sm: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.photographers}
|
|
</p>
|
|
</div>
|
|
<Camera 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">Total de Cinegrafistas</p>
|
|
<p className="text-3xl font-bold text-brand-black">
|
|
{stats.cinematographers}
|
|
</p>
|
|
</div>
|
|
<Video className="text-blue-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">Total de Recepcionistas</p>
|
|
<p className="text-3xl font-bold text-brand-black">
|
|
{stats.receptionists}
|
|
</p>
|
|
</div>
|
|
<UserCheck className="text-purple-600" size={32} />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Filters and Search */}
|
|
<div className="bg-white rounded-lg shadow-sm border border-gray-200 p-3 sm:p-4 md:p-6 mb-4 sm:mb-6">
|
|
<div className="flex flex-col gap-3 sm: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 flex-wrap gap-2">
|
|
<button
|
|
onClick={() => setRoleFilter("all")}
|
|
className={`px-4 py-2 rounded-md font-medium transition-colors ${
|
|
roleFilter === "all"
|
|
? "bg-brand-gold text-white"
|
|
: "bg-gray-100 text-gray-700 hover:bg-gray-200"
|
|
}`}
|
|
>
|
|
Todos
|
|
</button>
|
|
<button
|
|
onClick={() => setRoleFilter("Fotógrafo")}
|
|
className={`px-4 py-2 rounded-md font-medium transition-colors ${
|
|
roleFilter === "Fotógrafo"
|
|
? "bg-brand-gold text-white"
|
|
: "bg-gray-100 text-gray-700 hover:bg-gray-200"
|
|
}`}
|
|
>
|
|
Fotógrafos
|
|
</button>
|
|
<button
|
|
onClick={() => setRoleFilter("Cinegrafista")}
|
|
className={`px-4 py-2 rounded-md font-medium transition-colors ${
|
|
roleFilter === "Cinegrafista"
|
|
? "bg-blue-600 text-white"
|
|
: "bg-gray-100 text-gray-700 hover:bg-gray-200"
|
|
}`}
|
|
>
|
|
Cinegrafistas
|
|
</button>
|
|
<button
|
|
onClick={() => setRoleFilter("Recepcionista")}
|
|
className={`px-4 py-2 rounded-md font-medium transition-colors ${
|
|
roleFilter === "Recepcionista"
|
|
? "bg-purple-600 text-white"
|
|
: "bg-gray-100 text-gray-700 hover:bg-gray-200"
|
|
}`}
|
|
>
|
|
Recepcionistas
|
|
</button>
|
|
</div>
|
|
|
|
{/* Status Filters */}
|
|
<div className="flex flex-wrap 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 Status
|
|
</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ível
|
|
</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>
|
|
<button
|
|
onClick={() => setStatusFilter("inactive")}
|
|
className={`px-4 py-2 rounded-md font-medium transition-colors ${
|
|
statusFilter === "inactive"
|
|
? "bg-gray-600 text-white"
|
|
: "bg-gray-100 text-gray-700 hover:bg-gray-200"
|
|
}`}
|
|
>
|
|
Inativo
|
|
</button>
|
|
</div>
|
|
|
|
<Button
|
|
size="md"
|
|
variant="secondary"
|
|
onClick={() => setShowAddModal(true)}
|
|
>
|
|
<Plus size={20} className="mr-2" />
|
|
Adicionar Profissional
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Professionals Table */}
|
|
<div className="bg-white rounded-lg shadow-sm border border-gray-200 overflow-hidden">
|
|
{filteredProfessionals.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 profissional encontrado</p>
|
|
</div>
|
|
) : (
|
|
<div className="overflow-x-auto">
|
|
<table className="w-full">
|
|
<thead className="bg-gray-50 border-b border-gray-200">
|
|
<tr>
|
|
<th className="px-6 py-4 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
|
Nome
|
|
</th>
|
|
<th className="px-6 py-4 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
|
Função Profissional
|
|
</th>
|
|
<th className="px-6 py-4 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
|
Disponibilidade
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody className="bg-white divide-y divide-gray-200">
|
|
{filteredProfessionals.map((professional) => {
|
|
const RoleIcon = getRoleIcon(professional.role);
|
|
return (
|
|
<tr
|
|
key={professional.id}
|
|
className="hover:bg-gray-50 cursor-pointer transition-colors"
|
|
onClick={() => setSelectedProfessional(professional)}
|
|
>
|
|
<td className="px-6 py-4 whitespace-nowrap">
|
|
<div className="flex items-center gap-3">
|
|
<div>
|
|
<div className="font-semibold text-brand-black">
|
|
{professional.name}
|
|
</div>
|
|
<div className="flex items-center gap-1 mt-1">
|
|
<Star
|
|
size={14}
|
|
fill="#B9CF33"
|
|
className="text-brand-gold"
|
|
/>
|
|
<span className="text-sm font-medium text-gray-600">
|
|
{professional.ratings.average.toFixed(1)}
|
|
</span>
|
|
<span className="text-xs text-gray-500">
|
|
({professional.eventsCompleted} eventos)
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</td>
|
|
<td className="px-6 py-4 whitespace-nowrap">
|
|
<div className="flex items-center gap-2">
|
|
<RoleIcon size={18} className="text-brand-gold" />
|
|
<span className="text-sm font-medium text-gray-900">
|
|
{professional.role}
|
|
</span>
|
|
</div>
|
|
</td>
|
|
<td className="px-6 py-4 whitespace-nowrap">
|
|
<span
|
|
className={`px-3 py-1 rounded-full text-sm font-medium ${getStatusColor(
|
|
professional.status
|
|
)}`}
|
|
>
|
|
{getStatusLabel(professional.status)}
|
|
</span>
|
|
</td>
|
|
</tr>
|
|
);
|
|
})}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
|
|
{/* Add Professional Modal - com todos os campos da planilha */}
|
|
{showAddModal && (
|
|
<div
|
|
className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4 overflow-y-auto"
|
|
onClick={() => setShowAddModal(false)}
|
|
>
|
|
<div
|
|
className="bg-white rounded-lg max-w-4xl w-full p-8 max-h-[90vh] overflow-y-auto my-8"
|
|
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 Profissional
|
|
</h2>
|
|
<button
|
|
onClick={() => setShowAddModal(false)}
|
|
className="text-gray-400 hover:text-gray-600"
|
|
>
|
|
<X size={24} />
|
|
</button>
|
|
</div>
|
|
|
|
<form
|
|
className="space-y-6"
|
|
onSubmit={(e) => {
|
|
e.preventDefault();
|
|
alert("Profissional adicionado com sucesso!");
|
|
setShowAddModal(false);
|
|
}}
|
|
>
|
|
{/* Dados Básicos */}
|
|
<div className="space-y-4">
|
|
<h3 className="text-lg font-semibold text-gray-900 border-b pb-2">
|
|
Dados Básicos
|
|
</h3>
|
|
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
|
Nome *
|
|
</label>
|
|
<input
|
|
type="text"
|
|
required
|
|
value={newProfessional.name}
|
|
onChange={(e) =>
|
|
setNewProfessional({ ...newProfessional, name: e.target.value })
|
|
}
|
|
placeholder="Nome completo"
|
|
className="w-full px-4 py-3 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-gold"
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
|
Função Profissional *
|
|
</label>
|
|
<select
|
|
required
|
|
value={newProfessional.role}
|
|
onChange={(e) =>
|
|
setNewProfessional({
|
|
...newProfessional,
|
|
role: e.target.value as ProfessionalRole,
|
|
})
|
|
}
|
|
className="w-full px-4 py-3 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-gold"
|
|
>
|
|
<option value="Fotógrafo">Fotógrafo</option>
|
|
<option value="Cinegrafista">Cinegrafista</option>
|
|
<option value="Recepcionista">Recepcionista</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
|
Email *
|
|
</label>
|
|
<input
|
|
type="email"
|
|
required
|
|
value={newProfessional.email}
|
|
onChange={(e) =>
|
|
setNewProfessional({ ...newProfessional, email: e.target.value })
|
|
}
|
|
placeholder="email@exemplo.com"
|
|
className="w-full px-4 py-3 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-gold"
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
|
WhatsApp *
|
|
</label>
|
|
<input
|
|
type="tel"
|
|
required
|
|
value={newProfessional.whatsapp}
|
|
onChange={(e) =>
|
|
setNewProfessional({ ...newProfessional, whatsapp: e.target.value })
|
|
}
|
|
placeholder="(00) 00000-0000"
|
|
className="w-full px-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">
|
|
CPF ou CNPJ - do Titular da Conta *
|
|
</label>
|
|
<input
|
|
type="text"
|
|
required
|
|
value={newProfessional.cpfCnpj}
|
|
onChange={(e) =>
|
|
setNewProfessional({ ...newProfessional, cpfCnpj: e.target.value })
|
|
}
|
|
placeholder="000.000.000-00 ou 00.000.000/0000-00"
|
|
className="w-full px-4 py-3 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-gold"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Endereço */}
|
|
<div className="space-y-4">
|
|
<h3 className="text-lg font-semibold text-gray-900 border-b pb-2">
|
|
Endereço
|
|
</h3>
|
|
|
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
|
<div className="md:col-span-2">
|
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
|
Rua *
|
|
</label>
|
|
<input
|
|
type="text"
|
|
required
|
|
value={newProfessional.address?.street}
|
|
onChange={(e) =>
|
|
setNewProfessional({
|
|
...newProfessional,
|
|
address: { ...newProfessional.address!, street: e.target.value },
|
|
})
|
|
}
|
|
placeholder="Nome da rua"
|
|
className="w-full px-4 py-3 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-gold"
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
|
Número *
|
|
</label>
|
|
<input
|
|
type="text"
|
|
required
|
|
value={newProfessional.address?.number}
|
|
onChange={(e) =>
|
|
setNewProfessional({
|
|
...newProfessional,
|
|
address: { ...newProfessional.address!, number: e.target.value },
|
|
})
|
|
}
|
|
placeholder="123"
|
|
className="w-full px-4 py-3 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-gold"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
|
Complemento
|
|
</label>
|
|
<input
|
|
type="text"
|
|
value={newProfessional.address?.complement}
|
|
onChange={(e) =>
|
|
setNewProfessional({
|
|
...newProfessional,
|
|
address: { ...newProfessional.address!, complement: e.target.value },
|
|
})
|
|
}
|
|
placeholder="Apto, Sala, etc"
|
|
className="w-full px-4 py-3 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-gold"
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
|
Bairro *
|
|
</label>
|
|
<input
|
|
type="text"
|
|
required
|
|
value={newProfessional.address?.neighborhood}
|
|
onChange={(e) =>
|
|
setNewProfessional({
|
|
...newProfessional,
|
|
address: { ...newProfessional.address!, neighborhood: e.target.value },
|
|
})
|
|
}
|
|
placeholder="Nome do bairro"
|
|
className="w-full px-4 py-3 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-gold"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
|
Cidade *
|
|
</label>
|
|
<input
|
|
type="text"
|
|
required
|
|
value={newProfessional.address?.city}
|
|
onChange={(e) =>
|
|
setNewProfessional({
|
|
...newProfessional,
|
|
address: { ...newProfessional.address!, city: e.target.value },
|
|
})
|
|
}
|
|
placeholder="Nome da cidade"
|
|
className="w-full px-4 py-3 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-gold"
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
|
UF *
|
|
</label>
|
|
<input
|
|
type="text"
|
|
required
|
|
maxLength={2}
|
|
value={newProfessional.address?.state}
|
|
onChange={(e) =>
|
|
setNewProfessional({
|
|
...newProfessional,
|
|
address: { ...newProfessional.address!, state: e.target.value.toUpperCase() },
|
|
})
|
|
}
|
|
placeholder="SP"
|
|
className="w-full px-4 py-3 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-gold"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Dados Bancários */}
|
|
<div className="space-y-4">
|
|
<h3 className="text-lg font-semibold text-gray-900 border-b pb-2">
|
|
Dados Bancários
|
|
</h3>
|
|
|
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
|
Banco *
|
|
</label>
|
|
<input
|
|
type="text"
|
|
required
|
|
value={newProfessional.bankInfo?.bank}
|
|
onChange={(e) =>
|
|
setNewProfessional({
|
|
...newProfessional,
|
|
bankInfo: { ...newProfessional.bankInfo!, bank: e.target.value },
|
|
})
|
|
}
|
|
placeholder="Nome do banco"
|
|
className="w-full px-4 py-3 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-gold"
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
|
Agência *
|
|
</label>
|
|
<input
|
|
type="text"
|
|
required
|
|
value={newProfessional.bankInfo?.agency}
|
|
onChange={(e) =>
|
|
setNewProfessional({
|
|
...newProfessional,
|
|
bankInfo: { ...newProfessional.bankInfo!, agency: e.target.value },
|
|
})
|
|
}
|
|
placeholder="0000-0"
|
|
className="w-full px-4 py-3 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-gold"
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
|
Conta / Pix *
|
|
</label>
|
|
<input
|
|
type="text"
|
|
required
|
|
value={newProfessional.bankInfo?.accountPix}
|
|
onChange={(e) =>
|
|
setNewProfessional({
|
|
...newProfessional,
|
|
bankInfo: { ...newProfessional.bankInfo!, accountPix: e.target.value },
|
|
})
|
|
}
|
|
placeholder="Conta ou chave Pix"
|
|
className="w-full px-4 py-3 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-gold"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
|
Tipo Cartão *
|
|
</label>
|
|
<input
|
|
type="text"
|
|
required
|
|
value={newProfessional.cardType}
|
|
onChange={(e) =>
|
|
setNewProfessional({ ...newProfessional, cardType: e.target.value })
|
|
}
|
|
placeholder="Débito, Crédito, Pix, etc"
|
|
className="w-full px-4 py-3 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-gold"
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
|
Nome do Titular da Conta *
|
|
</label>
|
|
<input
|
|
type="text"
|
|
required
|
|
value={newProfessional.accountHolder}
|
|
onChange={(e) =>
|
|
setNewProfessional({ ...newProfessional, accountHolder: e.target.value })
|
|
}
|
|
placeholder="Nome do titular"
|
|
className="w-full px-4 py-3 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-gold"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Recursos e Equipamentos */}
|
|
<div className="space-y-4">
|
|
<h3 className="text-lg font-semibold text-gray-900 border-b pb-2">
|
|
Recursos e Equipamentos
|
|
</h3>
|
|
|
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
|
<div>
|
|
<label className="flex items-center gap-2 cursor-pointer">
|
|
<input
|
|
type="checkbox"
|
|
checked={newProfessional.hasCar}
|
|
onChange={(e) =>
|
|
setNewProfessional({ ...newProfessional, hasCar: e.target.checked })
|
|
}
|
|
className="w-4 h-4 text-brand-gold focus:ring-brand-gold border-gray-300 rounded"
|
|
/>
|
|
<span className="text-sm font-medium text-gray-700">
|
|
Carro Disponível para uso?
|
|
</span>
|
|
</label>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="flex items-center gap-2 cursor-pointer">
|
|
<input
|
|
type="checkbox"
|
|
checked={newProfessional.hasStudio}
|
|
onChange={(e) =>
|
|
setNewProfessional({ ...newProfessional, hasStudio: e.target.checked })
|
|
}
|
|
className="w-4 h-4 text-brand-gold focus:ring-brand-gold border-gray-300 rounded"
|
|
/>
|
|
<span className="text-sm font-medium text-gray-700">
|
|
Possui Estúdio?
|
|
</span>
|
|
</label>
|
|
</div>
|
|
|
|
{newProfessional.hasStudio && (
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
|
Qtd de Estúdios
|
|
</label>
|
|
<input
|
|
type="number"
|
|
min="0"
|
|
value={newProfessional.studioQuantity}
|
|
onChange={(e) =>
|
|
setNewProfessional({
|
|
...newProfessional,
|
|
studioQuantity: parseInt(e.target.value),
|
|
})
|
|
}
|
|
placeholder="0"
|
|
className="w-full px-4 py-3 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-gold"
|
|
/>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
|
|
{/* Avaliações */}
|
|
<div className="space-y-4">
|
|
<h3 className="text-lg font-semibold text-gray-900 border-b pb-2">
|
|
Avaliações (0 a 5)
|
|
</h3>
|
|
|
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
|
Qual. Téc / Aparência
|
|
</label>
|
|
<input
|
|
type="number"
|
|
min="0"
|
|
max="5"
|
|
step="0.1"
|
|
value={newProfessional.ratings?.technicalQuality}
|
|
onChange={(e) =>
|
|
setNewProfessional({
|
|
...newProfessional,
|
|
ratings: {
|
|
...newProfessional.ratings!,
|
|
technicalQuality: parseFloat(e.target.value),
|
|
},
|
|
})
|
|
}
|
|
placeholder="0.0"
|
|
className="w-full px-4 py-3 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-gold"
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
|
Educação / Simpatia
|
|
</label>
|
|
<input
|
|
type="number"
|
|
min="0"
|
|
max="5"
|
|
step="0.1"
|
|
value={newProfessional.ratings?.sympathy}
|
|
onChange={(e) =>
|
|
setNewProfessional({
|
|
...newProfessional,
|
|
ratings: {
|
|
...newProfessional.ratings!,
|
|
sympathy: parseFloat(e.target.value),
|
|
},
|
|
})
|
|
}
|
|
placeholder="0.0"
|
|
className="w-full px-4 py-3 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-gold"
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
|
Desempenho Evento
|
|
</label>
|
|
<input
|
|
type="number"
|
|
min="0"
|
|
max="5"
|
|
step="0.1"
|
|
value={newProfessional.ratings?.eventPerformance}
|
|
onChange={(e) =>
|
|
setNewProfessional({
|
|
...newProfessional,
|
|
ratings: {
|
|
...newProfessional.ratings!,
|
|
eventPerformance: parseFloat(e.target.value),
|
|
},
|
|
})
|
|
}
|
|
placeholder="0.0"
|
|
className="w-full px-4 py-3 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-gold"
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
|
Disp. Horário
|
|
</label>
|
|
<input
|
|
type="number"
|
|
min="0"
|
|
max="5"
|
|
step="0.1"
|
|
value={newProfessional.ratings?.scheduleAvailability}
|
|
onChange={(e) =>
|
|
setNewProfessional({
|
|
...newProfessional,
|
|
ratings: {
|
|
...newProfessional.ratings!,
|
|
scheduleAvailability: parseFloat(e.target.value),
|
|
},
|
|
})
|
|
}
|
|
placeholder="0.0"
|
|
className="w-full px-4 py-3 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-gold"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Valores */}
|
|
<div className="space-y-4">
|
|
<h3 className="text-lg font-semibold text-gray-900 border-b pb-2">
|
|
Valores
|
|
</h3>
|
|
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
|
Tabela de Free *
|
|
</label>
|
|
<input
|
|
type="text"
|
|
required
|
|
value={newProfessional.freeTable}
|
|
onChange={(e) =>
|
|
setNewProfessional({ ...newProfessional, freeTable: e.target.value })
|
|
}
|
|
placeholder="R$ 800,00"
|
|
className="w-full px-4 py-3 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-gold"
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
|
Extra no Cachê por Equipamento e Desempenho
|
|
</label>
|
|
<input
|
|
type="text"
|
|
value={newProfessional.extraFee}
|
|
onChange={(e) =>
|
|
setNewProfessional({ ...newProfessional, extraFee: e.target.value })
|
|
}
|
|
placeholder="R$ 150,00"
|
|
className="w-full px-4 py-3 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-gold"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Observações */}
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
|
Observações
|
|
</label>
|
|
<textarea
|
|
value={newProfessional.observations}
|
|
onChange={(e) =>
|
|
setNewProfessional({ ...newProfessional, observations: e.target.value })
|
|
}
|
|
placeholder="Qualquer tipo de observação relevante"
|
|
rows={4}
|
|
className="w-full px-4 py-3 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-gold"
|
|
/>
|
|
</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 Profissional
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Professional Detail Modal */}
|
|
{selectedProfessional && (
|
|
<div
|
|
className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4 overflow-y-auto"
|
|
onClick={() => setSelectedProfessional(null)}
|
|
>
|
|
<div
|
|
className="bg-white rounded-lg max-w-3xl w-full p-8 max-h-[90vh] overflow-y-auto my-8"
|
|
onClick={(e) => e.stopPropagation()}
|
|
>
|
|
<div className="flex items-start gap-4 mb-6">
|
|
<img
|
|
src={selectedProfessional.avatar}
|
|
alt={selectedProfessional.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">
|
|
{selectedProfessional.name}
|
|
</h2>
|
|
<p className="text-gray-600 mb-2">{selectedProfessional.role}</p>
|
|
<div className="flex items-center gap-2 mb-2">
|
|
<Star
|
|
size={18}
|
|
fill="#B9CF33"
|
|
className="text-brand-gold"
|
|
/>
|
|
<span className="font-semibold">
|
|
{selectedProfessional.ratings.average.toFixed(1)}
|
|
</span>
|
|
<span className="text-sm text-gray-500">
|
|
({selectedProfessional.eventsCompleted} eventos concluídos)
|
|
</span>
|
|
</div>
|
|
<span
|
|
className={`inline-block px-3 py-1 rounded-full text-xs font-medium ${getStatusColor(
|
|
selectedProfessional.status
|
|
)}`}
|
|
>
|
|
{getStatusLabel(selectedProfessional.status)}
|
|
</span>
|
|
</div>
|
|
<button
|
|
onClick={() => setSelectedProfessional(null)}
|
|
className="text-gray-400 hover:text-gray-600"
|
|
>
|
|
<X size={24} />
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Informações detalhadas */}
|
|
<div className="space-y-6">
|
|
{/* Contato */}
|
|
<div>
|
|
<h3 className="font-semibold text-lg mb-3 text-brand-black">Contato</h3>
|
|
<div className="space-y-2">
|
|
<div className="flex items-center text-gray-700">
|
|
<Mail size={18} className="mr-3 text-brand-gold" />
|
|
<span>{selectedProfessional.email}</span>
|
|
</div>
|
|
<div className="flex items-center text-gray-700">
|
|
<Phone size={18} className="mr-3 text-brand-gold" />
|
|
<span>{selectedProfessional.whatsapp}</span>
|
|
</div>
|
|
<div className="flex items-start text-gray-700">
|
|
<MapPin size={18} className="mr-3 text-brand-gold mt-1" />
|
|
<span>
|
|
{selectedProfessional.address.street}, {selectedProfessional.address.number}
|
|
{selectedProfessional.address.complement && ` - ${selectedProfessional.address.complement}`}
|
|
<br />
|
|
{selectedProfessional.address.neighborhood}, {selectedProfessional.address.city} - {selectedProfessional.address.state}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Recursos */}
|
|
<div>
|
|
<h3 className="font-semibold text-lg mb-3 text-brand-black">Recursos</h3>
|
|
<div className="flex flex-wrap gap-2">
|
|
{selectedProfessional.hasCar && (
|
|
<span className="flex items-center gap-2 px-3 py-1 bg-green-100 text-green-700 rounded-full text-sm">
|
|
<Car size={16} />
|
|
Possui Carro
|
|
</span>
|
|
)}
|
|
{selectedProfessional.hasStudio && (
|
|
<span className="flex items-center gap-2 px-3 py-1 bg-blue-100 text-blue-700 rounded-full text-sm">
|
|
<Building size={16} />
|
|
Possui Estúdio ({selectedProfessional.studioQuantity})
|
|
</span>
|
|
)}
|
|
</div>
|
|
</div>
|
|
|
|
{/* Avaliações */}
|
|
<div>
|
|
<h3 className="font-semibold text-lg mb-3 text-brand-black">Avaliações</h3>
|
|
<div className="grid grid-cols-2 md:grid-cols-3 gap-3">
|
|
{selectedProfessional.role !== "Recepcionista" && (
|
|
<div className="bg-gray-50 p-3 rounded-lg">
|
|
<p className="text-xs text-gray-600 mb-1">Qual. Técnica</p>
|
|
<p className="text-lg font-semibold text-brand-gold">
|
|
{selectedProfessional.ratings.technicalQuality.toFixed(1)}
|
|
</p>
|
|
</div>
|
|
)}
|
|
<div className="bg-gray-50 p-3 rounded-lg">
|
|
<p className="text-xs text-gray-600 mb-1">Aparência</p>
|
|
<p className="text-lg font-semibold text-brand-gold">
|
|
{selectedProfessional.ratings.appearance.toFixed(1)}
|
|
</p>
|
|
</div>
|
|
<div className="bg-gray-50 p-3 rounded-lg">
|
|
<p className="text-xs text-gray-600 mb-1">Simpatia</p>
|
|
<p className="text-lg font-semibold text-brand-gold">
|
|
{selectedProfessional.ratings.sympathy.toFixed(1)}
|
|
</p>
|
|
</div>
|
|
<div className="bg-gray-50 p-3 rounded-lg">
|
|
<p className="text-xs text-gray-600 mb-1">Desempenho</p>
|
|
<p className="text-lg font-semibold text-brand-gold">
|
|
{selectedProfessional.ratings.eventPerformance.toFixed(1)}
|
|
</p>
|
|
</div>
|
|
<div className="bg-gray-50 p-3 rounded-lg">
|
|
<p className="text-xs text-gray-600 mb-1">Disponibilidade</p>
|
|
<p className="text-lg font-semibold text-brand-gold">
|
|
{selectedProfessional.ratings.scheduleAvailability.toFixed(1)}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Valores */}
|
|
<div>
|
|
<h3 className="font-semibold text-lg mb-3 text-brand-black">Valores</h3>
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-3">
|
|
<div className="bg-gray-50 p-3 rounded-lg">
|
|
<p className="text-xs text-gray-600 mb-1">Tabela Free</p>
|
|
<p className="text-lg font-semibold text-brand-black">
|
|
{selectedProfessional.freeTable}
|
|
</p>
|
|
</div>
|
|
<div className="bg-gray-50 p-3 rounded-lg">
|
|
<p className="text-xs text-gray-600 mb-1">Extra/Equipamento</p>
|
|
<p className="text-lg font-semibold text-brand-black">
|
|
{selectedProfessional.extraFee}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Observações */}
|
|
{selectedProfessional.observations && (
|
|
<div>
|
|
<h3 className="font-semibold text-lg mb-2 text-brand-black">Observações</h3>
|
|
<p className="text-gray-700 bg-gray-50 p-3 rounded-lg">
|
|
{selectedProfessional.observations}
|
|
</p>
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
<div className="pt-6 border-t border-gray-200 flex gap-3 mt-6">
|
|
<button
|
|
onClick={() => setSelectedProfessional(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">
|
|
Editar Dados
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|