refactor: centralize data connect error handling and resolve build issues across applications

This commit addresses several critical issues across the mobile monorepo:

1. Centralized Error Handling: Integrated DataErrorHandler mixin into all repository implementations, ensuring consistent mapping of Data Connect exceptions to domain AppExceptions.
2. Build Stabilization: Fixed numerous type mismatches, parameter signature errors in widgets (e.g., google_places_flutter itemBuilder), and naming conflicts (StaffSession, FirebaseAuth).
3. Code Quality: Applied 'dart fix' across all modified packages and manually cleared debug print statements and UI clutter.
4. Mono-repo alignment: Standardized Data Connect usage and aliasing ('dc.') for better maintainability.

Signed-off-by: Suriya <suriya@tenext.in>
This commit is contained in:
2026-02-06 13:28:57 +05:30
parent e0636e46a3
commit 5e7bf0d5c0
150 changed files with 1506 additions and 2547 deletions

View File

@@ -7,21 +7,12 @@
/// They will implement interfaces defined in feature packages once those are created.
library;
export 'src/mocks/auth_repository_mock.dart';
export 'src/mocks/shifts_repository_mock.dart';
export 'src/mocks/staff_repository_mock.dart';
export 'src/mocks/profile_repository_mock.dart';
export 'src/mocks/event_repository_mock.dart';
export 'src/mocks/skill_repository_mock.dart';
export 'src/mocks/financial_repository_mock.dart';
export 'src/mocks/rating_repository_mock.dart';
export 'src/mocks/support_repository_mock.dart';
export 'src/mocks/home_repository_mock.dart';
export 'src/mocks/business_repository_mock.dart';
export 'src/mocks/order_repository_mock.dart';
export 'src/data_connect_module.dart';
export 'src/session/client_session_store.dart';
// Export the generated Data Connect SDK
export 'src/dataconnect_generated/generated.dart';
export 'src/session/staff_session_store.dart';
export 'src/mixins/data_error_handler.dart';

View File

@@ -1,19 +1,10 @@
import 'package:flutter_modular/flutter_modular.dart';
import 'mocks/auth_repository_mock.dart';
import 'mocks/business_repository_mock.dart';
import 'mocks/home_repository_mock.dart';
import 'mocks/order_repository_mock.dart';
import 'mocks/profile_repository_mock.dart';
/// A module that provides Data Connect dependencies, including mocks.
/// A module that provides Data Connect dependencies.
class DataConnectModule extends Module {
@override
void exportedBinds(Injector i) {
// Make these mocks available to any module that imports this one.
i.addLazySingleton(AuthRepositoryMock.new);
i.addLazySingleton(ProfileRepositoryMock.new);
i.addLazySingleton(HomeRepositoryMock.new);
i.addLazySingleton(BusinessRepositoryMock.new);
i.addLazySingleton(OrderRepositoryMock.new);
// No mock bindings anymore.
// Real repositories are instantiated in their feature modules.
}
}

View File

@@ -0,0 +1,44 @@
import 'dart:async';
import 'dart:io';
import 'package:firebase_core/firebase_core.dart';
import 'package:krow_domain/krow_domain.dart';
/// Mixin to handle Data Layer errors and map them to Domain Failures.
///
/// Use this in Repositories to wrap remote calls.
/// It catches [SocketException], [FirebaseException], etc., and throws [AppException].
mixin DataErrorHandler {
/// Executes a Future and maps low-level exceptions to [AppException].
///
/// [timeout] defaults to 30 seconds.
Future<T> executeProtected<T>(
Future<T> Function() action, {
Duration timeout = const Duration(seconds: 30),
}) async {
try {
return await action().timeout(timeout);
} on TimeoutException {
throw ServiceUnavailableException(
technicalMessage: 'Request timed out after ${timeout.inSeconds}s');
} on SocketException catch (e) {
throw NetworkException(technicalMessage: 'SocketException: ${e.message}');
} on FirebaseException catch (e) {
if (e.code == 'unavailable' || e.code == 'network-request-failed') {
throw NetworkException(
technicalMessage: 'Firebase ${e.code}: ${e.message}');
}
if (e.code == 'deadline-exceeded') {
throw ServiceUnavailableException(
technicalMessage: 'Firebase ${e.code}: ${e.message}');
}
// Fallback for other Firebase errors
throw ServerException(
technicalMessage: 'Firebase ${e.code}: ${e.message}');
} catch (e) {
// If it's already an AppException, rethrow it
if (e is AppException) rethrow;
throw UnknownException(technicalMessage: e.toString());
}
}
}

