medora-provider/lib/screens/patientScreens/registrationScreens/family_members_edit_screen.dart
DhanshCOSQ b57523599c feature/medora-55 (#6)
Booking physical consultation ,  bugs fixed and Profile picture adding using firebase storage is complete.

Co-authored-by: Jipson George <152465898+Jipson-cosq@users.noreply.github.com>
Reviewed-on: cosqnet/telemednet#6
Co-authored-by: DhanshCOSQ <dhanshas@cosq.net>
Co-committed-by: DhanshCOSQ <dhanshas@cosq.net>
2024-11-05 08:22:13 +00:00

286 lines
8.5 KiB
Dart

import 'package:flutter/material.dart';
import 'package:medora/controllers/patient_controller.dart';
import 'package:medora/data/models/patient.dart';
class FamilyMembersEditScreen extends StatefulWidget {
final FamilyMember? familyMember;
final PatientController controller;
const FamilyMembersEditScreen(
{super.key, this.familyMember, required this.controller});
@override
State<FamilyMembersEditScreen> createState() =>
_FamilyMembersEditScreenState();
}
class _FamilyMembersEditScreenState extends State<FamilyMembersEditScreen> {
late TextEditingController nameController;
late TextEditingController relationController;
late TextEditingController genderController;
late TextEditingController dobController;
Map<String, String> errors = {};
@override
void initState() {
super.initState();
nameController =
TextEditingController(text: widget.familyMember?.name ?? '');
relationController =
TextEditingController(text: widget.familyMember?.relation ?? '');
genderController =
TextEditingController(text: widget.familyMember?.gender ?? '');
dobController = TextEditingController(
text: widget.familyMember?.dateOfBirth?.toString().split(' ')[0] ?? '');
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Edit Family Member'),
actions: _buildAppBarActions(),
),
body: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildTextField(nameController, 'Name', Icons.person, 'name'),
_buildDropdownField(
'Relation',
relationController.text,
(String? newValue) {
setState(() {
relationController.text = newValue ?? '';
});
},
Icons.family_restroom,
),
_buildDropdownField(
'Gender',
genderController.text,
(String? newValue) {
setState(() {
genderController.text = newValue ?? '';
});
},
Icons.transgender,
),
_buildDateField(context),
],
),
),
);
}
Widget _buildDropdownField(
String label, String value, Function(String?) onChanged, IconData icon) {
return Padding(
padding: const EdgeInsets.only(bottom: 16),
child: DropdownButtonFormField<String>(
decoration: InputDecoration(
labelText: label,
prefixIcon: Icon(icon, color: Colors.blue),
border: const OutlineInputBorder(),
),
value: value.isEmpty ? null : value,
onChanged: onChanged,
items: label == 'Relation'
? <String>['Father', 'Mother', 'Son', 'Daughter', 'Other']
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList()
: <String>['Male', 'Female', 'Other']
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
),
);
}
Widget _buildDateField(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(bottom: 16),
child: TextField(
controller: dobController,
decoration: const InputDecoration(
labelText: 'Date of Birth',
border: OutlineInputBorder(),
prefixIcon: Icon(Icons.calendar_today, color: Colors.blue),
),
readOnly: true,
onTap: () async {
DateTime? pickedDate = await showDatePicker(
context: context,
initialDate: DateTime.now().subtract(const Duration(days: 365)),
firstDate: DateTime(1900),
lastDate: DateTime.now().subtract(const Duration(days: 365)),
);
if (pickedDate != null) {
setState(() {
dobController.text = pickedDate.toString().split(' ')[0];
});
}
},
),
);
}
bool _validateFields() {
errors.clear();
if (nameController.text.trim().isEmpty) {
errors['name'] = 'Name is required';
} else if (nameController.text.trim().length < 2) {
errors['name'] = 'Name must be at least 2 characters';
}
if (relationController.text.isEmpty) {
errors['relation'] = 'Please select a relation';
}
if (genderController.text.isEmpty) {
errors['gender'] = 'Please select a gender';
}
if (dobController.text.isEmpty) {
errors['dob'] = 'Date of Birth is required';
} else {
final dob = DateTime.tryParse(dobController.text);
if (dob == null) {
errors['dob'] = 'Invalid date format';
} else if (dob.isAfter(DateTime.now())) {
errors['dob'] = 'Date of Birth cannot be in the future';
}
}
setState(() {});
return errors.isEmpty;
}
void _showValidationErrors() {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: const Row(
children: [
Icon(Icons.error_outline, color: Colors.red),
SizedBox(width: 8),
Text('Validation Errors'),
],
),
content: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: errors.entries
.map((error) => Padding(
padding: const EdgeInsets.symmetric(vertical: 4),
child: Text(
'${error.value}',
style: const TextStyle(color: Colors.red),
),
))
.toList(),
),
),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('OK'),
),
],
),
);
}
Widget _buildTextField(
TextEditingController controller,
String label,
IconData icon,
String errorKey,
) {
return Padding(
padding: const EdgeInsets.only(bottom: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextField(
controller: controller,
decoration: InputDecoration(
labelText: label,
prefixIcon: Icon(
icon,
color: errors.containsKey(errorKey) ? Colors.red : Colors.blue,
),
border: OutlineInputBorder(
borderSide: BorderSide(
color:
errors.containsKey(errorKey) ? Colors.red : Colors.grey,
),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color:
errors.containsKey(errorKey) ? Colors.red : Colors.grey,
),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color:
errors.containsKey(errorKey) ? Colors.red : Colors.blue,
),
),
),
),
if (errors.containsKey(errorKey))
Padding(
padding: const EdgeInsets.only(top: 4, left: 12),
child: Text(
errors[errorKey]!,
style: const TextStyle(color: Colors.red, fontSize: 12),
),
),
],
),
);
}
List<Widget> _buildAppBarActions() {
return [
TextButton(
onPressed: () {
if (_validateFields()) {
FamilyMember newMember = FamilyMember(
name: nameController.text,
relation: relationController.text,
gender: genderController.text,
dateOfBirth: DateTime.tryParse(dobController.text),
);
Navigator.pop(context, newMember);
} else {
_showValidationErrors();
}
},
child: const Text('Done', style: TextStyle(color: Colors.blue)),
),
];
}
@override
void dispose() {
nameController.dispose();
relationController.dispose();
genderController.dispose();
dobController.dispose();
super.dispose();
}
}