Skip to content

Experience · Frontend · Active

cs-portal frontend

React and Vite frontend for CS Portal, rendering HR, operations, administration, documents and lookup workflows through same-origin APIs.

  • React 18
  • Vite
  • TypeScript
  • Tailwind
  • react-router-dom
  • reactflow
  • xlsx

Spec sheet

Repository path

cs-portal/frontend

Runtime

React 18 + Vite

Public host

http://portal.cs.lvh.me:8080

Frontend rule

No direct Salesforce or Core calls

Responsibilities

  • Render the portal application shell and domain pages for HR, operations and administration.
  • Render the economic forecast workbench with month selection, manual line editing, calculated totals, read-only costs and margins, virtual projection, clone flow and guarded month deletion.
  • Consume only the cs-portal BFF through same-origin /api calls.
  • Use structured lookup client helpers instead of composing raw Salesforce queries in the browser.
  • Keep heavy route logic in runtime modules with small route-level wrappers.

Interfaces and contract surface

  • GET / via portal host
  • /administration/forecast-economico
  • Same-origin /api
  • Vite dev server on 5177

Consumers

  • Internal Codestorm operators via browser

Dependencies and external touchpoints

Notes

  • The economic forecast page is under the Administration navigation and is also visible to Portal HR as a single protected item.
  • Economic forecast displays economics cards, cost/margin trend lines, collapsible line filters, per-line personnel cost source and cost-detail breakdown from BFF-enriched data; line weight scales both revenue and personnel cost.
  • Economic forecast projection is frontend-only and uses previous monthly details normalized by monthly billable working days, including January, August and December non-billable stop days, to show virtual rows without creating or saving Salesforce records; projected personnel cost stays on the historical monthly average and is not reduced by those caps.
  • Recent commits moved many large pages into *.runtime.tsx modules and left wrapper exports in the original files.

Source references

  • cs-portal/frontend/package.json
  • cs-portal/frontend/src/services/lookups.ts
  • cs-portal/frontend/src/services/administration-prebilling.ts
  • cs-portal/frontend/src/features/prebilling
  • cs-portal/frontend/src/pages

Header, sidebar e menu mobile consumano la stessa struttura app/categoria/scheda del BFF. Le categorie sono entita' esplicite, quindi il loro nome e la loro descrizione compaiono in modo coerente nei menu. La ricerca confronta testo normalizzato di app, categoria e scheda su label, descrizione e keyword; un risultato rapido mostra il breadcrumb App · Categoria e una ricerca sulla categoria rende disponibili le relative schede.

Gestione credenziali integrazione ​

/#/settings/integrations è disponibile a ogni utente autenticato e chiama soltanto le API same-origin del BFF. Il modulo separa client API, hook di stato, lista e modali per PAT personali e service account; creazione e rotazione mostrano il secret una sola volta, mentre rotazione e revoca richiedono conferma. Il frontend non esegue il token exchange e non persiste secret, client secret o token in URL, storage o cookie. Durante l'impersonazione le mutazioni restano disabilitate.

