baseproject

This commit is contained in:
Gaurav Kumar
2025-09-06 19:21:52 +05:30
commit 01be9df2ed
254 changed files with 28342 additions and 0 deletions

View File

@@ -0,0 +1,172 @@
import 'package:flutter/material.dart';
class ColorConstant {
static Color gray5001 = fromHex('#f6f7fb');
static Color purple211 = const Color.fromARGB(255, 93, 63, 211);
static Color gray5002 = fromHex('#f8f9fa');
static Color black900B2 = fromHex('#b2000000');
static Color gray5003 = fromHex('#fafcff');
static Color lightBlue100 = fromHex('#b0e5fc');
static Color gray80049 = fromHex('#493c3c43');
static Color yellow9003f = fromHex('#3feb9612');
static Color iris = fromHex('5D3FD3');
static Color red200 = fromHex('#fa9a9a');
static Color gray4004c = fromHex('#4cc4c4c4');
static Color blueA200 = fromHex('#468ee5');
static Color greenA100 = fromHex('#b5eacd');
static Color black9003f = fromHex('#3f000000');
static Color gray30099 = fromHex('#99e4e4e4');
static Color black90087 = fromHex('#87000000');
static Color whiteA70099 = fromHex('#99ffffff');
static Color black90001 = fromHex('#000000');
static Color blueGray90002 = fromHex('#24363c');
static Color blueGray90001 = fromHex('#2e3637');
static Color blueGray700 = fromHex('#535763');
static Color blueGray900 = fromHex('#262b35');
static Color black90003 = fromHex('#0b0a0a');
static Color black90002 = fromHex('#090b0d');
static Color redA700 = fromHex('#d80027');
static Color black90004 = fromHex('#000000');
static Color gray400 = fromHex('#c4c4c4');
static Color blue900 = fromHex('#003399');
static Color blueGray100 = fromHex('#d6dae2');
static Color blue700 = fromHex('#1976d2');
static Color blueGray300 = fromHex('#9ea8ba');
static Color amber500 = fromHex('#feb909');
static Color redA200 = fromHex('#fe555d');
static Color gray80099 = fromHex('#993c3c43');
static Color black9000c = fromHex('#0c000000');
static Color gray200 = fromHex('#efefef');
static Color gray60026 = fromHex('#266d6d6d');
static Color blue50 = fromHex('#e0ebff');
static Color indigo400 = fromHex('#4168d7');
static Color blueGray1006c = fromHex('#6cd1d3d4');
static Color black90011 = fromHex('#11000000');
static Color gray40001 = fromHex('#b3b3b3');
static Color whiteA70067 = fromHex('#67ffffff');
static Color gray10001 = fromHex('#fbf1f2');
static Color black90019 = fromHex('#19000000');
static Color blueGray40001 = fromHex('#888888');
static Color whiteA700 = fromHex('#ffffff');
static Color blueGray50 = fromHex('#eaecf0');
static Color red700 = fromHex('#d03329');
static Color blueA700 = fromHex('#0061ff');
static Color blueGray10001 = fromHex('#d6d6d6');
static Color gray60019 = fromHex('#197e7e7e');
static Color green600 = fromHex('#349765');
static Color blueA70001 = fromHex('#0068ff');
static Color gray50 = fromHex('#f9fbff');
static Color red100 = fromHex('#f6d6d4');
static Color blueGray20001 = fromHex('#adb5bd');
static Color black900 = fromHex('#000919');
static Color blueGray800 = fromHex('#37334d');
static Color blue5001 = fromHex('#eef4ff');
static Color deepOrange400 = fromHex('#d58c48');
static Color deepOrangeA400 = fromHex('#ff4b00');
static Color gray70011 = fromHex('#11555555');
static Color indigoA20033 = fromHex('#334871e3');
static Color gray90002 = fromHex('#0d062d');
static Color gray700 = fromHex('#666666');
static Color blueGray200 = fromHex('#bac1ce');
static Color blueGray400 = fromHex('#74839d');
static Color blue800 = fromHex('#2953c7');
static Color blueGray600 = fromHex('#5f6c86');
static Color gray900 = fromHex('#2a2a2a');
static Color gray90001 = fromHex('#212529');
static Color gray300 = fromHex('#d2efe0');
static Color gray30001 = fromHex('#e3e4e5');
static Color gray100 = fromHex('#f3f4f5');
static Color black90075 = fromHex('#75000000');
static Color deepOrangeA10033 = fromHex('#33dfa874');
static Color gray70026 = fromHex('#26555555');
static Color black90033 = fromHex('#33000000');
static Color blue200 = fromHex('#a6c8ff');
static Color purple900 = Colors.purple.shade900;
static Color fromHex(String hexString) {
final buffer = StringBuffer();
if (hexString.length == 6 || hexString.length == 7) buffer.write('ff');
buffer.write(hexString.replaceFirst('#', ''));
return Color(int.parse(buffer.toString(), radix: 16));
}
}

