9:30●●●● 🔋
Training session setup
Training name
Sport type
Fitness
Location
TNT Studio
Training type
Personal
Group
Max participants
10 athletes
Min participants (optional)
3 athletes
If not met, you'll be notified 24h before to cancel or proceed.
Duration
Hour
0
1
2
Minutes
0
15
30
Price per participant
Schedule
Recurring
One-off
Days
M
T
W
T
F
S
S
Start time
18:00
Payment method
Cash
Card
Select date
April 2026
M T W T F S S 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
Select time
1h session · available slots
08:00 2/4
08:00
08:15
08:30
08:45
10:00
10:00
10:15
10:30
10:45
12:00 Busy · Basketball Training
13:00 Busy · Yoga Flow
14:00 2/4
14:00
14:15
14:30
14:45
16:00 3/4
16:00
16:15
16:30
16:45
18:00
18:00
18:15
18:30
18:45
20:00
20:00
20:15
20:30
20:45
Please fill in required fields
Time slot reset — duration changed
Apply changes
Location and time were changed
23 participants across affected events will be notified about the changes.
9:30●●●● 🔋
My training sessions
Basketball Training
1h · cash/card
€50
TNT Studio Personal
HIIT Group Session
Tue & Thu, 18:00 · 1h
€25
/person
TNT Studio Group · max 10
Yoga Morning Flow
Mon & Wed, 08:00 · 1h 30m
€15
/person
GYM Bro Group · max 15
No training sessions yet
Create your first training session —
a reusable template with duration, price, and location.
9:30●●●● 🔋
Edit training session
Training name
HIIT Group Session
Sport type
Fitness
Location
GYM Bro
Training type
Personal
Group
Max participants
10 athletes
Min participants (optional)
3 athletes
Duration
Hour
0
1
2
Minutes
0
00
30
Price per participant
25
Schedule
Recurring
One-off
Days
M
T
W
T
F
S
S
Start time
18:00
Payment method
Cash
Card
Apply changes
Location was changed
Only future generated events will have the new settings.
Delete "HIIT Group Session"?
This will stop generating new sessions. You currently have 12 upcoming events with 47 total registrations.
New events will stop being generated. Existing 12 events will continue as scheduled.
9:30●●●● 🔋
Training locations
In-person
GYM Bro Default
Shota Rustaveli Ave, Tbilisi, Georgia
TNT Studio
улица Закария Джорджадзе 78, Tbilisi
Home location
улица Захаридзе 20, Tbilisi
Online
Zoom Meeting
zoom.us/j/•••4829
Google Meet
meet.google.com/•••-abc
Home Visit
Home visit
30 min travel buffer
9:30●●●● 🔋
Add location
Search address or gym name
Gyms Near You
GYM Bro
Shota Rustaveli Ave, Tbilisi
0.3 km
CrossFit Tbilisi
Kostava Str 42, Tbilisi
1.2 km
FitLife Studio
Chavchavadze Ave 12, Tbilisi
2.1 km
TNT Studio
улица Закария Джорджадзе 78
3.5 km
Use current location
Pick on map
9:30●●●● 🔋
Search address
Pin is locked Tap to adjust
Shota Rustaveli Ave 24
Tbilisi, Georgia
9:30●●●● 🔋
Location details
GYM Bro
Shota Rustaveli Ave, Tbilisi, Georgia
Change
Location name
e.g., GYM Bro, Home gym
Description (optional)
e.g., 2nd floor, ring the bell
Set as default location
Delete Location?
This will remove GYM Bro from your locations.
This location is used in 3 training templates (HIIT Group Session, Basketball Training, Yoga Flow). They will need a new location assigned.
9:30●●●● 🔋
Home visit
You travel to the athlete's location. Their address is provided when they book. Travel buffer blocks extra time in your calendar for commuting.
Travel buffer
15 min
30 min
45 min
60 min
Added before and after each home visit session
How it works
Example: 1h training + 30 min buffer
Travel 30m
Training 1h
Travel 30m
Total blocked: 2h
Service area (optional)
15 km
Athletes outside this radius won't see home visit option
Set as default location
9:30●●●● 🔋
Add online location
Platform
Zoom
Meeting link
https://zoom.us/j/1234567890
Display name (optional)
e.g., "My Zoom room"
Description (optional)
e.g., "Link updates 1h before training"
Set as default location
9:30●●●● 🔋
Settings
Profile
RH
Edit personal info
Avatar, name, gender, height weight
Invite a Coach
Recommend the app to a friend
Coaching
Sport types
Basketball, Padel, Tennis
Training sessions
Added 3
Available hours
5 days active
GYM locations
Added 2 locations
Calendar Sync
Google connected
Payments
Earnings
€340.50 available
S
Stripe Connect
Connected
Account
Account Access
Sign-in, password, delete
Log out
Signed out
9:30●●●● 🔋
Calendar sync
Google Calendar connected
Google Calendar
john.miller@gmail.com
2 of 3 calendars synced
Google Calendar
coach.work@gmail.com
Fetching calendars...
Add Google account
Apple Calendar
Not connected
9:30●●●● 🔋
Google Calendar
john.miller@gmail.com
Connected
Select calendars to sync
Personal
Work
Birthdays
Holidays in Poland
Disconnect Google Calendar?
john.miller@gmail.com will be disconnected. Synced events will be removed from your schedule.
9:30●●●● 🔋
Apple Calendar
Apple Calendar uses CalDAV, which requires an app-specific password instead of your iCloud password.
Apple ID
App-specific password
How to create an app-specific password:
1. Go to appleid.apple.com
2. Sign in with your Apple ID
3. Sign-In and SecurityApp-Specific Passwords
4. Generate a password and paste it here
Invalid credentials. Check your Apple ID and password.
9:30●●●● 🔋
Apple Calendar
youri@icloud.com
Connected
Select calendars to sync
Personal
Work
Family
Disconnect Apple Calendar?
youri@icloud.com will be disconnected. Synced events will be removed from your schedule.
9:30●●●● 🔋
Personal data
JM
First name
John
Last name
Miller
About me
Certified fitness & yoga coach with 8 years of experience. Multi-sport coach working with tennis, padel, and basketball players.
Time Zone
Warsaw, Europe (GMT+1)
Home location
Poland
Languages
Polski
Body metrics
Woman
Man
Weight
kg
Height
cm
Date of birth
Select your date of birth
Couldn't save changes. Check your connection and try again.
Personal data updated
Discard changes?
Your profile changes will be lost.
Profile photo
Date of birth
You must be at least 13 years old
9:30●●●● 🔋
About Me
Certified fitness & yoga coach with 8 years of experience. Multi-sport coach working with tennis, padel, and basketball players. Focused on improving technique, coordination, and game understanding.
9:30●●●● 🔋
Time zone
Honolulu, Pacific (GMT-10)
Anchorage, America (GMT-9)
Los Angeles, America (GMT-8)
Denver, America (GMT-7)
Chicago, America (GMT-6)
New York, America (GMT-5)
Halifax, America (GMT-4)
São Paulo, America (GMT-3)
Azores, Atlantic (GMT-1)
London, Europe (GMT+0)
Warsaw, Europe (GMT+1)
Cairo, Africa (GMT+2)
Moscow, Europe (GMT+3)
Dubai, Asia (GMT+4)
Karachi, Asia (GMT+5)
Bangkok, Asia (GMT+7)
Singapore, Asia (GMT+8)
Tokyo, Asia (GMT+9)
Sydney, Australia (GMT+10)
Auckland, Pacific (GMT+12)
No matches
Try a different city or region
9:30●●●● 🔋
Home country
🇦🇷
Argentina
🇦🇺
Australia
🇧🇷
Brazil
🇨🇦
Canada
🇨🇳
China
🇨🇿
Czech Republic
🇩🇰
Denmark
🇪🇬
Egypt
🇫🇮
Finland
🇫🇷
France
🇩🇪
Germany
🇮🇳
India
🇮🇩
Indonesia
🇮🇪
Ireland
🇮🇱
Israel
🇮🇹
Italy
🇯🇵
Japan
🇲🇽
Mexico
🇳🇱
Netherlands
🇳🇿
New Zealand
🇳🇴
Norway
🇵🇱
Poland
🇵🇹
Portugal
🇷🇴
Romania
🇸🇬
Singapore
🇿🇦
South Africa
🇪🇸
Spain
🇸🇪
Sweden
🇨🇭
Switzerland
🇹🇷
Turkey
🇺🇦
Ukraine
🇦🇪
United Arab Emirates
🇬🇧
United Kingdom
🇺🇸
United States
🇻🇳
Vietnam
No matches
Try a different country name
9:30●●●● 🔋
Languages
العربية · Arabic
বাংলা · Bengali
中文 · Chinese (Simplified)
Čeština · Czech
Dansk · Danish
Nederlands · Dutch
English · English
Suomi · Finnish
Français · French
Deutsch · German
Ελληνικά · Greek
עברית · Hebrew
हिन्दी · Hindi
Magyar · Hungarian
Indonesia · Indonesian
Italiano · Italian
日本語 · Japanese
한국어 · Korean
Norsk · Norwegian
فارسی · Persian
Polski · Polish
Português · Portuguese
Română · Romanian
Русский · Russian
Español · Spanish
Svenska · Swedish
ไทย · Thai
Türkçe · Turkish
Українська · Ukrainian
Tiếng Việt · Vietnamese
No matches
Try the native name or English
Discard changes?
Your language selection will not be saved.
9:30●●●● 🔋
Sport types
Fitness & Strength
Fitness
CrossFit
Functional
HIIT
Weightlifting
Calisthenics
Racket sports
Tennis
Padel
Badminton
Squash
Table tennis
Team & court
Basketball
Football
Volleyball
Combat & martial arts
Boxing
Muay Thai
MMA
BJJ
Karate
Endurance & cardio
Running
Cycling
Swimming
Triathlon
Mind & body
Yoga
Pilates
Stretching
Recovery & therapy
Massage
Sports massage
Physiotherapy
Other
Golf
Climbing
Skiing
Dance
No matches
Try a different sport name
Discard changes?
Your sport selection will not be saved.
9:30●●●● 🔋
Available hours
All times in Europe/Rome (set in Settings)
Monday
07:00
to
22:00
Tuesday
07:00
to
12:00
14:00
to
20:00
Wednesday
07:00
to
22:00
Thursday
07:00
to
22:00
Friday
Saturday
10:00
to
14:00
Sunday
Availability updated
Discard changes?
Your availability changes will be lost.
Sessions outside new hours
Already confirmed — they'll stay scheduled.
Basketball with Anna K.
Fri, Apr 24 · 10:00 – 11:00
HIIT with Marco R.
Fri, May 1 · 18:00 – 19:00
Padel with Sofia L.
Fri, May 8 · 14:00 – 15:30
Start time
15-minute increments
:
Coach