View File

@@ -1,48 +0,0 @@
import 'package:krow_domain/krow_domain.dart';
// TODO: Implement AuthRepositoryInterface once defined in a feature package.
class AuthRepositoryMock {
Stream<User?> get currentUser => Stream.value(
const User(id: 'mock_user_1', email: 'test@krow.com', role: 'staff'),
);
Future<String?> signInWithPhone(String phoneNumber) async {
await Future.delayed(const Duration(milliseconds: 500));
return 'mock_verification_id';
}
Future<User?> verifyOtp(String verificationId, String smsCode) async {
await Future.delayed(const Duration(milliseconds: 500));
return const User(id: 'mock_user_1', email: 'test@krow.com', role: 'staff');
}
Future<void> signOut() async {
await Future.delayed(const Duration(milliseconds: 200));
}
/// Signs in a user with email and password (Mock).
Future<User> signInWithEmail(String email, String password) async {
await Future.delayed(const Duration(milliseconds: 500));
return User(id: 'mock_client_1', email: email, role: 'client_admin');
}
/// Registers a new user with email and password (Mock).
Future<User> signUpWithEmail(
String email,
String password,
String companyName,
) async {
await Future.delayed(const Duration(milliseconds: 500));
return User(id: 'mock_client_new', email: email, role: 'client_admin');
}
/// Authenticates using a social provider (Mock).
Future<User> signInWithSocial(String provider) async {
await Future.delayed(const Duration(milliseconds: 500));
return const User(
id: 'mock_social_user',
email: 'social@example.com',
role: 'client_admin',
);
}
}

View File

@@ -1,54 +0,0 @@
import 'package:krow_domain/krow_domain.dart';
// TODO: Implement BusinessRepositoryInterface once defined in a feature package.
class BusinessRepositoryMock {
Future<Business?> getBusiness(String id) async {
await Future.delayed(const Duration(milliseconds: 300));
return const Business(
id: 'biz_1',
name: 'Acme Events Ltd',
registrationNumber: 'REG123456',
status: BusinessStatus.active,
avatar: 'https://via.placeholder.com/150',
);
}
Future<List<Hub>> getHubs(String businessId) async {
await Future.delayed(const Duration(milliseconds: 300));
return <Hub>[
const Hub(
id: 'hub_1',
businessId: 'biz_1',
name: 'London HQ',
address: '123 Oxford Street, London',
status: HubStatus.active,
),
];
}
Future<Hub> createHub({
required String businessId,
required String name,
required String address,
}) async {
await Future.delayed(const Duration(milliseconds: 500));
return Hub(
id: 'hub_${DateTime.now().millisecondsSinceEpoch}',
businessId: businessId,
name: name,
address: address,
status: HubStatus.active,
);
}
Future<void> deleteHub(String id) async {
await Future.delayed(const Duration(milliseconds: 300));
}
Future<void> assignNfcTag({
required String hubId,
required String nfcTagId,
}) async {
await Future.delayed(const Duration(milliseconds: 500));
}
}

View File

@@ -1,58 +0,0 @@
import 'package:krow_domain/krow_domain.dart';
// TODO: Implement EventRepositoryInterface once defined in a feature package.
class EventRepositoryMock {
Future<Assignment> applyForPosition(String positionId, String staffId) async {
await Future<void>.delayed(const Duration(milliseconds: 600));
return Assignment(
id: 'assign_1',
positionId: positionId,
staffId: staffId,
status: AssignmentStatus.assigned,
);
}
Future<Event?> getEvent(String id) async {
await Future<void>.delayed(const Duration(milliseconds: 300));
return _mockEvent;
}
Future<List<EventShift>> getEventShifts(String eventId) async {
await Future<void>.delayed(const Duration(milliseconds: 300));
return <EventShift>[
const EventShift(
id: 'shift_1',
eventId: 'event_1',
name: 'Morning Setup',
address: 'Hyde Park, London',
),
];
}
Future<List<Assignment>> getStaffAssignments(String staffId) async {
await Future<void>.delayed(const Duration(milliseconds: 500));
return <Assignment>[
const Assignment(
id: 'assign_1',
positionId: 'pos_1',
staffId: 'staff_1',
status: AssignmentStatus.confirmed,
),
];
}
Future<List<Event>> getUpcomingEvents() async {
await Future<void>.delayed(const Duration(milliseconds: 800));
return <Event>[_mockEvent];
}
static final Event _mockEvent = Event(
id: 'event_1',
businessId: 'biz_1',
hubId: 'hub_1',
name: 'Summer Festival 2026',
date: DateTime.now().add(const Duration(days: 10)),
status: EventStatus.active,
contractType: 'freelance',
);
}

