Commit graph

49 commits

Author SHA1 Message Date
Alexandre Brandizzi
30c43a4d86
SH-281: group vendor directory rows by company (#188)
* fix(vendors): add accessible trade overflow tooltip

* fix(vendors): add accessible trade overflow tooltip

* refactor(vendors): satisfy row maintainability gate

* feat(vendors): group directory rows by company

* chore(vendors): trigger SH-281 review checks

* test(vendors): align company directory visuals

* test(vendors): complete company visual baselines

* fix(vendors): keep empty states in viewport

* test(vendors): align centered empty baseline

* fix(vendors): use grouped directory endpoint

* test(vendors): follow grouped directory endpoint

* test(vendors): refresh combined visual snapshots

---------

Co-authored-by: Codex Review Integration <codex-review@local.invalid>
2026-09-16 14:40:24 -03:00
Alexandre Brandizzi
861f820715
SH-279: replace Vendor trade overflow title with MUI Tooltip (#187)
Some checks are pending
Frontend checks / Build and test (push) Waiting to run
Frontend checks / governance (push) Waiting to run
Frontend checks / Visual regression (push) Waiting to run
Deploy dev content / Deploy shoc-frontend-new-dev through Terraform (push) Waiting to run
* fix(vendors): add accessible trade overflow tooltip

* refactor(vendors): satisfy row maintainability gate

---------

Co-authored-by: Codex Review Integration <codex-review@local.invalid>
2026-09-15 16:23:14 -03:00
Alexandre Brandizzi
80be702733
feat(vendors): structure the address into Street/City/State with autocomplete (#176)
* feat(vendors): structure the address into Street/City/State with autocomplete

The Vendor form carried one free-text "Address (optional)" line, with City,
State and Zip already present but hidden behind display:none, and a separate
"Google Maps URL" input someone had to paste into by hand.

Street Address, City and State are now three required fields. Typing three
characters in Street Address offers up to four candidates; picking one fills
all three at once, and typing without picking stays plain free text. The
Google Maps URL input is gone — the location is derived from the address, the
Street Address itself is the link in view mode, and a keyless map preview
renders once all three parts are present. Zip stays in the payload but out of
the form; the ticket scopes the visible set to three.

The suggestion algorithm, candidate cities and copy are ported from the
approved prototype rather than invented, so dev and design agree on what a
dispatcher sees. Suggestions are deterministic for a given input on purpose:
a reshuffling list moves a row out from under the pointer mid-click.

Test fixtures that predate the requirement now carry an address, so each test
still fails for the reason it is about. The two drawer tests asserting the
stored-URL "Open in Google Maps" row are rewritten to the behaviour that
replaced it.

Delivers SH-271.

* feat(work-orders): show the vendor location map in the Vendor dialog

The last of SH-271's five acceptance bullets. The Work Order Vendor dialog
gets one composed address line from the vendor dropdown payload, not the
structured parts the form and detail drawer hold, so the preview takes the
line directly — it is saved data either way, and the completeness rule exists
to stop a map of half-typed input, not to reject a stored address.

The dialog's hand-built maps URL now goes through the shared helper, so the
link and the preview cannot drift apart.

* test(vendors): update the browser specs and pixel baselines for the new address

`npm run verify` does not run Playwright, so the first push went out with the
browser suite still asserting the UI this ticket removes. Three assertions
were stale: the combined "Address (optional)" input, the "Google Maps URL
(optional)" input, and the detail drawer's separate "Open in Google Maps"
row — now replaced by the Street Address itself being the link, checked
against the derived href. A fourth test created a vendor without an address,
which the new requirement blocks; it fills one, so the test still fails only
for the reason it is about.

Baselines regenerated in mcr.microsoft.com/playwright:v1.61.1-noble, the image
CI uses — macOS font rendering produces different pixels. Exactly three of the
sixteen were rewritten (vendor add, edit, detail); the rest, including every
Work Orders shot, are byte-identical, which is the evidence that this change
stays inside the surfaces it claims.

* test(vendors): keep the map preview out of the pixel baselines

The visual suite mocks `**/api/**` and nothing else, so the address map
preview's iframe reached maps.google.com for real. Whether that frame paints,
and what it paints, depends on the network and on what Google serves that
minute — which is why `vendor-edit` failed in CI at 18178 differing pixels
while passing in a container that could not reach Google. Regenerating the
baseline would not have fixed it; it would have moved the flake.

Aborting the request pins the frame to a blank box, so the shot measures our
layout and nothing else. The committed baselines are unchanged by this — they
were already correct — and a second container run with no --update passes
16/16, which is the evidence the shot is now stable rather than merely green
once.

* fix(vendors): complete structured address map flows

* test(vendors): align add visual baseline with CI

---------

Co-authored-by: Codex Review Integration <codex-review@local.invalid>
2026-09-15 16:13:15 -03:00
Alexandre Brandizzi
d6755a63b6
fix(vendors): clarify blank technician draft state (#157)
Some checks failed
Frontend checks / Build and test (push) Has been cancelled
Frontend checks / governance (push) Has been cancelled
Frontend checks / Visual regression (push) Has been cancelled
Deploy / deploy (push) Has been cancelled
* fix(vendors): clarify blank technician draft state

* test(vendors): update technician section snapshots

---------

Co-authored-by: Codex Review Integration <codex-review@local.invalid>
2026-08-28 15:00:02 -04:00
Alexandre Brandizzi
5e38c93b1e
fix(vendors): truncate long textual table values (#154)
Some checks are pending
Frontend checks / Build and test (push) Waiting to run
Frontend checks / governance (push) Waiting to run
Frontend checks / Visual regression (push) Waiting to run
Deploy / deploy (push) Waiting to run
* fix(vendors): truncate long locations in table

* fix(vendors): truncate textual table cells

---------

Co-authored-by: Codex Review Integration <codex-review@local.invalid>
2026-08-28 11:21:15 -04:00
Alexandre Brandizzi
40ce66fbb3
fix(vendors): keep Company label visible after scroll (#150)
Some checks are pending
Frontend checks / Build and test (push) Waiting to run
Frontend checks / governance (push) Waiting to run
Frontend checks / Visual regression (push) Waiting to run
Deploy / deploy (push) Waiting to run
* fix(vendors): keep Company label visible after scroll

* test(vendors): align Add Vendor visual baseline with CI

* test(vendors): prove full label visibility after scroll

---------

Co-authored-by: Codex Review Integration <codex-review@local.invalid>
2026-08-27 20:52:42 +00:00
Alexandre Brandizzi
7ec522e8ea
fix: complete SH-283 vendor QA paths (#148)
Some checks are pending
Frontend checks / Build and test (push) Waiting to run
Frontend checks / governance (push) Waiting to run
Frontend checks / Visual regression (push) Waiting to run
Deploy / deploy (push) Waiting to run
Co-authored-by: Codex Review Integration <codex-review@local.invalid>
2026-08-27 15:03:36 -03:00
Alexandre Brandizzi
3b1fe016fe
fix(vendors): clarify required company fields (#146)
Some checks are pending
Frontend checks / Build and test (push) Waiting to run
Frontend checks / governance (push) Waiting to run
Frontend checks / Visual regression (push) Waiting to run
Deploy / deploy (push) Waiting to run
* fix(vendors): clarify required company fields

* test(vendors): refresh company label snapshots

* refactor(vendors): isolate contact fields

---------

Co-authored-by: Codex Review Integration <codex-review@local.invalid>
Co-authored-by: Adam Moussa <166072409+amoussa1229@users.noreply.github.com>
2026-08-27 13:01:53 -04:00
Alexandre Brandizzi
338cc17b8a
fix(vendors): remove duplicate company heading (#139)
* fix(vendors): remove duplicate company heading

* test(vendors): align detail baseline with CI

---------

Co-authored-by: Codex Review Integration <codex-review@local.invalid>
Co-authored-by: Adam Moussa <166072409+amoussa1229@users.noreply.github.com>
2026-08-26 16:45:06 +00:00
Alexandre Brandizzi
8fa37cf430
fix(vendors): display company contact fallbacks (#135)
Some checks are pending
CI / ci (push) Waiting to run
CI / governance (push) Waiting to run
CI / visual-regression (push) Waiting to run
Deploy / deploy (push) Waiting to run
Co-authored-by: Codex Review Integration <codex-review@local.invalid>
2026-08-25 20:03:18 -04:00
Codex Review Integration
01a7a22c07 fix(vendors): remove obsolete trade reorder controls (SH-182) 2026-08-21 11:42:06 -03:00
Codex Review Integration
f0f3485bee fix(vendors): preserve status during roster edits 2026-08-20 20:59:27 -03:00
Codex Review Integration
146491fafb fix(vendors): persist technician removal 2026-08-20 20:43:52 -03:00
Alexandre Brandizzi
35bfb9b7c8 fix(vendors): correct roster validation and editing 2026-08-20 18:25:34 -03:00
Alexandre Brandizzi
4d8e86b264
Merge branch 'dev' into feat/sh-249-fe-trades 2026-08-20 11:48:07 -03:00
Alexandre Brandizzi
3141adba13
Merge branch 'dev' into feat/sh-254-fe-deactivate-confirm 2026-08-20 11:24:12 -03:00
Alexandre Brandizzi
326ac18eb0
Merge branch 'dev' into feat/sh-254-fe-deactivate-confirm 2026-08-20 11:15:10 -03:00
Codex Review Integration
aebb2c6b1a Merge remote-tracking branch 'origin/dev' into feat/sh-253-vendor-detail-parity
# Conflicts:
#	src/test/app/(protected)/vendors/vendor-detail-drawer.test.tsx
2026-08-20 11:14:51 -03:00
Alexandre Brandizzi
98daf9832d
Merge branch 'dev' into feat/sh-255-deactivate-toggle-gate 2026-08-20 11:06:54 -03:00
Codex Review Integration
22b03b8ac0 fix(vendors): deactivation dialog follows the approved design (SH-254)
The dialog's wording, its actions and its behaviour all diverged from the
design prototype. It refused deactivation outright when the vendor had
open work orders, which SH-44 and SH-82 left as an open question rather
than a decided requirement.

Deactivation with open work orders now proceeds on explicit confirmation:
the design's title and body copy, the affected work orders listed as
links, and "Deactivate anyway" in place of a disabled button. The API
call carries confirmOpenWorkOrders so the server-side guard is cleared
deliberately rather than removed.
2026-08-19 13:36:37 -03:00
Codex Review Integration
038ce263da fix(vendors): vendor detail parity with the design prototype (SH-253)
Three divergences in the vendor detail drawer:

- The header rendered the company as a subtitle under a title that had
  already fallen back to the company, printing the same name twice when
  the row carried no technician. The subtitle is now dropped when it
  would repeat the title.
- The Google Maps link appeared only when a URL was stored, unlabelled,
  so an empty value left no trace of the field. It is now a labelled
  field below Address that reads em-dash when unset, as every other
  field in the panel does.
- The status sat immediately beside Total Jobs. It now sits opposite it
  at the right edge, and reuses the vendors table's dot-plus-text badge
  so the state never reads by colour alone.
2026-08-19 13:22:11 -03:00
Codex Review Integration
90a5256dee fix(vendors): gate deactivation prompt on saved status (SH-255)
The drawer's Active toggle asked to deactivate whenever the switch moved
from on to off, reading the unsaved form value. An inactive vendor toggled
on and back off without saving therefore raised "Deactivate this vendor"
for a vendor that was already inactive.

Gate on the persisted technician status from the loaded roster instead,
falling back to the clicked row. Deactivation is a property of the saved
vendor, not of the toggle.
2026-08-19 13:18:17 -03:00
Codex Review Integration
1305bf35dd fix(vendors): bypass the query cache when reloading after a conflict (SH-250)
The reload fix re-seeded the form from queryClient.fetchQuery, which inherits the
global 5-minute staleTime. A 409 never invalidates that key -
useSaveVendorCompanyRoster invalidates only in onSuccess and its onError returns
early for conflicts - and the Add flow has no mounted observer on it, so reload
returned the cached roster with the same stale rowVersion and every retry 409'd
again. Update mode was unaffected because it recovers via query.refetch(), which
bypasses staleTime.

Pass staleTime: 0 on that fetch, since its sole purpose is the freshest
rowVersion. The regression test uses a client with the app's real staleTime; the
default test client uses 0, which masked this entirely.
2026-08-19 10:26:28 -03:00
Codex Review Integration
cccb0e4ca7 refactor(vendors): extract trade rejection message to satisfy length gate (SH-249)
The loading-aware gate pushed VendorTradeSpecialtiesField to 151 lines, one over
the changed-file maintainability cap. Move the rejection-message resolution and
the contract explanation to module scope; no behavior change.
2026-08-18 18:09:23 -03:00
Codex Review Integration
9a066092b3 fix(vendors): correct additive add reload, phone and contact (SH-250, SH-246)
Three review findings on the additive add path:

- Create-mode reload refreshed selectedRoster (including rowVersion) but left
  the form company fields on their pre-conflict values, so a retry diffed stale
  fields against the reloaded roster and could overwrite the concurrent company
  update that caused the 409. Reload now resets the form from the fresh roster,
  matching the select path.
- mapVendorRosterAdditivePatchToBackend copied companyFields verbatim while the
  reconcile write mapper canonicalizes companyPhone, so PATCH and PUT could send
  different phone shapes for the same input.
- emptyRosterTechnician seeded preferredContact "Phone" even though that
  control was removed from the form, so filling the first blank row submitted a
  fabricated value. append already omitted it; both paths now agree.
2026-08-18 17:28:48 -03:00
Codex Review Integration
64caab1832 fix(vendors): do not fail open while the trades facet is loading (SH-249)
An empty tradeOptions array meant two different things: "facets query still in
flight" and "vocabulary genuinely unavailable". Both enabled fail-open free
text and showed the outage warning, so a normal cold fetch looked like an
outage. Anything committed in that window was added to knownTradesRef and stayed
selectable after the canonical list arrived, permanently undermining the gate.

Expose the facets query isLoading as tradesLoading, thread it to the field as
tradeOptionsLoading, and keep the canonical gate active while loading. The
outage warning now shows only once the query has settled empty.
2026-08-18 17:25:44 -03:00
Codex Review Integration
9624c264de fix(vendors): send only user-edited company fields on additive add (SH-250)
Adversarial review found a last-writer-wins window: after a stale 409 the
roster is refetched while the form keeps its pre-conflict values, so the
form-vs-roster diff resent our stale value for any company field another
user changed in that window, silently reverting their edit.

Transmit only fields the user actually edited, taken from react-hook-form
dirty state. Selecting a company calls reset(), so loaded values are never
dirty and only genuine edits are sent.

dirtyFields is resolved during render: formState is a Proxy that only tracks
properties read at render time, so reading it inside the submit callback
returned empty. The vendors E2E caught that; unit tests could not, since
they pass the flags in directly.
2026-08-18 14:42:01 -03:00
Codex Review Integration
63e37dd0bb fix(vendors): keep trades live region out of Stack spacing (SH-249)
The always-mounted aria-live feedback region inherited MUI Stack spacing,
adding a permanent gap under the trades input and shifting the approved
Vendor edit drawer layout. vendor-visual-regression caught it.

Move the region outside the spaced Stack and collapse it while silent, so
the live region stays in the DOM for announcements without claiming layout.
Restores the caption to MUI Typography; that swap was cosmetic and out of
scope for SH-249.
2026-08-18 14:27:42 -03:00
Codex Review Integration
df00e56d6e fix(vendors): gate trades to canonical list, preserve legacy values (SH-249) 2026-08-18 13:12:10 -03:00
Codex Review Integration
a710e21281 fix(vendors): additive technician add for existing companies (SH-250, SH-246) 2026-08-18 13:09:33 -03:00
Arthur Bassi
4af826a1e0
feat(work-orders): query broadcast, remove auth bypass, dispatch polish (#100)
* fix(work-orders): address wizard create review findings

[recover] remove malicious eslint payload (was 166c63e4)

* fix(work-orders): remove legacy completedDate EditWorkorder path

[recover] remove malicious eslint payload (was f4e6132b)

* fix(work-orders): use local calendar day for completedDate

Restore todayIso() after parent merge reintroduced UTC slice, and keep the wizard-date-utils regression test.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(work-orders): send wizard status and clear POC notes on site change

Map draft.status to lifecycleStatus on board create, and reset pocNotes with POC fields when the wizard site changes.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(query): scope broadcast channel per account and clear on auth

Isolate TanStack Query broadcast by userId, dispose and clear on
logout/401, and extract vendor filter drawers for governance.

* feat(work-orders): board wizard create with service notes

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(work-orders): enforce single-service wizard create per SH-118

Use single service selection in the wizard and omit extraServices from board create.

* fix(vendors): restore filter drawer labels for e2e and visual CI

Use VendorFilterOptions again and keep the Apply filters footer label expected
by vendor Playwright specs and the committed visual baseline.

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-14 11:52:48 -03:00
Alexandre Brandizzi
cc0df8f569 fix(vendors): complete shell and visual parity gates 2026-08-10 12:11:38 -03:00
Alexandre Brandizzi
fca5487f6d fix(vendors): enforce prototype visual geometry 2026-08-06 23:30:23 -03:00
Alexandre Brandizzi
ec203e1f5b fix(vendors): preserve the selected edit state 2026-08-06 22:39:11 -03:00
Alexandre Brandizzi
ff2e04b30e refactor(vendors): satisfy changed-file governance 2026-08-06 22:31:12 -03:00
Alexandre Brandizzi
b61d46ce4b fix(vendors): match prototype directory experience 2026-08-06 22:23:30 -03:00
Alexandre Brandizzi
ca7829036f
feat(vendors): add company roster workflows (SH-198) (#64)
Some checks failed
CI / ci (push) Has been cancelled
CI / governance (push) Has been cancelled
Deploy / deploy (push) Has been cancelled
* feat(vendors): support company roster workflows

* fix(vendors): address roster review feedback

* test(vendors): preserve draft on roster load failure

* fix(vendors): preserve current roster selection
2026-08-04 09:53:48 -03:00
Alexandre Brandizzi
4b88a60751
fix(vendors): remove preferred contact and fix trade ordering (#63)
Some checks are pending
CI / ci (push) Waiting to run
CI / governance (push) Waiting to run
Deploy / deploy (push) Waiting to run
* fix(vendors): address SH-180 and SH-182

* refactor(vendors): satisfy maintainability gates
2026-08-03 17:53:39 -03:00
Alexandre Brandizzi
bcf63dffad refactor(vendors): satisfy maintainability gates 2026-07-28 17:27:34 -03:00
Alexandre Brandizzi
95cbfff301 fix(vendors): allow sparse reactivation updates 2026-07-28 17:16:07 -03:00
Alexandre Brandizzi
45909e7aa6
Complete vendor operations roadmap frontend (#52)
* feat(vendors): complete operations roadmap frontend

* test(vendors): cover work order assignment flow

* fix(vendors): address review feedback

* fix(vendors): prevent stale preference saves

* fix(vendors): require truthful appointment bounds
2026-07-24 18:10:45 -03:00
Alexandre Brandizzi
4f99406388 chore(work-orders): merge origin/dev into pr39 integration branch
Integrate current origin/dev (vendor-core completion plus frontend
maintainability) into the work-order board shell branch.

Resolved semantic conflicts against the new frontend-maintainability
ESLint conventions introduced on dev: guard non-boolean && left
operands with Boolean()/!=null and replace raw <p> with the shared
Text component (media-upload-modal). PR #39 board shell/detail modules
and hooks preserved; merged vendor-core behavior and Text/ESLint
conventions preserved.
2026-07-24 13:45:16 -03:00
Alexandre Brandizzi
9a88f0583b
Merge pull request #51 from Sea-Haven-Industries/codex/frontend-maintainability
chore(frontend): enforce maintainable text rendering
2026-07-24 13:24:35 -03:00
Alexandre Brandizzi
392af77b91 refactor(ui): enforce maintainable conditional feedback 2026-07-24 11:32:58 -03:00
Alexandre Brandizzi
6ca45bc0ae fix(vendors): preserve phone data across edits 2026-07-23 19:17:14 -03:00
Alexandre Brandizzi
bbbb51aed5 feat(vendors): complete core vendor workflows 2026-07-23 17:36:21 -03:00
Alexandre Brandizzi
20237f8142
feat(vendors): align directory UI with current prototype (#46)
Some checks are pending
CI / ci (push) Waiting to run
Deploy / deploy (push) Waiting to run
* feat(vendors): align directory UI with prototype

* fix(vendors): report the filtered total

* fix(vendors): keep company input in sync

* fix(vendors): scope facets to directory status
2026-07-23 15:23:03 -03:00
Alexandre Brandizzi
c68d47af7b
chore: upgrade frontend dependencies (#24)
Some checks failed
CI / ci (push) Has been cancelled
Deploy / deploy (push) Has been cancelled
* chore: upgrade frontend application dependencies

* chore: upgrade frontend infrastructure dependencies

* fix: align lockfiles with CI npm

* fix: preserve ky error semantics

* fix: sanitize timeout error message
2026-07-14 21:35:59 -03:00
Arthur Bassi
a0cf7b9ef0
Feat/vite typescript migration (#16)
* chore: add eslint, prettier, husky and commitlint tooling

* ci: add GitHub Actions workflow for lint and build

* build: migrate from CRA to Vite with TypeScript config

* docs: add architecture plan and design system documentation

* fix: scope ESLint to new components and hooks directories

* feat: add HTTP client, query cache and shared utilities

* feat: add theme system and global application styles

* feat: add shared UI, layout and domain badge components

* feat: add auth domain, provider and login page

* feat: add app shell, file-based routing and bootstrap

* feat: add protected layout and dashboard module

* feat: add accounts CRUD module

* feat: add assets CRUD module

* feat: add contacts CRUD module

* feat: add employees CRUD module

* feat: add locations CRUD module

* feat: add calendar events module

* feat: add follow-ups CRUD module

* feat: add PM schedules CRUD module

* feat: add work orders module with dispatch modals

* feat: add vendors CRUD and portal token panel

* feat: add vendor purchase orders module

* feat: add uplifts queue module

* feat: add settings for dropdowns and task templates

* feat: add vendor portal routes and signature capture

* test: add Vitest setup and Playwright login e2e spec

* chore: remove legacy CRA pages, Redux store and JS hooks

* chore: update gitignore and env example for Vite

* docs: translate pt-BR docs and Cursor rules to English

* fix(ci): fix login e2e session mock and prettier formatting

* fix(build): use mjs router script for Node 20 CI compatibility

* chore: remove migration scripts and unused generouted router

* fix(auth): restore JWT and align CRUD with backend routes

* fix(api): add no-content helpers and align paths with backend

* fix(accounts): align detail and mutation payloads with backend

* fix(contacts): resolve detail via GetContacts and map address DTOs

* fix(work-orders): align routes, delete body, and create payload

* fix(vendors): delete vendors via REST route

* fix(pm-schedules): handle empty save and delete responses

* fix(employees): add fallbacks for detail and dropdown calls

* chore(calendar): disable routes until backend exists

* chore(env): switch tracked env vars to Vite prefixes

* fix(api): align frontend contracts with backend review findings

Correct Work Order getById query param, asset site options via Location API,
Employee JobTitleId payload, and remove stale API paths.

* fix(employees,pm-schedules): align forms with backend API contracts

Align PM Schedule form and save payload with PMSchedule_DTO fields.
Bind employee Job Title select to jobTitleId for create/update payloads.
Add regression tests for both flows.

* fix(pm-schedules): gate edit/delete for Dev API contract

Production Dev API exposes only GetList and Save.

Hide unsupported edit/delete UI and block the edit route.

Add regression tests for disabled actions.

* docs(env): document VITE_API_URL must include /api suffix

* refactor(api): extract shared API prefix URL resolution

* feat(build): fail build on misconfigured absolute VITE_API_URL

* test(api): cover API URL contract and prefix resolution

* feat(auth): disable login submit until email and password are valid

* test(auth): align login tests with disabled submit behavior

* Feat/ab/menu-and-header (#17)

* chore(deps): add lucide-react for layout icon migration

* feat(auth): add getPrimaryUserRole helper for header display

* style(theme): add sidebar active tokens and nav group typography

* refactor(menu): migrate nav icons to lucide and trim menu groups

* feat(layout): redesign sidebar, topbar, and admin shell viewport

* chore(menu): hide Reports and Documents from sidebar

---------

Co-authored-by: Arthur Bassi <arthur.winiarski.ranger@outlook.com>

* ci: add frontend PR quality baseline (#18)

* chore(deps): add lucide-react for layout icon migration

* feat(auth): add getPrimaryUserRole helper for header display

* style(theme): add sidebar active tokens and nav group typography

* refactor(menu): migrate nav icons to lucide and trim menu groups

* feat(layout): redesign sidebar, topbar, and admin shell viewport

* chore(menu): hide Reports and Documents from sidebar

* ci: add PR quality baseline checks

* ci: avoid self-matching standards guard

* ci: split frontend quality gates

---------

Co-authored-by: Arthur Bassi <arthur.winiarski.ranger@outlook.com>

---------

Co-authored-by: Arthur Bassi <arthur.winiarski.ranger@outlook.com>
Co-authored-by: Alexandre Brandizzi <alex_brandizzi@hotmail.com>
2026-06-18 14:41:17 -03:00