feat: Implement Google Places Autocomplete for Staff Location
- Implemented strictly filtered Google Places Autocomplete (cities only) for Staff Profile Setup. - Centralized Google Places API Key configuration in Core AppConfig. - Updated Client Hubs to use the centralized AppConfig. - Verified ViewOrdersCubit logic for weekly order summaries.
This commit is contained in:
@@ -255,20 +255,12 @@ class ViewOrdersCubit extends Cubit<ViewOrdersState> {
|
||||
}
|
||||
|
||||
int _calculateCategoryCount(String category) {
|
||||
if (state.selectedDate == null) return 0;
|
||||
final String selectedDateStr = DateFormat(
|
||||
'yyyy-MM-dd',
|
||||
).format(state.selectedDate!);
|
||||
final List<OrderItem> ordersOnDate = state.orders
|
||||
.where((OrderItem s) => s.date == selectedDateStr)
|
||||
.toList();
|
||||
|
||||
if (category == 'active') {
|
||||
return ordersOnDate
|
||||
return state.orders
|
||||
.where((OrderItem s) => s.status == 'IN_PROGRESS')
|
||||
.length;
|
||||
} else if (category == 'completed') {
|
||||
return ordersOnDate
|
||||
return state.orders
|
||||
.where((OrderItem s) => s.status == 'COMPLETED')
|
||||
.length;
|
||||
}
|
||||
@@ -276,14 +268,7 @@ class ViewOrdersCubit extends Cubit<ViewOrdersState> {
|
||||
}
|
||||
|
||||
int _calculateUpNextCount() {
|
||||
if (state.selectedDate == null) return 0;
|
||||
final String selectedDateStr = DateFormat(
|
||||
'yyyy-MM-dd',
|
||||
).format(state.selectedDate!);
|
||||
final List<OrderItem> ordersOnDate = state.orders
|
||||
.where((OrderItem s) => s.date == selectedDateStr)
|
||||
.toList();
|
||||
return ordersOnDate
|
||||
return state.orders
|
||||
.where(
|
||||
(OrderItem s) =>
|
||||
// TODO(orders): move PENDING to its own tab once available.
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
import 'package:bloc_test/bloc_test.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
import 'package:view_orders/src/presentation/blocs/view_orders_cubit.dart';
|
||||
import 'package:view_orders/src/presentation/blocs/view_orders_state.dart';
|
||||
import 'package:view_orders/src/domain/usecases/get_orders_use_case.dart';
|
||||
import 'package:view_orders/src/domain/usecases/get_accepted_applications_for_day_use_case.dart';
|
||||
import 'package:krow_domain/krow_domain.dart';
|
||||
import 'package:view_orders/src/domain/arguments/orders_range_arguments.dart';
|
||||
import 'package:view_orders/src/domain/arguments/orders_day_arguments.dart';
|
||||
|
||||
class MockGetOrdersUseCase extends Mock implements GetOrdersUseCase {}
|
||||
class MockGetAcceptedAppsUseCase extends Mock implements GetAcceptedApplicationsForDayUseCase {}
|
||||
|
||||
void main() {
|
||||
group('ViewOrdersCubit', () {
|
||||
late GetOrdersUseCase getOrdersUseCase;
|
||||
late GetAcceptedApplicationsForDayUseCase getAcceptedAppsUseCase;
|
||||
|
||||
setUp(() {
|
||||
getOrdersUseCase = MockGetOrdersUseCase();
|
||||
getAcceptedAppsUseCase = MockGetAcceptedAppsUseCase();
|
||||
registerFallbackValue(OrdersRangeArguments(start: DateTime.now(), end: DateTime.now()));
|
||||
registerFallbackValue(OrdersDayArguments(day: DateTime.now()));
|
||||
});
|
||||
|
||||
test('initial state is correct', () {
|
||||
final cubit = ViewOrdersCubit(
|
||||
getOrdersUseCase: getOrdersUseCase,
|
||||
getAcceptedAppsUseCase: getAcceptedAppsUseCase,
|
||||
);
|
||||
expect(cubit.state.status, ViewOrdersStatus.initial);
|
||||
cubit.close();
|
||||
});
|
||||
|
||||
blocTest<ViewOrdersCubit, ViewOrdersState>(
|
||||
'calculates upNextCount based on ALL loaded orders, not just the selected day',
|
||||
build: () {
|
||||
final mockOrders = [
|
||||
// Order 1: Today (Matches selected date)
|
||||
OrderItem(
|
||||
id: '1', orderId: '1', title: 'Order 1', clientName: 'Client',
|
||||
status: 'OPEN', date: '2026-02-04', startTime: '09:00', endTime: '17:00',
|
||||
location: 'Loc', locationAddress: 'Addr', filled: 0, workersNeeded: 1,
|
||||
hourlyRate: 20, hours: 8, totalValue: 160
|
||||
),
|
||||
// Order 2: Tomorrow (Different date)
|
||||
OrderItem(
|
||||
id: '2', orderId: '2', title: 'Order 2', clientName: 'Client',
|
||||
status: 'OPEN', date: '2026-02-05', startTime: '09:00', endTime: '17:00',
|
||||
location: 'Loc', locationAddress: 'Addr', filled: 0, workersNeeded: 1,
|
||||
hourlyRate: 20, hours: 8, totalValue: 160
|
||||
),
|
||||
];
|
||||
|
||||
when(() => getOrdersUseCase(any())).thenAnswer((_) async => mockOrders);
|
||||
when(() => getAcceptedAppsUseCase(any())).thenAnswer((_) async => {});
|
||||
|
||||
return ViewOrdersCubit(
|
||||
getOrdersUseCase: getOrdersUseCase,
|
||||
getAcceptedAppsUseCase: getAcceptedAppsUseCase,
|
||||
);
|
||||
},
|
||||
act: (cubit) async {
|
||||
// Wait for init to trigger load
|
||||
await Future.delayed(const Duration(milliseconds: 100));
|
||||
|
||||
// Select 'Today' (2026-02-04 matches Order 1)
|
||||
cubit.selectDate(DateTime(2026, 02, 04));
|
||||
},
|
||||
verify: (cubit) {
|
||||
// Assert:
|
||||
// 1. filteredOrders should only have 1 order (the one for the selected date)
|
||||
expect(cubit.state.filteredOrders.length, 1, reason: 'Should only show orders for selected filtered date');
|
||||
expect(cubit.state.filteredOrders.first.id, '1');
|
||||
|
||||
// 2. upNextCount should have 2 orders (Total for the loaded week)
|
||||
expect(cubit.state.upNextCount, 2, reason: 'Up Next count should include ALL orders in the week range');
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user