View File

@@ -1,57 +0,0 @@
import 'package:krow_domain/krow_domain.dart';
// TODO: Implement FinancialRepositoryInterface once defined in a feature package.
class FinancialRepositoryMock {
Future<List<Invoice>> getInvoices(String businessId) async {
await Future.delayed(const Duration(milliseconds: 500));
return <Invoice>[
const Invoice(
id: 'inv_1',
eventId: 'event_1',
businessId: 'biz_1',
status: InvoiceStatus.paid,
totalAmount: 1500.0,
workAmount: 1400.0,
addonsAmount: 100.0,
invoiceNumber: 'INV-1',
issueDate: null,
),
];
}
Future<List<StaffPayment>> getStaffPayments(String staffId) async {
await Future.delayed(const Duration(milliseconds: 500));
return <StaffPayment>[
StaffPayment(
id: 'pay_1',
staffId: staffId,
assignmentId: 'assign_1',
amount: 120.0,
status: PaymentStatus.paid,
paidAt: DateTime.now().subtract(const Duration(days: 2)),
),
];
}
Future<List<InvoiceItem>> getInvoiceItems(String invoiceId) async {
await Future.delayed(const Duration(milliseconds: 500));
return <InvoiceItem>[
const InvoiceItem(
id: 'item_1',
invoiceId: 'inv_1',
staffId: 'staff_1',
workHours: 8.0,
rate: 25.0,
amount: 200.0,
),
const InvoiceItem(
id: 'item_2',
invoiceId: 'inv_1',
staffId: 'staff_2',
workHours: 6.0,
rate: 30.0,
amount: 180.0,
),
];
}
}

View File

@@ -1,32 +0,0 @@
import 'package:krow_domain/krow_domain.dart';
import '../session/client_session_store.dart';
/// Mock implementation of data source for Home dashboard data.
///
/// This mock simulates backend responses for dashboard-related queries.
class HomeRepositoryMock {
/// Returns a mock [HomeDashboardData].
Future<HomeDashboardData> getDashboardData() async {
// Simulate network delay
await Future.delayed(const Duration(milliseconds: 500));
return const HomeDashboardData(
weeklySpending: 4250.0,
next7DaysSpending: 6100.0,
weeklyShifts: 12,
next7DaysScheduled: 18,
totalNeeded: 10,
totalFilled: 8,
);
}
/// Returns the current user's session data.
///
/// Returns a tuple of (businessName, photoUrl).
(String, String?) getUserSession() {
final ClientSession? session = ClientSessionStore.instance.session;
final String businessName = session?.business?.businessName ?? 'Your Company';
final String? photoUrl = session?.userPhotoUrl;
return (businessName, photoUrl);
}
}

View File

