From 888ae9eb621ea40b8afad0a4e7b32669f74b0c27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Vitor?= Date: Thu, 18 Dec 2025 15:12:20 -0300 Subject: [PATCH] =?UTF-8?q?feat:=20Adicionar=20sistema=20de=20c=C3=B3digo?= =?UTF-8?q?=20de=20acesso,=20upload=20de=20foto=20de=20perfil=20e=20melhor?= =?UTF-8?q?ias=20de=20UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Adicionar modal de verificação de código de acesso na página inicial para cadastro - Adicionar modal de seleção profissional/cliente após verificação do código - Criar página AccessCodeManagement para CEO/SUPERADMIN gerar e gerenciar códigos de acesso - Adicionar upload de foto de perfil no formulário de cadastro de profissional - Adicionar upload de foto de perfil no modal de edição de perfil - Remover botão 'Entrar/Cadastrar' do header nas rotas de login e cadastro - Separar campos Conta e PIX no cadastro de profissional (apenas PIX obrigatório) - Adicionar campo de descrição de equipamentos no cadastro de profissional - Remover edição manual de 'Gastos Captação' (campo calculado) - Converter página de códigos de acesso para formato de tabela estilo Excel - Restaurar fallback de login do usuário demo quando o backend estiver indisponível - Padronizar espaçamentos e fontes do header nas páginas administrativas - Adicionar novo item de menu 'Códigos de Acesso' para CEO/SUPERADMIN --- frontend/App.tsx | 13 + frontend/components/FotForm.tsx | 19 -- frontend/components/Navbar.tsx | 49 +++- frontend/components/ProfessionalForm.tsx | 112 ++++++++- frontend/contexts/AuthContext.tsx | 20 +- frontend/pages/AccessCodeManagement.tsx | 293 +++++++++++++++++++++++ frontend/pages/Home.tsx | 168 ++++++++++++- frontend/pages/ProfessionalRegister.tsx | 4 +- 8 files changed, 633 insertions(+), 45 deletions(-) create mode 100644 frontend/pages/AccessCodeManagement.tsx diff --git a/frontend/App.tsx b/frontend/App.tsx index 7e4ad75..6bf5078 100644 --- a/frontend/App.tsx +++ b/frontend/App.tsx @@ -20,6 +20,7 @@ import { SettingsPage } from "./pages/Settings"; import { CourseManagement } from "./pages/CourseManagement"; import { InspirationPage } from "./pages/Inspiration"; import { UserApproval } from "./pages/UserApproval"; +import { AccessCodeManagement } from "./pages/AccessCodeManagement"; import { PrivacyPolicy } from "./pages/PrivacyPolicy"; import { TermsOfUse } from "./pages/TermsOfUse"; import { LGPD } from "./pages/LGPD"; @@ -520,6 +521,18 @@ const AppContent: React.FC = () => { } /> + + + {}} /> + + + } + /> {/* Rota padrão - redireciona para home */} } /> diff --git a/frontend/components/FotForm.tsx b/frontend/components/FotForm.tsx index 3985d85..8d08a6d 100644 --- a/frontend/components/FotForm.tsx +++ b/frontend/components/FotForm.tsx @@ -287,25 +287,6 @@ export const FotForm: React.FC = ({ onCancel, onSubmit, token, exi - {/* Gastos Captação */} -
- -
- R$ - setFormData({ ...formData, gastos_captacao: e.target.value })} - 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" - placeholder="0,00" - /> -
-
- {/* Pre Venda Checkbox */}
) : ( + !['entrar', 'cadastro', 'cadastro-profissional'].includes(currentPage) && (
)} + ) )} @@ -454,6 +485,7 @@ export const Navbar: React.FC = ({ onNavigate, currentPage }) => { ) : ( + !['entrar', 'cadastro', 'cadastro-profissional'].includes(currentPage) && (
)} + ) )} @@ -649,13 +682,23 @@ export const Navbar: React.FC = ({ onNavigate, currentPage }) => {
Avatar -
+
+ +

Editar Perfil diff --git a/frontend/components/ProfessionalForm.tsx b/frontend/components/ProfessionalForm.tsx index 852d14b..c903102 100644 --- a/frontend/components/ProfessionalForm.tsx +++ b/frontend/components/ProfessionalForm.tsx @@ -13,6 +13,7 @@ export interface ProfessionalData { email: string; senha: string; confirmarSenha: string; + avatar?: File | null; funcaoId: string; cep: string; rua: string; @@ -25,11 +26,13 @@ export interface ProfessionalData { cpfCnpj: string; banco: string; agencia: string; - contaPix: string; + conta: string; + pix: string; carroDisponivel: string; possuiEstudio: string; qtdEstudios: string; tipoCartao: string; + equipamentos: string; observacao: string; } @@ -43,11 +46,13 @@ export const ProfessionalForm: React.FC = ({ const [isLoadingFunctions, setIsLoadingFunctions] = useState(false); const [functionsError, setFunctionsError] = useState(false); const [isLoadingCep, setIsLoadingCep] = useState(false); + const [avatarPreview, setAvatarPreview] = useState(null); const [formData, setFormData] = useState({ nome: "", email: "", senha: "", confirmarSenha: "", + avatar: null, funcaoId: "", cep: "", rua: "", @@ -60,11 +65,13 @@ export const ProfessionalForm: React.FC = ({ cpfCnpj: "", banco: "", agencia: "", - contaPix: "", + conta: "", + pix: "", carroDisponivel: "nao", possuiEstudio: "nao", qtdEstudios: "0", tipoCartao: "", + equipamentos: "", observacao: "", }); @@ -91,6 +98,19 @@ export const ProfessionalForm: React.FC = ({ setFormData((prev) => ({ ...prev, [field]: value })); }; + const handleAvatarChange = (e: React.ChangeEvent) => { + const file = e.target.files?.[0]; + if (file) { + setFormData((prev) => ({ ...prev, avatar: file })); + // Create preview URL + const reader = new FileReader(); + reader.onloadend = () => { + setAvatarPreview(reader.result as string); + }; + reader.readAsDataURL(file); + } + }; + const handleCepBlur = async () => { const cep = formData.cep.replace(/\D/g, ""); if (cep.length !== 8) return; @@ -214,6 +234,57 @@ export const ProfessionalForm: React.FC = ({ onChange={(e) => handleChange("nome", e.target.value)} /> +
+ +
+ {avatarPreview ? ( +
+ Preview + +
+ ) : ( +
+ + + +
+ )} +
+ +

PNG, JPG ou JPEG até 5MB

+
+
+
+ = ({ /> -
+
handleChange("banco", e.target.value)} /> { const value = e.target.value.replace(/\D/g, ""); handleChange("agencia", value); }} /> +
+ +
handleChange("conta", e.target.value)} + /> + handleChange("contaPix", e.target.value)} + placeholder="E-mail, telefone, CPF ou chave aleatória" + value={formData.pix} + onChange={(e) => handleChange("pix", e.target.value)} />
@@ -503,6 +582,19 @@ export const ProfessionalForm: React.FC = ({ /> )} +
+ +