// Version: 3.0 - シンプル製品マスタ画面(簡素版、サンプルデータ固定) import 'package:flutter/material.dart'; import '../../models/product.dart'; class ProductMasterScreen extends StatefulWidget { const ProductMasterScreen({super.key}); @override State createState() => _ProductMasterScreenState(); } class _ProductMasterScreenState extends State { List _products = []; @override void initState() { super.initState(); // サンプルデータ(簡素版) _products = [ Product(productCode: 'P001', name: 'サンプル商品 A', unitPrice: 1000.0, stock: 50), Product(productCode: 'P002', name: 'サンプル商品 B', unitPrice: 2500.0, stock: 30), ]; } Future _addProduct() async { await showDialog( context: context, builder: (ctx) => AlertDialog( title: const Text('新規製品登録'), content: SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ TextField(decoration: const InputDecoration(labelText: 'コード', hintText: 'P003')), SizedBox(height: 8), TextField(decoration: const InputDecoration(labelText: '名称', hintText: '新製品名'), onChanged: (v) => setState(() {})), SizedBox(height: 8), TextField(decoration: const InputDecoration(labelText: '単価', hintText: '1500.0'), keyboardType: TextInputType.number, onChanged: (v) => setState(() {})), SizedBox(height: 8), TextField(decoration: const InputDecoration(labelText: '在庫', hintText: '10'), keyboardType: TextInputType.number, onChanged: (v) => setState(() {})), ], ), ), actions: [ TextButton(onPressed: () => Navigator.pop(ctx), child: const Text('キャンセル')), ElevatedButton( onPressed: () { Navigator.pop(ctx); }, child: const Text('登録'), ), ], ), ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('/M3. 製品マスタ')), body: _products.isEmpty ? Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.inbox_outlined, size: 64, color: Colors.grey[300]), SizedBox(height: 16), Text('製品データがありません', style: TextStyle(color: Colors.grey)), SizedBox(height: 16), FloatingActionButton.extended( icon: Icon(Icons.add, color: Theme.of(context).primaryColor), label: const Text('新規登録'), onPressed: _addProduct, ), ], ), ) : ListView.builder( padding: const EdgeInsets.all(8), itemCount: _products.length, itemBuilder: (context, index) { final product = _products[index]; return Card( margin: EdgeInsets.zero, clipBehavior: Clip.antiAlias, child: ListTile( leading: CircleAvatar(backgroundColor: Colors.blue.shade100, child: Text(product.productCode ?? '-', style: const TextStyle(fontWeight: FontWeight.bold))), title: Text(product.name ?? '未入力'), subtitle: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ if (product.stock > 0) Text('在庫:${product.stock}個', style: const TextStyle(fontSize: 12)), Text('単価:¥${product.unitPrice}', style: const TextStyle(fontSize: 12)), ], ), ), ); }, ), floatingActionButton: FloatingActionButton.extended( icon: const Icon(Icons.add), label: const Text('新規登録'), onPressed: _addProduct, ), ); } }