@@ -1,159 +0,0 @@
import 'package:krow_domain/krow_domain.dart';
/// Mock implementation of order-related data operations.
///
/// This class simulates backend responses for order types and order creation.
/// It is used by the feature-level repository implementations.
class OrderRepositoryMock {
/// Returns a list of available [OrderType]s.
Future<List<OrderType>> getOrderTypes() async {
await Future<void>.delayed(const Duration(milliseconds: 500));
return const <OrderType>[
OrderType(
id: 'rapid',
titleKey: 'client_create_order.types.rapid',
descriptionKey: 'client_create_order.types.rapid_desc',
),
OrderType(
id: 'one-time',
titleKey: 'client_create_order.types.one_time',
descriptionKey: 'client_create_order.types.one_time_desc',
),
OrderType(
id: 'recurring',
titleKey: 'client_create_order.types.recurring',
descriptionKey: 'client_create_order.types.recurring_desc',
),
OrderType(
id: 'permanent',
titleKey: 'client_create_order.types.permanent',
descriptionKey: 'client_create_order.types.permanent_desc',
),
];
}
/// Simulates creating a one-time order.
Future<void> createOneTimeOrder(OneTimeOrder order) async {
await Future<void>.delayed(const Duration(milliseconds: 800));
}
/// Simulates creating a rapid order.
Future<void> createRapidOrder(String description) async {
await Future<void>.delayed(const Duration(seconds: 1));
}
/// Returns a mock list of client orders.
Future<List<OrderItem>> getOrders() async {
await Future<void>.delayed(const Duration(milliseconds: 500));
return <OrderItem>[
OrderItem(
id: '1',
orderId: 'order_1',
title: 'Server - Wedding',
clientName: 'Grand Plaza Hotel',
status: 'filled',
date: DateTime.now()
.add(const Duration(days: 1))
.toIso8601String()
.split('T')[0],
startTime: '16:00',
endTime: '23:00',
location: 'Grand Plaza Hotel, 123 Main St',
locationAddress: 'Grand Plaza Hotel, 123 Main St',
filled: 10,
workersNeeded: 10,
hourlyRate: 22.0,
confirmedApps: List<Map<String, dynamic>>.generate(
10,
(int index) => <String, dynamic>{
'id': 'app_$index',
'worker_id': 'w_$index',
'worker_name': 'Worker ${String.fromCharCode(65 + index)}',
'status': 'confirmed',
'check_in_time': index < 5 ? '15:55' : null,
},
),
),
OrderItem(
id: '2',
orderId: 'order_2',
title: 'Bartender - Private Event',
clientName: 'Taste of the Town',
status: 'open',
date: DateTime.now()
.add(const Duration(days: 1))
.toIso8601String()
.split('T')[0],
startTime: '18:00',
endTime: '02:00',
location: 'Downtown Loft, 456 High St',
locationAddress: 'Downtown Loft, 456 High St',
filled: 4,
workersNeeded: 5,
hourlyRate: 28.0,
confirmedApps: List<Map<String, dynamic>>.generate(
4,
(int index) => <String, dynamic>{
'id': 'app_b_$index',
'worker_id': 'w_b_$index',
'worker_name': 'Bartender ${index + 1}',
'status': 'confirmed',
},
),
),
OrderItem(
id: '3',
orderId: 'order_3',
title: 'Event Staff',
clientName: 'City Center',
status: 'in_progress',
date: DateTime.now().toIso8601String().split('T')[0],
startTime: '08:00',
endTime: '16:00',
location: 'Convention Center, 789 Blvd',
locationAddress: 'Convention Center, 789 Blvd',
filled: 15,
workersNeeded: 15,
hourlyRate: 20.0,
confirmedApps: List<Map<String, dynamic>>.generate(
15,
(int index) => <String, dynamic>{
'id': 'app_c_$index',
'worker_id': 'w_c_$index',
'worker_name': 'Staff ${index + 1}',
'status': 'confirmed',
'check_in_time': '07:55',
},
),
),
OrderItem(
id: '4',
orderId: 'order_4',
title: 'Coat Check',
clientName: 'The Met Museum',
status: 'completed',
date: DateTime.now()
.subtract(const Duration(days: 1))
.toIso8601String()
.split('T')[0],
startTime: '17:00',
endTime: '22:00',
location: 'The Met Museum, 1000 5th Ave',
locationAddress: 'The Met Museum, 1000 5th Ave',
filled: 2,
workersNeeded: 2,
hourlyRate: 18.0,
confirmedApps: List<Map<String, dynamic>>.generate(
2,
(int index) => <String, dynamic>{
'id': 'app_d_$index',
'worker_id': 'w_d_$index',
'worker_name': 'Checker ${index + 1}',
'status': 'confirmed',
'check_in_time': '16:50',
},
),
),
];
}
}

View File

