Merge: mudanças locais + remotas do branch dev

This commit is contained in:
joaoaodt 2026-02-26 16:30:59 -03:00
parent 3c37efecc6
commit 5900241df6
4 changed files with 36 additions and 25 deletions

View file

@ -206,9 +206,10 @@ func (s *Server) Start(ctx context.Context) error {
}
repo := postgres.New(s.db)
if err := repo.ApplyMigrations(ctx); err != nil {
return err
}
// Migrações já aplicadas manualmente
// if err := repo.ApplyMigrations(ctx); err != nil {
// return err
// }
// Seed Admin
if s.cfg.AdminEmail != "" && s.cfg.AdminPassword != "" {
@ -263,8 +264,9 @@ func (s *Server) Start(ctx context.Context) error {
if err != nil {
// If error is duplicate key on company, maybe we should fetch the company and try creating user only?
// For now, let's log error but not fail startup hard, or fail hard to signal issue.
log.Printf("Failed to seed admin: %v", err)
// For now, let's log error but not fail startup hard
log.Printf("Failed to seed admin (may already exist): %v", err)
// Continue startup anyway
} else {
// FORCE VERIFY the admin company
if _, err := s.svc.VerifyCompany(ctx, company.ID); err != nil {

View file

@ -1,4 +1,4 @@
import { useEffect, useState } from 'react'
import { useEffect, useState } from 'react'
import { adminService, Company, CreateCompanyRequest } from '@/services/adminService'
import { useCepLookup } from '@/hooks/useCepLookup'
import { formatCNPJ, validateCNPJ } from '@/utils/cnpj'
@ -21,7 +21,7 @@ export function CompaniesPage() {
license_number: '',
latitude: -16.3281,
longitude: -48.9530,
city: 'Anápolis',
city: 'Anápolis',
state: 'GO',
phone: '',
email: '',
@ -73,16 +73,16 @@ export function CompaniesPage() {
// Only validate CNPJ on create (not on edit, since existing CNPJs may be legacy/test values)
if (!editingCompany) {
if (!formData.cnpj) {
setCnpjError('CNPJ é obrigatório')
setCnpjError('CNPJ ├® obrigat├│rio')
return
}
const cnpjDigits = formData.cnpj.replace(/\D/g, '')
if (cnpjDigits.length !== 14) {
setCnpjError('CNPJ deve ter 14 dígitos')
setCnpjError('CNPJ deve ter 14 dígitos')
return
}
if (!validateCNPJ(formData.cnpj)) {
setCnpjError('CNPJ inválido. Verifique o dígito verificador')
setCnpjError('CNPJ inválido. Verifique o dígito verificador')
return
}
}
@ -171,7 +171,7 @@ export function CompaniesPage() {
license_number: '',
latitude: -16.3281,
longitude: -48.9530,
city: 'Anápolis',
city: 'Anápolis',
state: 'GO',
phone: '',
email: '',
@ -233,12 +233,12 @@ export function CompaniesPage() {
<table className="min-w-full divide-y divide-gray-200">
<thead className="text-white" style={{ backgroundColor: '#0F4C81' }}>
<tr>
<th className="px-4 py-3 text-left text-sm font-medium">Razão Social</th>
<th className="px-4 py-3 text-left text-sm font-medium">Razúo Social</th>
<th className="px-4 py-3 text-left text-sm font-medium">CNPJ</th>
<th className="px-4 py-3 text-left text-sm font-medium">Categoria</th>
<th className="px-4 py-3 text-left text-sm font-medium">Cidade</th>
<th className="px-4 py-3 text-center text-sm font-medium">Verificada</th>
<th className="px-4 py-3 text-right text-sm font-medium">Ações</th>
<th className="px-4 py-3 text-right text-sm font-medium">AºÁes</th>
</tr>
</thead>
<tbody className="divide-y divide-gray-200">
@ -273,7 +273,7 @@ export function CompaniesPage() {
: 'bg-yellow-100 text-yellow-800'
}`}
>
{company.is_verified ? ' Verificada' : 'Pendente'}
{company.is_verified ? 'Ô£ô Verificada' : 'Pendente'}
</button>
</td>
<td className="px-4 py-3 text-right">
@ -316,7 +316,7 @@ export function CompaniesPage() {
disabled={page >= totalPages}
className="rounded border px-3 py-1 text-sm disabled:opacity-50"
>
Próxima
Prxima
</button>
</div>
</div>
@ -335,7 +335,7 @@ export function CompaniesPage() {
<div className="col-span-2">
<label className="block text-sm font-medium text-gray-700">
CNPJ
{editingCompany && <span className="ml-2 text-xs text-gray-400">(não editável)</span>}
{editingCompany && <span className="ml-2 text-xs text-gray-400">(núo editível)</span>}
</label>
<input
type="text"
@ -373,9 +373,9 @@ export function CompaniesPage() {
/>
</div>
{/* Razão Social */}
{/* Razão Social */}
<div className="col-span-2">
<label className="block text-sm font-medium text-gray-700">Razão Social</label>
<label className="block text-sm font-medium text-gray-700">Razúo Social</label>
<input
type="text"
value={formData.corporate_name}
@ -404,7 +404,7 @@ export function CompaniesPage() {
onChange={(e) => setFormData({ ...formData, category: e.target.value })}
className="mt-1 w-full rounded border border-gray-300 px-3 py-2 focus:border-blue-500 focus:ring-1 focus:ring-blue-500 outline-none"
>
<option value="farmacia">Farmácia</option>
<option value="farmacia">Farmícia</option>
<option value="distribuidora">Distribuidora</option>
<option value="admin">Admin</option>
</select>
@ -435,9 +435,9 @@ export function CompaniesPage() {
/>
</div>
{/* Licença Sanitária */}
{/* Licença Sanitária */}
<div className="col-span-2">
<label className="block text-sm font-medium text-gray-700">Licença Sanitária (mero)</label>
<label className="block text-sm font-medium text-gray-700">Licenºa Sanitíria (Nmero)</label>
<input
type="text"
value={formData.license_number}
@ -449,7 +449,7 @@ export function CompaniesPage() {
{editingCompany && (
<div className="col-span-2">
<label className="block text-sm font-medium text-gray-700 mb-1">
Upload de Documento (Licença PDF/Imagem)
Upload de Documento (Licenºa PDF/Imagem)
</label>
<input
type="file"
@ -502,7 +502,7 @@ export function CompaniesPage() {
<div className="col-span-2">
<label className="block text-sm font-medium text-gray-700">
CEP
{cepLoading && <span className="ml-2 text-xs text-blue-500 animate-pulse">🔍 Buscando...</span>}
{cepLoading && <span className="ml-2 text-xs text-blue-500 animate-pulse">­ƒöì Buscando...</span>}
</label>
<input
type="text"

View file

@ -38,6 +38,7 @@ export function DashboardHome() {
record.items,
record.users,
record.companies,
record.tenants, // API retorna tenants para empresas
record.products,
record.orders
]

View file

@ -346,8 +346,12 @@ export function ProductsPage() {
<input
type="number"
step="0.01"
min="0"
value={formData.price_cents / 100}
onChange={(e) => setFormData({ ...formData, price_cents: Math.round(parseFloat(e.target.value) * 100) })}
onChange={(e) => {
const value = parseFloat(e.target.value)
setFormData({ ...formData, price_cents: isNaN(value) ? 0 : Math.round(value * 100) })
}}
className="mt-1 w-full rounded border px-3 py-2"
required
/>
@ -356,8 +360,12 @@ export function ProductsPage() {
<label className="block text-sm font-medium text-gray-700">Estoque</label>
<input
type="number"
min="0"
value={formData.stock}
onChange={(e) => setFormData({ ...formData, stock: parseInt(e.target.value) })}
onChange={(e) => {
const value = parseInt(e.target.value)
setFormData({ ...formData, stock: isNaN(value) ? 0 : value })
}}
className="mt-1 w-full rounded border px-3 py-2"
required
/>