first commit
This commit is contained in:
100
lib/widgets/app_button.dart
Normal file
100
lib/widgets/app_button.dart
Normal file
@ -0,0 +1,100 @@
|
||||
import 'package:auto_size_text/auto_size_text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gascom/constants/app_theme.dart';
|
||||
|
||||
class AppButton extends StatelessWidget {
|
||||
const AppButton({
|
||||
super.key,
|
||||
required this.onPressed,
|
||||
required this.label,
|
||||
required this.isElevated,
|
||||
this.isLoading = false,
|
||||
this.textStyle,
|
||||
this.color,
|
||||
});
|
||||
|
||||
final void Function() onPressed;
|
||||
final String label;
|
||||
final bool isLoading;
|
||||
final bool isElevated;
|
||||
final TextStyle? textStyle;
|
||||
final Color? color;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return isElevated
|
||||
? ElevatedButton(
|
||||
onPressed: isLoading ? null : onPressed,
|
||||
style: Theme.of(context).elevatedButtonTheme.style?.copyWith(
|
||||
backgroundColor: WidgetStatePropertyAll(color ?? AppTheme.textColor),
|
||||
),
|
||||
child: isLoading
|
||||
? const Spinner(color: AppTheme.primaryColor)
|
||||
: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: AutoSizeText(
|
||||
label,
|
||||
minFontSize: 8,
|
||||
maxFontSize: 14,
|
||||
maxLines: 1,
|
||||
textAlign: TextAlign.center,
|
||||
style: textStyle ?? Theme.of(context).textTheme.bodyLarge?.copyWith(
|
||||
color: AppTheme.primaryColor,
|
||||
)
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
: OutlinedButton(
|
||||
onPressed: isLoading ? null : onPressed,
|
||||
style: Theme.of(context).elevatedButtonTheme.style?.copyWith(
|
||||
backgroundColor: WidgetStatePropertyAll(Theme.of(context).scaffoldBackgroundColor),
|
||||
side: WidgetStatePropertyAll(BorderSide(
|
||||
width: 1.5,
|
||||
color: color ?? AppTheme.textColor,
|
||||
))
|
||||
),
|
||||
child: isLoading
|
||||
? Spinner(color: color ?? AppTheme.textColor,)
|
||||
: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: AutoSizeText(
|
||||
label,
|
||||
minFontSize: 8,
|
||||
maxFontSize: 14,
|
||||
maxLines: 1,
|
||||
textAlign: TextAlign.center,
|
||||
style: textStyle ?? Theme.of(context).textTheme.bodyLarge?.copyWith(
|
||||
color: AppTheme.textColor,
|
||||
)
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class Spinner extends StatelessWidget {
|
||||
const Spinner({
|
||||
super.key,
|
||||
required this.color,
|
||||
});
|
||||
|
||||
final Color? color;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
width: 20,
|
||||
height: 20,
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 3,
|
||||
color: color ?? Colors.white,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
77
lib/widgets/app_text_field.dart
Normal file
77
lib/widgets/app_text_field.dart
Normal file
@ -0,0 +1,77 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:gascom/constants/app_theme.dart';
|
||||
|
||||
class AppTextField extends StatelessWidget {
|
||||
const AppTextField(
|
||||
{super.key,
|
||||
required this.controller,
|
||||
required this.keyboardType,
|
||||
this.onChanged,
|
||||
this.errorText,
|
||||
this.fillColor,
|
||||
this.textColor,
|
||||
this.isFilled,
|
||||
this.isCentered,
|
||||
this.maxCharacters,
|
||||
this.inputFormatters,});
|
||||
|
||||
final TextEditingController controller;
|
||||
final TextInputType keyboardType;
|
||||
final void Function(String)? onChanged;
|
||||
final String? errorText;
|
||||
final Color? fillColor;
|
||||
final Color? textColor;
|
||||
final bool? isFilled;
|
||||
final bool? isCentered;
|
||||
final int? maxCharacters;
|
||||
final List<TextInputFormatter>? inputFormatters;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
controller: controller,
|
||||
keyboardType: keyboardType,
|
||||
onChanged: onChanged,
|
||||
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||
fontWeight: FontWeight.w500,
|
||||
color: textColor ?? const Color.fromARGB(255, 20, 20, 20),
|
||||
),
|
||||
textAlign: isCentered ?? false ? TextAlign.center : TextAlign.start,
|
||||
autocorrect: false,
|
||||
inputFormatters: inputFormatters,
|
||||
cursorColor: textColor ?? const Color.fromARGB(255, 20, 20, 20),
|
||||
cursorRadius: const Radius.circular(10),
|
||||
maxLength: maxCharacters,
|
||||
decoration: InputDecoration(
|
||||
counterText: "",
|
||||
fillColor: fillColor ?? const Color.fromARGB(255, 20, 20, 20),
|
||||
filled: isFilled ?? false,
|
||||
contentPadding:
|
||||
const EdgeInsets.symmetric(vertical: 5, horizontal: 20),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(30),
|
||||
borderSide:
|
||||
const BorderSide(color: AppTheme.textColor, width: 1)),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(30),
|
||||
borderSide:
|
||||
const BorderSide(color: AppTheme.textColor, width: 1)),
|
||||
errorText: errorText,
|
||||
errorStyle: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium
|
||||
?.copyWith(color: AppTheme.redColor),
|
||||
errorBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
borderSide: const BorderSide(color: AppTheme.redColor, width: 1)),
|
||||
focusedErrorBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
borderSide: const BorderSide(color: AppTheme.redColor, width: 1)),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
104
lib/widgets/bottom_nav.dart
Normal file
104
lib/widgets/bottom_nav.dart
Normal file
@ -0,0 +1,104 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:gascom/constants/app_theme.dart';
|
||||
import 'package:gascom/screens/follow_order_screen.dart';
|
||||
import 'package:gascom/screens/generator_info_screen.dart';
|
||||
import 'package:gascom/screens/home_screen.dart';
|
||||
import 'package:persistent_bottom_nav_bar_v2/persistent_bottom_nav_bar_v2.dart';
|
||||
|
||||
class BottomNav extends StatelessWidget {
|
||||
const BottomNav({
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return PersistentTabView(
|
||||
controller: PersistentTabController(initialIndex: 0),
|
||||
resizeToAvoidBottomInset: false,
|
||||
navBarHeight: 70,
|
||||
tabs: [
|
||||
tabConfig(
|
||||
context,
|
||||
const HomeScreen(),
|
||||
"home",
|
||||
"assets/svgs/home_filled.svg",
|
||||
"assets/svgs/home.svg",
|
||||
"Home Active",
|
||||
"Home Inactive",
|
||||
"الرئيسية",
|
||||
),
|
||||
tabConfig(
|
||||
context,
|
||||
const GeneratorInfoScreen(),
|
||||
"generator_info",
|
||||
"assets/svgs/generator_filled.svg",
|
||||
"assets/svgs/generator.svg",
|
||||
"Generator Info Active",
|
||||
"Generator Info Inactive",
|
||||
"معلومات المولدة",
|
||||
),
|
||||
tabConfig(
|
||||
context,
|
||||
const FollowOrderScreen(),
|
||||
"follow_order",
|
||||
"assets/svgs/van_filled.svg",
|
||||
"assets/svgs/van.svg",
|
||||
"Follow Order Active",
|
||||
"Follow Order Inactive",
|
||||
"تتبع الطلب",
|
||||
),
|
||||
],
|
||||
navBarBuilder: (navBarConfig) => Style6BottomNavBar(
|
||||
navBarConfig: navBarConfig,
|
||||
navBarDecoration: NavBarDecoration(
|
||||
color: AppTheme.secondaryColor,
|
||||
padding: EdgeInsets.all(10),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.15),
|
||||
blurRadius: 10,
|
||||
spreadRadius: 1,
|
||||
offset: const Offset(0, 0),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
PersistentTabConfig tabConfig(
|
||||
BuildContext context,
|
||||
Widget screen,
|
||||
String initialRoute,
|
||||
String activeIcon,
|
||||
String inactiveIcon,
|
||||
String activeSemanticsLabel,
|
||||
String inactiveSemanticsLabel,
|
||||
String title,
|
||||
) {
|
||||
return PersistentTabConfig(
|
||||
screen: screen,
|
||||
navigatorConfig: NavigatorConfig(
|
||||
initialRoute: initialRoute,
|
||||
),
|
||||
item: ItemConfig(
|
||||
icon: Padding(
|
||||
padding: const EdgeInsets.only(top: 4, left: 4, right: 4),
|
||||
child: SvgPicture.asset(
|
||||
activeIcon,
|
||||
semanticsLabel: activeSemanticsLabel,
|
||||
),
|
||||
),
|
||||
inactiveIcon: SvgPicture.asset(
|
||||
inactiveIcon,
|
||||
semanticsLabel: inactiveSemanticsLabel,
|
||||
),
|
||||
activeForegroundColor: AppTheme.primaryColor,
|
||||
inactiveForegroundColor: AppTheme.primaryColor,
|
||||
textStyle: Theme.of(context).textTheme.bodySmall ?? TextStyle(),
|
||||
title: title,
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
40
lib/widgets/custom_app_bar.dart
Normal file
40
lib/widgets/custom_app_bar.dart
Normal file
@ -0,0 +1,40 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gascom/constants/app_theme.dart';
|
||||
|
||||
class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||
const CustomAppBar({super.key, this.title});
|
||||
|
||||
final String? title;
|
||||
|
||||
@override
|
||||
Size get preferredSize => const Size.fromHeight(80);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AppBar(
|
||||
toolbarHeight: 80,
|
||||
titleSpacing: 0,
|
||||
backgroundColor: AppTheme.primaryColor,
|
||||
surfaceTintColor: AppTheme.primaryColor,
|
||||
title: Text(
|
||||
title ?? "",
|
||||
style: Theme.of(context).textTheme.titleLarge,
|
||||
),
|
||||
leading: IconButton(
|
||||
icon: const Icon(CupertinoIcons.back, color: AppTheme.textColor,),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
bottom: title == null ? null : PreferredSize(
|
||||
preferredSize: const Size.fromHeight(1),
|
||||
child: Container(
|
||||
color: AppTheme.yellowColor,
|
||||
height: 1,
|
||||
margin: const EdgeInsets.symmetric(horizontal: 20),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
97
lib/widgets/fine_container.dart
Normal file
97
lib/widgets/fine_container.dart
Normal file
@ -0,0 +1,97 @@
|
||||
import 'package:auto_size_text/auto_size_text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gascom/constants/app_theme.dart';
|
||||
import 'package:gascom/screens/payment_screen.dart';
|
||||
import 'package:gascom/screens/success_screen.dart';
|
||||
import 'package:gascom/widgets/app_button.dart';
|
||||
import 'package:persistent_bottom_nav_bar_v2/persistent_bottom_nav_bar_v2.dart';
|
||||
|
||||
class FineContainer extends StatelessWidget {
|
||||
const FineContainer({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 20),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
border: Border.all(
|
||||
color: AppTheme.textColor,
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
child: AutoSizeText(
|
||||
"غرامة",
|
||||
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
AutoSizeText(
|
||||
"2024/12/12",
|
||||
style: Theme.of(context).textTheme.bodySmall,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
AutoSizeText(
|
||||
"200,000 د.ع",
|
||||
style: Theme.of(context).textTheme.bodyLarge?.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 15),
|
||||
const Divider(
|
||||
color: AppTheme.textColor,
|
||||
height: 1,
|
||||
thickness: 1,
|
||||
),
|
||||
const SizedBox(height: 15),
|
||||
AutoSizeText(
|
||||
"مخالفة ساعات التشغيل والاطفاء",
|
||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
AutoSizeText(
|
||||
"يجب دفع الغرامة قبل تاريخ 01/09/2024 وبخلافه، لن يتم تزويدك باي حصة بعد هذا التاريخ",
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
maxLines: 2,
|
||||
),
|
||||
const SizedBox(height: 15),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: MediaQuery.of(context).size.width * 0.45,
|
||||
child: AppButton(
|
||||
onPressed: () {
|
||||
pushScreenWithoutNavBar(context,
|
||||
PaymentScreen(
|
||||
title: "غرامات",
|
||||
onPaymentComplete: () {
|
||||
pushScreenWithoutNavBar(context, const SuccessScreen(title: "تم دفع الغرامة بنجاح", subtitle: ""));
|
||||
}
|
||||
)
|
||||
);
|
||||
},
|
||||
label: "دفع الغرامة",
|
||||
isElevated: true,
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
55
lib/widgets/home_grid_item.dart
Normal file
55
lib/widgets/home_grid_item.dart
Normal file
@ -0,0 +1,55 @@
|
||||
import 'package:auto_size_text/auto_size_text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:gascom/constants/app_theme.dart';
|
||||
|
||||
class HomeGridItem extends StatelessWidget {
|
||||
const HomeGridItem({
|
||||
super.key,
|
||||
required this.title,
|
||||
required this.svgPath,
|
||||
required this.onPressed,
|
||||
});
|
||||
|
||||
final String title;
|
||||
final String svgPath;
|
||||
final void Function() onPressed;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: onPressed,
|
||||
child: Column(
|
||||
// mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
AspectRatio(
|
||||
aspectRatio: 1,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(25),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(11),
|
||||
border: Border.all(
|
||||
color: AppTheme.secondaryColor,
|
||||
width: 2,
|
||||
),
|
||||
),
|
||||
child: SvgPicture.asset(
|
||||
svgPath,
|
||||
semanticsLabel: title,
|
||||
),
|
||||
),
|
||||
),
|
||||
// const SizedBox(height: 10,),
|
||||
AutoSizeText(
|
||||
title,
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
minFontSize: 12,
|
||||
maxLines: 2,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
70
lib/widgets/order_container.dart
Normal file
70
lib/widgets/order_container.dart
Normal file
@ -0,0 +1,70 @@
|
||||
import 'package:auto_size_text/auto_size_text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gascom/constants/app_theme.dart';
|
||||
import 'package:gascom/screens/order_details_screen.dart';
|
||||
import 'package:gascom/widgets/order_state_badge.dart';
|
||||
import 'package:persistent_bottom_nav_bar_v2/persistent_bottom_nav_bar_v2.dart';
|
||||
|
||||
class OrderContainer extends StatelessWidget {
|
||||
const OrderContainer({
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 15),
|
||||
decoration: BoxDecoration(
|
||||
color: AppTheme.cardColor,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
child: AutoSizeText(
|
||||
"2024/12/12",
|
||||
style: Theme.of(context).textTheme.bodySmall,
|
||||
),
|
||||
),
|
||||
const OrderStateBadge(state: "قيد المراجعة"),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
AutoSizeText(
|
||||
"5000 لتر",
|
||||
style: Theme.of(context).textTheme.bodyLarge?.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
AutoSizeText(
|
||||
"رقم الطلب: 67895435",
|
||||
style: Theme.of(context).textTheme.bodySmall,
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
const Divider(
|
||||
color: AppTheme.primaryColor,
|
||||
thickness: 1,
|
||||
height: 25,
|
||||
),
|
||||
InkWell(
|
||||
splashColor: AppTheme.primaryColor,
|
||||
onTap: () {
|
||||
pushScreenWithoutNavBar(context, OrderDetailsScreen());
|
||||
},
|
||||
child: Center(
|
||||
child: AutoSizeText(
|
||||
"اظهر التفاصيل",
|
||||
style: Theme.of(context).textTheme.bodySmall,
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
28
lib/widgets/order_state_badge.dart
Normal file
28
lib/widgets/order_state_badge.dart
Normal file
@ -0,0 +1,28 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gascom/constants/app_theme.dart';
|
||||
|
||||
class OrderStateBadge extends StatelessWidget {
|
||||
const OrderStateBadge({
|
||||
super.key,
|
||||
required this.state,
|
||||
});
|
||||
|
||||
final String state;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
|
||||
decoration: BoxDecoration(
|
||||
color: state == "قيد المراجعة" ? AppTheme.yellowColor : AppTheme.primaryColor,
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
child: Text(
|
||||
state,
|
||||
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||
color: state == "قيد المراجعة" ? AppTheme.brownColor : AppTheme.textColor,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
30
lib/widgets/text_container.dart
Normal file
30
lib/widgets/text_container.dart
Normal file
@ -0,0 +1,30 @@
|
||||
import 'package:auto_size_text/auto_size_text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gascom/constants/app_theme.dart';
|
||||
|
||||
class TextContainer extends StatelessWidget {
|
||||
const TextContainer({super.key, required this.text});
|
||||
|
||||
final String text;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 20),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
border: Border.all(
|
||||
color: AppTheme.textColor,
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
child: AutoSizeText(
|
||||
text,
|
||||
style: Theme.of(context).textTheme.bodySmall,
|
||||
minFontSize: 8,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user