Files
minhthu/lib/features/warehouse/presentation/pages/warehouse_selection_page.dart
Phuoc Nguyen 4b35d236df save
2025-10-28 16:48:31 +07:00

190 lines
5.6 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../../../core/di/providers.dart';
import '../../../../core/router/app_router.dart';
import '../widgets/warehouse_card.dart';
/// Warehouse selection page
/// Displays a list of warehouses and allows user to select one
///
/// Features:
/// - Loads warehouses on init
/// - Pull to refresh
/// - Loading, error, empty, and success states
/// - Navigate to operations page on warehouse selection
class WarehouseSelectionPage extends ConsumerStatefulWidget {
const WarehouseSelectionPage({super.key});
@override
ConsumerState<WarehouseSelectionPage> createState() =>
_WarehouseSelectionPageState();
}
class _WarehouseSelectionPageState
extends ConsumerState<WarehouseSelectionPage> {
@override
void initState() {
super.initState();
// Load warehouses and sync users when page is first created
Future.microtask(() {
ref.read(warehouseProvider.notifier).loadWarehouses();
// Sync users from API and save to local storage
ref.read(usersProvider.notifier).syncUsers();
});
}
@override
Widget build(BuildContext context) {
// Watch warehouse state
final warehouseState = ref.watch(warehouseProvider);
final warehouses = warehouseState.warehouses;
final isLoading = warehouseState.isLoading;
final error = warehouseState.error;
return Scaffold(
appBar: AppBar(
title: const Text('Select Warehouse'),
actions: [
IconButton(
icon: const Icon(Icons.refresh),
onPressed: () {
ref.read(warehouseProvider.notifier).loadWarehouses();
},
tooltip: 'Refresh',
),
],
),
body: _buildBody(
isLoading: isLoading,
error: error,
warehouses: warehouses,
),
);
}
/// Build body based on state
Widget _buildBody({
required bool isLoading,
required String? error,
required List warehouses,
}) {
// Loading state
if (isLoading && warehouses.isEmpty) {
return const Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CircularProgressIndicator(),
SizedBox(height: 16),
Text('Loading warehouses...'),
],
),
);
}
// Error state
if (error != null && warehouses.isEmpty) {
return Center(
child: Padding(
padding: const EdgeInsets.all(24),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.error_outline,
size: 64,
color: Theme.of(context).colorScheme.error,
),
const SizedBox(height: 16),
Text(
'Error Loading Warehouses',
style: Theme.of(context).textTheme.titleLarge,
),
const SizedBox(height: 8),
Text(
error,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.bodyMedium,
),
const SizedBox(height: 24),
FilledButton.icon(
onPressed: () {
ref.read(warehouseProvider.notifier).loadWarehouses();
},
icon: const Icon(Icons.refresh),
label: const Text('Retry'),
),
],
),
),
);
}
// Empty state
if (warehouses.isEmpty) {
return Center(
child: Padding(
padding: const EdgeInsets.all(24),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.inventory_2_outlined,
size: 64,
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
const SizedBox(height: 16),
Text(
'No Warehouses Available',
style: Theme.of(context).textTheme.titleLarge,
),
const SizedBox(height: 8),
Text(
'There are no warehouses to display.',
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.bodyMedium,
),
const SizedBox(height: 24),
OutlinedButton.icon(
onPressed: () {
ref.read(warehouseProvider.notifier).loadWarehouses();
},
icon: const Icon(Icons.refresh),
label: const Text('Refresh'),
),
],
),
),
);
}
// Success state - show warehouse list
return RefreshIndicator(
onRefresh: () async {
await ref.read(warehouseProvider.notifier).loadWarehouses();
},
child: ListView.builder(
padding: const EdgeInsets.symmetric(vertical: 8),
itemCount: warehouses.length,
itemBuilder: (context, index) {
final warehouse = warehouses[index];
return WarehouseCard(
warehouse: warehouse,
onTap: () {
// Select warehouse and navigate directly to products page
ref.read(warehouseProvider.notifier).selectWarehouse(warehouse);
// Navigate to products page with warehouse data
context.pushToProducts(
warehouse: warehouse,
operationType: 'import', // Default to import
);
},
);
},
),
);
}
}