πŸ—Ί

Fleet Admin

Wassalon-kassa intern

{{ error }}

Alleen voor app-admins (Samuel + support)

πŸ”

Activeer MFA

Verplicht voor fleet-toegang

  1. Open een authenticator-app (Bitwarden, 1Password, Authy, Google Authenticator)
  2. Scan onderstaande QR-code Γ³f voer de secret handmatig in
  3. Typ de 6-cijfer-code uit de app
MFA QR-code
Handmatig in plaats van QR scannen
{{ mfa.secret }}

{{ mfa.error }}

⚠ Bewaar de secret in je password-manager als backup. Bij verlies van je authenticator-app kan een Supabase Dashboard-admin de factor verwijderen via Authentication β†’ Users β†’ jouw user β†’ MFA factors.

πŸ”

Voer MFA-code in

{{ session.user.email }}

Open je authenticator-app en typ de huidige 6-cijfer-code.

{{ mfa.error }}

πŸ—Ί

Fleet Admin

{{ session.user.email }}

⚠ Geen toegang

{{ authError }}

Controleer dat je auth.uid() in de app_admins-tabel staat: SELECT * FROM app_admins WHERE user_id = '{{ session.user.id }}';

Totaal kassa's

{{ stats.total }}

Online

{{ stats.online }}

Offline

{{ stats.offline }}

Wassalons

{{ stats.wassalons }}

πŸ“ {{ needsSetup.length }} wassalon{{ needsSetup.length !== 1 ? 's' : '' }} zonder geocoding

Voeg adres + lat/lon toe om ze op de kaart te zien. Klik "Bewerk" naast een wassalon om dat in te vullen.

  • {{ w.wassalon_name }}

πŸ“Š Dashboard πŸ‘₯ Users πŸͺ Wassalons πŸ–₯ Kassa's 🎟️ Enrollment-tokens πŸ” Admin

{{ filteredKassas.length }} resultaaten {{ filteredOwners.length }} resultaaten {{ filteredWassalons.length }} resultaaten

⚠️ {{ conflictKassas.length }} re-enroll-conflict{{ conflictKassas.length !== 1 ? 'en' : '' }} β€” actie nodig

Een verse Pi met dezelfde Pi-serial als een bestaande kassa probeert te enrollen. Om een datalek tussen klanten te voorkomen wordt nooit automatisch herlinkt. De kassa toont intussen "wacht op activatie" en de Pi probeert elke 5 min opnieuw. Beslis per geval:

  • Zelfde klant, defecte/vervangen Pi β†’ klik Relink (behoudt wassalon + config).
  • Pi-hergebruik (andere klant / afgehaakt) β†’ klik Verwijder oude kassa. De volgende enroll wordt dan een schone nieuwe kassa.
  • {{ k.kassa_name }} 🎟️ unclaimed 🏠 {{ k.wassalon_name }} Β· serial …{{ k.pi_serial.slice(-12) }} Β· Pi meldt zich als {{ k.reenroll_hostname }} Β· laatste poging {{ formatLastSeen(k.reenroll_last_at) }} βœ“ Relink goedgekeurd β€” kassa komt vanzelf online (max 5 min)

Net de oude kassa verwijderd maar de Pi blijft hangen? Controleer dat de auth-user ook weg is (Supabase Dashboard β†’ Authentication β†’ Users, …@kassa.internal).

πŸ”Œ {{ unlinkedKassas.length }} kassa{{ unlinkedKassas.length !== 1 ? "'s" : '' }} wacht{{ unlinkedKassas.length === 1 ? '' : 'en' }} op koppeling

Deze kassas zijn online (heartbeat ontvangen) maar nog niet aan een wassalon gekoppeld. Klik 'Link' om toe te wijzen β€” Pi pickt het op binnen seconden via Realtime (of binnen 30 min via volgende heartbeat als Realtime niet werkt).

  • {{ k.name }} 🎟️ unclaimed Β· serial …{{ k.pi_serial.slice(-12) }} Β· laatst gezien {{ formatLastSeen(k.last_seen) }}

πŸ“‹ {{ wassalonsWithoutKassas.length }} wassalon{{ wassalonsWithoutKassas.length !== 1 ? 's' : '' }} zonder kassa-Pi

