Back to Portfolio

Modular Systems Solutions

Dual-Purpose Business Web Application — Marketing site, bilingual worker timesheet portal, and full admin suite with PDF invoicing

Live at modularsystemsolutions.com
Visit Site
modularsystemsolutions.com
Modular Systems Solutions homepage screenshot

Overview

Modular Systems Solutions is a full-stack business application built for a field assembly and installation company. It serves three distinct audiences from a single codebase: the public (marketing site), field workers (timesheet portal), and management (admin suite).

Field workers — many of whom are Spanish-speaking — submit daily timesheets through a bilingual portal that auto-calculates regular and overtime hours, emails confirmations, and stores submissions to a relational database. Administrators review, edit, approve, and reject submissions through a full dashboard, then group approved work into invoices with PDF generation and SMTP email delivery. Every admin edit is logged as a full revision snapshot for a complete audit trail.

10
DB Tables
3
User-Facing Systems
EN / ES
Bilingual UI
Live
Status

Tech Stack

Built entirely without a framework — raw PHP, PDO, and Vanilla JS on shared hosting. Every dependency was chosen deliberately for reliability and ease of deployment.

PHP
Server Language
MySQL / PDO
Database (no ORM)
Vanilla JS
Frontend Logic
CSS3
Styling (no framework)
PHPMailer
SMTP Email (SSL port 465)
FPDF
Invoice PDF Generation
Session Auth
Role-Based Access Control
Apache / cPanel
Shared Hosting
Architecture Note

No framework, no build step, no package manager — just PHP files deployed via SCP. This was a deliberate constraint for the client's shared hosting environment and IT comfort level. The result is a fully functional, multi-user business application with zero external runtime dependencies.

Key Features

Three distinct systems built into a single, cohesive application.

Marketing Site

  • Public-facing portfolio, services, and testimonials
  • Contact form with backend validation and email delivery
  • Rate limiting to prevent abuse
  • Fully mobile-responsive across all breakpoints

Worker Timesheet Portal

  • Bilingual UI — English / Spanish, persisted via localStorage
  • Login-gated — workers only see their own portal
  • Dynamic hours table: add/remove rows, auto-calculate regular vs. OT hours
  • Datalist autocomplete from past approved submissions
  • Confirmation email to worker + admin notification on submit
  • Rate limiting per session

Admin Dashboard

  • Stat tiles: pending, approved, rejected submissions
  • Active workers, clients, invoices at a glance
  • Total billed and last invoice sent with direct link
  • Recent submissions table with status filtering
  • Mobile hamburger sidebar with overlay drawer

Submissions Management

  • Filter by status, worker, and free-text search
  • Admin can edit all fields — worker, date, hours, job site, PO, order
  • Every edit snapshots prior state to submission_revisions
  • Approve with client assignment; reject with notes
  • Un-approving auto-removes submission from any draft invoices

Invoice System

  • Create invoices from approved, uninvoiced submissions
  • Add/remove submissions to/from draft invoices
  • PDF generation via FPDF — company header, bill-to, line items, submission breakdown
  • Send PDF to client via PHPMailer SMTP
  • Full email send history with SMTP Message-ID logged per attempt
  • Payment tracking: Unpaid / Partial / Paid in Full

Auth, Workers & Clients

  • Session-based auth with two roles: worker and admin
  • Workers locked to timesheet only; admins access all admin pages
  • Create/activate/deactivate workers, reset passwords
  • Client records with structured address fields for invoice Bill-To
  • App settings: company info, invoice prefix, hourly rate, notification toggle

Technical Highlights

The engineering decisions that made this a non-trivial business application to build.

Bilingual UI Without a Framework

The timesheet portal serves both English and Spanish-speaking field workers. Language switching is handled entirely in Vanilla JS using a translation object keyed by element IDs — no i18n library, no server round-trip. The selected language persists in localStorage so workers don't have to re-select on each visit. Every visible string, label, placeholder, and error message has a translation entry.

PDF Invoice Generation & Email Delivery

