Catalog ›Education & public sector ›Government offices
Townhall — municipal management
The municipal management app that fits in a file: registry, citizen reports, official acts and front desk. Everything stays on your device.
📊 Dashboard🗂️ Registry🚧 Reports📜 Acts📅 Front desk🗺️ Territory
data space «townhall-en» — the suite’s glue: on your device, multi-user with one invite (link or QR), end-to-end encrypted.
What it records
- Subject of the case
- Citizen / applicant
- Office...
- Status...
- Notes (missing documents, contact person...)
- What's wrong (pothole, streetlight, litter...)
- Where (street, square, district)
- Type...
- Status...
- Number (e.g. 42/2026)
- Type of act...
- Subject of the act
- Office / responsible
- Time (e.g. 10:30)
- Citizen
- Office...
- Reason for the appointment
- Municipality (e.g. Roma)
Composed of 6 micro apps
One job each, over the same data: every micro app reads and writes the shared data space “townhall-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.
- Use it right away. Hit “Use this app”: it opens right in your browser, ready to go, with data saved only on your device.
- Your data stays yours. Everything is stored locally on your device, kept separate for each app: no account, no server, nothing to set up.
- Make it your own. The text below is the entire app: copy it, tweak fields, views and words, and your changes become interactive instantly.
- 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
# 🏛️ Townhall
The municipal management app that fits in a file: registry, citizen reports, official acts and front desk. Everything stays on your device.
:::::page{title="Dashboard" icon="📊"}
## The town hall at a glance
:::grid{cols="3"}
**Cases logged**
:count[ncas]{path="cases"}
---
**Citizen reports**
:count[nrep]{path="reports"}
---
**Acts published**
:count[nact]{path="acts"}
:::
## Cases by status
::::if-empty{path="cases"}
*No cases yet: log the first one from the Registry page.*
::::
:::group-by{path="cases" field="status" as="list"}
**{subject}** — {applicant} · {office}
:::
:::::
:::::page{title="Registry" icon="🗂️"}
## Case register
::::form{path="cases" id="fcas"}
::input{form="fcas" field="date" type="date" required="true" legend="Received on"}
::input{form="fcas" field="subject" placeholder="Subject of the case" required="true"}
::input{form="fcas" field="applicant" placeholder="Citizen / applicant" required="true"}
:::select{form="fcas" field="office" placeholder="Office..."}
- Registry office
- Taxes
- Technical
- Social services
- Local police
- Other
:::
:::select{form="fcas" field="status" placeholder="Status..."}
- Received
- In progress
- On hold
- Closed
:::
::input{form="fcas" field="notes" placeholder="Notes (missing documents, contact person...)"}
::add-form{form="fcas" path="cases" label="Log case"}
::::
:::table{path="cases" headers="Received,Subject,Applicant,Office,Status" deletable="true" editform="fcas"}
{date} | **{subject}** | {applicant} | {office} | {status}
:::
## By office
:::group-by{path="cases" field="office" as="list"}
{date} — **{subject}** ({applicant}) · {status}
:::
:::::
:::::page{title="Reports" icon="🚧"}
## From citizens to the work crew
::::form{path="reports" id="frep"}
::input{form="frep" field="date" type="date" required="true" legend="Reported on"}
::input{form="frep" field="subject" placeholder="What's wrong (pothole, streetlight, litter...)" required="true"}
::input{form="frep" field="place" placeholder="Where (street, square, district)" required="true"}
:::select{form="frep" field="kind" placeholder="Type..."}
- Roads
- Lighting
- Public green
- Waste
- Other
:::
:::select{form="frep" field="status" placeholder="Status..."}
- Open
- In progress
- Resolved
:::
::add-form{form="frep" path="reports" label="Record report"}
::::
:::table{path="reports" headers="Reported,Subject,Where,Type,Status" deletable="true" editform="frep"}
{date} | **{subject}** | {place} | {kind} | {status}
:::
## By status
:::group-by{path="reports" field="status" as="list"}
{date} — **{subject}** ({place}) · {kind}
:::
:::::
:::::page{title="Acts" icon="📜"}
## Resolutions, decrees and ordinances
::::form{path="acts" id="fact"}
::input{form="fact" field="number" placeholder="Number (e.g. 42/2026)" required="true"}
::input{form="fact" field="date" type="date" required="true" legend="Date"}
:::select{form="fact" field="kind" placeholder="Type of act..."}
- Board resolution
- Council resolution
- Executive decree
- Ordinance
:::
::input{form="fact" field="subject" placeholder="Subject of the act" required="true"}
::input{form="fact" field="office" placeholder="Office / responsible"}
::add-form{form="fact" path="acts" label="Register act"}
::::
::::card{id="board" title="Public notice board"}
:::sort{path="acts" field="date" order="desc" as="list" deletable="true"}
**{kind} no. {number}** of {date} — {subject} ({office})
:::
::::
::print{target="board" label="Print / PDF for the board"}
:::::
:::::page{title="Front desk" icon="📅"}
## Appointments with citizens
::::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="citizen" placeholder="Citizen" required="true"}
:::select{form="fapp" field="office" placeholder="Office..."}
- Registry office
- Taxes
- Technical
- Social services
- Local police
- Other
:::
::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} {citizen} · {office}
:::
:::::
:::::page{title="Territory" icon="🗺️"}
## Official territorial references (open data)
The codes an office needs every day, straight from official open data:
Italian municipalities with their ISTAT code and plate code, always at hand.
::input[od_cityq]{placeholder="Municipality (e.g. Roma)"}
::od-query{into="od_territory" sql="SELECT LABEL_COMUNE_IT AS city, SIGLA_AUTOMOBILISTICA AS plate, CODICE_COMUNE AS code, CODICE_PROVINCIA AS province FROM voc_istat_cities WHERE DATA_FINE_VALIDITA = '31-12-9999' AND LABEL_COMUNE_IT LIKE '%' || UPPER('{#od_cityq}') || '%' ORDER BY city" limit="20"}
:::table{path="od_territory" headers="Municipality,Plate,ISTAT code,Province code" search="false" pagesize="5"}
{city} | {plate} | {code} | {province}
:::
## Find more public datasets
Describe the data you need in plain words (e.g. "classification of
professions") and discover the official datasets available, each with a
ready-to-copy query.
::od-search{}
:::::