@@ -1,90 +0,0 @@
import 'package:krow_domain/krow_domain.dart';
/// Mock implementation of profile-related data operations.
///
/// This mock provides hardcoded staff profile data for development and testing.
/// It simulates the behavior of a real backend service without requiring
/// actual API calls or Firebase Data Connect.
///
/// In production, this will be replaced with a real implementation that
/// interacts with Firebase Data Connect.
class ProfileRepositoryMock {
/// Fetches the staff profile for the given user ID.
///
/// Returns a [Staff] entity with mock data.
/// Simulates a network delay to mirror real API behavior.
///
/// Throws an exception if the profile cannot be retrieved.
Future<Staff> getStaffProfile(String userId) async {
// Simulate network delay
await Future.delayed(const Duration(milliseconds: 500));
// Return mock staff profile data
return const Staff(
id: '93673c8f-91aa-405d-8647-f1aac29cc19b',
authProviderId: 't8P3fYh4y1cPoZbbVPXUhfQCsDo3',
name: 'Krower',
email: 'worker@krow.com',
phone: '555-123-4567',
status: StaffStatus.active,
avatar: null,
address: null,
);
}
/// Signs out the current user.
///
/// Simulates the sign-out process with a delay.
/// In a real implementation, this would clear session tokens,
/// update Firebase auth state, etc.
Future<void> signOut() async {
// Simulate processing delay
await Future.delayed(const Duration(milliseconds: 300));
}
/// Fetches emergency contacts for the given staff ID.
///
/// Returns a list of [EmergencyContact].
Future<List<EmergencyContact>> getEmergencyContacts(String staffId) async {
await Future.delayed(const Duration(milliseconds: 500));
return [
const EmergencyContact(
name: 'Jane Doe',
phone: '555-987-6543',
relationship: RelationshipType.spouse,
id: 'contact_1',
),
];
}
/// Saves emergency contacts for the given staff ID.
Future<void> saveEmergencyContacts(
String staffId,
List<EmergencyContact> contacts,
) async {
await Future.delayed(const Duration(seconds: 1));
// Simulate save
}
/// Fetches selected industries for the given staff ID.
Future<List<String>> getStaffIndustries(String staffId) async {
await Future.delayed(const Duration(milliseconds: 500));
return ['hospitality', 'events'];
}
/// Fetches selected skills for the given staff ID.
Future<List<String>> getStaffSkills(String staffId) async {
await Future.delayed(const Duration(milliseconds: 500));
return ['Bartending', 'Server'];
}
/// Saves experience (industries and skills) for the given staff ID.
Future<void> saveExperience(
String staffId,
List<String> industries,
List<String> skills,
) async {
await Future.delayed(const Duration(seconds: 1));
// Simulate save
}
}

View File

@@ -1,22 +0,0 @@
import 'package:krow_domain/krow_domain.dart';
// TODO: Implement RatingRepositoryInterface once defined in a feature package.
class RatingRepositoryMock {
Future<List<StaffRating>> getStaffRatings(String staffId) async {
await Future.delayed(const Duration(milliseconds: 400));
return <StaffRating>[
const StaffRating(
id: 'rate_1',
staffId: 'staff_1',
eventId: 'event_1',
businessId: 'biz_1',
rating: 5,
comment: 'Great work!',
),
];
}
Future<void> submitRating(StaffRating rating) async {
await Future.delayed(const Duration(milliseconds: 500));
}
}

View File

@@ -1,89 +0,0 @@
import 'package:krow_domain/krow_domain.dart';
import 'package:intl/intl.dart';
// Mock Implementation for now.
class ShiftsRepositoryMock {
Future<List<Shift>> getMyShifts() async {
await Future.delayed(const Duration(milliseconds: 500));
return [
Shift(
id: 'm1',
title: 'Warehouse Assistant',
clientName: 'Amazon',
logoUrl: 'https://upload.wikimedia.org/wikipedia/commons/thumb/0/06/Amazon_2024.svg/500px-Amazon_2024.svg.png',
hourlyRate: 22.5,
date: DateFormat('yyyy-MM-dd').format(DateTime.now().add(const Duration(days: 1))),
startTime: '09:00',
endTime: '17:00',
location: 'Logistics Park',
locationAddress: '456 Industrial Way',
status: 'confirmed',
createdDate: DateTime.now().toIso8601String(),
description: 'Standard warehouse duties. Safety boots required.',
),
];
}
Future<List<Shift>> getAvailableShifts() async {
await Future.delayed(const Duration(milliseconds: 500));
return [
Shift(
id: 'a1',
title: 'Bartender',
clientName: 'Club Luxe',
logoUrl: null,
hourlyRate: 30.0,
date: DateFormat('yyyy-MM-dd').format(DateTime.now().add(const Duration(days: 3))),
startTime: '20:00',
endTime: '02:00',
location: 'City Center',
locationAddress: '789 Nightlife Blvd',
status: 'open',
createdDate: DateTime.now().toIso8601String(),
description: 'Experience mixing cocktails required.',
),
// Add more mocks if needed
];
}
Future<List<Shift>> getPendingAssignments() async {
await Future.delayed(const Duration(milliseconds: 500));
return [
Shift(
id: 'p1',
title: 'Event Server',
clientName: 'Grand Hotel',
logoUrl: null,
hourlyRate: 25.0,
date: DateFormat('yyyy-MM-dd').format(DateTime.now().add(const Duration(days: 2))),
startTime: '16:00',
endTime: '22:00',
location: 'Downtown',
locationAddress: '123 Main St',
status: 'pending',
createdDate: DateTime.now().toIso8601String(),
),
];
}
Future<Shift?> getShiftDetails(String shiftId) async {
await Future.delayed(const Duration(milliseconds: 500));
return Shift(
id: shiftId,
title: 'Event Server',
clientName: 'Grand Hotel',
logoUrl: null,
hourlyRate: 25.0,
date: DateFormat('yyyy-MM-dd').format(DateTime.now()),
startTime: '16:00',
endTime: '22:00',
location: 'Downtown',
locationAddress: '123 Main St, New York, NY',
status: 'open',
createdDate: DateTime.now().toIso8601String(),
description: 'Provide exceptional customer service. Respond to guest requests or concerns promptly and professionally.',
managers: [],
);
}
}

