Refactor provider initialization to load only essential providers at startup. Introduce TabNavigationService for managing tab state and update screens to respond to tab changes. Clean up view models and navigation logic for improved performance and maintainability.

This commit is contained in:
amirrezaghabeli
2025-10-06 14:12:40 +03:30
parent 645247183b
commit b43ebf885b
24 changed files with 839 additions and 218 deletions
+106 -86
View File
@@ -49,104 +49,124 @@ class _DesktopProfilePageState extends State<DesktopProfilePage> {
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppColors.backgroundColor,
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!));
}
body: Column(
children: [
const DesktopNavigationWidget(
currentIndex: 4, // Tenders index
),
Consumer<ProfileViewModel>(
builder: (context, viewModel, child) {
if (viewModel.isLoading) {
return const Expanded(
child: Center(
child: CircularProgressIndicator(
color: AppColors.secondary50,
),
),
);
}
if (viewModel.errorMessage != null) {
return Expanded(
child: Center(child: Text(viewModel.errorMessage!)),
);
}
if (viewModel.companyProfileData == null) {
return const Center(child: Text(CommonStrings.noData));
}
if (viewModel.companyProfileData == null) {
return const Expanded(
child: Center(child: Text(CommonStrings.noData)),
);
}
return SafeArea(
child: Column(
children: [
const DesktopNavigationWidget(
currentIndex: 4, // Tenders index
),
SizedBox(
width: 740,
return Expanded(
child: SingleChildScrollView(
child: Column(
children: [
SizedBox(height: 36.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: 24.0.h()),
// Theme Toggle
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()),
// Spacer(),
Align(
alignment: AlignmentDirectional.centerEnd,
child: InkWell(
onTap: () => viewModel.logout(),
borderRadius: BorderRadius.circular(100),
child: Container(
width: 156,
height: 56.0.h(),
decoration: BoxDecoration(
color: AppColors.primary20,
borderRadius: BorderRadius.circular(100),
SizedBox(
width: 740,
child: Column(
children: [
SizedBox(height: 36.0.h()),
TitleDescription(
title: ProfileStrings.companyName,
description: viewModel.companyProfileData!.name!,
),
alignment: Alignment.center,
child: Text(
ProfileStrings.logout,
style: TextStyle(
fontSize: 14.0.sp(),
fontWeight: FontWeight.w500,
color: AppColors.primaryColor,
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: 24.0.h()),
// Theme Toggle
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()),
// Spacer(),
Align(
alignment: AlignmentDirectional.centerEnd,
child: InkWell(
onTap: () => viewModel.logout(),
borderRadius: BorderRadius.circular(100),
child: Container(
width: 156,
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,
),
),
),
),
),
],
),
),
],
),
),
],
),
);
},
);
},
),
],
),
);
}
+21 -3
View File
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:tm_app/core/services/tab_navigation_service.dart';
import 'package:tm_app/core/utils/size_config.dart';
import 'package:tm_app/view_models/profile_view_model.dart';
import 'package:tm_app/views/shared/responsive_builder.dart';
@@ -16,17 +17,34 @@ class ProfileScreen extends StatefulWidget {
}
class _ProfileScreenState extends State<ProfileScreen> {
late ProfileViewModel viewModel;
late final ProfileViewModel _viewModel;
late final TabNavigationService _tabService;
@override
void initState() {
super.initState();
viewModel = context.read<ProfileViewModel>();
_viewModel = context.read<ProfileViewModel>();
_tabService = context.read<TabNavigationService>();
_tabService.addListener(_onTabChanged);
WidgetsBinding.instance.addPostFrameCallback((_) {
viewModel.getCompanyProfile();
_viewModel.getCompanyProfile();
});
}
@override
void dispose() {
_tabService.removeListener(_onTabChanged);
super.dispose();
}
void _onTabChanged() {
// Tab index 2 is Profile
if (_tabService.currentTabIndex == 2 && mounted) {
_viewModel.getCompanyProfile();
}
}
@override
Widget build(BuildContext context) {
SizeConfig.init(context);