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 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 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 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 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 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 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 = [ 'Hospitality', 'Restaurant', 'Warehouse', 'Logistics', 'Events', 'Stadiums', 'Education', 'Healthcare & cafeteria', 'Convention centre', 'Catering', ]; static const skills = [ 'Food prep', 'Cooking', 'Grilling', 'Dishwashing', 'Food service', 'Banquet', 'Bartender', 'Barista', 'Customer service', 'Safe food handling', 'Event setup', ]; static const supportTopics = [ 'Shift issue', 'Pay or billing', 'Schedule clash', 'Account', 'Bug report', 'Feature idea', ]; static const faqs = >{ '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.', ), ], }; }