Datebook — client diary and appointments
Your practice's appointments on a calendar, with clients and takings at your fingertips.
data space «studio-pro-en» — the suite’s glue: on your device, multi-user with one invite (link or QR), end-to-end encrypted.
▶ Open the suite (3 micro apps)
Integrates with: Hourglass — same data space.
What it records
- Time (e.g. 15:30)
- Service / reason
- Amount (€)
- Full name
- Phone
- Notes (preferences, history...)
Composed of 3 micro apps
One job each, over the same data: every micro app reads and writes the shared data space “studio-pro-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.
Shared micro apps are the bridge between solutions: the same data also powers Hourglass.
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
# 📅 Datebook
Your practice's appointments on a calendar, with clients and takings at your fingertips.
:::::page{title="Diary" icon="📅"}
## The month at a glance
::::form{path="appointments" id="fap"}
::input{form="fap" field="date" type="date" required="true" legend="Day"}
::input{form="fap" field="time" placeholder="Time (e.g. 15:30)" required="true"}
::select-from{from="clients" form="fap" field="client" label="name" value="name"}
::input{form="fap" field="service" placeholder="Service / reason"}
::input{form="fap" field="amount" type="number" placeholder="Amount (€)"}
::add-form{form="fap" path="appointments" label="Book appointment"}
::::
:::calendar{path="appointments" field="date"}
{time} {client}
:::
:::::
:::::page{title="Clients" icon="👥"}
## Directory
::::form{path="clients" id="fcl"}
::input{form="fcl" field="name" placeholder="Full name" required="true"}
::input{form="fcl" field="phone" placeholder="Phone"}
::input{form="fcl" field="notes" placeholder="Notes (preferences, history...)"}
::add-form{form="fcl" path="clients" label="Add client"}
::::
:::table{path="clients" headers="Client,Phone,Notes" deletable="true" editform="fcl"}
**{name}** | {phone} | {notes}
:::
:::::
:::::page{title="History and takings" icon="💶"}
## All appointments
:::sort{path="appointments" field="date" order="desc" as="table" headers="Day,Time,Client,Service,Amount" deletable="true"}
{date} | {time} | {client} | {service} | € {amount}
:::
**Appointments:** :count[nap]{path="appointments"} —
**Collected/expected: € :sum[inc]{path="appointments" field="amount"}**
## Per client
:::group-by{path="appointments" field="client" as="list"}
{date} {time} — {service} (€ {amount})
:::
:::::