fix: ajuste formulario de cadastro de pesquisador
This commit is contained in:
parent
02309f74c0
commit
58ee90df73
2 changed files with 384 additions and 364 deletions
|
|
@ -261,6 +261,56 @@ export const ProfessionalForm: React.FC<ProfessionalFormProps> = ({
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form onSubmit={handleSubmit} className="space-y-4">
|
<form onSubmit={handleSubmit} className="space-y-4">
|
||||||
|
{/* Seleção de Função (Movido para o topo) */}
|
||||||
|
<div className="space-y-4">
|
||||||
|
<h3 className="font-semibold text-lg text-gray-700 border-b pb-2">
|
||||||
|
Função
|
||||||
|
</h3>
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||||
|
Função Profissional *
|
||||||
|
</label>
|
||||||
|
{isLoadingFunctions ? (
|
||||||
|
<p className="text-sm text-gray-500">Carregando funções...</p>
|
||||||
|
) : functionsError ? (
|
||||||
|
<p className="text-sm text-red-500">
|
||||||
|
❌ Erro ao carregar funções. Verifique se o backend está
|
||||||
|
rodando.
|
||||||
|
</p>
|
||||||
|
) : (
|
||||||
|
<div className="flex flex-wrap gap-4 bg-gray-50 p-4 rounded-lg border border-gray-200">
|
||||||
|
{functions.map((func) => (
|
||||||
|
<label key={func.id} className="flex items-center gap-2 cursor-pointer bg-white px-3 py-2 rounded shadow-sm border border-gray-100 hover:border-brand-gold transition-colors">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
value={func.id}
|
||||||
|
checked={formData.funcoesIds?.includes(func.id)}
|
||||||
|
onChange={(e) => {
|
||||||
|
const checked = e.target.checked;
|
||||||
|
const currentIds = formData.funcoesIds || [];
|
||||||
|
let newIds: string[] = [];
|
||||||
|
if (checked) {
|
||||||
|
newIds = [...currentIds, func.id];
|
||||||
|
} else {
|
||||||
|
newIds = currentIds.filter((id) => id !== func.id);
|
||||||
|
}
|
||||||
|
setFormData((prev) => ({
|
||||||
|
...prev,
|
||||||
|
funcoesIds: newIds,
|
||||||
|
funcaoId: newIds.length > 0 ? newIds[0] : "", // Update primary
|
||||||
|
funcaoLabel: functions.find(f=>f.id === (newIds.length > 0 ? newIds[0] : ""))?.nome
|
||||||
|
}));
|
||||||
|
}}
|
||||||
|
className="w-5 h-5 text-[#B9CF33] rounded border-gray-300 focus:ring-[#B9CF33]"
|
||||||
|
/>
|
||||||
|
<span className="text-sm text-gray-700 font-medium">{func.nome}</span>
|
||||||
|
</label>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Informações Pessoais */}
|
{/* Informações Pessoais */}
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<h3 className="font-semibold text-lg text-gray-700 border-b pb-2">
|
<h3 className="font-semibold text-lg text-gray-700 border-b pb-2">
|
||||||
|
|
@ -275,6 +325,8 @@ export const ProfessionalForm: React.FC<ProfessionalFormProps> = ({
|
||||||
onChange={(e) => handleChange("nome", e.target.value)}
|
onChange={(e) => handleChange("nome", e.target.value)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{/* Conditional CPF Display */}
|
||||||
|
{(!formData.funcoesIds?.every(id => functions.find(f => f.id === id)?.nome.toLowerCase().includes("pesquisa")) || (formData.funcoesIds?.length === 0)) && (
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||||
CPF ou CNPJ do Titular *
|
CPF ou CNPJ do Titular *
|
||||||
|
|
@ -311,6 +363,7 @@ export const ProfessionalForm: React.FC<ProfessionalFormProps> = ({
|
||||||
Informe seu CPF para verificarmos se você já possui cadastro.
|
Informe seu CPF para verificarmos se você já possui cadastro.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-2">
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
||||||
|
|
@ -391,53 +444,10 @@ export const ProfessionalForm: React.FC<ProfessionalFormProps> = ({
|
||||||
value={formData.confirmarSenha}
|
value={formData.confirmarSenha}
|
||||||
onChange={(e) => handleChange("confirmarSenha", e.target.value)}
|
onChange={(e) => handleChange("confirmarSenha", e.target.value)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div>
|
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
|
||||||
Função Profissional *
|
|
||||||
</label>
|
|
||||||
{isLoadingFunctions ? (
|
|
||||||
<p className="text-sm text-gray-500">Carregando funções...</p>
|
|
||||||
) : functionsError ? (
|
|
||||||
<p className="text-sm text-red-500">
|
|
||||||
❌ Erro ao carregar funções. Verifique se o backend está
|
|
||||||
rodando.
|
|
||||||
</p>
|
|
||||||
) : (
|
|
||||||
<div className="flex flex-wrap gap-4 bg-gray-50 p-4 rounded-lg border border-gray-200">
|
|
||||||
{functions.map((func) => (
|
|
||||||
<label key={func.id} className="flex items-center gap-2 cursor-pointer bg-white px-3 py-2 rounded shadow-sm border border-gray-100 hover:border-brand-gold transition-colors">
|
|
||||||
<input
|
|
||||||
type="checkbox"
|
|
||||||
value={func.id}
|
|
||||||
checked={formData.funcoesIds?.includes(func.id)}
|
|
||||||
onChange={(e) => {
|
|
||||||
const checked = e.target.checked;
|
|
||||||
const currentIds = formData.funcoesIds || [];
|
|
||||||
let newIds: string[] = [];
|
|
||||||
if (checked) {
|
|
||||||
newIds = [...currentIds, func.id];
|
|
||||||
} else {
|
|
||||||
newIds = currentIds.filter((id) => id !== func.id);
|
|
||||||
}
|
|
||||||
setFormData((prev) => ({
|
|
||||||
...prev,
|
|
||||||
funcoesIds: newIds,
|
|
||||||
funcaoId: newIds.length > 0 ? newIds[0] : "", // Update primary
|
|
||||||
funcaoLabel: functions.find(f=>f.id === (newIds.length > 0 ? newIds[0] : ""))?.nome
|
|
||||||
}));
|
|
||||||
}}
|
|
||||||
className="w-5 h-5 text-[#B9CF33] rounded border-gray-300 focus:ring-[#B9CF33]"
|
|
||||||
/>
|
|
||||||
<span className="text-sm text-gray-700 font-medium">{func.nome}</span>
|
|
||||||
</label>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Endereço */}
|
{/* Endereço */}
|
||||||
|
{(!formData.funcoesIds?.every(id => functions.find(f => f.id === id)?.nome.toLowerCase().includes("pesquisa")) || (formData.funcoesIds?.length === 0)) && (
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<h3 className="font-semibold text-lg text-gray-700 border-b pb-2">
|
<h3 className="font-semibold text-lg text-gray-700 border-b pb-2">
|
||||||
Endereço
|
Endereço
|
||||||
|
|
@ -527,6 +537,7 @@ export const ProfessionalForm: React.FC<ProfessionalFormProps> = ({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Contato */}
|
{/* Contato */}
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
|
|
@ -546,15 +557,13 @@ export const ProfessionalForm: React.FC<ProfessionalFormProps> = ({
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Dados Bancários */}
|
{/* Dados Bancários */}
|
||||||
|
{(!formData.funcoesIds?.every(id => functions.find(f => f.id === id)?.nome.toLowerCase().includes("pesquisa")) || (formData.funcoesIds?.length === 0)) && (
|
||||||
|
<>
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<h3 className="font-semibold text-lg text-gray-700 border-b pb-2">
|
<h3 className="font-semibold text-lg text-gray-700 border-b pb-2">
|
||||||
Dados Bancários
|
Dados Bancários
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<div>
|
|
||||||
{/* CPF moved to personal info */}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||||
<Input
|
<Input
|
||||||
label="Banco *"
|
label="Banco *"
|
||||||
|
|
@ -594,7 +603,7 @@ export const ProfessionalForm: React.FC<ProfessionalFormProps> = ({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Informações Profissionais */}
|
{/* Informações Profissionais - Resources */}
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<h3 className="font-semibold text-lg text-gray-700 border-b pb-2">
|
<h3 className="font-semibold text-lg text-gray-700 border-b pb-2">
|
||||||
Informações Profissionais
|
Informações Profissionais
|
||||||
|
|
@ -685,6 +694,8 @@ export const ProfessionalForm: React.FC<ProfessionalFormProps> = ({
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Botões */}
|
{/* Botões */}
|
||||||
<div className="flex gap-4 pt-4">
|
<div className="flex gap-4 pt-4">
|
||||||
|
|
|
||||||
|
|
@ -387,27 +387,8 @@ export const ProfessionalModal: React.FC<ProfessionalModalProps> = ({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Name & CPF (Top) */}
|
{/* Seleção de Função (Movida para o topo) */}
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
<div className="col-span-1 md:col-span-2 mb-4">
|
||||||
<div>
|
|
||||||
<label className="block text-sm font-medium text-gray-700">Nome *</label>
|
|
||||||
<input required type="text" value={formData.nome || ""} onChange={e => setFormData({ ...formData, nome: e.target.value })} className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-brand-gold focus:ring focus:ring-brand-gold focus:ring-opacity-50 p-2 border" />
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label className="block text-sm font-medium text-gray-700">CPF/CNPJ Titular *</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
value={formData.cpf_cnpj_titular || ""}
|
|
||||||
onChange={e => setFormData({ ...formData, cpf_cnpj_titular: maskCpfCnpj(e.target.value) })}
|
|
||||||
onBlur={handleCpfBlur}
|
|
||||||
maxLength={18}
|
|
||||||
className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-brand-gold focus:ring focus:ring-brand-gold focus:ring-opacity-50 p-2 border"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Functions */}
|
|
||||||
<div className="col-span-1 md:col-span-2">
|
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||||
Funções *
|
Funções *
|
||||||
</label>
|
</label>
|
||||||
|
|
@ -441,6 +422,29 @@ export const ProfessionalModal: React.FC<ProfessionalModalProps> = ({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Name & CPF (Top) */}
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700">Nome *</label>
|
||||||
|
<input required type="text" value={formData.nome || ""} onChange={e => setFormData({ ...formData, nome: e.target.value })} className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-brand-gold focus:ring focus:ring-brand-gold focus:ring-opacity-50 p-2 border" />
|
||||||
|
</div>
|
||||||
|
{(!formData.funcoes_ids?.every(id => roles.find(r => r.id === id)?.nome.toLowerCase().includes("pesquisa")) || (formData.funcoes_ids?.length === 0)) && (
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700">CPF/CNPJ Titular *</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={formData.cpf_cnpj_titular || ""}
|
||||||
|
onChange={e => setFormData({ ...formData, cpf_cnpj_titular: maskCpfCnpj(e.target.value) })}
|
||||||
|
onBlur={handleCpfBlur}
|
||||||
|
maxLength={18}
|
||||||
|
className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-brand-gold focus:ring focus:ring-brand-gold focus:ring-opacity-50 p-2 border"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Functions removed from here */}
|
||||||
|
|
||||||
{/* Email & Pass */}
|
{/* Email & Pass */}
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm font-medium text-gray-700">Email *</label>
|
<label className="block text-sm font-medium text-gray-700">Email *</label>
|
||||||
|
|
@ -498,6 +502,9 @@ export const ProfessionalModal: React.FC<ProfessionalModalProps> = ({
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{/* Endereço */}
|
||||||
|
{(!formData.funcoes_ids?.every(id => roles.find(r => r.id === id)?.nome.toLowerCase().includes("pesquisa")) || (formData.funcoes_ids?.length === 0)) && (
|
||||||
|
<>
|
||||||
<h3 className="text-lg font-medium text-gray-900 border-b pb-2 mt-4">Endereço</h3>
|
<h3 className="text-lg font-medium text-gray-900 border-b pb-2 mt-4">Endereço</h3>
|
||||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||||
<div>
|
<div>
|
||||||
|
|
@ -623,6 +630,8 @@ export const ProfessionalModal: React.FC<ProfessionalModalProps> = ({
|
||||||
<label className="block text-sm font-medium text-gray-700">Observações</label>
|
<label className="block text-sm font-medium text-gray-700">Observações</label>
|
||||||
<textarea rows={3} value={formData.observacao || ""} onChange={e => setFormData({ ...formData, observacao: e.target.value })} className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-brand-gold focus:ring focus:ring-brand-gold focus:ring-opacity-50 p-2 border" />
|
<textarea rows={3} value={formData.observacao || ""} onChange={e => setFormData({ ...formData, observacao: e.target.value })} className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-brand-gold focus:ring focus:ring-brand-gold focus:ring-opacity-50 p-2 border" />
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
|
||||||
<div className="flex justify-end gap-4 pt-4 border-t sticky bottom-0 bg-white">
|
<div className="flex justify-end gap-4 pt-4 border-t sticky bottom-0 bg-white">
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue