cee5e6c6d6
- Implemented `ForgotPasswordViewModel`, `ResetPasswordViewModel`, and `VerifyOtpViewModel` for handling respective functionalities. - Created provider functions for lazy loading of these view models in the app. - Updated routing to utilize the new providers for managing state in the forgot password flow. - Refactored UI components to integrate with the new view models, ensuring proper state management and user feedback during operations.
192 lines
6.4 KiB
Dart
192 lines
6.4 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_svg/svg.dart';
|
|
import 'package:provider/provider.dart';
|
|
import 'package:tm_app/core/routes/app_routes.dart';
|
|
import 'package:tm_app/view_models/profile_view_model.dart';
|
|
import 'package:tm_app/views/profile/widgets/theme_toggle.dart';
|
|
|
|
import '../../../core/constants/assets.dart';
|
|
import '../../../core/constants/common_strings.dart';
|
|
import '../../../core/theme/colors.dart';
|
|
import '../../../core/utils/app_toast.dart';
|
|
import '../../../core/utils/size_config.dart';
|
|
import '../../../view_models/auth_view_model.dart';
|
|
import '../../shared/tender_app_bar.dart';
|
|
import '../strings/profile_strings.dart';
|
|
import '../widgets/title_description.dart';
|
|
|
|
class MobileProfilePage extends StatefulWidget {
|
|
const MobileProfilePage({super.key});
|
|
|
|
@override
|
|
State<MobileProfilePage> createState() => _MobileProfilePageState();
|
|
}
|
|
|
|
class _MobileProfilePageState extends State<MobileProfilePage> {
|
|
late ProfileViewModel viewModel;
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
viewModel = context.read<ProfileViewModel>();
|
|
viewModel.addListener(_profileListener);
|
|
// Load notification info saved in SharedPreferences
|
|
}
|
|
|
|
void _profileListener() {
|
|
if (viewModel.errorMessage != null) {
|
|
AppToast.error(context, viewModel.errorMessage!);
|
|
}
|
|
if (viewModel.loggedOut) {
|
|
context.read<AuthViewModel>().clearAuthFlow();
|
|
Router.neglect(context, () => const LoginScreenRoute().go(context));
|
|
}
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
viewModel.removeListener(_profileListener);
|
|
super.dispose();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
backgroundColor: AppColors.backgroundColor,
|
|
appBar: tenderMobileAppBar(title: ProfileStrings.profileTitle),
|
|
body: Consumer<ProfileViewModel>(
|
|
builder: (context, viewModel, child) {
|
|
if (viewModel.isLoading) {
|
|
return const Center(
|
|
child: CircularProgressIndicator(color: AppColors.secondary50),
|
|
);
|
|
}
|
|
|
|
if (viewModel.errorMessage != null) {
|
|
return Center(child: Text(viewModel.errorMessage!));
|
|
}
|
|
|
|
if (viewModel.companyProfileData == null) {
|
|
return const Center(child: Text(CommonStrings.noData));
|
|
}
|
|
|
|
return SafeArea(
|
|
child: Padding(
|
|
padding: EdgeInsets.symmetric(
|
|
horizontal: 24.0.w(),
|
|
vertical: 16.0.h(),
|
|
),
|
|
child: Column(
|
|
children: [
|
|
SizedBox(height: 36.0.h()),
|
|
Align(
|
|
alignment: AlignmentDirectional.centerStart,
|
|
child: Text(
|
|
'Last Notification',
|
|
style: TextStyle(
|
|
fontSize: 18.0.sp(),
|
|
fontWeight: FontWeight.w600,
|
|
color: AppColors.grey70,
|
|
),
|
|
),
|
|
),
|
|
|
|
SizedBox(height: 24.0.h()),
|
|
TitleDescription(
|
|
title: ProfileStrings.companyName,
|
|
description: viewModel.companyProfileData!.name!,
|
|
),
|
|
TitleDescription(
|
|
title: ProfileStrings.nationalId,
|
|
description: viewModel.companyProfileData!.id!,
|
|
),
|
|
TitleDescription(
|
|
title: ProfileStrings.registrationNumber,
|
|
description:
|
|
viewModel.companyProfileData!.registrationNumber!,
|
|
),
|
|
const TitleDescription(
|
|
title: ProfileStrings.businessType,
|
|
description: '-',
|
|
),
|
|
TitleDescription(
|
|
title: ProfileStrings.founded,
|
|
description:
|
|
viewModel.companyProfileData!.foundedYear!.toString(),
|
|
),
|
|
SizedBox(height: 32.0.h()),
|
|
Align(
|
|
alignment: AlignmentDirectional.centerStart,
|
|
child: Text(
|
|
ProfileStrings.settings,
|
|
style: TextStyle(
|
|
fontSize: 20.0.sp(),
|
|
fontWeight: FontWeight.w600,
|
|
color: AppColors.grey70,
|
|
),
|
|
),
|
|
),
|
|
SizedBox(height: 36.0.h()),
|
|
_themeChangeRow(),
|
|
SizedBox(height: 24.0.h()),
|
|
Divider(color: AppColors.dividerColor, thickness: 1),
|
|
SizedBox(height: 24.0.h()),
|
|
const Spacer(),
|
|
InkWell(
|
|
onTap: () => viewModel.logout(),
|
|
borderRadius: BorderRadius.circular(100),
|
|
child: Container(
|
|
width: double.infinity,
|
|
height: 56.0.h(),
|
|
decoration: BoxDecoration(
|
|
color: AppColors.primary20,
|
|
borderRadius: BorderRadius.circular(100),
|
|
),
|
|
alignment: Alignment.center,
|
|
child: Text(
|
|
ProfileStrings.logout,
|
|
style: TextStyle(
|
|
fontSize: 14.0.sp(),
|
|
fontWeight: FontWeight.w500,
|
|
color: AppColors.primaryColor,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
},
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _themeChangeRow() {
|
|
return Padding(
|
|
padding: EdgeInsets.symmetric(horizontal: 8.0.w()),
|
|
child: Row(
|
|
children: [
|
|
Text(
|
|
ProfileStrings.appTheme,
|
|
style: TextStyle(
|
|
fontSize: 16.0.sp(),
|
|
fontWeight: FontWeight.w400,
|
|
color: AppColors.grey70,
|
|
),
|
|
),
|
|
const Spacer(),
|
|
SvgPicture.asset(AssetsManager.sun),
|
|
SizedBox(width: 12.0.w()),
|
|
SizedBox(
|
|
width: 52.0.w(),
|
|
height: 32.0.h(),
|
|
child: const ThemeToggle(),
|
|
),
|
|
SizedBox(width: 12.0.w()),
|
|
SvgPicture.asset(AssetsManager.moon),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|