Skip to content
karim.semaan(open to work)
WorkExperienceAboutSkillsContactResume ↓
← All work
Excel Alchemy preview
Full-stackCompleted2025

Excel Alchemy

Payroll-file workflow front-end

Payroll run · upload to downloadSynthetic preview · no real data
  1. Upload
  2. →Company
  3. →Processing step
  4. →Validate
  5. →Download

Fabricated companies, file names and row counts (seeded, so the same clicks always replay the same run). The step counts, per-step accepted types and output naming mirror the real config.

0/7 steps

Press Process step 1 of 7 to advance the run: each click validates the staged file against the accepted types for that step and names the output.

  1. 1Employee updatesfmcg_co_employee_updates.xls · accepts .xlsx .xls .csvqueued
  2. 2Total variance reportfmcg_co_total_variance.csv · accepts .xlsx .xls .csvqueued
  3. 3Individual variance reportfmcg_co_individual_variance.xls · accepts .xlsx .xls .csvqueued
  4. 4Accrualsfmcg_co_accruals.xlsx · accepts .xlsx .xls .csvqueued
  5. 5GL reportfmcg_co_gl_report.xlsx · accepts .xlsx .xls .csvqueued
  6. 6Finance reportfmcg_co_finance_report.xls · accepts .xlsx .xls .csvqueued
  7. 7Bank payment filefmcg_co_bank_file.txt · accepts .txtqueued

Synthetic preview. No real payroll data: the companies, files and row counts are fabricated. What mirrors the audited front-end: seven steps for one client and six for the other, the bank-file step accepts only .txt while every other step takes .xlsx, .xls or .csv, a company change resets dependent selections, and outputs are named processed_<step>_<company>. The real transform runs server-side; this stepper replays the UI loop only.

Synthetic preview. Fabricated companies, files and row counts, no real payroll data. Step counts, per-step file-type rules and output naming mirror the real config.

Excel Alchemy is the operator front-end for an enterprise payroll-file workflow, built around the monthly runs of two multinational clients: an FMCG company and a pharmaceutical company (names anonymized). The config encodes each client's run as an ordered step list: employee updates, total and individual variance reports, accruals, GL and finance reports, and a bank payment file, seven steps for one client and six for the other. A React + TypeScript SPA (Vite, shadcn/ui, Radix, react-dropzone, TanStack Query) drives it as a strict upload, select, process, download loop: validation is per step (the bank-file step accepts only .txt, every other step takes .xlsx/.xls/.csv), dependent selections reset when the company changes, and outputs download as step-named files with the correct extension. What is genuinely real here: the repo's fixtures are actual payroll-run exports (data dumps, first- and second-run variance reports, accruals, GL and finance extracts, bank files) that the UI was designed against. The deterministic transformation runs server-side; the in-repo handler is a UI shell (the API call is simulated).

  • Vite
  • React
  • TypeScript
  • shadcn/ui
  • Radix UI
  • react-dropzone
  • TanStack Query
  • Tailwind CSS
Processing steps
7 (variance · accruals · GL · bank file)
Stack
Vite · React · shadcn/ui
Scope
Config front-end

What I'd improve

The gap to close is in this repo: the process handler simulates the API call (no /api/process-excel endpoint was ever built), so the front-end cannot be exercised end to end from source. Next: build and wire that endpoint, move the hardcoded per-company step config to a server-driven schema so onboarding a new client does not require a front-end deploy, and add fixture-driven tests asserting each step's accepted input types and output naming against the real payroll exports in the repo.

Request access
Want something like this? Get in touch →

Measured:30/30 chatbot evals·20-case Bastion eval·Serving·Calibration Lab

© 2026 Karim SemaanBuilt with Next.js, Tailwind & Supabase.LinkedIn ↗︎GitHub ↗︎