home page

This commit is contained in:
2025-02-24 18:54:00 +05:30
parent 27c3a14646
commit 71d0991366
19 changed files with 716 additions and 143 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@@ -19,6 +19,12 @@
"packageUri": "lib/",
"languageVersion": "3.3"
},
{
"name": "art_sweetalert",
"rootUri": "file:///Users/rajeevsingh/.pub-cache/hosted/pub.dev/art_sweetalert-0.0.5",
"packageUri": "lib/",
"languageVersion": "2.12"
},
{
"name": "async",
"rootUri": "file:///Users/rajeevsingh/.pub-cache/hosted/pub.dev/async-2.11.0",
@@ -992,7 +998,7 @@
"languageVersion": "3.4"
}
],
"generated": "2025-02-22T13:29:09.162780Z",
"generated": "2025-02-24T13:23:19.491834Z",
"generator": "pub",
"generatorVersion": "3.4.4",
"flutterRoot": "file:///Users/rajeevsingh/Documents/allSoftwares/flutter",

View File

@@ -10,6 +10,10 @@ args
3.3
file:///Users/rajeevsingh/.pub-cache/hosted/pub.dev/args-2.6.0/
file:///Users/rajeevsingh/.pub-cache/hosted/pub.dev/args-2.6.0/lib/
art_sweetalert
2.12
file:///Users/rajeevsingh/.pub-cache/hosted/pub.dev/art_sweetalert-0.0.5/
file:///Users/rajeevsingh/.pub-cache/hosted/pub.dev/art_sweetalert-0.0.5/lib/
async
2.18
file:///Users/rajeevsingh/.pub-cache/hosted/pub.dev/async-2.11.0/

File diff suppressed because one or more lines are too long

View File

@@ -6,7 +6,7 @@
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>

View File

