Skip to content
Completed2026//Case study

OPR Generator

A zero-dependency, offline-first web app that turns program details and photos into a print-ready one-page report for SK Kubang Gajah.

  • HTML
  • CSS
  • JavaScript
  • Print / PDF
  • Offline-first

Problem

Malaysian schools file a One Page Report (OPR) — Laporan Pelaksanaan Program/Aktiviti — after each program or activity. Assembling one by hand in a word processor is fiddly: getting the layout to fit a single A4 page, placing photos at a consistent size, and keeping every report looking the same across staff.

SK Kubang Gajah needed a faster, repeatable way to produce these reports that anyone on staff could use without training or special software.

Approach

The tool is deliberately small: pure HTML, CSS, and JavaScript with no framework and no backend. A teacher fills in a short guided form, drops in photos, and gets a clean A4 report they can print or save as PDF.

Keeping it dependency-free means it runs straight from the browser — it can even be opened from a local file — so there is nothing to deploy, host, or maintain for it to keep working.

Architecture

The code is split by responsibility rather than bundled together:

  • form.js — the 3-step wizard (details, content, photos): stepper logic, input handling, and validation.
  • photos.js — drag-and-drop upload of up to three images, with 1:1 thumbnail previews.
  • render.js — builds the report DOM from the entered data.
  • print.js — opens the print window tuned for a single A4 page.
  • css/tokens.css — the design tokens (the "Sapphire & Slate" system) that keep every report visually consistent.
  • print.css — a separate print stylesheet so the on-screen editor and the printed page can diverge where they need to.

Implementation

The input is a three-step wizard so a user is never shown the whole form at once — just information, then content, then photos. Images are added by drag-and-drop and previewed as square thumbnails so the final layout is predictable before printing.

A logo presented a real offline constraint: loading it from a file would trip browser security (CORS) when the app runs from file://. The fix was to inline the school logo as a Base64 string, so it always renders in the printed PDF without depending on a server or external file.

Outcome

The result is a single-purpose tool that produces a consistent, print-ready A4 OPR from a short form and a few photos — no installation, no account, and no internet connection required. It is deployed on the web for convenience but works identically offline.

Lessons Learned

Constraints clarified the design. "No framework, must work offline" ruled out the usual conveniences and forced direct solutions — splitting the JavaScript by job, separating the print stylesheet, and inlining the logo as Base64. For a tool with one clear task and non-technical users, the smaller surface is the feature: nothing to break, nothing to update, nothing to learn.