Modified Profile Page
This commit is contained in:
parent
099a8f5d80
commit
32a468f51d
@ -36,9 +36,10 @@ import 'package:uae_stat/presentation/routes/bottom_bar_routes/tab_routes/uae_nu
|
||||
import 'package:uae_stat/presentation/routes/drawer_routes/feedback_route.dart';
|
||||
import 'package:uae_stat/presentation/routes/drawer_routes/my_favorites_route.dart';
|
||||
import 'package:uae_stat/presentation/routes/drawer_routes/privacy_policy_route.dart';
|
||||
import 'package:uae_stat/presentation/routes/drawer_routes/profile/profile_route.dart';
|
||||
import 'package:uae_stat/presentation/routes/drawer_routes/profile/reset_pw_route.dart';
|
||||
|
||||
import '../presentation/routes/drawer_routes/profile/profile_route.dart';
|
||||
|
||||
part 'my_router.g.dart';
|
||||
|
||||
class _MyRouter {
|
||||
@ -64,18 +65,25 @@ class _MyRouter {
|
||||
}
|
||||
|
||||
Iterable<GoRoute> get authRoutes => [
|
||||
GoRoute(
|
||||
path: 'Profile',
|
||||
redirect: (context, state) =>
|
||||
isLoggedIn ? null : '${context.language.name}/profile',
|
||||
builder: (context, state) => const ProfileRoute(),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'login',
|
||||
redirect: (context, state) =>
|
||||
isLoggedIn ? '${context.language.name}/profile' : null,
|
||||
builder: (context, state) => const LoginRoute(),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'register',
|
||||
redirect: (context, state) =>
|
||||
isLoggedIn ? '${context.language.name}/profile' : null,
|
||||
builder: (context, state) => const RegisterRoute(),
|
||||
builder: (context, state) => const ProfileRoute(),
|
||||
//builder: (context, state) => const LoginRoute(),
|
||||
),
|
||||
// GoRoute(
|
||||
// path: 'register',
|
||||
// redirect: (context, state) =>
|
||||
// isLoggedIn ? '${context.language.name}/profile' : null,
|
||||
// builder: (context, state) => const RegisterRoute(),
|
||||
// ),
|
||||
];
|
||||
|
||||
static final Iterable<GoRoute> bottomBarRoutes = BottomNavBarItem.values.map(
|
||||
|
||||
118
lib/main.dart
118
lib/main.dart
@ -8,6 +8,7 @@ import 'package:uae_stat/config/my_theme.dart';
|
||||
import 'package:uae_stat/config/old_theme.dart';
|
||||
import 'package:uae_stat/domain/entities/language_locale.dart';
|
||||
import 'package:uae_stat/domain/use_cases/auth_use_case.dart';
|
||||
import 'package:uae_stat/presentation/Screens/profilepage.dart';
|
||||
|
||||
void main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
@ -20,61 +21,74 @@ void main() async {
|
||||
);
|
||||
}
|
||||
|
||||
class MainApp extends ConsumerWidget {
|
||||
class MainApp extends StatelessWidget {
|
||||
const MainApp({super.key});
|
||||
|
||||
@override
|
||||
Widget build(
|
||||
BuildContext context,
|
||||
WidgetRef ref,
|
||||
) {
|
||||
const loading = Material(
|
||||
child: Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
home: ProfileScreen(),
|
||||
debugShowCheckedModeBanner: false,
|
||||
);
|
||||
// waits to load preferences (language)
|
||||
// from local storage
|
||||
final languageFinalizedWidget = ref
|
||||
.watch(
|
||||
routerProvider,
|
||||
)
|
||||
.when(
|
||||
loading: () => loading,
|
||||
error: Error.throwWithStackTrace,
|
||||
data: (data) {
|
||||
final materialApp = MaterialApp.router(
|
||||
debugShowCheckedModeBanner: false,
|
||||
routerConfig: data,
|
||||
supportedLocales: LanguageLocale.values.map(
|
||||
(e) => e.toLocale(),
|
||||
),
|
||||
localizationsDelegates: GlobalMaterialLocalizations.delegates,
|
||||
theme: ThemeData.from(
|
||||
colorScheme: ColorScheme.fromSeed(
|
||||
seedColor: MyTheme.topicColor(
|
||||
IndicatorTopic.economy,
|
||||
),
|
||||
),
|
||||
textTheme: OldTheme.textTheme,
|
||||
),
|
||||
);
|
||||
return ColoredBox(
|
||||
color: Colors.white,
|
||||
child: materialApp,
|
||||
);
|
||||
},
|
||||
);
|
||||
// waits to load auth from local storage
|
||||
final authFinalizedWidget = ref
|
||||
.watch(
|
||||
authUseCaseProvider,
|
||||
)
|
||||
.when(
|
||||
loading: () => loading,
|
||||
error: Error.throwWithStackTrace,
|
||||
data: (data) => languageFinalizedWidget,
|
||||
);
|
||||
return authFinalizedWidget;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// class MainApp extends ConsumerWidget {
|
||||
// const MainApp({super.key});
|
||||
//
|
||||
// @override
|
||||
// Widget build(
|
||||
// BuildContext context,
|
||||
// WidgetRef ref,
|
||||
// ) {
|
||||
// const loading = Material(
|
||||
// child: Center(
|
||||
// child: CircularProgressIndicator(),
|
||||
// ),
|
||||
// );
|
||||
// // waits to load preferences (language)
|
||||
// // from local storage
|
||||
// final languageFinalizedWidget = ref
|
||||
// .watch(
|
||||
// routerProvider,
|
||||
// )
|
||||
// .when(
|
||||
// loading: () => loading,
|
||||
// error: Error.throwWithStackTrace,
|
||||
// data: (data) {
|
||||
// final materialApp = MaterialApp.router(
|
||||
// debugShowCheckedModeBanner: false,
|
||||
// routerConfig: data,
|
||||
// supportedLocales: LanguageLocale.values.map(
|
||||
// (e) => e.toLocale(),
|
||||
// ),
|
||||
// localizationsDelegates: GlobalMaterialLocalizations.delegates,
|
||||
// theme: ThemeData.from(
|
||||
// colorScheme: ColorScheme.fromSeed(
|
||||
// seedColor: MyTheme.topicColor(
|
||||
// IndicatorTopic.economy,
|
||||
// ),
|
||||
// ),
|
||||
// textTheme: OldTheme.textTheme,
|
||||
// ),
|
||||
// );
|
||||
// return ColoredBox(
|
||||
// color: Colors.white,
|
||||
// child: materialApp,
|
||||
// );
|
||||
// },
|
||||
// );
|
||||
// // waits to load auth from local storage
|
||||
// final authFinalizedWidget = ref
|
||||
// .watch(
|
||||
// authUseCaseProvider,
|
||||
// )
|
||||
// .when(
|
||||
// loading: () => loading,
|
||||
// error: Error.throwWithStackTrace,
|
||||
// data: (data) => languageFinalizedWidget,
|
||||
// );
|
||||
// return authFinalizedWidget;
|
||||
// }
|
||||
// }
|
||||
|
||||
@ -0,0 +1,126 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:uae_stat/presentation/components/my_bottom_nav_bar.dart';
|
||||
|
||||
|
||||
class ProfileScreen extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.white,
|
||||
elevation: 0,
|
||||
leading: IconButton(
|
||||
icon: Icon(Icons.arrow_back_ios_new, color: Colors.black),
|
||||
onPressed: () {},
|
||||
),
|
||||
title: Text(
|
||||
'My Profile',
|
||||
style: TextStyle(color: Colors.orange),
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () {},
|
||||
child: Text(
|
||||
'Logout',
|
||||
style: TextStyle(color: Colors.orange),
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
icon: Icon(Icons.logout, color: Colors.black),
|
||||
onPressed: () {},
|
||||
),
|
||||
],
|
||||
),
|
||||
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,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
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),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
),
|
||||
//bottomNavigationBar: MyBottomNavBar(),
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ProfileField extends StatelessWidget {
|
||||
final String label;
|
||||
final String hintText;
|
||||
final bool obscureText;
|
||||
final bool isDropdown;
|
||||
|
||||
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),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -14,6 +14,7 @@ import 'package:uae_stat/presentation/components/lang_toggle.dart';
|
||||
import 'package:uae_stat/presentation/components/my_bottom_nav_bar.dart';
|
||||
import 'package:uae_stat/presentation/components/space.dart';
|
||||
import 'package:uae_stat/presentation/components/themed_text_field.dart';
|
||||
import 'package:uae_stat/presentation/routes/drawer_routes/profile/profile_route.dart';
|
||||
|
||||
class LoginRoute extends HookConsumerWidget {
|
||||
const LoginRoute({super.key});
|
||||
@ -118,75 +119,76 @@ class LoginRoute extends HookConsumerWidget {
|
||||
width: double.infinity,
|
||||
child: ElevatedButton(
|
||||
onPressed: () async {
|
||||
final isValid = formKey.currentState!.validate();
|
||||
if (!isValid) return;
|
||||
await context.loaderWithErrorDialog(
|
||||
() => ref
|
||||
.read(
|
||||
authUseCaseProvider.notifier,
|
||||
)
|
||||
.login(
|
||||
emailCtl.text,
|
||||
pwCtl.text,
|
||||
),
|
||||
errorDialogBuilder: (
|
||||
error, [
|
||||
StackTrace? stackTrace,
|
||||
]) {
|
||||
if (error == LoginError.invalidEmailPw) {
|
||||
return context.simpleDialog(
|
||||
title: context.translate(
|
||||
'Incorrect credentials',
|
||||
'أوراق غير صحيحة',
|
||||
),
|
||||
content: context.translate(
|
||||
'Your email or password is invalid. Please try again.',
|
||||
'بريدك الإلكتروني أو كلمة المرور غير صالحة. حاول مرة اخرى.',
|
||||
),
|
||||
);
|
||||
}
|
||||
if (error == LoginError.emailAddressNotVerified) {
|
||||
return context.simpleDialog(
|
||||
title: context.translate(
|
||||
'Verification Error',
|
||||
'خطأ التحقق',
|
||||
),
|
||||
content: context.translate(
|
||||
'${emailCtl.text} is not a verified email address. Please check your email for a verification link.',
|
||||
'${emailCtl.text} ليس عنوان بريد إلكتروني تم التحقق منه. يرجى التحقق من بريدك الإلكتروني للحصول على رابط التحقق.',
|
||||
),
|
||||
extraAction: ElevatedButton(
|
||||
onPressed: () async {
|
||||
Navigator.of(
|
||||
context,
|
||||
rootNavigator: true,
|
||||
).pop();
|
||||
await context.loaderWithErrorDialog(
|
||||
() => ref
|
||||
.read(authUseCaseProvider.notifier)
|
||||
.requestVerificationEmail(emailCtl.text),
|
||||
);
|
||||
if (!context.mounted) return;
|
||||
context.simpleDialog(
|
||||
title: 'Email Re-sent',
|
||||
content:
|
||||
'We\'ve sent you the verification email at ${emailCtl.text} again.',
|
||||
);
|
||||
},
|
||||
child: Text(
|
||||
context.translate(
|
||||
'I did not receive an email',
|
||||
'لم أتلق بريدًا إلكترونيًا',
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
return context.simpleDialog();
|
||||
},
|
||||
);
|
||||
if (!context.mounted) return;
|
||||
context.go('/${context.language}/${BottomNavBarItem.home.routePath}');
|
||||
// final isValid = formKey.currentState!.validate();
|
||||
// if (!isValid) return;
|
||||
// await context.loaderWithErrorDialog(
|
||||
// () => ref
|
||||
// .read(
|
||||
// authUseCaseProvider.notifier,
|
||||
// )
|
||||
// .login(
|
||||
// emailCtl.text,
|
||||
// pwCtl.text,
|
||||
// ),
|
||||
// errorDialogBuilder: (
|
||||
// error, [
|
||||
// StackTrace? stackTrace,
|
||||
// ]) {
|
||||
// if (error == LoginError.invalidEmailPw) {
|
||||
// return context.simpleDialog(
|
||||
// title: context.translate(
|
||||
// 'Incorrect credentials',
|
||||
// 'أوراق غير صحيحة',
|
||||
// ),
|
||||
// content: context.translate(
|
||||
// 'Your email or password is invalid. Please try again.',
|
||||
// 'بريدك الإلكتروني أو كلمة المرور غير صالحة. حاول مرة اخرى.',
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
// if (error == LoginError.emailAddressNotVerified) {
|
||||
// return context.simpleDialog(
|
||||
// title: context.translate(
|
||||
// 'Verification Error',
|
||||
// 'خطأ التحقق',
|
||||
// ),
|
||||
// content: context.translate(
|
||||
// '${emailCtl.text} is not a verified email address. Please check your email for a verification link.',
|
||||
// '${emailCtl.text} ليس عنوان بريد إلكتروني تم التحقق منه. يرجى التحقق من بريدك الإلكتروني للحصول على رابط التحقق.',
|
||||
// ),
|
||||
// extraAction: ElevatedButton(
|
||||
// onPressed: () async {
|
||||
// Navigator.of(
|
||||
// context,
|
||||
// rootNavigator: true,
|
||||
// ).pop();
|
||||
// await context.loaderWithErrorDialog(
|
||||
// () => ref
|
||||
// .read(authUseCaseProvider.notifier)
|
||||
// .requestVerificationEmail(emailCtl.text),
|
||||
// );
|
||||
// if (!context.mounted) return;
|
||||
// context.simpleDialog(
|
||||
// title: 'Email Re-sent',
|
||||
// content:
|
||||
// 'We\'ve sent you the verification email at ${emailCtl.text} again.',
|
||||
// );
|
||||
// },
|
||||
// child: Text(
|
||||
// context.translate(
|
||||
// 'I did not receive an email',
|
||||
// 'لم أتلق بريدًا إلكترونيًا',
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
// return context.simpleDialog();
|
||||
// },
|
||||
// );
|
||||
// if (!context.mounted) return;
|
||||
// context.go('/${context.language}/${BottomNavBarItem.home.routePath}');
|
||||
context.go('/Profile');
|
||||
},
|
||||
style: ButtonStyle(
|
||||
shape: WidgetStatePropertyAll(
|
||||
@ -222,7 +224,7 @@ class LoginRoute extends HookConsumerWidget {
|
||||
children: [
|
||||
Text(
|
||||
context.translate(
|
||||
'Login',
|
||||
'Login log',
|
||||
'تسجيل الدخول',
|
||||
),
|
||||
),
|
||||
|
||||
@ -4,14 +4,14 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:uae_stat/config/my_theme.dart';
|
||||
import 'package:uae_stat/domain/use_cases/auth_use_case.dart';
|
||||
import 'package:uae_stat/domain/use_cases/language.dart';
|
||||
import 'package:uae_stat/domain/use_cases/user_use_case.dart';
|
||||
import 'package:uae_stat/presentation/components/dialogs.dart';
|
||||
import 'package:uae_stat/presentation/components/ref_watch_handled.dart';
|
||||
import 'package:uae_stat/presentation/components/space.dart';
|
||||
import 'package:uae_stat/presentation/components/themed_app_bar.dart';
|
||||
import '../../../../config/my_theme.dart';
|
||||
import '../../../../domain/use_cases/auth_use_case.dart';
|
||||
import '../../../../domain/use_cases/user_use_case.dart';
|
||||
import '../../../components/ref_watch_handled.dart';
|
||||
import '../../../components/themed_app_bar.dart';
|
||||
|
||||
class ProfileRoute extends HookConsumerWidget {
|
||||
const ProfileRoute({super.key});
|
||||
|
||||
@ -97,6 +97,7 @@ flutter:
|
||||
- assets/cached_responses/qlik/
|
||||
- assets/cached_responses/sharepoint/gov_init/
|
||||
- assets/cached_responses/sharepoint/country_leader_imgs/
|
||||
- assets/edit_profile/
|
||||
|
||||
fonts:
|
||||
- family: Segoe
|
||||
|
||||
Loading…
Reference in New Issue
Block a user