Merge: mudanças locais + remotas do branch dev
This commit is contained in:
parent
3c37efecc6
commit
5900241df6
4 changed files with 36 additions and 25 deletions
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
Pr├│xima
|
||||
</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 (Número)</label>
|
||||
<label className="block text-sm font-medium text-gray-700">Licença Sanitária (Número)</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"
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ export function DashboardHome() {
|
|||
record.items,
|
||||
record.users,
|
||||
record.companies,
|
||||
record.tenants, // API retorna tenants para empresas
|
||||
record.products,
|
||||
record.orders
|
||||
]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
/>
|
||||
|
|
|
|||
Loading…
Reference in a new issue