Initial commit: Krow Worker App

This commit is contained in:
R-Bharathraj
2026-09-17 22:26:11 +05:30
commit cafffd27e0
113 changed files with 13067 additions and 0 deletions

159
README.md Normal file
View File

@@ -0,0 +1,159 @@
# KROW Worker
A Flutter app for shift workers: find hospitality shifts, clock in on site, get
timecards filed automatically, and keep compliance documents in order.
Built from the workflow in the KROW worker-app prototype — the HTML was used as
the reference for screens and flow, not as a pixel spec.
## Running it
```bash
flutter pub get
flutter run
```
Targets Android, iOS and web. To try it in a browser:
```bash
flutter run -d chrome
```
**Demo sign-in:** any 10-digit mobile number, then the code `123456`.
## What works
Everything below is wired to real state, not static screens. Shifts, timecards
and compliance live in memory for the session; onboarding, sign-in,
availability, skills and preferences persist via `shared_preferences`.
**Getting in** — splash routes by how far you got last time · 3-screen
onboarding with skip · phone entry with validation · OTP with a resend
countdown, a wrong-code path and a 3-try budget · 3-step permission run whose
grants are recorded and reflected in Settings.
**Today** — greeting, period earnings and hours logged, a compliance nudge while
anything is outstanding, your next shift, quick tiles and matched open shifts.
**Shifts** — Booked / Open / History. The week strip filters booked shifts by
day and dots the days that have work. Open supports search and filters, and
Apply books the shift immediately. History carries completed, cancelled and
no-show shifts with a stat rail.
**Shift detail** — full schedule and pay breakdown, plus a requirements check
that compares what the business asks for against what you actually have on
file. Actions change with status: apply, cancel (with confirmation), or jump to
the clock.
**Clock** — the button unlocks 30 minutes before the shift, and only once you
are at the venue. Clocking in starts a live stopwatch against a progress ring;
clocking out completes the shift, deducts the unpaid break and files a timecard.
**Timecards** — every filed card with its scheduled vs clocked window, variance
in minutes, and pay. Review one to approve it or raise a dispute with a note.
The tab badge counts what is still waiting on you.
**Pay** — gross pre-tax earnings across week / month / year / all, a trend chart
split paid vs pending, per-payment detail, and a semi-monthly payroll schedule
that computes the current and next period from today's date.
**Profile & compliance** — live stats and a trust index derived from the shifts
you have actually worked. The compliance hub tracks documents, certificates, tax
forms and attire; uploading sends an item back for review, removing it drops it
to missing, and expiry dates are picked from a calendar. Plus emergency
contacts, experience and skills, availability, benefits, direct deposit,
settings, support, FAQs and privacy.
## Motion
Motion is used to explain what changed, not to decorate. The rules:
- **Going deeper pushes.** Detail screens slide in from the right while the
screen behind eases back and dims, so the stack reads as a stack. Going
sideways — sign-up steps, replacing a screen — cross-fades instead.
- **Selection travels.** The bottom nav indicator and the segmented controls
slide between positions and squash slightly at speed. Labels light up as the
indicator arrives over them, driven by the same animated value, so nothing
changes ahead of the thing causing it.
- **Numbers grow.** Progress bars and chart bars tween to new values, so an
uploaded document or a switched pay range is something you watch happen.
- **State changes animate together.** Availability blocks, week-strip days and
the clock dial move every part of themselves in one gesture rather than
flipping several properties at once.
- **Consequential actions are felt.** Clocking in and out give a medium impact;
selecting a tab, segment, or applying for a shift gives a selection click.
**Headers stay put.** On the five tabs the blue header is pinned: content
scrolls beneath it rather than pushing it off the top. A tall header held at
full size would cost a quarter of a phone screen for the whole session, so it
collapses as you scroll and cross-fades to a compact bar that keeps what still
matters — your name and the period figure on Today, the gross total on Pay.
Where a header holds a control, the collapsed state keeps it. Pay stops
shrinking while the range switcher is still on screen; collapsing that away
would mean scrolling back to the top just to change what you are looking at.
Shifts keeps its whole header fixed for the same reason — the Booked / Open /
History switch has to stay reachable.
Scrolling uses bouncing physics on every platform (`KrowScrollBehavior`). Under
a pinned header a rubber-band edge tells you that you have reached the end of
the content rather than the end of the screen; clamping just stops dead. The
overscroll glow is turned off, since the bounce already says it.
Two deliberate exceptions:
- **Tab content does not slide.** Switching bottom tabs fades and lifts the
content instead. An `AnimatedSwitcher` would hold two copies of the shell in
the tree, and the branch navigators are keyed by `GlobalKey`, so duplicating
them throws. `_TabTransition` animates one subtree in place, which keeps each
tab's scroll position.
- **No `Hero` between list and detail.** The tab branches all stay alive in an
`IndexedStack`, so the same shift can be on screen in two branches at once
and duplicate hero tags would throw.
## Layout
```
lib/
core/ theme, router, formatters
models/ shift, timecard, availability, compliance, worker
state/ Riverpod controllers + seed data
screens/ one file per area of the app
widgets/ shift card, week strip, shared pieces
```
## Packages
| Package | Why |
| --- | --- |
| `flutter_riverpod` | State: shifts, timecards, availability, compliance, profile, session |
| `go_router` | Routing, including the 5-tab shell where each tab keeps its own stack |
| `google_fonts` | Poppins, the brand typeface |
| `lucide_icons_flutter` | Icon set matching the prototype's line icons |
| `intl` | Currency, date and time formatting |
| `shared_preferences` | Persisting session, availability and preferences |
## Tests
```bash
flutter test
```
Covers pay calculation (break deduction, clocked vs scheduled hours, zero-pay
states), timecard variance, and the formatters — plus the custom nav and
segmented control: that the indicator actually travels rather than jumping,
that taps report the right index, and that each tab reaches the semantics tree
with its selected state (the dot alone is not readable).
## Wiring it to a backend
The seams are deliberate. `lib/state/seed.dart` is the only source of demo data;
swap each controller's `build()` for an API call and the screens are unchanged.
Two places currently stand in for device APIs:
- **Geofence** — `ClockScreen` has an "at the venue" switch in place of GPS.
Replace with `geolocator` and a 150 m radius check against the venue.
- **File upload** — the compliance sheet fakes a filename. Replace with
`image_picker` / `file_picker` and a real upload.
Notifications and SMS verification are also stubbed: the OTP is always `123456`.