From c4eb7e37750dd175f67446b3925ab4abdf8fa673 Mon Sep 17 00:00:00 2001 From: Enzo Sakamoto Date: Thu, 23 Oct 2025 10:45:30 -0300 Subject: [PATCH 01/11] Add utility functions for formatting CPF, CNPJ, and phone numbers --- src/shared/utils/string-extensions.ts | 75 +++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 src/shared/utils/string-extensions.ts diff --git a/src/shared/utils/string-extensions.ts b/src/shared/utils/string-extensions.ts new file mode 100644 index 0000000..ebc39a6 --- /dev/null +++ b/src/shared/utils/string-extensions.ts @@ -0,0 +1,75 @@ +export const formatCPF = (value: string) => { + // Remove tudo que não é dígito + const cleanValue = value.replace(/\D/g, '') + + // Aplica a máscara conforme o usuário digita + if (cleanValue.length <= 3) { + return cleanValue + } else if (cleanValue.length <= 6) { + return `${cleanValue.slice(0, 3)}.${cleanValue.slice(3)}` + } else if (cleanValue.length <= 9) { + return `${cleanValue.slice(0, 3)}.${cleanValue.slice(3, 6)}.${cleanValue.slice(6)}` + } else { + return `${cleanValue.slice(0, 3)}.${cleanValue.slice(3, 6)}.${cleanValue.slice(6, 9)}-${cleanValue.slice(9, 11)}` + } +} + +export const formatCNPJ = (value: string) => { + // Remove tudo que não é dígito + const cleanValue = value.replace(/\D/g, '') + + // Aplica a máscara conforme o usuário digita + if (cleanValue.length <= 2) { + return cleanValue + } else if (cleanValue.length <= 5) { + return `${cleanValue.slice(0, 2)}.${cleanValue.slice(2)}` + } else if (cleanValue.length <= 8) { + return `${cleanValue.slice(0, 2)}.${cleanValue.slice(2, 5)}.${cleanValue.slice(5)}` + } else if (cleanValue.length <= 12) { + return `${cleanValue.slice(0, 2)}.${cleanValue.slice(2, 5)}.${cleanValue.slice(5, 8)}/${cleanValue.slice(8)}` + } else { + return `${cleanValue.slice(0, 2)}.${cleanValue.slice(2, 5)}.${cleanValue.slice(5, 8)}/${cleanValue.slice(8, 12)}-${cleanValue.slice(12, 14)}` + } +} + +export const formatPhone = (value: string) => { + // Remove tudo que não é dígito + const cleanValue = value.replace(/\D/g, '') + + // Aplica a máscara conforme o usuário digita + if (cleanValue.length <= 2) { + return cleanValue + } else if (cleanValue.length <= 6) { + return `(${cleanValue.slice(0, 2)}) ${cleanValue.slice(2)}` + } else if (cleanValue.length <= 10) { + // Para telefone fixo (8 dígitos): (11) 5320-2121 + return `(${cleanValue.slice(0, 2)}) ${cleanValue.slice(2, 6)}-${cleanValue.slice(6)}` + } else { + // Para celular (9 dígitos): (11) 95320-2121 + return `(${cleanValue.slice(0, 2)}) ${cleanValue.slice(2, 7)}-${cleanValue.slice(7, 11)}` + } +} + +export const handleCPFChange = ( + value: string, + onChange: (value: string) => void +) => { + const formattedValue = formatCPF(value) + onChange(formattedValue) +} + +export const handleCNPJChange = ( + value: string, + onChange: (value: string) => void +) => { + const formattedValue = formatCNPJ(value) + onChange(formattedValue) +} + +export const handlePhoneChange = ( + value: string, + onChange: (value: string) => void +) => { + const formattedValue = formatPhone(value) + onChange(formattedValue) +} From bbda11d47dabb1ed6bbf8dae49688dbc7f406377 Mon Sep 17 00:00:00 2001 From: Enzo Sakamoto Date: Thu, 23 Oct 2025 10:47:26 -0300 Subject: [PATCH 02/11] chore: remove unused document formatting functions for CPF, CNPJ, and phone numbers --- src/shared/utils/format-documents.ts | 51 ---------------------------- 1 file changed, 51 deletions(-) diff --git a/src/shared/utils/format-documents.ts b/src/shared/utils/format-documents.ts index a753172..e69de29 100644 --- a/src/shared/utils/format-documents.ts +++ b/src/shared/utils/format-documents.ts @@ -1,51 +0,0 @@ -export const formatCPF = (value: string) => { - // Remove tudo que não é dígito - const cleanValue = value.replace(/\D/g, '') - - // Aplica a máscara conforme o usuário digita - if (cleanValue.length <= 3) { - return cleanValue - } else if (cleanValue.length <= 6) { - return `${cleanValue.slice(0, 3)}.${cleanValue.slice(3)}` - } else if (cleanValue.length <= 9) { - return `${cleanValue.slice(0, 3)}.${cleanValue.slice(3, 6)}.${cleanValue.slice(6)}` - } else { - return `${cleanValue.slice(0, 3)}.${cleanValue.slice(3, 6)}.${cleanValue.slice(6, 9)}-${cleanValue.slice(9, 11)}` - } -} - -export const formatCNPJ = (value: string) => { - // Remove tudo que não é dígito - const cleanValue = value.replace(/\D/g, '') - - // Aplica a máscara conforme o usuário digita - if (cleanValue.length <= 2) { - return cleanValue - } else if (cleanValue.length <= 5) { - return `${cleanValue.slice(0, 2)}.${cleanValue.slice(2)}` - } else if (cleanValue.length <= 8) { - return `${cleanValue.slice(0, 2)}.${cleanValue.slice(2, 5)}.${cleanValue.slice(5)}` - } else if (cleanValue.length <= 12) { - return `${cleanValue.slice(0, 2)}.${cleanValue.slice(2, 5)}.${cleanValue.slice(5, 8)}/${cleanValue.slice(8)}` - } else { - return `${cleanValue.slice(0, 2)}.${cleanValue.slice(2, 5)}.${cleanValue.slice(5, 8)}/${cleanValue.slice(8, 12)}-${cleanValue.slice(12, 14)}` - } -} - -export const formatPhone = (value: string) => { - // Remove tudo que não é dígito - const cleanValue = value.replace(/\D/g, '') - - // Aplica a máscara conforme o usuário digita - if (cleanValue.length <= 2) { - return cleanValue - } else if (cleanValue.length <= 6) { - return `(${cleanValue.slice(0, 2)}) ${cleanValue.slice(2)}` - } else if (cleanValue.length <= 10) { - // Para telefone fixo (8 dígitos): (11) 5320-2121 - return `(${cleanValue.slice(0, 2)}) ${cleanValue.slice(2, 6)}-${cleanValue.slice(6)}` - } else { - // Para celular (9 dígitos): (11) 95320-2121 - return `(${cleanValue.slice(0, 2)}) ${cleanValue.slice(2, 7)}-${cleanValue.slice(7, 11)}` - } -} From b18bcde32cb646a1d833c7dd050855dd4a085a8f Mon Sep 17 00:00:00 2001 From: Enzo Sakamoto Date: Thu, 23 Oct 2025 10:47:35 -0300 Subject: [PATCH 03/11] refactor: replace document type string literals with enum values and remove unused formatting functions --- src/features/sign-up/pages/sign-up-page.tsx | 62 ++++++++------------- 1 file changed, 23 insertions(+), 39 deletions(-) diff --git a/src/features/sign-up/pages/sign-up-page.tsx b/src/features/sign-up/pages/sign-up-page.tsx index 7107a90..37d5ae0 100644 --- a/src/features/sign-up/pages/sign-up-page.tsx +++ b/src/features/sign-up/pages/sign-up-page.tsx @@ -27,11 +27,6 @@ import { zodResolver } from '@hookform/resolvers/zod' import { useForm } from 'react-hook-form' import { Checkbox } from '@/shared/components/checkbox' import { Label } from '@/shared/components/label' -import { - formatCNPJ, - formatCPF, - formatPhone -} from '@/shared/utils/format-documents' import toast from 'react-hot-toast' import { BackgroundBlobs } from '@/shared/components/background-blobs' import { motion } from 'framer-motion' @@ -41,6 +36,12 @@ import { containerVariants, cardVariants } from '@/shared/utils/animations' import { useCreateUserMutation } from '@/shared/hooks/use-user' import { AxiosError } from 'axios' import { useNavigate } from 'react-router-dom' +import { DOCUMENT_TYPE } from '@/shared/enums/document-type' +import { + handleCNPJChange, + handleCPFChange, + handlePhoneChange +} from '@/shared/utils/string-extensions' export function SignUpPage() { const [showPassword, setShowPassword] = useState(false) @@ -55,33 +56,9 @@ export function SignUpPage() { mode: 'onBlur' }) - const handleCPFChange = ( - value: string, - onChange: (value: string) => void - ) => { - const formattedValue = formatCPF(value) - onChange(formattedValue) - } - - const handleCNPJChange = ( - value: string, - onChange: (value: string) => void - ) => { - const formattedValue = formatCNPJ(value) - onChange(formattedValue) - } - - const handlePhoneChange = ( - value: string, - onChange: (value: string) => void - ) => { - const formattedValue = formatPhone(value) - onChange(formattedValue) - } - async function onSubmit(values: SignUpFormData) { try { - const isIndividual = values.documentType === 'individual' + const isIndividual = values.documentType === DOCUMENT_TYPE.INDIVIDUAL // Convert birthDate to seconds since epoch if provided const birthDateSeconds = values.birthDate @@ -196,9 +173,11 @@ export function SignUpPage() { > { - field.onChange('individual') + field.onChange(DOCUMENT_TYPE.INDIVIDUAL) form.setValue('document', '') }} /> @@ -210,9 +189,9 @@ export function SignUpPage() { > { - field.onChange('business') + field.onChange(DOCUMENT_TYPE.BUSINESS) form.setValue('document', '') form.setValue('birthDate', undefined) }} @@ -231,7 +210,8 @@ export function SignUpPage() { render={({ field }) => ( - {form.getValues('documentType') === 'individual' + {form.getValues('documentType') === + DOCUMENT_TYPE.INDIVIDUAL ? 'CPF' : 'CNPJ'} @@ -240,7 +220,8 @@ export function SignUpPage() { {...field} onChange={(e) => { if ( - form.getValues('documentType') === 'individual' + form.getValues('documentType') === + DOCUMENT_TYPE.INDIVIDUAL ) { handleCPFChange(e.target.value, field.onChange) } else { @@ -248,12 +229,14 @@ export function SignUpPage() { } }} placeholder={ - form.getValues('documentType') === 'individual' + form.getValues('documentType') === + DOCUMENT_TYPE.INDIVIDUAL ? '000.000.000-00' : '00.000.000/0000-00' } maxLength={ - form.getValues('documentType') === 'individual' + form.getValues('documentType') === + DOCUMENT_TYPE.INDIVIDUAL ? 14 : 18 } @@ -263,7 +246,8 @@ export function SignUpPage() { )} /> - {form.getValues('documentType') === 'individual' && ( + {form.getValues('documentType') === + DOCUMENT_TYPE.INDIVIDUAL && ( Date: Thu, 23 Oct 2025 10:47:46 -0300 Subject: [PATCH 04/11] refactor: replace string literals with enum values for document type in sign-up schema --- src/features/sign-up/types/sign-up-schema.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/features/sign-up/types/sign-up-schema.ts b/src/features/sign-up/types/sign-up-schema.ts index 1642bf0..1631038 100644 --- a/src/features/sign-up/types/sign-up-schema.ts +++ b/src/features/sign-up/types/sign-up-schema.ts @@ -68,7 +68,7 @@ export const signUpFormSchema = z }) } - if (data.documentType === 'individual' && !data.birthDate) { + if (data.documentType === DOCUMENT_TYPE.INDIVIDUAL && !data.birthDate) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'A data de nascimento é obrigatória para pessoa física.', @@ -76,7 +76,7 @@ export const signUpFormSchema = z }) } - if (data.documentType === 'individual') { + if (data.documentType === DOCUMENT_TYPE.INDIVIDUAL) { // Validação CPF const cpfRegex = /^\d{3}\.?\d{3}\.?\d{3}-?\d{2}$/ if (!cpfRegex.test(data.document)) { @@ -104,7 +104,7 @@ export const signUpFormInitialValues: SignUpFormData = { name: '', email: '', phone: '', - documentType: 'individual', + documentType: DOCUMENT_TYPE.INDIVIDUAL, document: '', birthDate: undefined, password: '', From 3eb6de3b594773aab52db448aeb835a2c337749b Mon Sep 17 00:00:00 2001 From: Enzo Sakamoto Date: Thu, 23 Oct 2025 10:47:53 -0300 Subject: [PATCH 05/11] refactor: update user info page to use new string-extensions for document formatting and improve personType handling --- src/features/user-area/pages/user-info.tsx | 86 ++++++++-------------- 1 file changed, 29 insertions(+), 57 deletions(-) diff --git a/src/features/user-area/pages/user-info.tsx b/src/features/user-area/pages/user-info.tsx index 2f7ac09..6531d06 100644 --- a/src/features/user-area/pages/user-info.tsx +++ b/src/features/user-area/pages/user-info.tsx @@ -23,15 +23,15 @@ import { TooltipTrigger } from '@/shared/components/tooltip' import { DOCUMENT_TYPE } from '@/shared/enums/document-type' -import { - formatCNPJ, - formatCPF, - formatPhone -} from '@/shared/utils/format-documents' import { Background } from '@/shared/components/background' import { useUpdateUserMutation, useUser } from '@/shared/hooks/use-user' import { UpdateUserRequest } from '@/services/user' import toast from 'react-hot-toast' +import { + formatCPF, + formatCNPJ, + handlePhoneChange +} from '@/shared/utils/string-extensions' export function UserInfoPage() { const [isEditing, setIsEditing] = useState(false) @@ -45,7 +45,7 @@ export function UserInfoPage() { name: user?.name || '', email: user?.email || '', cellphone: user?.cellphone || '', - personType: user?.personType || 'individual', + personType: user?.personType || DOCUMENT_TYPE.INDIVIDUAL, cpfCnpj: user?.cpfCnpj || '', birthDate: user?.birthDate }, @@ -56,30 +56,6 @@ export function UserInfoPage() { return
Loading
} - const handleCPFChange = ( - value: string, - onChange: (value: string) => void - ) => { - const formattedValue = formatCPF(value) - onChange(formattedValue) - } - - const handleCNPJChange = ( - value: string, - onChange: (value: string) => void - ) => { - const formattedValue = formatCNPJ(value) - onChange(formattedValue) - } - - const handlePhoneChange = ( - value: string, - onChange: (value: string) => void - ) => { - const formattedValue = formatPhone(value) - onChange(formattedValue) - } - function handleEdit() { if (!user) return @@ -129,8 +105,10 @@ export function UserInfoPage() { await updateUser(changedData as UpdateUserRequest) refetch?.() } catch (error) { - console.error('Failed to update user:', error) - toast.error('Erro ao atualizar os dados. Tente novamente.') + toast.error( + 'Erro ao atualizar os dados. Tente novamente. ' + + (error as Error).message || (error as { details: string }).details + ) } finally { setIsEditing(false) } @@ -258,7 +236,7 @@ export function UserInfoPage() { ( + render={({ field }) => ( Tipo de Pessoa @@ -266,8 +244,7 @@ export function UserInfoPage() { Documento - { - if ( - form.getValues('personType') === - 'individual' - ) { - handleCPFChange( - e.target.value, - field.onChange - ) - } else { - handleCNPJChange( - e.target.value, - field.onChange - ) - } - }} - /> + + + + + +

Não é possível alterar o documento

+
+
@@ -331,9 +305,7 @@ export function UserInfoPage() { .split('T')[0] : '' } - onChange={(e) => - field.onChange(new Date(e.target.value)) - } + disabled /> From f4d0645f45f590dad83a01e8f901e42b0b74868f Mon Sep 17 00:00:00 2001 From: Enzo Sakamoto Date: Thu, 23 Oct 2025 11:03:11 -0300 Subject: [PATCH 06/11] feat: add linkedin links for team members and update navigation to use react-router --- src/features/home/pages/home-page.tsx | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/features/home/pages/home-page.tsx b/src/features/home/pages/home-page.tsx index 3c2da9f..d1ceeff 100644 --- a/src/features/home/pages/home-page.tsx +++ b/src/features/home/pages/home-page.tsx @@ -16,6 +16,7 @@ import { import { ArrowDown, ArrowRight, Check } from 'lucide-react' import { BackgroundBlobs } from '@/shared/components/background-blobs' import { Footer } from '@/features/home/components/footer' +import { Link } from 'react-router-dom' const plans = [ { @@ -130,7 +131,8 @@ const owners = [ { name: 'Júlia Galhardi Cerqueira', image: 'https://d1b8zs4rmj3xdl.cloudfront.net/julia.jpeg', - role: 'Estagiária' + role: 'Estagiária', + linkedin: 'https://www.linkedin.com/in/j%C3%BAliacerqueira/' }, { name: 'Vinícius Berti', @@ -255,14 +257,16 @@ export function HomePage() { transition={transition} variants={variants} > - - + + + - + @@ -444,9 +448,9 @@ export function HomePage() { variants={variants} > {owners.map((owner, index) => ( - - + ))} From d290cea77f5c1bf69263ab5af79a993f8e9e28da Mon Sep 17 00:00:00 2001 From: Enzo Sakamoto Date: Thu, 23 Oct 2025 11:30:54 -0300 Subject: [PATCH 07/11] refactor: update color variables for improved contrast and consistency in light and dark themes --- src/shared/styles/global.css | 166 ++++++++++++++++++----------------- 1 file changed, 84 insertions(+), 82 deletions(-) diff --git a/src/shared/styles/global.css b/src/shared/styles/global.css index 65c1036..1cae253 100644 --- a/src/shared/styles/global.css +++ b/src/shared/styles/global.css @@ -4,101 +4,103 @@ :root { --radius: 0.625rem; - /* neutros de fundo / texto (modo claro: mais claro e contrastante) */ - --background: oklch(0.995 0.02 280); /* quase branco com leve toque violeta */ - --foreground: oklch(0.15 0.07 280); /* texto roxo escuro para contraste */ + /* neutros de fundo / texto (modo claro) */ + --background: oklch(0.995 0.02 280); + --foreground: oklch(0.15 0.07 280); /* cards e popovers */ - --card: oklch(0.995 0.02 280); /* quase branco */ + --card: oklch(0.995 0.02 280); --card-foreground: oklch(0.15 0.07 280); --popover: oklch(0.98 0.02 280); --popover-foreground: oklch(0.15 0.07 280); - /* cores principais – roxo brilhante */ - --primary: oklch(0.5 0.2 280); /* roxo vivo e claro */ - --primary-foreground: oklch(0.995 0.02 280); /* texto quase branco */ + /* cores principais */ + --primary: oklch(0.5 0.2 280); + --primary-foreground: oklch(0.995 0.02 280); /* secundárias e neutras */ - --secondary: oklch(0.95 0.05 280); - --secondary-foreground: oklch(0.5 0.2 280); - --muted: oklch(0.97 0.03 280); - --muted-foreground: oklch(0.6 0.05 280); + --secondary: oklch(0.92 0.05 280); + --secondary-foreground: oklch(0.2 0.15 280); + --muted: oklch(0.94 0.03 280); + --muted-foreground: oklch(0.45 0.05 280); /* acentos e destrutivo */ - --accent: oklch(0.9 0.15 280); - --accent-foreground: oklch(0.5 0.2 280); - --destructive: oklch(0.6338 0.1801 15.35); + --accent: oklch(0.88 0.12 280); + --accent-foreground: oklch(0.2 0.15 280); + --destructive: oklch(0.55 0.22 25); + --destructive-foreground: oklch(0.98 0.02 280); /* bordas, inputs e foco */ - --border: oklch(0.9 0.01 280); - --input: oklch(0.9 0.01 280); - --ring: oklch(0.75 0.02 280); - - /* paleta para charts – cores destacadas */ - --chart-1: oklch(0.7 0.25 260); - --chart-2: oklch(0.65 0.2 280); - --chart-3: oklch(0.6 0.15 300); - --chart-4: oklch(0.75 0.22 280); - --chart-5: oklch(0.7 0.18 300); - - /* sidebar (modo claro aprimorado) */ - --sidebar: oklch(0.98 0.02 280); - --sidebar-foreground: oklch(0.15 0.07 280); + --border: oklch(0.88 0.02 280); + --input: oklch(0.88 0.02 280); + --ring: oklch(0.5 0.2 280); + + /* charts */ + --chart-1: oklch(0.65 0.25 260); + --chart-2: oklch(0.6 0.22 280); + --chart-3: oklch(0.55 0.18 300); + --chart-4: oklch(0.7 0.24 280); + --chart-5: oklch(0.65 0.2 300); + + /* sidebar */ + --sidebar: oklch(0.97 0.02 280); + --sidebar-foreground: oklch(0.2 0.1 280); --sidebar-primary: oklch(0.5 0.2 280); --sidebar-primary-foreground: oklch(0.995 0.02 280); - --sidebar-accent: oklch(0.9 0.15 280); - --sidebar-accent-foreground: oklch(0.5 0.2 280); - --sidebar-border: oklch(0.9 0.01 280); - --sidebar-ring: oklch(0.75 0.02 280); + --sidebar-accent: oklch(0.88 0.12 280); + --sidebar-accent-foreground: oklch(0.2 0.15 280); + --sidebar-border: oklch(0.88 0.02 280); + --sidebar-ring: oklch(0.5 0.2 280); } .dark { - /* fundo escuro profundo e texto claro */ - --background: oklch(0.15 0.08 280); - --foreground: oklch(0.9 0.02 280); - - /* cards e popovers */ - --card: oklch(0.3 0.05 280); - --card-foreground: oklch(0.9 0.02 280); - --popover: oklch(0.35 0.06 280); - --popover-foreground: oklch(0.9 0.02 280); - - /* principais */ - --primary: oklch(0.7 0.05 280); - --primary-foreground: oklch(0.25 0.12 280); - - /* secundárias e neutras */ - --secondary: oklch(0.35 0.07 280); - --secondary-foreground: oklch(0.9 0.02 280); - --muted: oklch(0.35 0.07 280); - --muted-foreground: oklch(0.7 0.02 280); - - /* acento e destrutivo */ - --accent: oklch(0.5 0.08 280); - --accent-foreground: oklch(0.9 0.02 280); - --destructive: oklch(0.6 0.2 300); - - /* bordas, inputs e foco */ - --border: oklch(0.25 0 280 / 10%); - --input: oklch(0.25 0 280 / 15%); - --ring: oklch(0.5 0.02 280); - - /* charts */ - --chart-1: oklch(0.4 0.15 260); - --chart-2: oklch(0.5 0.12 280); - --chart-3: oklch(0.55 0.1 300); - --chart-4: oklch(0.38 0.2 280); - --chart-5: oklch(0.45 0.12 300); - - /* sidebar */ - --sidebar: oklch(0.3 0.05 280); - --sidebar-foreground: oklch(0.9 0.02 280); - --sidebar-primary: oklch(0.4 0.15 260); - --sidebar-primary-foreground: oklch(0.9 0.02 280); - --sidebar-accent: oklch(0.35 0.07 280); - --sidebar-accent-foreground: oklch(0.9 0.02 280); - --sidebar-border: oklch(0.25 0 280 / 10%); - --sidebar-ring: oklch(0.45 0.02 280); + /* fundo escuro e texto claro com melhor contraste */ + --background: oklch(0.15 0.04 280); + --foreground: oklch(0.98 0.005 280); + + /* cards e popovers com contraste aprimorado */ + --card: oklch(0.2 0.04 280); + --card-foreground: oklch(0.98 0.005 280); + --popover: oklch(0.18 0.04 280); + --popover-foreground: oklch(0.98 0.005 280); + + /* cores principais com melhor visibilidade */ + --primary: oklch(0.7 0.18 280); + --primary-foreground: oklch(0.98 0.005 280); + + /* secundárias e neutras otimizadas */ + --secondary: oklch(0.28 0.05 280); + --secondary-foreground: oklch(0.98 0.005 280); + --muted: oklch(0.25 0.04 280); + --muted-foreground: oklch(0.75 0.02 280); + + /* acento e destrutivo com contraste adequado */ + --accent: oklch(0.35 0.08 280); + --accent-foreground: oklch(0.98 0.005 280); + --destructive: oklch(0.6 0.25 25); + --destructive-foreground: oklch(0.98 0.005 280); + + /* bordas, inputs e foco mais visíveis */ + --border: oklch(0.35 0.04 280); + --input: oklch(0.35 0.04 280); + --ring: oklch(0.7 0.18 280); + + /* charts com cores distintas e visíveis */ + --chart-1: oklch(0.65 0.2 260); + --chart-2: oklch(0.7 0.18 280); + --chart-3: oklch(0.75 0.15 300); + --chart-4: oklch(0.63 0.22 280); + --chart-5: oklch(0.68 0.18 300); + + /* sidebar otimizada */ + --sidebar: oklch(0.18 0.04 280); + --sidebar-foreground: oklch(0.98 0.005 280); + --sidebar-primary: oklch(0.7 0.18 280); + --sidebar-primary-foreground: oklch(0.98 0.005 280); + --sidebar-accent: oklch(0.28 0.05 280); + --sidebar-accent-foreground: oklch(0.98 0.005 280); + --sidebar-border: oklch(0.35 0.04 280); + --sidebar-ring: oklch(0.7 0.18 280); } @theme { @@ -139,6 +141,7 @@ --color-accent: var(--accent); --color-accent-foreground: var(--accent-foreground); --color-destructive: var(--destructive); + --color-destructive-foreground: var(--destructive-foreground); --color-border: var(--border); --color-input: var(--input); --color-ring: var(--ring); @@ -157,17 +160,16 @@ 0%, 100% { transform: translateX(0); - animation-timing-function: cubic-bezier(0.8, 0, 1, 1); /* saída rápida */ + animation-timing-function: cubic-bezier(0.8, 0, 1, 1); } 50% { - transform: translateX(25%); /* “salto” → */ - animation-timing-function: cubic-bezier(0, 0, 0.2, 1); /* volta suave */ + transform: translateX(25%); + animation-timing-function: cubic-bezier(0, 0, 0.2, 1); } } } html { scroll-behavior: smooth; - /* background-color: var(--background); */ font-family: 'Geist', sans-serif; } From 931ed8c82d9e84727817f01faf20905861946e30 Mon Sep 17 00:00:00 2001 From: Enzo Sakamoto Date: Thu, 23 Oct 2025 11:30:59 -0300 Subject: [PATCH 08/11] refactor: update sidebar component styles for improved border definition --- src/shared/components/sidebar.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/components/sidebar.tsx b/src/shared/components/sidebar.tsx index 0c223fd..ada4dce 100644 --- a/src/shared/components/sidebar.tsx +++ b/src/shared/components/sidebar.tsx @@ -46,7 +46,7 @@ export function Sidebar() { return ( Date: Thu, 23 Oct 2025 11:31:52 -0300 Subject: [PATCH 09/11] fix: improve error handling in create base pipeline process --- src/features/user-area/pages/create-base-pipeline.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/features/user-area/pages/create-base-pipeline.tsx b/src/features/user-area/pages/create-base-pipeline.tsx index a74fdab..935fedc 100644 --- a/src/features/user-area/pages/create-base-pipeline.tsx +++ b/src/features/user-area/pages/create-base-pipeline.tsx @@ -25,6 +25,7 @@ import { CreateBaseData } from '../types/create-base-schema' import { useCreateKnowledgeBaseMutation } from '../hooks/use-kb' import { knowledgeBaseService } from '@/services/knowledge-base' import { bucketName } from '@/shared/enviroment' +import { AxiosError } from 'axios' type PipelineStep = { id: string @@ -257,7 +258,6 @@ export function CreateBasePipeline() { navigate('/bases') }, 5000) } catch (error) { - console.error('Pipeline error:', error) const currentStepIndex = pipeline.currentStep updateStepStatus( currentStepIndex, @@ -265,7 +265,9 @@ export function CreateBasePipeline() { 'Erro inesperado durante o processo' ) toast.error( - 'Erro ao criar base de conhecimento: ' + (error as Error).message + 'Erro ao criar base de conhecimento: ' + + (error as AxiosError<{ details: string }>).response?.data?.details || + (error as Error).message ) } } From f9736cd2affd7e8e6e247032f1dc3de2f6d777da Mon Sep 17 00:00:00 2001 From: Enzo Sakamoto Date: Thu, 23 Oct 2025 11:32:09 -0300 Subject: [PATCH 10/11] refactor: update styles for knowledge base detail modal for improved readability and consistency --- .../knowledge-base-detail-modal.tsx | 78 +++++++++++-------- 1 file changed, 46 insertions(+), 32 deletions(-) diff --git a/src/features/user-area/components/knowledge-base-detail-modal.tsx b/src/features/user-area/components/knowledge-base-detail-modal.tsx index 3145035..7d851cb 100644 --- a/src/features/user-area/components/knowledge-base-detail-modal.tsx +++ b/src/features/user-area/components/knowledge-base-detail-modal.tsx @@ -274,7 +274,7 @@ echo $data['response'];` - + {knowledgeBase.displayName} {knowledgeBase.status} @@ -287,31 +287,35 @@ echo $data['response'];` {/* Informações gerais */}
- - Criada em: - -

{knowledgeBase.createdAt.toLocaleDateString('pt-BR')}

+ Criada em: +

+ {knowledgeBase.createdAt.toLocaleDateString('pt-BR')} +

- + Última modificação: -

{knowledgeBase.updatedAt.toLocaleDateString('pt-BR')}

+

+ {knowledgeBase.updatedAt.toLocaleDateString('pt-BR')} +

- + Total de arquivos: -

+

{knowledgeBase.files.length} arquivo {knowledgeBase.files.length !== 1 ? 's' : ''}

- + Tamanho total: -

{knowledgeBase.totalSizeMB.toFixed(1)} MB

+

+ {knowledgeBase.totalSizeMB.toFixed(1)} MB +

@@ -319,9 +323,9 @@ echo $data['response'];` {/* API Keys */}
-

API Keys

+

API Keys

{knowledgeBase.keys.length === 0 ? ( -
+
Nenhuma chave de API encontrada
) : ( @@ -337,12 +341,12 @@ echo $data['response'];` className="hover:bg-muted/50 border-border rounded-lg border-1 p-4 transition-colors" >
- + {key.kbKeyAlias}
-
+
{isVisible ? key.kbKey : maskKey(key.kbKey)}
@@ -386,13 +390,15 @@ echo $data['response'];` className="hover:bg-muted/50 flex w-full items-center justify-between rounded-lg p-2 transition-colors" >
- -

Exemplos de Código

+ +

+ Exemplos de Código +

{isCodeSectionExpanded ? ( - + ) : ( - + )} @@ -405,7 +411,7 @@ echo $data['response'];` >
{knowledgeBase.keys.length === 0 ? ( -
+
Crie uma API Key para ver os exemplos de código
) : ( @@ -418,9 +424,11 @@ echo $data['response'];` onClick={() => setSelectedLanguage(lang.id)} size="sm" variant={ - selectedLanguage === lang.id ? 'default' : 'outline' + selectedLanguage === lang.id + ? 'secondary' + : 'outline' } - className="flex items-center gap-1.5" + className="text-foreground flex items-center gap-1.5" > {lang.icon} {lang.name} @@ -468,12 +476,14 @@ echo $data['response'];` {/* Lista de arquivos */}
-

Arquivos

+

+ Arquivos +

{knowledgeBase.files.length === 0 ? ( -
+

Nenhum arquivo encontrado

@@ -499,12 +509,12 @@ echo $data['response'];`

{file.fileName}

-

+

{formatFileSize(file.sizeMB)}

@@ -528,7 +538,11 @@ echo $data['response'];` {/* Botões de ação */}
-