finished ui/ux

This commit is contained in:
mohamadmahdi jebeli 2025-07-02 16:58:01 +03:30
parent 15782a7d34
commit 61611fef04
22 changed files with 283 additions and 171 deletions

View File

@ -1,4 +1,3 @@
import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:image_picker/image_picker.dart'; import 'package:image_picker/image_picker.dart';

View File

@ -1,13 +1,14 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_animate/flutter_animate.dart'; import 'package:flutter_animate/flutter_animate.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
// ignore: depend_on_referenced_packages
import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:proxibuy/data/models/datasources/offer_data_source.dart'; import 'package:proxibuy/data/models/datasources/offer_data_source.dart';
import 'package:proxibuy/data/repositories/offer_repository.dart'; import 'package:proxibuy/data/repositories/offer_repository.dart';
import 'package:proxibuy/presentation/auth/bloc/auth_bloc.dart'; import 'package:proxibuy/presentation/auth/bloc/auth_bloc.dart';
import 'package:proxibuy/presentation/notification_preferences/bloc/notification_preferences_bloc.dart'; import 'package:proxibuy/presentation/notification_preferences/bloc/notification_preferences_bloc.dart';
import 'package:proxibuy/presentation/notification_preferences/bloc/notification_preferences_event.dart'; import 'package:proxibuy/presentation/notification_preferences/bloc/notification_preferences_event.dart';
import 'package:proxibuy/presentation/offer/bloc/offer_bloc.dart'; // مسیر BLoC آفر import 'package:proxibuy/presentation/offer/bloc/offer_bloc.dart';
import 'package:proxibuy/presentation/reservation/cubit/reservation_cubit.dart'; import 'package:proxibuy/presentation/reservation/cubit/reservation_cubit.dart';
import 'core/config/app_colors.dart'; import 'core/config/app_colors.dart';
import 'presentation/pages/onboarding_page.dart'; import 'presentation/pages/onboarding_page.dart';
@ -98,6 +99,7 @@ class MyApp extends StatelessWidget {
), ),
), ),
labelStyle: const TextStyle(color: Colors.black), labelStyle: const TextStyle(color: Colors.black),
// ignore: deprecated_member_use
hintStyle: TextStyle(color: Colors.black.withOpacity(0.8)), hintStyle: TextStyle(color: Colors.black.withOpacity(0.8)),
), ),
outlinedButtonTheme: OutlinedButtonThemeData( outlinedButtonTheme: OutlinedButtonThemeData(

View File

@ -1,4 +1,6 @@
// ignore: depend_on_referenced_packages
import 'package:bloc/bloc.dart'; import 'package:bloc/bloc.dart';
// ignore: depend_on_referenced_packages
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import 'dart:async'; import 'dart:async';
@ -31,8 +33,6 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
emit(AuthLoading()); emit(AuthLoading());
await Future.delayed(const Duration(milliseconds: 500)); await Future.delayed(const Duration(milliseconds: 500));
print('User info to save: Name: ${event.name}, Gender: ${event.gender}');
if (event.name.trim().isEmpty) { if (event.name.trim().isEmpty) {
emit(AuthFailure('لطفاً نام خود را وارد کنید.')); emit(AuthFailure('لطفاً نام خود را وارد کنید.'));
} else { } else {

View File

@ -1,3 +1,4 @@
// ignore: depend_on_referenced_packages
import 'package:bloc/bloc.dart'; import 'package:bloc/bloc.dart';
import 'package:proxibuy/data/repositories/offer_repository.dart'; import 'package:proxibuy/data/repositories/offer_repository.dart';
import 'package:proxibuy/presentation/offer/bloc/offer_event.dart'; import 'package:proxibuy/presentation/offer/bloc/offer_event.dart';

View File

@ -80,6 +80,7 @@ class _OfferCardState extends State<OfferCard> {
), ),
boxShadow: [ boxShadow: [
BoxShadow( BoxShadow(
// ignore: deprecated_member_use
color: Colors.grey.withOpacity(0.2), color: Colors.grey.withOpacity(0.2),
spreadRadius: 2, spreadRadius: 2,
blurRadius: 5, blurRadius: 5,

View File

@ -188,6 +188,7 @@ class AddPhotoScreen extends StatelessWidget {
), ),
boxShadow: [ boxShadow: [
BoxShadow( BoxShadow(
// ignore: deprecated_member_use
color: Colors.black.withOpacity(0.08), color: Colors.black.withOpacity(0.08),
blurRadius: 10, blurRadius: 10,
offset: const Offset(0, 4), offset: const Offset(0, 4),
@ -321,6 +322,7 @@ class AddPhotoScreen extends StatelessWidget {
shape: BoxShape.circle, shape: BoxShape.circle,
boxShadow: [ boxShadow: [
BoxShadow( BoxShadow(
// ignore: deprecated_member_use
color: Colors.black.withOpacity(0.3), color: Colors.black.withOpacity(0.3),
blurRadius: 8, blurRadius: 8,
offset: const Offset(0, 4), offset: const Offset(0, 4),

View File

@ -8,6 +8,8 @@ import 'package:proxibuy/presentation/notification_preferences/bloc/notification
import 'package:proxibuy/presentation/offer/bloc/offer_bloc.dart'; import 'package:proxibuy/presentation/offer/bloc/offer_bloc.dart';
import 'package:proxibuy/presentation/offer/bloc/offer_event.dart'; import 'package:proxibuy/presentation/offer/bloc/offer_event.dart';
import 'package:proxibuy/presentation/pages/offers_page.dart'; import 'package:proxibuy/presentation/pages/offers_page.dart';
import 'package:proxibuy/presentation/pages/reserved_list_page.dart';
import 'package:proxibuy/presentation/reservation/cubit/reservation_cubit.dart';
import 'package:proxibuy/presentation/widgets/category_selection_card.dart'; import 'package:proxibuy/presentation/widgets/category_selection_card.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
@ -31,18 +33,66 @@ class NotificationPreferencesPage extends StatelessWidget {
child: Assets.icons.logoWithName.svg(height: 40, width: 200), child: Assets.icons.logoWithName.svg(height: 40, width: 200),
), ),
actions: [ actions: [
IconButton(onPressed: () {}, icon: Assets.icons.notification.svg()),
BlocBuilder<ReservationCubit, ReservationState>(
builder: (context, state) {
final reservedCount = state.reservedProductIds.length;
return Stack(
alignment: Alignment.center,
children: [
IconButton( IconButton(
onPressed: () { onPressed: () {
// TODO: Navigate to notifications page Navigator.of(context).push(
}, MaterialPageRoute(
icon: Assets.icons.notification.svg(), builder: (_) => const ReservedListPage(),
), ),
IconButton( );
onPressed: () {
// TODO: Navigate to QR codes page
}, },
icon: Assets.icons.scanBarcode.svg(), icon: Assets.icons.scanBarcode.svg(),
), ),
if (reservedCount > 0)
Positioned(
top: 0,
right: 2,
child: GestureDetector(
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => const ReservedListPage(),
),
);
},
child: Container(
padding: const EdgeInsets.all(4),
decoration: BoxDecoration(
color: Colors.green,
shape: BoxShape.circle,
border: Border.all(color: Colors.white, width: 1.5),
),
constraints: const BoxConstraints(
minWidth: 18,
minHeight: 18,
),
child: Padding(
padding: const EdgeInsets.fromLTRB(2, 4, 2, 2),
child: Text(
'$reservedCount',
style: const TextStyle(
color: Colors.white,
fontSize: 11,
fontWeight: FontWeight.bold,
),
textAlign: TextAlign.center,
),
),
),
),
),
],
);
},
),
const SizedBox(width: 8), const SizedBox(width: 8),
], ],
), ),
@ -73,7 +123,7 @@ class NotificationPreferencesPage extends StatelessWidget {
TextSpan( TextSpan(
text: text:
'ترجیح می‌دی از کدام دسته‌بندی‌ها اعلان تخفیف دریافت کنی؟ ', 'ترجیح می‌دی از کدام دسته‌بندی‌ها اعلان تخفیف دریافت کنی؟ ',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16), style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14),
), ),
TextSpan(text: '(حداقل یک مورد رو انتخاب کن).'), TextSpan(text: '(حداقل یک مورد رو انتخاب کن).'),
], ],
@ -105,6 +155,7 @@ class NotificationPreferencesPage extends StatelessWidget {
final itemHeight = itemWidth / childAspectRatio; final itemHeight = itemWidth / childAspectRatio;
return SingleChildScrollView( return SingleChildScrollView(
child: Center(
child: Wrap( child: Wrap(
alignment: WrapAlignment.center, alignment: WrapAlignment.center,
spacing: crossAxisSpacing, spacing: crossAxisSpacing,
@ -114,8 +165,9 @@ class NotificationPreferencesPage extends StatelessWidget {
final isSelected = state.selectedCategoryIds final isSelected = state.selectedCategoryIds
.contains(category.id); .contains(category.id);
return SizedBox( return SizedBox(
width: itemWidth, width: 100,
height: itemHeight, height: itemHeight,
child: Center(
child: CategorySelectionCard( child: CategorySelectionCard(
name: category.name, name: category.name,
icon: category.icon, icon: category.icon,
@ -126,13 +178,17 @@ class NotificationPreferencesPage extends StatelessWidget {
context context
.read<NotificationPreferencesBloc>() .read<NotificationPreferencesBloc>()
.add( .add(
ToggleCategorySelection(category.id), ToggleCategorySelection(
category.id,
),
); );
}, },
), ),
),
); );
}).toList(), }).toList(),
), ),
),
); );
}, },
), ),
@ -212,7 +268,7 @@ class NotificationPreferencesPage extends StatelessWidget {
); );
}, },
), ),
const SizedBox(height: 40), const SizedBox(height: 20),
], ],
), ),
), ),

