saveinmed/frontend/src/utils/cnpj.ts
eycksilva 3559afc1f7 feat(ui): padronizar paleta #0F4C81 e estrutura em múltiplas telas
- SellerDashboard: migrado para Shell (header topo), removida sidebar lateral,
  cards KPI brancos com react-icons pretos (FaChartLine, FaBoxOpen, FaReceipt)
- Shell: adicionados todos os links de nav para owner/seller no header
  (Estoque, Buscar Produtos, Pedidos, Carteira, Equipe, Config. Entrega)
- Wallet: ícone FaMoneyCheck no botão Solicitar Saque, card saldo com #0F4C81,
  thead da tabela com #0F4C81, fix R$ NaN (formatCurrency null-safe)
- Team: botões e thead com #0F4C81, emojis removidos dos roleLabels
- ShippingSettings: wrapped com Shell (mantém header), emojis substituídos por
  react-icons pretos (FaTruck, FaLocationDot, FaStore, FaCircleInfo, FaFloppyDisk),
  botão Salvar com #0F4C81
- Orders: removido box cinza de fundo dos ícones nas abas e estado vazio
- LocationPicker: fallback seguro para OpenStreetMap quando VITE_MAP_TILE_LAYER
  não está definido (corrige tela branca em /search)
- Inventory/Cart: cores dos botões e thead atualizadas para #0F4C81
2026-02-26 15:56:03 -03:00

70 lines
1.9 KiB
TypeScript

/**
* Validates a CNPJ (Cadastro Nacional da Pessoa Jurídica)
* Checks format and verifies check digits
*/
export function validateCNPJ(cnpj: string): boolean {
// Remove non-numeric characters
const cleaned = cnpj.replace(/\D/g, '')
// Must have exactly 14 digits
if (cleaned.length !== 14) {
return false
}
// All same digits are invalid
if (/^(\d)\1{13}$/.test(cleaned)) {
return false
}
// Validate first check digit
let sum = 0
let position = 5
for (let i = 0; i < 8; i++) {
sum += parseInt(cleaned[i]) * position
position -= 1
}
let remainder = sum % 11
const firstDigit = remainder < 2 ? 0 : 11 - remainder
if (parseInt(cleaned[8]) !== firstDigit) {
return false
}
// Validate second check digit
sum = 0
position = 9
for (let i = 0; i < 9; i++) {
sum += parseInt(cleaned[i]) * position
position -= 1
}
remainder = sum % 11
const secondDigit = remainder < 2 ? 0 : 11 - remainder
if (parseInt(cleaned[9]) !== secondDigit) {
return false
}
return true
}
/**
* Formats a CNPJ string to the standard format: 00.000.000/0000-00
* Accepts both formatted and unformatted input
*/
export function formatCNPJ(value: string): string {
const cleaned = value.replace(/\D/g, '').slice(0, 14)
if (cleaned.length === 0) return ''
if (cleaned.length <= 2) return cleaned
if (cleaned.length <= 5) return `${cleaned.slice(0, 2)}.${cleaned.slice(2)}`
if (cleaned.length <= 8) return `${cleaned.slice(0, 2)}.${cleaned.slice(2, 5)}.${cleaned.slice(5)}`
if (cleaned.length <= 12) return `${cleaned.slice(0, 2)}.${cleaned.slice(2, 5)}.${cleaned.slice(5, 8)}/${cleaned.slice(8)}`
return `${cleaned.slice(0, 2)}.${cleaned.slice(2, 5)}.${cleaned.slice(5, 8)}/${cleaned.slice(8, 12)}-${cleaned.slice(12)}`
}
/**
* Removes CNPJ formatting, returning only digits
*/
export function removeCNPJFormatting(cnpj: string): string {
return cnpj.replace(/\D/g, '')
}