import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:gifunavi/model/user.dart'; import 'package:gifunavi/routes/app_pages.dart'; import 'package:gifunavi/services/api_service.dart'; import 'package:gifunavi/pages/index/index_controller.dart'; import 'package:intl/intl.dart'; import 'package:gifunavi/widgets/custom_date_picker.dart'; // 追加: 日付フォーマット用 class UserDetailsEditPage extends StatefulWidget { const UserDetailsEditPage({super.key}); @override _UserDetailsEditPageState createState() => _UserDetailsEditPageState(); } class _UserDetailsEditPageState extends State { final _formKey = GlobalKey(); final IndexController indexController = Get.find(); late User _user; final TextEditingController _firstnameController = TextEditingController(); final TextEditingController _lastnameController = TextEditingController(); final TextEditingController _dateOfBirthController = TextEditingController(); late bool _female; @override void initState() { super.initState(); _user = User.fromJson(indexController.currentUser[0]['user']); _firstnameController.text = _user.firstname; _lastnameController.text = _user.lastname; _dateOfBirthController.text = _user.dateOfBirth != null ? '${_user.dateOfBirth!.year}/${_user.dateOfBirth!.month.toString().padLeft(2, '0')}/${_user.dateOfBirth!.day.toString().padLeft(2, '0')}' : ''; _female = _user.female; } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('個人情報の修正'), automaticallyImplyLeading: false, ), body: Form( key: _formKey, child: ListView( padding: const EdgeInsets.all(16.0), children: [ TextFormField( controller: _lastnameController, decoration: const InputDecoration( labelText: '姓', border: OutlineInputBorder(), ), validator: (value) { if (value == null || value.isEmpty) { return '姓を入力してください'; } return null; }, ), const SizedBox(height: 16), TextFormField( controller: _firstnameController, decoration: const InputDecoration( labelText: '名', border: OutlineInputBorder(), ), validator: (value) { if (value == null || value.isEmpty) { return '名を入力してください'; } return null; }, ), const SizedBox(height: 16), TextFormField( controller: _dateOfBirthController, decoration: InputDecoration( labelText: '生年月日 (YYYY/MM/DD)', border: const OutlineInputBorder(), hintText: 'YYYY/MM/DD', suffixIcon: IconButton( icon: const Icon(Icons.calendar_today), onPressed: () => _selectDate(context), ), ), keyboardType: TextInputType.number, // <=datetime, onChanged: (value) { // スラッシュを除去 value = value.replaceAll('/', ''); if (value.length <= 8) { String formattedValue = ''; // 年の処理(4桁) if (value.length >= 4) { formattedValue += '${value.substring(0, 4)}/'; value = value.substring(4); } else { formattedValue += value; value = ''; } // 月の処理(2桁) if (value.length >= 2) { formattedValue += '${value.substring(0, 2)}/'; value = value.substring(2); } else if (value.isNotEmpty) { formattedValue += value; value = ''; } // 残りの日付 formattedValue += value; // 末尾のスラッシュを削除 if (formattedValue.endsWith('/')) { formattedValue = formattedValue.substring(0, formattedValue.length - 1); } _dateOfBirthController.value = TextEditingValue( text: formattedValue, selection: TextSelection.collapsed(offset: formattedValue.length), ); } }, validator: (value) { if (value == null || value.isEmpty) { return '生年月日を入力してください'; } if (!RegExp(r'^\d{4}/\d{2}/\d{2}$').hasMatch(value)) { return '正しい形式で入力してください (YYYY/MM/DD)'; } final date = DateTime.tryParse(value.replaceAll('/', '-')); if (date == null) { return '有効な日付を入力してください'; } if (date.isAfter(DateTime.now())) { return '未来の日付は入力できません'; } return null; }, ), const SizedBox(height: 16), SwitchListTile( title: const Text('性別'), subtitle: Text(_female ? '女性' : '男性'), value: _female, onChanged: (bool value) { setState(() { _female = value; }); }, ), const SizedBox(height: 16), TextFormField( initialValue: _user.email, decoration: const InputDecoration( labelText: 'メールアドレス', border: OutlineInputBorder(), ), enabled: false, ), const SizedBox(height: 16), SwitchListTile( title: const Text('アクティブ状態'), value: _user.isActive, onChanged: null, ), const SizedBox(height: 32), ElevatedButton( onPressed: _updateUserDetails, child: const Text('更新'), ), ], ), ), ); } // 日付選択用の関数を追加 Future _selectDate(BuildContext context) async { final DateTime? picked = await showDialog( context: context, builder: (BuildContext context) { return CustomDatePicker( initialDate: _user.dateOfBirth ?? DateTime.now(), firstDate: DateTime(1900), lastDate: DateTime.now(), currentDateText: _dateOfBirthController.text, ); }, ); if (picked != null) { setState(() { _dateOfBirthController.text = DateFormat('yyyy/MM/dd').format(picked); }); } } void _updateUserDetails() async { if (_formKey.currentState!.validate()) { final dateOfBirth = DateTime.tryParse(_dateOfBirthController.text.replaceAll('/', '-')); if (dateOfBirth == null || dateOfBirth.isAfter(DateTime.now())) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('生年月日が無効です', style: TextStyle(color: Colors.red))), ); return; } // 13歳以上かどうかをチェック final now = DateTime.now(); final age = now.year - dateOfBirth.year - (now.month > dateOfBirth.month || (now.month == dateOfBirth.month && now.day >= dateOfBirth.day) ? 0 : 1); if (age < 13) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('13歳未満の方は登録できません', style: TextStyle(color: Colors.red))), ); return; } User updatedUser = User( id: _user.id, email: _user.email, firstname: _firstnameController.text, lastname: _lastnameController.text, dateOfBirth: dateOfBirth, female: _female, isActive: _user.isActive, ); try { bool success = await ApiService.updateUserDetail(updatedUser, indexController.currentUser[0]['token']); if (success) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('個人情報が更新されました')), ); indexController.updateCurrentUser(updatedUser); Get.offAllNamed(AppPages.INDEX); //Get.back(); } else { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('更新に失敗しました', style: TextStyle(color: Colors.red))), ); } } catch (e) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('エラーが発生しました: $e', style: const TextStyle(color: Colors.red))), ); } } } }