Edit Profile Page Updated
This commit is contained in:
parent
32a468f51d
commit
aa08648a56
@ -1,8 +1,87 @@
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:uae_stat/presentation/components/my_bottom_nav_bar.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
class ProfileScreen extends StatefulWidget {
|
||||
@override
|
||||
State<ProfileScreen> createState() => _ProfileScreenState();
|
||||
}
|
||||
|
||||
class _ProfileScreenState extends State<ProfileScreen> {
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
final TextEditingController _fullNameController = TextEditingController();
|
||||
final TextEditingController _dateController = TextEditingController();
|
||||
// To keep track of the selected date
|
||||
DateTime? _selectedDate;
|
||||
|
||||
// Date format for the display
|
||||
final DateFormat _dateFormat = DateFormat('yyyy-MM-dd');
|
||||
final List<String> _countries = [
|
||||
'United Arab Emirates',
|
||||
'United States',
|
||||
'India',
|
||||
'Canada'
|
||||
];
|
||||
String? _selectedCountry;
|
||||
bool _termsAccepted = false;
|
||||
|
||||
// Regular expression to validate Full Name (no special characters)
|
||||
final RegExp _nameRegExp = RegExp(r"^[a-zA-Z\s]+$");
|
||||
|
||||
// Function to open the date picker
|
||||
Future<void> _pickDate() async {
|
||||
final DateTime today = DateTime.now();
|
||||
final DateTime initialDate = _selectedDate ?? today.subtract(const Duration(days: 365 * 18)); // Default to 18 years ago
|
||||
final DateTime firstDate = today.subtract(const Duration(days: 365 * 100)); // Allow picking dates back to 100 years ago
|
||||
final DateTime lastDate = today; // Allow picking dates up to today
|
||||
|
||||
// Updated Date format to DD/MM/YYYY
|
||||
final DateFormat _dateFormat = DateFormat('dd/MM/yyyy');
|
||||
|
||||
final DateTime? pickedDate = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: initialDate,
|
||||
firstDate: firstDate,
|
||||
lastDate: lastDate,
|
||||
);
|
||||
|
||||
if (pickedDate != null && pickedDate != _selectedDate) {
|
||||
setState(() {
|
||||
_selectedDate = pickedDate;
|
||||
_dateController.text = _dateFormat.format(pickedDate);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Function to validate the DOB field
|
||||
String? _validateDob(String? value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return 'Please select your date of birth';
|
||||
}
|
||||
|
||||
final DateTime selectedDate = _selectedDate!;
|
||||
final DateTime today = DateTime.now();
|
||||
|
||||
// Check if the selected date is in the future
|
||||
if (selectedDate.isAfter(today)) {
|
||||
return 'Date of birth cannot be in the future';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
String? _validateDropdown(String? value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return 'Please select an option';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
void _toggleCheckbox(bool? value) {
|
||||
setState(() {
|
||||
_termsAccepted = value ?? false;
|
||||
});
|
||||
}
|
||||
|
||||
class ProfileScreen extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
@ -11,7 +90,9 @@ class ProfileScreen extends StatelessWidget {
|
||||
elevation: 0,
|
||||
leading: IconButton(
|
||||
icon: Icon(Icons.arrow_back_ios_new, color: Colors.black),
|
||||
onPressed: () {},
|
||||
onPressed: () {
|
||||
print("Back Button");
|
||||
},
|
||||
),
|
||||
title: Text(
|
||||
'My Profile',
|
||||
@ -32,95 +113,259 @@ class ProfileScreen extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
children: [
|
||||
CircleAvatar(
|
||||
radius: 50,
|
||||
backgroundImage: AssetImage("assets/edit_profile/profile.png"), // Replace with actual image URL
|
||||
child: Align(
|
||||
alignment: Alignment.bottomRight,
|
||||
child: CircleAvatar(
|
||||
radius: 15,
|
||||
backgroundColor: Colors.white,
|
||||
child: Icon(
|
||||
Icons.camera_alt,
|
||||
size: 15,
|
||||
color: Colors.grey,
|
||||
child: Form(
|
||||
key: _formKey,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(20.0),
|
||||
child: Column(
|
||||
children: [
|
||||
CircleAvatar(
|
||||
radius: 50,
|
||||
backgroundImage:
|
||||
AssetImage("assets/edit_profile/profile.png"),
|
||||
// Replace with actual image URL
|
||||
child: Align(
|
||||
alignment: Alignment.bottomRight,
|
||||
child: CircleAvatar(
|
||||
radius: 15,
|
||||
backgroundColor: Colors.white,
|
||||
child: Icon(
|
||||
Icons.camera_alt,
|
||||
size: 15,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
ProfileField(label: 'Name', hintText: 'Mohammad Hassan'),
|
||||
SizedBox(height: 10),
|
||||
ProfileField(label: 'Email', hintText: 'mohammad.hassan@fcsc.gov.ae'),
|
||||
SizedBox(height: 10),
|
||||
ProfileField(label: 'Password', hintText: '********', obscureText: true),
|
||||
SizedBox(height: 10),
|
||||
ProfileField(label: 'Date of Birth', hintText: '23/05/1995', isDropdown: true),
|
||||
SizedBox(height: 10),
|
||||
ProfileField(label: 'Country/Region', hintText: 'United Arab Emirates', isDropdown: true),
|
||||
SizedBox(height: 20),
|
||||
ElevatedButton.icon(
|
||||
onPressed: () {},
|
||||
icon: Icon(Icons.save,color: Colors.white,),
|
||||
label: Text('Save',style: TextStyle(color: Colors.white),),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xFF92722A),
|
||||
minimumSize: Size(double.infinity, 50),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
SizedBox(height: 20),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Text("User Name",
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
TextFormField(
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Mohammad Hassan',
|
||||
hintStyle: TextStyle(color: Colors.grey),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),enabled: false,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Text("E-mail",
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
TextFormField(
|
||||
decoration: InputDecoration(
|
||||
hintText: 'mohammad.hassan@fcsc.gov.ae',
|
||||
hintStyle: TextStyle(color: Colors.grey),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),enabled: false,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Text("Full Name",
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
TextFormField(
|
||||
enabled: true,
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return 'Required';
|
||||
}
|
||||
final nameRegex = RegExp(r"^[a-zA-Z\s]+$");
|
||||
if (!nameRegex.hasMatch(value)) {
|
||||
return 'Invalid Characters';
|
||||
}
|
||||
return null;
|
||||
},
|
||||
controller: _fullNameController,
|
||||
decoration: InputDecoration(
|
||||
hintText: "Mohammad",
|
||||
hintStyle: TextStyle(color: Colors.grey),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Text("Date of Birth*",
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
|
||||
),
|
||||
//bottomNavigationBar: MyBottomNavBar(),
|
||||
TextFormField(
|
||||
controller: _dateController,
|
||||
decoration: InputDecoration(
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
hintText: 'Select your Date of Birth',
|
||||
suffixIcon: const Icon(Icons.arrow_drop_down_sharp),
|
||||
),
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
readOnly: true,
|
||||
onTap: _pickDate,
|
||||
validator: _validateDob,
|
||||
),
|
||||
|
||||
class ProfileField extends StatelessWidget {
|
||||
final String label;
|
||||
final String hintText;
|
||||
final bool obscureText;
|
||||
final bool isDropdown;
|
||||
SizedBox(height: 10),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Text("Country/Region*",
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
DropdownButtonFormField<String>(
|
||||
value: _selectedCountry,
|
||||
decoration: InputDecoration(
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
labelText: 'Select',
|
||||
),
|
||||
items: _countries
|
||||
.map((item) => DropdownMenuItem<String>(
|
||||
value: item,
|
||||
child: Text(item),
|
||||
))
|
||||
.toList(),
|
||||
onChanged: (String? newValue) {
|
||||
setState(() {
|
||||
_selectedCountry = newValue;
|
||||
});
|
||||
},
|
||||
validator: _validateDropdown,
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
Row(
|
||||
children: [
|
||||
Checkbox(
|
||||
value: _termsAccepted,
|
||||
onChanged: _toggleCheckbox,
|
||||
),
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(height: 10,),
|
||||
Text.rich(
|
||||
TextSpan(
|
||||
text: 'I agree to the ',
|
||||
style: TextStyle(color: Colors.black),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: 'Terms & Conditions',
|
||||
style: TextStyle(
|
||||
color: Colors.blue,
|
||||
decoration: TextDecoration.underline,
|
||||
),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () {
|
||||
// Add action for Terms & Conditions tap
|
||||
},
|
||||
),
|
||||
TextSpan(
|
||||
text: ' and ',
|
||||
style: TextStyle(color: Colors.black),
|
||||
),
|
||||
TextSpan(
|
||||
text: 'Privacy Policy',
|
||||
style: TextStyle(
|
||||
color: Colors.blue,
|
||||
decoration: TextDecoration.underline,
|
||||
),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () {
|
||||
// Add action for Privacy Policy tap
|
||||
},
|
||||
),
|
||||
TextSpan(
|
||||
text: ' of FCSC.',
|
||||
style: TextStyle(color: Colors.black),
|
||||
),
|
||||
],
|
||||
),
|
||||
textAlign: TextAlign.start,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.visible,
|
||||
softWrap: true,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
|
||||
ProfileField({
|
||||
required this.label,
|
||||
required this.hintText,
|
||||
this.obscureText = false,
|
||||
this.isDropdown = false,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
TextFormField(
|
||||
obscureText: obscureText,
|
||||
readOnly: isDropdown,
|
||||
decoration: InputDecoration(
|
||||
hintText: hintText,
|
||||
suffixIcon: isDropdown ? Icon(Icons.arrow_drop_down) : null,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
Center(child: Text("Change Password",style: TextStyle(color: Colors.blue,decoration: TextDecoration.underline),),),
|
||||
SizedBox(height: 20),
|
||||
ElevatedButton.icon(
|
||||
onPressed: () {
|
||||
if (_formKey.currentState?.validate() ?? false) {
|
||||
_formKey.currentState?.save();
|
||||
}
|
||||
},
|
||||
icon: Icon(
|
||||
Icons.save,
|
||||
color: Colors.white,
|
||||
),
|
||||
label: Text(
|
||||
'Save',
|
||||
style: TextStyle(color: Colors.white),
|
||||
),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xFF92722A),
|
||||
minimumSize: Size(double.infinity, 50),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
//bottomNavigationBar: MyBottomNavBar(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
|
||||
import 'package:external_repos/external_repos.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
|
||||
16
pubspec.lock
16
pubspec.lock
@ -753,6 +753,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
nested:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: nested
|
||||
sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
package_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -857,6 +865,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.5.1"
|
||||
provider:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: provider
|
||||
sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.1.2"
|
||||
pub_semver:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@ -51,6 +51,7 @@ dependencies:
|
||||
freezed_annotation: ^2.4.4
|
||||
shared_preferences: ^2.2.3
|
||||
flutter_rating_bar: ^4.0.1
|
||||
provider: ^6.1.2
|
||||
|
||||
dependency_overrides:
|
||||
fading_edge_scrollview: ^4.1.1
|
||||
|
||||
Loading…
Reference in New Issue
Block a user