Invoices are generated on the fly using FPDF — a pure-PHP PDF library with no external process dependencies. The PDF includes a company header, structured Bill-To block, period, line items (Regular Hours, OT Hours, Total Due), and a submission breakdown table with dates and job sites. Once generated, the PDF is attached and sent to the client via PHPMailer over SMTP SSL. Every send attempt is logged to invoice_email_log with the SMTP Message-ID, enabling support tracing for any delivery dispute.

Full Audit Trail via Revision Snapshots

Before any admin edit to a submission is saved, the current state is captured in full and written to submission_revisions. This means every version of a submission is recoverable — who changed what, and when. For a payroll-adjacent application where hours data has financial consequences, this audit trail is a hard requirement. The revision table stores the complete row state rather than a diff, keeping replay logic simple and reliable.

Post-Redirect-Get on Shared Hosting

All admin POST handlers follow the Post-Redirect-Get pattern to prevent duplicate form submissions on browser refresh. On shared cPanel hosting, this requires discipline: header() calls must happen before any output — including the shared header.php layout that starts the HTML immediately. Every admin POST handler validates, writes to the database, then issues a redirect before including any layout files.

Dynamic OT Calculation & Autocomplete

The timesheet's hours table is built entirely with Vanilla JS event delegation — rows are added and removed dynamically, and each row's regular vs. overtime split is calculated in real time as the worker types. Federal OT rules (over 40 hours/week) are enforced client-side with server-side validation on submit. The job site, supervisor, leadman, PO, and order fields use <datalist> autocomplete populated from the worker's past approved submissions — reducing data entry errors on repetitive job site work.

Mobile-First Admin Portal

The admin portal is fully usable on a phone — a requirement for management reviewing submissions in the field. A hamburger icon toggles a sidebar drawer with an overlay on screens 768px and below. Stat tiles collapse from a 4-column to a 2-column grid. Data tables scroll horizontally within cards rather than reflowing. Detail page side panels stack to a single column. All touch targets meet minimum size guidelines.

Challenges Solved

The hardest problems encountered during development, and how they were resolved.

Bilingual UI Without a Library

Supporting English and Spanish for field workers who may switch mid-session required translating every visible string dynamically. Building a lightweight translation system in Vanilla JS — keyed by element IDs, driven by a single translation object — avoided adding an i18n library to a no-dependency stack. The language preference is written to localStorage on toggle and applied on every page load, with no server involvement after the initial page render.

FPDF Layout Precision

FPDF gives you a blank canvas and a cursor — no layout engine, no auto-sizing. Building a professional invoice PDF required calculating every column width, line height, and page break manually. The submissions breakdown table needed to handle variable row counts without overflowing the page. Header and footer blocks needed consistent positioning regardless of how many line items appeared. The result is a clean, client-ready PDF indistinguishable from one produced by dedicated invoicing software.

Invoice State Integrity

Invoices are assembled from approved submissions. If an admin subsequently un-approves or rejects a submission, it must be automatically removed from any draft invoices that contain it — otherwise the invoice total would be wrong. The rejection handler queries for draft invoices containing the affected submission and removes the relationship in the same transaction. Sent invoices are deliberately left intact as a historical record.

Server JS Restrictions

The hosting environment enforces strict JS sandboxing: no eval(), no new Function(), no smart quotes, and no inline event handlers. All interactivity had to be wired through addEventListener() and event delegation on parent containers. The dynamic timesheet table — which adds, removes, and recalculates rows — was built entirely within these constraints using standard DOM APIs and delegated input events.

What This Project Demonstrates

Business Application Design
Multi-user system with distinct roles, workflows, and data relationships serving real operational needs
Relational Database Design
10-table schema with complex many-to-many relationships, audit logging, and transactional integrity
PDF Generation
Professional invoice PDFs built with FPDF — manual layout, dynamic content, and direct email attachment
Bilingual Internationalization
Full EN/ES translation system in Vanilla JS with localStorage persistence — no library required
Role-Based Access Control
Session auth with worker and admin roles, route guards, and strict separation of accessible features
Constraint-Driven Engineering
Full-featured app built within shared hosting limits — no CLI, no framework, no package manager

Need a Custom Business Application?

From internal tools to client-facing portals — we build practical software that fits your workflow.

Visit Site Get In Touch