Create Training Session

Unified form for personal and group. Group-only fields hide/show with animation based on type toggle.

Full behavior spec

Prefilled defaults

Sport: first from profile. Location: first address. Type: Personal. Payment: Cash. Max: 10, Min: 3. Days: current weekday. Date: today. Time: NOT prefilled.

Validation (Errors state)

Save always active. On tap Save: validates name, duration, price, time. Red border + red label on empty fields (all at once). Auto-scroll to first error. Snackbar: "Please fill in required fields" for 2.5s. Error styles auto-clear after 3s so user can focus and retype. Re-typing in a field does NOT auto-clear — only Save re-validates.

Side-effect resets (Time reset state)

Changing duration or date after time was selected → resets time to "Select time" + neutral snackbar: "Time slot reset — duration changed". Prevents invalid slot selection.

Time picker (sheet)

Accordion: hours with busy labels + "2/4" partial badges. Tap hour → expand minute chips. Busy minutes greyed. Confirm button shows selected range.

Recurring

Auto-generates events 2 months ahead. Daily rolling check.

One-off

Calendar grid in bottom sheet. Past dates greyed. "Special" badge on profile.

Location picker

Tap Location field → pushes to Training Locations screen in select mode. Shows all in-person + online locations. Tap = select + pop back. Supports both physical gyms and online meeting links.