Deze staan in de cloud maar hebben nog geen Pi met heartbeat. Voeg een kassa toe via scripts/onboard-kassa.sh om ze in de hoofdlijst te zien verschijnen.

  • {{ w.name }} Β· {{ w.address_city }} Β· eigenaar {{ ownerNameFor(w.owner_id) }}
⏳

Laden...

Geen kassas gevonden voor deze filter.

Kassa Wassalon Plaats Eigenaar Laatst gezien
{{ k.kassa_name }} 🎟️ unclaimed ⚠️ re-enroll-conflict ↻ relink goedgekeurd
{{ k.kassa_id.slice(0, 8) }}...
Pi: …{{ k.pi_serial.slice(-12) }}
{{ k.owner_full_name || k.owner_email }}
{{ k.owner_email }}
geen eigenaar
{{ formatLastSeen(k.last_seen) }}
nog nooit
Nog geen wassalons met lat/lon. Bewerk een wassalon en gebruik de Geocode-knop om adres β†’ coΓΆrdinaten te krijgen.
Alle kassa's online Deels online Alle offline Β© OpenStreetMap contributors

Geen wassalons aangemaakt. Klik "+ Nieuwe wassalon" om er één aan te maken.

Geen wassalons matchen de zoekterm.

Naam Plaats Eigenaar Kassas Geocoded Aangemaakt
{{ w.name }}
{{ w.address_line1 }}
{{ w.address_postal }} {{ w.address_city }}
{{ w.location }}
β€”
{{ w.country || '?' }} Β· {{ w.timezone || 'Europe/Brussels' }}
{{ ownerNameFor(w.owner_id) }}
geen eigenaar
{{ kassaCountForWassalon(w.id) }} βœ“ geen lat/lon {{ formatDate(w.created_at) }}
⏳

Users laden...

Geen users gevonden.

User Wassalons Kassa's Online Aangemaakt Laatste login
{{ displayName(o) }} admin
{{ o.email }}
geen naam ingevuld
{{ o.wassalons_owned }} + {{ o.wassalons_staff }} staff
{{ o.kassas_count }} β€” {{ o.online_kassas }}/{{ o.kassas_count }} {{ o.online_kassas }}/{{ o.kassas_count }} 0/{{ o.kassas_count }} {{ formatDate(o.created_at) }} {{ formatLastSeen(o.last_sign_in_at) }} nooit

πŸ” App-admins

Users die fleet-app toegang hebben β€” kunnen alle wassalons + kassas + eigenaars zien en beheren. Wees voorzichtig met wie je hier bij voegt.

⏳

App-admins laden...

Geen app-admins. (Dit kan eigenlijk niet β€” als je dit ziet ben je waarschijnlijk uitgelogd.)

Email Sinds Notes Laatste login
{{ displayName(a) }} jij
{{ a.email }}
{{ a.user_id.slice(0, 8) }}...
{{ formatDate(a.admin_since) }} {{ a.notes }} β€” {{ formatLastSeen(a.last_sign_in_at) }} nooit

🎟️ Enrollment-tokens β€” zero-touch kassa-onboarding

Tokens worden door install.sh op de Pi gebruikt om zichzelf bij Supabase te registreren. Geen service-key op de Pi nodig. Token-bron: pre-staged op SD-kaart (/boot/firmware/wassalon-enrollment.txt) of interactief getypt tijdens install.

Workflow: Genereer token β†’ kopieer plain-text (alleen nu zichtbaar) β†’ plak op SD-kaart of geef aan installateur β†’ Pi enrollt zichzelf β†’ kassa verschijnt als 'unclaimed' op het dashboard.

{{ filteredTokens.length }} tokens
⏳

Tokens laden...

Nog geen tokens. Klik + Genereer tokens om er aan te maken.

Geen tokens matchen dit filter.

Prefix Status Label Aangemaakt Vervalt Gebruikt door
{{ t.token_prefix }}… βœ“ gebruikt vervallen beschikbaar {{ t.label }} β€” {{ formatDate(t.created_at) }} {{ formatDate(t.expires_at) }}
{{ t.pi_hostname }}
…{{ t.pi_serial.slice(-12) }}
β€”