View File

@@ -0,0 +1,61 @@
import 'package:another_flushbar/flushbar.dart';
import 'package:base_project/resources/app_colors.dart';
import 'package:flutter/material.dart';
class FlushBarMessageUtil {
static void showFlushBar({
required BuildContext context,
required String message,
FlushBarType flushBarType = FlushBarType.info,
int durationInSeconds = 3,
}) {
Flushbar(
message: message,
duration: Duration(seconds: durationInSeconds),
backgroundColor: _getBackgroundColor(flushBarType),
margin: const EdgeInsets.all(8.0),
borderRadius: BorderRadius.circular(8.0),
flushbarPosition: FlushbarPosition.BOTTOM,
icon: _getIcon(flushBarType),
leftBarIndicatorColor: _getBackgroundColor(flushBarType),
).show(context);
}
static Color _getBackgroundColor(FlushBarType flushBarType) {
switch (flushBarType) {
case FlushBarType.success:
return AppColors.success;
case FlushBarType.error:
return AppColors.error;
case FlushBarType.warning:
return AppColors.warning;
case FlushBarType.info:
return AppColors.info;
case FlushBarType.general:
return AppColors.darkGrey;
default:
return AppColors.info;
}
}
static Icon _getIcon(FlushBarType flushBarType) {
switch (flushBarType) {
case FlushBarType.success:
return const Icon(Icons.check_circle, color: Colors.white);
case FlushBarType.error:
return const Icon(Icons.error, color: Colors.white);
case FlushBarType.warning:
return const Icon(Icons.warning, color: Colors.white);
case FlushBarType.info:
return const Icon(Icons.info, color: Colors.white);
case FlushBarType.general:
return const Icon(Icons.notifications, color: Colors.white);
default:
return const Icon(Icons.info, color: Colors.white);
}
}
}
enum FlushBarType { success, error, warning, info, general }

View File

@@ -0,0 +1,35 @@
class FormValidators {
// Validator for non-empty fields
static String? validateNotEmpty(String? value) {
return value == null || value.isEmpty ? 'This field cannot be empty' : null;
}
// Validator for email format
static String? validateEmail(String? value) {
const emailPattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$';
final regex = RegExp(emailPattern);
return value == null || !regex.hasMatch(value) ? 'Enter a valid email address' : null;
}
// Validator for phone number format
static String? validatePhoneNumber(String? value) {
const phonePattern = r'^\+?[1-9]\d{1,14}$'; // E.164 format
final regex = RegExp(phonePattern);
return value == null || !regex.hasMatch(value) ? 'Enter a valid phone number' : null;
}
// Validator for min length
static String? validateMinLength(String? value, int minLength) {
return value == null || value.length < minLength ? 'Must be at least $minLength characters long' : null;
}
// Validator for max length
static String? validateMaxLength(String? value, int maxLength) {
return value != null && value.length > maxLength ? 'Must be no more than $maxLength characters long' : null;
}
// Validator for matching passwords
static String? validatePasswordMatch(String? value, String password) {
return value != password ? 'Passwords do not match' : null;
}
}

View File

