Merge pull request 'some changes' (#30) from new_fixes into main

Reviewed-on: https://repo.ravanertebat.com/TM/tm_app/pulls/30
This commit is contained in:
a.ghabeli
2025-08-11 10:28:11 +03:30
11 changed files with 66 additions and 76 deletions
@@ -28,6 +28,7 @@ class DesktopShellPage extends StatelessWidget {
return Container( return Container(
height: 64, height: 64,
decoration: BoxDecoration( decoration: BoxDecoration(
color: AppColors.backgroundColor,
border: Border(bottom: BorderSide(color: AppColors.grey30)), border: Border(bottom: BorderSide(color: AppColors.grey30)),
), ),
@@ -29,6 +29,7 @@ class TabletShellPage extends StatelessWidget {
height: 64.0.h(), height: 64.0.h(),
padding: EdgeInsets.symmetric(horizontal: 24.0.w()), padding: EdgeInsets.symmetric(horizontal: 24.0.w()),
decoration: BoxDecoration( decoration: BoxDecoration(
color: AppColors.backgroundColor,
border: Border( border: Border(
bottom: BorderSide(color: AppColors.grey30, width: 1), bottom: BorderSide(color: AppColors.grey30, width: 1),
), ),
+5 -3
View File
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../core/utils/result.dart'; import '../core/utils/result.dart';
import '../data/models/user_model.dart'; import '../data/models/user_model.dart';
import '../data/repositories/auth_repository.dart'; import '../data/repositories/auth_repository.dart';
@@ -7,7 +8,7 @@ class AuthViewModel with ChangeNotifier {
final AuthRepository _authRepository; final AuthRepository _authRepository;
AuthViewModel({required AuthRepository authRepository}) AuthViewModel({required AuthRepository authRepository})
: _authRepository = authRepository { : _authRepository = authRepository {
usernameController.addListener(_onTextChanged); usernameController.addListener(_onTextChanged);
passwordController.addListener(_onTextChanged); passwordController.addListener(_onTextChanged);
usernameFocus.addListener(_onTextChanged); usernameFocus.addListener(_onTextChanged);
@@ -22,8 +23,7 @@ class AuthViewModel with ChangeNotifier {
bool _obscurePassword = true; bool _obscurePassword = true;
bool get obscurePassword => _obscurePassword; bool get obscurePassword => _obscurePassword;
bool get isLoginEnabled => bool get isLoginEnabled =>
usernameController.text.isNotEmpty && usernameController.text.isNotEmpty && passwordController.text.isNotEmpty;
passwordController.text.isNotEmpty;
// Auth state // Auth state
bool _isLoading = false; bool _isLoading = false;
@@ -64,6 +64,8 @@ class AuthViewModel with ChangeNotifier {
_isLoading = false; _isLoading = false;
notifyListeners(); notifyListeners();
_errorMessage = null;
notifyListeners();
} }
@override @override
+11 -4
View File
@@ -7,8 +7,13 @@ import 'package:tm_app/data/services/model/tender_detail_response/tender_detail_
class TenderDetailViewModel with ChangeNotifier { class TenderDetailViewModel with ChangeNotifier {
final TenderDetailRepository _tenderDetailRepository; final TenderDetailRepository _tenderDetailRepository;
TenderDetailViewModel({required TenderDetailRepository tenderDetailRepository}) TenderDetailViewModel({
: _tenderDetailRepository = tenderDetailRepository; required TenderDetailRepository tenderDetailRepository,
}) : _tenderDetailRepository = tenderDetailRepository {
WidgetsBinding.instance.addPostFrameCallback((_) {
getTenderDetail(id: 'JNDFKMDV-100JF');
});
}
bool _isLoading = false; bool _isLoading = false;
String? _errorMessage; String? _errorMessage;
@@ -23,8 +28,10 @@ class TenderDetailViewModel with ChangeNotifier {
_errorMessage = null; _errorMessage = null;
notifyListeners(); notifyListeners();
final request = TenderDetailRequest(id: id); final request = TenderDetailRequest(id: id);
final result = await _tenderDetailRepository.getTenderDetail(request: request); final result = await _tenderDetailRepository.getTenderDetail(
request: request,
);
switch (result) { switch (result) {
case Ok<TenderDetailResponseModel>(): case Ok<TenderDetailResponseModel>():
_tenderDetail = result.value; _tenderDetail = result.value;
@@ -10,26 +10,10 @@ import 'package:tm_app/views/detail/widgets/tender_detail_action.dart';
import 'package:tm_app/views/detail/widgets/tender_detail_card.dart'; import 'package:tm_app/views/detail/widgets/tender_detail_card.dart';
import 'package:tm_app/views/detail/widgets/tender_detail_header.dart'; import 'package:tm_app/views/detail/widgets/tender_detail_header.dart';
class TenderDetailDesktopPage extends StatefulWidget { class TenderDetailDesktopPage extends StatelessWidget {
final String tenderId; final String tenderId;
const TenderDetailDesktopPage({required this.tenderId, super.key}); const TenderDetailDesktopPage({required this.tenderId, super.key});
@override
State<TenderDetailDesktopPage> createState() =>
_TenderDetailDesktopPageState();
}
class _TenderDetailDesktopPageState extends State<TenderDetailDesktopPage> {
@override
void initState() {
super.initState();
Future.microtask(() {
context.read<TenderDetailViewModel>().getTenderDetail(
id: widget.tenderId,
);
});
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
+3 -18
View File
@@ -10,24 +10,9 @@ import 'package:tm_app/views/detail/widgets/tender_detail_action.dart';
import 'package:tm_app/views/detail/widgets/tender_detail_card.dart'; import 'package:tm_app/views/detail/widgets/tender_detail_card.dart';
import 'package:tm_app/views/detail/widgets/tender_detail_header.dart'; import 'package:tm_app/views/detail/widgets/tender_detail_header.dart';
class TenderDetailMobilePage extends StatefulWidget { class TenderDetailMobilePage extends StatelessWidget {
final String tenderId; final String tenderId;
const TenderDetailMobilePage({super.key, required this.tenderId}); const TenderDetailMobilePage({required this.tenderId, super.key});
@override
State<TenderDetailMobilePage> createState() => _TenderDetailMobilePageState();
}
class _TenderDetailMobilePageState extends State<TenderDetailMobilePage> {
@override
void initState() {
super.initState();
Future.microtask(() {
context.read<TenderDetailViewModel>().getTenderDetail(
id: widget.tenderId,
);
});
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@@ -48,7 +33,7 @@ class _TenderDetailMobilePageState extends State<TenderDetailMobilePage> {
final detail = tenderViewModel.tenderDetail; final detail = tenderViewModel.tenderDetail;
if (detail == null) { if (detail == null) {
return const Center(child: Text("No tender details available")); return const Center(child: Text('No tender details available'));
} }
return SingleChildScrollView( return SingleChildScrollView(
+1 -16
View File
@@ -10,25 +10,10 @@ import 'package:tm_app/views/detail/widgets/tender_detail_action.dart';
import 'package:tm_app/views/detail/widgets/tender_detail_card.dart'; import 'package:tm_app/views/detail/widgets/tender_detail_card.dart';
import 'package:tm_app/views/detail/widgets/tender_detail_header.dart'; import 'package:tm_app/views/detail/widgets/tender_detail_header.dart';
class TenderDetailTabletPage extends StatefulWidget { class TenderDetailTabletPage extends StatelessWidget {
final String tenderId; final String tenderId;
const TenderDetailTabletPage({required this.tenderId, super.key}); const TenderDetailTabletPage({required this.tenderId, super.key});
@override
State<TenderDetailTabletPage> createState() => _TenderDetailTabletPageState();
}
class _TenderDetailTabletPageState extends State<TenderDetailTabletPage> {
@override
void initState() {
super.initState();
Future.microtask(() {
context.read<TenderDetailViewModel>().getTenderDetail(
id: widget.tenderId,
);
});
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
@@ -28,7 +28,7 @@ class TenderDetailActions extends StatelessWidget {
isEnabled: true, isEnabled: true,
text: AppStrings.tenderSubmitButton, text: AppStrings.tenderSubmitButton,
backgroundColor: AppColors.lightBlue, backgroundColor: AppColors.lightBlue,
textColor: AppColors.primary30, textColor: AppColors.mainBlue,
onPressed: () {}, onPressed: () {},
width: 120.0.w(), width: 120.0.w(),
), ),
+2 -1
View File
@@ -164,8 +164,9 @@ class DesktopHomePage extends StatelessWidget {
Widget _bottomListView(HomeResponseModel homeResponse) { Widget _bottomListView(HomeResponseModel homeResponse) {
return SizedBox( return SizedBox(
width: 740, width: 740,
height: 310.0.h(), height: 290.0,
child: ListView.builder( child: ListView.builder(
padding: EdgeInsets.only(bottom: 20),
itemCount: homeResponse.yourTenders?.length ?? 0, itemCount: homeResponse.yourTenders?.length ?? 0,
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
itemBuilder: (context, index) { itemBuilder: (context, index) {
+36 -16
View File
@@ -9,9 +9,39 @@ import '../../../core/utils/size_config.dart';
import '../../../view_models/auth_view_model.dart'; import '../../../view_models/auth_view_model.dart';
import '../widgets/widgets.dart'; import '../widgets/widgets.dart';
class LoginMobilePage extends StatelessWidget { class LoginMobilePage extends StatefulWidget {
const LoginMobilePage({super.key}); const LoginMobilePage({super.key});
@override
State<LoginMobilePage> createState() => _LoginMobilePageState();
}
class _LoginMobilePageState extends State<LoginMobilePage> {
late final AuthViewModel viewModel;
@override
void initState() {
viewModel = context.read<AuthViewModel>();
viewModel.addListener(_viewModelListener);
super.initState();
}
void _viewModelListener() {
if (viewModel.loggedInUser != null) {
HomeRouteData().go(context);
}
if (viewModel.errorMessage != null) {
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text(viewModel.errorMessage!)));
}
}
@override
void dispose() {
viewModel.removeListener(_viewModelListener);
super.dispose();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
@@ -58,21 +88,11 @@ class LoginMobilePage extends StatelessWidget {
else else
BaseButton( BaseButton(
isEnabled: viewModel.isLoginEnabled, isEnabled: viewModel.isLoginEnabled,
onPressed: onPressed: () async {
viewModel.isLoginEnabled if (viewModel.isLoginEnabled) {
? () async { await viewModel.login();
await viewModel.login(); }
if (viewModel.loggedInUser != null) { },
HomeRouteData().go(context);
} else if (viewModel.errorMessage != null) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(viewModel.errorMessage!),
),
);
}
}
: null,
), ),
], ],
); );
@@ -30,6 +30,7 @@ class TenderActionButtons extends StatelessWidget {
Tooltip( Tooltip(
message: 'Dislike', message: 'Dislike',
child: InkWell( child: InkWell(
splashColor: Colors.transparent,
onTap: () { onTap: () {
viewModel.onDislike(tender); viewModel.onDislike(tender);
}, },
@@ -69,6 +70,7 @@ class TenderActionButtons extends StatelessWidget {
Tooltip( Tooltip(
message: 'Reject', message: 'Reject',
child: InkWell( child: InkWell(
splashColor: Colors.transparent,
onTap: () { onTap: () {
viewModel.onReject(tender); viewModel.onReject(tender);
}, },
@@ -119,6 +121,7 @@ class TenderActionButtons extends StatelessWidget {
Tooltip( Tooltip(
message: 'Submit', message: 'Submit',
child: InkWell( child: InkWell(
splashColor: Colors.transparent,
onTap: () { onTap: () {
viewModel.onSubmit(tender); viewModel.onSubmit(tender);
}, },
@@ -170,6 +173,7 @@ class TenderActionButtons extends StatelessWidget {
Tooltip( Tooltip(
message: 'Like', message: 'Like',
child: InkWell( child: InkWell(
splashColor: Colors.transparent,
onTap: () { onTap: () {
viewModel.onLike(tender); viewModel.onLike(tender);
}, },