Initial commit: Krow Worker App
This commit is contained in:
392
lib/state/seed.dart
Normal file
392
lib/state/seed.dart
Normal file
@@ -0,0 +1,392 @@
|
||||
import '../models/compliance.dart';
|
||||
import '../models/shift.dart';
|
||||
import '../models/timecard.dart';
|
||||
|
||||
/// Demo content. Everything is anchored to "now" so the app is live whenever
|
||||
/// it is opened: the next shift always starts in 41 minutes.
|
||||
abstract final class Seed {
|
||||
static DateTime get _now => DateTime.now();
|
||||
|
||||
static DateTime _at(int dayOffset, int hour, int minute) {
|
||||
final base = _now.add(Duration(days: dayOffset));
|
||||
return DateTime(base.year, base.month, base.day, hour, minute);
|
||||
}
|
||||
|
||||
static const _baristaReqs = [
|
||||
'Government ID',
|
||||
'Food handler certification',
|
||||
'Black pants',
|
||||
'Black shirt',
|
||||
'Non-slip black shoes',
|
||||
];
|
||||
|
||||
static List<Shift> shifts() {
|
||||
final now = _now;
|
||||
// Inside the 30-minute clock-in window, so the app opens on a shift you
|
||||
// can actually start.
|
||||
final soon = now.add(const Duration(minutes: 20));
|
||||
return [
|
||||
// Today: the shift you are about to clock into.
|
||||
Shift(
|
||||
id: 's1',
|
||||
role: 'Barista',
|
||||
business: 'Zoox',
|
||||
venue: 'Zoox - San Jose Hub',
|
||||
address: '848 E Gish Rd, San Jose CA',
|
||||
start: soon,
|
||||
end: soon.add(const Duration(hours: 6)),
|
||||
rate: 21.00,
|
||||
status: ShiftStatus.booked,
|
||||
distanceMiles: 2.4,
|
||||
manager: 'Kirk R. - Owner',
|
||||
requirements: _baristaReqs,
|
||||
),
|
||||
Shift(
|
||||
id: 's2',
|
||||
role: 'Server',
|
||||
business: 'Google LLC',
|
||||
venue: 'Google LLC - Midpoint',
|
||||
address: 'Midpoint, Sunnyvale CA',
|
||||
start: _at(1, 13, 0),
|
||||
end: _at(1, 18, 0),
|
||||
rate: 24.00,
|
||||
status: ShiftStatus.booked,
|
||||
distanceMiles: 3.1,
|
||||
manager: 'Dana W. - Floor lead',
|
||||
requirements: _baristaReqs,
|
||||
),
|
||||
// Open market, highest paying first.
|
||||
Shift(
|
||||
id: 's3',
|
||||
role: 'Bartender',
|
||||
business: 'Google LLC',
|
||||
venue: 'Google LLC - Midpoint',
|
||||
address: 'Midpoint, Sunnyvale CA',
|
||||
start: _at(2, 16, 0),
|
||||
end: _at(2, 23, 0),
|
||||
rate: 28.00,
|
||||
status: ShiftStatus.open,
|
||||
distanceMiles: 3.1,
|
||||
requirements: [..._baristaReqs, 'Responsible beverage service'],
|
||||
),
|
||||
Shift(
|
||||
id: 's4',
|
||||
role: 'Barista',
|
||||
business: 'Zoox',
|
||||
venue: 'Zoox - San Jose Hub',
|
||||
address: '848 E Gish Rd, San Jose CA',
|
||||
start: _at(3, 18, 0),
|
||||
end: _at(3, 23, 50),
|
||||
rate: 21.00,
|
||||
status: ShiftStatus.open,
|
||||
distanceMiles: 2.4,
|
||||
requirements: _baristaReqs,
|
||||
),
|
||||
Shift(
|
||||
id: 's5',
|
||||
role: 'Host',
|
||||
business: 'Google LLC',
|
||||
venue: 'Google LLC - Midpoint',
|
||||
address: 'Midpoint, Sunnyvale CA',
|
||||
start: _at(4, 11, 0),
|
||||
end: _at(4, 17, 0),
|
||||
rate: 19.50,
|
||||
status: ShiftStatus.open,
|
||||
distanceMiles: 3.1,
|
||||
requirements: _baristaReqs,
|
||||
),
|
||||
Shift(
|
||||
id: 's6',
|
||||
role: 'Banquet server',
|
||||
business: 'Legendary Events',
|
||||
venue: 'Legendary Events - Convention Centre',
|
||||
address: '150 W San Carlos St, San Jose CA',
|
||||
start: _at(5, 9, 0),
|
||||
end: _at(5, 17, 30),
|
||||
rate: 22.50,
|
||||
status: ShiftStatus.open,
|
||||
distanceMiles: 4.8,
|
||||
requirements: _baristaReqs,
|
||||
),
|
||||
// Worked history.
|
||||
Shift(
|
||||
id: 's7',
|
||||
role: 'Barista',
|
||||
business: 'Zoox',
|
||||
venue: 'Zoox - San Jose Hub',
|
||||
address: '848 E Gish Rd, San Jose CA',
|
||||
start: _at(-4, 17, 50),
|
||||
end: _at(-4, 23, 50),
|
||||
rate: 21.00,
|
||||
status: ShiftStatus.completed,
|
||||
distanceMiles: 2.4,
|
||||
clockIn: _at(-4, 18, 1),
|
||||
clockOut: _at(-4, 23, 50),
|
||||
requirements: _baristaReqs,
|
||||
),
|
||||
Shift(
|
||||
id: 's8',
|
||||
role: 'Barista',
|
||||
business: 'Google LLC',
|
||||
venue: 'Google LLC - Midpoint',
|
||||
address: 'Midpoint, Sunnyvale CA',
|
||||
start: _at(-6, 11, 0),
|
||||
end: _at(-6, 18, 0),
|
||||
rate: 21.00,
|
||||
status: ShiftStatus.cancelled,
|
||||
distanceMiles: 3.1,
|
||||
requirements: _baristaReqs,
|
||||
),
|
||||
Shift(
|
||||
id: 's9',
|
||||
role: 'Barista',
|
||||
business: 'Google LLC',
|
||||
venue: 'Google LLC - Midpoint',
|
||||
address: 'Midpoint, Sunnyvale CA',
|
||||
start: _at(-13, 9, 0),
|
||||
end: _at(-13, 15, 0),
|
||||
rate: 21.00,
|
||||
status: ShiftStatus.noShow,
|
||||
distanceMiles: 3.1,
|
||||
requirements: _baristaReqs,
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
static List<Timecard> timecards() {
|
||||
final worked = shifts().firstWhere((s) => s.id == 's7');
|
||||
return [
|
||||
Timecard(
|
||||
id: 'tc1',
|
||||
shiftId: worked.id,
|
||||
role: worked.role,
|
||||
business: worked.business,
|
||||
scheduledStart: worked.start,
|
||||
scheduledEnd: worked.end,
|
||||
clockIn: worked.clockIn!,
|
||||
clockOut: worked.clockOut!,
|
||||
breakMinutes: worked.breakMinutes,
|
||||
rate: worked.rate,
|
||||
status: TimecardStatus.needsReview,
|
||||
submittedAt: worked.clockOut!.add(const Duration(minutes: 12)),
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
static List<ComplianceItem> documents() => [
|
||||
ComplianceItem(
|
||||
id: 'd1',
|
||||
title: 'Government ID',
|
||||
subtitle: 'State ID or passport',
|
||||
state: ComplianceState.verified,
|
||||
fileName: 'government-id-front.jpg',
|
||||
fileMeta: '2.1 MB - uploaded 2 Aug',
|
||||
expires: DateTime(2029, 3, 14),
|
||||
),
|
||||
ComplianceItem(
|
||||
id: 'd2',
|
||||
title: 'Social security',
|
||||
subtitle: 'Card or SSA letter',
|
||||
state: ComplianceState.verified,
|
||||
fileName: 'ssn-card.jpg',
|
||||
fileMeta: '1.2 MB - uploaded 2 Aug',
|
||||
),
|
||||
ComplianceItem(
|
||||
id: 'd3',
|
||||
title: 'Work permit',
|
||||
subtitle: 'Right-to-work evidence',
|
||||
state: ComplianceState.verified,
|
||||
fileName: 'work-permit.pdf',
|
||||
fileMeta: '640 KB - uploaded 2 Aug',
|
||||
),
|
||||
ComplianceItem(
|
||||
id: 'd4',
|
||||
title: 'Proof of address',
|
||||
subtitle: 'Bill or statement, last 90 days',
|
||||
state: ComplianceState.pending,
|
||||
statusLabel: 'In review',
|
||||
fileName: 'utility-bill.pdf',
|
||||
fileMeta: '380 KB - uploaded yesterday',
|
||||
),
|
||||
];
|
||||
|
||||
static List<ComplianceItem> certificates() => [
|
||||
ComplianceItem(
|
||||
id: 'c1',
|
||||
title: 'Food handler certification',
|
||||
subtitle: 'Accepted by all California venues',
|
||||
state: ComplianceState.verified,
|
||||
statusLabel: 'Validated',
|
||||
fileName: 'food-safety-certificate.pdf',
|
||||
fileMeta: '840 KB - uploaded 2 Aug',
|
||||
expires: DateTime(2027, 3, 14),
|
||||
),
|
||||
ComplianceItem(
|
||||
id: 'c2',
|
||||
title: 'Responsible beverage service',
|
||||
subtitle: 'Needed for bartender shifts',
|
||||
state: ComplianceState.verified,
|
||||
statusLabel: 'Validated',
|
||||
fileName: 'rbs-certificate.pdf',
|
||||
fileMeta: '510 KB - uploaded 2 Aug',
|
||||
expires: DateTime(2028, 1, 9),
|
||||
),
|
||||
ComplianceItem(
|
||||
id: 'c3',
|
||||
title: 'CPR / AED',
|
||||
subtitle: 'Adds around 4 shifts a week near you',
|
||||
state: ComplianceState.missing,
|
||||
statusLabel: 'Not added',
|
||||
required_: false,
|
||||
),
|
||||
ComplianceItem(
|
||||
id: 'c4',
|
||||
title: 'Forklift licence',
|
||||
subtitle: 'Warehouse and logistics roles',
|
||||
state: ComplianceState.missing,
|
||||
statusLabel: 'Not added',
|
||||
required_: false,
|
||||
),
|
||||
];
|
||||
|
||||
static List<ComplianceItem> taxForms() => [
|
||||
ComplianceItem(
|
||||
id: 't1',
|
||||
title: 'Form I-9',
|
||||
subtitle: 'Employment eligibility verification',
|
||||
state: ComplianceState.verified,
|
||||
statusLabel: 'Approved',
|
||||
fileName: 'i9-form.pdf',
|
||||
fileMeta: 'Approved 3 Aug',
|
||||
),
|
||||
ComplianceItem(
|
||||
id: 't2',
|
||||
title: 'Form W-4',
|
||||
subtitle: 'Sets how much tax is withheld',
|
||||
state: ComplianceState.verified,
|
||||
statusLabel: 'Approved',
|
||||
fileName: 'w4-form.pdf',
|
||||
fileMeta: 'Approved 3 Aug',
|
||||
),
|
||||
];
|
||||
|
||||
static List<ComplianceItem> wardrobe() => [
|
||||
ComplianceItem(
|
||||
id: 'w1',
|
||||
title: 'Black pants',
|
||||
subtitle: 'Solid black dress pants or slacks',
|
||||
state: ComplianceState.verified,
|
||||
statusLabel: 'Approved',
|
||||
fileName: 'black-pants.jpg',
|
||||
fileMeta: '1.4 MB - uploaded 2 Aug',
|
||||
),
|
||||
ComplianceItem(
|
||||
id: 'w2',
|
||||
title: 'Black shirt',
|
||||
subtitle: 'Plain, no logos',
|
||||
state: ComplianceState.verified,
|
||||
statusLabel: 'Approved',
|
||||
fileName: 'black-shirt.jpg',
|
||||
fileMeta: '1.1 MB - uploaded 2 Aug',
|
||||
),
|
||||
ComplianceItem(
|
||||
id: 'w3',
|
||||
title: 'Non-slip black shoes',
|
||||
subtitle: 'Closed-toe, required on every shift',
|
||||
state: ComplianceState.verified,
|
||||
statusLabel: 'Approved',
|
||||
fileName: 'black-shoes.jpg',
|
||||
fileMeta: '0.9 MB - uploaded 2 Aug',
|
||||
),
|
||||
ComplianceItem(
|
||||
id: 'w4',
|
||||
title: 'Black belt',
|
||||
subtitle: 'Plain, simple buckle',
|
||||
state: ComplianceState.missing,
|
||||
statusLabel: 'Not added',
|
||||
required_: false,
|
||||
),
|
||||
];
|
||||
|
||||
static const workSettings = <String>[
|
||||
'Hospitality',
|
||||
'Restaurant',
|
||||
'Warehouse',
|
||||
'Logistics',
|
||||
'Events',
|
||||
'Stadiums',
|
||||
'Education',
|
||||
'Healthcare & cafeteria',
|
||||
'Convention centre',
|
||||
'Catering',
|
||||
];
|
||||
|
||||
static const skills = <String>[
|
||||
'Food prep',
|
||||
'Cooking',
|
||||
'Grilling',
|
||||
'Dishwashing',
|
||||
'Food service',
|
||||
'Banquet',
|
||||
'Bartender',
|
||||
'Barista',
|
||||
'Customer service',
|
||||
'Safe food handling',
|
||||
'Event setup',
|
||||
];
|
||||
|
||||
static const supportTopics = <String>[
|
||||
'Shift issue',
|
||||
'Pay or billing',
|
||||
'Schedule clash',
|
||||
'Account',
|
||||
'Bug report',
|
||||
'Feature idea',
|
||||
];
|
||||
|
||||
static const faqs = <String, List<(String, String)>>{
|
||||
'Getting started': [
|
||||
(
|
||||
'How do I finish my worker profile?',
|
||||
'Open Profile, then Compliance. Work down the sections until every one '
|
||||
'shows a green tick. You can accept shifts as soon as documents, '
|
||||
'tax forms and attire are complete.',
|
||||
),
|
||||
(
|
||||
"Why can't I apply to shifts yet?",
|
||||
'Businesses only see workers who are fully compliant. Anything still '
|
||||
'marked yellow on the compliance hub is blocking you.',
|
||||
),
|
||||
],
|
||||
'Shifts and attendance': [
|
||||
(
|
||||
'How does clock-in work?',
|
||||
'The clock-in button unlocks 30 minutes before your shift starts, once '
|
||||
'you are within 150 m of the venue. Tap out when you leave and the '
|
||||
'timecard submits itself.',
|
||||
),
|
||||
(
|
||||
'What happens if I request a swap?',
|
||||
'Your shift is offered to other qualified workers. You stay responsible '
|
||||
'for it until someone accepts, so keep an eye on notifications.',
|
||||
),
|
||||
(
|
||||
'What counts as a no-show?',
|
||||
'Not clocking in within 30 minutes of the scheduled start, with no '
|
||||
'cancellation. No-shows cost 15 points of trust index each.',
|
||||
),
|
||||
],
|
||||
'Pay and compliance': [
|
||||
(
|
||||
'When do I actually get paid?',
|
||||
'Semi-monthly. Each period closes on the 15th and the last day of the '
|
||||
'month, and pays 11 days later.',
|
||||
),
|
||||
(
|
||||
'How are documents verified?',
|
||||
'A reviewer checks each upload by hand, usually within one business '
|
||||
'day. You get a notification either way.',
|
||||
),
|
||||
],
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user