@@ -0,0 +1,26 @@
class ImageConstant {
// Image folder path
static String imagePath = 'assets/images';
// All images
static String imgArrowleft = '$imagePath/img_arrowleft.svg';
static String userProfileImg = "$imagePath/user-line.svg";
static String imgFire = '$imagePath/img_fire.svg';
static String imgSearchWhiteA70020x20 =
'$imagePath/img_search_white_a700_20x20.svg';
static String imgMenu = '$imagePath/img_menu.svg';
static String imgOverflowmenuWhiteA700 =
'$imagePath/img_overflowmenu_white_a700.svg';
static String imgArrowleftBlueGray900 =
'$imagePath/img_arrowleft_blue_gray_900.svg';
static String bubbles = 'assets/icon/bubbles.svg';
static String close = 'assets/icon/close.svg';
static String fail = 'assets/icon/fail.svg';
}

View File

@@ -0,0 +1,100 @@
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
class UserManager {
static const String _userKey = 'user';
static const String _accountKey = 'sys_account';
static UserManager? _instance;
static Map<String, dynamic>? _cachedUser;
static Map<String, dynamic>? _cachedAccount;
// Private constructor for singleton
UserManager._privateConstructor();
// Factory constructor to get the singleton instance
factory UserManager() {
_instance ??= UserManager._privateConstructor();
return _instance!;
}
// Initialize and load user data
Future<void> initialize() async {
if (_cachedUser == null) {
final prefs = await SharedPreferences.getInstance();
final userData = prefs.getString(_userKey);
if (userData != null) {
_cachedUser = jsonDecode(userData) as Map<String, dynamic>;
}
}
if (_cachedAccount == null) {
final prefs = await SharedPreferences.getInstance();
final accountData = prefs.getString(_accountKey);
if (accountData != null) {
_cachedAccount = jsonDecode(accountData) as Map<String, dynamic>;
}
}
}
// Accessor for user token
String? get token {
return _cachedUser?['token'];
}
// Accessor for user name
String? get userName {
return _cachedUser?['fullname'];
}
// Accessor for user email
String? get email {
return _cachedUser?['email'];
}
// Accessor for user id
int? get userId {
return _cachedUser?['userId'];
}
// Accessor for user roles (Assuming it's a list of roles in the user data)
List<String>? get roles {
if (_cachedUser?['roles'] != null) {
return List<String>.from(_cachedUser!['roles']);
}
return null;
}
// Save user data and cache it
Future<void> setUser(Map<String, dynamic> user) async {
final prefs = await SharedPreferences.getInstance();
final userData = jsonEncode(user);
await prefs.setString(_userKey, userData);
_cachedUser = user; // Update cache
}
// Save account data and cache it
Future<void> setAccount(Map<String, dynamic> account) async {
final prefs = await SharedPreferences.getInstance();
final accountData = jsonEncode(account);
await prefs.setString(_accountKey, accountData);
_cachedAccount = account;
}
Map<String, dynamic>? get account => _cachedAccount;
String? get accountId {
final id = _cachedAccount?['account_id'] ?? _cachedAccount?['id'];
return id?.toString();
}
// Clear user data and cache
Future<void> clearUser() async {
final prefs = await SharedPreferences.getInstance();
await prefs.remove(_userKey);
await prefs.remove(_accountKey);
await prefs.remove('isLoggedIn');
await prefs.clear();
_cachedUser = null; // Clear cache
_cachedAccount = null;
}
}

View File

