Clients module handles all client-facing functionality: browsing and searching clients, adding and editing client records, viewing debt history, recording partial or full payments, and selecting a client from a modal when completing a credit sale.
Properties
| Property | Type | Description |
|---|---|---|
currentClients | array | In-memory cache of all clients, loaded from Storage. Updated on every loadClients() call. |
searchTerm | string | The current client list search filter. Updated by the #searchClients input. Defaults to ''. |
onClientSelect | function | null | Callback invoked when a client is chosen in the selector modal. Set by showClientSelector(). |
Methods
Clients.init()
Loads clients from storage and binds all DOM event listeners. Called once by App.init().
Clients.loadClients()
Fetches the clients array from Storage.getClients(), stores it in currentClients, and calls render().
Clients.bindEvents()
Attaches event listeners to:
#btnAddClient— opens the client form in create mode.#clientForm— handles form submission viasaveClient().#paymentForm— handles payment form submission viarecordPayment().#searchClients— updatessearchTermand callsrender().#searchClientSelect— callsrenderClientSelector()to filter the selector modal.#clientsList— delegates clicks on.client-cardelements toshowClientDetail().#clientNotesList— delegates clicks on.btn-paybuttons toshowPaymentForm().
Clients.render()
Renders client cards in #clientsList, filtered by searchTerm. Each card displays the client name, optional phone number, and current debt. Cards with a non-zero saldoDeuda receive the has-debt CSS class.
Shows a “No se encontraron clientes” message when no clients match the filter.
Clients.showClientForm(client)
Opens the client modal. If client is provided, pre-fills the form with the client’s name and phone for editing and sets the title to “Editar Cliente”. Otherwise resets the form for creating a new client.
The client to edit. Pass
null (or omit) to open in create mode.Clients.saveClient()
Reads nombre and telefono from the client form. Validates that nombre is not empty, then calls either Storage.updateClient() or Storage.addClient(). Reloads the client list, shows a toast, and closes the client modal.
Shows an error toast and returns early if the name field is blank.
Clients.showClientDetail(clientId)
Opens the clientDetail modal for the given client. Displays the client’s name and total outstanding debt, then renders their debt notes sorted newest-first. Each note shows the date, product summary (e.g., “2x Coca Cola 1L”), total, and remaining balance. Unpaid notes include an “Abonar” button that triggers showPaymentForm().
The id of the client to display.
Clients.showPaymentForm(clientId, noteId, pending)
Opens the payment modal pre-filled with the outstanding amount. Sets the max attribute on the amount input to prevent over-payment.
The id of the client making the payment.
The id of the debt note being paid.
The outstanding amount to pre-fill in the payment input.
Clients.recordPayment()
Reads the payment amount from the form. Validates that the amount is positive and does not exceed the pending balance, then calls Storage.recordPayment(). Shows a success toast, closes the payment modal, reloads the client list, and reopens the client detail modal after a 100 ms delay.
Clients.showClientSelector(callback)
Stores callback as onClientSelect, renders the full unfiltered client list in the selector, and opens the selectClient modal. When a client is chosen, callback is called with the client’s id.
Used by Sales.selectClientForCredit() to let the cashier assign a credit sale to a client.
Function called with
(clientId: string) when the user selects a client.Clients.renderClientSelector(searchTerm)
Renders a filterable client list in #selectClientList. Each item is clickable and invokes onClientSelect with the chosen client’s id. If no clients match, shows an “Agregar Nuevo Cliente” button that opens the client form.
Text to filter clients by name. Matched case-insensitively.
Clients.escapeHtml(text)
Sanitizes a string to prevent XSS when injecting user-provided content into HTML. Creates a temporary <div> element, assigns the text as textContent, and returns innerHTML.
The raw string to sanitize.
The HTML-escaped string safe for insertion into the DOM.