Catalog ›Companies & SMBs ›Operations
Relay — shifts and attendance
The team's shifts on a calendar, hours always counted. For bars, shops and small teams.
👥 Team📅 Shifts⏱️ Hours
data space «relay-en» — the suite’s glue: on your device, multi-user with one invite (link or QR), end-to-end encrypted.
What it records
- Full name
- Role (counter, floor, warehouse...)
- Time slot...
- Hours
Composed of 3 micro apps
One job each, over the same data: every micro app reads and writes the shared data space “relay-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
# 🔄 Relay
The team's shifts on a calendar, hours always counted. For bars, shops and small teams.
:::::page{title="Team" icon="👥"}
## The people
::::form{path="team" id="fsq"}
::input{form="fsq" field="name" placeholder="Full name" required="true"}
::input{form="fsq" field="role" placeholder="Role (counter, floor, warehouse...)"}
::add-form{form="fsq" path="team" label="Add person"}
::::
:::list{path="team" deletable="true"}
**{name}** — {role}
:::
:::::
:::::page{title="Shifts" icon="📅"}
## Planning on the calendar
::::form{path="shifts" id="ftu"}
::input{form="ftu" field="date" type="date" required="true" legend="Day"}
::select-from{from="team" form="ftu" field="employee" label="name" value="name"}
:::select{form="ftu" field="slot" placeholder="Time slot..."}
- Morning
- Afternoon
- Evening
- Night
:::
::input{form="ftu" field="hours" type="number" placeholder="Hours" required="true"}
::add-form{form="ftu" path="shifts" label="Assign shift"}
::::
:::calendar{path="shifts" field="date"}
{slot}: {employee}
:::
:::::
:::::page{title="Hours" icon="⏱️"}
## The hours tally
Total planned hours: **:sum[oretot]{path="shifts" field="hours"}**
## Per person
:::group-by{path="shifts" field="employee" as="table" headers="Day,Slot,Hours"}
{date} | {slot} | {hours}
:::
> Tip: from the shifts table (Shifts page) you can export the CSV for your
> payroll accountant with the export button.
:::table{path="shifts" headers="Day,Person,Slot,Hours" deletable="true" editform="ftu"}
{date} | {employee} | {slot} | {hours}
:::
:::::