View File

@ -170,7 +170,8 @@ class _OffersPageState extends State<OffersPage> {
onPressed: () { onPressed: () {
Navigator.of(context).push( Navigator.of(context).push(
MaterialPageRoute( MaterialPageRoute(
builder: (_) => const ReservedListPage()), builder: (_) => const ReservedListPage(),
),
); );
}, },
icon: Assets.icons.scanBarcode.svg(), icon: Assets.icons.scanBarcode.svg(),
@ -179,12 +180,23 @@ class _OffersPageState extends State<OffersPage> {
Positioned( Positioned(
top: 0, top: 0,
right: 2, right: 2,
child: GestureDetector(
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => const ReservedListPage(),
),
);
},
child: Container( child: Container(
padding: const EdgeInsets.all(4), padding: const EdgeInsets.all(4),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.green, color: Colors.green,
shape: BoxShape.circle, shape: BoxShape.circle,
border: Border.all(color: Colors.white, width: 1.5), border: Border.all(
color: Colors.white,
width: 1.5,
),
), ),
constraints: const BoxConstraints( constraints: const BoxConstraints(
minWidth: 18, minWidth: 18,
@ -204,6 +216,7 @@ class _OffersPageState extends State<OffersPage> {
), ),
), ),
), ),
),
], ],
); );
}, },