View File

@@ -1,40 +0,0 @@
import 'package:krow_domain/krow_domain.dart';
// TODO: Implement SkillRepositoryInterface once defined in a feature package.
class SkillRepositoryMock {
Future<void> addStaffSkill(StaffSkill skill) async {
await Future.delayed(const Duration(milliseconds: 500));
}
Future<List<Skill>> getAllSkills() async {
await Future.delayed(const Duration(milliseconds: 300));
return <Skill>[
const Skill(
id: 'skill_1',
categoryId: 'cat_1',
name: 'Bartender',
basePrice: 15.0,
),
const Skill(
id: 'skill_2',
categoryId: 'cat_2',
name: 'Security Guard',
basePrice: 18.0,
),
];
}
Future<List<StaffSkill>> getStaffSkills(String staffId) async {
await Future.delayed(const Duration(milliseconds: 400));
return <StaffSkill>[
const StaffSkill(
id: 'staff_skill_1',
staffId: 'staff_1',
skillId: 'skill_1',
level: SkillLevel.skilled,
experienceYears: 3,
status: StaffSkillStatus.verified,
),
];
}
}

View File

@@ -1,58 +0,0 @@
import 'package:krow_domain/krow_domain.dart';
// TODO: Implement StaffRepositoryInterface once defined in a feature package.
class StaffRepositoryMock {
Future<Staff> createStaffProfile(Staff staff) async {
await Future.delayed(const Duration(milliseconds: 500));
return staff;
}
Future<List<Membership>> getMemberships(String userId) async {
await Future.delayed(const Duration(milliseconds: 300));
return <Membership>[
Membership(
id: 'mem_1',
userId: userId,
memberableId: 'biz_1',
memberableType: 'business',
role: 'staff',
),
];
}
Future<Staff?> getStaffProfile(String userId) async {
await Future.delayed(const Duration(milliseconds: 400));
return Staff(
id: 'staff_1',
authProviderId: userId,
name: 'John Doe',
email: 'john@krow.com',
status: StaffStatus.active,
avatar: 'https://i.pravatar.cc/300',
);
}
Future<Staff> updateStaffProfile(Staff staff) async {
await Future.delayed(const Duration(milliseconds: 500));
return staff;
}
// Mock Availability Data Store
final Map<String, dynamic> _mockAvailability = {};
Future<Map<String, dynamic>> getAvailability(String userId, DateTime start, DateTime end) async {
await Future.delayed(const Duration(milliseconds: 300));
// Return mock structure: Date ISO String -> { isAvailable: bool, slots: { id: bool } }
// Auto-generate some data if empty
if (_mockAvailability.isEmpty) {
// Just return empty, let the caller handle defaults
}
return _mockAvailability;
}
Future<void> updateAvailability(String userId, String dateIso, Map<String, dynamic> data) async {
await Future.delayed(const Duration(milliseconds: 200));
_mockAvailability[dateIso] = data;
}
}

View File

@@ -1,25 +0,0 @@
import 'package:krow_domain/krow_domain.dart';
// TODO: Implement SupportRepositoryInterface once defined in a feature package.
class SupportRepositoryMock {
Future<List<Tag>> getTags() async {
await Future.delayed(const Duration(milliseconds: 200));
return <Tag>[
const Tag(id: 'tag_1', label: 'Urgent'),
const Tag(id: 'tag_2', label: 'VIP Event'),
];
}
Future<List<WorkingArea>> getWorkingAreas() async {
await Future.delayed(const Duration(milliseconds: 200));
return <WorkingArea>[
const WorkingArea(
id: 'area_1',
name: 'Central London',
centerLat: 51.5074,
centerLng: -0.1278,
radiusKm: 10.0,
),
];
}
}