// 従業員編集ダイアログ(リッチ版) // ※ Employee モデルに特化した編集用ダイアログ import 'package:flutter/material.dart'; import '../models/employee.dart'; /// 従業員用のリッチな編集ダイアログ class EmployeeEditDialog extends StatefulWidget { final String title; final Employee? initialData; // null = 新規作成 final void Function(Employee) onSave; // 保存コールバック const EmployeeEditDialog({ super.key, required this.title, this.initialData, required this.onSave, }); @override State createState() => _EmployeeEditDialogState(); } class _EmployeeEditDialogState extends State { late TextEditingController nameController; late TextEditingController emailController; late TextEditingController telController; late TextEditingController departmentController; late TextEditingController roleController; @override void initState() { super.initState(); final data = widget.initialData; nameController = TextEditingController(text: data?.name ?? ''); emailController = TextEditingController(text: data?.email ?? ''); telController = TextEditingController(text: data?.tel ?? ''); departmentController = TextEditingController(text: data?.department ?? ''); roleController = TextEditingController(text: data?.role ?? ''); } @override void dispose() { nameController.dispose(); emailController.dispose(); telController.dispose(); departmentController.dispose(); roleController.dispose(); super.dispose(); } /// リッチな入力フィールドビルダー(共通) Widget _buildRichTextField( String label, TextEditingController controller, { TextInputType? keyboard, IconData? icon, String hint = '', }) { return Padding( padding: const EdgeInsets.only(bottom: 12), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( label, style: TextStyle(fontWeight: FontWeight.bold, fontSize: 13, color: Colors.grey.shade700), ), const SizedBox(height: 4), Container( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), decoration: BoxDecoration( border: Border.all(color: Theme.of(context).dividerColor), borderRadius: BorderRadius.circular(8), ), child: TextField( controller: controller, keyboardType: keyboard, style: const TextStyle(fontSize: 14), decoration: InputDecoration( hintText: hint.isEmpty ? null : hint, prefixIcon: Icon(icon, size: 16, color: Theme.of(context).primaryColor), border: InputBorder.none, contentPadding: EdgeInsets.zero, ), ), ), ], ), ); } @override Widget build(BuildContext context) { return Dialog( backgroundColor: Colors.white, child: Container( constraints: const BoxConstraints(maxWidth: 420), padding: const EdgeInsets.all(16), child: SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ // タイトル Row( children: [ Icon(Icons.person, size: 20, color: Theme.of(context).primaryColor), const SizedBox(width: 8), Expanded(child: Text( widget.title, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold), )), IconButton( icon: Icon(Icons.close, color: Colors.grey), onPressed: () => Navigator.pop(context), ), ], ), const SizedBox(height: 12), // ヒントテキスト Center( child: Text( '新規作成の場合は「空白」から入力して OK を押してください', style: TextStyle(fontSize: 12, color: Colors.grey.shade500, fontStyle: FontStyle.italic), ), ), const SizedBox(height: 8), // リッチな編集フォーム Container( decoration: BoxDecoration( color: Theme.of(context).cardColor, borderRadius: BorderRadius.circular(12), border: Border.all(color: Theme.of(context).dividerColor), ), padding: const EdgeInsets.all(12), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 基本情報セクション Text( '■ 基本情報', style: TextStyle( fontSize: 14, fontWeight: FontWeight.bold, color: Theme.of(context).primaryColor, ), ), const SizedBox(height: 8), // 名前フィールド _buildRichTextField( '氏名 *', nameController, keyboard: TextInputType.name, icon: Icons.person, hint: e.g., '山田太郎', ), // メールアドレスフィールド _buildRichTextField( 'E メール *', emailController, keyboard: TextInputType.emailAddress, icon: Icons.email, hint: 'example@company.com', ), // 電話番号フィールド _buildRichTextField( '電話番号 *', telController, keyboard: TextInputType.phone, icon: Icons.phone, hint: '03-1234-5678', ), const Divider(), // 部署情報セクション Text( '■ 部署・役職', style: TextStyle( fontSize: 14, fontWeight: FontWeight.bold, color: Theme.of(context).primaryColor, ), ), const SizedBox(height: 8), // 部門フィールド _buildRichTextField( '部署 *', departmentController, keyboard: TextInputType.text, icon: Icons.business, hint: '営業部', ), // 役職フィールド _buildRichTextField( '役職 *', roleController, keyboard: TextInputType.text, icon: Icons.badge, hint: '営業担当', ), ], ), ), const SizedBox(height: 16), // アクションボタン(Flex で配置) Row( children: [ Expanded( child: OutlinedButton( onPressed: () => Navigator.pop(context), style: OutlinedButton.styleFrom( padding: const EdgeInsets.symmetric(vertical: 14), ), child: Text(' キャンセル ', textAlign: TextAlign.center, style: TextStyle(fontSize: 15)), ), ), const SizedBox(width: 8), Expanded( flex: 3, // より広いボタン child: ElevatedButton( onPressed: () { final employee = Employee( id: widget.initialData?.id ?? -1, name: nameController.text.isEmpty ? widget.initialData?.name ?? '未入力' : nameController.text, email: emailController.text.isEmpty ? widget.initialData?.email ?? '未入力' : emailController.text, tel: telController.text.isEmpty ? widget.initialData?.tel ?? '未入力' : telController.text, department: departmentController.text.isEmpty ? widget.initialData?.department ?? '未入力' : departmentController.text, role: roleController.text.isEmpty ? widget.initialData?.role ?? '未入力' : roleController.text, ); widget.onSave(employee); }, style: ElevatedButton.styleFrom( padding: const EdgeInsets.symmetric(vertical: 14), ), child: Text(' 保存 ', textAlign: TextAlign.center, style: TextStyle(fontSize: 15)), ), ), ], ), ], ), ), ), ); } }