API

POST /coach/training-sessions/ (create) · PUT /coach/training-sessions/{id}/ (edit).

Coach

My Training Sessions

All templates. Tap a card → edit (same form, prefilled).

States & behavior

Empty state

Coach has 0 templates (fresh signup or all deleted). Illustration + title + subtitle + primary "Create session" CTA. CTA pushes to s-create. Bottom navbar still visible.

Loading state

Shown during GET /coach/training-sessions/. Skeleton cards (3 placeholders) with shimmer. Prevents layout shift when data arrives.

Error state

Network/server error → inline retry card replaces list (cross-cutting pattern, #8).

API

GET /coach/training-sessions/ — returns template list.
DELETE /coach/training-sessions/{id}/ — with cascade warning if used in scheduled events.

Coach

My Training Sessions

All templates. Pencil icon → edit (same form, prefilled).

Coach

Training Locations

Three location types + two usage modes.


Settings mode: tap card → edit details
Select mode: tap → select + pop back

Travel buffer: added before AND after each home visit session. Backend uses blocked_start = event_start - buffer, blocked_end = event_end + buffer for overlap checks.

Coach

Add In-person

Search-first approach with smart suggestions.

When user types → "Gyms Near You" replaced by autocomplete results.

Coach

Pick on Map

Fullscreen map with two modes. Tap the pill to toggle.


Why locked by default: prevents accidental pin movement when user opens from Location Details to verify position.

Coach

Location Details

Used for both create and edit location.


Create vs Edit: same screen. Edit prefills all fields + shows trash icon. Create hides trash icon.

Coach

Home Visit

Settings for home visit training type.


Backend: location_type='home_visit', travel_buffer_minutes, service_area_km (optional). At booking: athlete's address + distance check against service area.

Coach

Add Online Location

Form for virtual meeting location.

Backend needed: location_type enum + meeting_link field. Make lat/lon optional.

Coach

Settings

Coach: Profile, Coaching, Payments, Account.

Coach

Calendar Sync

Connected: account cards with details. Zero: provider cards with Connect CTAs.

Connection flows

Google OAuth

Tap "+" → system Google Sign-In → OAuth → backend stores tokens → auto-creates "321 Fit" calendar → loading → calendars fetched.

Apple CalDAV

Tap Connect → Apple ID + app-specific password form. Backend validates → stores encrypted → fetches calendars.

Sync

Bidirectional. External events anonymized. Webhook + 15-min fallback.

Coach

Google Calendar Detail

Dedicated screen per account. 4 states via toggle.

Coach

Apple Calendar Connect

CalDAV connection. Apple ID + app-specific password.

Coach

Apple Calendar Detail

Apple-specific error states differ from Google.

Coach

Personal Data

Edit profile from Settings.

Coach

About Me Editor

Full-screen text editor. Cancel/Save header. Reusable for About Me and Notes fields.

Coach

Sport types

Push screen opened from Sport types set-card in Settings. Closed list of 33 sports across 8 sections — no custom sports (discovery, search, filter, matching all depend on canonical sport ID).

Recovery & therapy section exists because home-visit location type makes massage/physio a significant offering. Deferred from v1: Surfing / Kitesurfing / SUP / Equestrian — added on geo expansion.

Icons = draft adapted Tabler/Material style. Formal 33-icon set goes to design-tokens/assets/icons/sport/ as Phase 3 task (stable IDs, Style Dictionary pipeline).

Coach

Languages

Full-screen push from Personal Data. Multi-select — tap toggles row, Save commits all changes.

Prototype = 30 common languages. Production pulls full BCP-47 list.

Coach

Home Country

Full-screen push from Personal Data. Same pattern as Time Zone — single-select, auto-dismiss.

Prototype uses ~35 countries covering major markets. Production pulls full ISO 3166-1 list.

Coach

Time Zone

Full-screen push from Personal Data. Single-select — tap row auto-dismisses back to Personal Data with the new value.

Prototype uses ~20 representative TZs. Production pulls full IANA zone list from device.

Coach

Available Hours

Coach's weekly schedule — when athletes can book training sessions. Applies indefinitely until edited. New accounts are seeded with Mon–Sun 07:00–22:00 so the screen opens populated rather than empty.


Validation (live per-interval):

Non-blocking warning banners:


Time picker (platform-native in production):


Flow states:

Back button behavior: opens Discard changes? bottom sheet. Discard = Medium destructive (tinted red), Keep editing = text button. In production, the sheet only opens when there are unsaved changes.


HIG / a11y / theming:


Scope decisions (v1): single availability for all locations · no copy-to-other-days · no quick presets · no vacation mode — see project_pending_spec_updates.md for deferred items.