CatalogEducation & public sector ›Schools & education

Campus — school office management

The school office that fits in a file: enrollments, certificate requests, office hours and circulars. Everything stays on your device.

📊 Dashboard👥 Enrollments🗂️ Requests📅 Office hours📣 Circulars

data space «campus-en» — the suite’s glue: on your device, multi-user with one invite (link or QR), end-to-end encrypted.

▶ Open the suite (5 micro apps)

or open it as a single app

schoolofficeenrollmentscertificatesregistrycircularsappointments

What it records

  • Student full name
  • Class and section (e.g. 2B)
  • Family contact (email or phone)
  • Notes (exemptions, missing documents...)
  • Applicant (family, student, institution)
  • Request type...
  • Status...
  • Notes (missing documents, urgency...)
  • Time (e.g. 10:30)
  • Who is coming (family, teacher, supplier...)
  • Reason for the appointment
  • Number (e.g. 42/2026)
  • Subject of the circular
  • Audience...
  • Text of the circular

Composed of 5 micro apps

One job each, over the same data: every micro app reads and writes the shared data space “campus-en” (with your consent, asked on first open). Everything stays on your device — and with a single invite the whole suite goes multi-user, end-to-end encrypted.

How it works

This is a Reactive app: a plain text document that your browser turns into a working app — forms, live data, tables, statistics and even charts, with nothing to install or configure.

  1. Use it right away. Hit “Use this app”: it opens right in your browser, ready to go, with data saved only on your device.
  2. Your data stays yours. Everything is stored locally on your device, kept separate for each app: no account, no server, nothing to set up.
  3. Make it your own. The text below is the entire app: copy it, tweak fields, views and words, and your changes become interactive instantly.
  4. Share it as a file. An app is a simple file: save it, export it or share it with a link; and with encrypted collaboration several people edit the same data in real time.
The app’s source
# 🎓 Campus

The school office that fits in a file: enrollments, certificate requests, office hours and circulars. Everything stays on your device.

:::::page{title="Dashboard" icon="📊"}
## The office at a glance

:::grid{cols="3"}
**Enrolled students**

:count[nenr]{path="enrollments"}

---

**Open requests**

:count[nreq]{path="requests"}

---

**Circulars issued**

:count[ncir]{path="circulars"}
:::

## Requests by status

::::if-empty{path="requests"}
*No requests yet: log the first one from the Requests page.*
::::

:::group-by{path="requests" field="status" as="list"}
**{kind}** — {applicant} · {date}
:::
:::::

:::::page{title="Enrollments" icon="👥"}
## Student records

::::form{path="enrollments" id="fenr"}
::input{form="fenr" field="name" placeholder="Student full name" required="true"}
::input{form="fenr" field="class" placeholder="Class and section (e.g. 2B)"}
::input{form="fenr" field="enrolled" type="date" legend="Enrollment date"}
::input{form="fenr" field="contact" placeholder="Family contact (email or phone)"}
::input{form="fenr" field="notes" placeholder="Notes (exemptions, missing documents...)"}
::add-form{form="fenr" path="enrollments" label="Register enrollment"}
::::

:::table{path="enrollments" headers="Student,Class,Enrolled on,Family contact,Notes" deletable="true" editform="fenr"}
**{name}** | {class} | {enrolled} | {contact} | {notes}
:::

## By class

:::group-by{path="enrollments" field="class" as="list"}
**{name}** — {contact}
:::
:::::

:::::page{title="Requests" icon="🗂️"}
## Certificate and paperwork registry

::::form{path="requests" id="freq"}
::input{form="freq" field="date" type="date" required="true" legend="Received on"}
::input{form="freq" field="applicant" placeholder="Applicant (family, student, institution)" required="true"}
:::select{form="freq" field="kind" placeholder="Request type..."}
- Enrollment certificate
- Attendance certificate
- Transfer clearance
- Diploma copy
- Other
:::
:::select{form="freq" field="status" placeholder="Status..."}
- Received
- In progress
- Ready for pickup
- Delivered
:::
::input{form="freq" field="notes" placeholder="Notes (missing documents, urgency...)"}
::add-form{form="freq" path="requests" label="Log request"}
::::

:::table{path="requests" headers="Received,Applicant,Type,Status,Notes" deletable="true" editform="freq"}
{date} | **{applicant}** | {kind} | {status} | {notes}
:::
:::::

:::::page{title="Office hours" icon="📅"}
## Appointments at the office

::::form{path="appointments" id="fapp"}
::input{form="fapp" field="date" type="date" required="true" legend="Day"}
::input{form="fapp" field="time" placeholder="Time (e.g. 10:30)" required="true"}
::input{form="fapp" field="person" placeholder="Who is coming (family, teacher, supplier...)" required="true"}
::input{form="fapp" field="reason" placeholder="Reason for the appointment"}
::add-form{form="fapp" path="appointments" label="Book appointment"}
::::

:::calendar{path="appointments" field="date"}
{time} {person} · {reason}
:::
:::::

:::::page{title="Circulars" icon="📣"}
## School communications

::::form{path="circulars" id="fcir"}
::input{form="fcir" field="number" placeholder="Number (e.g. 42/2026)" required="true"}
::input{form="fcir" field="date" type="date" required="true" legend="Date"}
::input{form="fcir" field="title" placeholder="Subject of the circular" required="true"}
:::select{form="fcir" field="audience" placeholder="Audience..."}
- Families
- Teachers
- Staff
- Everyone
:::
::input{form="fcir" field="text" placeholder="Text of the circular"}
::add-form{form="fcir" path="circulars" label="Issue circular"}
::::

::::card{id="board" title="Circular register"}
:::sort{path="circulars" field="date" order="desc" as="list" deletable="true"}
**no. {number}** of {date} — **{title}** ({audience}): {text}
:::
::::

::print{target="board" label="Print / PDF for the board"}
:::::