Feature HR e amministrazione ​

  • La pagina consuntivi dipendente mantiene moduli distinti per ferie/permessi e smart working. Tra invio e inizio deve trascorrere almeno un'intera giornata lavorativa, conteggiata dal BFF e dal frontend; per iniziare martedì la richiesta va inviata entro venerdì. In caso di blocco mostra una modal informativa con l'invito a contattare HR per le urgenze. “Torna alla richiesta” conserva i dati inseriti; la malattia sulla commessa MA è esente.
  • La gestione pagamenti Qonto e una pagina HR dedicata in /hr/qonto-payments, raggiungibile dal riepilogo costi e dalla categoria Costi del personale. La feature frontend/src/features/qonto-payments separa stato URL (month, status, resource), hook dati, filtri, tabella e azioni bulk. I tab “Da pagare” e “Pagamenti effettuati” mostrano una lista per volta; il rollback conserva una conferma esplicita, mentre la precedente modale di gestione non esiste piu'. Il browser chiama solo endpoint same-origin del BFF.
  • /hr/import-costi riconcilia i netti PDF con il CSV tramite codice dipendente normalizzato e mese letto dal PDF. Se il CF non e' nel PDF, la feature lo usa dal CSV soltanto quando quel binomio risolve un solo CF valido; non usa il nome e mantiene esplicitamente in errore codici assenti, ambigui, di un altro mese o con CF discordante.
  • /hr/chiudi-mese e una pagina HR distinta dall'import costi: il periodo non ha un valore predefinito, la preview mostra solo conteggi e l'azione richiede una conferma modale con digitazione di YYYY-MM. Service, componenti preview e modal restano separati; il browser usa soltanto /api/hr/month-close/* same-origin e rende esplicito il rifiuto di una preview non piu' valida.
  • La pagina /administration/commesse e una vista separata da /administration/projects-status: filtra per anno, mese (oppure tutti i mesi) e Account obbligatorio. Finché l'Account non è selezionato non carica né mostra tabella e riepilogo; la selezione limita il perimetro delle righe contabili normalizzate e la testata può selezionare tutte le righe correnti. La CTA Confronta foglio guida i passi Righe → Tab → Esito e richiede la scelta esplicita del tab. L'esito rende prima visibili Già allineate, Aggiornamenti suggeriti, Da aggiungere al foglio e Da verificare, poi i gruppi dettagliati. Un possibile match è strettamente uno-a-uno su riferimento stabile e mostra i campi discordanti. Per PORTAL_ADMIN, PORTAL_AMMINISTRAZIONE e PORTAL_HR la modale consente selezione esplicita di update/create oppure di N coppie manuali indipendenti in cui ogni riga Portale scelta sovrascrive nella stessa posizione la propria riga Foglio scelta; preview, fingerprint e conferma testuale precedono la scrittura. Dopo l'execute, il BFF restituisce la snapshot verificata post-scrittura e la modale aggiorna insieme righe, gruppi e contatori. Il browser invia solo filtri, ID e chiavi verso endpoint same-origin; non riceve credenziali né chiama Google direttamente.
  • Le righe fattura di Commesse aggiungono il testo Invoice__c.Subject__c al titolo FATTURA #<numero>/<anno> senza dedurre una risorsa dalla commessa. Se il foglio conserva il formato storico privo del Subject, la coppia univoca con stesso riferimento stabile, competenza, tipo, stato e importi resta un Possibile match aggiornabile e non entra nei Disallineati.
  • Nella modale Commesse i tre esiti principali sono tab esclusivi, con conteggio e apertura prioritaria dell'esito che richiede azione: prima Aggiornamenti suggeriti, poi Disallineati, altrimenti Già allineate. Dentro Disallineati, i sottotab Da aggiungere e Da verificare permettono di consultare entrambi i lati, con filtro Portale per Fatture, Costi e, quando presenti, Fee. Da aggiungere resta l'avvio se contiene righe; se sono presenti solo righe Foglio, la modale apre direttamente Da verificare evitando una vista vuota. Senza riga Portale selezionata, la lista Foglio resta consultabile ma Usa come riga foglio non è utilizzabile. La scelta manuale Usa dal portale fissa la sorgente e abilita i soli target Foglio disponibili; Usa come riga foglio registra una coppia 1:1 nel riepilogo e riporta alla sorgente Portale. Si possono selezionare N coppie: ogni sorgente e target è evidenziato, ogni target Foglio già usato non è più selezionabile e Cambia coppia riapre esclusivamente la coppia scelta. Le azioni massive esplicite possono selezionare o deselezionare solo i possible_match aggiornabili oppure i portal_only creabili; non coinvolgono allineamenti manuali né scrivono il foglio senza anteprima e conferma.
  • /hr/jobs e il punto d'ingresso recruiting: lista, form metadata-driven riusati per create/edit e workspace con requisiti, CV in lavorazione e candidature. Componenti distinti gestiscono header, liste paginate, filtri della pagina corrente e form Job Member; nessuna cancellazione fisica e nessun avanzamento automatico della pipeline.
  • /hr/talent-pool riusa la lista Curriculum con vista unassigned bloccata e azione visibile “Assegna a Job”. /hr/curricula apre la review e conserva viste profili/errori/storico; non registra Curriculum__c nel CRUD entity generico. Su mobile le liste usano card.
  • Il provider bulk vive nel layout autenticato e orchestra 1–50 PDF con massimo tre upload concorrenti, preview e Job comune, stati per file, retry manuale e riepilogo. La navigazione interna non interrompe la coda, mentre refresh/chiusura comportano la perdita dei file non ancora inviati, dichiarata esplicitamente. Nessun file o dato candidato e persistito nel browser.
  • /hr/curricula/:curriculumId compone header, documento sorgente, risoluzione Contact, merge campo-per-campo, posizione, sezioni CV e storico. Il registry delle sezioni e selezionato per schemaVersion; una versione non supportata produce un errore esplicito senza layout di fallback.
  • Hook separati possiedono query, polling, lookup e mutation. Cambiare Contact o scegliere CREATE ricarica dal BFF diff e revisione completi prima di abilitare approve. Le decisioni di merge restano nello stato React quando approve/reject falliscono o restituiscono 409, mentre i componenti di presentazione non eseguono fetch. Un Curriculum APPROVED con storage FAILED o FINALIZE_PENDING espone il retry della sola archiviazione.
  • La scheda “Compatibilita Job” distingue score 0–100, fascia, match/gap/evidenze, versione e risultato obsoleto dalla “Confidenza estrazione” percentuale. La review usa il Job contestuale del link; dopo l'approvazione il pannello candidature permette associazioni a piu Job senza ricreare Contact. Tutte le chiamate passano dal BFF same-origin, con errori 403, 404, 409 e retry espliciti.

HR lifecycle ​

La feature hr-lifecycle compone pannello Rapporto con l'azienda, wizard anagrafica/ responsabile BU/contratto/anteprima, offboarding con selezione esplicita e stato operazione/email. L’onboarding richiede la selezione di un referente attivo o la dichiarazione esplicita che la persona è responsabile di una BU. Le route sono centralizzate; l'estensione del dettaglio Contact passa da un registry, senza inserire dominio HR nel renderer CRUD generico. Gli hook possiedono fetch e mutation; i componenti usano i metadata del BFF e chiamano soltanto /api/*.

La navigazione o approvazione CV non esegue onboarding. Soltanto Conferma onboarding invia execute. Il retry incerto riusa la chiave originale e blocca modifiche dei dati. Le liste preservano selezioni nascoste dai filtri e selezionano tutti solo sui record visibili ammessi; un contratto futuro non puo essere chiuso prima dell'inizio. I vecchi link pubblici mostrano la dismissione e non caricano dati personali.

Task tracking ​

/tasks, /tasks/new e /tasks/:boardId sono route autenticate senza allowlist ACL specifica. La pagina lista usa ricerca server-side, ordinamento e paginazione delle board; la creazione mantiene i dati digitati quando l'API fallisce. Il dettaglio compone Kanban responsive e tabella paginata, filtri, editor task, gestione colonne e condivisione con batch sequenziali fino a 100 Contact. Owner/Editor/Viewer controllano le azioni mostrate, mentre il BFF rivalida sempre la policy.

Il client è isolato in frontend/src/features/task-tracking: servizio e tipi API, route page, vista Kanban/tabella, editor, manager colonne e dialog membri sono componenti separati. Il browser usa esclusivamente /api/task-boards/*; i nomi Contact sono risolti dal BFF e un errore Salesforce lascia visibili i task con un'azione esplicita di retry. Kanban permette drag desktop e comandi di spostamento accessibili, mentre su mobile mostra una colonna per volta. La preferenza Kanban/tabella resta in localStorage con chiave per Contact e dispositivo. Le card urgenti sono evidenziate e ordinate prima delle normali in ciascuna colonna; il riordino manuale resta interno al gruppo. Kanban e tabella mostrano stati testuali per task scaduti e in scadenza, calcolati sulla data Portal Europe/Rome (oggi e i due giorni successivi).

Workspace reference: /Users/jeanpaul/projects/cs-repository