h-1.flutter.4/lib/screens/master/warehouse_master_screen.dart

162 lines
No EOL
6.1 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Version: 1.9 - 倉庫マスタ画面(簡素版として維持)
// ※ DB モデルと同期していないため簡素版のまま
import 'package:flutter/material.dart';
/// 倉庫マスタ管理画面CRUD 機能付き - 簡素版)
class WarehouseMasterScreen extends StatefulWidget {
const WarehouseMasterScreen({super.key});
@override
State<WarehouseMasterScreen> createState() => _WarehouseMasterScreenState();
}
class _WarehouseMasterScreenState extends State<WarehouseMasterScreen> {
List<Map<String, dynamic>> _warehouses = [];
bool _loading = true;
@override
void initState() {
super.initState();
_loadWarehouses();
}
Future<void> _loadWarehouses() async {
setState(() => _loading = true);
try {
final demoData = [
{'id': 1, 'name': '札幌倉庫', 'area': '北海道', 'address': '〒040-0001 札幌市中央区'},
{'id': 2, 'name': '仙台倉庫', 'area': '東北', 'address': '〒980-0001 仙台市青葉区'},
{'id': 3, 'name': '東京倉庫', 'area': '関東', 'address': '〒100-0001 東京都千代田区'},
{'id': 4, 'name': '名古屋倉庫', 'area': '中部', 'address': '〒460-0001 名古屋市中村区'},
{'id': 5, 'name': '大阪倉庫', 'area': '近畿', 'address': '〒530-0001 大阪市中央区'},
];
setState(() => _warehouses = demoData);
} catch (e) {
if (mounted) ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('読み込みエラー:$e'), backgroundColor: Colors.red),
);
} finally {
setState(() => _loading = false);
}
}
Future<void> _addWarehouse() async {
final warehouse = <String, dynamic>{'id': DateTime.now().millisecondsSinceEpoch, 'name': '', 'area': '', 'address': ''};
final result = await showDialog<Map<String, dynamic>>(
context: context,
builder: (context) => _WarehouseDialogState(
Dialog(
child: SingleChildScrollView(
padding: EdgeInsets.zero,
child: ConstrainedBox(
constraints: const BoxConstraints(minHeight: 200),
child: WarehouseForm(warehouse: warehouse),
),
),
),
),
);
if (result != null && mounted) {
setState(() => _warehouses.add(result));
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('倉庫登録完了'), backgroundColor: Colors.green));
}
}
Future<void> _editWarehouse(int id) async {
final warehouse = _warehouses.firstWhere((w) => w['id'] == id);
final edited = await showDialog<Map<String, dynamic>>(
context: context,
builder: (context) => _WarehouseDialogState(
Dialog(
child: SingleChildScrollView(
padding: EdgeInsets.zero,
child: ConstrainedBox(
constraints: const BoxConstraints(minHeight: 200),
child: WarehouseForm(warehouse: warehouse),
),
),
),
),
);
if (edited != null && mounted) {
final index = _warehouses.indexWhere((w) => w['id'] == id);
setState(() => _warehouses[index] = edited);
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('倉庫更新完了'), backgroundColor: Colors.green));
}
}
Future<void> _deleteWarehouse(int id) async {
final confirmed = await showDialog<bool>(
context: context,
builder: (context) => AlertDialog(
title: const Text('倉庫削除'),
content: Text('この倉庫を削除しますか?'),
actions: [
TextButton(onPressed: () => Navigator.pop(context), child: const Text('キャンセル')),
ElevatedButton(
onPressed: () => Navigator.pop(context, true),
style: ElevatedButton.styleFrom(backgroundColor: Colors.red),
child: const Text('削除'),
),
],
),
);
if (confirmed == true) {
setState(() {
_warehouses.removeWhere((w) => w['id'] == id);
});
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('倉庫削除完了'), backgroundColor: Colors.green));
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('/M4. 倉庫マスタ'),
actions: [
IconButton(icon: const Icon(Icons.refresh), onPressed: _loadWarehouses),
IconButton(icon: const Icon(Icons.add), onPressed: _addWarehouse),
],
),
body: _loading ? const Center(child: CircularProgressIndicator()) :
_warehouses.isEmpty ? Center(child: Text('倉庫データがありません')) :
ListView.builder(
padding: const EdgeInsets.all(8),
itemCount: _warehouses.length,
itemBuilder: (context, index) {
final warehouse = _warehouses[index];
return Card(
margin: const EdgeInsets.only(bottom: 8),
child: ListTile(
leading: CircleAvatar(backgroundColor: Colors.orange.shade50, child: Icon(Icons.storage, color: Colors.orange)),
title: Text(warehouse['name'] ?? '倉庫(未入力)'),
subtitle: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Text('エリア:${warehouse['area']}'),
if (warehouse['address'] != null) Text('住所:${warehouse['address']}'),
]),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(icon: const Icon(Icons.edit), onPressed: () => _editWarehouse(warehouse['id'] as int)),
IconButton(icon: const Icon(Icons.delete), onPressed: () => _deleteWarehouse(warehouse['id'] as int)),
],
),
),
);
},
),
);
}
}
/// 倉庫フォーム部品(簡素版)
class WarehouseForm extends StatelessWidget {
final Map<String, dynamic> warehouse;
const