medora-provider/lib/screens/doctorScreens/doctorProfileScreens/achivements_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

281 lines
9.6 KiB
Dart

import 'package:flutter/material.dart';
import 'package:medora/controllers/doctor_controller.dart';
import '../../../route/route_names.dart';
class AchievementsScreen extends StatefulWidget {
final DoctorController controller;
const AchievementsScreen({
super.key,
required this.controller,
});
@override
State<AchievementsScreen> createState() => _AchievementsScreenState();
}
class _AchievementsScreenState extends State<AchievementsScreen> {
final _formKey = GlobalKey<FormState>();
late DoctorController _controller;
late TextEditingController _achievementController;
late List<String> achievements;
bool _isEditing = false;
@override
void initState() {
super.initState();
_controller = widget.controller;
_controller.model.achievements ??= [];
_achievementController = TextEditingController();
achievements = List<String>.from(_controller.model.achievements ?? []);
// if (achievements.isNotEmpty) {
// _achievementController.text = achievements.join(', ');
// }
// _achievementController.addListener(_onFieldChanged);
}
void _onFieldChanged() {
setState(() {
_isEditing = _achievementController.text.isNotEmpty;
});
}
bool _validateAchievement(String value) {
if (value.isEmpty) {
_showError('Please enter an achievement');
return false;
}
if (achievements.any((a) => a.toLowerCase() == value.toLowerCase())) {
_showError('This achievement has already been added');
return false;
}
if (value.length < 3) {
_showError('Achievement must be at least 3 characters long');
return false;
}
if (!RegExp(r'^[a-zA-Z0-9\s.,]+$').hasMatch(value)) {
_showError('Please enter valid achievement text');
return false;
}
return true;
}
void _addAchievement() {
if (_formKey.currentState!.validate()) {
final achievement = _achievementController.text.trim();
if (_validateAchievement(achievement)) {
setState(() {
achievements.add(achievement);
_isEditing = true;
});
_controller.updateAchievements(List<String>.from(achievements));
_achievementController.clear();
}
}
}
void _removeAchievement(int index) {
setState(() {
achievements.removeAt(index);
_isEditing = true;
});
_controller.updateAchievements(List<String>.from(achievements));
}
void _showError(String message) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(message),
backgroundColor: Colors.red,
behavior: SnackBarBehavior.floating,
),
);
}
bool _validateBeforeNextPage() {
if (achievements.isEmpty) {
_showError('Please add at least one achievement');
return false;
}
return true;
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
if (_isEditing) {
final shouldPop = await showDialog<bool>(
context: context,
builder: (context) => AlertDialog(
title: const Text('Discard Changes?'),
content: const Text(
'You have unsaved changes. Are you sure you want to go back?'),
actions: [
TextButton(
onPressed: () => Navigator.pop(context, false),
child: const Text('CANCEL'),
),
TextButton(
onPressed: () => Navigator.pop(context, true),
child: const Text('DISCARD'),
),
],
),
);
return shouldPop ?? false;
}
return true;
},
child: Scaffold(
appBar: AppBar(
actions: [
IconButton(
onPressed: () {
if (_validateBeforeNextPage()) {
Navigator.pushNamed(
context, RouteNames.digitalSignatureScreeen,
arguments: _controller);
}
},
icon: const Icon(Icons.arrow_forward)),
],
title: const Text('Achievements'),
),
body: Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Padding(
padding: EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Add Your Achievements',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
],
),
),
const SizedBox(height: 8),
Container(
margin:
const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: Colors.blueGrey.withOpacity(0.5),
blurRadius: 10,
offset: const Offset(0, 2),
),
],
),
child: Padding(
padding: const EdgeInsets.all(12.0),
child: TextFormField(
controller: _achievementController,
autovalidateMode: AutovalidateMode.onUserInteraction,
decoration: InputDecoration(
hintText: 'Enter your achievement',
labelText: 'Achievement',
filled: true,
fillColor: Colors.grey[100],
suffixIcon: IconButton(
icon: const Icon(Icons.add_circle_outline,
color: Colors.blue),
onPressed: _addAchievement,
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide:
BorderSide(color: Colors.grey.shade300, width: 1),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide:
const BorderSide(color: Colors.blue, width: 1.5),
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide:
const BorderSide(color: Colors.red, width: 1.5),
),
focusedErrorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide:
const BorderSide(color: Colors.red, width: 1.5),
),
helperText: achievements.isEmpty
? 'Minimum 3 characters required'
: null,
),
validator: (value) {
if (achievements.isEmpty) {
if (value == null || value.isEmpty) {
return 'Please enter an achievement';
}
if (value.length < 3) {
return 'Achievement must be at least 3 characters long';
}
}
if (value != null &&
value.isNotEmpty &&
achievements.any((a) =>
a.toLowerCase() == value.toLowerCase())) {
return 'This achievement has already been added';
}
return null;
},
onFieldSubmitted: (_) => _addAchievement(),
),
),
),
Expanded(
child: ListView.builder(
itemCount: achievements.length,
padding: const EdgeInsets.all(16),
itemBuilder: (context, index) {
return Card(
elevation: 2,
margin: const EdgeInsets.only(bottom: 8),
child: ListTile(
leading: CircleAvatar(
backgroundColor: const Color(0xFF5BC0DE),
child: Text('${index + 1}'),
),
title: Text(achievements[index]),
trailing: IconButton(
icon: const Icon(Icons.delete, color: Colors.red),
onPressed: () => _removeAchievement(index),
),
),
);
},
),
),
],
),
),
));
}
@override
void dispose() {
_achievementController.removeListener(_onFieldChanged);
_achievementController.dispose();
super.dispose();
}
}