Adiciona o frontend Next.js em frontend/ (setup, design system, autenticação/tema, layout/navegação, área master, área tenant completa: clientes, produtos, vendas, recebimentos, whatsapp, e-mail, alertas, equipe e perfil). Estende o backend de forma aditiva e autorizada: cookie httpOnly para refresh token (Etapa 13) e CRUD de equipe + edição de perfil do tenant (Etapa 18, módulo src/modules/equipe/ novo e PUT /tenant/perfil). Detalhes completos em Etapas/V2/*. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
108 lines
3.0 KiB
TypeScript
108 lines
3.0 KiB
TypeScript
import { apiClient } from '@/lib/api/client';
|
|
import { buildQuery, type PaginatedResult } from '@/lib/api/types';
|
|
|
|
/** Espelha o model `customers`. */
|
|
export interface Customer {
|
|
id: string;
|
|
razao_social: string;
|
|
nome_fantasia: string | null;
|
|
documento: string | null;
|
|
email: string | null;
|
|
telefone_whatsapp: string | null;
|
|
endereco: string | null;
|
|
cidade: string | null;
|
|
uf: string | null;
|
|
observacoes: string | null;
|
|
ativo: boolean;
|
|
criado_em: string;
|
|
atualizado_em: string;
|
|
}
|
|
|
|
/** `GET /tenant/customers/:id` inclui os contatos. */
|
|
export interface CustomerDetail extends Customer {
|
|
contatos: CustomerContact[];
|
|
}
|
|
|
|
/** Espelha `CreateCustomerDto`/`UpdateCustomerDto` — `ativo` fica de fora de propósito (só via desativar). */
|
|
export interface CustomerInput {
|
|
razao_social: string;
|
|
nome_fantasia?: string;
|
|
documento?: string;
|
|
email?: string;
|
|
telefone_whatsapp?: string;
|
|
endereco?: string;
|
|
cidade?: string;
|
|
uf?: string;
|
|
observacoes?: string;
|
|
}
|
|
|
|
export interface ListCustomersParams {
|
|
busca?: string;
|
|
ativo?: boolean;
|
|
page?: number;
|
|
limit?: number;
|
|
}
|
|
|
|
export function listCustomers(params: ListCustomersParams) {
|
|
return apiClient.get<PaginatedResult<Customer>>(`/tenant/customers${buildQuery(params)}`);
|
|
}
|
|
|
|
export function getCustomer(id: string) {
|
|
return apiClient.get<CustomerDetail>(`/tenant/customers/${id}`);
|
|
}
|
|
|
|
export function createCustomer(input: CustomerInput) {
|
|
return apiClient.post<Customer>('/tenant/customers', input);
|
|
}
|
|
|
|
export function updateCustomer(id: string, input: Partial<CustomerInput>) {
|
|
return apiClient.put<Customer>(`/tenant/customers/${id}`, input);
|
|
}
|
|
|
|
/** Soft delete (`ativo: false`). */
|
|
export function deactivateCustomer(id: string) {
|
|
return apiClient.delete<Customer>(`/tenant/customers/${id}`);
|
|
}
|
|
|
|
/** Espelha o model `customer_contacts`. */
|
|
export interface CustomerContact {
|
|
id: string;
|
|
customer_id: string;
|
|
nome: string;
|
|
cargo: string | null;
|
|
email: string | null;
|
|
telefone_whatsapp: string | null;
|
|
principal: boolean;
|
|
criado_em: string;
|
|
}
|
|
|
|
/** Espelha `CreateContactDto`/`UpdateContactDto`. */
|
|
export interface CustomerContactInput {
|
|
nome: string;
|
|
cargo?: string;
|
|
email?: string;
|
|
telefone_whatsapp?: string;
|
|
principal?: boolean;
|
|
}
|
|
|
|
export function listCustomerContacts(customerId: string) {
|
|
return apiClient.get<CustomerContact[]>(`/tenant/customers/${customerId}/contatos`);
|
|
}
|
|
|
|
export function createCustomerContact(customerId: string, input: CustomerContactInput) {
|
|
return apiClient.post<CustomerContact>(`/tenant/customers/${customerId}/contatos`, input);
|
|
}
|
|
|
|
export function updateCustomerContact(
|
|
customerId: string,
|
|
contactId: string,
|
|
input: Partial<CustomerContactInput>,
|
|
) {
|
|
return apiClient.put<CustomerContact>(`/tenant/customers/${customerId}/contatos/${contactId}`, input);
|
|
}
|
|
|
|
/** Hard delete. */
|
|
export function deleteCustomerContact(customerId: string, contactId: string) {
|
|
return apiClient.delete<void>(`/tenant/customers/${customerId}/contatos/${contactId}`);
|
|
}
|