initial code
This commit is contained in:
67
lib/main.dart
Normal file
67
lib/main.dart
Normal file
@@ -0,0 +1,67 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:grocery_app/src/core/routes/routes.dart';
|
||||
import 'package:grocery_app/src/ui/splash/splash_screen.dart';
|
||||
import 'package:grocery_app/utils/constants/color_constant.dart';
|
||||
import 'package:grocery_app/utils/constants/string_constant.dart';
|
||||
import 'package:loader_overlay/loader_overlay.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
void main() {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
runApp(const MyApplication());
|
||||
}
|
||||
|
||||
class MyApplication extends StatelessWidget {
|
||||
const MyApplication({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return
|
||||
|
||||
// ScreenUtilInit(
|
||||
// designSize: const Size(360, 690),
|
||||
// minTextAdapt: true,
|
||||
// splitScreenMode: true,
|
||||
// builder: (context, child) => GlobalLoaderOverlay(
|
||||
// overlayColor: APPCOLOR.appGreen,
|
||||
// useDefaultLoading: false,
|
||||
// // overlayWidgetBuilder: (progress) => const GlobalLoader(),
|
||||
// child: MultiProvider(
|
||||
// providers: [
|
||||
// // ChangeNotifierProvider(create: (_) => PageNotifier()),
|
||||
// // ChangeNotifierProvider(create: (_) => DaySelectionProvider()),
|
||||
// // ChangeNotifierProvider(create: (_) => LoginProvider()),
|
||||
// // ChangeNotifierProvider(create: (_) => ProductProvider()),
|
||||
// // ChangeNotifierProvider(create: (_) => HomeProvider()),
|
||||
// ],
|
||||
// child: MaterialApp.router(
|
||||
// routerConfig: MyRoutes.router,
|
||||
// debugShowCheckedModeBanner: false,
|
||||
// theme: ThemeData(
|
||||
// colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
|
||||
// scaffoldBackgroundColor: Colors.white,
|
||||
// canvasColor: const Color.fromRGBO(255, 255, 255, 1),
|
||||
// fontFamily: 'GoogleSans',
|
||||
// primarySwatch: Colors.blue,
|
||||
// ),
|
||||
// themeMode: ThemeMode.light,
|
||||
// title: APPSTRING.appName,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
|
||||
MaterialApp.router(
|
||||
title: 'Customer App',
|
||||
routerConfig: MyRoutes.router,
|
||||
|
||||
debugShowCheckedModeBanner: false,
|
||||
theme: ThemeData(
|
||||
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
|
||||
useMaterial3: true,
|
||||
),
|
||||
// home: const SplashScreen(),
|
||||
);
|
||||
}
|
||||
}
|
||||
44
lib/src/common_widget/name_text_field.dart
Normal file
44
lib/src/common_widget/name_text_field.dart
Normal file
@@ -0,0 +1,44 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:grocery_app/utils/constants/color_constant.dart';
|
||||
import 'package:grocery_app/utils/extensions/uicontext.dart';
|
||||
|
||||
class NameTextField extends StatelessWidget {
|
||||
final String name;
|
||||
final String? initText;
|
||||
const NameTextField({super.key, required this.name, this.initText});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
height: 60,
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
decoration: BoxDecoration(border: Border.all(color: APPCOLOR.lightGreen), borderRadius: BorderRadius.circular(15)),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
name,
|
||||
style: context.customMedium(APPCOLOR.lightGreen, 14),
|
||||
),
|
||||
Expanded(
|
||||
child: TextFormField(
|
||||
controller: TextEditingController(text: initText ?? ""),
|
||||
decoration: const InputDecoration(
|
||||
border: InputBorder.none,
|
||||
isCollapsed: true,
|
||||
contentPadding: EdgeInsets.only(
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 5,
|
||||
top: 5,
|
||||
)),
|
||||
))
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
106
lib/src/common_widget/network_image.dart
Normal file
106
lib/src/common_widget/network_image.dart
Normal file
@@ -0,0 +1,106 @@
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:grocery_app/utils/constants/assets_constant.dart';
|
||||
import 'package:grocery_app/utils/constants/color_constant.dart';
|
||||
|
||||
//Custom AppBar widget
|
||||
class AppNetworkImage extends StatelessWidget {
|
||||
final double height;
|
||||
final double width;
|
||||
final String imageUrl;
|
||||
final double? noImageTextSize;
|
||||
final bool isBorderShow;
|
||||
final Color backGroundColor;
|
||||
final Color? noImageTextColor;
|
||||
final BoxFit? boxFit;
|
||||
final double? radius;
|
||||
final Color? imageColor;
|
||||
final bool isShowColor;
|
||||
final bool isFromProfile;
|
||||
final bool isFromSlider;
|
||||
|
||||
const AppNetworkImage(
|
||||
{super.key,
|
||||
required this.height,
|
||||
required this.width,
|
||||
required this.imageUrl,
|
||||
this.noImageTextSize,
|
||||
this.isBorderShow = false,
|
||||
required this.backGroundColor,
|
||||
this.noImageTextColor,
|
||||
this.boxFit,
|
||||
this.radius,
|
||||
this.imageColor,
|
||||
this.isShowColor = false,
|
||||
this.isFromProfile = false,
|
||||
this.isFromSlider = false});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CachedNetworkImage(
|
||||
height: height,
|
||||
width: width,
|
||||
errorWidget: (context, url, error) {
|
||||
return Container(
|
||||
height: height,
|
||||
width: width,
|
||||
decoration: BoxDecoration(
|
||||
color: backGroundColor,
|
||||
borderRadius: BorderRadius.circular(radius ?? 0),
|
||||
border: Border.all(
|
||||
color: isBorderShow ? APPCOLOR.bgGrey : Colors.transparent,
|
||||
width: 1,
|
||||
)),
|
||||
child: Center(
|
||||
child: Image.asset(
|
||||
APPASSETS.placeHolder,
|
||||
height: height * 0.4,
|
||||
color: imageColor,
|
||||
)),
|
||||
);
|
||||
},
|
||||
placeholder: (context, url) {
|
||||
return Container(
|
||||
width: width,
|
||||
height: height,
|
||||
decoration: BoxDecoration(
|
||||
color: backGroundColor,
|
||||
borderRadius: BorderRadius.circular(radius ?? 0),
|
||||
border: Border.all(
|
||||
color: isBorderShow ? APPCOLOR.bgGrey : Colors.transparent,
|
||||
width: 1,
|
||||
)),
|
||||
child: const Center(
|
||||
child: CupertinoActivityIndicator(),
|
||||
),
|
||||
);
|
||||
},
|
||||
imageBuilder: (context, cIMage) {
|
||||
return Container(
|
||||
width: width,
|
||||
height: height,
|
||||
decoration: BoxDecoration(
|
||||
color: backGroundColor,
|
||||
borderRadius: isFromSlider
|
||||
? BorderRadius.only(
|
||||
topLeft: Radius.circular(radius!),
|
||||
topRight: Radius.circular(radius!),
|
||||
)
|
||||
: isFromProfile
|
||||
? BorderRadius.only(
|
||||
bottomLeft: Radius.circular(radius!),
|
||||
bottomRight: Radius.circular(radius!),
|
||||
)
|
||||
: BorderRadius.circular(radius ?? 0),
|
||||
border: Border.all(color: isBorderShow ? APPCOLOR.bgGrey : Colors.transparent, width: 1),
|
||||
image: DecorationImage(
|
||||
fit: boxFit ?? BoxFit.contain,
|
||||
colorFilter: isShowColor ? ColorFilter.mode(imageColor ?? APPCOLOR.bgGrey, BlendMode.srcIn) : null,
|
||||
image: cIMage,
|
||||
)),
|
||||
);
|
||||
},
|
||||
imageUrl: imageUrl);
|
||||
}
|
||||
}
|
||||
95
lib/src/common_widget/textfield_widget.dart
Normal file
95
lib/src/common_widget/textfield_widget.dart
Normal file
@@ -0,0 +1,95 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:grocery_app/utils/constants/color_constant.dart';
|
||||
import 'package:grocery_app/utils/extensions/decoration_ex.dart';
|
||||
import 'package:grocery_app/utils/extensions/uicontext.dart';
|
||||
|
||||
class AppTextFieldWidget extends StatelessWidget {
|
||||
final TextEditingController controller;
|
||||
final String hintText;
|
||||
final Widget? prefixIcon; //if you don't want to set icon the pass null
|
||||
final Widget? suffixIcon; //if you don't want to set icon the pass null
|
||||
final bool? isReadOnly;
|
||||
final bool? isObscure;
|
||||
final bool? isCurruncy;
|
||||
final String? lable;
|
||||
final int? length;
|
||||
final Color? lableTextColor;
|
||||
final VoidCallback? suffixIconTouch;
|
||||
final double? hintSize;
|
||||
final VoidCallback? onTapFiled;
|
||||
final bool isRoundedFiled;
|
||||
final VoidCallback? onEditingComplete;
|
||||
final FocusNode? focusNode;
|
||||
final Function? onValidate;
|
||||
final Function? onChanged;
|
||||
final TextInputAction? textInputAction;
|
||||
final TextInputType? keyBoardType;
|
||||
final Color? hintColor;
|
||||
final List<TextInputFormatter>? inputFormatters;
|
||||
final TextCapitalization? textCapitalization;
|
||||
|
||||
|
||||
const AppTextFieldWidget({
|
||||
super.key,
|
||||
required this.controller,
|
||||
required this.hintText,
|
||||
this.isReadOnly,
|
||||
this.prefixIcon,
|
||||
this.suffixIcon,
|
||||
this.lable,
|
||||
this.isObscure,
|
||||
this.isCurruncy,
|
||||
this.suffixIconTouch,
|
||||
this.onTapFiled,
|
||||
this.length,
|
||||
this.lableTextColor,
|
||||
this.onEditingComplete,
|
||||
this.focusNode,
|
||||
this.isRoundedFiled = false,
|
||||
this.onValidate,
|
||||
this.onChanged,
|
||||
this.hintSize,
|
||||
this.hintColor,
|
||||
this.textInputAction,
|
||||
this.inputFormatters,
|
||||
this.textCapitalization,
|
||||
this.keyBoardType,
|
||||
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return TextFormField(
|
||||
readOnly: isReadOnly ?? false,
|
||||
obscureText: isObscure ?? false,
|
||||
controller: controller,
|
||||
onTap: onTapFiled,
|
||||
maxLength: length,
|
||||
keyboardType: keyBoardType, //TextInputType.number
|
||||
focusNode: focusNode,
|
||||
validator: (value) => onValidate?.call(value),
|
||||
onChanged: (value) => onChanged?.call(value),
|
||||
onEditingComplete: onEditingComplete,
|
||||
inputFormatters: inputFormatters ?? [],
|
||||
textCapitalization: textCapitalization ?? TextCapitalization.none,
|
||||
enableSuggestions: true,
|
||||
style: context.customRegular(Colors.black, 16),
|
||||
decoration: const InputDecoration().customRoundedTextFieldDecoration(
|
||||
hintText,
|
||||
prefixIcon,
|
||||
suffixIcon,
|
||||
context.customRegular(APPCOLOR.balck1A1A1A, 14)));
|
||||
}
|
||||
}
|
||||
|
||||
class UpperCaseTextFormatter extends TextInputFormatter {
|
||||
@override
|
||||
TextEditingValue formatEditUpdate(
|
||||
TextEditingValue oldValue, TextEditingValue newValue) {
|
||||
return TextEditingValue(
|
||||
text: newValue.text.toUpperCase(),
|
||||
selection: newValue.selection,
|
||||
);
|
||||
}
|
||||
}
|
||||
23
lib/src/core/constant/api.dart
Normal file
23
lib/src/core/constant/api.dart
Normal file
@@ -0,0 +1,23 @@
|
||||
class APIURL {
|
||||
static const BASE_URL = "http://210.89.44.183:3333/xam/";
|
||||
static const String sendOtp = "${BASE_URL}auth/send-otp/vendor";
|
||||
static const String verifyOtp = "${BASE_URL}auth/verify-otp/vendor";
|
||||
static const String login = "${BASE_URL}auth/login/vendor";
|
||||
static const String vendorRegister = "${BASE_URL}auth/register/vendor";
|
||||
static const String createStore = "${BASE_URL}stores";
|
||||
static const String getStore = "${BASE_URL}stores/";
|
||||
static const String updateStore = "${BASE_URL}stores/";
|
||||
static const String forgetPassword = "${BASE_URL}auth/forgot-password/vendor";
|
||||
static const String verifyForgetPassword = "${BASE_URL}auth/forgot-password-verify-otp/vendor";
|
||||
static const String reset_password = "${BASE_URL}auth/reset-password/vendor";
|
||||
static const String get_category = "${BASE_URL}categories";
|
||||
static const String getProduct = "${BASE_URL}products";
|
||||
static const String getCategoryByLevel = "${BASE_URL}categories/by-level/1";
|
||||
static const String getMe = "${BASE_URL}auth/me";
|
||||
static const String refresh_token = "${BASE_URL}auth/refresh-token";
|
||||
static const String createProduct = "${BASE_URL}products";
|
||||
static const String vendorLogOut = "${BASE_URL}auth/logout/vendor";
|
||||
static const String uploadImage = "${BASE_URL}images/upload";
|
||||
static const String deleteProduct = "${BASE_URL}products/";
|
||||
static const String updateProduct = "${BASE_URL}products/";
|
||||
}
|
||||
12
lib/src/core/network_services/api_services.dart
Normal file
12
lib/src/core/network_services/api_services.dart
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:grocery_app/src/core/network_services/dio_client.dart';
|
||||
import 'package:grocery_app/src/core/network_services/service_locator.dart';
|
||||
|
||||
|
||||
/// Base api service
|
||||
abstract class ApiService {
|
||||
// Dio client object
|
||||
@protected
|
||||
final api = getIt<DioClient>();
|
||||
}
|
||||
11
lib/src/core/network_services/dev_utils.dart
Normal file
11
lib/src/core/network_services/dev_utils.dart
Normal file
@@ -0,0 +1,11 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
/// All the required utilities which helps in the development of the project
|
||||
|
||||
void debugLog(String? text) {
|
||||
if (kDebugMode) {
|
||||
log("##################\n$text\n>>>>>>>>>>>>>>>>>");
|
||||
}
|
||||
}
|
||||
219
lib/src/core/network_services/dio_client.dart
Normal file
219
lib/src/core/network_services/dio_client.dart
Normal file
@@ -0,0 +1,219 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:grocery_app/src/core/constant/api.dart';
|
||||
import 'package:grocery_app/src/core/network_services/dev_utils.dart';
|
||||
import 'package:grocery_app/utils/constants/shared_pref_utils.dart';
|
||||
import 'package:grocery_app/utils/extensions/common_utils.dart';
|
||||
import 'package:pretty_dio_logger/pretty_dio_logger.dart';
|
||||
|
||||
|
||||
/// Dio class wrapper for sending api request to the network
|
||||
class DioClient {
|
||||
final Dio _dio;
|
||||
|
||||
DioClient(this._dio) {
|
||||
_dio
|
||||
..options.baseUrl = APIURL.BASE_URL
|
||||
..options.connectTimeout = const Duration(seconds: 30)
|
||||
..options.receiveTimeout = const Duration(seconds: 30)
|
||||
..options.responseType = ResponseType.json
|
||||
..options.contentType = Headers.jsonContentType
|
||||
..interceptors.add(
|
||||
PrettyDioLogger(requestBody: true, compact: true, request: true));
|
||||
}
|
||||
|
||||
/// Send GET request
|
||||
Future<Response> get(String url,
|
||||
{Map<String, dynamic>? queryParameters,
|
||||
Options? options,
|
||||
CancelToken? cancelToken,
|
||||
ProgressCallback? onReceiveProgress,
|
||||
bool hideSoftKeyboard = true,
|
||||
required data}) async {
|
||||
if (hideSoftKeyboard) {
|
||||
// hideKeyBoard();
|
||||
}
|
||||
|
||||
print("post request Bearer token: ${await SharedPrefUtils.getToken()}");
|
||||
|
||||
try {
|
||||
final Response response = await _dio.get(
|
||||
url,
|
||||
queryParameters: queryParameters,
|
||||
options: options ??
|
||||
Options(headers: {
|
||||
"authorization": "Bearer ${await SharedPrefUtils.getToken()}"
|
||||
}),
|
||||
cancelToken: cancelToken,
|
||||
onReceiveProgress: onReceiveProgress,
|
||||
);
|
||||
return response;
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
/// Send POST request
|
||||
Future<Response> post(String url,
|
||||
{data,
|
||||
Map<String, dynamic>? queryParameters,
|
||||
Options? options,
|
||||
CancelToken? cancelToken,
|
||||
ProgressCallback? onSendProgress,
|
||||
ProgressCallback? onReceiveProgress,
|
||||
bool hideSoftKeyboard = true}) async {
|
||||
if (hideSoftKeyboard) {
|
||||
hideKeyBoard();
|
||||
}
|
||||
debugLog(" post request Bearer token: ${await SharedPrefUtils.getToken()}");
|
||||
try {
|
||||
final Response response = await _dio.post(
|
||||
url,
|
||||
data: data,
|
||||
queryParameters: queryParameters,
|
||||
options: options ??
|
||||
Options(headers: {
|
||||
"authorization": "Bearer ${await SharedPrefUtils.getToken()}"
|
||||
}),
|
||||
cancelToken: cancelToken,
|
||||
onSendProgress: onSendProgress,
|
||||
onReceiveProgress: onReceiveProgress,
|
||||
);
|
||||
return response;
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
/// Send PUT request
|
||||
Future<Response> patch(String url,
|
||||
{data,
|
||||
Map<String, dynamic>? queryParameters,
|
||||
Options? options,
|
||||
CancelToken? cancelToken,
|
||||
ProgressCallback? onSendProgress,
|
||||
ProgressCallback? onReceiveProgress,
|
||||
bool hideSoftKeyboard = true}) async {
|
||||
if (hideSoftKeyboard) {
|
||||
hideKeyBoard();
|
||||
}
|
||||
debugLog("Put Bearer token: ${await SharedPrefUtils.getToken()}");
|
||||
try {
|
||||
final Response response = await _dio.patch(
|
||||
url,
|
||||
data: data,
|
||||
queryParameters: queryParameters,
|
||||
options: options ??
|
||||
Options(headers: {
|
||||
"authorization": "Bearer ${await SharedPrefUtils.getToken()}"
|
||||
}),
|
||||
cancelToken: cancelToken,
|
||||
onSendProgress: onSendProgress,
|
||||
onReceiveProgress: onReceiveProgress,
|
||||
);
|
||||
return response;
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
/// Send DELETE request
|
||||
Future<dynamic> delete(String url,
|
||||
{data,
|
||||
Map<String, dynamic>? queryParameters,
|
||||
Options? options,
|
||||
CancelToken? cancelToken,
|
||||
ProgressCallback? onSendProgress,
|
||||
ProgressCallback? onReceiveProgress,
|
||||
bool hideSoftKeyboard = true}) async {
|
||||
if (hideSoftKeyboard) {
|
||||
hideKeyBoard();
|
||||
}
|
||||
debugLog("delete Bearer token: ${await SharedPrefUtils.getToken()}");
|
||||
try {
|
||||
final Response response = await _dio.delete(
|
||||
url,
|
||||
data: data,
|
||||
queryParameters: queryParameters,
|
||||
options: options ??
|
||||
Options(headers: {
|
||||
"authorization": "Bearer ${await SharedPrefUtils.getToken()}"
|
||||
}),
|
||||
cancelToken: cancelToken,
|
||||
);
|
||||
return response;
|
||||
|
||||
/// return response.data
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
//Download:--------------------------------------------------------------------
|
||||
Future<dynamic> download(
|
||||
String url,
|
||||
dynamic savePath, {
|
||||
Map<String, dynamic>? queryParameters,
|
||||
Options? options,
|
||||
CancelToken? cancelToken,
|
||||
ProgressCallback? onSendProgress,
|
||||
ProgressCallback? onReceiveProgress,
|
||||
}) async {
|
||||
hideKeyBoard();
|
||||
debugLog("Bearer ${await SharedPrefUtils.getToken()}");
|
||||
try {
|
||||
final Response response = await _dio.download(
|
||||
url,
|
||||
savePath,
|
||||
queryParameters: queryParameters,
|
||||
options: options ??
|
||||
Options(
|
||||
headers: {"authorization": await SharedPrefUtils.getToken()}),
|
||||
cancelToken: cancelToken,
|
||||
);
|
||||
return response.data;
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Future<Response> uploadImage(String url, File imageFile,
|
||||
{Map<String, dynamic>? additionalFields,
|
||||
Options? options,
|
||||
CancelToken? cancelToken,
|
||||
ProgressCallback? onSendProgress,
|
||||
ProgressCallback? onReceiveProgress,
|
||||
bool hideSoftKeyboard = true}) async {
|
||||
if (hideSoftKeyboard) {
|
||||
hideKeyBoard();
|
||||
}
|
||||
|
||||
debugLog("UPLOAD IMAGE Bearer token: ${await SharedPrefUtils.getToken()}");
|
||||
|
||||
try {
|
||||
String fileName = imageFile.path.split('/').last;
|
||||
FormData formData = FormData.fromMap({
|
||||
"image": await MultipartFile.fromFile(imageFile.path, filename: fileName),
|
||||
...?additionalFields,
|
||||
});
|
||||
|
||||
final Response response = await _dio.post(
|
||||
url,
|
||||
data: formData,
|
||||
options: options ??
|
||||
Options(headers: {
|
||||
"authorization": "Bearer ${await SharedPrefUtils.getToken()}"
|
||||
}),
|
||||
cancelToken: cancelToken,
|
||||
onSendProgress: onSendProgress,
|
||||
onReceiveProgress: onReceiveProgress,
|
||||
);
|
||||
return response;
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
40
lib/src/core/network_services/service_locator.dart
Normal file
40
lib/src/core/network_services/service_locator.dart
Normal file
@@ -0,0 +1,40 @@
|
||||
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:grocery_app/src/core/network_services/dio_client.dart';
|
||||
|
||||
|
||||
|
||||
|
||||
GetIt getIt = GetIt.instance;
|
||||
|
||||
class ServiceLocator
|
||||
{
|
||||
static void setup() {
|
||||
|
||||
// dio client
|
||||
getIt.registerSingleton(Dio());
|
||||
getIt.registerSingleton(DioClient(getIt<Dio>()));
|
||||
// getIt.registerSingleton(AuthServices());
|
||||
// getIt.registerSingleton(ProductService());
|
||||
// getIt.registerSingleton(StoreService());
|
||||
// getIt.registerSingleton(HomeService());
|
||||
|
||||
// StoreRepo
|
||||
|
||||
// getIt.registerSingleton(ContactApiService());
|
||||
// getIt.registerSingleton(BuzzService());
|
||||
// getIt.registerSingleton(CmsServices());
|
||||
// getIt.registerSingleton(SettingService());
|
||||
// getIt.registerSingleton(ActivityService());
|
||||
|
||||
|
||||
// Repos
|
||||
// getIt.registerSingleton(AuthRepo(getIt<AuthServices>()));
|
||||
// getIt.registerSingleton(ProductRepo(getIt<ProductService>()));
|
||||
// getIt.registerSingleton(StoreRepo(getIt<StoreService>()));
|
||||
// getIt.registerSingleton(HomeRepo(getIt<HomeService>()));
|
||||
|
||||
}
|
||||
}
|
||||
244
lib/src/core/routes/routes.dart
Normal file
244
lib/src/core/routes/routes.dart
Normal file
@@ -0,0 +1,244 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:grocery_app/src/ui/login/login_screen.dart';
|
||||
import 'package:grocery_app/src/ui/onboarding/on_boarding_screen.dart';
|
||||
import 'package:grocery_app/src/ui/splash/splash_screen.dart';
|
||||
import 'package:grocery_app/utils/constants/globle_variable.dart';
|
||||
|
||||
|
||||
|
||||
/// Route names as constants
|
||||
class MyRoutes {
|
||||
static GoRouter router = GoRouter(
|
||||
navigatorKey: GlobalVariable.globalScaffoldKey,
|
||||
initialLocation: SPLASH,
|
||||
routes: [
|
||||
animatedGoRoute(
|
||||
path: SPLASH,
|
||||
name: SPLASH,
|
||||
pageBuilder: (context, state) => const SplashScreen(),
|
||||
),
|
||||
|
||||
animatedGoRoute(
|
||||
path: ONBOARDING,
|
||||
name: ONBOARDING,
|
||||
pageBuilder: (context, state) => const OnBoardingScreen(),
|
||||
),
|
||||
|
||||
animatedGoRoute(
|
||||
path: LOGIN,
|
||||
name: LOGIN,
|
||||
pageBuilder: (context, state) => LoginScreen(),
|
||||
),
|
||||
|
||||
|
||||
// animatedGoRoute(
|
||||
// path: SELECTACCOUNT,
|
||||
// name: SELECTACCOUNT,
|
||||
// pageBuilder: (context, state) => const SelectAccount(),
|
||||
// ),
|
||||
// animatedGoRoute(
|
||||
// path: TERMANDCONDITIONS,
|
||||
// name: TERMANDCONDITIONS,
|
||||
// pageBuilder: (context, state) => const TermsAndConditionsScreen(),
|
||||
// ),
|
||||
// animatedGoRoute(
|
||||
// path: SETUPBUSSINESS,
|
||||
// name: SETUPBUSSINESS,
|
||||
// pageBuilder: (context, state) {
|
||||
// final extra = state.extra as Map<String, dynamic>?;
|
||||
// final String status = extra?['status'] ?? '';
|
||||
// return SetupBussiness(status: status);
|
||||
// }),
|
||||
// animatedGoRoute(
|
||||
// path: CREATESTORE,
|
||||
// name: CREATESTORE,
|
||||
// pageBuilder: (context, state) => const CreateStore(),
|
||||
// ),
|
||||
// animatedGoRoute(
|
||||
// path: UPDATESTORE,
|
||||
// name: UPDATESTORE,
|
||||
// pageBuilder: (context, state) {
|
||||
// final extra = state.extra as Map<String, dynamic>?;
|
||||
// final String status = extra?['storeId'] ?? '';
|
||||
// return UpdateStoreScreen(storeId: status);
|
||||
// }
|
||||
|
||||
// ),
|
||||
|
||||
|
||||
// animatedGoRoute(
|
||||
// path: SUBMITSCREEN,
|
||||
// name: SUBMITSCREEN,
|
||||
// pageBuilder: (context, state) => const PinCreated(),
|
||||
// ),
|
||||
// animatedGoRoute(
|
||||
// path: APPROVEDSTATUS,
|
||||
// name: APPROVEDSTATUS,
|
||||
// pageBuilder: (context, state) => const ApprovalScreen(),
|
||||
// ),
|
||||
// animatedGoRoute(
|
||||
// path: SIGNUP,
|
||||
// name: SIGNUP,
|
||||
// pageBuilder: (context, state) => LoginHostScreen(),
|
||||
// ),
|
||||
// animatedGoRoute(
|
||||
// path: DASHBOARDSCREEN,
|
||||
// name: DASHBOARDSCREEN,
|
||||
// pageBuilder: (context, state) => DashboardScree(),
|
||||
// ),
|
||||
// animatedGoRoute(
|
||||
// path: CUSTOMERORDER,
|
||||
// name: CUSTOMERORDER,
|
||||
// pageBuilder: (context, state) {
|
||||
// // Extract data from `state.extra`
|
||||
// final Map<String, dynamic> orderDetails =
|
||||
// state.extra as Map<String, dynamic>;
|
||||
|
||||
// return CustomerOrder(
|
||||
// orderDetails:
|
||||
// orderDetails, // Pass the data to the destination widget
|
||||
// );
|
||||
// },
|
||||
// ),
|
||||
// animatedGoRoute(
|
||||
// path: PRODUCTFORMSCREEN,
|
||||
// name: PRODUCTFORMSCREEN,
|
||||
// pageBuilder: (context, state) => ProductFormScreen(),
|
||||
// ),
|
||||
// animatedGoRoute(
|
||||
// path: PRODUCTDETAILS,
|
||||
// name: PRODUCTDETAILS,
|
||||
// pageBuilder: (context, state) {
|
||||
// final Product product = state.extra as Product;
|
||||
// return Productdetails(
|
||||
// product: product, // Pass the `Product` object directly
|
||||
// );
|
||||
// },
|
||||
// ),
|
||||
// animatedGoRoute(
|
||||
// path: TRANSACTIONHISTORY,
|
||||
// name: TRANSACTIONHISTORY,
|
||||
// pageBuilder: (context, state) => TransactionHistory(),
|
||||
// ),
|
||||
// animatedGoRoute(
|
||||
// path: INSIGHTSHISTORY,
|
||||
// name: INSIGHTSHISTORY,
|
||||
// pageBuilder: (context, state) => InsightsHistory(),
|
||||
// ),
|
||||
// animatedGoRoute(
|
||||
// path: DETAILSBUSSINESS,
|
||||
// name: DETAILSBUSSINESS,
|
||||
// pageBuilder: (context, state) => DetailsBussiness(),
|
||||
// ),
|
||||
// animatedGoRoute(
|
||||
// path: STOREMANAGEMENT,
|
||||
// name: STOREMANAGEMENT,
|
||||
// pageBuilder: (context, state) => StoreManagement(),
|
||||
// ),
|
||||
// animatedGoRoute(
|
||||
// path: SETTING,
|
||||
// name: SETTING,
|
||||
// pageBuilder: (context, state) => Settings(),
|
||||
// ),
|
||||
// animatedGoRoute(
|
||||
// path: FORGETPASSWORD,
|
||||
// name: FORGETPASSWORD,
|
||||
// pageBuilder: (context, state) => ForgetPassword(),
|
||||
// ),
|
||||
// animatedGoRoute(
|
||||
// path: VERIFYPASSWORD,
|
||||
// name: VERIFYPASSWORD,
|
||||
// pageBuilder: (context, state) => VerifyOtpForgetPassword(),
|
||||
// ),
|
||||
// animatedGoRoute(
|
||||
// path: FORGETNEWPASSWORD,
|
||||
// name: FORGETNEWPASSWORD,
|
||||
// pageBuilder: (context, state) => ForgetNewPassword(),
|
||||
// ),
|
||||
// ],
|
||||
]
|
||||
);
|
||||
|
||||
/// Route constants
|
||||
static const SPLASH = "/";
|
||||
static const HOME = "/home";
|
||||
static const SELECTACCOUNT = "/selectAccount";
|
||||
static const DASHBOARD = "/dashboard";
|
||||
|
||||
static const BOTTOM_NAV = "/home";
|
||||
static const LOGIN = "/login";
|
||||
static const ONBOARDING = "/onboarding";
|
||||
static const TERMANDCONDITIONS = "/termsandcondition";
|
||||
static const SETUPBUSSINESS = "/setupbussiness";
|
||||
static const CREATESTORE = "/createStore";
|
||||
static const SUBMITSCREEN = "/submitscreen";
|
||||
static const APPROVEDSTATUS = "/approvedstatus";
|
||||
static const SIGNUP = "/signup";
|
||||
static const DASHBOARDSCREEN = "/dashboardscreen";
|
||||
static const CUSTOMERORDER = "/customerorder";
|
||||
|
||||
static const PRODUCTFORMSCREEN = "/productformscreen";
|
||||
static const PRODUCTDETAILS = "/productdetails";
|
||||
|
||||
static const TRANSACTIONHISTORY = "/transationhistory";
|
||||
|
||||
static const INSIGHTSHISTORY = "/insightshistory";
|
||||
|
||||
static const DETAILSBUSSINESS = "/detailsbussiness";
|
||||
|
||||
static const STOREMANAGEMENT = "/storemanagement";
|
||||
|
||||
static const SETTING = "/settings";
|
||||
|
||||
static const FORGETPASSWORD = "/forgetpassword";
|
||||
static const VERIFYPASSWORD = "/verifypassword";
|
||||
|
||||
static const FORGETNEWPASSWORD = "/forgetnewpassword";
|
||||
|
||||
static const UPDATESTORE = "/updatestore";
|
||||
|
||||
}
|
||||
|
||||
GoRoute animatedGoRoute({
|
||||
required String path,
|
||||
required String name,
|
||||
ExitCallback? onExitPage,
|
||||
required Widget Function(BuildContext, GoRouterState) pageBuilder,
|
||||
}) {
|
||||
return GoRoute(
|
||||
path: path,
|
||||
name: name,
|
||||
onExit: onExitPage,
|
||||
pageBuilder: (context, state) => CustomTransitionPage<void>(
|
||||
key: state.pageKey,
|
||||
transitionDuration: const Duration(milliseconds: 400),
|
||||
child: pageBuilder(context, state),
|
||||
transitionsBuilder: (_, animation, __, child) {
|
||||
return FadeTransition(
|
||||
opacity: animation,
|
||||
child: child,
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
class CustomSlideTransition extends CustomTransitionPage<void> {
|
||||
CustomSlideTransition({super.key, required super.child})
|
||||
: super(
|
||||
transitionDuration: const Duration(milliseconds: 250),
|
||||
transitionsBuilder: (_, animation, __, child) {
|
||||
return SlideTransition(
|
||||
position: animation.drive(
|
||||
Tween(begin: const Offset(1.5, 0), end: Offset.zero).chain(
|
||||
CurveTween(curve: Curves.bounceIn),
|
||||
),
|
||||
),
|
||||
child: child,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
237
lib/src/ui/bestdeal/bestdeal_screen.dart
Normal file
237
lib/src/ui/bestdeal/bestdeal_screen.dart
Normal file
@@ -0,0 +1,237 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:grocery_app/src/common_widget/network_image.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/uicontext.dart';
|
||||
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
||||
|
||||
class BestDealScreen extends StatefulWidget {
|
||||
const BestDealScreen({super.key});
|
||||
|
||||
@override
|
||||
State<BestDealScreen> createState() => _BestDealScreenState();
|
||||
}
|
||||
|
||||
class _BestDealScreenState extends State<BestDealScreen> {
|
||||
@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: const Text(
|
||||
"Best Deal",
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
InkWell(
|
||||
onTap: () {},
|
||||
child: Icon(
|
||||
MdiIcons.magnify,
|
||||
size: 35,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
floatingActionButton: Padding(
|
||||
padding: const EdgeInsets.only(left: 30),
|
||||
child: Container(
|
||||
height: 80,
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
decoration: BoxDecoration(color: APPCOLOR.lightGreen, borderRadius: BorderRadius.circular(15)),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(10),
|
||||
child: Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 80,
|
||||
child: Stack(
|
||||
children: [
|
||||
Container(
|
||||
height: 70,
|
||||
width: 70,
|
||||
decoration: BoxDecoration(color: Colors.white.withOpacity(0.5), borderRadius: BorderRadius.circular(10)),
|
||||
),
|
||||
const Positioned(
|
||||
left: 20,
|
||||
bottom: 0,
|
||||
top: 0,
|
||||
right: 0,
|
||||
child: AppNetworkImage(
|
||||
height: 70,
|
||||
width: 70,
|
||||
radius: 10,
|
||||
imageUrl: "https://5.imimg.com/data5/SELLER/Default/2024/2/385126988/OL/DA/VW/8627346/1l-fortune-sunflower-oil.jpg",
|
||||
backGroundColor: Colors.white,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'2 Items',
|
||||
style: context.customRegular(Colors.white, 18),
|
||||
),
|
||||
Text(
|
||||
'\$25',
|
||||
style: context.customExtraBold(Colors.white, 20),
|
||||
)
|
||||
],
|
||||
),
|
||||
const Spacer(),
|
||||
Text(
|
||||
'View Cart',
|
||||
style: context.customMedium(Colors.white, 24),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
const Icon(
|
||||
Icons.arrow_forward,
|
||||
color: Colors.white,
|
||||
size: 35,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(15),
|
||||
child: GridView.builder(
|
||||
itemCount: 20,
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 2, childAspectRatio: MediaQuery.of(context).size.width / (MediaQuery.of(context).size.height / 1.1), crossAxisSpacing: 10, mainAxisSpacing: 10),
|
||||
itemBuilder: (context, index) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(15), boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.grey.withOpacity(0.1),
|
||||
blurRadius: 1,
|
||||
offset: const Offset(5, 5),
|
||||
),
|
||||
]),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(5),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
height: 160,
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
// width: 150,
|
||||
decoration: BoxDecoration(color: APPCOLOR.bgGrey, borderRadius: BorderRadius.circular(15)),
|
||||
child: const Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
AppNetworkImage(
|
||||
height: 150,
|
||||
width: 140,
|
||||
imageUrl: "https://5.imimg.com/data5/SELLER/Default/2024/2/385126988/OL/DA/VW/8627346/1l-fortune-sunflower-oil.jpg",
|
||||
backGroundColor: Colors.transparent),
|
||||
Positioned(right: 5, top: 5, child: Icon(Icons.favorite_border))
|
||||
],
|
||||
),
|
||||
),
|
||||
Text(
|
||||
"Fortune Arhar Dal (Toor Dal)",
|
||||
textAlign: TextAlign.left,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: context.customMedium(APPCOLOR.balck1A1A1A, 16),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
Text(
|
||||
"500 ML",
|
||||
textAlign: TextAlign.left,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: context.customMedium(Colors.grey.withOpacity(0.8), 12),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 3,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
"\$12",
|
||||
textAlign: TextAlign.left,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: context.customSemiBold(Colors.black, 16),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 5,
|
||||
),
|
||||
Text(
|
||||
"\$14",
|
||||
textAlign: TextAlign.left,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: context.customMedium(Colors.grey.withOpacity(0.8), 16).copyWith(
|
||||
decoration: TextDecoration.lineThrough,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: Container(
|
||||
height: 40,
|
||||
width: 60,
|
||||
decoration: BoxDecoration(
|
||||
color: APPCOLOR.lightGreen,
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Add',
|
||||
style: context.customRegular(Colors.white, 12),
|
||||
)),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
199
lib/src/ui/bottomnavigation/bottom_bar_widget.dart
Normal file
199
lib/src/ui/bottomnavigation/bottom_bar_widget.dart
Normal file
@@ -0,0 +1,199 @@
|
||||
// ignore_for_file: library_private_types_in_public_api
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:grocery_app/src/ui/home/home_screen.dart';
|
||||
import 'package:grocery_app/src/ui/profilepage/profile_screen.dart';
|
||||
import 'package:grocery_app/utils/constants/color_constant.dart';
|
||||
|
||||
class BottomBarWidget extends StatefulWidget {
|
||||
const BottomBarWidget({super.key});
|
||||
|
||||
@override
|
||||
_BottomBarState createState() => _BottomBarState();
|
||||
}
|
||||
|
||||
class _BottomBarState extends State<BottomBarWidget> {
|
||||
int _currentIndex = 0;
|
||||
PageController bottomWidgetPageController = PageController(
|
||||
initialPage: 0,
|
||||
keepPage: true,
|
||||
);
|
||||
|
||||
void _onNavButtonTapped(int index) {
|
||||
setState(() {
|
||||
_currentIndex = index;
|
||||
});
|
||||
|
||||
if (bottomWidgetPageController.hasClients) {
|
||||
bottomWidgetPageController.animateToPage(index, duration: const Duration(milliseconds: 100), curve: Curves.ease);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_currentIndex = 0;
|
||||
bottomWidgetPageController = PageController(
|
||||
initialPage: 0,
|
||||
keepPage: true,
|
||||
);
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
SizeConfig().init(context);
|
||||
|
||||
return Scaffold(
|
||||
body: PageView(
|
||||
controller: bottomWidgetPageController,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
children: const <Widget>[
|
||||
HomeScreen(),
|
||||
Text('1'),
|
||||
Text('2'),
|
||||
ProfileScreen(),
|
||||
],
|
||||
),
|
||||
bottomNavigationBar: SizedBox(
|
||||
height: SizeConfig.blockSizeHorizontal! * 15,
|
||||
child: Stack(
|
||||
children: [
|
||||
AnimatedPositioned(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
curve: Curves.decelerate,
|
||||
top: 0,
|
||||
left: (_currentIndex * MediaQuery.sizeOf(context).width / 4) + 42,
|
||||
child: Column(
|
||||
children: [
|
||||
ClipPath(
|
||||
clipper: MyCustomClipper(),
|
||||
child: Container(
|
||||
height: SizeConfig.blockSizeHorizontal! * 4,
|
||||
width: SizeConfig.blockSizeHorizontal! * 5,
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
colors: [
|
||||
APPCOLOR.lightGreen.withOpacity(0.8),
|
||||
APPCOLOR.lightGreen.withOpacity(0.5),
|
||||
Colors.transparent,
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
BottomNavButton(
|
||||
icon: Icons.home,
|
||||
index: 0,
|
||||
currentIndex: _currentIndex,
|
||||
onPressed: _onNavButtonTapped,
|
||||
),
|
||||
BottomNavButton(
|
||||
icon: Icons.favorite,
|
||||
index: 1,
|
||||
currentIndex: _currentIndex,
|
||||
onPressed: _onNavButtonTapped,
|
||||
),
|
||||
BottomNavButton(
|
||||
icon: Icons.shopping_bag,
|
||||
index: 2,
|
||||
currentIndex: _currentIndex,
|
||||
onPressed: _onNavButtonTapped,
|
||||
),
|
||||
BottomNavButton(
|
||||
icon: Icons.person,
|
||||
index: 3,
|
||||
currentIndex: _currentIndex,
|
||||
onPressed: _onNavButtonTapped,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class SizeConfig {
|
||||
static MediaQueryData? _mediaQueryData;
|
||||
static double? screenWidth;
|
||||
static double? screenHeight;
|
||||
static double? blockSizeHorizontal;
|
||||
static double? blockSizeVertical;
|
||||
|
||||
void init(BuildContext context) {
|
||||
_mediaQueryData = MediaQuery.of(context);
|
||||
screenWidth = _mediaQueryData!.size.width;
|
||||
screenHeight = _mediaQueryData!.size.height;
|
||||
blockSizeHorizontal = screenWidth! / 100;
|
||||
blockSizeVertical = screenHeight! / 100;
|
||||
}
|
||||
}
|
||||
|
||||
class BottomNavButton extends StatelessWidget {
|
||||
final Function(int) onPressed;
|
||||
final IconData? icon;
|
||||
final int? index;
|
||||
final int? currentIndex;
|
||||
|
||||
const BottomNavButton({
|
||||
super.key,
|
||||
this.icon,
|
||||
required this.onPressed,
|
||||
this.index,
|
||||
this.currentIndex,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
if (index != null) {
|
||||
onPressed(index!);
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
height: SizeConfig.blockSizeHorizontal! * 13,
|
||||
width: SizeConfig.blockSizeHorizontal! * 17,
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.transparent,
|
||||
),
|
||||
child: AnimatedOpacity(
|
||||
opacity: (currentIndex == index) ? 1 : 0.2,
|
||||
duration: const Duration(milliseconds: 300),
|
||||
curve: Curves.easeIn,
|
||||
child: Icon(
|
||||
icon,
|
||||
color: (currentIndex == index) ? APPCOLOR.lightGreen : Colors.black,
|
||||
size: SizeConfig.blockSizeHorizontal! * 6,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class MyCustomClipper extends CustomClipper<Path> {
|
||||
@override
|
||||
Path getClip(Size size) {
|
||||
var path = Path();
|
||||
path.lineTo(SizeConfig.blockSizeHorizontal! * 3, 0);
|
||||
path.lineTo(0, size.height);
|
||||
path.lineTo(size.width, size.height);
|
||||
path.lineTo(size.width - SizeConfig.blockSizeHorizontal! * 3, 0);
|
||||
return path;
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldReclip(CustomClipper oldClipper) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
260
lib/src/ui/card_checkout/card_checkout_screen.dart
Normal file
260
lib/src/ui/card_checkout/card_checkout_screen.dart
Normal file
@@ -0,0 +1,260 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:grocery_app/src/common_widget/name_text_field.dart';
|
||||
import 'package:grocery_app/src/common_widget/network_image.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/uicontext.dart';
|
||||
|
||||
class CardCheckoutScreen extends StatefulWidget {
|
||||
const CardCheckoutScreen({super.key});
|
||||
|
||||
@override
|
||||
State<CardCheckoutScreen> createState() => _CardCheckoutScreenState();
|
||||
}
|
||||
|
||||
class _CardCheckoutScreenState extends State<CardCheckoutScreen> {
|
||||
@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: const Text(
|
||||
"Checkout",
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
),
|
||||
bottomNavigationBar: Container(
|
||||
color: Colors.transparent,
|
||||
height: 60,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(bottom: 10),
|
||||
child: Row(
|
||||
children: [
|
||||
const SizedBox(
|
||||
width: 15,
|
||||
),
|
||||
Expanded(
|
||||
child: InkWell(
|
||||
onTap: () {},
|
||||
child: Container(
|
||||
height: 50,
|
||||
decoration: BoxDecoration(color: APPCOLOR.lightGreen, borderRadius: BorderRadius.circular(10)),
|
||||
child: Center(
|
||||
child: Text(
|
||||
"Next",
|
||||
style: context.customRegular(Colors.white, 16),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 15,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
body: Padding(
|
||||
padding: context.bodyAllPadding,
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Saved Cards",
|
||||
style: context.customExtraBold(Colors.black, 16),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
Container(
|
||||
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(15)),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(10),
|
||||
child: Row(
|
||||
children: [
|
||||
const AppNetworkImage(
|
||||
height: 50,
|
||||
width: 50,
|
||||
imageUrl: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSeaqcsR_xDLZTOQ7G-NxCe7mLDxFe-xC2JC_DIojrF2CiVJRnviMf9fvGGFZyzyII3jdY&usqp=CAU',
|
||||
backGroundColor: Colors.transparent),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
"6895 8578 8578 5525",
|
||||
style: context.customMedium(Colors.black, 16),
|
||||
)),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Icon(
|
||||
Icons.radio_button_off_outlined,
|
||||
color: Colors.grey.withOpacity(0.3),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Container(
|
||||
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(15)),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(10),
|
||||
child: Row(
|
||||
children: [
|
||||
const AppNetworkImage(
|
||||
height: 50, width: 50, imageUrl: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQIXY75wxXccxnFoger82T83BZxDPpMavUI1A&s', backGroundColor: Colors.transparent),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
"6895 8578 8578 5525",
|
||||
style: context.customMedium(Colors.black, 16),
|
||||
)),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Icon(
|
||||
Icons.radio_button_off_outlined,
|
||||
color: Colors.grey.withOpacity(0.3),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
child: ExpansionTile(
|
||||
minTileHeight: 0,
|
||||
backgroundColor: Colors.white,
|
||||
collapsedBackgroundColor: Colors.white,
|
||||
//trailing: SizedBox(),
|
||||
childrenPadding: const EdgeInsets.only(left: 10, right: 10, bottom: 10),
|
||||
tilePadding: const EdgeInsets.only(right: 10),
|
||||
title: Container(
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(15)),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 10, right: 10),
|
||||
child: Row(
|
||||
children: [
|
||||
const AppNetworkImage(
|
||||
height: 50,
|
||||
width: 50,
|
||||
imageUrl: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSeaqcsR_xDLZTOQ7G-NxCe7mLDxFe-xC2JC_DIojrF2CiVJRnviMf9fvGGFZyzyII3jdY&usqp=CAU',
|
||||
backGroundColor: Colors.transparent),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
"6895 8578 8578 5525",
|
||||
style: context.customMedium(Colors.black, 16),
|
||||
)),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
children: const [
|
||||
NameTextField(
|
||||
name: 'Card Number',
|
||||
initText: "2352 5285 8545 7528",
|
||||
),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
NameTextField(
|
||||
name: 'Card Holder Name',
|
||||
initText: "Smith Watson",
|
||||
),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: NameTextField(
|
||||
name: 'Expiry Date',
|
||||
initText: "09/22",
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Expanded(
|
||||
child: NameTextField(
|
||||
name: 'CVV',
|
||||
initText: "129",
|
||||
),
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Container(
|
||||
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(15)),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(10),
|
||||
child: Row(
|
||||
children: [
|
||||
const AppNetworkImage(
|
||||
height: 50, width: 50, imageUrl: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTwiraGT0PrLTwZKDg-u25PAlVRgnkdeL96mA&s', backGroundColor: Colors.transparent),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
"Paypal",
|
||||
style: context.customMedium(Colors.black, 16),
|
||||
)),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Icon(
|
||||
Icons.radio_button_off_outlined,
|
||||
color: Colors.grey.withOpacity(0.3),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
156
lib/src/ui/edit_profile/edit_profile_screen.dart
Normal file
156
lib/src/ui/edit_profile/edit_profile_screen.dart
Normal file
@@ -0,0 +1,156 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:grocery_app/src/common_widget/name_text_field.dart';
|
||||
import 'package:grocery_app/src/common_widget/network_image.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/uicontext.dart';
|
||||
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
||||
|
||||
class EditProfileScreen extends StatefulWidget {
|
||||
const EditProfileScreen({super.key});
|
||||
|
||||
@override
|
||||
State<EditProfileScreen> createState() => _EditProfileScreenState();
|
||||
}
|
||||
|
||||
class _EditProfileScreenState extends State<EditProfileScreen> {
|
||||
@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: const Text(
|
||||
"Edit Profile",
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
),
|
||||
bottomNavigationBar: Container(
|
||||
color: Colors.transparent,
|
||||
height: 60,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(bottom: 10),
|
||||
child: Row(
|
||||
children: [
|
||||
const SizedBox(
|
||||
width: 15,
|
||||
),
|
||||
Expanded(
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Container(
|
||||
height: 50,
|
||||
decoration: BoxDecoration(color: APPCOLOR.lightGreen, borderRadius: BorderRadius.circular(10)),
|
||||
child: Center(
|
||||
child: Text(
|
||||
"Update",
|
||||
style: context.customRegular(Colors.white, 16),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 15,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
body: Padding(
|
||||
padding: context.bodyAllPadding,
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
const AppNetworkImage(
|
||||
height: 80,
|
||||
width: 80,
|
||||
imageUrl: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTdQLwDqDwd2JfzifvfBTFT8I7iKFFevcedYg&s",
|
||||
radius: 90,
|
||||
backGroundColor: Colors.white,
|
||||
boxFit: BoxFit.fill,
|
||||
),
|
||||
Positioned(
|
||||
bottom: 0,
|
||||
right: 0,
|
||||
child: Container(
|
||||
height: 20,
|
||||
width: 20,
|
||||
decoration: BoxDecoration(color: APPCOLOR.lightGreen, border: Border.all(color: Colors.white), borderRadius: BorderRadius.circular(5)),
|
||||
child: Center(
|
||||
child: Icon(
|
||||
MdiIcons.pencil,
|
||||
size: 10,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
)),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
const NameTextField(
|
||||
name: "Name",
|
||||
initText: "Smith Mate",
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
const NameTextField(
|
||||
name: "Email Address",
|
||||
initText: "SmithMate@example.com",
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
const NameTextField(
|
||||
name: "Mobile Number",
|
||||
initText: "(205) 555-0100",
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
const NameTextField(
|
||||
name: "Enter Address",
|
||||
initText: "8502 Preston Rd. inglewood, USA",
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
],
|
||||
)),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
86
lib/src/ui/entername/enter_fullname_screen.dart
Normal file
86
lib/src/ui/entername/enter_fullname_screen.dart
Normal file
@@ -0,0 +1,86 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:grocery_app/src/common_widget/textfield_widget.dart';
|
||||
import 'package:grocery_app/src/ui/bottomnavigation/bottom_bar_widget.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/string_constant.dart';
|
||||
import 'package:grocery_app/utils/extensions/uicontext.dart';
|
||||
|
||||
class EnterFullNameScreen extends StatefulWidget {
|
||||
const EnterFullNameScreen({super.key});
|
||||
|
||||
@override
|
||||
State<EnterFullNameScreen> createState() => _EnterFullNameScreenState();
|
||||
}
|
||||
|
||||
class _EnterFullNameScreenState extends State<EnterFullNameScreen> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Container(
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
height: MediaQuery.sizeOf(context).height,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.greenAccent.withOpacity(0.1),
|
||||
),
|
||||
child: Padding(
|
||||
padding: context.bodyAllPadding,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(height: 30),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: SvgPicture.asset(APPASSETS.back)),
|
||||
const SizedBox(height: 30),
|
||||
Text(
|
||||
APPSTRING.pleaseEnterYourFullName,
|
||||
style: context.customMedium(APPCOLOR.black333333, 18),
|
||||
),
|
||||
const SizedBox(height: 30),
|
||||
AppTextFieldWidget(
|
||||
controller: TextEditingController(),
|
||||
hintText: APPSTRING.fullNameHint,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
bottomNavigationBar: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.greenAccent.withOpacity(0.1),
|
||||
),
|
||||
height: 100,
|
||||
child: Padding(
|
||||
padding: context.bodyAllPadding.copyWith(bottom: 20),
|
||||
child: Center(
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
Navigator.of(context).push(MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const BottomBarWidget();
|
||||
},
|
||||
));
|
||||
},
|
||||
child: Container(
|
||||
height: 50,
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
decoration: BoxDecoration(color: APPCOLOR.appGreen, borderRadius: BorderRadius.circular(4)),
|
||||
child: Center(
|
||||
child: Text(
|
||||
APPSTRING.continueBtn,
|
||||
style: context.customMedium(Colors.white, 16),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
236
lib/src/ui/fruitvegidetail/fruit_veggie_detail.dart
Normal file
236
lib/src/ui/fruitvegidetail/fruit_veggie_detail.dart
Normal file
@@ -0,0 +1,236 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:grocery_app/src/common_widget/network_image.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/uicontext.dart';
|
||||
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
||||
|
||||
class FruitVeggieDetail extends StatefulWidget {
|
||||
const FruitVeggieDetail({super.key});
|
||||
|
||||
@override
|
||||
State<FruitVeggieDetail> createState() => _FruitVeggieDetailState();
|
||||
}
|
||||
|
||||
class _FruitVeggieDetailState extends State<FruitVeggieDetail> {
|
||||
int activeIndex = 0;
|
||||
|
||||
void changeActiveIndex(int currentActiveIndex) {
|
||||
activeIndex = currentActiveIndex;
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
@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: const Text(
|
||||
"Vegetables & Fruits",
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 10),
|
||||
child: InkWell(
|
||||
onTap: () {},
|
||||
child: Icon(
|
||||
MdiIcons.magnify,
|
||||
size: 35,
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
body: Row(
|
||||
children: [
|
||||
Container(
|
||||
decoration: const BoxDecoration(color: Colors.white),
|
||||
width: 100,
|
||||
child: ListView.builder(
|
||||
itemCount: 10,
|
||||
scrollDirection: Axis.vertical,
|
||||
itemBuilder: (context, index) {
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
changeActiveIndex(index);
|
||||
},
|
||||
child: SizedBox(
|
||||
height: 150,
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Center(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: activeIndex == index ? Colors.greenAccent.withOpacity(0.1) : APPCOLOR.bgGrey,
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
child: AppNetworkImage(
|
||||
height: 80,
|
||||
width: 80,
|
||||
imageUrl: 'https://i.pinimg.com/originals/a5/f3/5f/a5f35fb23e942809da3df91b23718e8d.png',
|
||||
backGroundColor: APPCOLOR.bgGrey,
|
||||
radius: 10,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: 3,
|
||||
height: 100,
|
||||
color: activeIndex == index ? APPCOLOR.lightGreen : Colors.transparent,
|
||||
)
|
||||
],
|
||||
),
|
||||
Text(
|
||||
"Fresh Vegitables",
|
||||
textAlign: TextAlign.center,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: activeIndex == index ? context.customExtraBold(APPCOLOR.balck1A1A1A, 14) : context.customMedium(APPCOLOR.balck1A1A1A, 14),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 10, right: 10),
|
||||
child: GridView.builder(
|
||||
itemCount: 20,
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 2, childAspectRatio: MediaQuery.of(context).size.width / (MediaQuery.of(context).size.height / 1.1), crossAxisSpacing: 10, mainAxisSpacing: 10),
|
||||
itemBuilder: (context, index) {
|
||||
return Container(
|
||||
height: 300,
|
||||
// width: 150,
|
||||
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(15), boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.grey.withOpacity(0.1),
|
||||
blurRadius: 1,
|
||||
offset: const Offset(5, 5),
|
||||
),
|
||||
]),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(5),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
height: 100,
|
||||
width: 150,
|
||||
decoration: BoxDecoration(color: APPCOLOR.bgGrey, borderRadius: BorderRadius.circular(15)),
|
||||
child: const Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
AppNetworkImage(
|
||||
height: 70,
|
||||
width: 70,
|
||||
imageUrl: "https://5.imimg.com/data5/SELLER/Default/2024/2/385126988/OL/DA/VW/8627346/1l-fortune-sunflower-oil.jpg",
|
||||
backGroundColor: Colors.transparent),
|
||||
Positioned(right: 5, top: 5, child: Icon(Icons.favorite_border))
|
||||
],
|
||||
),
|
||||
),
|
||||
Text(
|
||||
"Fortune Arhar Dal (Toor Dal)",
|
||||
textAlign: TextAlign.left,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: context.customMedium(APPCOLOR.balck1A1A1A, 14),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
Text(
|
||||
"500 ML",
|
||||
textAlign: TextAlign.left,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: context.customMedium(Colors.grey.withOpacity(0.8), 12),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 3,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
Text(
|
||||
"\$12",
|
||||
textAlign: TextAlign.left,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: context.customSemiBold(Colors.black, 12),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 5,
|
||||
),
|
||||
Text(
|
||||
"\$14",
|
||||
textAlign: TextAlign.left,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: context.customMedium(Colors.grey.withOpacity(0.8), 12).copyWith(
|
||||
decoration: TextDecoration.lineThrough,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Expanded(
|
||||
child: Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: Container(
|
||||
height: 40,
|
||||
width: 60,
|
||||
decoration: BoxDecoration(
|
||||
color: APPCOLOR.lightGreen,
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Add',
|
||||
style: context.customRegular(Colors.white, 12),
|
||||
)),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
))
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
401
lib/src/ui/home/home_screen.dart
Normal file
401
lib/src/ui/home/home_screen.dart
Normal file
@@ -0,0 +1,401 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:grocery_app/src/common_widget/network_image.dart';
|
||||
import 'package:grocery_app/src/ui/bestdeal/bestdeal_screen.dart';
|
||||
import 'package:grocery_app/src/ui/fruitvegidetail/fruit_veggie_detail.dart';
|
||||
import 'package:grocery_app/utils/constants/color_constant.dart';
|
||||
import 'package:grocery_app/utils/extensions/uicontext.dart';
|
||||
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
||||
|
||||
class HomeScreen extends StatefulWidget {
|
||||
const HomeScreen({super.key});
|
||||
|
||||
@override
|
||||
State<HomeScreen> createState() => _HomeScreenState();
|
||||
}
|
||||
|
||||
class _HomeScreenState extends State<HomeScreen> {
|
||||
@override
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SafeArea(
|
||||
child: Scaffold(
|
||||
body: Padding(
|
||||
padding: context.bodyAllPadding.copyWith(
|
||||
top: 0,
|
||||
),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Icon(
|
||||
MdiIcons.mapMarkerOutline,
|
||||
color: APPCOLOR.appGreen,
|
||||
size: 30,
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
"Home",
|
||||
style: context.customMedium(APPCOLOR.black333333, 18),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 5,
|
||||
),
|
||||
Icon(
|
||||
MdiIcons.chevronDown,
|
||||
color: APPCOLOR.black333333,
|
||||
size: 30,
|
||||
)
|
||||
],
|
||||
),
|
||||
Text(
|
||||
"639| Elgin St. Celina, Delaware 10299",
|
||||
style: context.customMedium(APPCOLOR.grey666666, 14),
|
||||
),
|
||||
],
|
||||
)),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Icon(
|
||||
MdiIcons.shoppingOutline,
|
||||
color: APPCOLOR.balck1A1A1A,
|
||||
size: 30,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Container(
|
||||
height: 50,
|
||||
decoration: BoxDecoration(
|
||||
color: APPCOLOR.bgGrey,
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
child: TextFormField(
|
||||
decoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
fillColor: Colors.transparent,
|
||||
prefixIcon: Icon(MdiIcons.magnify),
|
||||
hintText: 'Search',
|
||||
hintStyle: context.customRegular(APPCOLOR.grey666666, 18),
|
||||
isCollapsed: true,
|
||||
contentPadding: const EdgeInsets.symmetric(vertical: 10, horizontal: 10),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Container(
|
||||
height: 50,
|
||||
width: 50,
|
||||
decoration: BoxDecoration(
|
||||
color: APPCOLOR.lightGreen,
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
child: Center(
|
||||
child: Icon(
|
||||
MdiIcons.tuneVariant,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
"Shop By Category",
|
||||
style: context.customExtraBold(Colors.black, 18),
|
||||
),
|
||||
),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
Navigator.of(context).push(MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const FruitVeggieDetail();
|
||||
},
|
||||
));
|
||||
},
|
||||
child: Text(
|
||||
"See All",
|
||||
style: context.customMedium(APPCOLOR.lightGreen, 16),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
GridView.builder(
|
||||
shrinkWrap: true,
|
||||
itemCount: 8,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 4,
|
||||
crossAxisSpacing: 5,
|
||||
mainAxisSpacing: 5,
|
||||
childAspectRatio: MediaQuery.of(context).size.width / (MediaQuery.of(context).size.height / 1.2),
|
||||
),
|
||||
itemBuilder: (context, index) {
|
||||
return InkWell(
|
||||
onTap: () {},
|
||||
child: SizedBox(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: APPCOLOR.bgGrey,
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
child: AppNetworkImage(
|
||||
height: 80,
|
||||
width: 80,
|
||||
imageUrl: 'https://i.pinimg.com/originals/a5/f3/5f/a5f35fb23e942809da3df91b23718e8d.png',
|
||||
backGroundColor: APPCOLOR.bgGrey,
|
||||
radius: 10,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Text(
|
||||
"Vegitables and Fruits",
|
||||
textAlign: TextAlign.center,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: context.customMedium(APPCOLOR.balck1A1A1A, 14),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
Container(
|
||||
height: 180,
|
||||
decoration: BoxDecoration(color: Colors.greenAccent.withOpacity(0.1), borderRadius: BorderRadius.circular(15)),
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
top: 15,
|
||||
left: 15,
|
||||
child: SizedBox(
|
||||
width: 200,
|
||||
child: Text(
|
||||
"World Food Festival, Bring the world to your Kitchen!",
|
||||
style: context.customExtraBold(Colors.black, 18),
|
||||
))),
|
||||
Positioned(
|
||||
bottom: 15,
|
||||
left: 15,
|
||||
child: Container(
|
||||
height: 40,
|
||||
width: 100,
|
||||
decoration: BoxDecoration(
|
||||
color: APPCOLOR.lightGreen,
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Shop now',
|
||||
style: context.customRegular(Colors.white, 14),
|
||||
)),
|
||||
),
|
||||
),
|
||||
const Positioned(
|
||||
right: 15,
|
||||
bottom: 15,
|
||||
child: AppNetworkImage(
|
||||
height: 130,
|
||||
width: 150,
|
||||
imageUrl: 'https://e7.pngegg.com/pngimages/742/816/png-clipart-coca-cola-can-illustration-coca-cola-soft-drink-surge-pepsi-coke-sweetness-cola-thumbnail.png',
|
||||
backGroundColor: Colors.transparent))
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
"Best Deal",
|
||||
style: context.customExtraBold(Colors.black, 18),
|
||||
),
|
||||
),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
Navigator.of(context).push(MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const BestDealScreen();
|
||||
},
|
||||
));
|
||||
},
|
||||
child: Text(
|
||||
"See All",
|
||||
style: context.customMedium(APPCOLOR.lightGreen, 16),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
SizedBox(
|
||||
height: 222,
|
||||
child: ListView.builder(
|
||||
itemCount: 5,
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemBuilder: (context, index) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(right: 10, bottom: 5, top: 5),
|
||||
child: Container(
|
||||
height: 215,
|
||||
width: 150,
|
||||
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(15), boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.grey.withOpacity(0.1),
|
||||
blurRadius: 1,
|
||||
offset: const Offset(5, 5),
|
||||
),
|
||||
]),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(5),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
height: 100,
|
||||
width: 150,
|
||||
decoration: BoxDecoration(color: APPCOLOR.bgGrey, borderRadius: BorderRadius.circular(15)),
|
||||
child: const Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
AppNetworkImage(
|
||||
height: 70,
|
||||
width: 70,
|
||||
imageUrl: "https://5.imimg.com/data5/SELLER/Default/2024/2/385126988/OL/DA/VW/8627346/1l-fortune-sunflower-oil.jpg",
|
||||
backGroundColor: Colors.transparent),
|
||||
Positioned(right: 5, top: 5, child: Icon(Icons.favorite_border))
|
||||
],
|
||||
),
|
||||
),
|
||||
Text(
|
||||
"Fortune Arhar Dal (Toor Dal)",
|
||||
textAlign: TextAlign.left,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: context.customMedium(APPCOLOR.balck1A1A1A, 14),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
Text(
|
||||
"500 ML",
|
||||
textAlign: TextAlign.left,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: context.customMedium(Colors.grey.withOpacity(0.8), 12),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 3,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
"\$12",
|
||||
textAlign: TextAlign.left,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: context.customSemiBold(Colors.black, 12),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 5,
|
||||
),
|
||||
Text(
|
||||
"\$14",
|
||||
textAlign: TextAlign.left,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: context.customMedium(Colors.grey.withOpacity(0.8), 12).copyWith(
|
||||
decoration: TextDecoration.lineThrough,
|
||||
),
|
||||
),
|
||||
],
|
||||
)),
|
||||
Expanded(
|
||||
child: Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: Container(
|
||||
height: 30,
|
||||
width: 50,
|
||||
decoration: BoxDecoration(
|
||||
color: APPCOLOR.lightGreen,
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Add',
|
||||
style: context.customRegular(Colors.white, 12),
|
||||
)),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
// SizeConfig().init(context);
|
||||
super.initState();
|
||||
}
|
||||
}
|
||||
110
lib/src/ui/login/login_screen.dart
Normal file
110
lib/src/ui/login/login_screen.dart
Normal file
@@ -0,0 +1,110 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:grocery_app/src/common_widget/textfield_widget.dart';
|
||||
import 'package:grocery_app/src/ui/otp/otp_screen.dart';
|
||||
import 'package:grocery_app/utils/constants/color_constant.dart';
|
||||
import 'package:grocery_app/utils/constants/string_constant.dart';
|
||||
import 'package:grocery_app/utils/extensions/uicontext.dart';
|
||||
|
||||
class LoginScreen extends StatefulWidget {
|
||||
const LoginScreen({super.key});
|
||||
|
||||
@override
|
||||
State<LoginScreen> createState() => _LoginScreenState();
|
||||
}
|
||||
|
||||
class _LoginScreenState extends State<LoginScreen> {
|
||||
String? validatePhoneNumber(String? value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return 'Phone number cannot be empty';
|
||||
} else if (!RegExp(r'^\d{10}$').hasMatch(value)) {
|
||||
return 'Enter a valid 10-digit phone number';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Container(
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
height: MediaQuery.sizeOf(context).height,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.greenAccent.withOpacity(0.1),
|
||||
),
|
||||
child: Padding(
|
||||
padding: context.bodyAllPadding,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(height: 30),
|
||||
Text(
|
||||
APPSTRING.enterYourMobileNumber,
|
||||
style: context.customMedium(APPCOLOR.balck1A1A1A, 18),
|
||||
),
|
||||
const SizedBox(height: 40),
|
||||
Text(
|
||||
APPSTRING.whatYourPhoneNumber,
|
||||
style: context.customMedium(APPCOLOR.black333333, 18),
|
||||
),
|
||||
SizedBox(
|
||||
width: 200,
|
||||
child: Text(
|
||||
APPSTRING.codeSentText,
|
||||
style: context.customMedium(APPCOLOR.grey666666, 14),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 40),
|
||||
Form(
|
||||
key: _formKey,
|
||||
child: AppTextFieldWidget(
|
||||
length: 10,
|
||||
controller: TextEditingController(),
|
||||
hintText: APPSTRING.phoneNumberHint,
|
||||
onValidate: (value) => validatePhoneNumber(value),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
bottomNavigationBar: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.greenAccent.withOpacity(0.1),
|
||||
),
|
||||
height: 100,
|
||||
child: Padding(
|
||||
padding: context.bodyAllPadding.copyWith(bottom: 20),
|
||||
child: Center(
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
print("djkhfjdgf ${_formKey.currentState?.validate()}");
|
||||
if (_formKey.currentState?.validate() ?? false) {
|
||||
Navigator.of(context).push(MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const OtpScreen();
|
||||
},
|
||||
));
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
height: 50,
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
decoration: BoxDecoration(
|
||||
color: APPCOLOR.appGreen,
|
||||
borderRadius: BorderRadius.circular(4)),
|
||||
child: Center(
|
||||
child: Text(
|
||||
APPSTRING.verifyButton,
|
||||
style: context.customMedium(Colors.white, 16),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
176
lib/src/ui/mapscreen/map_screen.dart
Normal file
176
lib/src/ui/mapscreen/map_screen.dart
Normal file
@@ -0,0 +1,176 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.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/uicontext.dart';
|
||||
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
||||
|
||||
class MapScreen extends StatefulWidget {
|
||||
const MapScreen({super.key});
|
||||
|
||||
@override
|
||||
State<MapScreen> createState() => _MapScreenState();
|
||||
}
|
||||
|
||||
class _MapScreenState extends State<MapScreen> {
|
||||
final cSearch = TextEditingController();
|
||||
|
||||
@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: const Text(
|
||||
"Confirm Delivery Location",
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
),
|
||||
body: Stack(
|
||||
children: [
|
||||
Container(
|
||||
color: Colors.grey.withOpacity(0.4),
|
||||
child: const Center(
|
||||
child: Text("Map"),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
top: 15,
|
||||
left: 15,
|
||||
right: 15,
|
||||
child: Container(
|
||||
height: 50,
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
child: TextFormField(
|
||||
controller: cSearch,
|
||||
onChanged: (c) {
|
||||
setState(() {});
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
fillColor: Colors.transparent,
|
||||
prefixIcon: Icon(MdiIcons.magnify),
|
||||
hintText: 'Search',
|
||||
hintStyle: context.customRegular(APPCOLOR.grey666666, 18),
|
||||
isCollapsed: true,
|
||||
contentPadding: const EdgeInsets.symmetric(vertical: 12, horizontal: 10),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
floatingActionButton: Padding(
|
||||
padding: const EdgeInsets.only(bottom: 80),
|
||||
child: FloatingActionButton(
|
||||
backgroundColor: Colors.transparent,
|
||||
elevation: 0,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: APPCOLOR.lightGreen,
|
||||
),
|
||||
child: Center(
|
||||
child: Icon(
|
||||
MdiIcons.crosshairsGps,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
onPressed: () {},
|
||||
),
|
||||
),
|
||||
bottomSheet: Container(
|
||||
height: 205,
|
||||
decoration: const BoxDecoration(color: Colors.white, borderRadius: BorderRadius.only(topLeft: Radius.circular(15), topRight: Radius.circular(15))),
|
||||
width: MediaQuery.of(context).size.width,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(15),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
height: 2,
|
||||
width: 50,
|
||||
color: Colors.grey.withOpacity(0.5),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
Text(
|
||||
"Select Location",
|
||||
style: context.customExtraBold(Colors.black, 18),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
const Text("4517 wasington Ave, wasington, Manchester, Kettucy, 369525"),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
Navigator.of(context).push(MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const MapScreen();
|
||||
},
|
||||
));
|
||||
},
|
||||
child: Container(
|
||||
height: 50,
|
||||
decoration: BoxDecoration(color: APPCOLOR.lightGreen, borderRadius: BorderRadius.circular(10)),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.add,
|
||||
color: Colors.white,
|
||||
),
|
||||
Text(
|
||||
"Add New Address",
|
||||
style: context.customMedium(Colors.white, 16),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
)),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
157
lib/src/ui/message/message_screen.dart
Normal file
157
lib/src/ui/message/message_screen.dart
Normal file
@@ -0,0 +1,157 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.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/uicontext.dart';
|
||||
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
||||
|
||||
class MessageScreen extends StatefulWidget {
|
||||
const MessageScreen({super.key});
|
||||
|
||||
@override
|
||||
State<MessageScreen> createState() => _MessageScreenState();
|
||||
}
|
||||
|
||||
class _MessageScreenState extends State<MessageScreen> {
|
||||
List<ChatMessage> messages = [
|
||||
ChatMessage(messageContent: "Hello, Will", messageType: "receiver"),
|
||||
ChatMessage(messageContent: "How have you been?", messageType: "receiver"),
|
||||
ChatMessage(messageContent: "Hey Kriss, I am doing fine dude. wbu?", messageType: "sender"),
|
||||
ChatMessage(messageContent: "ehhhh, doing OK.", messageType: "receiver"),
|
||||
ChatMessage(messageContent: "Is there any thing wrong?", messageType: "sender"),
|
||||
];
|
||||
@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: const Text(
|
||||
"Message",
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
),
|
||||
body: Padding(
|
||||
padding: context.bodyAllPadding.copyWith(left: 0, bottom: 0, right: 0, top: 0),
|
||||
child: Stack(
|
||||
children: <Widget>[
|
||||
ListView.builder(
|
||||
itemCount: messages.length,
|
||||
shrinkWrap: true,
|
||||
padding: const EdgeInsets.only(top: 10, bottom: 10),
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemBuilder: (context, index) {
|
||||
return Column(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.only(left: 14, right: 14, top: 10, bottom: 10),
|
||||
child: Align(
|
||||
alignment: (messages[index].messageType == "receiver" ? Alignment.topLeft : Alignment.topRight),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: messages[index].messageType == "receiver"
|
||||
? const BorderRadius.only(topLeft: Radius.circular(10), bottomLeft: Radius.circular(0), bottomRight: Radius.circular(10), topRight: Radius.circular(10))
|
||||
: const BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(0), bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10)),
|
||||
color: (messages[index].messageType == "receiver" ? Colors.grey.shade200 : APPCOLOR.lightGreen),
|
||||
),
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Text(
|
||||
messages[index].messageContent,
|
||||
style: TextStyle(fontSize: 15, color: messages[index].messageType == "receiver" ? Colors.black : Colors.white),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
messages[index].messageType == "receiver"
|
||||
? Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 15),
|
||||
child: Text(
|
||||
"12:33 AM",
|
||||
style: context.customMedium(Colors.grey.withOpacity(0.6), 12),
|
||||
),
|
||||
),
|
||||
)
|
||||
: Align(
|
||||
alignment: Alignment.topRight,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(right: 15),
|
||||
child: Text(
|
||||
"12:33 AM",
|
||||
style: context.customMedium(Colors.grey.withOpacity(0.6), 12),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.bottomLeft,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.only(left: 10, bottom: 10, top: 10, right: 10),
|
||||
height: 70,
|
||||
width: double.infinity,
|
||||
color: Colors.white,
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: TextFormField(
|
||||
decoration: InputDecoration(
|
||||
prefixIcon: Icon(MdiIcons.cameraOutline),
|
||||
hintText: "Type Something...",
|
||||
hintStyle: TextStyle(color: Colors.grey.withOpacity(0.5)),
|
||||
border: InputBorder.none,
|
||||
isCollapsed: true,
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 10, vertical: 15)),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 15,
|
||||
),
|
||||
Container(
|
||||
height: 50,
|
||||
width: 50,
|
||||
decoration: BoxDecoration(color: APPCOLOR.lightGreen, borderRadius: BorderRadius.circular(10)),
|
||||
child: const Center(
|
||||
child: Icon(
|
||||
Icons.send,
|
||||
color: Colors.white,
|
||||
size: 18,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ChatMessage {
|
||||
String messageContent;
|
||||
String messageType;
|
||||
ChatMessage({required this.messageContent, required this.messageType});
|
||||
}
|
||||
140
lib/src/ui/notification/notification_screen.dart
Normal file
140
lib/src/ui/notification/notification_screen.dart
Normal file
@@ -0,0 +1,140 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.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/uicontext.dart';
|
||||
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
||||
|
||||
class NotificationScreen extends StatefulWidget {
|
||||
const NotificationScreen({super.key});
|
||||
|
||||
@override
|
||||
State<NotificationScreen> createState() => _NotificationState();
|
||||
}
|
||||
|
||||
class _NotificationState extends State<NotificationScreen> {
|
||||
final notificationList = [
|
||||
NotificationModel("Today", [
|
||||
{"title": "30% Special Discount!", "subtitle": "Special promotion only valid today", "icon": MdiIcons.percentCircleOutline},
|
||||
{"title": "Password Update Successfull", "subtitle": "Your password update successfully", "icon": MdiIcons.lockOutline},
|
||||
]),
|
||||
NotificationModel("Yesterday", [
|
||||
{"title": "Account Setup Successful", "subtitle": "Your account has been created", "icon": Icons.person_outline},
|
||||
{"title": "Redeem your gift cart", "subtitle": "You have get one gift card", "icon": MdiIcons.gift},
|
||||
])
|
||||
];
|
||||
|
||||
@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: const Text(
|
||||
"Notifications",
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
),
|
||||
body: Padding(
|
||||
padding: context.bodyAllPadding,
|
||||
child: ListView.builder(
|
||||
itemCount: notificationList.length,
|
||||
itemBuilder: (context, index) {
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
notificationList[index].title,
|
||||
style: context.customExtraBold(Colors.black, 20),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
ListView.builder(
|
||||
itemCount: notificationList[index].notification.length,
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemBuilder: (context, index2) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: 10),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(15)),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(10),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
height: 60,
|
||||
width: 60,
|
||||
decoration: BoxDecoration(
|
||||
color: APPCOLOR.lightGreen,
|
||||
borderRadius: BorderRadius.circular(90),
|
||||
),
|
||||
child: Center(
|
||||
child: Icon(
|
||||
notificationList[index].notification[index2]['icon'],
|
||||
color: Colors.white,
|
||||
size: 30,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 15,
|
||||
),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
notificationList[index].notification[index2]['title'],
|
||||
style: context.customExtraBold(Colors.black, 18),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
Text(
|
||||
notificationList[index].notification[index2]['subtitle'],
|
||||
style: context.customMedium(Colors.grey.withOpacity(0.7), 14),
|
||||
),
|
||||
],
|
||||
))
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
)
|
||||
],
|
||||
);
|
||||
},
|
||||
)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class NotificationModel {
|
||||
String title;
|
||||
List<Map<String, dynamic>> notification;
|
||||
|
||||
NotificationModel(this.title, this.notification);
|
||||
}
|
||||
506
lib/src/ui/onboarding/on_boarding_screen.dart
Normal file
506
lib/src/ui/onboarding/on_boarding_screen.dart
Normal file
@@ -0,0 +1,506 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:grocery_app/src/core/routes/routes.dart';
|
||||
import 'package:grocery_app/src/ui/login/login_screen.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';
|
||||
import 'package:grocery_app/utils/extensions/extensions.dart';
|
||||
import 'package:grocery_app/utils/extensions/uicontext.dart';
|
||||
|
||||
class OnBoardingScreen extends StatefulWidget {
|
||||
const OnBoardingScreen({super.key});
|
||||
|
||||
@override
|
||||
State<OnBoardingScreen> createState() => _OnBoardingScreenState();
|
||||
}
|
||||
|
||||
class _OnBoardingScreenState extends State<OnBoardingScreen> {
|
||||
late PageController _pageController;
|
||||
int currentIndex = 0;
|
||||
|
||||
static const _kDuration = Duration(milliseconds: 300);
|
||||
static const _kCurve = Curves.ease;
|
||||
|
||||
nextFunction() {
|
||||
_pageController.nextPage(duration: _kDuration, curve: _kCurve);
|
||||
}
|
||||
|
||||
skipFunction()
|
||||
{
|
||||
SharedPrefUtils.setFreshInstall(isFresh: false).then(
|
||||
(value) => context.clearAndPush(routePath: MyRoutes.LOGIN, args: 0),
|
||||
);
|
||||
|
||||
// Navigator.pushReplacement(context, MaterialPageRoute(
|
||||
// builder: (context) {
|
||||
// return const LoginScreen();
|
||||
// },
|
||||
// ));
|
||||
}
|
||||
|
||||
onChangedFunction(int index) {
|
||||
setState(() {
|
||||
currentIndex = index;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_pageController = PageController();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_pageController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
extendBody: true,
|
||||
extendBodyBehindAppBar: true,
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.transparent,
|
||||
toolbarHeight: 20,
|
||||
),
|
||||
body: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.greenAccent.withOpacity(0.2),
|
||||
),
|
||||
child: Stack(
|
||||
children: <Widget>[
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(15).copyWith(top: 40),
|
||||
child: PageView(
|
||||
controller: _pageController,
|
||||
onPageChanged: onChangedFunction,
|
||||
children: <Widget>[
|
||||
Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
top: 10,
|
||||
right: 0,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
print("djfhgk");
|
||||
skipFunction();
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
Text(
|
||||
"Skip",
|
||||
style:
|
||||
context.customMedium(APPCOLOR.appGreen, 14),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Container(
|
||||
height: 35,
|
||||
width: 35,
|
||||
decoration: BoxDecoration(
|
||||
color: APPCOLOR.appGreen,
|
||||
borderRadius: BorderRadius.circular(90)),
|
||||
child: const Center(
|
||||
child: Icon(
|
||||
Icons.arrow_forward,
|
||||
color: Colors.white,
|
||||
size: 15,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Image.asset(APPASSETS.onBoardMan),
|
||||
Positioned(
|
||||
bottom: 100,
|
||||
right: 0,
|
||||
left: 0,
|
||||
child: Container(
|
||||
// height: 100,
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
color: Colors.white),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
children: [
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Indicator(
|
||||
positionIndex: 0,
|
||||
currentIndex: currentIndex,
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Indicator(
|
||||
positionIndex: 1,
|
||||
currentIndex: currentIndex,
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Indicator(
|
||||
positionIndex: 2,
|
||||
currentIndex: currentIndex,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
SizedBox(
|
||||
width: 250,
|
||||
child: Text(
|
||||
"Buy Groceries Easily with US",
|
||||
textAlign: TextAlign.center,
|
||||
style: context.customExtraBold(
|
||||
Colors.black, 22),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
Text(
|
||||
"It is a long established fact that a reader will be distracted by the readable",
|
||||
textAlign: TextAlign.center,
|
||||
style:
|
||||
context.customRegular(Colors.black, 16),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
bottom: 60,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: Center(
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
nextFunction();
|
||||
},
|
||||
child: Container(
|
||||
height: 70,
|
||||
width: 70,
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
color: Colors.white,
|
||||
width: 10,
|
||||
style: BorderStyle.solid,
|
||||
),
|
||||
color: APPCOLOR.appGreen,
|
||||
borderRadius: BorderRadius.circular(90),
|
||||
),
|
||||
child: const Center(
|
||||
child: Icon(
|
||||
Icons.arrow_forward,
|
||||
color: Colors.white,
|
||||
size: 20,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
top: 10,
|
||||
right: 0,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
skipFunction();
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
Text(
|
||||
"Skip",
|
||||
style:
|
||||
context.customMedium(APPCOLOR.appGreen, 14),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Container(
|
||||
height: 35,
|
||||
width: 35,
|
||||
decoration: BoxDecoration(
|
||||
color: APPCOLOR.appGreen,
|
||||
borderRadius: BorderRadius.circular(90)),
|
||||
child: const Center(
|
||||
child: Icon(
|
||||
Icons.arrow_forward,
|
||||
color: Colors.white,
|
||||
size: 15,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Image.asset(APPASSETS.onBoardMan),
|
||||
Positioned(
|
||||
bottom: 100,
|
||||
right: 0,
|
||||
left: 0,
|
||||
child: Container(
|
||||
// height: 100,
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
color: Colors.white),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
children: [
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Indicator(
|
||||
positionIndex: 0,
|
||||
currentIndex: currentIndex,
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Indicator(
|
||||
positionIndex: 1,
|
||||
currentIndex: currentIndex,
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Indicator(
|
||||
positionIndex: 2,
|
||||
currentIndex: currentIndex,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
SizedBox(
|
||||
width: 250,
|
||||
child: Text(
|
||||
"We Delivery Grocery at Your Doorstep",
|
||||
textAlign: TextAlign.center,
|
||||
style: context.customExtraBold(
|
||||
Colors.black, 22),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
Text(
|
||||
"It is a long established fact that a reader will be distracted by the readable",
|
||||
textAlign: TextAlign.center,
|
||||
style:
|
||||
context.customRegular(Colors.black, 16),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
bottom: 60,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: Center(
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
nextFunction();
|
||||
},
|
||||
child: Container(
|
||||
height: 70,
|
||||
width: 70,
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
color: Colors.white,
|
||||
width: 10,
|
||||
style: BorderStyle.solid,
|
||||
),
|
||||
color: APPCOLOR.appGreen,
|
||||
borderRadius: BorderRadius.circular(90),
|
||||
),
|
||||
child: const Center(
|
||||
child: Icon(
|
||||
Icons.arrow_forward,
|
||||
color: Colors.white,
|
||||
size: 20,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
Stack(
|
||||
children: [
|
||||
const SizedBox(
|
||||
height: 50,
|
||||
),
|
||||
Image.asset(APPASSETS.onBoardMan),
|
||||
Positioned(
|
||||
bottom: 100,
|
||||
right: 0,
|
||||
left: 0,
|
||||
child: Container(
|
||||
// height: 100,
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
color: Colors.white),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
children: [
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Indicator(
|
||||
positionIndex: 0,
|
||||
currentIndex: currentIndex,
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Indicator(
|
||||
positionIndex: 1,
|
||||
currentIndex: currentIndex,
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Indicator(
|
||||
positionIndex: 2,
|
||||
currentIndex: currentIndex,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
SizedBox(
|
||||
width: 250,
|
||||
child: Text(
|
||||
"All Your Kitchen Needs are Here",
|
||||
textAlign: TextAlign.center,
|
||||
style: context.customExtraBold(
|
||||
Colors.black, 22),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
Text(
|
||||
"It is a long established fact that a reader will be distracted by the readable",
|
||||
textAlign: TextAlign.center,
|
||||
style:
|
||||
context.customRegular(Colors.black, 16),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
bottom: 60,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: Center(
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
skipFunction();
|
||||
},
|
||||
child: Container(
|
||||
height: 70,
|
||||
width: 70,
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
color: Colors.white,
|
||||
width: 10,
|
||||
style: BorderStyle.solid,
|
||||
),
|
||||
color: APPCOLOR.appGreen,
|
||||
borderRadius: BorderRadius.circular(90),
|
||||
),
|
||||
child: const Center(
|
||||
child: Icon(
|
||||
Icons.arrow_forward,
|
||||
color: Colors.white,
|
||||
size: 20,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class Indicator extends StatelessWidget {
|
||||
final int positionIndex, currentIndex;
|
||||
const Indicator(
|
||||
{super.key, required this.currentIndex, required this.positionIndex});
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
height: 10,
|
||||
width: 10,
|
||||
decoration: BoxDecoration(
|
||||
color: positionIndex == currentIndex
|
||||
? APPCOLOR.appGreen
|
||||
: Colors.grey.withOpacity(0.2),
|
||||
borderRadius: BorderRadius.circular(100)),
|
||||
);
|
||||
}
|
||||
}
|
||||
94
lib/src/ui/otp/otp_screen.dart
Normal file
94
lib/src/ui/otp/otp_screen.dart
Normal file
@@ -0,0 +1,94 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:grocery_app/src/ui/entername/enter_fullname_screen.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/string_constant.dart';
|
||||
import 'package:grocery_app/utils/extensions/color_ex.dart';
|
||||
import 'package:grocery_app/utils/extensions/uicontext.dart';
|
||||
import 'package:otp_text_field/otp_text_field.dart';
|
||||
import 'package:otp_text_field/style.dart';
|
||||
|
||||
class OtpScreen extends StatefulWidget {
|
||||
const OtpScreen({super.key});
|
||||
|
||||
@override
|
||||
State<OtpScreen> createState() => _OtpScreenState();
|
||||
}
|
||||
|
||||
class _OtpScreenState extends State<OtpScreen> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Container(
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
height: MediaQuery.sizeOf(context).height,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.greenAccent.withOpacity(0.1),
|
||||
),
|
||||
child: Padding(
|
||||
padding: context.bodyAllPadding,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(height: 30),
|
||||
InkWell(
|
||||
onTap: ()
|
||||
{
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: SvgPicture.asset(APPASSETS.back)),
|
||||
const SizedBox(height: 30),
|
||||
Text(
|
||||
APPSTRING.enterVerificationCode,
|
||||
style: context.customMedium(APPCOLOR.black333333, 18),
|
||||
),
|
||||
SizedBox(
|
||||
width: 300,
|
||||
child: Text(
|
||||
APPSTRING.enterCode,
|
||||
style: context.customRegular(APPCOLOR.grey666666, 16),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
OTPTextField(
|
||||
length: 6,
|
||||
onChanged: (c)
|
||||
{
|
||||
if (c.length == 6)
|
||||
{
|
||||
Navigator.push(context, MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const EnterFullNameScreen();
|
||||
},
|
||||
));
|
||||
}
|
||||
},
|
||||
width: MediaQuery.of(context).size.width,
|
||||
fieldWidth: 50,
|
||||
otpFieldStyle: OtpFieldStyle(
|
||||
backgroundColor: HexColor('F4F5F5'),
|
||||
),
|
||||
style: const TextStyle(fontSize: 17),
|
||||
textFieldAlignment: MainAxisAlignment.spaceBetween,
|
||||
fieldStyle: FieldStyle.box,
|
||||
onCompleted: (pin) {},
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
RichText(
|
||||
text: TextSpan(text: 'Didn’t get the code? ', style: context.customRegular(APPCOLOR.gery48514D, 14), children: [
|
||||
TextSpan(
|
||||
text: 'Resend',
|
||||
style: context.customRegular(APPCOLOR.appGreen, 14),
|
||||
)
|
||||
]))
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
269
lib/src/ui/profilepage/profile_screen.dart
Normal file
269
lib/src/ui/profilepage/profile_screen.dart
Normal file
@@ -0,0 +1,269 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:grocery_app/src/common_widget/network_image.dart';
|
||||
import 'package:grocery_app/src/ui/card_checkout/card_checkout_screen.dart';
|
||||
import 'package:grocery_app/src/ui/edit_profile/edit_profile_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/utils/constants/color_constant.dart';
|
||||
import 'package:grocery_app/utils/extensions/uicontext.dart';
|
||||
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
||||
|
||||
class ProfileScreen extends StatefulWidget {
|
||||
const ProfileScreen({super.key});
|
||||
|
||||
@override
|
||||
State<ProfileScreen> createState() => _ProfileScreenState();
|
||||
}
|
||||
|
||||
class _ProfileScreenState extends State<ProfileScreen> {
|
||||
var top = 0.0;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: NestedScrollView(
|
||||
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
|
||||
return <Widget>[
|
||||
SliverAppBar(
|
||||
expandedHeight: 180.0,
|
||||
floating: false,
|
||||
pinned: true,
|
||||
backgroundColor: Colors.white,
|
||||
leading: const SizedBox(),
|
||||
flexibleSpace: LayoutBuilder(builder: (BuildContext context, BoxConstraints constraints) {
|
||||
top = constraints.biggest.height;
|
||||
|
||||
return FlexibleSpaceBar(
|
||||
centerTitle: true,
|
||||
title: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
top > 100
|
||||
? Text(
|
||||
"My Profile",
|
||||
style: context.customExtraBold(Colors.white, 14),
|
||||
)
|
||||
: const SizedBox(),
|
||||
|
||||
const SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
//Spacer(),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
const SizedBox(
|
||||
width: 15,
|
||||
),
|
||||
Stack(
|
||||
children: [
|
||||
AppNetworkImage(
|
||||
height: top < 150 ? 30 : 50,
|
||||
width: top < 150 ? 30 : 50,
|
||||
imageUrl: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTdQLwDqDwd2JfzifvfBTFT8I7iKFFevcedYg&s",
|
||||
radius: 90,
|
||||
backGroundColor: Colors.white,
|
||||
boxFit: BoxFit.fill,
|
||||
),
|
||||
top > 100
|
||||
? Positioned(
|
||||
bottom: 0,
|
||||
right: 0,
|
||||
child: Container(
|
||||
height: 18,
|
||||
width: 18,
|
||||
decoration: BoxDecoration(color: APPCOLOR.lightGreen, border: Border.all(color: Colors.white), borderRadius: BorderRadius.circular(5)),
|
||||
child: Center(
|
||||
child: Icon(
|
||||
MdiIcons.pencil,
|
||||
size: 10,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
))
|
||||
: const SizedBox(),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
width: 15,
|
||||
),
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
"Smith Mate",
|
||||
style: context.customExtraBold(top < 100 ? Colors.black : Colors.white, 14),
|
||||
),
|
||||
Text(
|
||||
'smithmate@example.com',
|
||||
style: context.customRegular(top < 100 ? Colors.black : Colors.white, 10),
|
||||
)
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
width: 15,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
background: Container(
|
||||
height: 200,
|
||||
decoration: BoxDecoration(color: APPCOLOR.lightGreen, borderRadius: const BorderRadius.only(bottomLeft: Radius.circular(30), bottomRight: Radius.circular(30))),
|
||||
));
|
||||
}),
|
||||
),
|
||||
];
|
||||
},
|
||||
body: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
ListTile(
|
||||
onTap: () {
|
||||
Navigator.of(context).push(MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const EditProfileScreen();
|
||||
},
|
||||
));
|
||||
},
|
||||
leading: Icon(MdiIcons.pencilBoxOutline),
|
||||
title: const Text('Edit Profile'),
|
||||
trailing: Icon(MdiIcons.chevronRight),
|
||||
),
|
||||
ListTile(
|
||||
leading: Icon(MdiIcons.lockOutline),
|
||||
title: const Text('Change Password'),
|
||||
trailing: Icon(MdiIcons.chevronRight),
|
||||
),
|
||||
ListTile(
|
||||
onTap: () {
|
||||
Navigator.of(context).push(MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const CardCheckoutScreen();
|
||||
},
|
||||
));
|
||||
},
|
||||
leading: Icon(MdiIcons.cardOutline),
|
||||
title: const Text('Payment Method'),
|
||||
trailing: Icon(MdiIcons.chevronRight),
|
||||
),
|
||||
ListTile(
|
||||
onTap: () {},
|
||||
leading: Icon(MdiIcons.cubeOutline),
|
||||
title: const Text('My Order'),
|
||||
trailing: Icon(MdiIcons.chevronRight),
|
||||
),
|
||||
ListTile(
|
||||
onTap: () {
|
||||
Navigator.of(context).push(MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const NotificationScreen();
|
||||
},
|
||||
));
|
||||
},
|
||||
leading: Icon(MdiIcons.bellOutline),
|
||||
title: const Text('Notifications'),
|
||||
trailing: Icon(MdiIcons.chevronRight),
|
||||
),
|
||||
ListTile(
|
||||
onTap: () {
|
||||
Navigator.of(context).push(MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const RatingReviewScreen();
|
||||
},
|
||||
));
|
||||
},
|
||||
leading: Icon(MdiIcons.starOutline),
|
||||
title: const Text('Rating & Review'),
|
||||
trailing: Icon(MdiIcons.chevronRight),
|
||||
),
|
||||
ListTile(
|
||||
onTap: () {
|
||||
Navigator.of(context).push(MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const MessageScreen();
|
||||
},
|
||||
));
|
||||
},
|
||||
leading: Icon(MdiIcons.messageOutline),
|
||||
title: const Text('Driver Message'),
|
||||
trailing: Icon(MdiIcons.chevronRight),
|
||||
),
|
||||
ListTile(
|
||||
onTap: () {
|
||||
Navigator.of(context).push(MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const StaticPage(
|
||||
title: "Privacy Policy",
|
||||
);
|
||||
},
|
||||
));
|
||||
},
|
||||
leading: Icon(MdiIcons.shieldCheckOutline),
|
||||
title: const Text('Privacy Policy'),
|
||||
trailing: Icon(MdiIcons.chevronRight),
|
||||
),
|
||||
ListTile(
|
||||
onTap: () {
|
||||
Navigator.of(context).push(MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const StaticPage(
|
||||
title: "Terms & Conditions",
|
||||
);
|
||||
},
|
||||
));
|
||||
},
|
||||
leading: Icon(MdiIcons.noteTextOutline),
|
||||
title: const Text('Term & Conditions'),
|
||||
trailing: Icon(MdiIcons.chevronRight),
|
||||
),
|
||||
ListTile(
|
||||
onTap: () {},
|
||||
leading: Icon(MdiIcons.basketOutline),
|
||||
title: const Text('Grocery List'),
|
||||
trailing: Icon(MdiIcons.chevronRight),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
margin: const EdgeInsets.only(left: 15, right: 15, top: 10, bottom: 10),
|
||||
height: 50,
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
decoration: BoxDecoration(color: APPCOLOR.lightGreen, borderRadius: BorderRadius.circular(10)),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Icon(
|
||||
MdiIcons.logout,
|
||||
color: Colors.white,
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Text(
|
||||
"Logout",
|
||||
style: context.customMedium(Colors.white, 16),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
244
lib/src/ui/rating_review/rating_review_screen.dart
Normal file
244
lib/src/ui/rating_review/rating_review_screen.dart
Normal file
@@ -0,0 +1,244 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:grocery_app/src/common_widget/network_image.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/uicontext.dart';
|
||||
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
||||
|
||||
class RatingReviewScreen extends StatefulWidget {
|
||||
const RatingReviewScreen({super.key});
|
||||
|
||||
@override
|
||||
State<RatingReviewScreen> createState() => _RatingReviewScreenState();
|
||||
}
|
||||
|
||||
class _RatingReviewScreenState extends State<RatingReviewScreen> {
|
||||
@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: const Text(
|
||||
"Rider Review",
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
),
|
||||
bottomNavigationBar: Container(
|
||||
color: Colors.transparent,
|
||||
height: 60,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(bottom: 10),
|
||||
child: Row(
|
||||
children: [
|
||||
const SizedBox(
|
||||
width: 15,
|
||||
),
|
||||
Expanded(
|
||||
child: InkWell(
|
||||
onTap: () {},
|
||||
child: Container(
|
||||
height: 50,
|
||||
decoration: BoxDecoration(color: APPCOLOR.lightGreen, borderRadius: BorderRadius.circular(10)),
|
||||
child: Center(
|
||||
child: Text(
|
||||
"Submit",
|
||||
style: context.customRegular(Colors.white, 16),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 15,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
body: Padding(
|
||||
padding: context.bodyAllPadding,
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
const Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
AppNetworkImage(
|
||||
height: 100,
|
||||
width: 100,
|
||||
imageUrl: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTdQLwDqDwd2JfzifvfBTFT8I7iKFFevcedYg&s",
|
||||
backGroundColor: Colors.white,
|
||||
boxFit: BoxFit.cover,
|
||||
radius: 10,
|
||||
)
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
Text(
|
||||
"Make Johnson",
|
||||
style: context.customExtraBold(Colors.black, 18),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
Text(
|
||||
"Delivery Boy",
|
||||
style: context.customMedium(Colors.grey.withOpacity(0.9), 14),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
Text(
|
||||
"Please Rate Delivery Service",
|
||||
style: context.customMedium(Colors.black, 18),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(
|
||||
MdiIcons.star,
|
||||
color: APPCOLOR.lightGreen,
|
||||
size: 40,
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Icon(
|
||||
MdiIcons.star,
|
||||
color: APPCOLOR.lightGreen,
|
||||
size: 40,
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Icon(
|
||||
MdiIcons.star,
|
||||
color: APPCOLOR.lightGreen,
|
||||
size: 40,
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Icon(
|
||||
MdiIcons.star,
|
||||
color: APPCOLOR.lightGreen,
|
||||
size: 40,
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Icon(
|
||||
MdiIcons.star,
|
||||
color: APPCOLOR.lightGreen,
|
||||
size: 40,
|
||||
)
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 25,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Add Tips",
|
||||
style: context.customMedium(Colors.black, 18),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Text(
|
||||
"No Tips",
|
||||
style: context.customMedium(Colors.black, 14),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 15,
|
||||
),
|
||||
Container(
|
||||
height: 35,
|
||||
width: 35,
|
||||
decoration: BoxDecoration(color: APPCOLOR.lightGreen, borderRadius: BorderRadius.circular(5)),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'\$2',
|
||||
style: context.customRegular(Colors.white, 12),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 15,
|
||||
),
|
||||
Text(
|
||||
'\$5',
|
||||
style: context.customRegular(Colors.black, 12),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 15,
|
||||
),
|
||||
Text(
|
||||
'\$10',
|
||||
style: context.customRegular(Colors.black, 12),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 15,
|
||||
),
|
||||
Text(
|
||||
'\$20',
|
||||
style: context.customRegular(Colors.black, 12),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
TextFormField(
|
||||
minLines: 5,
|
||||
maxLines: 6,
|
||||
decoration: InputDecoration(
|
||||
hintText: "Add a comment",
|
||||
hintStyle: context.customRegular(Colors.grey.withOpacity(0.8), 16),
|
||||
border: OutlineInputBorder(borderSide: BorderSide(color: Colors.grey.withOpacity(0.2))),
|
||||
disabledBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.grey.withOpacity(0.2))),
|
||||
enabledBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.grey.withOpacity(0.2))),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
47
lib/src/ui/splash/splash_screen.dart
Normal file
47
lib/src/ui/splash/splash_screen.dart
Normal file
@@ -0,0 +1,47 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:grocery_app/src/core/routes/routes.dart';
|
||||
import 'package:grocery_app/src/ui/onboarding/on_boarding_screen.dart';
|
||||
import 'package:grocery_app/utils/constants/assets_constant.dart';
|
||||
import 'package:grocery_app/utils/extensions/extensions.dart';
|
||||
import 'package:grocery_app/utils/extensions/uicontext.dart';
|
||||
|
||||
class SplashScreen extends StatefulWidget {
|
||||
const SplashScreen({super.key});
|
||||
|
||||
@override
|
||||
State<SplashScreen> createState() => _SplashScreenState();
|
||||
}
|
||||
|
||||
class _SplashScreenState extends State<SplashScreen> {
|
||||
couting() async {
|
||||
Future.delayed(const Duration(seconds: 3)).then((c) {
|
||||
Navigator.of(context).pushReplacement(MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const OnBoardingScreen();
|
||||
},
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
// couting();
|
||||
|
||||
Future.delayed(const Duration(seconds: 2), () async {
|
||||
context.clearAndPush(routePath: MyRoutes.ONBOARDING);
|
||||
});
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
height: context.screenHeight(),
|
||||
width: context.screenWidth(),
|
||||
child: Image.asset(
|
||||
APPASSETS.splashImagePNG,
|
||||
fit: BoxFit.fill,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
44
lib/src/ui/static_page/static_page_screen.dart
Normal file
44
lib/src/ui/static_page/static_page_screen.dart
Normal file
@@ -0,0 +1,44 @@
|
||||
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,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
11
lib/utils/constants/assets_constant.dart
Normal file
11
lib/utils/constants/assets_constant.dart
Normal file
@@ -0,0 +1,11 @@
|
||||
class APPASSETS {
|
||||
static const String svgBaseUrl = "assets/images/svgs";
|
||||
static const String pngBaseUrl = "assets/images/pngs";
|
||||
|
||||
//SVG
|
||||
static const String back = "$svgBaseUrl/back.svg";
|
||||
//PNG
|
||||
static const String splashImagePNG = "$pngBaseUrl/splash.png";
|
||||
static const String onBoardMan = "$pngBaseUrl/onboard_man.png";
|
||||
static const String placeHolder = '$pngBaseUrl/placeHolder.png';
|
||||
}
|
||||
15
lib/utils/constants/color_constant.dart
Normal file
15
lib/utils/constants/color_constant.dart
Normal file
@@ -0,0 +1,15 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:grocery_app/utils/extensions/color_ex.dart';
|
||||
|
||||
class APPCOLOR {
|
||||
static Color appGreen = HexColor('228B22');
|
||||
static Color lightGreen = HexColor('00d267');
|
||||
static Color balck1A1A1A = HexColor('1A1A1A');
|
||||
static Color black333333 = HexColor('333333');
|
||||
static Color grey666666 = HexColor('666666');
|
||||
static Color whiteFBFEFB = HexColor('FBFEFB');
|
||||
static Color borderColor = HexColor('181616');
|
||||
static Color gery48514D = HexColor('48514D');
|
||||
static Color lightGreyF4F5F5 = HexColor('F7FDF7');
|
||||
static Color bgGrey = Colors.grey.withOpacity(0.0500);
|
||||
}
|
||||
5
lib/utils/constants/globle_variable.dart
Normal file
5
lib/utils/constants/globle_variable.dart
Normal file
@@ -0,0 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class GlobalVariable{
|
||||
static final globalScaffoldKey = GlobalKey<NavigatorState>();
|
||||
}
|
||||
314
lib/utils/constants/shared_pref_utils.dart
Normal file
314
lib/utils/constants/shared_pref_utils.dart
Normal file
@@ -0,0 +1,314 @@
|
||||
// ignore_for_file: constant_identifier_names
|
||||
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
|
||||
// Shared preference for the app to store data locally
|
||||
class SharedPrefUtils {
|
||||
SharedPrefUtils._();
|
||||
|
||||
static String? _token;
|
||||
static String? _resetToken;
|
||||
static String? _refreshToken;
|
||||
static const String PROFILE_PIC = "profile_pic";
|
||||
static const String BADGE_URL = "badge_url";
|
||||
static String USER_NAME = "username";
|
||||
static const String INS_RANDOM = "ins_random";
|
||||
static const String INS_NearBy = "ins_nearby";
|
||||
static const String USER_ID = "user_id";
|
||||
static String PHONE = "phone";
|
||||
static const String BACK_STATUS = "back_status";
|
||||
static const String HAND_OF_ACTION = "hand_of_action";
|
||||
static const String VERIFIED_USER = "verified_user";
|
||||
static const String KEY_TOKEN = "KEY_TOKEN";
|
||||
static const String IS_PROFILE = "is_profile";
|
||||
static const String IS_FRESH_INSTALL = "is_fresh_install";
|
||||
static const String LAST_LOCATION = "LAST_LOCATION";
|
||||
static const String COUNTRY_CODE = "COUNTRY_CODE";
|
||||
static const String SELECTED_PROFILE = "selected_profile";
|
||||
static const String CITY = "city";
|
||||
static const String IS_SUBSCRIPTION_PURCHASE = "IS_SUBSCRIPTION_PURCHASE";
|
||||
static const String FIRST_NAME = "FIRST_NAME";
|
||||
static const String LAST_NAME = "FIRST_NAME";
|
||||
static const String EMAIL = "EMAIL";
|
||||
static const String PASSWORD = "PASSWORD";
|
||||
static const String RESET_TOKEN = "RESET_TOKEN";
|
||||
static const String STORE_ID = "STORE_ID";
|
||||
static const String REFRESH_TOKEN = "REFRESH_TOKEN";
|
||||
|
||||
/// Set bearer authorization token
|
||||
static Future<bool> setToken({required String authToken}) {
|
||||
_token = authToken;
|
||||
return SharedPreferences.getInstance()
|
||||
.then((sp) async => await sp.setString(KEY_TOKEN, authToken));
|
||||
}
|
||||
|
||||
static Future<bool> setRefreshToken({required String refresh_token}) {
|
||||
_refreshToken = refresh_token;
|
||||
return SharedPreferences.getInstance()
|
||||
.then((sp) async => await sp.setString(REFRESH_TOKEN, refresh_token));
|
||||
}
|
||||
|
||||
static Future<bool> setStoreId({required String storeId}) {
|
||||
return SharedPreferences.getInstance()
|
||||
.then((sp) async => await sp.setString(STORE_ID, storeId));
|
||||
}
|
||||
|
||||
static Future<String?> getStoreId() async {
|
||||
final sp = await SharedPreferences.getInstance();
|
||||
_token = sp.getString(STORE_ID);
|
||||
return _token;
|
||||
}
|
||||
|
||||
static Future<bool> setResetToken({required String resetToken}) {
|
||||
resetToken = resetToken;
|
||||
return SharedPreferences.getInstance()
|
||||
.then((sp) async => await sp.setString(RESET_TOKEN, resetToken));
|
||||
}
|
||||
|
||||
static Future<bool> setFistName({required String firstName}) {
|
||||
return SharedPreferences.getInstance()
|
||||
.then((sp) async => await sp.setString(FIRST_NAME, firstName));
|
||||
}
|
||||
|
||||
static Future<bool> setLastName({required String LastName}) {
|
||||
return SharedPreferences.getInstance()
|
||||
.then((sp) async => await sp.setString(LAST_NAME, LastName));
|
||||
}
|
||||
|
||||
static Future<bool> setEmail({required String email}) {
|
||||
return SharedPreferences.getInstance()
|
||||
.then((sp) async => await sp.setString(EMAIL, email));
|
||||
}
|
||||
|
||||
static Future<bool> setPassWord({required String password}) {
|
||||
return SharedPreferences.getInstance()
|
||||
.then((sp) async => await sp.setString(PASSWORD, password));
|
||||
}
|
||||
|
||||
static Future<bool> setPhone({required int phone}) {
|
||||
return SharedPreferences.getInstance()
|
||||
.then((sp) async => await sp.setInt(PHONE, phone));
|
||||
}
|
||||
|
||||
static Future<bool> getBackPopStatus() async {
|
||||
final sp = await SharedPreferences.getInstance();
|
||||
return sp.getBool(BACK_STATUS) ?? true;
|
||||
}
|
||||
|
||||
static Future<bool> setBackPopStatus(bool status) {
|
||||
return SharedPreferences.getInstance()
|
||||
.then((sp) async => await sp.setBool(BACK_STATUS, status));
|
||||
}
|
||||
|
||||
/// Get bearer authorization token
|
||||
static Future<String?> getToken() async {
|
||||
final sp = await SharedPreferences.getInstance();
|
||||
_token = sp.getString(KEY_TOKEN);
|
||||
return _token;
|
||||
}
|
||||
|
||||
static Future<String?> getRefreshToken() async {
|
||||
final sp = await SharedPreferences.getInstance();
|
||||
_refreshToken = sp.getString(REFRESH_TOKEN);
|
||||
return _refreshToken;
|
||||
}
|
||||
|
||||
static Future<String?> getResetToken() async {
|
||||
final sp = await SharedPreferences.getInstance();
|
||||
_resetToken = sp.getString(RESET_TOKEN);
|
||||
return _resetToken;
|
||||
}
|
||||
|
||||
static Future<bool> setIsSubscriptionPurchase(bool value) {
|
||||
return SharedPreferences.getInstance()
|
||||
.then((sp) async => await sp.setBool(IS_SUBSCRIPTION_PURCHASE, value));
|
||||
}
|
||||
|
||||
///Set availability of user profile
|
||||
static Future<bool> setIsUserProfileUpdated({required bool isUpdated}) {
|
||||
return SharedPreferences.getInstance()
|
||||
.then((sp) async => await sp.setBool(IS_PROFILE, isUpdated));
|
||||
}
|
||||
|
||||
/// Get availability of user profile
|
||||
static Future<bool> isUserProfileUpdated() async {
|
||||
final sp = await SharedPreferences.getInstance();
|
||||
return sp.getBool(IS_PROFILE) ?? false;
|
||||
}
|
||||
|
||||
///Set is fresh install
|
||||
static Future<bool> setFreshInstall({required bool isFresh}) {
|
||||
return SharedPreferences.getInstance()
|
||||
.then((sp) async => await sp.setBool(IS_FRESH_INSTALL, isFresh));
|
||||
}
|
||||
|
||||
/// Get is Fresh install
|
||||
static Future<bool> isFreshInstall() async {
|
||||
final sp = await SharedPreferences.getInstance();
|
||||
return sp.getBool(IS_FRESH_INSTALL) ?? true;
|
||||
}
|
||||
|
||||
static Future<int> getPhone() async {
|
||||
final sp = await SharedPreferences.getInstance();
|
||||
return sp.getInt(PHONE) ?? 0;
|
||||
}
|
||||
|
||||
/// Get Selected profile, will be used
|
||||
static Future<String?> getSelectedProfile() async {
|
||||
final sp = await SharedPreferences.getInstance();
|
||||
return sp.getString(SELECTED_PROFILE) ;
|
||||
}
|
||||
|
||||
/// Get is Fresh install
|
||||
/// Set last location of the user
|
||||
static setLatLongUserPosition(String location) async {
|
||||
final sp = await SharedPreferences.getInstance();
|
||||
sp.setString(LAST_LOCATION, location);
|
||||
}
|
||||
|
||||
/// Get last location of the user
|
||||
static Future<String?> getLatLongUserPosition() async {
|
||||
final sp = await SharedPreferences.getInstance();
|
||||
return sp.getString(LAST_LOCATION);
|
||||
}
|
||||
|
||||
/// Get country code of the user
|
||||
static Future<String?> getCountryCode() async {
|
||||
final sp = await SharedPreferences.getInstance();
|
||||
return sp.getString(COUNTRY_CODE);
|
||||
}
|
||||
|
||||
static setCountryCode(String countryCode) async {
|
||||
final sp = await SharedPreferences.getInstance();
|
||||
sp.setString(COUNTRY_CODE, countryCode);
|
||||
}
|
||||
|
||||
/// Set Selected profile, will be used
|
||||
static Future setSelectedProfile(String profileName) async {
|
||||
final sp = await SharedPreferences.getInstance();
|
||||
sp.setString(SELECTED_PROFILE, profileName);
|
||||
}
|
||||
|
||||
///Set profile url
|
||||
static Future<bool> setUserId({required String id}) {
|
||||
return SharedPreferences.getInstance()
|
||||
.then((sp) async => await sp.setString(USER_ID, id));
|
||||
}
|
||||
|
||||
// /// Set Selected display name, will be used
|
||||
// static Future setUsername(String displayName) async {
|
||||
// final sp = await SharedPreferences.getInstance();
|
||||
// sp.setString(USER_NAME, displayName);
|
||||
// }
|
||||
|
||||
/// Set Selected display name, will be used
|
||||
static Future setUsername({required String displayName}) async {
|
||||
final sp = await SharedPreferences.getInstance();
|
||||
sp.setString(USER_NAME, displayName);
|
||||
}
|
||||
|
||||
static Future setRandomInstruction({required bool status}) async {
|
||||
final sp = await SharedPreferences.getInstance();
|
||||
sp.setBool(INS_RANDOM, status);
|
||||
}
|
||||
|
||||
static Future setNerarByInstruction({required bool status}) async {
|
||||
final sp = await SharedPreferences.getInstance();
|
||||
sp.setBool(INS_NearBy, status);
|
||||
}
|
||||
|
||||
/// Get username
|
||||
///
|
||||
///
|
||||
|
||||
static Future<String> getFirstName() async {
|
||||
final sp = await SharedPreferences.getInstance();
|
||||
|
||||
final firstName = sp.getString(FIRST_NAME);
|
||||
print("lkjhdsgkhfdkjg ${sp.getString(FIRST_NAME)}");
|
||||
|
||||
return firstName!;
|
||||
}
|
||||
|
||||
static Future<String> getLastName() async {
|
||||
final sp = await SharedPreferences.getInstance();
|
||||
return sp.getString(LAST_NAME) ?? "";
|
||||
}
|
||||
|
||||
static Future<String> getEmail() async {
|
||||
final sp = await SharedPreferences.getInstance();
|
||||
return sp.getString(EMAIL) ?? "";
|
||||
}
|
||||
|
||||
static Future<String> getPassword() async {
|
||||
final sp = await SharedPreferences.getInstance();
|
||||
return sp.getString(PASSWORD) ?? "";
|
||||
}
|
||||
|
||||
static Future<String> getUsername() async {
|
||||
final sp = await SharedPreferences.getInstance();
|
||||
return sp.getString(USER_NAME) ?? "";
|
||||
}
|
||||
|
||||
static Future<bool> getRandomInstruction() async {
|
||||
final sp = await SharedPreferences.getInstance();
|
||||
return sp.getBool(INS_RANDOM) ?? true;
|
||||
}
|
||||
|
||||
static Future<bool> getNerarByInstruction() async {
|
||||
final sp = await SharedPreferences.getInstance();
|
||||
return sp.getBool(INS_NearBy) ?? true;
|
||||
}
|
||||
|
||||
///Set profile url
|
||||
static Future<bool> setProfilePicUrl({required String profileUrl}) {
|
||||
return SharedPreferences.getInstance()
|
||||
.then((sp) async => await sp.setString(PROFILE_PIC, profileUrl));
|
||||
}
|
||||
|
||||
/// Get profile url
|
||||
static Future<String> getProfilePicUrl() async {
|
||||
final sp = await SharedPreferences.getInstance();
|
||||
return sp.getString(PROFILE_PIC) ?? "";
|
||||
}
|
||||
|
||||
/// Get profile url
|
||||
static Future<String> getBadgeUrl() async {
|
||||
final sp = await SharedPreferences.getInstance();
|
||||
return sp.getString(BADGE_URL) ?? "";
|
||||
}
|
||||
|
||||
static Future setBadgeUrl({required String url}) async {
|
||||
final sp = await SharedPreferences.getInstance();
|
||||
sp.setString(BADGE_URL, url);
|
||||
}
|
||||
|
||||
/// Get profile url
|
||||
static Future<String> getUserId() async {
|
||||
final sp = await SharedPreferences.getInstance();
|
||||
return sp.getString(USER_ID) ?? "";
|
||||
}
|
||||
|
||||
//Back Popup
|
||||
|
||||
static Future setCity(String city) {
|
||||
return SharedPreferences.getInstance()
|
||||
.then((sp) async => await sp.setString(CITY, city));
|
||||
}
|
||||
|
||||
static Future<String> getCity() async {
|
||||
final sp = await SharedPreferences.getInstance();
|
||||
return sp.getString(CITY) ?? "";
|
||||
}
|
||||
|
||||
/// Clear all preferences
|
||||
static Future<void> clear() async {
|
||||
final sp = await SharedPreferences.getInstance();
|
||||
sp.getKeys().forEach((key) async {
|
||||
if (key != IS_FRESH_INSTALL) {
|
||||
await sp.remove(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
19
lib/utils/constants/string_constant.dart
Normal file
19
lib/utils/constants/string_constant.dart
Normal file
@@ -0,0 +1,19 @@
|
||||
class APPSTRING {
|
||||
//title
|
||||
static const String enterYourMobileNumber = "Enter Your Mobile Number";
|
||||
static const String whatYourPhoneNumber = "What's your phone number?";
|
||||
static const String codeSentText = "A code will be send to verify your phone number";
|
||||
|
||||
static const String enterVerificationCode = "Enter Verification Code";
|
||||
static const String enterCode = "Enter the 6-digit code sent to you at ********8902";
|
||||
static const String pleaseEnterYourFullName = "Please Enter Your Full Name";
|
||||
|
||||
//hint
|
||||
static const String phoneNumberHint = "Phone Number";
|
||||
static const String fullNameHint = "Full Name";
|
||||
|
||||
//button
|
||||
static const String verifyButton = "Verify";
|
||||
static const String continueBtn = "Continue";
|
||||
static const String appName = "Customer App";
|
||||
}
|
||||
15
lib/utils/extensions/color_ex.dart
Normal file
15
lib/utils/extensions/color_ex.dart
Normal file
@@ -0,0 +1,15 @@
|
||||
// ignore_for_file: file_names
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class HexColor extends Color {
|
||||
static int _getColorFromHex(String hexColor) {
|
||||
hexColor = hexColor.toUpperCase().replaceAll("#", "");
|
||||
if (hexColor.length == 6) {
|
||||
hexColor = "FF$hexColor";
|
||||
}
|
||||
return int.parse(hexColor, radix: 16);
|
||||
}
|
||||
|
||||
HexColor(final String hexColor) : super(_getColorFromHex(hexColor));
|
||||
}
|
||||
76
lib/utils/extensions/common_utils.dart
Normal file
76
lib/utils/extensions/common_utils.dart
Normal file
@@ -0,0 +1,76 @@
|
||||
import 'dart:math' as math;
|
||||
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:grocery_app/utils/constants/globle_variable.dart';
|
||||
|
||||
|
||||
|
||||
|
||||
/// Hides soft keyboard if already shown
|
||||
///
|
||||
enum SnackType {
|
||||
success,
|
||||
alert,
|
||||
error
|
||||
}
|
||||
|
||||
|
||||
void hideKeyBoard() {
|
||||
FocusManager.instance.primaryFocus?.unfocus();
|
||||
}
|
||||
|
||||
|
||||
/// Show snackbar
|
||||
void showSnackBar(
|
||||
{ BuildContext ?context,
|
||||
required String message,
|
||||
SnackType snackType = SnackType.success,
|
||||
bool canDismiss = true,
|
||||
bool sticky = false,
|
||||
SnackBarBehavior behaviour = SnackBarBehavior.floating,
|
||||
}) {
|
||||
//if (!context?.mounted??) return;
|
||||
//Clear snack bars
|
||||
ScaffoldMessenger.of(context??GlobalVariable.globalScaffoldKey.currentContext!).clearSnackBars();
|
||||
// Snack bar
|
||||
final snackBar = SnackBar(
|
||||
behavior: behaviour,
|
||||
padding: EdgeInsets.zero,
|
||||
elevation: 0,
|
||||
content: Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 8.h),
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
colors:snackType==SnackType.success? const [
|
||||
Color(0xFF61B15A),
|
||||
Color(0xFF6ABE8B)
|
||||
]:snackType==SnackType.alert?
|
||||
const [
|
||||
Color(0xFFFF8906),
|
||||
Color(0xFFFFA745),
|
||||
]:
|
||||
const [
|
||||
Colors.red,
|
||||
Colors.redAccent,
|
||||
],
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
message,
|
||||
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
duration: sticky ? const Duration(days: 365) : const Duration(seconds: 3),
|
||||
dismissDirection:
|
||||
canDismiss ? DismissDirection.down : DismissDirection.none,
|
||||
);
|
||||
|
||||
// Find the ScaffoldMessenger in the widget tree
|
||||
// and use it to show a SnackBar.
|
||||
ScaffoldMessenger.of(context??GlobalVariable.globalScaffoldKey.currentContext!).showSnackBar(snackBar);
|
||||
}
|
||||
|
||||
|
||||
26
lib/utils/extensions/datehelper_ex.dart
Normal file
26
lib/utils/extensions/datehelper_ex.dart
Normal file
@@ -0,0 +1,26 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
String dateFormatter = 'MMMM dd, y';
|
||||
|
||||
extension DateHelper on DateTime
|
||||
{
|
||||
String formatDate() {
|
||||
final formatter = DateFormat(dateFormatter);
|
||||
return formatter.format(this);
|
||||
}
|
||||
|
||||
bool isSameDate(DateTime other) {
|
||||
return year == other.year && month == other.month && day == other.day;
|
||||
}
|
||||
|
||||
int getDifferenceInDaysWithNow() {
|
||||
final now = DateTime.now();
|
||||
return now.difference(this).inDays;
|
||||
}
|
||||
}
|
||||
|
||||
extension TimeOfDayExt on TimeOfDay {
|
||||
/// note: 'hour' is in 24-hour format
|
||||
double toDouble() => hour + minute / 60.0;
|
||||
}
|
||||
54
lib/utils/extensions/decoration_ex.dart
Normal file
54
lib/utils/extensions/decoration_ex.dart
Normal file
@@ -0,0 +1,54 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:grocery_app/utils/constants/color_constant.dart';
|
||||
|
||||
extension CommonInputDecoration on InputDecoration {
|
||||
InputDecoration customRoundedTextFieldDecoration(String hint, Widget? prefix, Widget? suffix, TextStyle hintStyle) {
|
||||
var returnResult = InputDecoration(
|
||||
hintText: hint,
|
||||
labelText: hint,
|
||||
alignLabelWithHint: false,
|
||||
suffixIcon: suffix,
|
||||
suffixIconConstraints: const BoxConstraints(minWidth: 25, maxWidth: 25, maxHeight: 25, minHeight: 25),
|
||||
contentPadding: const EdgeInsets.only(top: 10, right: 10, bottom: 10, left: 10),
|
||||
prefix: prefix,
|
||||
constraints: const BoxConstraints(maxHeight: 60, minHeight: 60),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
labelStyle: hintStyle,
|
||||
hintStyle: hintStyle,
|
||||
isCollapsed: true,
|
||||
fillColor: APPCOLOR.whiteFBFEFB,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
borderSide: BorderSide(
|
||||
color: APPCOLOR.borderColor.withOpacity(0.4),
|
||||
),
|
||||
),
|
||||
counterText: "",
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
borderSide: BorderSide(
|
||||
color: APPCOLOR.borderColor.withOpacity(0.4),
|
||||
),
|
||||
),
|
||||
errorBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
borderSide: const BorderSide(
|
||||
color: Colors.red,
|
||||
),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
borderSide: BorderSide(
|
||||
color: APPCOLOR.borderColor.withOpacity(0.4),
|
||||
),
|
||||
),
|
||||
disabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
borderSide: BorderSide(
|
||||
color: APPCOLOR.borderColor.withOpacity(0.4),
|
||||
),
|
||||
),
|
||||
);
|
||||
return returnResult;
|
||||
}
|
||||
}
|
||||
338
lib/utils/extensions/extensions.dart
Normal file
338
lib/utils/extensions/extensions.dart
Normal file
@@ -0,0 +1,338 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
|
||||
import 'package:loader_overlay/loader_overlay.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
extension ResponsiveExt on BuildContext {
|
||||
/// Returns true if the current running device is a mobile device
|
||||
bool get isMobile => MediaQuery.of(this).size.shortestSide < 600;
|
||||
}
|
||||
|
||||
extension IntExt on int {
|
||||
String formatAsK() {
|
||||
if (this >= 1000000) {
|
||||
return this % 1000000 == 0
|
||||
? '${(this / 1000000).toStringAsFixed(0)}M'
|
||||
: '${(this / 1000000).toStringAsFixed(1)}M';
|
||||
} else if (this >= 1000) {
|
||||
return this % 1000 == 0
|
||||
? '${(this / 1000).toStringAsFixed(0)}K'
|
||||
: '${(this / 1000).toStringAsFixed(1)}K';
|
||||
}
|
||||
return toString();
|
||||
}
|
||||
}
|
||||
|
||||
extension ThemeExt on BuildContext {
|
||||
/// Theme extensions
|
||||
TextStyle get titleStyle => GoogleFonts.nunito(
|
||||
color: appColor.blackColor, fontSize: 16.sp, fontWeight: FontWeight.w400);
|
||||
|
||||
TextStyle get titleStyleRegular => GoogleFonts.nunito(
|
||||
color: appColor.blackColor, fontSize: 19.sp, fontWeight: FontWeight.w600);
|
||||
|
||||
TextStyle get subTitleStyle => GoogleFonts.nunito(
|
||||
fontWeight: FontWeight.w500,
|
||||
color: appColor.blackColor,
|
||||
fontSize: 18.sp,
|
||||
);
|
||||
TextStyle get buttonTestStyle => GoogleFonts.nunito(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: appColor.blackColor,
|
||||
fontSize: 14.sp,
|
||||
);
|
||||
|
||||
TextStyle get subTitleTextStyle => GoogleFonts.nunito(
|
||||
fontWeight: FontWeight.w400,
|
||||
color: appColor.greyColor,
|
||||
fontSize: 16.sp,
|
||||
);
|
||||
TextStyle get subTitleTextStyleBloack => GoogleFonts.nunito(
|
||||
fontWeight: FontWeight.w500,
|
||||
color: appColor.blackColor,
|
||||
fontSize: 14.sp,
|
||||
);
|
||||
|
||||
TextStyle get subTitleTxtStyleblack => GoogleFonts.nunito(
|
||||
fontWeight: FontWeight.w400,
|
||||
color: appColor.blackColor,
|
||||
fontSize: 13.sp,
|
||||
);
|
||||
|
||||
TextStyle get subTitleTxtStyle => GoogleFonts.nunito(
|
||||
fontWeight: FontWeight.w400,
|
||||
color: appColor.greyColor,
|
||||
fontSize: 13.sp,
|
||||
);
|
||||
|
||||
TextStyle get bodyTxtStyle => GoogleFonts.chivo(
|
||||
fontSize: 14.sp, fontWeight: FontWeight.w400, color: appColor.blackColor);
|
||||
|
||||
TextStyle get bodyTxtStyleTwo => GoogleFonts.chivo(
|
||||
fontSize: 13.sp,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: appColor.blackColor,
|
||||
decoration: TextDecoration.underline,
|
||||
decorationColor: appColor.primary);
|
||||
|
||||
TextStyle get smallTxtStyle => GoogleFonts.chivo(
|
||||
color: appColor.blackColor,
|
||||
fontSize: 10.sp,
|
||||
);
|
||||
|
||||
TextStyle get smallTxtStyleBold => GoogleFonts.chivo(
|
||||
color: appColor.blackColor,
|
||||
fontSize: 10.sp,
|
||||
fontWeight: FontWeight.w500,
|
||||
);
|
||||
|
||||
TextStyle get titleTextStyle => GoogleFonts.chivo(
|
||||
color: appColor.blackColor,
|
||||
fontSize: 16.sp,
|
||||
fontWeight: FontWeight.w500,
|
||||
);
|
||||
|
||||
TextStyle get cardTitleStyle => GoogleFonts.chivo(
|
||||
color: appColor.blackColor,
|
||||
fontSize: 13.76.sp,
|
||||
fontWeight: FontWeight.w500,
|
||||
);
|
||||
|
||||
TextStyle get cardTitleStyleWhite => GoogleFonts.chivo(
|
||||
color: appColor.whiteColor,
|
||||
fontSize: 13.76.sp,
|
||||
fontWeight: FontWeight.w500,
|
||||
);
|
||||
|
||||
TextStyle get dropdownBodyTxtStyle => GoogleFonts.chivo(
|
||||
color: appColor.blackColor,
|
||||
fontSize: 14.sp,
|
||||
fontWeight: FontWeight.w500,
|
||||
);
|
||||
|
||||
TextStyle get ratingTextStyle => GoogleFonts.chivo(
|
||||
color: appColor.blackColor,
|
||||
fontSize: 40.sp,
|
||||
fontWeight: FontWeight.w700,
|
||||
);
|
||||
|
||||
TextStyle get noReviewYetTextStyle => GoogleFonts.chivo(
|
||||
color: appColor.blackColor,
|
||||
fontSize: 33.sp,
|
||||
fontWeight: FontWeight.w700,
|
||||
);
|
||||
|
||||
TextStyle get dropdownTitleTxtStyle => GoogleFonts.chivo(
|
||||
color: appColor.blackColor,
|
||||
fontSize: 13.sp,
|
||||
fontWeight: FontWeight.w500,
|
||||
);
|
||||
|
||||
TextStyle get yourTicketTextStyle => GoogleFonts.chivo(
|
||||
color: appColor.blackColor,
|
||||
fontSize: 13.5.sp,
|
||||
fontWeight: FontWeight.bold,
|
||||
);
|
||||
|
||||
TextStyle get priceBodyTxtStyle => GoogleFonts.chivo(
|
||||
color: appColor.blackColor,
|
||||
fontSize: 16.sp,
|
||||
fontWeight: FontWeight.w500,
|
||||
);
|
||||
|
||||
TextStyle get orderDetailsHeadingTxtStyle => GoogleFonts.chivo(
|
||||
color: appColor.blackColor,
|
||||
fontSize: 18.sp,
|
||||
fontWeight: FontWeight.w500,
|
||||
);
|
||||
|
||||
TextStyle get buttonTxtStyle => GoogleFonts.chivo(
|
||||
color: appColor.whiteColor,
|
||||
fontSize: 15.59.sp,
|
||||
fontWeight: FontWeight.w500,
|
||||
);
|
||||
|
||||
TextStyle get bottomNavTextStyle => GoogleFonts.chivo(
|
||||
fontSize: 9.sp,
|
||||
color: appColor.greyColor500,
|
||||
fontWeight: FontWeight.w400,
|
||||
);
|
||||
|
||||
TextStyle get headingTextStyle => GoogleFonts.chivo(
|
||||
fontSize: 20.sp,
|
||||
color: appColor.blackColor,
|
||||
fontWeight: FontWeight.w500,
|
||||
);
|
||||
|
||||
TextStyle get mainHeadingTextStyle => GoogleFonts.chivo(
|
||||
fontSize: 35.sp,
|
||||
color: appColor.blackColor,
|
||||
fontWeight: FontWeight.w500,
|
||||
);
|
||||
|
||||
TextStyle get orderConfirmHeadingTextStyle => GoogleFonts.chivo(
|
||||
fontSize: 28.sp,
|
||||
color: appColor.blackColor,
|
||||
fontWeight: FontWeight.w600,
|
||||
);
|
||||
}
|
||||
|
||||
/// Build context extensions
|
||||
extension ContextExtension on BuildContext {
|
||||
void to({required Widget screen}) {
|
||||
Navigator.push(this, MaterialPageRoute(builder: (context) => screen));
|
||||
}
|
||||
|
||||
///Pops all screen until last screen then replaces it with the required screen
|
||||
void clearAndPush({required String routePath, Object? args}) {
|
||||
while (GoRouter.of(this).canPop()) {
|
||||
GoRouter.of(this).pop();
|
||||
}
|
||||
GoRouter.of(this).pushReplacement(routePath, extra: args);
|
||||
}
|
||||
|
||||
/// Get color scheme
|
||||
ColorScheme get appColor => Theme.of(this).colorScheme;
|
||||
|
||||
/// Get current height of the screen
|
||||
double get height => MediaQuery.of(this).size.height;
|
||||
|
||||
/// Get current height of the screen
|
||||
double get width => MediaQuery.of(this).size.width;
|
||||
|
||||
/// Provides safe context
|
||||
BuildContext? getSafeContext() {
|
||||
if (mounted) {
|
||||
return this;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// show global loader
|
||||
void showLoader({bool show = true}) {
|
||||
if (mounted) {
|
||||
if (show) {
|
||||
loaderOverlay.show();
|
||||
} else {
|
||||
loaderOverlay.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension DateTimeExtension on DateTime? {
|
||||
bool? isAfterOrEqualTo(DateTime dateTime) {
|
||||
final date = this;
|
||||
if (date != null) {
|
||||
final isAtSameMomentAs = dateTime.isAtSameMomentAs(date);
|
||||
return isAtSameMomentAs | date.isAfter(dateTime);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
String getFormattedDate({String pattern = "dd-mm-yyyy"}) {
|
||||
if (this != null) {
|
||||
return DateFormat(pattern).format(this!.toLocal());
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
bool? isBeforeOrEqualTo(DateTime dateTime) {
|
||||
final date = this;
|
||||
if (date != null) {
|
||||
final isAtSameMomentAs = dateTime.isAtSameMomentAs(date);
|
||||
return isAtSameMomentAs | date.isBefore(dateTime);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
bool? isBetween(DateTime fromDateTime, DateTime toDateTime) {
|
||||
final date = this;
|
||||
if (date != null) {
|
||||
final isAfter = date.isAfterOrEqualTo(fromDateTime) ?? false;
|
||||
final isBefore = date.isBeforeOrEqualTo(toDateTime) ?? false;
|
||||
return isAfter && isBefore;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// Color scheme extensions
|
||||
|
||||
extension ColorExtension on String {
|
||||
toColor() {
|
||||
var hexColor = this.replaceAll("#", "");
|
||||
if (hexColor.length == 6) {
|
||||
hexColor = "FF$hexColor";
|
||||
}
|
||||
if (hexColor.length == 8) {
|
||||
return Color(int.parse("0x$hexColor"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension ColorExt on ColorScheme {
|
||||
Color get blackColor =>
|
||||
brightness == Brightness.light ? const Color(0xff1A1A1A) : Colors.white38;
|
||||
|
||||
Color get greyColor =>
|
||||
brightness == Brightness.light ? const Color(0xff666666) : Colors.white30;
|
||||
|
||||
Color get greyColor500 =>
|
||||
brightness == Brightness.light ? Color(0xff6F6B7D) : Colors.white30;
|
||||
|
||||
Color get greyColor400 =>
|
||||
brightness == Brightness.light ? Colors.grey.shade400 : Colors.white30;
|
||||
|
||||
Color get greyColor200 =>
|
||||
brightness == Brightness.light ? Colors.grey.shade200 : Colors.white12;
|
||||
|
||||
Color get greyColor300 =>
|
||||
brightness == Brightness.light ? Colors.grey.shade300 : Colors.white12;
|
||||
|
||||
Color get greyColor100 =>
|
||||
brightness == Brightness.light ? Colors.grey.shade100 : Colors.white12;
|
||||
|
||||
Color get greyColor50 =>
|
||||
brightness == Brightness.light ? Color(0xffF8F8F8) : Colors.white12;
|
||||
|
||||
Color get lightBlackColor =>
|
||||
brightness == Brightness.light ? Colors.black26 : Colors.white30;
|
||||
|
||||
Color get whiteColor =>
|
||||
brightness == Brightness.light ? Colors.white : Colors.black;
|
||||
|
||||
Color get backgroundColor =>
|
||||
brightness == Brightness.dark ? const Color(0xFF0F0E17) : Colors.white;
|
||||
|
||||
Color get transparent => Colors.transparent;
|
||||
|
||||
Color get redColor => Colors.red;
|
||||
|
||||
Color get primarycolor => Color(0xff228B22);
|
||||
|
||||
// Color get reviewColor =>
|
||||
// brightness == Brightness.dark ? Colors.green : const Color(0xff006D60);
|
||||
//
|
||||
// Color get successColor =>
|
||||
// brightness == Brightness.light ? Colors.green : Colors.green;
|
||||
//
|
||||
// Color get chatTextColor =>
|
||||
// brightness == Brightness.light ? Colors.blue : Colors.lightBlue;
|
||||
Color get smallTextColor => brightness == Brightness.light
|
||||
? const Color(0xFF6A6A6A)
|
||||
: const Color(0xFF6A6A6A);
|
||||
Color get darkGreen => brightness == Brightness.light
|
||||
? const Color(0xFF1D713E)
|
||||
: const Color(0xFF07E55E);
|
||||
|
||||
Color get lightGreen => brightness == Brightness.light
|
||||
? const Color(0xFFEDF8F1)
|
||||
: Colors.greenAccent;
|
||||
|
||||
Color get yellow =>
|
||||
brightness == Brightness.light ? const Color(0xFFE9A706) : Colors.yellow;
|
||||
}
|
||||
49
lib/utils/extensions/uicontext.dart
Normal file
49
lib/utils/extensions/uicontext.dart
Normal file
@@ -0,0 +1,49 @@
|
||||
// ignore_for_file: file_names
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
extension CustomUITheme on BuildContext {
|
||||
TextStyle customLight(Color color, double fontSize) {
|
||||
return TextStyle(fontWeight: FontWeight.w300, color: color, fontSize: fontSize, fontFamily: 'Nunito');
|
||||
}
|
||||
|
||||
TextStyle customBold(Color color, double fontSize) {
|
||||
return TextStyle(fontWeight: FontWeight.w700, color: color, fontSize: fontSize, fontFamily: 'Nunito');
|
||||
}
|
||||
|
||||
TextStyle customRegular(Color color, double fontSize) {
|
||||
return TextStyle(fontWeight: FontWeight.w400, color: color, fontSize: fontSize, fontFamily: 'Nunito');
|
||||
}
|
||||
|
||||
TextStyle customMedium(Color color, double fontSize) {
|
||||
return TextStyle(fontWeight: FontWeight.w500, color: color, fontSize: fontSize, fontFamily: 'Nunito');
|
||||
}
|
||||
|
||||
TextStyle customSemiBold(Color color, double fontSize) {
|
||||
return TextStyle(fontWeight: FontWeight.w600, color: color, fontSize: fontSize, fontFamily: 'Nunito');
|
||||
}
|
||||
|
||||
TextStyle customExtraBold(Color color, double fontSize) {
|
||||
return TextStyle(fontWeight: FontWeight.w800, color: color, fontSize: fontSize, fontFamily: 'Nunito');
|
||||
}
|
||||
|
||||
double screenWidth() {
|
||||
return MediaQuery.sizeOf(this).width;
|
||||
}
|
||||
|
||||
double screenHeight() {
|
||||
return MediaQuery.sizeOf(this).height;
|
||||
}
|
||||
|
||||
EdgeInsets get bodyPadding {
|
||||
return const EdgeInsets.only(left: 15, right: 15);
|
||||
}
|
||||
|
||||
EdgeInsets get bodyLeftOnly {
|
||||
return const EdgeInsets.only(left: 15);
|
||||
}
|
||||
|
||||
EdgeInsets get bodyAllPadding {
|
||||
return const EdgeInsets.all(15);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user