Skip to main content

Frontend

The Taxes module uses the Partial Views pattern to keep the global index modular. All strings use translation keys — no hardcoding.

File Structure

resources/views/taxes/
├── index.blade.php
├── index/
│ ├── _header.blade.php
│ ├── _stats-cards.blade.php
│ ├── _filters.blade.php
│ ├── _table.blade.php
│ ├── _empty-state.blade.php
│ ├── filters/
│ │ ├── _search.blade.php
│ │ ├── _reference-year.blade.php
│ │ ├── _paid.blade.php
│ │ └── _actions.blade.php
│ ├── stats-cards/
│ │ ├── _total-all-time.blade.php
│ │ ├── _this-year.blade.php
│ │ ├── _unpaid.blade.php
│ │ └── _count-this-year.blade.php
│ └── tax-table/
│ ├── _header.blade.php
│ └── _row.blade.php
└── partials/
├── _modal-form.blade.php
├── _form-fields.blade.php
└── _upload-attachment-modal.blade.php

resources/js/components/
├── taxModal.js
└── taxAttachmentModal.js

Frontend Pattern

Orchestrator View

taxes/index.blade.php acts as orchestrator:

  • includes header, stat cards, filters
  • renders table or empty-state based on $taxes->isNotEmpty()
  • includes both modals at the bottom

Color Scheme

The module uses amber as the primary accent color (fiscal/tax theme), with red for unpaid amounts.

Filters

The filter bar uses a 4-column grid:

FilterInputParameter
Searchtext inputsearch
Reference yearselectreference_year
Paid statusselectpaid (1/0/all)
Actionsreset button

The _reference-year.blade.php partial receives $availableYears from the controller (logic never in the view). The list starts from 2026 and grows automatically each year.

Stat Cards

CardValueColor
Total All TimeSum of all paid taxesAmber
This YearTaxes paid in current yearAmber
UnpaidSum of unpaid taxesRed
Taxes This YearCount of taxes due this yearAmber

Tax Table Row

Each row (tax-table/_row.blade.php) shows:

ColumnNotes
DescriptionWith optional notes preview
AmountFormatted with $currencySymbol
Due DateWith unpaid badge if past and unpaid; Google Calendar icon if unpaid
Paid AtCheckmark + date if paid, <x-not-set-badge> otherwise
Reference YearAmber pill badge
AttachmentPreview / download / delete icons + upload button
ActionsEdit / delete

Google Calendar Button

Displayed on the due date cell only when !$tax->paid_at. Calls $tax->googleCalendarUrl() (generated by GoogleCalendarLinkBuilder). Opens Google Calendar in a new tab with the event pre-filled — Google Calendar handles reminders natively.

Attachment Actions

ActionRouteCondition
Previewtaxes.attachment.previewHas attachment
Downloadtaxes.attachment.downloadHas attachment
Deletetaxes.attachment.destroyHas attachment
Uploadupload-tax-attachment eventAlways visible

Modals (Alpine.js)

Tax Modal

Manages create and edit operations.

  • View: taxes/partials/_modal-form.blade.php
  • Component: resources/js/components/taxModal.js

Flow:

  • open create → data-action="open-tax-modal" button dispatches open-tax-modal event
  • open edit → data-action="edit-tax" with data-payload dispatches edit-tax event with record payload
  • submit to taxes.store (POST) or taxes.update (PUT)

State managed: open, isEdit, taxId, formData.

Upload Attachment Modal

Manages document upload per tax record.

  • View: taxes/partials/_upload-attachment-modal.blade.php
  • Component: resources/js/components/taxAttachmentModal.js

Flow:

  • open → data-action="upload-tax-attachment" with data-payload="{taxId}" dispatches event
  • dynamic uploadUrl construction (/taxes/{taxId}/attachment)
  • file selection triggers handleFileSelect()
  • submit uploads to taxes.attachment.upload

Global JS Wiring

Component registration in resources/js/app.js:

import taxModal from './components/taxModal.js';
import taxAttachmentModal from './components/taxAttachmentModal.js';

window.taxModal = taxModal;
window.taxAttachmentModal = taxAttachmentModal;

The global data-action listener in app.js dispatches the custom events used by both modals.

Internationalization

All strings use translation keys — no hardcoded text:

  • lang/*/taxes.php — all module strings
  • lang/*/ui.php — shared UI strings (ui.upload, ui.download, ui.preview, ui.delete, ui.edit, ui.choose_file, ui.or_drag)

Translations available in 13 languages: it, en, de, fr, es, pt, nl, pl, ro, ru, uk, da, zh.

Dark Mode

The module supports dark mode via Tailwind dark:* classes, consistent with the application layout.