View File

@ -157,12 +157,11 @@ class _OnboardingPageState extends State<OnboardingPage> {
), ),
),), ),),
Positioned( Positioned(
bottom: 85, bottom: 90,
left: 24, left: 24,
right: 24, right: 24,
child: Column( child: Column(
children: [ children: [
const SizedBox(height: 40),
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -173,7 +172,7 @@ class _OnboardingPageState extends State<OnboardingPage> {
context, context,
).textTheme.headlineSmall?.copyWith( ).textTheme.headlineSmall?.copyWith(
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
fontSize: 20, fontSize: 18,
color: color:
Colors.white Colors.white
), ),
@ -183,7 +182,9 @@ class _OnboardingPageState extends State<OnboardingPage> {
onboardingPages[_currentPage].description, onboardingPages[_currentPage].description,
textAlign: TextAlign.right, textAlign: TextAlign.right,
style: Theme.of(context).textTheme.bodyLarge?.copyWith( style: Theme.of(context).textTheme.bodyLarge?.copyWith(
// ignore: deprecated_member_use
color: Colors.white.withOpacity(0.8), color: Colors.white.withOpacity(0.8),
fontSize: 16,
height: 1.5, height: 1.5,
), ),
), ),

View File

@ -1,4 +1,3 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
@ -18,8 +17,10 @@ class OtpPage extends StatefulWidget {
class _OtpPageState extends State<OtpPage> { class _OtpPageState extends State<OtpPage> {
final List<FocusNode> _focusNodes = List.generate(5, (_) => FocusNode()); final List<FocusNode> _focusNodes = List.generate(5, (_) => FocusNode());
final List<TextEditingController> _controllers = final List<TextEditingController> _controllers = List.generate(
List.generate(5, (_) => TextEditingController()); 5,
(_) => TextEditingController(),
);
late final OtpTimerHelper _otpTimer; late final OtpTimerHelper _otpTimer;
bool _hasError = false; bool _hasError = false;
@ -54,7 +55,6 @@ class _OtpPageState extends State<OtpPage> {
return Directionality( return Directionality(
textDirection: TextDirection.rtl, textDirection: TextDirection.rtl,
child: Scaffold( child: Scaffold(
appBar: AppBar(backgroundColor: Colors.transparent, elevation: 0),
body: SafeArea( body: SafeArea(
child: SingleChildScrollView( child: SingleChildScrollView(
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16), padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16),
@ -70,14 +70,28 @@ class _OtpPageState extends State<OtpPage> {
), ),
), ),
const SizedBox(height: 12), const SizedBox(height: 12),
Text( Text.rich(
"کد تایید به شماره ${widget.phoneNumber} ارسال شد.", TextSpan(
style: textTheme.titleMedium?.copyWith( style: textTheme.titleMedium?.copyWith(
color: Colors.grey, color: Colors.grey,
height: 1.5, height: 1.5,
), ),
children: <TextSpan>[
const TextSpan(text: 'کد تایید به شماره ',style: TextStyle(fontSize: 15)),
TextSpan(
text: widget.phoneNumber,
style: const TextStyle(
fontWeight:
FontWeight.bold,
fontSize: 15
), ),
SizedBox(height: 15,), ),
const TextSpan(text: ' ارسال شد.',style: TextStyle(fontSize: 15)),
],
),
textDirection: TextDirection.rtl, // جهت متن برای RichText
),
SizedBox(height: 15),
Row( Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
@ -85,7 +99,10 @@ class _OtpPageState extends State<OtpPage> {
const SizedBox(width: 4), const SizedBox(width: 4),
TextButton( TextButton(
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
child: const Text("ویرایش شماره همراه",style: TextStyle(color: AppColors.active),), child: const Text(
"ویرایش شماره همراه",
style: TextStyle(color: AppColors.active),
),
), ),
], ],
), ),
@ -118,9 +135,7 @@ class _OtpPageState extends State<OtpPage> {
} }
if (state is AuthVerified) { if (state is AuthVerified) {
Navigator.of(context).pushAndRemoveUntil( Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute( MaterialPageRoute(builder: (_) => const UserInfoPage()),
builder: (_) => const UserInfoPage(),
),
(route) => false, (route) => false,
); );
} }
@ -156,11 +171,15 @@ class _OtpPageState extends State<OtpPage> {
return canResend return canResend
? TextButton( ? TextButton(
onPressed: _resendOtp, onPressed: _resendOtp,
child: const Text("ارسال مجدد کد",style: TextStyle(color: AppColors.active),), child: const Text(
"ارسال مجدد کد",
style: TextStyle(color: AppColors.active),
),
) )
: ValueListenableBuilder<int>( : ValueListenableBuilder<int>(
valueListenable: _otpTimer.remainingSeconds, valueListenable: _otpTimer.remainingSeconds,
builder: (context, seconds, child) => Text( builder:
(context, seconds, child) => Text(
"${_otpTimer.formatTime()} تا دریافت مجدد", "${_otpTimer.formatTime()} تا دریافت مجدد",
style: const TextStyle(color: Colors.grey), style: const TextStyle(color: Colors.grey),
), ),
@ -202,7 +221,8 @@ class _OtpPageState extends State<OtpPage> {
enabledBorder: OutlineInputBorder( enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
borderSide: BorderSide( borderSide: BorderSide(
color: _hasError color:
_hasError
? Colors.red ? Colors.red
: (Theme.of(context) : (Theme.of(context)
.inputDecorationTheme .inputDecorationTheme

View File

@ -263,6 +263,7 @@ class _ProductDetailViewState extends State<ProductDetailView> {
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
boxShadow: [ boxShadow: [
BoxShadow( BoxShadow(
// ignore: deprecated_member_use
color: Colors.black.withOpacity(0.15), color: Colors.black.withOpacity(0.15),
blurRadius: 7, blurRadius: 7,
spreadRadius: 0, spreadRadius: 0,

View File

@ -63,7 +63,8 @@ class _ReservationConfirmationPageState extends State<ReservationConfirmationPag
child: Scaffold( child: Scaffold(
backgroundColor: Colors.grey[50], backgroundColor: Colors.grey[50],
appBar: _buildCustomAppBar(context), appBar: _buildCustomAppBar(context),
body: Padding( body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 32.0), padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 32.0),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@ -104,6 +105,7 @@ class _ReservationConfirmationPageState extends State<ReservationConfirmationPag
), ),
), ),
), ),
),
); );
} }
@ -118,6 +120,7 @@ class _ReservationConfirmationPageState extends State<ReservationConfirmationPag
), ),
boxShadow: [ boxShadow: [
BoxShadow( BoxShadow(
// ignore: deprecated_member_use
color: Colors.black.withOpacity(0.08), color: Colors.black.withOpacity(0.08),
blurRadius: 10, blurRadius: 10,
offset: const Offset(0, 4), offset: const Offset(0, 4),
@ -216,6 +219,7 @@ class _ReservationConfirmationPageState extends State<ReservationConfirmationPag
const SizedBox(height: 10), const SizedBox(height: 10),
Row( Row(
children: [ children: [
// ignore: deprecated_member_use
SvgPicture.asset(Assets.icons.cardPos.path,height: 22,color: Color.fromARGB(255, 157, 157, 155),), SvgPicture.asset(Assets.icons.cardPos.path,height: 22,color: Color.fromARGB(255, 157, 157, 155),),
SizedBox(width: 6,), SizedBox(width: 6,),
Text( Text(

View File

@ -119,6 +119,7 @@ class _ReservedListPageState extends State<ReservedListPage> {
), ),
boxShadow: [ boxShadow: [
BoxShadow( BoxShadow(
// ignore: deprecated_member_use
color: Colors.black.withOpacity(0.08), color: Colors.black.withOpacity(0.08),
blurRadius: 10, blurRadius: 10,
offset: const Offset(0, 4), offset: const Offset(0, 4),

View File

@ -76,6 +76,7 @@ class _UserInfoPageState extends State<UserInfoPage> {
width: 50, width: 50,
height: 5, height: 5,
decoration: BoxDecoration( decoration: BoxDecoration(
// ignore: deprecated_member_use
color:Colors.grey.withOpacity(0.5), color:Colors.grey.withOpacity(0.5),
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
), ),
@ -113,7 +114,7 @@ class _UserInfoPageState extends State<UserInfoPage> {
_buildGenderRadio('تمایلی به پاسخ ندارم', 'نامشخص'), _buildGenderRadio('تمایلی به پاسخ ندارم', 'نامشخص'),
], ],
), ),
const SizedBox(height: 70), const SizedBox(height: 55),
BlocConsumer<AuthBloc, AuthState>( BlocConsumer<AuthBloc, AuthState>(
listener: (context, state) { listener: (context, state) {
@ -154,7 +155,7 @@ class _UserInfoPageState extends State<UserInfoPage> {
Center( Center(
child: TextButton( child: TextButton(
onPressed: () { onPressed: () {
Navigator.of(context).push(NotificationPreferencesPage.route()); Navigator.of(context).pushReplacement(NotificationPreferencesPage.route());
}, },
child: const Text( child: const Text(
"رد شدن", "رد شدن",

View File

@ -1,3 +1,4 @@
// ignore: depend_on_referenced_packages
import 'package:bloc/bloc.dart'; import 'package:bloc/bloc.dart';
import 'package:proxibuy/data/repositories/offer_repository.dart'; import 'package:proxibuy/data/repositories/offer_repository.dart';
import 'package:proxibuy/presentation/product_detail/bloc/product_detail_event.dart'; import 'package:proxibuy/presentation/product_detail/bloc/product_detail_event.dart';

View File

@ -1,3 +1,4 @@
// ignore: depend_on_referenced_packages
import 'package:bloc/bloc.dart'; import 'package:bloc/bloc.dart';
part 'reservation_state.dart'; part 'reservation_state.dart';
@ -10,10 +11,8 @@ class ReservationCubit extends Cubit<ReservationState> {
final updatedList = List<String>.from(state.reservedProductIds)..add(productId); final updatedList = List<String>.from(state.reservedProductIds)..add(productId);
emit(state.copyWith(reservedProductIds: updatedList)); emit(state.copyWith(reservedProductIds: updatedList));
// در اینجا میتوانید لاگیک مربوط به ارسال درخواست به API را نیز اضافه کنید
} }
// متد برای بررسی اینکه آیا یک محصول خاص رزرو شده است یا نه
bool isProductReserved(String productId) { bool isProductReserved(String productId) {
return state.reservedProductIds.contains(productId); return state.reservedProductIds.contains(productId);
} }

View File

@ -11,13 +11,13 @@ class CategorySelectionCard extends StatelessWidget {
final VoidCallback onTap; final VoidCallback onTap;
const CategorySelectionCard({ const CategorySelectionCard({
Key? key, super.key,
required this.name, required this.name,
required this.icon, required this.icon,
required this.isSelected, required this.isSelected,
required this.showSelectableIndicator, required this.showSelectableIndicator,
required this.onTap, required this.onTap,
}) : super(key: key); });
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -44,6 +44,7 @@ class CategorySelectionCard extends StatelessWidget {
boxShadow: isSelected boxShadow: isSelected
? [ ? [
BoxShadow( BoxShadow(
// ignore: deprecated_member_use
color: AppColors.confirm.withOpacity(0.25), color: AppColors.confirm.withOpacity(0.25),
blurRadius: 8, blurRadius: 8,
spreadRadius: 2, spreadRadius: 2,

View File

@ -35,8 +35,9 @@ class PhotoGalleryView extends StatelessWidget {
child: Stack( child: Stack(
fit: StackFit.expand, fit: StackFit.expand,
children: [ children: [
_buildSmartImage(imageUrl), // از ویجت هوشمند استفاده میکنیم _buildSmartImage(imageUrl),
Container( Container(
// ignore: deprecated_member_use
color: Colors.white.withOpacity(0.7), color: Colors.white.withOpacity(0.7),
child: Center( child: Center(
child: Text( child: Text(

View File

@ -8,6 +8,7 @@ Future<void> showGPSDialog(BuildContext context) async {
bool isLocationEnabled = await Geolocator.isLocationServiceEnabled(); bool isLocationEnabled = await Geolocator.isLocationServiceEnabled();
if (!isLocationEnabled) { if (!isLocationEnabled) {
await showDialog( await showDialog(
// ignore: use_build_context_synchronously
context: context, context: context,
barrierDismissible: false, barrierDismissible: false,
builder: (BuildContext context) { builder: (BuildContext context) {
@ -67,6 +68,7 @@ Future<void> showGPSDialog(BuildContext context) async {
), ),
onPressed: () async { onPressed: () async {
await Geolocator.openLocationSettings(); await Geolocator.openLocationSettings();
// ignore: use_build_context_synchronously
Navigator.of(context).pop(); Navigator.of(context).pop();
}, },
child: const Text( child: const Text(
@ -86,6 +88,7 @@ Future<void> showGPSDialog(BuildContext context) async {
shape: BoxShape.circle, shape: BoxShape.circle,
boxShadow: [ boxShadow: [
BoxShadow( BoxShadow(
// ignore: deprecated_member_use
color: Colors.black.withOpacity(0.3), color: Colors.black.withOpacity(0.3),
blurRadius: 8, blurRadius: 8,
offset: const Offset(0, 4), offset: const Offset(0, 4),

View File

@ -11,6 +11,7 @@ Future<void> showNotificationPermissionDialog(BuildContext context) async {
} }
await showDialog( await showDialog(
// ignore: use_build_context_synchronously
context: context, context: context,
barrierDismissible: false, barrierDismissible: false,
builder: (BuildContext dialogContext) { builder: (BuildContext dialogContext) {
@ -77,6 +78,7 @@ Future<void> showNotificationPermissionDialog(BuildContext context) async {
final result = final result =
await Permission.notification.request(); await Permission.notification.request();
if (result.isGranted) { if (result.isGranted) {
// ignore: use_build_context_synchronously
Navigator.of(dialogContext).pop(); Navigator.of(dialogContext).pop();
} else { } else {
openAppSettings(); openAppSettings();
@ -99,6 +101,7 @@ Future<void> showNotificationPermissionDialog(BuildContext context) async {
shape: BoxShape.circle, shape: BoxShape.circle,
boxShadow: [ boxShadow: [
BoxShadow( BoxShadow(
// ignore: deprecated_member_use
color: Colors.black.withOpacity(0.3), color: Colors.black.withOpacity(0.3),
blurRadius: 8, blurRadius: 8,
offset: const Offset(0, 4), offset: const Offset(0, 4),

View File

@ -55,6 +55,7 @@ class _ReservedListItemCardState extends State<ReservedListItemCard> {
super.dispose(); super.dispose();
} }
// ignore: unused_element
String _formatDuration(Duration duration) { String _formatDuration(Duration duration) {
if (duration.inSeconds <= 0) return "پایان یافته"; if (duration.inSeconds <= 0) return "پایان یافته";
final hours = duration.inHours.toString().padLeft(2, '0'); final hours = duration.inHours.toString().padLeft(2, '0');

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
// ignore: depend_on_referenced_packages
import 'package:intl/intl.dart' as intl; import 'package:intl/intl.dart' as intl;
import 'package:proxibuy/core/config/app_colors.dart'; import 'package:proxibuy/core/config/app_colors.dart';
import 'package:proxibuy/core/gen/assets.gen.dart'; import 'package:proxibuy/core/gen/assets.gen.dart';