@@ -22,6 +22,8 @@ import 'package:grocery_app/src/ui/payment/payment_failure_screen.dart';
import 'package:grocery_app/src/ui/payment/payment_success_screen.dart';
import 'package:grocery_app/src/ui/productdetails/product_details.dart';
import 'package:grocery_app/src/ui/splash/splash_screen.dart';
import 'package:grocery_app/src/ui/static_page/privacyandpolicy.dart';
import 'package:grocery_app/src/ui/static_page/tersandconditions.dart';
import 'package:grocery_app/utils/constants/globle_variable.dart';
/// Route names as constants
@@ -99,8 +101,7 @@ class MyRoutes {
animatedGoRoute(
path: PRODUCTDETAILS,
name: PRODUCTDETAILS,
pageBuilder: (context, state)
{
pageBuilder: (context, state) {
// final id = state.extra as String; // Get the extra object
// return ProductDetails(id: id);
@@ -114,11 +115,17 @@ class MyRoutes {
},
),
// animatedGoRoute(
// path: SELECTPAYMENTSCREEN,
// name: SELECTPAYMENTSCREEN,
// pageBuilder: (context, state) => const CardCheckoutScreen(),
// ),
animatedGoRoute(
path: TERMANDCONDITIONS,
name: TERMANDCONDITIONS,
pageBuilder: (context, state) => const TermsAndConditionsScreen(),
),
animatedGoRoute(
path: PRIVACY,
name: PRIVACY,
pageBuilder: (context, state) => const PrivacyPolicy(),
),
animatedGoRoute(
path: SUCCESSPAYMENT,
@@ -268,7 +275,10 @@ class MyRoutes {
static const ORDERDETAILS = "/OrderDetailsScreen";
// static const TERMANDCONDITIONS = "/termsandcondition";
static const TERMANDCONDITIONS = "/termsandcondition";
static const PRIVACY = "/privacyandpolicy";
// static const SETUPBUSSINESS = "/setupbussiness";
// static const CREATESTORE = "/createStore";
// static const SUBMITSCREEN = "/submitscreen";

View File

@@ -8,6 +8,7 @@ import 'package:grocery_app/src/core/routes/routes.dart';
import 'package:grocery_app/src/data/all_cart_items.dart';
import 'package:grocery_app/src/logic/provider/bottom_navbar_provider.dart';
import 'package:grocery_app/src/logic/provider/home_provider.dart';
import 'package:grocery_app/src/ui/data_notfound.dart';
import 'package:grocery_app/utils/constants/assets_constant.dart';
import 'package:grocery_app/utils/constants/color_constant.dart';
import 'package:grocery_app/utils/constants/shared_pref_utils.dart';
@@ -281,7 +282,13 @@ class _BestDealScreenState extends State<BestDealScreen> {
),
);
} else if (provider.bestdeal.isEmpty) {
return Center(child: Text('No products available'));
return Center(
child: DataNotFound(
imagePath: 'assets/images/cart.jpg',
message: "Sorry! Don't have a product",
width: 300.w,
height: 300.h,
));
} else {
return Padding(
padding: const EdgeInsets.all(15),
@@ -298,16 +305,13 @@ class _BestDealScreenState extends State<BestDealScreen> {
var bestdealproduct = provider.bestdeal[index];
return InkWell(
onTap: () {
context.push(MyRoutes.PRODUCTDETAILS,
context.push(
MyRoutes.PRODUCTDETAILS,
extra: {
"id": bestdealproduct.id,
"quantity": 0,
"price": '0',
},
);
},
child: Container(

View File

@@ -98,7 +98,7 @@ class _MycartState extends State<Mycart> {
if (provider.isBestdealingloading) {
return Center(child: CircularProgressIndicator());
} else if (provider.bestdeal.isEmpty) {
return Center(child: Text('No products available'));
return Center(child: Text(''));
} else {
return SizedBox(
height: MediaQuery.of(context).size.height * 0.28,
@@ -112,15 +112,13 @@ class _MycartState extends State<Mycart> {
return InkWell(
onTap: () {
context.push(MyRoutes.PRODUCTDETAILS,
context.push(
MyRoutes.PRODUCTDETAILS,
extra: {
"id": bestdealproduct.id,
"quantity": 0,
"price": "0",
},
);
},
child: Padding(
@@ -434,8 +432,8 @@ class _MycartState extends State<Mycart> {
return DataNotFound(
imagePath: 'assets/images/cartempty.jpg',
message: "",
width: 250.w,
height: 200.h,
width: 100.w,
height: 100.h,
);
} else {
return ListView.separated(
@@ -450,8 +448,7 @@ class _MycartState extends State<Mycart> {
var items = provider.allitem.items![index];
return InkWell(
onTap: ()
{
onTap: () {
context.push(
MyRoutes.PRODUCTDETAILS,
extra: {

View File

@@ -20,12 +20,14 @@ class DataNotFound extends StatelessWidget {
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
Center(
child: Image.asset(
imagePath,
width: width,
height: height,
fit: BoxFit.contain,
),
),
const SizedBox(height: 20),
Text(
message,

View File

@@ -122,7 +122,8 @@ class _FruitVeggieDetailState extends State<FruitVeggieDetail> {
)),
);
} else if (provider.products.isEmpty) {
return Padding(
return Center(
child: Padding(
padding: const EdgeInsets.only(left: 40),
child: DataNotFound(
imagePath: 'assets/images/cart.jpg',
@@ -130,6 +131,7 @@ class _FruitVeggieDetailState extends State<FruitVeggieDetail> {
width: 200.w,
height: 250.h,
),
),
);
} else {
return Expanded(
@@ -179,7 +181,8 @@ class _FruitVeggieDetailState extends State<FruitVeggieDetail> {
var product = provider.products[index];
return InkWell(
onTap: () {
context.push(MyRoutes.PRODUCTDETAILS,
context.push(
MyRoutes.PRODUCTDETAILS,
// extra: product.id
extra: {
@@ -187,7 +190,6 @@ class _FruitVeggieDetailState extends State<FruitVeggieDetail> {
"quantity": 0,
"price": "0",
},
);
},
child: Container(
@@ -474,7 +476,7 @@ class _FruitVeggieDetailState extends State<FruitVeggieDetail> {
),
));
} else if (provider.categoryList.isEmpty) {
return Center(child: Text('No products available'));
return SizedBox.shrink();
} else {
return Container(
decoration: const BoxDecoration(color: Colors.white),

View File

@@ -1,11 +1,13 @@
import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:go_router/go_router.dart';
import 'package:grocery_app/src/common_widget/network_image.dart';
import 'package:grocery_app/src/core/routes/routes.dart';
import 'package:grocery_app/src/logic/provider/home_provider.dart';
import 'package:grocery_app/src/ui/bestdeal/bestdeal_screen.dart';
import 'package:grocery_app/src/ui/data_notfound.dart';
import 'package:grocery_app/src/ui/fruitvegidetail/fruit_veggie_detail.dart';
import 'package:grocery_app/src/ui/header.dart';
import 'package:grocery_app/utils/constants/color_constant.dart';
@@ -40,7 +42,6 @@ class _HomeScreenState extends State<HomeScreen> {
productProvider.getBestDealProduct(context, '');
productProvider.getAllcategory(context);
getUserDetails();
});
}
@@ -71,8 +72,7 @@ class _HomeScreenState extends State<HomeScreen> {
Row(
children: [
Consumer<ProductProvider>(
builder: (context, provider, child)
{
builder: (context, provider, child) {
return Expanded(
child: Container(
height: 50,
@@ -286,7 +286,13 @@ class _HomeScreenState extends State<HomeScreen> {
),
)
: provider.bestdeal.isEmpty
? Center(child: Text('No products available'))
? Center(
child: DataNotFound(
imagePath: 'assets/images/cart.jpg',
message: "",
width: 300.w,
height: 300.h,
))
: SizedBox(
height: MediaQuery.of(context).size.height * 0.28,
child: ListView.builder(
@@ -299,7 +305,8 @@ class _HomeScreenState extends State<HomeScreen> {
return InkWell(
onTap: () {
context.push(MyRoutes.PRODUCTDETAILS,
context.push(
MyRoutes.PRODUCTDETAILS,
// extra: bestdealproduct.id
extra: {
@@ -307,8 +314,6 @@ class _HomeScreenState extends State<HomeScreen> {
"quantity": 0,
"price": "0",
},
);
},
child: Padding(
@@ -687,7 +692,8 @@ class _HomeScreenState extends State<HomeScreen> {
var product = provider.homeproducts[index];
return InkWell(
onTap: () {
context.push(MyRoutes.PRODUCTDETAILS,
context.push(
MyRoutes.PRODUCTDETAILS,
// extra: product.id
extra: {

View File

@@ -1,9 +1,11 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_svg/svg.dart';
import 'package:go_router/go_router.dart';
import 'package:grocery_app/src/common_widget/network_image.dart';
import 'package:grocery_app/src/core/routes/routes.dart';
import 'package:grocery_app/src/logic/provider/order_provider.dart';
import 'package:grocery_app/src/ui/data_notfound.dart';
import 'package:grocery_app/utils/constants/assets_constant.dart';
import 'package:grocery_app/utils/constants/color_constant.dart';
import 'package:grocery_app/utils/extensions/extensions.dart';
@@ -73,7 +75,13 @@ class _MyOrderScreenState extends State<MyOrderScreen> {
}
if (orderProvider.orderList.isEmpty) {
return Center(child: Text('No orders found!'));
return Center(
child: DataNotFound(
imagePath: 'assets/images/wishlist.jpg',
message: "No Order Available! ",
// width: 200.w,
// height: 200.h,
));
}
return Column(

View File

@@ -1,4 +1,7 @@
import 'package:art_sweetalert/art_sweetalert.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:gap/gap.dart';
import 'package:go_router/go_router.dart';
import 'package:grocery_app/src/common_widget/network_image.dart';
import 'package:grocery_app/src/core/routes/routes.dart';
@@ -12,10 +15,13 @@ import 'package:grocery_app/src/ui/mapscreen/map_screen.dart';
import 'package:grocery_app/src/ui/message/message_screen.dart';
import 'package:grocery_app/src/ui/notification/notification_screen.dart';
import 'package:grocery_app/src/ui/rating_review/rating_review_screen.dart';
import 'package:grocery_app/src/ui/static_page/static_page_screen.dart';
import 'package:grocery_app/src/ui/static_page/tersandconditions.dart';
import 'package:grocery_app/src/ui/widgets/custom_text_field.dart';
import 'package:grocery_app/src/ui/widgets/elevated_button.dart';
import 'package:grocery_app/utils/constants/color_constant.dart';
import 'package:grocery_app/utils/constants/shared_pref_utils.dart';
import 'package:grocery_app/utils/constants/string_constant.dart';
import 'package:grocery_app/utils/extensions/extensions.dart';
import 'package:grocery_app/utils/extensions/uicontext.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
import 'package:provider/provider.dart';
@@ -45,6 +51,21 @@ class _ProfileScreenState extends State<ProfileScreen> {
APPSTRING.userLastName = (await SharedPrefUtils.getLastName())!;
}
final _formKey = GlobalKey<FormState>();
final TextEditingController _passwordController = TextEditingController();
final TextEditingController _confirmPasswordController =
TextEditingController();
bool _isPasswordVisible = false;
bool _isConfirmPasswordVisible = false;
@override
void dispose() {
_passwordController.dispose();
_confirmPasswordController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
print("jdfgkjhgjh ${APPSTRING.userProfile}");
@@ -181,6 +202,9 @@ class _ProfileScreenState extends State<ProfileScreen> {
trailing: Icon(MdiIcons.chevronRight),
),
ListTile(
onTap: () {
_showBottomSheet(context);
},
leading: Icon(MdiIcons.lockOutline),
title: const Text('Change Password'),
trailing: Icon(MdiIcons.chevronRight),
@@ -244,13 +268,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
ListTile(
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) {
return const StaticPage(
title: "Privacy Policy",
);
},
));
context.push(MyRoutes.PRIVACY);
},
leading: Icon(MdiIcons.shieldCheckOutline),
title: const Text('Privacy Policy'),
@@ -258,13 +276,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
),
ListTile(
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) {
return const StaticPage(
title: "Terms & Conditions",
);
},
));
context.push(MyRoutes.TERMANDCONDITIONS);
},
leading: Icon(MdiIcons.noteTextOutline),
title: const Text('Term & Conditions'),
@@ -317,4 +329,132 @@ class _ProfileScreenState extends State<ProfileScreen> {
),
);
}
// Function to show the Bottom Sheet
void _showBottomSheet(BuildContext context) {
showModalBottomSheet(
context: context,
builder: (BuildContext context) {
return Container(
decoration: BoxDecoration(
border: Border.all(color: context.appColor.greyColor400),
color: context.appColor.whiteColor,
borderRadius: BorderRadius.all(Radius.circular(5.0)),
),
padding: EdgeInsets.all(20.w),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
// Centered App Logo
Align(
alignment: Alignment.center,
child: Text('Change Password', style: context.subTitleStyle),
),
Align(
alignment: Alignment.center,
child: Container(
width: 300,
child: Text('Enter your new password',
textAlign: TextAlign.center,
style:
context.subTitleTextStyle.copyWith(fontSize: 13.sp)),
),
),
Form(
key: _formKey,
child: Column(
children: [
// Password Field
CustomTextField(
controller: _passwordController,
obscureText: !_isPasswordVisible,
validator: (val) {
if (val == null || val.isEmpty) {
return "Please enter a password";
} else if (val.length < 6) {
return "Password must be at least 6 characters long";
}
return null;
},
maxLength: 64,
counterWidget: const Offstage(),
hintText: "Enter password",
fillColor: context.appColor.greyColor100,
suffix: IconButton(
icon: Icon(
_isPasswordVisible
? Icons.visibility
: Icons.visibility_off,
),
onPressed: () {
setState(() {
_isPasswordVisible = !_isPasswordVisible;
});
},
),
),
Gap(10.h),
// Confirm Password Field
CustomTextField(
controller: _confirmPasswordController,
obscureText: !_isConfirmPasswordVisible,
validator: (val) {
if (val == null || val.isEmpty) {
return "Please confirm your password";
} else if (val != _passwordController.text) {
return "Passwords do not match";
}
return null;
},
maxLength: 64,
counterWidget: const Offstage(),
hintText: "Confirm password",
fillColor: context.appColor.greyColor100,
suffix: IconButton(
icon: Icon(
_isConfirmPasswordVisible
? Icons.visibility
: Icons.visibility_off,
),
onPressed: () {
setState(() {
_isConfirmPasswordVisible =
!_isConfirmPasswordVisible;
});
},
),
),
],
),
),
Gap(20.h),
Center(
child: SizedBox(
child: SizedBox(
width: double.infinity,
child: ButtonElevated(
text: 'Change Password',
onPressed: () {
Navigator.pop(context);
ArtSweetAlert.show(
context: context,
artDialogArgs: ArtDialogArgs(
type: ArtSweetAlertType.success,
title: "Password Reset Successful",
text: ""));
},
backgroundColor: context.appColor.primarycolor),
),
),
),
Gap(10.h),
],
),
);
},
);
}
}

View File

@@ -0,0 +1,137 @@
import 'package:flutter/material.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:grocery_app/utils/extensions/extensions.dart';
import 'package:provider/provider.dart';
import 'package:gap/gap.dart';
class PrivacyPolicy extends StatelessWidget {
const PrivacyPolicy({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
leading: IconButton(
icon: Icon(Icons.arrow_back_ios_rounded),
onPressed: () {
Navigator.pop(context); // Handle back button functionality
},
),
title: Text(
'Privacy & Policy',
style: TextStyle(
fontSize: 18.sp,
fontWeight: FontWeight.bold,
),
),
),
body: Padding(
padding: EdgeInsets.all(16.w),
child: ListView(
children: [
_buildSectionTitle('1. General Terms'),
_buildSectionContent(
'Welcome to Frontshop Emporium! Were delighted to have you here. By accessing or using our platform, '
'we kindly ask that you review and agree to our terms and conditions. These ensure a safe and seamless '
'experience for everyone. If you have any concerns or do not agree with these terms, we respect your '
'choice to refrain from using our platform. Thank you for understanding!',
),
_buildSectionTitle('2. User Terms'),
_buildSubSectionTitle('Eligibility'),
_buildSectionContent(
'• Users must provide accurate and complete information during registration.',
),
_buildSubSectionTitle('User Responsibilities'),
_buildSectionContent(
'• Ensure your account details are secure. You are responsible for all activities under your account.\n'
'• Use the platform in compliance with all applicable laws and regulations.\n'
'• Do not engage in fraudulent, abusive, or harmful activities, including posting inappropriate content '
'or exploiting platform features.',
),
_buildSubSectionTitle('Order and Payment'),
_buildSectionContent(
'• Orders are confirmed only upon payment.\n'
'• Prices, discounts, and offers are subject to change without notice.',
),
_buildSectionTitle('3. Vendor Terms'),
_buildSubSectionTitle('Registration and Eligibility'),
_buildSectionContent(
'• Vendors must provide valid business details and adhere to local commerce regulations.\n'
'• Vendors must be legally registered businesses and provide necessary documentation (e.g., business '
'licenses, tax identification). The Company reserves the right to approve or deny vendor applications.\n'
'• Both parties agree to keep proprietary information confidential. Vendor information will not be shared '
'without consent, except as required by law.',
),
_buildSubSectionTitle('Vendor Responsibilities'),
_buildSectionContent(
'• Maintain accurate product descriptions, prices, and inventory levels.\n'
'• Ensure timely dispatch and delivery of products. Resolve user complaints promptly.\n'
'• Vendors must ensure that all products meet quality and safety standards.',
),
_buildSectionTitle('4. Delivery Partner Terms'),
_buildSubSectionTitle('Eligibility'),
_buildSectionContent(
'• Delivery Partners must provide valid identification. Delivery Partners must be legally registered entities '
'or individuals with appropriate licenses and follow all traffic rules and regulations.',
),
_buildSectionTitle('5. Privacy Policy'),
_buildSectionContent(
'Frontshop Emporium is committed to protecting your privacy.\n'
'• We do not sell your data to third parties.\n'
'• Data may be shared with service providers, delivery partners, and legal authorities as necessary.',
),
_buildSectionTitle('6. Refund Policy'),
_buildSectionContent(
'• Products are eligible for a refund if they are defective, damaged during delivery, or not as described.\n'
'• Requests must be initiated within 7 days of receiving the product.',
),
_buildSectionTitle('7. Support Policy'),
_buildSectionContent(
'• For assistance, contact our support team via email or live chat available on the platform.\n'
'• Support hours: Monday to Friday, 9 AM 6 PM (local time).',
),
SizedBox(height: 20),
Gap(20.h),
// Continue Button
Gap(20.h),
],
),
),
);
}
}
Widget _buildSectionTitle(String title) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Text(
title,
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
);
}
Widget _buildSubSectionTitle(String title) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0),
child: Text(
title,
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
),
);
}
Widget _buildSectionContent(String content) {
return Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: Text(
content,
style: TextStyle(fontSize: 14, height: 1.5),
),
);
}

View File

@@ -1,44 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:grocery_app/utils/constants/assets_constant.dart';
class StaticPage extends StatefulWidget {
final String title;
const StaticPage({super.key, required this.title});
@override
State<StaticPage> createState() => _StaticPageState();
}
class _StaticPageState extends State<StaticPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
leading: Center(
child: SizedBox(
height: 20,
width: 20,
child: InkWell(
onTap: () {
Navigator.of(context).pop();
},
child: SvgPicture.asset(
APPASSETS.back,
height: 20,
width: 20,
)),
),
),
title: Text(
widget.title,
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.w700,
),
),
),
);
}
}

View File

@@ -0,0 +1,137 @@
import 'package:flutter/material.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:grocery_app/utils/extensions/extensions.dart';
import 'package:provider/provider.dart';
import 'package:gap/gap.dart';
class TermsAndConditionsScreen extends StatelessWidget {
const TermsAndConditionsScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
leading: IconButton(
icon: Icon(Icons.arrow_back_ios_rounded),
onPressed: () {
Navigator.pop(context); // Handle back button functionality
},
),
title: Text(
'Terms & Conditions',
style: TextStyle(
fontSize: 18.sp,
fontWeight: FontWeight.bold,
),
),
),
body: Padding(
padding: EdgeInsets.all(16.w),
child: ListView(
children: [
_buildSectionTitle('1. General Terms'),
_buildSectionContent(
'Welcome to Frontshop Emporium! Were delighted to have you here. By accessing or using our platform, '
'we kindly ask that you review and agree to our terms and conditions. These ensure a safe and seamless '
'experience for everyone. If you have any concerns or do not agree with these terms, we respect your '
'choice to refrain from using our platform. Thank you for understanding!',
),
_buildSectionTitle('2. User Terms'),
_buildSubSectionTitle('Eligibility'),
_buildSectionContent(
'• Users must provide accurate and complete information during registration.',
),
_buildSubSectionTitle('User Responsibilities'),
_buildSectionContent(
'• Ensure your account details are secure. You are responsible for all activities under your account.\n'
'• Use the platform in compliance with all applicable laws and regulations.\n'
'• Do not engage in fraudulent, abusive, or harmful activities, including posting inappropriate content '
'or exploiting platform features.',
),
_buildSubSectionTitle('Order and Payment'),
_buildSectionContent(
'• Orders are confirmed only upon payment.\n'
'• Prices, discounts, and offers are subject to change without notice.',
),
_buildSectionTitle('3. Vendor Terms'),
_buildSubSectionTitle('Registration and Eligibility'),
_buildSectionContent(
'• Vendors must provide valid business details and adhere to local commerce regulations.\n'
'• Vendors must be legally registered businesses and provide necessary documentation (e.g., business '
'licenses, tax identification). The Company reserves the right to approve or deny vendor applications.\n'
'• Both parties agree to keep proprietary information confidential. Vendor information will not be shared '
'without consent, except as required by law.',
),
_buildSubSectionTitle('Vendor Responsibilities'),
_buildSectionContent(
'• Maintain accurate product descriptions, prices, and inventory levels.\n'
'• Ensure timely dispatch and delivery of products. Resolve user complaints promptly.\n'
'• Vendors must ensure that all products meet quality and safety standards.',
),
_buildSectionTitle('4. Delivery Partner Terms'),
_buildSubSectionTitle('Eligibility'),
_buildSectionContent(
'• Delivery Partners must provide valid identification. Delivery Partners must be legally registered entities '
'or individuals with appropriate licenses and follow all traffic rules and regulations.',
),
_buildSectionTitle('5. Privacy Policy'),
_buildSectionContent(
'Frontshop Emporium is committed to protecting your privacy.\n'
'• We do not sell your data to third parties.\n'
'• Data may be shared with service providers, delivery partners, and legal authorities as necessary.',
),
_buildSectionTitle('6. Refund Policy'),
_buildSectionContent(
'• Products are eligible for a refund if they are defective, damaged during delivery, or not as described.\n'
'• Requests must be initiated within 7 days of receiving the product.',
),
_buildSectionTitle('7. Support Policy'),
_buildSectionContent(
'• For assistance, contact our support team via email or live chat available on the platform.\n'
'• Support hours: Monday to Friday, 9 AM 6 PM (local time).',
),
SizedBox(height: 20),
Gap(20.h),
// Continue Button
Gap(20.h),
],
),
),
);
}
}
Widget _buildSectionTitle(String title) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Text(
title,
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
);
}
Widget _buildSubSectionTitle(String title) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0),
child: Text(
title,
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
),
);
}
Widget _buildSectionContent(String content) {
return Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: Text(
content,
style: TextStyle(fontSize: 14, height: 1.5),
),
);
}

View File

@@ -0,0 +1,155 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:grocery_app/utils/extensions/extensions.dart';
class CustomTextField extends StatelessWidget {
final TextEditingController? controller;
final double? height;
final double? width;
final Widget? prefix;
final Widget? suffix;
final String? hintText;
final String? labelText;
final TextInputType? keyBoardType;
final String? Function(String?)? validator;
final bool obscureText;
final TextInputAction? textInputAction;
final bool readOnly;
final bool isEnabledBorder;
final void Function(String)? onChanged;
final void Function(String)? onFieldSubmitted;
final void Function()? onTapOutside;
final void Function()? onTap;
final TextStyle? textStyle;
final TextStyle? hintStyle;
final double? borderRadius;
final Color? fillColor;
final Color? borderColor;
final InputBorder? enabledBorder;
final int? maxLines;
final int? maxLength;
final List<TextInputFormatter>? inputFormatters;
final TextAlign textAlign;
final double? horizontalContentPadding;
final double? verticalContentPadding;
final FocusNode? focusNode;
final Function()? functionCallOutsideOfTextfield;
final Widget? counterWidget;
const CustomTextField({
Key? key,
this.controller,
this.hintText,
this.height,
this.width,
this.prefix,
this.suffix,
this.validator,
this.labelText,
this.keyBoardType,
this.obscureText = false,
this.onTapOutside,
this.textInputAction = TextInputAction.next,
this.readOnly = false,
this.onChanged,
this.onFieldSubmitted,
this.onTap,
this.textStyle,
this.hintStyle,
this.borderRadius,
this.fillColor,
this.borderColor,
this.enabledBorder,
this.isEnabledBorder = false,
this.maxLines = 1,
this.maxLength,
this.inputFormatters,
this.textAlign = TextAlign.start,
this.horizontalContentPadding,
this.verticalContentPadding,
this.focusNode,
this.functionCallOutsideOfTextfield,
this.counterWidget,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return TextFormField(
focusNode: focusNode ?? FocusNode(),
textAlign: textAlign,
maxLines: maxLines,
maxLength: maxLength,
scrollPhysics: AlwaysScrollableScrollPhysics(),
scrollPadding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom + 180),
readOnly: readOnly,
inputFormatters: inputFormatters,
validator: validator,
controller: controller,
style: textStyle ?? context.bodyTxtStyle,
obscureText: obscureText,
keyboardType: keyBoardType,
decoration: InputDecoration(
counter: counterWidget,
hintStyle: hintStyle ??
context.subTitleTxtStyleblack.copyWith(
color: context.appColor.lightBlackColor,
),
labelStyle: context.subTitleTxtStyleblack
.copyWith(color: context.appColor.blackColor, fontSize: 16.sp),
contentPadding: EdgeInsets.symmetric(
horizontal: horizontalContentPadding ?? 10.w,
vertical: verticalContentPadding ?? 10.h,
),
fillColor: fillColor ?? context.appColor.greyColor200,
filled: true,
labelText: labelText,
hintText: hintText,
prefixIcon: prefix,
suffixIcon: suffix,
border: isEnabledBorder
? enabledBorder
: OutlineInputBorder(
borderSide: BorderSide(
color: borderColor ?? context.appColor.greyColor400,
),
borderRadius: BorderRadius.circular(borderRadius ?? 4.r),
),
enabledBorder: isEnabledBorder
? enabledBorder ??
UnderlineInputBorder(
borderSide: BorderSide(
color: borderColor ?? context.appColor.greyColor400,
),
)
: OutlineInputBorder(
borderSide: BorderSide(
color: borderColor ?? context.appColor.greyColor400,
),
borderRadius: BorderRadius.circular(borderRadius ?? 4.r),
),
focusedBorder: isEnabledBorder
? UnderlineInputBorder(
borderSide: BorderSide(
color: borderColor ?? context.appColor.greyColor400,
),
)
: OutlineInputBorder(
borderSide: BorderSide(
color: borderColor ?? context.appColor.greyColor400,
),
borderRadius: BorderRadius.circular(borderRadius ?? 4.r),
),
),
textInputAction: textInputAction,
onTapOutside: (value) {
onTapOutside ?? ();
FocusScope.of(context).unfocus();
},
onChanged: onChanged,
onFieldSubmitted: onFieldSubmitted,
onTap: onTap,
);
}
}

View File

@@ -25,6 +25,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.6.0"
art_sweetalert:
dependency: "direct main"
description:
name: art_sweetalert
sha256: "64dd68fc8648197e2b8201b3d28e2e9ec41c0883a05e18be21386ec6435d2b54"
url: "https://pub.dev"
source: hosted
version: "0.0.5"
async:
dependency: transitive
description:

View File

@@ -33,6 +33,7 @@ dependencies:
flutter_rating_stars: ^1.1.0
url_launcher: ^6.3.1
skeletonizer: ^1.4.3
art_sweetalert: ^0.0.5