@@ -0,0 +1,120 @@
import 'package:flutter/material.dart';
// This is where the magic happens.
// This functions are responsible to make UI responsive across all the mobile devices.
Size size = WidgetsBinding.instance.window.physicalSize /
WidgetsBinding.instance.window.devicePixelRatio;
// Caution! If you think these are static values and are used to build a static UI, you mustnt.
// These are the Viewport values of your Figma Design.
// These are used in the code as a reference to create your UI Responsively.
const num FIGMA_DESIGN_WIDTH = 428;
const num FIGMA_DESIGN_HEIGHT = 926;
const num FIGMA_DESIGN_STATUS_BAR = 47;
///This method is used to get device viewport width.
get width {
return size.width;
}
///This method is used to get device viewport height.
get height {
num statusBar =
MediaQueryData.fromView(WidgetsBinding.instance.window).viewPadding.top;
num bottomBar = MediaQueryData.fromView(WidgetsBinding.instance.window)
.viewPadding
.bottom;
num screenHeight = size.height - statusBar - bottomBar;
return screenHeight;
}
///This method is used to set padding/margin (for the left and Right side) & width of the screen or widget according to the Viewport width.
double getHorizontalSize(double px) {
return ((px * width) / FIGMA_DESIGN_WIDTH);
}
///This method is used to set padding/margin (for the top and bottom side) & height of the screen or widget according to the Viewport height.
double getVerticalSize(double px) {
return ((px * height) / (FIGMA_DESIGN_HEIGHT - FIGMA_DESIGN_STATUS_BAR));
}
///This method is used to set smallest px in image height and width
double getSize(double px) {
var height = getVerticalSize(px);
var width = getHorizontalSize(px);
if (height < width) {
return height.toInt().toDouble();
} else {
return width.toInt().toDouble();
}
}
///This method is used to set text font size according to Viewport
double getFontSize(double px) {
return getSize(px);
}
///This method is used to set padding responsively
EdgeInsetsGeometry getPadding({
double? all,
double? left,
double? top,
double? right,
double? bottom,
}) {
return getMarginOrPadding(
all: all,
left: left,
top: top,
right: right,
bottom: bottom,
);
}
///This method is used to set margin responsively
EdgeInsetsGeometry getMargin({
double? all,
double? left,
double? top,
double? right,
double? bottom,
}) {
return getMarginOrPadding(
all: all,
left: left,
top: top,
right: right,
bottom: bottom,
);
}
///This method is used to get padding or margin responsively
EdgeInsetsGeometry getMarginOrPadding({
double? all,
double? left,
double? top,
double? right,
double? bottom,
}) {
if (all != null) {
left = all;
top = all;
right = all;
bottom = all;
}
return EdgeInsets.only(
left: getHorizontalSize(
left ?? 0,
),
top: getVerticalSize(
top ?? 0,
),
right: getHorizontalSize(
right ?? 0,
),
bottom: getVerticalSize(
bottom ?? 0,
),
);
}

View File

@@ -0,0 +1,41 @@
import 'package:base_project/resources/app_colors.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
class ToastMessageUtil {
static void showToast({
required String message,
ToastType toastType = ToastType.info,
ToastGravity gravity = ToastGravity.TOP,
int durationInSeconds = 2,
}) {
Fluttertoast.showToast(
msg: message,
toastLength: Toast.LENGTH_SHORT,
gravity: gravity,
timeInSecForIosWeb: durationInSeconds,
backgroundColor: _getBackgroundColor(toastType),
textColor: Colors.white,
fontSize: 16.0,
);
}
static Color? _getBackgroundColor(ToastType toastType) {
switch (toastType) {
case ToastType.success:
return AppColors.success;
case ToastType.error:
return AppColors.error;
case ToastType.warning:
return AppColors.warning;
case ToastType.info:
return AppColors.info;
case ToastType.general:
return Colors.grey[900];
default:
return AppColors.info;
}
}
}
enum ToastType { success, error, warning, info, general }

View File

@@ -0,0 +1,54 @@
class TextFieldValidator {
// Email validation using RegExp for strict validation
static String? validateEmail(String? value) {
if (value == null || value.isEmpty) {
return 'Email is required';
}
// Strict email pattern
String pattern =
r"^[a-zA-Z0-9]+([._-]?[a-zA-Z0-9]+)*@[a-zA-Z0-9]+([._-]?[a-zA-Z0-9]+)*\.[a-zA-Z]{2,7}$";
RegExp regex = RegExp(pattern);
if (!regex.hasMatch(value)) {
return 'Enter a valid email address';
}
return null;
}
// Simple field validation (non-empty check)
static String? validateField(String? value) {
if (value == null || value.isEmpty) {
return 'This field is required';
}
return null;
}
// Password validation (simple length check, can be expanded for complexity)
static String? validatePassword(String? value) {
if (value == null || value.isEmpty) {
return 'Password is required';
}
// Minimum 8 characters check
// if (value.length < 8) {
// return 'Password must be at least 8 characters long';
// }
return null;
}
// Confirm password validation
static String? validateConfirmPassword(String? value, String? password) {
if (value == null || value.isEmpty) {
return 'Confirm password is required';
}
if (value != password) {
return 'Passwords do not match';
}
return null;
}
}