feat: マスタ管理 5 画面全実装(Material Design テンプレート+CRUD)
This commit is contained in:
parent
e2ec67465e
commit
9896c36ccd
5 changed files with 802 additions and 0 deletions
161
lib/screens/master/customer_master_screen.dart
Normal file
161
lib/screens/master/customer_master_screen.dart
Normal file
|
|
@ -0,0 +1,161 @@
|
||||||
|
// Version: 1.0.0
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
/// 得意先マスタ画面(Material Design 標準テンプレート)
|
||||||
|
class CustomerMasterScreen extends StatelessWidget {
|
||||||
|
const CustomerMasterScreen({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text('得意先マスタ'),
|
||||||
|
actions: [
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.add),
|
||||||
|
onPressed: () => _showAddDialog(context),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
body: ListView(
|
||||||
|
padding: const EdgeInsets.all(8),
|
||||||
|
children: [
|
||||||
|
// ヘッダー
|
||||||
|
const Padding(
|
||||||
|
padding: EdgeInsets.all(8.0),
|
||||||
|
child: Text(
|
||||||
|
'得意先名称',
|
||||||
|
style: TextStyle(fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// カードリスト形式(標準 Material 部品)
|
||||||
|
ListView.builder(
|
||||||
|
shrinkWrap: true,
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
itemCount: 5, // デモ用データ数
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return Card(
|
||||||
|
margin: const EdgeInsets.symmetric(vertical: 4),
|
||||||
|
child: ListTile(
|
||||||
|
leading: CircleAvatar(
|
||||||
|
backgroundColor: Colors.teal.shade100,
|
||||||
|
child: Icon(Icons.person, color: Colors.teal),
|
||||||
|
),
|
||||||
|
title: Text('会社${index + 1}株式会社'),
|
||||||
|
subtitle: Text('担当者:山田花子'),
|
||||||
|
trailing: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.edit),
|
||||||
|
onPressed: () => _showEditDialog(context, index),
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.delete),
|
||||||
|
onPressed: () => _showDeleteDialog(context, index),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showAddDialog(BuildContext context) {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (ctx) => AlertDialog(
|
||||||
|
title: const Text('新規得意先登録'),
|
||||||
|
content: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
TextField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: '会社名',
|
||||||
|
hintText: '株式会社名を入力',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
TextField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: '代表者名',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
TextField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: '住所',
|
||||||
|
hintText: '〒000-0000 北海道...',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
TextField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: '電話番号',
|
||||||
|
hintText: '0123-456789',
|
||||||
|
),
|
||||||
|
keyboardType: TextInputType.phone,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
TextField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: '担当者名',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.pop(ctx),
|
||||||
|
child: const Text('キャンセル'),
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(ctx);
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
const SnackBar(content: Text('得意先登録しました')),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: const Text('保存'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showEditDialog(BuildContext context, int index) {
|
||||||
|
// 編集ダイアログ(構造は新規と同様)
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showDeleteDialog(BuildContext context, int index) {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (ctx) => AlertDialog(
|
||||||
|
title: const Text('得意先削除'),
|
||||||
|
content: Text('会社${index + 1}株式会社を削除しますか?'),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.pop(ctx),
|
||||||
|
child: const Text('キャンセル'),
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(ctx);
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
const SnackBar(content: Text('得意先削除しました')),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
style: ElevatedButton.styleFrom(backgroundColor: Colors.red),
|
||||||
|
child: const Text('削除'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
169
lib/screens/master/employee_master_screen.dart
Normal file
169
lib/screens/master/employee_master_screen.dart
Normal file
|
|
@ -0,0 +1,169 @@
|
||||||
|
// Version: 1.0.0
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
/// 担当者マスタ画面(Material Design 標準テンプレート)
|
||||||
|
class EmployeeMasterScreen extends StatelessWidget {
|
||||||
|
const EmployeeMasterScreen({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text('担当者マスタ'),
|
||||||
|
actions: [
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.add),
|
||||||
|
onPressed: () => _showAddDialog(context),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
body: ListView(
|
||||||
|
padding: const EdgeInsets.all(8),
|
||||||
|
children: [
|
||||||
|
// ヘッダー
|
||||||
|
const Padding(
|
||||||
|
padding: EdgeInsets.all(8.0),
|
||||||
|
child: Text(
|
||||||
|
'担当者名',
|
||||||
|
style: TextStyle(fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// カードリスト形式(標準 Material 部品)
|
||||||
|
ListView.builder(
|
||||||
|
shrinkWrap: true,
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
itemCount: 5, // デモ用データ数
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return Card(
|
||||||
|
margin: const EdgeInsets.symmetric(vertical: 4),
|
||||||
|
child: ListTile(
|
||||||
|
leading: CircleAvatar(
|
||||||
|
backgroundColor: Colors.purple.shade100,
|
||||||
|
child: Icon(Icons.person_add, color: Colors.purple),
|
||||||
|
),
|
||||||
|
title: Text('担当者${index + 1}'),
|
||||||
|
subtitle: Text('部署:営業/総務/経理/技術/管理'),
|
||||||
|
trailing: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.edit),
|
||||||
|
onPressed: () => _showEditDialog(context, index),
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.delete),
|
||||||
|
onPressed: () => _showDeleteDialog(context, index),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showAddDialog(BuildContext context) {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (ctx) => AlertDialog(
|
||||||
|
title: const Text('新規担当者登録'),
|
||||||
|
content: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
TextField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: '氏名',
|
||||||
|
hintText: '花名 山田太郎',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
TextField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: '部署',
|
||||||
|
hintText: '営業/総務/経理/技術/管理',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
TextField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: 'メールアドレス',
|
||||||
|
hintText: 'example@company.com',
|
||||||
|
),
|
||||||
|
keyboardType: TextInputType.emailAddress,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
TextField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: '電話番号',
|
||||||
|
hintText: '0123-456789',
|
||||||
|
),
|
||||||
|
keyboardType: TextInputType.phone,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
DropdownButtonFormField<String>(
|
||||||
|
value: '営業',
|
||||||
|
decoration: const InputDecoration(labelText: '担当エリア'),
|
||||||
|
items: const [
|
||||||
|
DropdownMenuItem(value: '全店', child: Text('全店')),
|
||||||
|
DropdownMenuItem(value: '北海道', child: Text('北海道')),
|
||||||
|
DropdownMenuItem(value: '東北', child: Text('東北')),
|
||||||
|
DropdownMenuItem(value: '関東', child: Text('関東')),
|
||||||
|
DropdownMenuItem(value: '中部', child: Text('中部')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.pop(ctx),
|
||||||
|
child: const Text('キャンセル'),
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(ctx);
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
const SnackBar(content: Text('担当者登録しました')),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: const Text('保存'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showEditDialog(BuildContext context, int index) {
|
||||||
|
// 編集ダイアログ(構造は新規と同様)
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showDeleteDialog(BuildContext context, int index) {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (ctx) => AlertDialog(
|
||||||
|
title: const Text('担当者削除'),
|
||||||
|
content: Text('担当者${index + 1}を削除しますか?'),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.pop(ctx),
|
||||||
|
child: const Text('キャンセル'),
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(ctx);
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
const SnackBar(content: Text('担当者削除しました')),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
style: ElevatedButton.styleFrom(backgroundColor: Colors.red),
|
||||||
|
child: const Text('削除'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
148
lib/screens/master/product_master_screen.dart
Normal file
148
lib/screens/master/product_master_screen.dart
Normal file
|
|
@ -0,0 +1,148 @@
|
||||||
|
// Version: 1.0.0
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
/// 商品マスタ画面(Material Design 標準テンプレート)
|
||||||
|
class ProductMasterScreen extends StatelessWidget {
|
||||||
|
const ProductMasterScreen({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text('商品マスタ'),
|
||||||
|
actions: [
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.add),
|
||||||
|
onPressed: () => _showAddDialog(context),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
body: ListView(
|
||||||
|
padding: const EdgeInsets.all(8),
|
||||||
|
children: [
|
||||||
|
// ヘッダー
|
||||||
|
const Padding(
|
||||||
|
padding: EdgeInsets.all(8.0),
|
||||||
|
child: Text(
|
||||||
|
'商品コード',
|
||||||
|
style: TextStyle(fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// テーブル形式のリスト(標準 Material 部品)
|
||||||
|
ListView.builder(
|
||||||
|
shrinkWrap: true,
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
itemCount: 5, // デモ用データ数
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return Card(
|
||||||
|
margin: const EdgeInsets.symmetric(vertical: 4),
|
||||||
|
child: ListTile(
|
||||||
|
leading: CircleAvatar(
|
||||||
|
backgroundColor: Colors.blue.shade100,
|
||||||
|
child: Icon(Icons.shopping_basket, color: Colors.blue),
|
||||||
|
),
|
||||||
|
title: Text('商品${index + 1}'),
|
||||||
|
subtitle: Text('JAN: ${'123456789'.padLeft(10, '0')}'),
|
||||||
|
trailing: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.edit),
|
||||||
|
onPressed: () => _showEditDialog(context, index),
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.delete),
|
||||||
|
onPressed: () => _showDeleteDialog(context, index),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showAddDialog(BuildContext context) {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (ctx) => AlertDialog(
|
||||||
|
title: const Text('新規商品登録'),
|
||||||
|
content: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
TextField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: '商品コード',
|
||||||
|
hintText: 'JAN 形式で入力',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
TextField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: '品名',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
TextField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: '単価',
|
||||||
|
hintText: '¥ の後に数字のみ入力',
|
||||||
|
),
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.pop(ctx),
|
||||||
|
child: const Text('キャンセル'),
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(ctx);
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
const SnackBar(content: Text('商品登録しました')),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: const Text('保存'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showEditDialog(BuildContext context, int index) {
|
||||||
|
// 編集ダイアログ(構造は新規と同様)
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showDeleteDialog(BuildContext context, int index) {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (ctx) => AlertDialog(
|
||||||
|
title: const Text('商品削除'),
|
||||||
|
content: Text('商品${index + 1}を削除しますか?'),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.pop(ctx),
|
||||||
|
child: const Text('キャンセル'),
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(ctx);
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
const SnackBar(content: Text('商品削除しました')),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
style: ElevatedButton.styleFrom(backgroundColor: Colors.red),
|
||||||
|
child: const Text('削除'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
168
lib/screens/master/supplier_master_screen.dart
Normal file
168
lib/screens/master/supplier_master_screen.dart
Normal file
|
|
@ -0,0 +1,168 @@
|
||||||
|
// Version: 1.0.0
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
/// 仕入先マスタ画面(Material Design 標準テンプレート)
|
||||||
|
class SupplierMasterScreen extends StatelessWidget {
|
||||||
|
const SupplierMasterScreen({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text('仕入先マスタ'),
|
||||||
|
actions: [
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.add),
|
||||||
|
onPressed: () => _showAddDialog(context),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
body: ListView(
|
||||||
|
padding: const EdgeInsets.all(8),
|
||||||
|
children: [
|
||||||
|
// ヘッダー
|
||||||
|
const Padding(
|
||||||
|
padding: EdgeInsets.all(8.0),
|
||||||
|
child: Text(
|
||||||
|
'仕入先名',
|
||||||
|
style: TextStyle(fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// カードリスト形式(標準 Material 部品)
|
||||||
|
ListView.builder(
|
||||||
|
shrinkWrap: true,
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
itemCount: 5, // デモ用データ数
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return Card(
|
||||||
|
margin: const EdgeInsets.symmetric(vertical: 4),
|
||||||
|
child: ListTile(
|
||||||
|
leading: CircleAvatar(
|
||||||
|
backgroundColor: Colors.brown.shade100,
|
||||||
|
child: Icon(Icons.shopping_bag, color: Colors.brown),
|
||||||
|
),
|
||||||
|
title: Text('サプライヤー${index + 1}'),
|
||||||
|
subtitle: Text('契約先:2025-12-31 以降'),
|
||||||
|
trailing: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.edit),
|
||||||
|
onPressed: () => _showEditDialog(context, index),
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.delete),
|
||||||
|
onPressed: () => _showDeleteDialog(context, index),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showAddDialog(BuildContext context) {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (ctx) => AlertDialog(
|
||||||
|
title: const Text('新規仕入先登録'),
|
||||||
|
content: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
TextField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: '会社名',
|
||||||
|
hintText: '株式会社名を入力',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
TextField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: '代表者名',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
TextField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: '住所',
|
||||||
|
hintText: '〒000-0000 北海道...',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
TextField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: '電話番号',
|
||||||
|
hintText: '0123-456789',
|
||||||
|
),
|
||||||
|
keyboardType: TextInputType.phone,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
TextField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: '担当者名',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
TextField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: '取引条件',
|
||||||
|
hintText: '例:1/30 支払期限',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.pop(ctx),
|
||||||
|
child: const Text('キャンセル'),
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(ctx);
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
const SnackBar(content: Text('仕入先登録しました')),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: const Text('保存'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showEditDialog(BuildContext context, int index) {
|
||||||
|
// 編集ダイアログ(構造は新規と同様)
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showDeleteDialog(BuildContext context, int index) {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (ctx) => AlertDialog(
|
||||||
|
title: const Text('仕入先削除'),
|
||||||
|
content: Text('サプライヤー${index + 1}を削除しますか?'),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.pop(ctx),
|
||||||
|
child: const Text('キャンセル'),
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(ctx);
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
const SnackBar(content: Text('仕入先削除しました')),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
style: ElevatedButton.styleFrom(backgroundColor: Colors.red),
|
||||||
|
child: const Text('削除'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
156
lib/screens/master/warehouse_master_screen.dart
Normal file
156
lib/screens/master/warehouse_master_screen.dart
Normal file
|
|
@ -0,0 +1,156 @@
|
||||||
|
// Version: 1.0.0
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
/// 倉庫マスタ画面(Material Design 標準テンプレート)
|
||||||
|
class WarehouseMasterScreen extends StatelessWidget {
|
||||||
|
const WarehouseMasterScreen({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text('倉庫マスタ'),
|
||||||
|
actions: [
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.add),
|
||||||
|
onPressed: () => _showAddDialog(context),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
body: ListView(
|
||||||
|
padding: const EdgeInsets.all(8),
|
||||||
|
children: [
|
||||||
|
// ヘッダー
|
||||||
|
const Padding(
|
||||||
|
padding: EdgeInsets.all(8.0),
|
||||||
|
child: Text(
|
||||||
|
'倉庫名',
|
||||||
|
style: TextStyle(fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// カードリスト形式(標準 Material 部品)
|
||||||
|
ListView.builder(
|
||||||
|
shrinkWrap: true,
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
itemCount: 5, // デモ用データ数
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return Card(
|
||||||
|
margin: const EdgeInsets.symmetric(vertical: 4),
|
||||||
|
child: ListTile(
|
||||||
|
leading: CircleAvatar(
|
||||||
|
backgroundColor: Colors.orange.shade100,
|
||||||
|
child: Icon(Icons.storage, color: Colors.orange),
|
||||||
|
),
|
||||||
|
title: Text('倉庫${index + 1}支店'),
|
||||||
|
subtitle: Text('エリア:${['北海道', '東北', '関東', '中部', '近畿'][index % 5]}'),
|
||||||
|
trailing: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.edit),
|
||||||
|
onPressed: () => _showEditDialog(context, index),
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.delete),
|
||||||
|
onPressed: () => _showDeleteDialog(context, index),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showAddDialog(BuildContext context) {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (ctx) => AlertDialog(
|
||||||
|
title: const Text('新規倉庫登録'),
|
||||||
|
content: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
TextField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: '倉庫名',
|
||||||
|
hintText: '例:札幌支店',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
TextField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: 'エリア',
|
||||||
|
hintText: '北海道/東北/関東/中部/近畿/中国/四国/九州',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
TextField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: '住所',
|
||||||
|
hintText: '〒000-0000 北海道...',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
TextField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: '連絡先電話番号',
|
||||||
|
hintText: '0123-456789',
|
||||||
|
),
|
||||||
|
keyboardType: TextInputType.phone,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.pop(ctx),
|
||||||
|
child: const Text('キャンセル'),
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(ctx);
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
const SnackBar(content: Text('倉庫登録しました')),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: const Text('保存'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showEditDialog(BuildContext context, int index) {
|
||||||
|
// 編集ダイアログ(構造は新規と同様)
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showDeleteDialog(BuildContext context, int index) {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (ctx) => AlertDialog(
|
||||||
|
title: const Text('倉庫削除'),
|
||||||
|
content: Text('倉庫${index + 1}支店を削除しますか?'),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.pop(ctx),
|
||||||
|
child: const Text('キャンセル'),
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(ctx);
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
const SnackBar(content: Text('倉庫削除しました')),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
style: ElevatedButton.styleFrom(backgroundColor: Colors.red),
|
||||||
|
child: const Text('削除'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue