Edit Profile Page Updated

This commit is contained in:
VINISTAN 2024-11-08 21:09:59 +05:30
parent 32a468f51d
commit aa08648a56
4 changed files with 343 additions and 80 deletions

View File

@ -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(),
);
}
}

View File

@ -1,3 +1,4 @@
import 'package:external_repos/external_repos.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';

View File

@ -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:

View File

@ -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