Add initial mobile app prototypes and staff payments feature
Introduces the first versions of client and staff mobile application prototypes, including platform-specific assets, screens, and configuration for Android, iOS, macOS, Linux, and Windows. Adds documentation, AI prompt guides, and a new staff payments feature module with repository, use cases, and presentation logic. Also includes generated localization files and supporting resources for both client and staff apps.
75
apps/mobile/ai_prompts/-1-context-refresh.md
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
You are continuing work on an existing **Flutter monorepo–based mobile system** with multiple applications and a shared data/connect layer.
|
||||||
|
|
||||||
|
This prompt **replaces all missing prior thread context** and must be treated as the **single source of truth** for how you reason, plan, and execute work in this thread.
|
||||||
|
|
||||||
|
## 🧭 PROJECT OVERVIEW
|
||||||
|
|
||||||
|
* The project contains **multiple Flutter applications** (e.g. Staff app, Client app) that are being **rebuilt from scratch** using **Flutter Clean Architecture**, while **reusing UI code and flows** from POCs (prototypes).
|
||||||
|
* The goal is to rebuild the mobile apps in a **production-grade, scalable, agent-first manner**, not as POCs.
|
||||||
|
|
||||||
|
## 🧠 YOUR ROLE IN THIS THREAD
|
||||||
|
|
||||||
|
You are acting as a **Senior Flutter Architect + Execution Agent**, responsible for:
|
||||||
|
* Enforcing architectural consistency across features
|
||||||
|
* Preventing scope creep, tight coupling, and shortcut implementations
|
||||||
|
* Producing outputs that are suitable for **real engineering teams**, not demos
|
||||||
|
|
||||||
|
You **do not** invent architecture, flows, or patterns unless explicitly asked.
|
||||||
|
You **do** challenge requirements if they violate architecture or agent rules.
|
||||||
|
|
||||||
|
|
||||||
|
## 📚 MANDATORY DOCUMENTS (NON-NEGOTIABLE)
|
||||||
|
|
||||||
|
You MUST strictly follow the rules and constraints defined in **both documents below** at all times:
|
||||||
|
|
||||||
|
### 1️⃣ Architecture Principles
|
||||||
|
|
||||||
|
**apps/mobile/docs/01-architecture-principles.md**
|
||||||
|
|
||||||
|
This document defines:
|
||||||
|
* Clean Architecture boundaries
|
||||||
|
* Layer responsibilities (presentation / domain / data)
|
||||||
|
* Dependency rules
|
||||||
|
* Navigation, state management, and feature isolation expectations
|
||||||
|
and others.
|
||||||
|
|
||||||
|
### 2️⃣ Agent Development Rules
|
||||||
|
|
||||||
|
**apps/mobile/docs/02-agent-development-rules.md**
|
||||||
|
|
||||||
|
This document defines:
|
||||||
|
* How features are planned, split, and executed
|
||||||
|
* What an agent may or may not do
|
||||||
|
* Output formats, assumptions, and guardrails
|
||||||
|
* How prompts must be structured for future reuse
|
||||||
|
and others.
|
||||||
|
|
||||||
|
### 3️⃣ Design system guidelines
|
||||||
|
|
||||||
|
**apps/mobile/docs/03-design-system-usage.md**
|
||||||
|
|
||||||
|
This document defines:
|
||||||
|
* The design system of the project and the rules on how to use the design system.
|
||||||
|
|
||||||
|
⚠️ If a request conflicts with either document, you must:
|
||||||
|
|
||||||
|
* Call out the conflict explicitly
|
||||||
|
* Propose a compliant alternative
|
||||||
|
* Never silently violate the rules
|
||||||
|
|
||||||
|
## 🔁 CURRENT STATE
|
||||||
|
|
||||||
|
* Prior thread context is **not available**
|
||||||
|
* Architecture and agent rules **do exist** and must be referenced
|
||||||
|
* Any assumptions you make must be stated clearly
|
||||||
|
|
||||||
|
## ✅ ACKNOWLEDGEMENT REQUIRED
|
||||||
|
|
||||||
|
Before proceeding with any feature work, you must:
|
||||||
|
|
||||||
|
1. Acknowledge that this context has been loaded
|
||||||
|
2. Confirm adherence to:
|
||||||
|
* `apps/mobile/docs/01-architecture-principles.md`
|
||||||
|
* `apps/mobile/docs/02-agent-development-rules.md`
|
||||||
|
* `apps/mobile/docs/03-design-system-usage.md`
|
||||||
|
3. Wait for the next instruction or feature prompt
|
||||||
34
apps/mobile/ai_prompts/0-global.md
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
You are an expert Flutter architect and monorepo engineer.
|
||||||
|
|
||||||
|
You are working on the KROW workforce management platform.
|
||||||
|
Your responsibility is to rebuild two Flutter mobile applications (Client + Staff)
|
||||||
|
using a clean, agent-first architecture.
|
||||||
|
|
||||||
|
You must strictly follow:
|
||||||
|
- Clean Architecture
|
||||||
|
- Feature-first packaging
|
||||||
|
- Melos monorepo conventions
|
||||||
|
- Bloc for state management
|
||||||
|
- Flutter Modular for
|
||||||
|
- Modularized routes.
|
||||||
|
- Modularized Dependency Injection.
|
||||||
|
- Firebase Data Connect as the ONLY backend access layer
|
||||||
|
- No UI polish unless explicitly requested
|
||||||
|
|
||||||
|
IMPORTANT CONSTRAINTS:
|
||||||
|
- Firebase Data Connect code DOES NOT EXIST YET
|
||||||
|
- You must mock Data Connect responses using interfaces and fake implementations
|
||||||
|
- Domain entities MUST match the provided KROW domain model exactly
|
||||||
|
- No DTOs or entities inside feature packages
|
||||||
|
- Features must be independently testable
|
||||||
|
- Do not invent new entities, statuses, or workflows
|
||||||
|
|
||||||
|
You must never:
|
||||||
|
- Access Firebase directly
|
||||||
|
- Hardcode backend logic inside UI
|
||||||
|
- Mix domain logic with presentation
|
||||||
|
- Change entity definitions unless explicitly instructed
|
||||||
|
|
||||||
|
If ambiguity exists, document it instead of guessing.
|
||||||
|
|
||||||
|
Confirm understanding silently and wait for step instructions.
|
||||||
54
apps/mobile/ai_prompts/1-architecture-scaffolding.md
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
TASK: Create the KROW Flutter monorepo skeleton using Melos.
|
||||||
|
|
||||||
|
You must:
|
||||||
|
1. Create the directory structure exactly as defined below (some of the parts are already developed)
|
||||||
|
2. Initialize Melos (some of the parts are already developed)
|
||||||
|
3. Create minimal pubspec.yaml files where required (some of the parts are already developed)
|
||||||
|
4. Do NOT add application logic
|
||||||
|
5. Do NOT generate Flutter apps yet (basic strcuture of the apps/ are developed)
|
||||||
|
|
||||||
|
Target structure:
|
||||||
|
|
||||||
|
root/
|
||||||
|
├── apps/
|
||||||
|
│ ├── client/
|
||||||
|
│ ├── staff/
|
||||||
|
│ └── design_system_viewer/
|
||||||
|
│
|
||||||
|
├── packages/
|
||||||
|
│ ├── core/
|
||||||
|
│ ├── design_system/
|
||||||
|
│ ├── domain/
|
||||||
|
│ ├── data_connect/
|
||||||
|
│ └── features/
|
||||||
|
│ ├─ domain/
|
||||||
|
│ │ ├─ repositories/
|
||||||
|
│ │ └─ usecases/
|
||||||
|
│ │
|
||||||
|
│ ├─ data/
|
||||||
|
│ │ ├─ datasources/
|
||||||
|
│ │ └─ repositories_impl/
|
||||||
|
│ │
|
||||||
|
│ ├─ presentation/
|
||||||
|
│ │ ├─ state/
|
||||||
|
│ │ ├─ pages/
|
||||||
|
│ │ └─ widgets/
|
||||||
|
│ │
|
||||||
|
│ └─ feature_manifest.md
|
||||||
|
├── docs/
|
||||||
|
└── dataconnect/
|
||||||
|
|
||||||
|
Rules:
|
||||||
|
- Use Flutter 3.x compatible setup
|
||||||
|
- All packages must be melos-aware
|
||||||
|
- Keep pubspec files minimal
|
||||||
|
- No dependencies unless required for structure
|
||||||
|
- No example widgets or boilerplate UI
|
||||||
|
|
||||||
|
Output:
|
||||||
|
- melos.yaml
|
||||||
|
- Folder tree
|
||||||
|
- Minimal pubspec.yaml per package/app
|
||||||
|
- Short explanation of dependency boundaries
|
||||||
|
|
||||||
|
Do NOT proceed beyond skeleton creation.
|
||||||
19
apps/mobile/ai_prompts/2-agent-dev-rules.md
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
TASK: Create docs/02-agent-development-rules.md
|
||||||
|
|
||||||
|
This document defines NON-NEGOTIABLE rules for AI agents.
|
||||||
|
|
||||||
|
Must include:
|
||||||
|
- File creation rules
|
||||||
|
- Naming conventions
|
||||||
|
- Where logic is allowed / forbidden
|
||||||
|
- How to mock Data Connect safely
|
||||||
|
- How to introduce new features
|
||||||
|
- How to reuse prototype code without copying architecture mistakes
|
||||||
|
- Rules for handling ambiguity (must document, not assume)
|
||||||
|
|
||||||
|
Format:
|
||||||
|
- Clear numbered rules
|
||||||
|
- Short explanations
|
||||||
|
- Explicit "DO / DO NOT" sections
|
||||||
|
|
||||||
|
This document will be enforced strictly.
|
||||||
251
apps/mobile/ai_prompts/3-data-domain.md
Normal file
@@ -0,0 +1,251 @@
|
|||||||
|
TASK: Create the shared domain package.
|
||||||
|
|
||||||
|
Domain Details:
|
||||||
|
|
||||||
|
## 1. Core Domain Logic
|
||||||
|
|
||||||
|
### 1.1 Domain Entities Overview
|
||||||
|
|
||||||
|
The KROW platform has **49 domain entities** organized into 8 logical groups:
|
||||||
|
|
||||||
|
```
|
||||||
|
┌────────────────────────────────────────────────────────────────────┐
|
||||||
|
│ KROW DOMAIN MODEL │
|
||||||
|
├────────────────────────────────────────────────────────────────────┤
|
||||||
|
│ │
|
||||||
|
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||||
|
│ │ USERS & │ │ BUSINESS & │ │ EVENTS & │ │
|
||||||
|
│ │ MEMBERSHIP │ │ ORGANIZATION│ │ SHIFTS │ │
|
||||||
|
│ ├─────────────┤ ├─────────────┤ ├─────────────┤ │
|
||||||
|
│ │ User │ │ Business │ │ Event │ │
|
||||||
|
│ │ Staff │ │ BusinessSet │ │ EventShift │ │
|
||||||
|
│ │ Membership │ │ Hub │ │ Position │ │
|
||||||
|
│ │ BizMember │ │ HubDept │ │ Assignment │ │
|
||||||
|
│ │ HubMember │ │ BizContract │ │ WorkSession │ │
|
||||||
|
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||||||
|
│ │
|
||||||
|
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||||
|
│ │ SKILLS & │ │ FINANCIAL │ │ RATINGS & │ │
|
||||||
|
│ │ CERTS │ │ PAYROLL │ │ PENALTIES │ │
|
||||||
|
│ ├─────────────┤ ├─────────────┤ ├─────────────┤ │
|
||||||
|
│ │ Skill │ │ Invoice │ │ StaffRating │ │
|
||||||
|
│ │ SkillCat │ │ InvoiceItem │ │ PenaltyLog │ │
|
||||||
|
│ │ StaffSkill │ │ InvDecline │ │ BizStaffPref│ │
|
||||||
|
│ │ Certificate │ │ StaffPayment│ │ │ │
|
||||||
|
│ │ SkillKit │ │ │ │ │ │
|
||||||
|
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||||||
|
│ │
|
||||||
|
│ ┌─────────────┐ ┌─────────────┐ │
|
||||||
|
│ │ STAFF │ │ SUPPORT │ │
|
||||||
|
│ │ PROFILE │ │ CONFIG │ │
|
||||||
|
│ ├─────────────┤ ├─────────────┤ │
|
||||||
|
│ │ EmergencyC │ │ Addon │ │
|
||||||
|
│ │ BankAccount │ │ Tag │ │
|
||||||
|
│ │ Accessibl │ │ Media │ │
|
||||||
|
│ │ Schedule │ │ WorkingArea │ │
|
||||||
|
│ └─────────────┘ └─────────────┘ │
|
||||||
|
│ │
|
||||||
|
└────────────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.2 Key Entity Definitions
|
||||||
|
|
||||||
|
#### User & Authentication
|
||||||
|
|
||||||
|
| Entity | Description | Key Fields |
|
||||||
|
|--------|-------------|------------|
|
||||||
|
| **User** | Base auth entity (Firebase) | `id`, `email`, `phone`, `role` |
|
||||||
|
| **Staff** | Worker profile | `auth_provider_id`, `name`, `email`, `phone`, `status`, `address`, `avatar`, `live_photo` |
|
||||||
|
| **Membership** | Polymorphic org membership | `user_id`, `memberable_id`, `memberable_type`, `role` |
|
||||||
|
|
||||||
|
**Staff Status Flow:**
|
||||||
|
```
|
||||||
|
registered → pending → completed_profile → verified → [active | blocked | inactive]
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Business & Organization
|
||||||
|
|
||||||
|
| Entity | Description | Key Fields |
|
||||||
|
|--------|-------------|------------|
|
||||||
|
| **Business** | Client company | `name`, `registration`, `status`, `avatar` |
|
||||||
|
| **BusinessSetting** | Payroll config | `prefix`, `overtime`, `clock_in`, `clock_out` |
|
||||||
|
| **Hub** | Branch location | `business_id`, `name`, `address`, `status` |
|
||||||
|
| **HubDepartment** | Dept within hub | `hub_id`, `name` |
|
||||||
|
|
||||||
|
#### Events & Shifts
|
||||||
|
|
||||||
|
| Entity | Description | Key Fields |
|
||||||
|
|--------|-------------|------------|
|
||||||
|
| **Event** | Job posting | `business_id`, `hub_id`, `name`, `date`, `status`, `contract_type` |
|
||||||
|
| **EventShift** | Work session | `event_id`, `name`, `address` |
|
||||||
|
| **EventShiftPosition** | Job opening | `shift_id`, `skill_id`, `count`, `rate`, `start_time`, `end_time`, `break` |
|
||||||
|
| **EventShiftPositionStaff** | Assignment | `staff_id`, `position_id`, `status`, `clock_in`, `clock_out` |
|
||||||
|
|
||||||
|
**Event Status Flow:**
|
||||||
|
```
|
||||||
|
draft → pending → assigned → confirmed → active → finished → completed → closed
|
||||||
|
↘ under_review
|
||||||
|
```
|
||||||
|
|
||||||
|
**Assignment Status Flow:**
|
||||||
|
```
|
||||||
|
assigned → confirmed → ongoing → completed
|
||||||
|
↘ decline_by_staff → [penalty logged]
|
||||||
|
↘ canceled_by_staff → [penalty logged]
|
||||||
|
↘ no_showed → [penalty logged]
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Skills & Certifications
|
||||||
|
|
||||||
|
| Entity | Description | Key Fields |
|
||||||
|
|--------|-------------|------------|
|
||||||
|
| **Skill** | Job category | `category_id`, `name`, `price` |
|
||||||
|
| **StaffSkill** | Worker qualification | `staff_id`, `skill_id`, `level`, `experience`, `status` |
|
||||||
|
| **Certificate** | Required credential | `name`, `required` |
|
||||||
|
| **SkillKit** | Uniform/equipment req | `skill_id`, `name`, `is_required`, `type` |
|
||||||
|
|
||||||
|
**Skill Levels:** `beginner` | `skilled` | `professional`
|
||||||
|
|
||||||
|
#### Financial & Payroll
|
||||||
|
|
||||||
|
| Entity | Description | Key Fields |
|
||||||
|
|--------|-------------|------------|
|
||||||
|
| **Invoice** | Business bill | `event_id`, `business_id`, `status`, `total`, `work_amount`, `addons_amount` |
|
||||||
|
| **InvoiceItem** | Line item | `invoice_id`, `staff_id`, `work_hours`, `rate`, `amounts` |
|
||||||
|
| **StaffPayment** | Worker payout | `staff_id`, `assignment_id`, `amount`, `status`, `paid_at` |
|
||||||
|
|
||||||
|
**Invoice Status Flow:**
|
||||||
|
```
|
||||||
|
open → disputed → resolved → verified → paid/reconciled
|
||||||
|
↘ overdue
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.3 Core Business Workflows
|
||||||
|
|
||||||
|
#### Workflow 1: Event Lifecycle
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
sequenceDiagram
|
||||||
|
participant Client as Client App
|
||||||
|
participant API as Backend API
|
||||||
|
participant Admin as Admin
|
||||||
|
participant Staff as Worker App
|
||||||
|
|
||||||
|
Note over Client,API: 1. Event Creation
|
||||||
|
Client->>API: Create Event with Shifts & Positions
|
||||||
|
API-->>Client: Event Created (Draft)
|
||||||
|
Client->>API: Publish Event
|
||||||
|
API-->>Client: Event Published
|
||||||
|
|
||||||
|
opt 2. Staff Assignment (Optional)
|
||||||
|
Note over Admin,API: Optional Staff Assignment
|
||||||
|
Admin->>API: Assign Staff to Shift
|
||||||
|
API-->>Admin: Assignment Confirmed
|
||||||
|
API->>Staff: Notification: New Shift
|
||||||
|
end
|
||||||
|
|
||||||
|
Note over Staff,API: 3. Shift Acceptance
|
||||||
|
Staff->>API: Accept Shift
|
||||||
|
API-->>Staff: Shift Confirmed
|
||||||
|
|
||||||
|
Note over Client,Staff: 4. Day of Event
|
||||||
|
Client->>Client: Generate QR Code
|
||||||
|
Staff->>Staff: Scan QR Code
|
||||||
|
Staff->>API: Clock In
|
||||||
|
Staff->>API: Clock Out
|
||||||
|
|
||||||
|
Note over Client,API: 5. Post-Event
|
||||||
|
Client->>API: Rate Staff
|
||||||
|
API->>API: Generate Invoice
|
||||||
|
Client->>API: Approve Invoice
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Workflow 2: Staff Onboarding
|
||||||
|
|
||||||
|
```
|
||||||
|
1. Registration (Firebase Phone Auth)
|
||||||
|
├── Create Staff record (status: registered)
|
||||||
|
└── Profile created with auth_provider_id
|
||||||
|
|
||||||
|
2. Profile Completion
|
||||||
|
├── Personal info (name, email, address)
|
||||||
|
├── Avatar upload
|
||||||
|
├── Emergency contacts
|
||||||
|
└── Bank account details
|
||||||
|
|
||||||
|
3. Skills Declaration
|
||||||
|
├── Add skills with level/experience
|
||||||
|
└── Status: pending → verified (admin)
|
||||||
|
|
||||||
|
4. Certification Upload
|
||||||
|
├── Upload certificates
|
||||||
|
└── Status: pending → verified (admin)
|
||||||
|
|
||||||
|
5. Equipment Confirmation
|
||||||
|
├── Confirm uniforms per skill
|
||||||
|
├── Confirm equipment per skill
|
||||||
|
└── Upload photos as proof
|
||||||
|
|
||||||
|
6. Profile Submission
|
||||||
|
├── Complete verification checklist
|
||||||
|
└── Status: completed_profile → verified
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Workflow 3: Payroll Calculation
|
||||||
|
|
||||||
|
```
|
||||||
|
Work Hours = (clock_out - clock_in) - break_duration
|
||||||
|
|
||||||
|
Overtime Rules:
|
||||||
|
├── Regular Hours (1x): hours <= 8
|
||||||
|
├── Overtime Hours (1.5x): 8 < hours <= 10
|
||||||
|
└── Doubletime Hours (2x): hours > 10
|
||||||
|
|
||||||
|
Payment = (regular_hours × rate × 1.0)
|
||||||
|
+ (overtime_hours × rate × 1.5)
|
||||||
|
+ (doubletime_hours × rate × 2.0)
|
||||||
|
+ addons_amount
|
||||||
|
```
|
||||||
|
|
||||||
|
You must:
|
||||||
|
1. Create domain entities for ALL KROW entities provided
|
||||||
|
2. Group entities by logical folders
|
||||||
|
3. Use immutable models
|
||||||
|
4. Do NOT add JSON, serialization, or Firebase annotations
|
||||||
|
5. Do NOT add business logic
|
||||||
|
6. Use enums for all status flows
|
||||||
|
7. Add Doc comments for readability of the code.
|
||||||
|
|
||||||
|
Entities MUST match:
|
||||||
|
- Names
|
||||||
|
- Fields
|
||||||
|
- Status flows
|
||||||
|
|
||||||
|
Include:
|
||||||
|
- Enums for status flows
|
||||||
|
- Value objects where appropriate
|
||||||
|
- Clear folder structure
|
||||||
|
|
||||||
|
Exclude:
|
||||||
|
- DTOs
|
||||||
|
- Repositories
|
||||||
|
- Firebase logic
|
||||||
|
- Validation logic
|
||||||
|
|
||||||
|
Create packages/domain/lib/domain.dart (barrel file)
|
||||||
|
This file must export ALL entities and enums.
|
||||||
|
|
||||||
|
All other packages will import ONLY:
|
||||||
|
import 'package:domain/domain.dart';
|
||||||
|
|
||||||
|
Must follow archtiecture principles defined in:
|
||||||
|
- docs/01-architecture-principles.md
|
||||||
|
|
||||||
|
Must Follow Agent rules defined in:
|
||||||
|
- docs/02-agent-development-rules.md
|
||||||
|
|
||||||
|
Output:
|
||||||
|
- Folder structure
|
||||||
|
- Dart files
|
||||||
|
- Short explanation of grouping strategy
|
||||||
26
apps/mobile/ai_prompts/4-data-connect-mock.md
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
TASK: Create the data_connect package as a mockable abstraction layer.
|
||||||
|
|
||||||
|
You must:
|
||||||
|
1. Define abstract repositories for each domain group
|
||||||
|
2. Create fake/mock implementations using in-memory data
|
||||||
|
3. Simulate async GraphQL-style behavior
|
||||||
|
4. Ensure replaceability with real generated SDK later
|
||||||
|
|
||||||
|
Rules:
|
||||||
|
- No Firebase imports
|
||||||
|
- No HTTP
|
||||||
|
- No direct entity mutation
|
||||||
|
- Return domain entities ONLY
|
||||||
|
|
||||||
|
Must follow archtiecture principles defined in:
|
||||||
|
- docs/01-architecture-principles.md
|
||||||
|
|
||||||
|
Must Follow Agent rules defined in:
|
||||||
|
- docs/02-agent-development-rules.md
|
||||||
|
|
||||||
|
Include:
|
||||||
|
- Interfaces
|
||||||
|
- Fake implementations
|
||||||
|
- Clear TODO markers for real SDK replacement
|
||||||
|
|
||||||
|
This package must compile and be dependency-safe.
|
||||||
23
apps/mobile/ai_prompts/5-match-to-design-system.md
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
Task is to reafactor an existing Flutter page so that it fully complies with the design system defined in:
|
||||||
|
- apps/mobile/docs/03-design-system-usage.md
|
||||||
|
|
||||||
|
## 📍 TARGET PAGE
|
||||||
|
|
||||||
|
File to refactor the widgets in:
|
||||||
|
|
||||||
|
- apps/mobile/packages/features/staff/profile_sections/compliance/tax_forms
|
||||||
|
/lib/src/presentation/pages
|
||||||
|
- apps/mobile/packages/features/staff/profile_sections/compliance/tax_forms
|
||||||
|
/lib/src/presentation/widgets
|
||||||
|
|
||||||
|
Example page to get inspiration as this page is fully complies with the design system guide mentioned above:
|
||||||
|
apps/mobile/packages/features/staff/authentication/lib/src/presentation/pages/profile_setup_page.dart
|
||||||
|
|
||||||
|
## 🎯 GOAL
|
||||||
|
|
||||||
|
Transform the existing page implementation so that it complies with the design guideline provieded.
|
||||||
|
|
||||||
|
## 🔒 STRICT RULES (NON-NEGOTIABLE)
|
||||||
|
While following the rules outlined in the document above you should also DO NOT remove or change existing functionality of the page, add doc comments and use named parameters in functions.
|
||||||
|
|
||||||
|
Proceed with the refactor now.
|
||||||
85
apps/mobile/ai_prompts/6-feature-development.md
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
# FEATURE EXECUTION WORKFLOW — Modular Feature Development
|
||||||
|
|
||||||
|
## APPLICATION TARGET
|
||||||
|
`apps/mobile/apps/staff`
|
||||||
|
|
||||||
|
## EXECUTION PLAN (MANDATORY 3-STEP PROCESS)
|
||||||
|
|
||||||
|
### Step 1: Prototype Implementation
|
||||||
|
- **Goal**: First move the entire UI(pages and widgets) and logic from the prototype into the new feature package without changes. The page in the new package should be an one-one of the POC page.
|
||||||
|
- **Action**: Create the package in the folder structure under `apps/mobile/packages/features/[domain]/[feature_name]`.
|
||||||
|
- **References**: Use the specified prototypes as the primary source of truth for UI/UX, logic and business logic.
|
||||||
|
- **MANDATORY**: The **Layout** and **Wireframing** from the prototype should stay **EXACTLY** as they are. Do not re-design the UX or move elements around.
|
||||||
|
- **Note**: Pages should end with `_page.dart` instead of `_screen.dart`.
|
||||||
|
|
||||||
|
### Step 2: Architecture & Clean Code Refactor
|
||||||
|
- **Goal**: Align the prototype code with the project's long-term standards.
|
||||||
|
- **Rules**:
|
||||||
|
- Follow `apps/mobile/docs/01-architecture-principles.md` (BLoC, Domain-Driven, Repository pattern).
|
||||||
|
- Move the logic into blocs, domain and data. Use only the `apps/mobile/packages/data_connect/lib/src/mocks` to retrive / add data. This should happen via the data layer (presentation (ui -> bloc) -> domain -> data).
|
||||||
|
- Apply Clean Code: Meaningful names, one responsibility per class, small methods. Add doc comments to the files, functions for better readability.
|
||||||
|
- No magic strings inside business logic.
|
||||||
|
|
||||||
|
### Step 3: Localization & Navigation Finalization
|
||||||
|
- **Goal**: Centralize resources and decouple routing.
|
||||||
|
- **Mandatory Requirements**:
|
||||||
|
1. **Centralized Localization**:
|
||||||
|
- Extract ALL strings to `apps/mobile/packages/core_localization/lib/src/l10n/en.i18n.json` (and `es`).
|
||||||
|
- Use a unique namespace for the feature (e.g., `t.feature_name.sub_section.key`).
|
||||||
|
- Remove `slang` dependencies from the feature; re-export `core_localization` instead.
|
||||||
|
2. **Typed Navigation**:
|
||||||
|
- Create `lib/src/presentation/navigation/[feature_name]_navigator.dart`.
|
||||||
|
- Implement an extension on `IModularNavigator` for all feature-specific routes.
|
||||||
|
- Replace all `Modular.to.pushNamed('/path')` with typed methods like `Modular.to.pushFeaturePage()`.
|
||||||
|
|
||||||
|
### Step 4: Design Matching & Design System Alignment
|
||||||
|
- **Goal**: Ensure the visual identity matches the Design System perfectly while maintaining the prototype's layout.
|
||||||
|
- **Action**: Follow `apps/mobile/docs/03-design-system-usage.md` (Section 10: POC → Themed workflow).
|
||||||
|
- **Mandatory Requirements**:
|
||||||
|
- **Colors**: Replace all hex codes or raw colors with `UiColors`.
|
||||||
|
- **Typography**: Replace all manual `TextStyle` with `UiTypography`.
|
||||||
|
- **Spacing/Radius**: Replace all magic numbers with `UiConstants`.
|
||||||
|
- **Icons**: Use `UiIcons` exclusively.
|
||||||
|
- **Policy**: Maintain the prototype's layout structure while upgrading the "atoms" and "molecules" to the Design System tokens.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# FEATURE SCOPE — Staff shifts Screen
|
||||||
|
|
||||||
|
This feature implements the **staff shifts screen** for the **Mobile Staff application**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## PROTOTYPE REFERENCES (SOURCE OF TRUTH)
|
||||||
|
|
||||||
|
* `apps/mobile/prototypes/staff_mobile_application/lib/screens/worker/payments_screen.dart`
|
||||||
|
|
||||||
|
## WHERE THE FEATURE SHOULD RESIDE
|
||||||
|
This feature should reside in the feature `apps/mobile/packages/features/staff/payments`.
|
||||||
|
|
||||||
|
## ARCHITECTURE CONSTRAINTS (NON-NEGOTIABLE)
|
||||||
|
|
||||||
|
You MUST strictly follow:
|
||||||
|
1. `apps/mobile/docs/01-architecture-principles.md`
|
||||||
|
2. `apps/mobile/docs/02-agent-development-rules.md`
|
||||||
|
3. `apps/mobile/docs/03-design-system-usage.md`
|
||||||
|
4. `MEMORY[user_global]` (Clean Code & architectural decisions)
|
||||||
|
|
||||||
|
Violations must be **explicitly reported**, never silently ignored.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## REFERENCE IMPLEMENTATION
|
||||||
|
|
||||||
|
Use:
|
||||||
|
|
||||||
|
```
|
||||||
|
apps/mobile/packages/features/staff/authentication
|
||||||
|
```
|
||||||
|
|
||||||
|
as the **gold standard** for:
|
||||||
|
|
||||||
|
* Feature structure
|
||||||
|
* Navigation pattern
|
||||||
|
* Localization strategy
|
||||||
|
* Design system integration
|
||||||
6
apps/mobile/ai_prompts/6.5-feature-broke-into-clean.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
for the "apps/mobile/packages/features/staff/payments" feature
|
||||||
|
|
||||||
|
- Follow apps/mobile/docs/01-architecture-principles.md (BLoC, Domain-Driven, Repository pattern).
|
||||||
|
- Move the logic into blocs, domain and data. Use only the apps/mobile/packages/data_connect/lib/src/mocks to retrive / add data. This should happen via the data layer (presentation (ui -> bloc) -> domain -> data).
|
||||||
|
- Apply Clean Code: Meaningful names, one responsibility per class, small methods. Add doc comments to the files, functions for better readability.
|
||||||
|
No magic strings inside business logic.
|
||||||
66
apps/mobile/ai_prompts/7-architecutre-fix.md
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
Task is to refactor an existing Flutter package so that it fully complies with the architecture rules defined in:
|
||||||
|
|
||||||
|
* `apps/mobile/docs/01-architecture-principles.md`
|
||||||
|
|
||||||
|
## TARGET PAGE
|
||||||
|
|
||||||
|
Package to refactor:
|
||||||
|
|
||||||
|
```
|
||||||
|
apps/mobile/packages/features/staff/shifts
|
||||||
|
```
|
||||||
|
|
||||||
|
Reference feature that already follows the architecture correctly (this is the GOLD STANDARD):
|
||||||
|
|
||||||
|
```
|
||||||
|
apps/mobile/packages/features/staff/authentication
|
||||||
|
```
|
||||||
|
|
||||||
|
## GOAL
|
||||||
|
|
||||||
|
Refactor the feature so that it strictly follows **KROW Clean Architecture principles**, while preserving **all existing behavior and UI output**.
|
||||||
|
|
||||||
|
The result must be structurally correct, testable, and aligned with feature-level responsibilities.
|
||||||
|
|
||||||
|
## STRICT RULES (NON-NEGOTIABLE)
|
||||||
|
|
||||||
|
You MUST follow **all** rules defined in:
|
||||||
|
|
||||||
|
* `apps/mobile/docs/01-architecture-principles.md`
|
||||||
|
|
||||||
|
Additionally, enforce the following:
|
||||||
|
|
||||||
|
### Architecture Rules
|
||||||
|
|
||||||
|
* The pages **MUST remain inside the feature package**
|
||||||
|
* The pages **MUST NOT import other features**
|
||||||
|
* Business logic **MUST NOT exist inside the page**
|
||||||
|
* State handling **MUST be moved to a Bloc/Cubit or external widget**
|
||||||
|
* Use cases **MUST live in `domain/`**
|
||||||
|
* Repository access **MUST go through abstractions**
|
||||||
|
|
||||||
|
### Presentation Rules
|
||||||
|
|
||||||
|
* Use `StatelessWidget` for pages
|
||||||
|
* If state is required:
|
||||||
|
* Move it to a Bloc/Cubit, OR
|
||||||
|
* Extract it into a separate widget file
|
||||||
|
* Use named parameters
|
||||||
|
* Add clear doc comments where structure or intent is non-obvious
|
||||||
|
|
||||||
|
### Safety Rules
|
||||||
|
|
||||||
|
* ❌ Do NOT remove existing functionality
|
||||||
|
* ❌ Do NOT change user-facing behavior
|
||||||
|
* ❌ Do NOT introduce new dependencies
|
||||||
|
* ❌ Do NOT break modular boundaries
|
||||||
|
|
||||||
|
## EXPECTED OUTPUT
|
||||||
|
|
||||||
|
* A refactored page that:
|
||||||
|
* Fully complies with `apps/mobile/docs/01-architecture-principles.md`
|
||||||
|
* Has clean separation of concerns
|
||||||
|
* Is easy to reason about and extend
|
||||||
|
* Any required supporting files (Bloc, use case, widget extraction) created **inside the same feature**
|
||||||
|
|
||||||
|
Proceed with the refactor now.
|
||||||
88
apps/mobile/ai_prompts/8-data-domain-layer-fix.md
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
Task is to refactor the **domain and data layers** of an existing feature so that they fully comply with the architecture rules defined in:
|
||||||
|
|
||||||
|
* `apps/mobile/docs/01-architecture-principles.md`
|
||||||
|
|
||||||
|
## 📍 TARGET FEATURE
|
||||||
|
|
||||||
|
Feature to refactor:
|
||||||
|
|
||||||
|
```
|
||||||
|
apps/mobile/packages/features/staff/payments
|
||||||
|
```
|
||||||
|
|
||||||
|
Files exist in:
|
||||||
|
|
||||||
|
```
|
||||||
|
lib/src/domain/
|
||||||
|
lib/src/data/
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🏆 GOLD STANDARD REFERENCE
|
||||||
|
|
||||||
|
Use the following feature as the **gold standard implementation** for structure, responsibility split, and dependency direction:
|
||||||
|
|
||||||
|
```
|
||||||
|
apps/mobile/packages/features/staff/authentication
|
||||||
|
```
|
||||||
|
|
||||||
|
Follow its patterns for:
|
||||||
|
|
||||||
|
* Repository interfaces
|
||||||
|
* Use case design
|
||||||
|
* Data layer delegation
|
||||||
|
* Interaction with `apps/mobile/packages/data_connect`
|
||||||
|
|
||||||
|
## 🎯 GOAL
|
||||||
|
|
||||||
|
Refactor the feature so that its **Domain** and **Data** layers strictly follow **KROW Clean Architecture** as defined in `apps/mobile/docs/01-architecture-principles.md`.
|
||||||
|
|
||||||
|
The feature must rely on **shared Domain entities** and must delegate all data access through `apps/mobile/packages/data_connect`.
|
||||||
|
|
||||||
|
## STRICT RULES (NON-NEGOTIABLE)
|
||||||
|
|
||||||
|
You MUST follow **all rules defined in**:
|
||||||
|
|
||||||
|
* `apps/mobile/docs/01-architecture-principles.md`
|
||||||
|
|
||||||
|
In particular, ensure that:
|
||||||
|
|
||||||
|
* Domain uses **only entities from**:
|
||||||
|
|
||||||
|
```
|
||||||
|
apps/mobile/packages/domain/lib/src/entities
|
||||||
|
```
|
||||||
|
* Feature-level domain models are removed
|
||||||
|
* Repository interfaces live in the Domain layer
|
||||||
|
* Repository implementations live in the Data layer
|
||||||
|
* Domain does NOT return concrete data objects
|
||||||
|
* Usecases in the domain layer must be extended from the `apps/mobile/packages/core/lib/src/domain/usecases/usecase.dart`.
|
||||||
|
* If there are arguments in the usecases, they must be extended from the `apps/mobile/packages/core/lib/src/domain/arguments/usecase_argument.dart`. Example usecase is given below
|
||||||
|
- `apps/mobile/packages/features/staff/authentication/lib/src/domain/usecases/verify_otp_usecase.dart`
|
||||||
|
* Data layer does NOT contain business logic and not create objects only call the `apps/mobile/packages/data_connect`.
|
||||||
|
* All data access flows through `apps/mobile/packages/data_connect`
|
||||||
|
|
||||||
|
## DOCUMENTATION
|
||||||
|
|
||||||
|
* Add clear **doc comments** to all files you modify
|
||||||
|
* Document:
|
||||||
|
* Purpose of the file
|
||||||
|
* Role of the class or interface in the architecture
|
||||||
|
|
||||||
|
## SAFETY GUARANTEES
|
||||||
|
|
||||||
|
* Do NOT change existing behavior
|
||||||
|
* Do NOT break presentation layer contracts
|
||||||
|
* Do NOT bypass `apps/mobile/packages/data_connect`
|
||||||
|
|
||||||
|
## EXPECTED OUTPUT
|
||||||
|
|
||||||
|
* Domain layer aligned with `apps/mobile/docs/01-architecture-principles.md`
|
||||||
|
* Data layer aligned with `apps/mobile/docs/01-architecture-principles.md`
|
||||||
|
* Structure and patterns consistent with:
|
||||||
|
|
||||||
|
```
|
||||||
|
apps/mobile/packages/features/staff/authentication
|
||||||
|
```
|
||||||
|
* Clean, documented, and compliant implementation
|
||||||
|
|
||||||
|
Proceed with the refactor now.
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package io.flutter.plugins;
|
||||||
|
|
||||||
|
import androidx.annotation.Keep;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import io.flutter.Log;
|
||||||
|
|
||||||
|
import io.flutter.embedding.engine.FlutterEngine;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generated file. Do not edit.
|
||||||
|
* This file is generated by the Flutter tool based on the
|
||||||
|
* plugins that support the Android platform.
|
||||||
|
*/
|
||||||
|
@Keep
|
||||||
|
public final class GeneratedPluginRegistrant {
|
||||||
|
private static final String TAG = "GeneratedPluginRegistrant";
|
||||||
|
public static void registerWith(@NonNull FlutterEngine flutterEngine) {
|
||||||
|
try {
|
||||||
|
flutterEngine.getPlugins().add(new io.flutter.plugins.firebase.appcheck.FlutterFirebaseAppCheckPlugin());
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "Error registering plugin firebase_app_check, io.flutter.plugins.firebase.appcheck.FlutterFirebaseAppCheckPlugin", e);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
flutterEngine.getPlugins().add(new io.flutter.plugins.firebase.auth.FlutterFirebaseAuthPlugin());
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "Error registering plugin firebase_auth, io.flutter.plugins.firebase.auth.FlutterFirebaseAuthPlugin", e);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
flutterEngine.getPlugins().add(new io.flutter.plugins.firebase.core.FlutterFirebaseCorePlugin());
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "Error registering plugin firebase_core, io.flutter.plugins.firebase.core.FlutterFirebaseCorePlugin", e);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
flutterEngine.getPlugins().add(new io.flutter.plugins.pathprovider.PathProviderPlugin());
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "Error registering plugin path_provider_android, io.flutter.plugins.pathprovider.PathProviderPlugin", e);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
flutterEngine.getPlugins().add(new io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin());
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "Error registering plugin shared_preferences_android, io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin", e);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
flutterEngine.getPlugins().add(new io.flutter.plugins.urllauncher.UrlLauncherPlugin());
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "Error registering plugin url_launcher_android, io.flutter.plugins.urllauncher.UrlLauncherPlugin", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
apps/mobile/apps/client/android/gradle/wrapper/gradle-wrapper.jar
vendored
Executable file
160
apps/mobile/apps/client/android/gradlew
vendored
Executable file
@@ -0,0 +1,160 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
##
|
||||||
|
## Gradle start up script for UN*X
|
||||||
|
##
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS=""
|
||||||
|
|
||||||
|
APP_NAME="Gradle"
|
||||||
|
APP_BASE_NAME=`basename "$0"`
|
||||||
|
|
||||||
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
|
MAX_FD="maximum"
|
||||||
|
|
||||||
|
warn ( ) {
|
||||||
|
echo "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
die ( ) {
|
||||||
|
echo
|
||||||
|
echo "$*"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# OS specific support (must be 'true' or 'false').
|
||||||
|
cygwin=false
|
||||||
|
msys=false
|
||||||
|
darwin=false
|
||||||
|
case "`uname`" in
|
||||||
|
CYGWIN* )
|
||||||
|
cygwin=true
|
||||||
|
;;
|
||||||
|
Darwin* )
|
||||||
|
darwin=true
|
||||||
|
;;
|
||||||
|
MINGW* )
|
||||||
|
msys=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Attempt to set APP_HOME
|
||||||
|
# Resolve links: $0 may be a link
|
||||||
|
PRG="$0"
|
||||||
|
# Need this for relative symlinks.
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG=`dirname "$PRG"`"/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
SAVED="`pwd`"
|
||||||
|
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||||
|
APP_HOME="`pwd -P`"
|
||||||
|
cd "$SAVED" >/dev/null
|
||||||
|
|
||||||
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
# Determine the Java command to use to start the JVM.
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||||
|
else
|
||||||
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
|
fi
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD="java"
|
||||||
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Increase the maximum file descriptors if we can.
|
||||||
|
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||||
|
MAX_FD_LIMIT=`ulimit -H -n`
|
||||||
|
if [ $? -eq 0 ] ; then
|
||||||
|
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||||
|
MAX_FD="$MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
ulimit -n $MAX_FD
|
||||||
|
if [ $? -ne 0 ] ; then
|
||||||
|
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Darwin, add options to specify how the application appears in the dock
|
||||||
|
if $darwin; then
|
||||||
|
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin, switch paths to Windows format before running java
|
||||||
|
if $cygwin ; then
|
||||||
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
|
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||||
|
|
||||||
|
# We build the pattern for arguments to be converted via cygpath
|
||||||
|
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||||
|
SEP=""
|
||||||
|
for dir in $ROOTDIRSRAW ; do
|
||||||
|
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||||
|
SEP="|"
|
||||||
|
done
|
||||||
|
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||||
|
# Add a user-defined pattern to the cygpath arguments
|
||||||
|
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||||
|
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||||
|
fi
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
i=0
|
||||||
|
for arg in "$@" ; do
|
||||||
|
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||||
|
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||||
|
|
||||||
|
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||||
|
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||||
|
else
|
||||||
|
eval `echo args$i`="\"$arg\""
|
||||||
|
fi
|
||||||
|
i=$((i+1))
|
||||||
|
done
|
||||||
|
case $i in
|
||||||
|
(0) set -- ;;
|
||||||
|
(1) set -- "$args0" ;;
|
||||||
|
(2) set -- "$args0" "$args1" ;;
|
||||||
|
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
|
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
|
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
|
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
|
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
|
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
|
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||||
|
function splitJvmOpts() {
|
||||||
|
JVM_OPTS=("$@")
|
||||||
|
}
|
||||||
|
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||||
|
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||||
|
|
||||||
|
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
||||||
90
apps/mobile/apps/client/android/gradlew.bat
vendored
Executable file
@@ -0,0 +1,90 @@
|
|||||||
|
@if "%DEBUG%" == "" @echo off
|
||||||
|
@rem ##########################################################################
|
||||||
|
@rem
|
||||||
|
@rem Gradle startup script for Windows
|
||||||
|
@rem
|
||||||
|
@rem ##########################################################################
|
||||||
|
|
||||||
|
@rem Set local scope for the variables with windows NT shell
|
||||||
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
set DEFAULT_JVM_OPTS=
|
||||||
|
|
||||||
|
set DIRNAME=%~dp0
|
||||||
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
|
set APP_BASE_NAME=%~n0
|
||||||
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Find java.exe
|
||||||
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
|
set JAVA_EXE=java.exe
|
||||||
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
|
if "%ERRORLEVEL%" == "0" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:findJavaFromJavaHome
|
||||||
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
|
if exist "%JAVA_EXE%" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:init
|
||||||
|
@rem Get command-line arguments, handling Windowz variants
|
||||||
|
|
||||||
|
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||||
|
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||||
|
|
||||||
|
:win9xME_args
|
||||||
|
@rem Slurp the command line arguments.
|
||||||
|
set CMD_LINE_ARGS=
|
||||||
|
set _SKIP=2
|
||||||
|
|
||||||
|
:win9xME_args_slurp
|
||||||
|
if "x%~1" == "x" goto execute
|
||||||
|
|
||||||
|
set CMD_LINE_ARGS=%*
|
||||||
|
goto execute
|
||||||
|
|
||||||
|
:4NT_args
|
||||||
|
@rem Get arguments from the 4NT Shell from JP Software
|
||||||
|
set CMD_LINE_ARGS=%$
|
||||||
|
|
||||||
|
:execute
|
||||||
|
@rem Setup the command line
|
||||||
|
|
||||||
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
|
@rem Execute Gradle
|
||||||
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||||
|
|
||||||
|
:end
|
||||||
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||||
|
|
||||||
|
:fail
|
||||||
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
|
rem the _cmd.exe /c_ return code!
|
||||||
|
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||||
|
exit /b 1
|
||||||
|
|
||||||
|
:mainEnd
|
||||||
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
||||||
|
:omega
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
#
|
||||||
|
# Generated file, do not edit.
|
||||||
|
#
|
||||||
|
|
||||||
|
import lldb
|
||||||
|
|
||||||
|
def handle_new_rx_page(frame: lldb.SBFrame, bp_loc, extra_args, intern_dict):
|
||||||
|
"""Intercept NOTIFY_DEBUGGER_ABOUT_RX_PAGES and touch the pages."""
|
||||||
|
base = frame.register["x0"].GetValueAsAddress()
|
||||||
|
page_len = frame.register["x1"].GetValueAsUnsigned()
|
||||||
|
|
||||||
|
# Note: NOTIFY_DEBUGGER_ABOUT_RX_PAGES will check contents of the
|
||||||
|
# first page to see if handled it correctly. This makes diagnosing
|
||||||
|
# misconfiguration (e.g. missing breakpoint) easier.
|
||||||
|
data = bytearray(page_len)
|
||||||
|
data[0:8] = b'IHELPED!'
|
||||||
|
|
||||||
|
error = lldb.SBError()
|
||||||
|
frame.GetThread().GetProcess().WriteMemory(base, data, error)
|
||||||
|
if not error.Success():
|
||||||
|
print(f'Failed to write into {base}[+{page_len}]', error)
|
||||||
|
return
|
||||||
|
|
||||||
|
def __lldb_init_module(debugger: lldb.SBDebugger, _):
|
||||||
|
target = debugger.GetDummyTarget()
|
||||||
|
# Caveat: must use BreakpointCreateByRegEx here and not
|
||||||
|
# BreakpointCreateByName. For some reasons callback function does not
|
||||||
|
# get carried over from dummy target for the later.
|
||||||
|
bp = target.BreakpointCreateByRegex("^NOTIFY_DEBUGGER_ABOUT_RX_PAGES$")
|
||||||
|
bp.SetScriptCallbackFunction('{}.handle_new_rx_page'.format(__name__))
|
||||||
|
bp.SetAutoContinue(True)
|
||||||
|
print("-- LLDB integration loaded --")
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
#
|
||||||
|
# Generated file, do not edit.
|
||||||
|
#
|
||||||
|
|
||||||
|
command script import --relative-to-command-file flutter_lldb_helper.py
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// Generated file. Do not edit.
|
||||||
|
//
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
|
||||||
|
#ifndef GeneratedPluginRegistrant_h
|
||||||
|
#define GeneratedPluginRegistrant_h
|
||||||
|
|
||||||
|
#import <Flutter/Flutter.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface GeneratedPluginRegistrant : NSObject
|
||||||
|
+ (void)registerWithRegistry:(NSObject<FlutterPluginRegistry>*)registry;
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
|
#endif /* GeneratedPluginRegistrant_h */
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
//
|
||||||
|
// Generated file. Do not edit.
|
||||||
|
//
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
|
||||||
|
#import "GeneratedPluginRegistrant.h"
|
||||||
|
|
||||||
|
#if __has_include(<firebase_app_check/FLTFirebaseAppCheckPlugin.h>)
|
||||||
|
#import <firebase_app_check/FLTFirebaseAppCheckPlugin.h>
|
||||||
|
#else
|
||||||
|
@import firebase_app_check;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __has_include(<firebase_auth/FLTFirebaseAuthPlugin.h>)
|
||||||
|
#import <firebase_auth/FLTFirebaseAuthPlugin.h>
|
||||||
|
#else
|
||||||
|
@import firebase_auth;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __has_include(<firebase_core/FLTFirebaseCorePlugin.h>)
|
||||||
|
#import <firebase_core/FLTFirebaseCorePlugin.h>
|
||||||
|
#else
|
||||||
|
@import firebase_core;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __has_include(<shared_preferences_foundation/SharedPreferencesPlugin.h>)
|
||||||
|
#import <shared_preferences_foundation/SharedPreferencesPlugin.h>
|
||||||
|
#else
|
||||||
|
@import shared_preferences_foundation;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __has_include(<url_launcher_ios/URLLauncherPlugin.h>)
|
||||||
|
#import <url_launcher_ios/URLLauncherPlugin.h>
|
||||||
|
#else
|
||||||
|
@import url_launcher_ios;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@implementation GeneratedPluginRegistrant
|
||||||
|
|
||||||
|
+ (void)registerWithRegistry:(NSObject<FlutterPluginRegistry>*)registry {
|
||||||
|
[FLTFirebaseAppCheckPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTFirebaseAppCheckPlugin"]];
|
||||||
|
[FLTFirebaseAuthPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTFirebaseAuthPlugin"]];
|
||||||
|
[FLTFirebaseCorePlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTFirebaseCorePlugin"]];
|
||||||
|
[SharedPreferencesPlugin registerWithRegistrar:[registry registrarForPlugin:@"SharedPreferencesPlugin"]];
|
||||||
|
[URLLauncherPlugin registerWithRegistrar:[registry registrarForPlugin:@"URLLauncherPlugin"]];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
/Users/achinthaisuru/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
/Users/achinthaisuru/.pub-cache/hosted/pub.dev/shared_preferences_linux-2.4.1/
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
/Users/achinthaisuru/.pub-cache/hosted/pub.dev/url_launcher_linux-3.2.2/
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
// This is a generated file; do not edit or check into version control.
|
||||||
|
FLUTTER_ROOT=/Users/achinthaisuru/Documents/flutter
|
||||||
|
FLUTTER_APPLICATION_PATH=/Users/achinthaisuru/Documents/Github/krow-workforce/apps/mobile/apps/client
|
||||||
|
COCOAPODS_PARALLEL_CODE_SIGN=true
|
||||||
|
FLUTTER_BUILD_DIR=build
|
||||||
|
FLUTTER_BUILD_NAME=1.0.0
|
||||||
|
FLUTTER_BUILD_NUMBER=1
|
||||||
|
DART_OBFUSCATION=false
|
||||||
|
TRACK_WIDGET_CREATION=true
|
||||||
|
TREE_SHAKE_ICONS=false
|
||||||
|
PACKAGE_CONFIG=.dart_tool/package_config.json
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# This is a generated file; do not edit or check into version control.
|
||||||
|
export "FLUTTER_ROOT=/Users/achinthaisuru/Documents/flutter"
|
||||||
|
export "FLUTTER_APPLICATION_PATH=/Users/achinthaisuru/Documents/Github/krow-workforce/apps/mobile/apps/client"
|
||||||
|
export "COCOAPODS_PARALLEL_CODE_SIGN=true"
|
||||||
|
export "FLUTTER_BUILD_DIR=build"
|
||||||
|
export "FLUTTER_BUILD_NAME=1.0.0"
|
||||||
|
export "FLUTTER_BUILD_NUMBER=1"
|
||||||
|
export "DART_OBFUSCATION=false"
|
||||||
|
export "TRACK_WIDGET_CREATION=true"
|
||||||
|
export "TREE_SHAKE_ICONS=false"
|
||||||
|
export "PACKAGE_CONFIG=.dart_tool/package_config.json"
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
/Users/achinthaisuru/.pub-cache/hosted/pub.dev/firebase_auth-6.1.4/
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
/Users/achinthaisuru/.pub-cache/hosted/pub.dev/firebase_core-4.4.0/
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
/Users/achinthaisuru/.pub-cache/hosted/pub.dev/path_provider_windows-2.3.0/
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
/Users/achinthaisuru/.pub-cache/hosted/pub.dev/shared_preferences_windows-2.4.1/
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
/Users/achinthaisuru/.pub-cache/hosted/pub.dev/url_launcher_windows-3.1.5/
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package io.flutter.plugins;
|
||||||
|
|
||||||
|
import androidx.annotation.Keep;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import io.flutter.Log;
|
||||||
|
|
||||||
|
import io.flutter.embedding.engine.FlutterEngine;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generated file. Do not edit.
|
||||||
|
* This file is generated by the Flutter tool based on the
|
||||||
|
* plugins that support the Android platform.
|
||||||
|
*/
|
||||||
|
@Keep
|
||||||
|
public final class GeneratedPluginRegistrant {
|
||||||
|
private static final String TAG = "GeneratedPluginRegistrant";
|
||||||
|
public static void registerWith(@NonNull FlutterEngine flutterEngine) {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
#
|
||||||
|
# Generated file, do not edit.
|
||||||
|
#
|
||||||
|
|
||||||
|
import lldb
|
||||||
|
|
||||||
|
def handle_new_rx_page(frame: lldb.SBFrame, bp_loc, extra_args, intern_dict):
|
||||||
|
"""Intercept NOTIFY_DEBUGGER_ABOUT_RX_PAGES and touch the pages."""
|
||||||
|
base = frame.register["x0"].GetValueAsAddress()
|
||||||
|
page_len = frame.register["x1"].GetValueAsUnsigned()
|
||||||
|
|
||||||
|
# Note: NOTIFY_DEBUGGER_ABOUT_RX_PAGES will check contents of the
|
||||||
|
# first page to see if handled it correctly. This makes diagnosing
|
||||||
|
# misconfiguration (e.g. missing breakpoint) easier.
|
||||||
|
data = bytearray(page_len)
|
||||||
|
data[0:8] = b'IHELPED!'
|
||||||
|
|
||||||
|
error = lldb.SBError()
|
||||||
|
frame.GetThread().GetProcess().WriteMemory(base, data, error)
|
||||||
|
if not error.Success():
|
||||||
|
print(f'Failed to write into {base}[+{page_len}]', error)
|
||||||
|
return
|
||||||
|
|
||||||
|
def __lldb_init_module(debugger: lldb.SBDebugger, _):
|
||||||
|
target = debugger.GetDummyTarget()
|
||||||
|
# Caveat: must use BreakpointCreateByRegEx here and not
|
||||||
|
# BreakpointCreateByName. For some reasons callback function does not
|
||||||
|
# get carried over from dummy target for the later.
|
||||||
|
bp = target.BreakpointCreateByRegex("^NOTIFY_DEBUGGER_ABOUT_RX_PAGES$")
|
||||||
|
bp.SetScriptCallbackFunction('{}.handle_new_rx_page'.format(__name__))
|
||||||
|
bp.SetAutoContinue(True)
|
||||||
|
print("-- LLDB integration loaded --")
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
#
|
||||||
|
# Generated file, do not edit.
|
||||||
|
#
|
||||||
|
|
||||||
|
command script import --relative-to-command-file flutter_lldb_helper.py
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// Generated file. Do not edit.
|
||||||
|
//
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
|
||||||
|
#ifndef GeneratedPluginRegistrant_h
|
||||||
|
#define GeneratedPluginRegistrant_h
|
||||||
|
|
||||||
|
#import <Flutter/Flutter.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface GeneratedPluginRegistrant : NSObject
|
||||||
|
+ (void)registerWithRegistry:(NSObject<FlutterPluginRegistry>*)registry;
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
|
#endif /* GeneratedPluginRegistrant_h */
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
//
|
||||||
|
// Generated file. Do not edit.
|
||||||
|
//
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
|
||||||
|
#import "GeneratedPluginRegistrant.h"
|
||||||
|
|
||||||
|
@implementation GeneratedPluginRegistrant
|
||||||
|
|
||||||
|
+ (void)registerWithRegistry:(NSObject<FlutterPluginRegistry>*)registry {
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
// This is a generated file; do not edit or check into version control.
|
||||||
|
FLUTTER_ROOT=/Users/achinthaisuru/Documents/flutter
|
||||||
|
FLUTTER_APPLICATION_PATH=/Users/achinthaisuru/Documents/Github/krow-workforce/apps/mobile/apps/design_system_viewer
|
||||||
|
COCOAPODS_PARALLEL_CODE_SIGN=true
|
||||||
|
FLUTTER_BUILD_DIR=build
|
||||||
|
FLUTTER_BUILD_NAME=1.0.0
|
||||||
|
FLUTTER_BUILD_NUMBER=1
|
||||||
|
DART_OBFUSCATION=false
|
||||||
|
TRACK_WIDGET_CREATION=true
|
||||||
|
TREE_SHAKE_ICONS=false
|
||||||
|
PACKAGE_CONFIG=.dart_tool/package_config.json
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# This is a generated file; do not edit or check into version control.
|
||||||
|
export "FLUTTER_ROOT=/Users/achinthaisuru/Documents/flutter"
|
||||||
|
export "FLUTTER_APPLICATION_PATH=/Users/achinthaisuru/Documents/Github/krow-workforce/apps/mobile/apps/design_system_viewer"
|
||||||
|
export "COCOAPODS_PARALLEL_CODE_SIGN=true"
|
||||||
|
export "FLUTTER_BUILD_DIR=build"
|
||||||
|
export "FLUTTER_BUILD_NAME=1.0.0"
|
||||||
|
export "FLUTTER_BUILD_NUMBER=1"
|
||||||
|
export "DART_OBFUSCATION=false"
|
||||||
|
export "TRACK_WIDGET_CREATION=true"
|
||||||
|
export "TREE_SHAKE_ICONS=false"
|
||||||
|
export "PACKAGE_CONFIG=.dart_tool/package_config.json"
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package io.flutter.plugins;
|
||||||
|
|
||||||
|
import androidx.annotation.Keep;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import io.flutter.Log;
|
||||||
|
|
||||||
|
import io.flutter.embedding.engine.FlutterEngine;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generated file. Do not edit.
|
||||||
|
* This file is generated by the Flutter tool based on the
|
||||||
|
* plugins that support the Android platform.
|
||||||
|
*/
|
||||||
|
@Keep
|
||||||
|
public final class GeneratedPluginRegistrant {
|
||||||
|
private static final String TAG = "GeneratedPluginRegistrant";
|
||||||
|
public static void registerWith(@NonNull FlutterEngine flutterEngine) {
|
||||||
|
try {
|
||||||
|
flutterEngine.getPlugins().add(new io.flutter.plugins.firebase.appcheck.FlutterFirebaseAppCheckPlugin());
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "Error registering plugin firebase_app_check, io.flutter.plugins.firebase.appcheck.FlutterFirebaseAppCheckPlugin", e);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
flutterEngine.getPlugins().add(new io.flutter.plugins.firebase.auth.FlutterFirebaseAuthPlugin());
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "Error registering plugin firebase_auth, io.flutter.plugins.firebase.auth.FlutterFirebaseAuthPlugin", e);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
flutterEngine.getPlugins().add(new io.flutter.plugins.firebase.core.FlutterFirebaseCorePlugin());
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "Error registering plugin firebase_core, io.flutter.plugins.firebase.core.FlutterFirebaseCorePlugin", e);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
flutterEngine.getPlugins().add(new io.flutter.plugins.pathprovider.PathProviderPlugin());
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "Error registering plugin path_provider_android, io.flutter.plugins.pathprovider.PathProviderPlugin", e);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
flutterEngine.getPlugins().add(new io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin());
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "Error registering plugin shared_preferences_android, io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
apps/mobile/apps/staff/android/gradle/wrapper/gradle-wrapper.jar
vendored
Executable file
160
apps/mobile/apps/staff/android/gradlew
vendored
Executable file
@@ -0,0 +1,160 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
##
|
||||||
|
## Gradle start up script for UN*X
|
||||||
|
##
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS=""
|
||||||
|
|
||||||
|
APP_NAME="Gradle"
|
||||||
|
APP_BASE_NAME=`basename "$0"`
|
||||||
|
|
||||||
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
|
MAX_FD="maximum"
|
||||||
|
|
||||||
|
warn ( ) {
|
||||||
|
echo "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
die ( ) {
|
||||||
|
echo
|
||||||
|
echo "$*"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# OS specific support (must be 'true' or 'false').
|
||||||
|
cygwin=false
|
||||||
|
msys=false
|
||||||
|
darwin=false
|
||||||
|
case "`uname`" in
|
||||||
|
CYGWIN* )
|
||||||
|
cygwin=true
|
||||||
|
;;
|
||||||
|
Darwin* )
|
||||||
|
darwin=true
|
||||||
|
;;
|
||||||
|
MINGW* )
|
||||||
|
msys=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Attempt to set APP_HOME
|
||||||
|
# Resolve links: $0 may be a link
|
||||||
|
PRG="$0"
|
||||||
|
# Need this for relative symlinks.
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG=`dirname "$PRG"`"/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
SAVED="`pwd`"
|
||||||
|
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||||
|
APP_HOME="`pwd -P`"
|
||||||
|
cd "$SAVED" >/dev/null
|
||||||
|
|
||||||
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
# Determine the Java command to use to start the JVM.
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||||
|
else
|
||||||
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
|
fi
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD="java"
|
||||||
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Increase the maximum file descriptors if we can.
|
||||||
|
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||||
|
MAX_FD_LIMIT=`ulimit -H -n`
|
||||||
|
if [ $? -eq 0 ] ; then
|
||||||
|
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||||
|
MAX_FD="$MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
ulimit -n $MAX_FD
|
||||||
|
if [ $? -ne 0 ] ; then
|
||||||
|
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Darwin, add options to specify how the application appears in the dock
|
||||||
|
if $darwin; then
|
||||||
|
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin, switch paths to Windows format before running java
|
||||||
|
if $cygwin ; then
|
||||||
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
|
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||||
|
|
||||||
|
# We build the pattern for arguments to be converted via cygpath
|
||||||
|
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||||
|
SEP=""
|
||||||
|
for dir in $ROOTDIRSRAW ; do
|
||||||
|
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||||
|
SEP="|"
|
||||||
|
done
|
||||||
|
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||||
|
# Add a user-defined pattern to the cygpath arguments
|
||||||
|
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||||
|
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||||
|
fi
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
i=0
|
||||||
|
for arg in "$@" ; do
|
||||||
|
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||||
|
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||||
|
|
||||||
|
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||||
|
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||||
|
else
|
||||||
|
eval `echo args$i`="\"$arg\""
|
||||||
|
fi
|
||||||
|
i=$((i+1))
|
||||||
|
done
|
||||||
|
case $i in
|
||||||
|
(0) set -- ;;
|
||||||
|
(1) set -- "$args0" ;;
|
||||||
|
(2) set -- "$args0" "$args1" ;;
|
||||||
|
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
|
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
|
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
|
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
|
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
|
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
|
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||||
|
function splitJvmOpts() {
|
||||||
|
JVM_OPTS=("$@")
|
||||||
|
}
|
||||||
|
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||||
|
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||||
|
|
||||||
|
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
||||||
90
apps/mobile/apps/staff/android/gradlew.bat
vendored
Executable file
@@ -0,0 +1,90 @@
|
|||||||
|
@if "%DEBUG%" == "" @echo off
|
||||||
|
@rem ##########################################################################
|
||||||
|
@rem
|
||||||
|
@rem Gradle startup script for Windows
|
||||||
|
@rem
|
||||||
|
@rem ##########################################################################
|
||||||
|
|
||||||
|
@rem Set local scope for the variables with windows NT shell
|
||||||
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
set DEFAULT_JVM_OPTS=
|
||||||
|
|
||||||
|
set DIRNAME=%~dp0
|
||||||
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
|
set APP_BASE_NAME=%~n0
|
||||||
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Find java.exe
|
||||||
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
|
set JAVA_EXE=java.exe
|
||||||
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
|
if "%ERRORLEVEL%" == "0" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:findJavaFromJavaHome
|
||||||
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
|
if exist "%JAVA_EXE%" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:init
|
||||||
|
@rem Get command-line arguments, handling Windowz variants
|
||||||
|
|
||||||
|
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||||
|
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||||
|
|
||||||
|
:win9xME_args
|
||||||
|
@rem Slurp the command line arguments.
|
||||||
|
set CMD_LINE_ARGS=
|
||||||
|
set _SKIP=2
|
||||||
|
|
||||||
|
:win9xME_args_slurp
|
||||||
|
if "x%~1" == "x" goto execute
|
||||||
|
|
||||||
|
set CMD_LINE_ARGS=%*
|
||||||
|
goto execute
|
||||||
|
|
||||||
|
:4NT_args
|
||||||
|
@rem Get arguments from the 4NT Shell from JP Software
|
||||||
|
set CMD_LINE_ARGS=%$
|
||||||
|
|
||||||
|
:execute
|
||||||
|
@rem Setup the command line
|
||||||
|
|
||||||
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
|
@rem Execute Gradle
|
||||||
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||||
|
|
||||||
|
:end
|
||||||
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||||
|
|
||||||
|
:fail
|
||||||
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
|
rem the _cmd.exe /c_ return code!
|
||||||
|
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||||
|
exit /b 1
|
||||||
|
|
||||||
|
:mainEnd
|
||||||
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
||||||
|
:omega
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
#
|
||||||
|
# Generated file, do not edit.
|
||||||
|
#
|
||||||
|
|
||||||
|
import lldb
|
||||||
|
|
||||||
|
def handle_new_rx_page(frame: lldb.SBFrame, bp_loc, extra_args, intern_dict):
|
||||||
|
"""Intercept NOTIFY_DEBUGGER_ABOUT_RX_PAGES and touch the pages."""
|
||||||
|
base = frame.register["x0"].GetValueAsAddress()
|
||||||
|
page_len = frame.register["x1"].GetValueAsUnsigned()
|
||||||
|
|
||||||
|
# Note: NOTIFY_DEBUGGER_ABOUT_RX_PAGES will check contents of the
|
||||||
|
# first page to see if handled it correctly. This makes diagnosing
|
||||||
|
# misconfiguration (e.g. missing breakpoint) easier.
|
||||||
|
data = bytearray(page_len)
|
||||||
|
data[0:8] = b'IHELPED!'
|
||||||
|
|
||||||
|
error = lldb.SBError()
|
||||||
|
frame.GetThread().GetProcess().WriteMemory(base, data, error)
|
||||||
|
if not error.Success():
|
||||||
|
print(f'Failed to write into {base}[+{page_len}]', error)
|
||||||
|
return
|
||||||
|
|
||||||
|
def __lldb_init_module(debugger: lldb.SBDebugger, _):
|
||||||
|
target = debugger.GetDummyTarget()
|
||||||
|
# Caveat: must use BreakpointCreateByRegEx here and not
|
||||||
|
# BreakpointCreateByName. For some reasons callback function does not
|
||||||
|
# get carried over from dummy target for the later.
|
||||||
|
bp = target.BreakpointCreateByRegex("^NOTIFY_DEBUGGER_ABOUT_RX_PAGES$")
|
||||||
|
bp.SetScriptCallbackFunction('{}.handle_new_rx_page'.format(__name__))
|
||||||
|
bp.SetAutoContinue(True)
|
||||||
|
print("-- LLDB integration loaded --")
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
#
|
||||||
|
# Generated file, do not edit.
|
||||||
|
#
|
||||||
|
|
||||||
|
command script import --relative-to-command-file flutter_lldb_helper.py
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// Generated file. Do not edit.
|
||||||
|
//
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
|
||||||
|
#ifndef GeneratedPluginRegistrant_h
|
||||||
|
#define GeneratedPluginRegistrant_h
|
||||||
|
|
||||||
|
#import <Flutter/Flutter.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface GeneratedPluginRegistrant : NSObject
|
||||||
|
+ (void)registerWithRegistry:(NSObject<FlutterPluginRegistry>*)registry;
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
|
#endif /* GeneratedPluginRegistrant_h */
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
//
|
||||||
|
// Generated file. Do not edit.
|
||||||
|
//
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
|
||||||
|
#import "GeneratedPluginRegistrant.h"
|
||||||
|
|
||||||
|
#if __has_include(<firebase_app_check/FLTFirebaseAppCheckPlugin.h>)
|
||||||
|
#import <firebase_app_check/FLTFirebaseAppCheckPlugin.h>
|
||||||
|
#else
|
||||||
|
@import firebase_app_check;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __has_include(<firebase_auth/FLTFirebaseAuthPlugin.h>)
|
||||||
|
#import <firebase_auth/FLTFirebaseAuthPlugin.h>
|
||||||
|
#else
|
||||||
|
@import firebase_auth;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __has_include(<firebase_core/FLTFirebaseCorePlugin.h>)
|
||||||
|
#import <firebase_core/FLTFirebaseCorePlugin.h>
|
||||||
|
#else
|
||||||
|
@import firebase_core;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __has_include(<shared_preferences_foundation/SharedPreferencesPlugin.h>)
|
||||||
|
#import <shared_preferences_foundation/SharedPreferencesPlugin.h>
|
||||||
|
#else
|
||||||
|
@import shared_preferences_foundation;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@implementation GeneratedPluginRegistrant
|
||||||
|
|
||||||
|
+ (void)registerWithRegistry:(NSObject<FlutterPluginRegistry>*)registry {
|
||||||
|
[FLTFirebaseAppCheckPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTFirebaseAppCheckPlugin"]];
|
||||||
|
[FLTFirebaseAuthPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTFirebaseAuthPlugin"]];
|
||||||
|
[FLTFirebaseCorePlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTFirebaseCorePlugin"]];
|
||||||
|
[SharedPreferencesPlugin registerWithRegistrar:[registry registrarForPlugin:@"SharedPreferencesPlugin"]];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
/Users/achinthaisuru/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
/Users/achinthaisuru/.pub-cache/hosted/pub.dev/shared_preferences_linux-2.4.1/
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
// This is a generated file; do not edit or check into version control.
|
||||||
|
FLUTTER_ROOT=/Users/achinthaisuru/Documents/flutter
|
||||||
|
FLUTTER_APPLICATION_PATH=/Users/achinthaisuru/Documents/Github/krow-workforce/apps/mobile/apps/staff
|
||||||
|
COCOAPODS_PARALLEL_CODE_SIGN=true
|
||||||
|
FLUTTER_BUILD_DIR=build
|
||||||
|
FLUTTER_BUILD_NAME=1.0.0
|
||||||
|
FLUTTER_BUILD_NUMBER=1
|
||||||
|
DART_OBFUSCATION=false
|
||||||
|
TRACK_WIDGET_CREATION=true
|
||||||
|
TREE_SHAKE_ICONS=false
|
||||||
|
PACKAGE_CONFIG=.dart_tool/package_config.json
|
||||||
12
apps/mobile/apps/staff/macos/Flutter/ephemeral/flutter_export_environment.sh
Executable file
@@ -0,0 +1,12 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# This is a generated file; do not edit or check into version control.
|
||||||
|
export "FLUTTER_ROOT=/Users/achinthaisuru/Documents/flutter"
|
||||||
|
export "FLUTTER_APPLICATION_PATH=/Users/achinthaisuru/Documents/Github/krow-workforce/apps/mobile/apps/staff"
|
||||||
|
export "COCOAPODS_PARALLEL_CODE_SIGN=true"
|
||||||
|
export "FLUTTER_BUILD_DIR=build"
|
||||||
|
export "FLUTTER_BUILD_NAME=1.0.0"
|
||||||
|
export "FLUTTER_BUILD_NUMBER=1"
|
||||||
|
export "DART_OBFUSCATION=false"
|
||||||
|
export "TRACK_WIDGET_CREATION=true"
|
||||||
|
export "TREE_SHAKE_ICONS=false"
|
||||||
|
export "PACKAGE_CONFIG=.dart_tool/package_config.json"
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
/Users/achinthaisuru/.pub-cache/hosted/pub.dev/firebase_auth-6.1.4/
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
/Users/achinthaisuru/.pub-cache/hosted/pub.dev/firebase_core-4.4.0/
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
/Users/achinthaisuru/.pub-cache/hosted/pub.dev/path_provider_windows-2.3.0/
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
/Users/achinthaisuru/.pub-cache/hosted/pub.dev/shared_preferences_windows-2.4.1/
|
||||||
135
apps/mobile/docs/01-architecture-principles.md
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
# KROW Architecture Principles
|
||||||
|
|
||||||
|
This document is the **AUTHORITATIVE** source of truth for the KROW engineering architecture.
|
||||||
|
All agents and engineers must adhere strictly to these principles. Deviations are interpreted as errors.
|
||||||
|
|
||||||
|
## 1. High-Level Architecture
|
||||||
|
|
||||||
|
The KROW platform follows a strict **Clean Architecture** implementation within a **Melos Monorepo**.
|
||||||
|
Dependencies flow **inwards** towards the Domain.
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
graph TD
|
||||||
|
subgraph "Apps (Entry Points)"
|
||||||
|
ClientApp[apps/mobile/apps/client]
|
||||||
|
StaffApp[apps/mobile/apps/staff]
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph "Features (Presentation & Application)"
|
||||||
|
ClientFeature[apps/mobile/packages/features/client/jobs]
|
||||||
|
StaffFeature[apps/mobile/packages/features/staff/schedule]
|
||||||
|
SharedFeature[apps/mobile/packages/features/shared/auth]
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph "Interface Adapters"
|
||||||
|
DataConnect[apps/mobile/packages/data_connect]
|
||||||
|
DesignSystem[apps/mobile/packages/design_system]
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph "Core Domain"
|
||||||
|
Domain[apps/mobile/packages/domain]
|
||||||
|
Core[apps/mobile/packages/core]
|
||||||
|
end
|
||||||
|
|
||||||
|
%% Dependency Flow
|
||||||
|
ClientApp --> ClientFeature & SharedFeature
|
||||||
|
StaffApp --> StaffFeature & SharedFeature
|
||||||
|
ClientApp --> DataConnect
|
||||||
|
StaffApp --> DataConnect
|
||||||
|
|
||||||
|
ClientFeature & StaffFeature & SharedFeature --> Domain
|
||||||
|
ClientFeature & StaffFeature & SharedFeature --> DesignSystem
|
||||||
|
ClientFeature & StaffFeature & SharedFeature --> Core
|
||||||
|
|
||||||
|
DataConnect --> Domain
|
||||||
|
DataConnect --> Core
|
||||||
|
DesignSystem --> Core
|
||||||
|
Domain --> Core
|
||||||
|
|
||||||
|
%% Strict Barriers
|
||||||
|
linkStyle default stroke-width:2px,fill:none,stroke:gray
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2. Repository Structure & Package Roles
|
||||||
|
|
||||||
|
### 2.1 Apps (`apps/mobile/apps/`)
|
||||||
|
- **Role**: Application entry points and Dependency Injection (DI) roots.
|
||||||
|
- **Responsibilities**:
|
||||||
|
- Initialize Flutter Modular.
|
||||||
|
- Assemble features into a navigation tree.
|
||||||
|
- Inject concrete implementations (from `data_connect`) into Feature packages.
|
||||||
|
- Configure environment-specific settings.
|
||||||
|
- **RESTRICTION**: NO business logic. NO UI widgets (except `App` and `Main`).
|
||||||
|
|
||||||
|
### 2.2 Features (`apps/mobile/packages/features/<APP_NAME>/<FEATURE_NAME>`)
|
||||||
|
- **Role**: Vertical slices of user-facing functionality.
|
||||||
|
- **Internal Structure**:
|
||||||
|
- `domain/`: Feature-specific Use Cases and Repository Interfaces.
|
||||||
|
- `data/`: Repository Implementations.
|
||||||
|
- `presentation/`:
|
||||||
|
- Pages, BLoCs, Widgets.
|
||||||
|
- For performance make the pages as `StatelessWidget` and move the state management to the BLoC or `StatefulWidget` to an external separate widget file.
|
||||||
|
- **Responsibilities**:
|
||||||
|
- **Presentation**: UI Pages, Modular Routes.
|
||||||
|
- **State Management**: BLoCs / Cubits.
|
||||||
|
- **Application Logic**: Use Cases.
|
||||||
|
- **RESTRICTION**: Features MUST NOT import other features. Communication happens via shared domain events.
|
||||||
|
|
||||||
|
### 2.3 Domain (`apps/mobile/packages/domain`)
|
||||||
|
- **Role**: The stable heart of the system. Pure Dart.
|
||||||
|
- **Responsibilities**:
|
||||||
|
- **Entities**: Immutable data models (Data Classes).
|
||||||
|
- **Failures**: Domain-specific error types.
|
||||||
|
- **RESTRICTION**: NO Flutter dependencies. NO `json_annotation`. NO package dependencies (except `equatable`).
|
||||||
|
|
||||||
|
### 2.4 Data Connect (`apps/mobile/packages/data_connect/lib/src/mocks`)
|
||||||
|
- **Role**: Interface Adapter for Backend Access (Datasource Layer).
|
||||||
|
- **Responsibilities**:
|
||||||
|
- Implement low-level Datasources or generated SDK wrappers.
|
||||||
|
- map Domain Entities to/from Firebase Data Connect generated code.
|
||||||
|
- Handle Firebase exceptions.
|
||||||
|
- For now use the mock repositories to connect to the features, not the dataconnect_generated.
|
||||||
|
|
||||||
|
### 2.5 Design System (`apps/mobile/packages/design_system`)
|
||||||
|
- **Role**: Visual language and component library.
|
||||||
|
- **Responsibilities**:
|
||||||
|
- UI components if needed. But mostly try to modify the theme file (apps/mobile/packages/design_system/lib/src/ui_theme.dart) so we can directly use the theme in the app, to use the default material widgets.
|
||||||
|
- If not possible, and if that specific widget is used in multiple features, then try to create a shared widget in the `apps/mobile/packages/design_system/widgets`.
|
||||||
|
- Theme definitions (Colors, Typography).
|
||||||
|
- Assets (Icons, Images).
|
||||||
|
- More details on how to use this package is available in the `apps/mobile/docs/03-design-system-usage.md`.
|
||||||
|
- **RESTRICTION**:
|
||||||
|
- CANNOT change colours or typography.
|
||||||
|
- Dumb widgets only. NO business logic. NO state management (Bloc).
|
||||||
|
- More details on how to use this package is available in the `apps/mobile/docs/03-design-system-usage.md`.
|
||||||
|
|
||||||
|
### 2.6 Core (`apps/mobile/packages/core`)
|
||||||
|
- **Role**: Cross-cutting concerns.
|
||||||
|
- **Responsibilities**:
|
||||||
|
- Extension methods.
|
||||||
|
- Logger configuration.
|
||||||
|
- Base classes for Use Cases or Result types (functional error handling).
|
||||||
|
|
||||||
|
## 3. Dependency Direction & Boundaries
|
||||||
|
|
||||||
|
1. **Domain Independence**: `apps/mobile/packages/domain` knows NOTHING about the outer world. It defines *what* needs to be done, not *how*.
|
||||||
|
2. **UI Agnosticism**: `apps/mobile/packages/features` depends on `apps/mobile/packages/design_system` for looks and `apps/mobile/packages/domain` for logic. It does NOT know about Firebase.
|
||||||
|
3. **Data Isolation**: `apps/mobile/packages/data_connect` depends on `apps/mobile/packages/domain` to know what interfaces to implement. It does NOT know about the UI.
|
||||||
|
|
||||||
|
## 4. Firebase Data Connect Strategy
|
||||||
|
|
||||||
|
Since Firebase Data Connect code does not yet exist, we adhere to a **Strict Mocking Strategy**:
|
||||||
|
|
||||||
|
1. **Interface First**: All data requirements are first defined as `abstract interface class IRepository` in `apps/mobile/packages/domain`.
|
||||||
|
2. **Mock Implementation**:
|
||||||
|
- Inside `apps/mobile/packages/data_connect`, create a `MockRepository` implementation.
|
||||||
|
- Use in-memory lists or hardcoded futures to simulate backend responses.
|
||||||
|
- **CRITICAL**: Do NOT put mocks in `test/` folders if they are needed to run the app in "dev" mode. Put them in `lib/src/mocks/`.
|
||||||
|
3. **Future Integration**: When Data Connect is ready, we will add `RealRepository` in `apps/mobile/packages/data_connect`.
|
||||||
|
4. **Injection**: `apps/mobile/apps/` will inject either `MockRepository` or `RealRepository` based on build flags or environment variables.
|
||||||
|
|
||||||
|
## 5. Feature Isolation
|
||||||
|
|
||||||
|
- **Zero Direct Imports**: `import 'package:feature_a/...'` is FORBIDDEN inside `package:feature_b`.
|
||||||
|
- **Navigation**: Use string-based routes or a shared route definition module in `core` (if absolutely necessary) to navigate between features.
|
||||||
|
- **Data Sharing**: Features do not share state directly. They share data via the underlying `Domain` repositories (e.g., both observe the same `User` stream from `AuthRepository`).
|
||||||
83
apps/mobile/docs/02-agent-development-rules.md
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
# Agent Development Rules
|
||||||
|
|
||||||
|
These rules are **NON-NEGOTIABLE**. They are designed to prevent architectural degradation by automated agents.
|
||||||
|
|
||||||
|
## 1. File Creation & Structure
|
||||||
|
|
||||||
|
1. **Feature-First Packaging**:
|
||||||
|
* **DO**: Create new features as independent packages in `apps/mobile/packages/features/<feature_name>`.
|
||||||
|
* **DO NOT**: Add features to `apps/mobile/packages/core` or existing apps directly.
|
||||||
|
2. **Path Conventions**:
|
||||||
|
* Entities: `apps/mobile/packages/domain/lib/src/entities/<entity>.dart`
|
||||||
|
* Repositories (Interface): `apps/mobile/packages/<feature>/lib/src/domain/repositories/<name>_repository_interface.dart`
|
||||||
|
* Repositories (Impl): `apps/mobile/packages/<feature>/lib/src/data/repositories_impl/<name>_repository_impl.dart`
|
||||||
|
* Use Cases: `apps/mobile/packages/<feature>/lib/src/application/<name>_usecase.dart`
|
||||||
|
* BLoCs: `apps/mobile/packages/<feature>/lib/src/presentation/blocs/<name>_bloc.dart`
|
||||||
|
* Pages: `apps/mobile/packages/<feature>/lib/src/presentation/pages/<name>_page.dart`
|
||||||
|
3. **Barrel Files**:
|
||||||
|
* **DO**: Use `export` in `lib/<package_name>.dart` only for public APIs.
|
||||||
|
* **DO NOT**: Export internal implementation details (like mocks or helper widgets) in the main package file.
|
||||||
|
|
||||||
|
## 2. Naming Conventions
|
||||||
|
|
||||||
|
Follow Dart standards strictly.
|
||||||
|
|
||||||
|
| Type | Convention | Example |
|
||||||
|
| :--- | :--- | :--- |
|
||||||
|
| **Files** | `snake_case` | `user_profile_page.dart` |
|
||||||
|
| **Classes** | `PascalCase` | `UserProfilePage` |
|
||||||
|
| **Variables** | `camelCase` | `userProfile` |
|
||||||
|
| **Interfaces** | terminate with `Interface` | `AuthRepositoryInterface` |
|
||||||
|
| **Implementations** | terminate with `Impl` | `FirebaseDataConnectAuthRepositoryImpl` |
|
||||||
|
| **Mocks** | terminate with `Mock` | `AuthRepositoryMock` |
|
||||||
|
|
||||||
|
## 3. Logic Placement (Strict Boundaries)
|
||||||
|
|
||||||
|
* **Business Rules**: MUST reside in **Use Cases** (Domain/Feature Application layer).
|
||||||
|
* *Forbidden*: Placing business rules in BLoCs or Widgets.
|
||||||
|
* **State Logic**: MUST reside in **BLoCs**.
|
||||||
|
* *Forbidden*: `setState` in Pages (except for purely ephemeral UI animations).
|
||||||
|
* **Data Transformation**: MUST reside in **Repositories** (Data Connect layer).
|
||||||
|
* *Forbidden*: Parsing JSON in the UI or Domain.
|
||||||
|
* **Navigation Logic**: MUST reside in **Modular Routes**.
|
||||||
|
* *Forbidden*: `Navigator.push` with hardcoded widgets.
|
||||||
|
|
||||||
|
## 4. Data Connect Mocking Strategy
|
||||||
|
|
||||||
|
Since the backend does not exist, you must mock strictly:
|
||||||
|
|
||||||
|
1. **Define Interface**: Create `abstract interface class <name>RepositoryInterface` in `apps/mobile/packages/<feature>/lib/src/domain/repositories/<name>_repository_interface.dart`.
|
||||||
|
2. **Create Mock**: Create `class MockRepository implements IRepository` in `apps/mobile/packages/data_connect/lib/src/mocks/`.
|
||||||
|
3. **Fake Data**: Return hardcoded `Future`s with realistic dummy entities.
|
||||||
|
4. **Injection**: Register the `MockRepository` in the `AppModule` (in `apps/mobile/apps/client` or `apps/mobile/apps/staff`) until the real implementation exists.
|
||||||
|
|
||||||
|
**DO NOT** use `mockito` or `mocktail` for these *runtime* mocks. Use simple fake classes.
|
||||||
|
|
||||||
|
## 5. Prototype Migration Rules
|
||||||
|
|
||||||
|
You have access to `prototypes/` folders. When migrating code:
|
||||||
|
|
||||||
|
1. **Extract Assets**:
|
||||||
|
* You MAY copy icons, images, and colors. But they should be tailored to the current design system. Do not change the colours and typgorahys in the design system. They are final. And you have to use these in the UI.
|
||||||
|
* When you matching colous and typography, from the POC match it with the design system and use the colors and typography from the design system. As mentioned in the `apps/mobile/docs/03-design-system-usage.md`.
|
||||||
|
2. **Extract Layouts**: You MAY copy `build` methods for UI structure.
|
||||||
|
3. **REJECT Architecture**: You MUST **NOT** copy the `GetX`, `Provider`, or `MVC` patterns often found in prototypes. Refactor immediately to **Bloc + Clean Architecture with Flutter Modular and Melos**.
|
||||||
|
|
||||||
|
## 6. Handling Ambiguity
|
||||||
|
|
||||||
|
If a user request is vague:
|
||||||
|
|
||||||
|
1. **STOP**: Do not guess domain fields or workflows.
|
||||||
|
2. **ANALYZE**:
|
||||||
|
- For architecture related questions, refer to `apps/mobile/docs/01-architecture-principles.md` or existing code.
|
||||||
|
- For design system related questions, refer to `apps/mobile/docs/03-design-system-usage.md` or existing code.
|
||||||
|
3. **DOCUMENT**: If you must make an assumption to proceed, add a comment `// ASSUMPTION: <explanation>` and mention it in your final summary.
|
||||||
|
4. **ASK**: Prefer asking the user for clarification on business rules (e.g., "Should a 'Job' have a 'status'?").
|
||||||
|
|
||||||
|
## 7. Dependencies
|
||||||
|
|
||||||
|
* **DO NOT** add 3rd party packages without checking `apps/mobile/packages/core` first.
|
||||||
|
* **DO NOT** add `firebase_auth` or `cloud_firestore` to any Feature package. They belong in `data_connect` only.
|
||||||
|
|
||||||
|
## 8. Follow Clean Code Principles
|
||||||
|
* Add doc comments to all classes and methods you create.
|
||||||
131
apps/mobile/docs/03-design-system-usage.md
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
# 03 - Design System Usage Guide
|
||||||
|
|
||||||
|
This document defines the mandatory standards for designing and implementing user interfaces across all applications and feature packages using the shared `apps/mobile/packages/design_system`.
|
||||||
|
|
||||||
|
## 1. Introduction & Purpose
|
||||||
|
|
||||||
|
The Design System is the single source of truth for the visual identity of the project. Its purpose is to ensure UI consistency, reduce development velocity by providing reusable primitives, and eliminate "design drift" across multiple feature teams and applications.
|
||||||
|
|
||||||
|
**All UI implementation MUST consume values ONLY from the `design_system` package.**
|
||||||
|
|
||||||
|
## 2. Design System Ownership & Responsibility
|
||||||
|
|
||||||
|
- **Centralized Authority**: The `apps/mobile/packages/design_system` is the owner of all brand assets, colors, typography, and core components.
|
||||||
|
- **No Local Overrides**: Feature packages (e.g., `staff_authentication`) are consumers. They are prohibited from defining their own global styles or overriding theme values locally.
|
||||||
|
- **Extension Policy**: If a required style (color, font, or icon) is missing, the developer must first add it to the `design_system` package following existing patterns before using it in a feature.
|
||||||
|
|
||||||
|
## 3. Package Structure Overview (`apps/mobile/packages/design_system`)
|
||||||
|
|
||||||
|
The package is organized to separate tokens from implementation:
|
||||||
|
- `lib/src/ui_colors.dart`: Color tokens and semantic mappings.
|
||||||
|
- `lib/src/ui_typography.dart`: Text styles and font configurations.
|
||||||
|
- `lib/src/ui_icons.dart`: Exported icon sets.
|
||||||
|
- `lib/src/ui_constants.dart`: Spacing, radius, and elevation tokens.
|
||||||
|
- `lib/src/ui_theme.dart`: Centralized `ThemeData` factory.
|
||||||
|
- `lib/src/widgets/`: Common "Smart Widgets" and reusable UI building blocks.
|
||||||
|
|
||||||
|
## 4. Colors Usage Rules
|
||||||
|
|
||||||
|
Feature packages **MUST NOT** define custom hex codes or `Color` constants.
|
||||||
|
|
||||||
|
### Usage Protocol
|
||||||
|
- **Primary Method**:Use `UiColors` from the design system for specific brand accents.
|
||||||
|
- **Naming Matching**: If an exact color is missing, use the closest existing semantic color (e.g., use `UiColors.mutedForeground` instead of a hardcoded grey).
|
||||||
|
|
||||||
|
```dart
|
||||||
|
// ❌ ANTI-PATTERN: Hardcoded color
|
||||||
|
Container(color: Color(0xFF1A2234))
|
||||||
|
|
||||||
|
// ✅ CORRECT: Design system token
|
||||||
|
Container(color: UiColors.background)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 5. Typography Usage Rules
|
||||||
|
|
||||||
|
Custom `TextStyle` definitions in feature packages are **STRICTLY PROHIBITED**.
|
||||||
|
|
||||||
|
### Usage Protocol
|
||||||
|
- Use `UiTypography` from the design system for specific brand accents.
|
||||||
|
|
||||||
|
```dart
|
||||||
|
// ❌ ANTI-PATTERN: Custom TextStyle
|
||||||
|
Text('Hello', style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold))
|
||||||
|
|
||||||
|
// ✅ CORRECT: Design system typography
|
||||||
|
Text('Hello', style: UiTypography.display1m)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 6. Icons Usage Rules
|
||||||
|
|
||||||
|
Feature packages **MUST NOT** import icon libraries (like `lucide_icons`) directly. They should use the icons exposed via `UiIcons`.
|
||||||
|
|
||||||
|
- **Standardization**: Ensure the same icon is used for the same action across all features (e.g., always use `UiIcons.chevronLeft` for navigation).
|
||||||
|
- **Additions**: New icons must be added to the design system (only using the typedef _IconLib = LucideIcons or typedef _IconLib2 = FontAwesomeIcons; and nothing else) first to ensure they follow the project's stroke weight and sizing standards.
|
||||||
|
|
||||||
|
## 7. UI Constants & Layout Rules
|
||||||
|
|
||||||
|
Hardcoded padding, margins, and radius values are **PROHIBITED**.
|
||||||
|
|
||||||
|
- **Spacing**: Use `UiConstants.spacing` multiplied by tokens (e.g., `S`, `M`, `L`).
|
||||||
|
- **Border Radius**: Use `UiConstants.borderRadius`.
|
||||||
|
- **Elevation**: Use `UiConstants.elevation`.
|
||||||
|
|
||||||
|
```dart
|
||||||
|
// ✅ CORRECT: Spacing and Radius constants
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.all(UiConstants.spacingL),
|
||||||
|
child: Container(
|
||||||
|
borderRadius: BorderRadius.circular(UiConstants.radiusM),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 8. Common Smart Widgets Guidelines
|
||||||
|
|
||||||
|
The design system provides "Smart Widgets" – these are high-level UI components that encapsulate both styling and standard behavior.
|
||||||
|
|
||||||
|
- **Standard Widgets**: Prefer standard Flutter Material widgets (e.g., `ElevatedButton`) but styled via the central theme.
|
||||||
|
- **Custom Components**: Use `design_system` widgets for non-standard elements or wisgets that has similar design across various features, if provided.
|
||||||
|
- **Composition**: Prefer composing standard widgets over creating deep inheritance hierarchies in features.
|
||||||
|
|
||||||
|
## 9. Theme Configuration & Usage
|
||||||
|
|
||||||
|
Applications (`apps/mobile/apps/`) must initialize the theme once in the root `MaterialApp`.
|
||||||
|
|
||||||
|
```dart
|
||||||
|
MaterialApp.router(
|
||||||
|
theme: StaffTheme.light, // Mandatory: Consumption of centralized theme
|
||||||
|
// ...
|
||||||
|
)
|
||||||
|
```
|
||||||
|
**No application-level theme customization is allowed.**
|
||||||
|
|
||||||
|
## 10. Feature Development Workflow (POC → Themed)
|
||||||
|
|
||||||
|
To bridge the gap between rapid prototyping (POCs) and production-grade code, developers must follow this three-step workflow:
|
||||||
|
|
||||||
|
1. **Step 1: Structural Implementation**: Implement the UI logic and layout **exactly matching the POC**. Hardcoded values from the POC are acceptable in this transient state to ensure visual parity.
|
||||||
|
2. **Step 2: Logic Refactor**: Immediately refactor the code to:
|
||||||
|
- Follow the `apps/mobile/docs/01-architecture-principles.md` and `apps/mobile/docs/02-agent-development-rules.md` to refactor the code.
|
||||||
|
3. **Step 3: Theme Refactor**: Immediately refactor the code to:
|
||||||
|
- Replace hex codes with `UiColors`.
|
||||||
|
- Replace manual `TextStyle` with `UiTypography`.
|
||||||
|
- Replace hardcoded padding/radius with `UiConstants`.
|
||||||
|
- Upgrade icons to design system versions.
|
||||||
|
|
||||||
|
## 11. Anti-Patterns & Common Mistakes
|
||||||
|
|
||||||
|
- **"Magic Numbers"**: Hardcoding `EdgeInsets.all(12.0)` instead of using design system constants.
|
||||||
|
- **Local Themes**: Using `Theme(data: ...)` to override colors for a specific section of a page.
|
||||||
|
- **Hex Hunting**: Copy-pasting hex codes from Figma or POCs into feature code.
|
||||||
|
- **Package Bypassing**: Importing `package:flutter/material.dart` and ignoring `package:design_system`.
|
||||||
|
|
||||||
|
## 12. Enforcement & Review Checklist
|
||||||
|
|
||||||
|
Before any UI code is merged, it must pass this checklist:
|
||||||
|
1. [ ] No hardcoded `Color(...)` or `0xFF...` in the feature package.
|
||||||
|
2. [ ] No custom `TextStyle(...)` definitions.
|
||||||
|
3. [ ] All spacing/padding/radius uses `UiConstants`.
|
||||||
|
4. [ ] All icons are consumed from the approved design system source.
|
||||||
|
5. [ ] The feature relies on the global `ThemeData` and does not provide local overrides.
|
||||||
|
6. [ ] The layout matches the POC visual intent and element placement(wireframing and logic) while using the design system primitives.
|
||||||
0
apps/mobile/docs/04-
Normal file
183
apps/mobile/lib/gen/strings.g.dart
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
/// Generated file. Do not edit.
|
||||||
|
///
|
||||||
|
/// Source: packages/core_localization/lib/src/l10n
|
||||||
|
/// To regenerate, run: `dart run slang`
|
||||||
|
///
|
||||||
|
/// Locales: 2
|
||||||
|
/// Strings: 816 (408 per locale)
|
||||||
|
///
|
||||||
|
/// Built on 2026-01-25 at 02:11 UTC
|
||||||
|
|
||||||
|
// coverage:ignore-file
|
||||||
|
// ignore_for_file: type=lint, unused_import
|
||||||
|
// dart format off
|
||||||
|
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:slang/generated.dart';
|
||||||
|
import 'package:slang_flutter/slang_flutter.dart';
|
||||||
|
export 'package:slang_flutter/slang_flutter.dart';
|
||||||
|
|
||||||
|
import 'strings_es.g.dart' deferred as l_es;
|
||||||
|
part 'strings_en.g.dart';
|
||||||
|
|
||||||
|
/// Supported locales.
|
||||||
|
///
|
||||||
|
/// Usage:
|
||||||
|
/// - LocaleSettings.setLocale(AppLocale.en) // set locale
|
||||||
|
/// - Locale locale = AppLocale.en.flutterLocale // get flutter locale from enum
|
||||||
|
/// - if (LocaleSettings.currentLocale == AppLocale.en) // locale check
|
||||||
|
enum AppLocale with BaseAppLocale<AppLocale, Translations> {
|
||||||
|
en(languageCode: 'en'),
|
||||||
|
es(languageCode: 'es');
|
||||||
|
|
||||||
|
const AppLocale({
|
||||||
|
required this.languageCode,
|
||||||
|
this.scriptCode, // ignore: unused_element, unused_element_parameter
|
||||||
|
this.countryCode, // ignore: unused_element, unused_element_parameter
|
||||||
|
});
|
||||||
|
|
||||||
|
@override final String languageCode;
|
||||||
|
@override final String? scriptCode;
|
||||||
|
@override final String? countryCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Translations> build({
|
||||||
|
Map<String, Node>? overrides,
|
||||||
|
PluralResolver? cardinalResolver,
|
||||||
|
PluralResolver? ordinalResolver,
|
||||||
|
}) async {
|
||||||
|
switch (this) {
|
||||||
|
case AppLocale.en:
|
||||||
|
return TranslationsEn(
|
||||||
|
overrides: overrides,
|
||||||
|
cardinalResolver: cardinalResolver,
|
||||||
|
ordinalResolver: ordinalResolver,
|
||||||
|
);
|
||||||
|
case AppLocale.es:
|
||||||
|
await l_es.loadLibrary();
|
||||||
|
return l_es.TranslationsEs(
|
||||||
|
overrides: overrides,
|
||||||
|
cardinalResolver: cardinalResolver,
|
||||||
|
ordinalResolver: ordinalResolver,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Translations buildSync({
|
||||||
|
Map<String, Node>? overrides,
|
||||||
|
PluralResolver? cardinalResolver,
|
||||||
|
PluralResolver? ordinalResolver,
|
||||||
|
}) {
|
||||||
|
switch (this) {
|
||||||
|
case AppLocale.en:
|
||||||
|
return TranslationsEn(
|
||||||
|
overrides: overrides,
|
||||||
|
cardinalResolver: cardinalResolver,
|
||||||
|
ordinalResolver: ordinalResolver,
|
||||||
|
);
|
||||||
|
case AppLocale.es:
|
||||||
|
return l_es.TranslationsEs(
|
||||||
|
overrides: overrides,
|
||||||
|
cardinalResolver: cardinalResolver,
|
||||||
|
ordinalResolver: ordinalResolver,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets current instance managed by [LocaleSettings].
|
||||||
|
Translations get translations => LocaleSettings.instance.getTranslations(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Method A: Simple
|
||||||
|
///
|
||||||
|
/// No rebuild after locale change.
|
||||||
|
/// Translation happens during initialization of the widget (call of t).
|
||||||
|
/// Configurable via 'translate_var'.
|
||||||
|
///
|
||||||
|
/// Usage:
|
||||||
|
/// String a = t.someKey.anotherKey;
|
||||||
|
/// String b = t['someKey.anotherKey']; // Only for edge cases!
|
||||||
|
Translations get t => LocaleSettings.instance.currentTranslations;
|
||||||
|
|
||||||
|
/// Method B: Advanced
|
||||||
|
///
|
||||||
|
/// All widgets using this method will trigger a rebuild when locale changes.
|
||||||
|
/// Use this if you have e.g. a settings page where the user can select the locale during runtime.
|
||||||
|
///
|
||||||
|
/// Step 1:
|
||||||
|
/// wrap your App with
|
||||||
|
/// TranslationProvider(
|
||||||
|
/// child: MyApp()
|
||||||
|
/// );
|
||||||
|
///
|
||||||
|
/// Step 2:
|
||||||
|
/// final t = Translations.of(context); // Get t variable.
|
||||||
|
/// String a = t.someKey.anotherKey; // Use t variable.
|
||||||
|
/// String b = t['someKey.anotherKey']; // Only for edge cases!
|
||||||
|
class TranslationProvider extends BaseTranslationProvider<AppLocale, Translations> {
|
||||||
|
TranslationProvider({required super.child}) : super(settings: LocaleSettings.instance);
|
||||||
|
|
||||||
|
static InheritedLocaleData<AppLocale, Translations> of(BuildContext context) => InheritedLocaleData.of<AppLocale, Translations>(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Method B shorthand via [BuildContext] extension method.
|
||||||
|
/// Configurable via 'translate_var'.
|
||||||
|
///
|
||||||
|
/// Usage (e.g. in a widget's build method):
|
||||||
|
/// context.t.someKey.anotherKey
|
||||||
|
extension BuildContextTranslationsExtension on BuildContext {
|
||||||
|
Translations get t => TranslationProvider.of(this).translations;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Manages all translation instances and the current locale
|
||||||
|
class LocaleSettings extends BaseFlutterLocaleSettings<AppLocale, Translations> {
|
||||||
|
LocaleSettings._() : super(
|
||||||
|
utils: AppLocaleUtils.instance,
|
||||||
|
lazy: true,
|
||||||
|
);
|
||||||
|
|
||||||
|
static final instance = LocaleSettings._();
|
||||||
|
|
||||||
|
// static aliases (checkout base methods for documentation)
|
||||||
|
static AppLocale get currentLocale => instance.currentLocale;
|
||||||
|
static Stream<AppLocale> getLocaleStream() => instance.getLocaleStream();
|
||||||
|
static Future<AppLocale> setLocale(AppLocale locale, {bool? listenToDeviceLocale = false}) => instance.setLocale(locale, listenToDeviceLocale: listenToDeviceLocale);
|
||||||
|
static Future<AppLocale> setLocaleRaw(String rawLocale, {bool? listenToDeviceLocale = false}) => instance.setLocaleRaw(rawLocale, listenToDeviceLocale: listenToDeviceLocale);
|
||||||
|
static Future<AppLocale> useDeviceLocale() => instance.useDeviceLocale();
|
||||||
|
static Future<void> setPluralResolver({String? language, AppLocale? locale, PluralResolver? cardinalResolver, PluralResolver? ordinalResolver}) => instance.setPluralResolver(
|
||||||
|
language: language,
|
||||||
|
locale: locale,
|
||||||
|
cardinalResolver: cardinalResolver,
|
||||||
|
ordinalResolver: ordinalResolver,
|
||||||
|
);
|
||||||
|
|
||||||
|
// synchronous versions
|
||||||
|
static AppLocale setLocaleSync(AppLocale locale, {bool? listenToDeviceLocale = false}) => instance.setLocaleSync(locale, listenToDeviceLocale: listenToDeviceLocale);
|
||||||
|
static AppLocale setLocaleRawSync(String rawLocale, {bool? listenToDeviceLocale = false}) => instance.setLocaleRawSync(rawLocale, listenToDeviceLocale: listenToDeviceLocale);
|
||||||
|
static AppLocale useDeviceLocaleSync() => instance.useDeviceLocaleSync();
|
||||||
|
static void setPluralResolverSync({String? language, AppLocale? locale, PluralResolver? cardinalResolver, PluralResolver? ordinalResolver}) => instance.setPluralResolverSync(
|
||||||
|
language: language,
|
||||||
|
locale: locale,
|
||||||
|
cardinalResolver: cardinalResolver,
|
||||||
|
ordinalResolver: ordinalResolver,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Provides utility functions without any side effects.
|
||||||
|
class AppLocaleUtils extends BaseAppLocaleUtils<AppLocale, Translations> {
|
||||||
|
AppLocaleUtils._() : super(
|
||||||
|
baseLocale: AppLocale.en,
|
||||||
|
locales: AppLocale.values,
|
||||||
|
);
|
||||||
|
|
||||||
|
static final instance = AppLocaleUtils._();
|
||||||
|
|
||||||
|
// static aliases (checkout base methods for documentation)
|
||||||
|
static AppLocale parse(String rawLocale) => instance.parse(rawLocale);
|
||||||
|
static AppLocale parseLocaleParts({required String languageCode, String? scriptCode, String? countryCode}) => instance.parseLocaleParts(languageCode: languageCode, scriptCode: scriptCode, countryCode: countryCode);
|
||||||
|
static AppLocale findDeviceLocale() => instance.findDeviceLocale();
|
||||||
|
static List<Locale> get supportedLocales => instance.supportedLocales;
|
||||||
|
static List<String> get supportedLocalesRaw => instance.supportedLocalesRaw;
|
||||||
|
}
|
||||||
2498
apps/mobile/lib/gen/strings_en.g.dart
Normal file
1669
apps/mobile/lib/gen/strings_es.g.dart
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
/// Generated file. Do not edit.
|
||||||
|
///
|
||||||
|
/// Source: lib/src/l10n
|
||||||
|
/// To regenerate, run: `dart run slang`
|
||||||
|
///
|
||||||
|
/// Locales: 2
|
||||||
|
/// Strings: 1004 (502 per locale)
|
||||||
|
///
|
||||||
|
/// Built on 2026-01-25 at 22:00 UTC
|
||||||
|
|
||||||
|
// coverage:ignore-file
|
||||||
|
// ignore_for_file: type=lint, unused_import
|
||||||
|
// dart format off
|
||||||
|
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:slang/generated.dart';
|
||||||
|
import 'package:slang_flutter/slang_flutter.dart';
|
||||||
|
export 'package:slang_flutter/slang_flutter.dart';
|
||||||
|
|
||||||
|
import 'strings_es.g.dart' deferred as l_es;
|
||||||
|
part 'strings_en.g.dart';
|
||||||
|
|
||||||
|
/// Supported locales.
|
||||||
|
///
|
||||||
|
/// Usage:
|
||||||
|
/// - LocaleSettings.setLocale(AppLocale.en) // set locale
|
||||||
|
/// - Locale locale = AppLocale.en.flutterLocale // get flutter locale from enum
|
||||||
|
/// - if (LocaleSettings.currentLocale == AppLocale.en) // locale check
|
||||||
|
enum AppLocale with BaseAppLocale<AppLocale, Translations> {
|
||||||
|
en(languageCode: 'en'),
|
||||||
|
es(languageCode: 'es');
|
||||||
|
|
||||||
|
const AppLocale({
|
||||||
|
required this.languageCode,
|
||||||
|
this.scriptCode, // ignore: unused_element, unused_element_parameter
|
||||||
|
this.countryCode, // ignore: unused_element, unused_element_parameter
|
||||||
|
});
|
||||||
|
|
||||||
|
@override final String languageCode;
|
||||||
|
@override final String? scriptCode;
|
||||||
|
@override final String? countryCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Translations> build({
|
||||||
|
Map<String, Node>? overrides,
|
||||||
|
PluralResolver? cardinalResolver,
|
||||||
|
PluralResolver? ordinalResolver,
|
||||||
|
}) async {
|
||||||
|
switch (this) {
|
||||||
|
case AppLocale.en:
|
||||||
|
return TranslationsEn(
|
||||||
|
overrides: overrides,
|
||||||
|
cardinalResolver: cardinalResolver,
|
||||||
|
ordinalResolver: ordinalResolver,
|
||||||
|
);
|
||||||
|
case AppLocale.es:
|
||||||
|
await l_es.loadLibrary();
|
||||||
|
return l_es.TranslationsEs(
|
||||||
|
overrides: overrides,
|
||||||
|
cardinalResolver: cardinalResolver,
|
||||||
|
ordinalResolver: ordinalResolver,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Translations buildSync({
|
||||||
|
Map<String, Node>? overrides,
|
||||||
|
PluralResolver? cardinalResolver,
|
||||||
|
PluralResolver? ordinalResolver,
|
||||||
|
}) {
|
||||||
|
switch (this) {
|
||||||
|
case AppLocale.en:
|
||||||
|
return TranslationsEn(
|
||||||
|
overrides: overrides,
|
||||||
|
cardinalResolver: cardinalResolver,
|
||||||
|
ordinalResolver: ordinalResolver,
|
||||||
|
);
|
||||||
|
case AppLocale.es:
|
||||||
|
return l_es.TranslationsEs(
|
||||||
|
overrides: overrides,
|
||||||
|
cardinalResolver: cardinalResolver,
|
||||||
|
ordinalResolver: ordinalResolver,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets current instance managed by [LocaleSettings].
|
||||||
|
Translations get translations => LocaleSettings.instance.getTranslations(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Method A: Simple
|
||||||
|
///
|
||||||
|
/// No rebuild after locale change.
|
||||||
|
/// Translation happens during initialization of the widget (call of t).
|
||||||
|
/// Configurable via 'translate_var'.
|
||||||
|
///
|
||||||
|
/// Usage:
|
||||||
|
/// String a = t.someKey.anotherKey;
|
||||||
|
/// String b = t['someKey.anotherKey']; // Only for edge cases!
|
||||||
|
Translations get t => LocaleSettings.instance.currentTranslations;
|
||||||
|
|
||||||
|
/// Method B: Advanced
|
||||||
|
///
|
||||||
|
/// All widgets using this method will trigger a rebuild when locale changes.
|
||||||
|
/// Use this if you have e.g. a settings page where the user can select the locale during runtime.
|
||||||
|
///
|
||||||
|
/// Step 1:
|
||||||
|
/// wrap your App with
|
||||||
|
/// TranslationProvider(
|
||||||
|
/// child: MyApp()
|
||||||
|
/// );
|
||||||
|
///
|
||||||
|
/// Step 2:
|
||||||
|
/// final t = Translations.of(context); // Get t variable.
|
||||||
|
/// String a = t.someKey.anotherKey; // Use t variable.
|
||||||
|
/// String b = t['someKey.anotherKey']; // Only for edge cases!
|
||||||
|
class TranslationProvider extends BaseTranslationProvider<AppLocale, Translations> {
|
||||||
|
TranslationProvider({required super.child}) : super(settings: LocaleSettings.instance);
|
||||||
|
|
||||||
|
static InheritedLocaleData<AppLocale, Translations> of(BuildContext context) => InheritedLocaleData.of<AppLocale, Translations>(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Method B shorthand via [BuildContext] extension method.
|
||||||
|
/// Configurable via 'translate_var'.
|
||||||
|
///
|
||||||
|
/// Usage (e.g. in a widget's build method):
|
||||||
|
/// context.t.someKey.anotherKey
|
||||||
|
extension BuildContextTranslationsExtension on BuildContext {
|
||||||
|
Translations get t => TranslationProvider.of(this).translations;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Manages all translation instances and the current locale
|
||||||
|
class LocaleSettings extends BaseFlutterLocaleSettings<AppLocale, Translations> {
|
||||||
|
LocaleSettings._() : super(
|
||||||
|
utils: AppLocaleUtils.instance,
|
||||||
|
lazy: true,
|
||||||
|
);
|
||||||
|
|
||||||
|
static final instance = LocaleSettings._();
|
||||||
|
|
||||||
|
// static aliases (checkout base methods for documentation)
|
||||||
|
static AppLocale get currentLocale => instance.currentLocale;
|
||||||
|
static Stream<AppLocale> getLocaleStream() => instance.getLocaleStream();
|
||||||
|
static Future<AppLocale> setLocale(AppLocale locale, {bool? listenToDeviceLocale = false}) => instance.setLocale(locale, listenToDeviceLocale: listenToDeviceLocale);
|
||||||
|
static Future<AppLocale> setLocaleRaw(String rawLocale, {bool? listenToDeviceLocale = false}) => instance.setLocaleRaw(rawLocale, listenToDeviceLocale: listenToDeviceLocale);
|
||||||
|
static Future<AppLocale> useDeviceLocale() => instance.useDeviceLocale();
|
||||||
|
static Future<void> setPluralResolver({String? language, AppLocale? locale, PluralResolver? cardinalResolver, PluralResolver? ordinalResolver}) => instance.setPluralResolver(
|
||||||
|
language: language,
|
||||||
|
locale: locale,
|
||||||
|
cardinalResolver: cardinalResolver,
|
||||||
|
ordinalResolver: ordinalResolver,
|
||||||
|
);
|
||||||
|
|
||||||
|
// synchronous versions
|
||||||
|
static AppLocale setLocaleSync(AppLocale locale, {bool? listenToDeviceLocale = false}) => instance.setLocaleSync(locale, listenToDeviceLocale: listenToDeviceLocale);
|
||||||
|
static AppLocale setLocaleRawSync(String rawLocale, {bool? listenToDeviceLocale = false}) => instance.setLocaleRawSync(rawLocale, listenToDeviceLocale: listenToDeviceLocale);
|
||||||
|
static AppLocale useDeviceLocaleSync() => instance.useDeviceLocaleSync();
|
||||||
|
static void setPluralResolverSync({String? language, AppLocale? locale, PluralResolver? cardinalResolver, PluralResolver? ordinalResolver}) => instance.setPluralResolverSync(
|
||||||
|
language: language,
|
||||||
|
locale: locale,
|
||||||
|
cardinalResolver: cardinalResolver,
|
||||||
|
ordinalResolver: ordinalResolver,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Provides utility functions without any side effects.
|
||||||
|
class AppLocaleUtils extends BaseAppLocaleUtils<AppLocale, Translations> {
|
||||||
|
AppLocaleUtils._() : super(
|
||||||
|
baseLocale: AppLocale.en,
|
||||||
|
locales: AppLocale.values,
|
||||||
|
);
|
||||||
|
|
||||||
|
static final instance = AppLocaleUtils._();
|
||||||
|
|
||||||
|
// static aliases (checkout base methods for documentation)
|
||||||
|
static AppLocale parse(String rawLocale) => instance.parse(rawLocale);
|
||||||
|
static AppLocale parseLocaleParts({required String languageCode, String? scriptCode, String? countryCode}) => instance.parseLocaleParts(languageCode: languageCode, scriptCode: scriptCode, countryCode: countryCode);
|
||||||
|
static AppLocale findDeviceLocale() => instance.findDeviceLocale();
|
||||||
|
static List<Locale> get supportedLocales => instance.supportedLocales;
|
||||||
|
static List<String> get supportedLocalesRaw => instance.supportedLocalesRaw;
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import 'package:krow_data_connect/krow_data_connect.dart';
|
||||||
|
import 'package:krow_domain/krow_domain.dart';
|
||||||
|
import '../../domain/repositories/payments_repository.dart';
|
||||||
|
|
||||||
|
class PaymentsRepositoryImpl implements PaymentsRepository {
|
||||||
|
final FinancialRepositoryMock financialRepository;
|
||||||
|
|
||||||
|
PaymentsRepositoryImpl({required this.financialRepository});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<List<StaffPayment>> getPayments() async {
|
||||||
|
// TODO: Get actual logged in staff ID
|
||||||
|
return await financialRepository.getStaffPayments('staff_1');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
<<<<<<< Updated upstream
|
||||||
import '../entities/payment_summary.dart';
|
import '../entities/payment_summary.dart';
|
||||||
import '../entities/payment_transaction.dart';
|
import '../entities/payment_transaction.dart';
|
||||||
|
|
||||||
@@ -7,4 +8,11 @@ abstract class PaymentsRepository {
|
|||||||
|
|
||||||
/// Fetches the list of recent payment transactions (history).
|
/// Fetches the list of recent payment transactions (history).
|
||||||
Future<List<PaymentTransaction>> getPaymentHistory(String period);
|
Future<List<PaymentTransaction>> getPaymentHistory(String period);
|
||||||
|
=======
|
||||||
|
import 'package:krow_domain/krow_domain.dart';
|
||||||
|
|
||||||
|
abstract class PaymentsRepository {
|
||||||
|
/// Fetches the list of payments.
|
||||||
|
Future<List<StaffPayment>> getPayments();
|
||||||
|
>>>>>>> Stashed changes
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,27 @@
|
|||||||
|
<<<<<<< Updated upstream
|
||||||
import '../entities/payment_transaction.dart';
|
import '../entities/payment_transaction.dart';
|
||||||
import '../repositories/payments_repository.dart';
|
import '../repositories/payments_repository.dart';
|
||||||
|
|
||||||
class GetPaymentHistoryUseCase {
|
class GetPaymentHistoryUseCase {
|
||||||
|
=======
|
||||||
|
import 'package:krow_core/core.dart';
|
||||||
|
import 'package:krow_domain/krow_domain.dart';
|
||||||
|
import '../repositories/payments_repository.dart';
|
||||||
|
|
||||||
|
class GetPaymentHistoryUseCase extends UseCase<String, List<StaffPayment>> {
|
||||||
|
>>>>>>> Stashed changes
|
||||||
final PaymentsRepository repository;
|
final PaymentsRepository repository;
|
||||||
|
|
||||||
GetPaymentHistoryUseCase(this.repository);
|
GetPaymentHistoryUseCase(this.repository);
|
||||||
|
|
||||||
|
<<<<<<< Updated upstream
|
||||||
Future<List<PaymentTransaction>> call({String period = 'week'}) async {
|
Future<List<PaymentTransaction>> call({String period = 'week'}) async {
|
||||||
return await repository.getPaymentHistory(period);
|
return await repository.getPaymentHistory(period);
|
||||||
|
=======
|
||||||
|
@override
|
||||||
|
Future<List<StaffPayment>> call(String period) async {
|
||||||
|
// TODO: Implement filtering by period
|
||||||
|
return await repository.getPayments();
|
||||||
|
>>>>>>> Stashed changes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,26 @@
|
|||||||
|
<<<<<<< Updated upstream
|
||||||
import '../entities/payment_summary.dart';
|
import '../entities/payment_summary.dart';
|
||||||
import '../repositories/payments_repository.dart';
|
import '../repositories/payments_repository.dart';
|
||||||
|
|
||||||
class GetPaymentSummaryUseCase {
|
class GetPaymentSummaryUseCase {
|
||||||
|
=======
|
||||||
|
import 'package:krow_core/core.dart';
|
||||||
|
import 'package:krow_domain/krow_domain.dart';
|
||||||
|
import '../repositories/payments_repository.dart';
|
||||||
|
|
||||||
|
class GetPaymentSummaryUseCase extends NoInputUseCase<List<StaffPayment>> {
|
||||||
|
>>>>>>> Stashed changes
|
||||||
final PaymentsRepository repository;
|
final PaymentsRepository repository;
|
||||||
|
|
||||||
GetPaymentSummaryUseCase(this.repository);
|
GetPaymentSummaryUseCase(this.repository);
|
||||||
|
|
||||||
|
<<<<<<< Updated upstream
|
||||||
Future<PaymentSummary> call() async {
|
Future<PaymentSummary> call() async {
|
||||||
return await repository.getPaymentSummary();
|
return await repository.getPaymentSummary();
|
||||||
|
=======
|
||||||
|
@override
|
||||||
|
Future<List<StaffPayment>> call() async {
|
||||||
|
return await repository.getPayments();
|
||||||
|
>>>>>>> Stashed changes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,31 @@
|
|||||||
import 'package:flutter_modular/flutter_modular.dart';
|
import 'package:flutter_modular/flutter_modular.dart';
|
||||||
|
<<<<<<< Updated upstream
|
||||||
import 'domain/repositories/payments_repository.dart';
|
import 'domain/repositories/payments_repository.dart';
|
||||||
import 'domain/usecases/get_payment_summary_usecase.dart';
|
import 'domain/usecases/get_payment_summary_usecase.dart';
|
||||||
import 'domain/usecases/get_payment_history_usecase.dart';
|
import 'domain/usecases/get_payment_history_usecase.dart';
|
||||||
import 'data/datasources/payments_remote_datasource.dart';
|
import 'data/datasources/payments_remote_datasource.dart';
|
||||||
import 'data/datasources/payments_mock_datasource.dart';
|
import 'data/datasources/payments_mock_datasource.dart';
|
||||||
import 'data/repositories/payments_repository_impl.dart';
|
import 'data/repositories/payments_repository_impl.dart';
|
||||||
|
=======
|
||||||
|
import 'package:krow_data_connect/krow_data_connect.dart';
|
||||||
|
import 'domain/repositories/payments_repository.dart';
|
||||||
|
import 'domain/usecases/get_payment_summary_usecase.dart';
|
||||||
|
import 'domain/usecases/get_payment_history_usecase.dart';
|
||||||
|
import 'data/repositories_impl/payments_repository_impl.dart';
|
||||||
|
>>>>>>> Stashed changes
|
||||||
import 'presentation/blocs/payments/payments_bloc.dart';
|
import 'presentation/blocs/payments/payments_bloc.dart';
|
||||||
import 'presentation/pages/payments_page.dart';
|
import 'presentation/pages/payments_page.dart';
|
||||||
|
|
||||||
class StaffPaymentsModule extends Module {
|
class StaffPaymentsModule extends Module {
|
||||||
@override
|
@override
|
||||||
void binds(Injector i) {
|
void binds(Injector i) {
|
||||||
|
<<<<<<< Updated upstream
|
||||||
// Data Sources
|
// Data Sources
|
||||||
i.add<PaymentsRemoteDataSource>(PaymentsMockDataSource.new);
|
i.add<PaymentsRemoteDataSource>(PaymentsMockDataSource.new);
|
||||||
|
=======
|
||||||
|
// Data Connect Mocks
|
||||||
|
i.add<FinancialRepositoryMock>(FinancialRepositoryMock.new);
|
||||||
|
>>>>>>> Stashed changes
|
||||||
|
|
||||||
// Repositories
|
// Repositories
|
||||||
i.add<PaymentsRepository>(PaymentsRepositoryImpl.new);
|
i.add<PaymentsRepository>(PaymentsRepositoryImpl.new);
|
||||||
|
|||||||
@@ -1,8 +1,15 @@
|
|||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
<<<<<<< Updated upstream
|
||||||
import '../../../domain/entities/payment_summary.dart';
|
import '../../../domain/entities/payment_summary.dart';
|
||||||
import '../../../domain/entities/payment_transaction.dart';
|
import '../../../domain/entities/payment_transaction.dart';
|
||||||
import '../../../domain/usecases/get_payment_summary_usecase.dart';
|
import '../../../domain/usecases/get_payment_summary_usecase.dart';
|
||||||
import '../../../domain/usecases/get_payment_history_usecase.dart';
|
import '../../../domain/usecases/get_payment_history_usecase.dart';
|
||||||
|
=======
|
||||||
|
import 'package:krow_domain/krow_domain.dart';
|
||||||
|
import '../../../domain/usecases/get_payment_summary_usecase.dart';
|
||||||
|
import '../../../domain/usecases/get_payment_history_usecase.dart';
|
||||||
|
import '../../models/payment_stats.dart';
|
||||||
|
>>>>>>> Stashed changes
|
||||||
import 'payments_event.dart';
|
import 'payments_event.dart';
|
||||||
import 'payments_state.dart';
|
import 'payments_state.dart';
|
||||||
|
|
||||||
@@ -24,10 +31,19 @@ class PaymentsBloc extends Bloc<PaymentsEvent, PaymentsState> {
|
|||||||
) async {
|
) async {
|
||||||
emit(PaymentsLoading());
|
emit(PaymentsLoading());
|
||||||
try {
|
try {
|
||||||
|
<<<<<<< Updated upstream
|
||||||
final PaymentSummary summary = await getPaymentSummary();
|
final PaymentSummary summary = await getPaymentSummary();
|
||||||
final List<PaymentTransaction> history = await getPaymentHistory(period: 'week');
|
final List<PaymentTransaction> history = await getPaymentHistory(period: 'week');
|
||||||
emit(PaymentsLoaded(
|
emit(PaymentsLoaded(
|
||||||
summary: summary,
|
summary: summary,
|
||||||
|
=======
|
||||||
|
final List<StaffPayment> allPayments = await getPaymentSummary();
|
||||||
|
final PaymentStats stats = _calculateStats(allPayments);
|
||||||
|
|
||||||
|
final List<StaffPayment> history = await getPaymentHistory('week');
|
||||||
|
emit(PaymentsLoaded(
|
||||||
|
summary: stats,
|
||||||
|
>>>>>>> Stashed changes
|
||||||
history: history,
|
history: history,
|
||||||
activePeriod: 'week',
|
activePeriod: 'week',
|
||||||
));
|
));
|
||||||
@@ -44,10 +60,15 @@ class PaymentsBloc extends Bloc<PaymentsEvent, PaymentsState> {
|
|||||||
if (currentState is PaymentsLoaded) {
|
if (currentState is PaymentsLoaded) {
|
||||||
if (currentState.activePeriod == event.period) return;
|
if (currentState.activePeriod == event.period) return;
|
||||||
|
|
||||||
|
<<<<<<< Updated upstream
|
||||||
// Optimistic update or set loading state if expecting delay
|
// Optimistic update or set loading state if expecting delay
|
||||||
// For now, we'll keep the current data and fetch new history
|
// For now, we'll keep the current data and fetch new history
|
||||||
try {
|
try {
|
||||||
final List<PaymentTransaction> newHistory = await getPaymentHistory(period: event.period);
|
final List<PaymentTransaction> newHistory = await getPaymentHistory(period: event.period);
|
||||||
|
=======
|
||||||
|
try {
|
||||||
|
final List<StaffPayment> newHistory = await getPaymentHistory(event.period);
|
||||||
|
>>>>>>> Stashed changes
|
||||||
emit(currentState.copyWith(
|
emit(currentState.copyWith(
|
||||||
history: newHistory,
|
history: newHistory,
|
||||||
activePeriod: event.period,
|
activePeriod: event.period,
|
||||||
@@ -57,4 +78,41 @@ class PaymentsBloc extends Bloc<PaymentsEvent, PaymentsState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
<<<<<<< Updated upstream
|
||||||
|
=======
|
||||||
|
|
||||||
|
PaymentStats _calculateStats(List<StaffPayment> payments) {
|
||||||
|
double total = 0;
|
||||||
|
double pending = 0;
|
||||||
|
double weekly = 0;
|
||||||
|
double monthly = 0;
|
||||||
|
|
||||||
|
final DateTime now = DateTime.now();
|
||||||
|
|
||||||
|
for (final StaffPayment p in payments) {
|
||||||
|
// Assuming all payments count towards total history
|
||||||
|
total += p.amount;
|
||||||
|
|
||||||
|
if (p.status == PaymentStatus.pending) {
|
||||||
|
pending += p.amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p.paidAt != null) {
|
||||||
|
if (now.difference(p.paidAt!).inDays < 7) {
|
||||||
|
weekly += p.amount;
|
||||||
|
}
|
||||||
|
if (now.month == p.paidAt!.month && now.year == p.paidAt!.year) {
|
||||||
|
monthly += p.amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return PaymentStats(
|
||||||
|
totalEarnings: total,
|
||||||
|
pendingEarnings: pending,
|
||||||
|
weeklyEarnings: weekly,
|
||||||
|
monthlyEarnings: monthly,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
>>>>>>> Stashed changes
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
|
<<<<<<< Updated upstream
|
||||||
import '../../../domain/entities/payment_summary.dart';
|
import '../../../domain/entities/payment_summary.dart';
|
||||||
import '../../../domain/entities/payment_transaction.dart';
|
import '../../../domain/entities/payment_transaction.dart';
|
||||||
|
=======
|
||||||
|
import 'package:krow_domain/krow_domain.dart';
|
||||||
|
import '../../models/payment_stats.dart';
|
||||||
|
>>>>>>> Stashed changes
|
||||||
|
|
||||||
abstract class PaymentsState extends Equatable {
|
abstract class PaymentsState extends Equatable {
|
||||||
const PaymentsState();
|
const PaymentsState();
|
||||||
@@ -14,8 +19,13 @@ class PaymentsInitial extends PaymentsState {}
|
|||||||
class PaymentsLoading extends PaymentsState {}
|
class PaymentsLoading extends PaymentsState {}
|
||||||
|
|
||||||
class PaymentsLoaded extends PaymentsState {
|
class PaymentsLoaded extends PaymentsState {
|
||||||
|
<<<<<<< Updated upstream
|
||||||
final PaymentSummary summary;
|
final PaymentSummary summary;
|
||||||
final List<PaymentTransaction> history;
|
final List<PaymentTransaction> history;
|
||||||
|
=======
|
||||||
|
final PaymentStats summary;
|
||||||
|
final List<StaffPayment> history;
|
||||||
|
>>>>>>> Stashed changes
|
||||||
final String activePeriod;
|
final String activePeriod;
|
||||||
|
|
||||||
const PaymentsLoaded({
|
const PaymentsLoaded({
|
||||||
@@ -25,8 +35,13 @@ class PaymentsLoaded extends PaymentsState {
|
|||||||
});
|
});
|
||||||
|
|
||||||
PaymentsLoaded copyWith({
|
PaymentsLoaded copyWith({
|
||||||
|
<<<<<<< Updated upstream
|
||||||
PaymentSummary? summary,
|
PaymentSummary? summary,
|
||||||
List<PaymentTransaction>? history,
|
List<PaymentTransaction>? history,
|
||||||
|
=======
|
||||||
|
PaymentStats? summary,
|
||||||
|
List<StaffPayment>? history,
|
||||||
|
>>>>>>> Stashed changes
|
||||||
String? activePeriod,
|
String? activePeriod,
|
||||||
}) {
|
}) {
|
||||||
return PaymentsLoaded(
|
return PaymentsLoaded(
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import 'package:equatable/equatable.dart';
|
||||||
|
|
||||||
|
class PaymentStats extends Equatable {
|
||||||
|
final double weeklyEarnings;
|
||||||
|
final double monthlyEarnings;
|
||||||
|
final double pendingEarnings;
|
||||||
|
final double totalEarnings;
|
||||||
|
|
||||||
|
const PaymentStats({
|
||||||
|
this.weeklyEarnings = 0.0,
|
||||||
|
this.monthlyEarnings = 0.0,
|
||||||
|
this.pendingEarnings = 0.0,
|
||||||
|
this.totalEarnings = 0.0,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [
|
||||||
|
weeklyEarnings,
|
||||||
|
monthlyEarnings,
|
||||||
|
pendingEarnings,
|
||||||
|
totalEarnings,
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -3,7 +3,11 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
import 'package:flutter_modular/flutter_modular.dart';
|
import 'package:flutter_modular/flutter_modular.dart';
|
||||||
import 'package:lucide_icons/lucide_icons.dart';
|
import 'package:lucide_icons/lucide_icons.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
<<<<<<< Updated upstream
|
||||||
import '../../domain/entities/payment_transaction.dart';
|
import '../../domain/entities/payment_transaction.dart';
|
||||||
|
=======
|
||||||
|
import 'package:krow_domain/krow_domain.dart';
|
||||||
|
>>>>>>> Stashed changes
|
||||||
import '../blocs/payments/payments_bloc.dart';
|
import '../blocs/payments/payments_bloc.dart';
|
||||||
import '../blocs/payments/payments_event.dart';
|
import '../blocs/payments/payments_event.dart';
|
||||||
import '../blocs/payments/payments_state.dart';
|
import '../blocs/payments/payments_state.dart';
|
||||||
@@ -177,11 +181,16 @@ class _PaymentsPageState extends State<PaymentsPage> {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
Column(
|
Column(
|
||||||
|
<<<<<<< Updated upstream
|
||||||
children: state.history.map((PaymentTransaction payment) {
|
children: state.history.map((PaymentTransaction payment) {
|
||||||
|
=======
|
||||||
|
children: state.history.map((StaffPayment payment) {
|
||||||
|
>>>>>>> Stashed changes
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.only(bottom: 8),
|
padding: const EdgeInsets.only(bottom: 8),
|
||||||
child: PaymentHistoryItem(
|
child: PaymentHistoryItem(
|
||||||
amount: payment.amount,
|
amount: payment.amount,
|
||||||
|
<<<<<<< Updated upstream
|
||||||
title: payment.title,
|
title: payment.title,
|
||||||
location: payment.location,
|
location: payment.location,
|
||||||
address: payment.address,
|
address: payment.address,
|
||||||
@@ -190,6 +199,16 @@ class _PaymentsPageState extends State<PaymentsPage> {
|
|||||||
hours: payment.hours,
|
hours: payment.hours,
|
||||||
rate: payment.rate,
|
rate: payment.rate,
|
||||||
status: payment.status,
|
status: payment.status,
|
||||||
|
=======
|
||||||
|
title: 'Assignment ${payment.assignmentId}',
|
||||||
|
location: 'Location', // TODO: Fetch from assignment
|
||||||
|
address: '',
|
||||||
|
date: payment.paidAt != null ? DateFormat('E, MMM d').format(payment.paidAt!) : 'Pending',
|
||||||
|
workedTime: '00:00 - 00:00', // TODO: Fetch from assignment
|
||||||
|
hours: 0,
|
||||||
|
rate: 0,
|
||||||
|
status: payment.status.toString().split('.').last,
|
||||||
|
>>>>>>> Stashed changes
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}).toList(),
|
}).toList(),
|
||||||
|
|||||||
@@ -2,9 +2,16 @@ name: staff_payments
|
|||||||
description: Staff Payments feature
|
description: Staff Payments feature
|
||||||
version: 0.0.1
|
version: 0.0.1
|
||||||
publish_to: 'none'
|
publish_to: 'none'
|
||||||
|
<<<<<<< Updated upstream
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=3.0.0 <4.0.0'
|
sdk: '>=3.0.0 <4.0.0'
|
||||||
|
=======
|
||||||
|
resolution: workspace
|
||||||
|
|
||||||
|
environment:
|
||||||
|
sdk: '>=3.10.0 <4.0.0'
|
||||||
|
>>>>>>> Stashed changes
|
||||||
flutter: ">=3.0.0"
|
flutter: ">=3.0.0"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -21,6 +28,11 @@ dependencies:
|
|||||||
path: ../../../core_localization
|
path: ../../../core_localization
|
||||||
krow_domain:
|
krow_domain:
|
||||||
path: ../../../domain
|
path: ../../../domain
|
||||||
|
<<<<<<< Updated upstream
|
||||||
|
=======
|
||||||
|
krow_core:
|
||||||
|
path: ../../../core
|
||||||
|
>>>>>>> Stashed changes
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|||||||
45
apps/mobile/prototypes/client_mobile_application/.gitignore
vendored
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
# Miscellaneous
|
||||||
|
*.class
|
||||||
|
*.log
|
||||||
|
*.pyc
|
||||||
|
*.swp
|
||||||
|
.DS_Store
|
||||||
|
.atom/
|
||||||
|
.build/
|
||||||
|
.buildlog/
|
||||||
|
.history
|
||||||
|
.svn/
|
||||||
|
.swiftpm/
|
||||||
|
migrate_working_dir/
|
||||||
|
|
||||||
|
# IntelliJ related
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
*.iws
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
# The .vscode folder contains launch configuration and tasks you configure in
|
||||||
|
# VS Code which you may wish to be included in version control, so this line
|
||||||
|
# is commented out by default.
|
||||||
|
#.vscode/
|
||||||
|
|
||||||
|
# Flutter/Dart/Pub related
|
||||||
|
**/doc/api/
|
||||||
|
**/ios/Flutter/.last_build_id
|
||||||
|
.dart_tool/
|
||||||
|
.flutter-plugins-dependencies
|
||||||
|
.pub-cache/
|
||||||
|
.pub/
|
||||||
|
/build/
|
||||||
|
/coverage/
|
||||||
|
|
||||||
|
# Symbolication related
|
||||||
|
app.*.symbols
|
||||||
|
|
||||||
|
# Obfuscation related
|
||||||
|
app.*.map.json
|
||||||
|
|
||||||
|
# Android Studio will place build artifacts here
|
||||||
|
/android/app/debug
|
||||||
|
/android/app/profile
|
||||||
|
/android/app/release
|
||||||
45
apps/mobile/prototypes/client_mobile_application/.metadata
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
# This file tracks properties of this Flutter project.
|
||||||
|
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
||||||
|
#
|
||||||
|
# This file should be version controlled and should not be manually edited.
|
||||||
|
|
||||||
|
version:
|
||||||
|
revision: "b45fa18946ecc2d9b4009952c636ba7e2ffbb787"
|
||||||
|
channel: "stable"
|
||||||
|
|
||||||
|
project_type: app
|
||||||
|
|
||||||
|
# Tracks metadata for the flutter migrate command
|
||||||
|
migration:
|
||||||
|
platforms:
|
||||||
|
- platform: root
|
||||||
|
create_revision: b45fa18946ecc2d9b4009952c636ba7e2ffbb787
|
||||||
|
base_revision: b45fa18946ecc2d9b4009952c636ba7e2ffbb787
|
||||||
|
- platform: android
|
||||||
|
create_revision: b45fa18946ecc2d9b4009952c636ba7e2ffbb787
|
||||||
|
base_revision: b45fa18946ecc2d9b4009952c636ba7e2ffbb787
|
||||||
|
- platform: ios
|
||||||
|
create_revision: b45fa18946ecc2d9b4009952c636ba7e2ffbb787
|
||||||
|
base_revision: b45fa18946ecc2d9b4009952c636ba7e2ffbb787
|
||||||
|
- platform: linux
|
||||||
|
create_revision: b45fa18946ecc2d9b4009952c636ba7e2ffbb787
|
||||||
|
base_revision: b45fa18946ecc2d9b4009952c636ba7e2ffbb787
|
||||||
|
- platform: macos
|
||||||
|
create_revision: b45fa18946ecc2d9b4009952c636ba7e2ffbb787
|
||||||
|
base_revision: b45fa18946ecc2d9b4009952c636ba7e2ffbb787
|
||||||
|
- platform: web
|
||||||
|
create_revision: b45fa18946ecc2d9b4009952c636ba7e2ffbb787
|
||||||
|
base_revision: b45fa18946ecc2d9b4009952c636ba7e2ffbb787
|
||||||
|
- platform: windows
|
||||||
|
create_revision: b45fa18946ecc2d9b4009952c636ba7e2ffbb787
|
||||||
|
base_revision: b45fa18946ecc2d9b4009952c636ba7e2ffbb787
|
||||||
|
|
||||||
|
# User provided section
|
||||||
|
|
||||||
|
# List of Local paths (relative to this file) that should be
|
||||||
|
# ignored by the migrate tool.
|
||||||
|
#
|
||||||
|
# Files that are not part of the templates will be ignored by default.
|
||||||
|
unmanaged_files:
|
||||||
|
- 'lib/main.dart'
|
||||||
|
- 'ios/Runner.xcodeproj/project.pbxproj'
|
||||||
16
apps/mobile/prototypes/client_mobile_application/README.md
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# client_app_mvp
|
||||||
|
|
||||||
|
A new Flutter project.
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
This project is a starting point for a Flutter application.
|
||||||
|
|
||||||
|
A few resources to get you started if this is your first Flutter project:
|
||||||
|
|
||||||
|
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
|
||||||
|
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
|
||||||
|
|
||||||
|
For help getting started with Flutter development, view the
|
||||||
|
[online documentation](https://docs.flutter.dev/), which offers tutorials,
|
||||||
|
samples, guidance on mobile development, and a full API reference.
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
# This file configures the analyzer, which statically analyzes Dart code to
|
||||||
|
# check for errors, warnings, and lints.
|
||||||
|
#
|
||||||
|
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
|
||||||
|
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
|
||||||
|
# invoked from the command line by running `flutter analyze`.
|
||||||
|
|
||||||
|
# The following line activates a set of recommended lints for Flutter apps,
|
||||||
|
# packages, and plugins designed to encourage good coding practices.
|
||||||
|
include: package:flutter_lints/flutter.yaml
|
||||||
|
|
||||||
|
linter:
|
||||||
|
# The lint rules applied to this project can be customized in the
|
||||||
|
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
|
||||||
|
# included above or to enable additional rules. A list of all available lints
|
||||||
|
# and their documentation is published at https://dart.dev/lints.
|
||||||
|
#
|
||||||
|
# Instead of disabling a lint rule for the entire project in the
|
||||||
|
# section below, it can also be suppressed for a single line of code
|
||||||
|
# or a specific dart file by using the `// ignore: name_of_lint` and
|
||||||
|
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
|
||||||
|
# producing the lint.
|
||||||
|
rules:
|
||||||
|
# avoid_print: false # Uncomment to disable the `avoid_print` rule
|
||||||
|
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
|
||||||
|
|
||||||
|
# Additional information about this file can be found at
|
||||||
|
# https://dart.dev/guides/language/analysis-options
|
||||||
14
apps/mobile/prototypes/client_mobile_application/android/.gitignore
vendored
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
gradle-wrapper.jar
|
||||||
|
/.gradle
|
||||||
|
/captures/
|
||||||
|
/gradlew
|
||||||
|
/gradlew.bat
|
||||||
|
/local.properties
|
||||||
|
GeneratedPluginRegistrant.java
|
||||||
|
.cxx/
|
||||||
|
|
||||||
|
# Remember to never publicly share your keystore.
|
||||||
|
# See https://flutter.dev/to/reference-keystore
|
||||||
|
key.properties
|
||||||
|
**/*.keystore
|
||||||
|
**/*.jks
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
plugins {
|
||||||
|
id("com.android.application")
|
||||||
|
id("kotlin-android")
|
||||||
|
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
|
||||||
|
id("dev.flutter.flutter-gradle-plugin")
|
||||||
|
id("com.google.gms.google-services")
|
||||||
|
}
|
||||||
|
|
||||||
|
android {
|
||||||
|
namespace = "com.example.client_app_mvp"
|
||||||
|
compileSdk = flutter.compileSdkVersion
|
||||||
|
ndkVersion = flutter.ndkVersion
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility = JavaVersion.VERSION_17
|
||||||
|
targetCompatibility = JavaVersion.VERSION_17
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = JavaVersion.VERSION_17.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||||
|
applicationId = "com.example.client_app_mvp"
|
||||||
|
// You can update the following values to match your application needs.
|
||||||
|
// For more information, see: https://flutter.dev/to/review-gradle-config.
|
||||||
|
minSdk = flutter.minSdkVersion
|
||||||
|
targetSdk = flutter.targetSdkVersion
|
||||||
|
versionCode = flutter.versionCode
|
||||||
|
versionName = flutter.versionName
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
// TODO: Add your own signing config for the release build.
|
||||||
|
// Signing with the debug keys for now, so `flutter run --release` works.
|
||||||
|
signingConfig = signingConfigs.getByName("debug")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
flutter {
|
||||||
|
source = "../.."
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
{
|
||||||
|
"project_info": {
|
||||||
|
"project_number": "717206318340",
|
||||||
|
"project_id": "krow-apps",
|
||||||
|
"storage_bucket": "krow-apps.firebasestorage.app"
|
||||||
|
},
|
||||||
|
"client": [
|
||||||
|
{
|
||||||
|
"client_info": {
|
||||||
|
"mobilesdk_app_id": "1:717206318340:android:b0bff06f9967d8678af451",
|
||||||
|
"android_client_info": {
|
||||||
|
"package_name": "com.example.client_app_mvp"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"oauth_client": [
|
||||||
|
{
|
||||||
|
"client_id": "717206318340-9c24vluvsda8gh0pt8gk9sd7vj2nptn2.apps.googleusercontent.com",
|
||||||
|
"client_type": 3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"api_key": [
|
||||||
|
{
|
||||||
|
"current_key": "AIzaSyCXKJ5yME2a4FlrAzZA5LzSt97JwEwn9qE"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"services": {
|
||||||
|
"appinvite_service": {
|
||||||
|
"other_platform_oauth_client": [
|
||||||
|
{
|
||||||
|
"client_id": "717206318340-9c24vluvsda8gh0pt8gk9sd7vj2nptn2.apps.googleusercontent.com",
|
||||||
|
"client_type": 3
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"client_info": {
|
||||||
|
"mobilesdk_app_id": "1:717206318340:android:d3eac8c3774905e08af451",
|
||||||
|
"android_client_info": {
|
||||||
|
"package_name": "com.example.staff_app_mvp"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"oauth_client": [
|
||||||
|
{
|
||||||
|
"client_id": "717206318340-9c24vluvsda8gh0pt8gk9sd7vj2nptn2.apps.googleusercontent.com",
|
||||||
|
"client_type": 3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"api_key": [
|
||||||
|
{
|
||||||
|
"current_key": "AIzaSyCXKJ5yME2a4FlrAzZA5LzSt97JwEwn9qE"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"services": {
|
||||||
|
"appinvite_service": {
|
||||||
|
"other_platform_oauth_client": [
|
||||||
|
{
|
||||||
|
"client_id": "717206318340-9c24vluvsda8gh0pt8gk9sd7vj2nptn2.apps.googleusercontent.com",
|
||||||
|
"client_type": 3
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"configuration_version": "1"
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<!-- The INTERNET permission is required for development. Specifically,
|
||||||
|
the Flutter tool needs it to communicate with the running application
|
||||||
|
to allow setting breakpoints, to provide hot reload, etc.
|
||||||
|
-->
|
||||||
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
|
</manifest>
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<application
|
||||||
|
android:label="Krow Client App MVP"
|
||||||
|
android:name="${applicationName}"
|
||||||
|
android:icon="@mipmap/launcher_icon">
|
||||||
|
<activity
|
||||||
|
android:name=".MainActivity"
|
||||||
|
android:exported="true"
|
||||||
|
android:launchMode="singleTop"
|
||||||
|
android:taskAffinity=""
|
||||||
|
android:theme="@style/LaunchTheme"
|
||||||
|
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||||
|
android:hardwareAccelerated="true"
|
||||||
|
android:windowSoftInputMode="adjustResize">
|
||||||
|
<!-- Specifies an Android theme to apply to this Activity as soon as
|
||||||
|
the Android process has started. This theme is visible to the user
|
||||||
|
while the Flutter UI initializes. After that, this theme continues
|
||||||
|
to determine the Window background behind the Flutter UI. -->
|
||||||
|
<meta-data
|
||||||
|
android:name="io.flutter.embedding.android.NormalTheme"
|
||||||
|
android:resource="@style/NormalTheme"
|
||||||
|
/>
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
<!-- Don't delete the meta-data below.
|
||||||
|
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
||||||
|
<meta-data
|
||||||
|
android:name="flutterEmbedding"
|
||||||
|
android:value="2" />
|
||||||
|
</application>
|
||||||
|
<!-- Required to query activities that can process text, see:
|
||||||
|
https://developer.android.com/training/package-visibility and
|
||||||
|
https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.
|
||||||
|
|
||||||
|
In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
|
||||||
|
<queries>
|
||||||
|
<intent>
|
||||||
|
<action android:name="android.intent.action.PROCESS_TEXT"/>
|
||||||
|
<data android:mimeType="text/plain"/>
|
||||||
|
</intent>
|
||||||
|
</queries>
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
|
</manifest>
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package com.example.client_app_mvp
|
||||||
|
|
||||||
|
import io.flutter.embedding.android.FlutterActivity
|
||||||
|
|
||||||
|
class MainActivity : FlutterActivity()
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Modify this file to customize your launch splash screen -->
|
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:drawable="?android:colorBackground" />
|
||||||
|
|
||||||
|
<!-- You can insert your own image assets here -->
|
||||||
|
<!-- <item>
|
||||||
|
<bitmap
|
||||||
|
android:gravity="center"
|
||||||
|
android:src="@mipmap/launch_image" />
|
||||||
|
</item> -->
|
||||||
|
</layer-list>
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Modify this file to customize your launch splash screen -->
|
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:drawable="@android:color/white" />
|
||||||
|
|
||||||
|
<!-- You can insert your own image assets here -->
|
||||||
|
<!-- <item>
|
||||||
|
<bitmap
|
||||||
|
android:gravity="center"
|
||||||
|
android:src="@mipmap/launch_image" />
|
||||||
|
</item> -->
|
||||||
|
</layer-list>
|
||||||
|
After Width: | Height: | Size: 544 B |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 442 B |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 721 B |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
@@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
|
||||||
|
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||||
|
<!-- Show a splash screen on the activity. Automatically removed when
|
||||||
|
the Flutter engine draws its first frame -->
|
||||||
|
<item name="android:windowBackground">@drawable/launch_background</item>
|
||||||
|
</style>
|
||||||
|
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||||
|
This theme determines the color of the Android Window while your
|
||||||
|
Flutter UI initializes, as well as behind your Flutter UI while its
|
||||||
|
running.
|
||||||
|
|
||||||
|
This Theme is only used starting with V2 of Flutter's Android embedding. -->
|
||||||
|
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||||
|
<item name="android:windowBackground">?android:colorBackground</item>
|
||||||
|
</style>
|
||||||
|
</resources>
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
|
||||||
|
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||||
|
<!-- Show a splash screen on the activity. Automatically removed when
|
||||||
|
the Flutter engine draws its first frame -->
|
||||||
|
<item name="android:windowBackground">@drawable/launch_background</item>
|
||||||
|
</style>
|
||||||
|
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||||
|
This theme determines the color of the Android Window while your
|
||||||
|
Flutter UI initializes, as well as behind your Flutter UI while its
|
||||||
|
running.
|
||||||
|
|
||||||
|
This Theme is only used starting with V2 of Flutter's Android embedding. -->
|
||||||
|
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||||
|
<item name="android:windowBackground">?android:colorBackground</item>
|
||||||
|
</style>
|
||||||
|
</resources>
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<!-- The INTERNET permission is required for development. Specifically,
|
||||||
|
the Flutter tool needs it to communicate with the running application
|
||||||
|
to allow setting breakpoints, to provide hot reload, etc.
|
||||||
|
-->
|
||||||
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
|
</manifest>
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
allprojects {
|
||||||
|
repositories {
|
||||||
|
google()
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val newBuildDir: Directory =
|
||||||
|
rootProject.layout.buildDirectory
|
||||||
|
.dir("../../build")
|
||||||
|
.get()
|
||||||
|
rootProject.layout.buildDirectory.value(newBuildDir)
|
||||||
|
|
||||||
|
subprojects {
|
||||||
|
val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name)
|
||||||
|
project.layout.buildDirectory.value(newSubprojectBuildDir)
|
||||||
|
}
|
||||||
|
subprojects {
|
||||||
|
project.evaluationDependsOn(":app")
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.register<Delete>("clean") {
|
||||||
|
delete(rootProject.layout.buildDirectory)
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError
|
||||||
|
android.useAndroidX=true
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-all.zip
|
||||||