Initial commit

This commit is contained in:
jahongireshonqulov
2025-10-18 09:40:06 +05:00
commit 1bf3e41abe
352 changed files with 16315 additions and 0 deletions

View File

@@ -0,0 +1,46 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import '../../injector_container.dart';
import '../local_source/local_source.dart';
import '../theme/app_theme.dart';
part 'app_event.dart';
part 'app_state.dart';
class AppBloc extends Bloc<AppEvent, AppState> {
AppBloc()
: super(
AppState(
lightTheme: lightThemes.values.first,
darkTheme: darkThemes.values.first,
themeMode: ThemeMode.values.byName(sl<LocalSource>().getThemeMode()),
appLocale: sl<LocalSource>().getLocale(),
),
) {
on<AppThemeSwitchLight>(_switchToLightHandler);
on<AppThemeSwitchDark>(_switchToDarkHandler);
on<AppChangeLocale>(_changeLocale);
}
void _changeLocale(AppChangeLocale event, Emitter<AppState> emit) {
sl<LocalSource>().setLocale(event.appLocale);
emit(state.copyWith(appLocale: event.appLocale));
}
void _switchToLightHandler(
AppThemeSwitchLight event,
Emitter<AppState> emit,
) {
sl<LocalSource>().setThemeMode(ThemeMode.light.name);
emit(
state.copyWith(lightTheme: event.lightTheme, themeMode: ThemeMode.light),
);
}
void _switchToDarkHandler(AppThemeSwitchDark event, Emitter<AppState> emit) {
sl<LocalSource>().setThemeMode(ThemeMode.dark.name);
emit(state.copyWith(darkTheme: event.darkTheme, themeMode: ThemeMode.dark));
}
}

View File

@@ -0,0 +1,32 @@
part of 'app_bloc.dart';
sealed class AppEvent extends Equatable {
const AppEvent();
}
final class AppThemeSwitchLight extends AppEvent {
final ThemeData lightTheme;
const AppThemeSwitchLight({required this.lightTheme});
@override
List<Object?> get props => [lightTheme];
}
final class AppThemeSwitchDark extends AppEvent {
final ThemeData darkTheme;
const AppThemeSwitchDark({required this.darkTheme});
@override
List<Object?> get props => [darkTheme];
}
final class AppChangeLocale extends AppEvent {
final String appLocale;
const AppChangeLocale(this.appLocale);
@override
List<Object?> get props => [appLocale];
}

View File

@@ -0,0 +1,37 @@
part of 'app_bloc.dart';
class AppState extends Equatable {
final ThemeData? lightTheme;
final ThemeData? darkTheme;
final ThemeMode? themeMode;
final String appLocale;
const AppState({
required this.appLocale,
this.lightTheme,
this.darkTheme,
this.themeMode,
});
AppState copyWith({
ThemeData? lightTheme,
ThemeData? darkTheme,
ThemeMode? themeMode,
String? appLocale,
}) {
return AppState(
lightTheme: lightTheme ?? this.lightTheme,
darkTheme: darkTheme ?? this.darkTheme,
themeMode: themeMode ?? this.themeMode,
appLocale: appLocale ?? this.appLocale,
);
}
@override
List<Object?> get props => [
lightTheme,
darkTheme,
themeMode,
appLocale,
];
}

View File

@@ -0,0 +1,12 @@
import 'package:equatable/equatable.dart';
class NameEntity extends Equatable {
final String? uz;
final String? ru;
final String? zh;
const NameEntity({this.uz, this.ru, this.zh});
@override
List<Object?> get props => [uz, ru, zh];
}

View File

@@ -0,0 +1,26 @@
class ServerException implements Exception {
final String message;
ServerException({required this.message});
factory ServerException.fromJson(Map<String, dynamic> json) {
return ServerException(message: json['message']);
}
}
class NoInternetException implements Exception {}
class CacheException implements Exception {
final String message;
CacheException({required this.message});
@override
String toString() {
return message;
}
}
class MultipleOrdersException implements Exception {
MultipleOrdersException();
}

View File

@@ -0,0 +1,33 @@
import 'package:equatable/equatable.dart';
abstract class Failure extends Equatable {}
class ServerFailure extends Failure {
final String message;
ServerFailure({required this.message});
@override
List<Object?> get props => [message];
}
class NoInternetFailure extends Failure {
@override
List<Object?> get props => [];
}
class CacheFailure extends Failure {
final String message;
CacheFailure({required this.message});
@override
List<Object?> get props => [message];
}
class MultipleOrderFailure extends Failure {
MultipleOrderFailure();
@override
List<Object?> get props => [];
}

View File

@@ -0,0 +1,12 @@
import 'package:flutter/material.dart';
import '../theme/colors/app_colors.dart';
import '../theme/theme_text_style.dart';
extension BuildContextExt on BuildContext {
ThemeTextStyles get text => Theme.of(this).extension<ThemeTextStyles>()!;
AppThemeColors get color => Theme.of(this).extension<AppThemeColors>()!;
bool get isDarkMode => Theme.of(this).brightness == Brightness.dark;
}

View File

@@ -0,0 +1,11 @@
import 'package:flutter/material.dart';
extension HexColor on Color {
/// String is in the format "aabbcc" or "ffaabbcc" with an optional leading "#".
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,13 @@
extension SliverCountExtension on int {
int get doubleTheListCount => (this * 2) - 1;
int get exactIndex => (this ~/ 2);
int get lastIndex => (this * 2) - 2;
}
extension VersionParsing on String {
int toVersion() {
return int.tryParse(replaceAll(".", "")) ?? 0;
}
}

View File

@@ -0,0 +1,12 @@
import 'package:flutter/cupertino.dart';
import '../../router/app_routes.dart';
extension ScreenSize on double {
double get w {
return this / 375 * MediaQuery.sizeOf(rootNavigatorKey.currentContext!).width;
}
double get h {
return this / 812 * MediaQuery.sizeOf(rootNavigatorKey.currentContext!).height;
}
}

View File

@@ -0,0 +1,73 @@
import 'package:flutter/material.dart';
import '../../router/app_routes.dart';
import '../entity/name/name_entity.dart';
import '../models/name.dart';
class Functions {
static String getTranslatedItem(NameEntity? name, BuildContext context) {
var local = Localizations.localeOf(context);
switch (local.languageCode) {
case 'uz':
{
return name?.uz ?? " ";
}
case "ru":
{
return name?.ru ?? " ";
}
case "zh":
{
return name?.zh ?? " ";
}
default:
{
return name?.uz ?? " ";
}
}
}
static String getTranslatedNameModel(Name? name, BuildContext context) {
var local = Localizations.localeOf(context);
switch (local.languageCode) {
case 'uz':
{
return name?.uz ?? " ";
}
case "ru":
{
return name?.ru ?? " ";
}
case "zh":
{
return name?.zh ?? " ";
}
default:
{
return name?.uz ?? " ";
}
}
}
static void showErrorSnackBar(String message) {
final snackBar = SnackBar(
backgroundColor: Colors.red,
content: Row(
children: [
const Icon(Icons.error, color: Colors.white),
const SizedBox(width: 8),
Expanded(
child: Text(
message,
style: const TextStyle(color: Colors.white),
),
),
],
),
behavior: SnackBarBehavior.floating,
duration: const Duration(seconds: 3),
);
ScaffoldMessenger.of(
rootNavigatorKey.currentContext!,
).showSnackBar(snackBar);
}
}

View File

@@ -0,0 +1,13 @@
import 'dart:async';
import 'package:flutter/cupertino.dart';
class Debouncer {
static Timer? _timer;
static run(VoidCallback action) {
if (null != _timer) {
_timer?.cancel();
}
_timer = Timer(const Duration(milliseconds: 600), action);
}
}

View File

@@ -0,0 +1,37 @@
import 'package:flutter/services.dart';
class CustomTextInputFormatter extends TextInputFormatter {
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue, TextEditingValue newValue) {
var re = RegExp(('[^0-9]'));
if (newValue.selection.baseOffset == 0 && newValue.text.isNotEmpty) {
return newValue;
}
if (newValue.text.isEmpty) {
return newValue.copyWith(text: '');
} else if (newValue.text.compareTo(oldValue.text) != 0) {
final selectionIndexFromTheRight =
newValue.text.length - newValue.selection.extentOffset;
final reversedText =
String.fromCharCodes(newValue.text.runes.toList().reversed);
final chars = reversedText.replaceAll(re, '').split('');
var reversedNewString = '';
for (var i = 0; i < chars.length; i++) {
if (i % 3 == 0 && i != 0) reversedNewString += ' ';
reversedNewString += chars[i];
}
final newString =
String.fromCharCodes(reversedNewString.runes.toList().reversed);
return TextEditingValue(
text: newString,
selection: TextSelection.collapsed(
offset: newString.length - selectionIndexFromTheRight,
),
);
} else {
return newValue;
}
}
}

View File

@@ -0,0 +1,64 @@
import 'package:flutter/services.dart';
class MaskedTextInputFormatter extends TextInputFormatter {
final String mask;
final String separator;
MaskedTextInputFormatter({
required this.mask,
required this.separator,
});
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue, TextEditingValue newValue) {
String text = newValue.text;
String newText = newValue.toJSON()['text'].toString();
if (text.isNotEmpty) {
if (text.length > oldValue.text.length) {
if (text.length > mask.length) return oldValue;
if (text.length < mask.length && mask[text.length - 1] == separator) {
return TextEditingValue(
text:
'${oldValue.text}$separator${text.substring(text.length - 1)}',
selection: TextSelection.collapsed(
offset: newValue.selection.end + 1,
),
);
}
if (text.length == mask.replaceAll(separator, "").length &&
oldValue.text.isEmpty) {
String newText = '';
int t = 0;
for (int i = 0; i < text.length; i++) {
if (mask[i + t] == separator) {
newText += separator;
t++;
}
newText += text[i];
}
return TextEditingValue(
text: newText,
selection: TextSelection.collapsed(offset: newText.length),
);
}
} else {
if (newText.substring(newText.length - 1) == separator) {
return TextEditingValue(
text: newValue.text.substring(0, newValue.text.length - 1),
selection: TextSelection.collapsed(
offset: newValue.selection.end - 1,
),
);
}
}
return TextEditingValue(
text: newText,
selection: TextSelection.collapsed(
offset: newValue.selection.end,
),
);
}
return newValue;
}
}

View File

@@ -0,0 +1,134 @@
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import '../../constants/constants.dart';
class LocalSource {
final Box<dynamic> box;
LocalSource(this.box);
Future<void> clear() async {
await box.clear();
}
Future<void> setLocale(String locale) async {
await box.put(AppKeys.locale, locale);
}
String getLocale() {
return box.get(AppKeys.locale, defaultValue: "uz") ?? "uz";
}
void setAccessToken(String accessToken) {
box.put(AppKeys.accessToken, accessToken);
}
String? getAccessToken() {
return box.get(AppKeys.accessToken);
}
void setFirstName(String firstName) {
box.put(AppKeys.firstName, firstName);
}
String? getFirstName() {
return box.get(AppKeys.firstName);
}
void setLastName(String lastName) {
box.put(AppKeys.lastName, lastName);
}
String? getLastName() {
return box.get(AppKeys.lastName);
}
void setEmail(String email) {
box.put(AppKeys.email, email);
}
String? getEmail() {
return box.get(AppKeys.email);
}
void setIsFirstEnter(bool isFirst) {
box.put(AppKeys.isFirst, isFirst);
}
bool getIsFirstEnter() {
return box.get(AppKeys.isFirst) ?? true;
}
void setUserId(String id) {
box.put(AppKeys.userId, id);
}
String getUserId() {
return box.get(AppKeys.userId) ?? "";
}
void setDateOfBirth(String id) {
box.put(AppKeys.dateOfBirth, id);
}
String getDateOfBirth() {
return box.get(AppKeys.dateOfBirth) ?? "";
}
void setRefreshToken(String id) {
box.put(AppKeys.refreshToken, id);
}
String getRefreshToken() {
return box.get(AppKeys.refreshToken) ?? "";
}
void setPhone(String id) {
box.put(AppKeys.phone, id);
}
String getPhone() {
return box.get(AppKeys.phone) ?? "";
}
void setHasProfile(bool id) {
box.put(AppKeys.hasProfile, id);
}
bool getHasProfile() {
return box.get(AppKeys.hasProfile) ?? false;
}
void setGender(String id) {
box.put(AppKeys.gender, id);
}
String getGender() {
return box.get(AppKeys.gender) ?? "";
}
void setIsProd(bool isProd) {
box.put(AppKeys.isProd, isProd);
}
bool getIsProd() {
return box.get(AppKeys.isProd) ?? true;
}
void setThemeMode(String mode) {
box.put(AppKeys.themeMode, mode);
}
String getThemeMode() {
return box.get(AppKeys.themeMode) ?? ThemeMode.light.name;
}
void setUCode(String mode) {
box.put(AppKeys.ucode, mode);
}
String getUCode() {
return box.get(AppKeys.ucode) ?? "";
}
}

24
lib/core/models/name.dart Normal file
View File

@@ -0,0 +1,24 @@
import 'package:equatable/equatable.dart';
class Name extends Equatable {
const Name({this.uz, this.ru, this.zh});
factory Name.fromJson(dynamic json) {
return Name(uz: json['uz'], ru: json['ru'], zh: json['zh']);
}
final String? uz;
final String? ru;
final String? zh;
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['uz'] = uz;
map['ru'] = ru;
map['zh'] = zh;
return map;
}
@override
List<Object?> get props => [uz, ru, zh];
}

View File

@@ -0,0 +1,14 @@
import 'package:internet_connection_checker_plus/internet_connection_checker_plus.dart';
abstract class NetworkInfo {
Future<bool> get isConnected;
}
class NetworkInfoImpl implements NetworkInfo{
final InternetConnection internetConnectionCheckerPlus;
NetworkInfoImpl(this.internetConnectionCheckerPlus);
@override
Future<bool> get isConnected => internetConnectionCheckerPlus.hasInternetAccess;
}

View File

@@ -0,0 +1,121 @@
import 'package:flutter/material.dart';
import 'colors/app_colors.dart';
class AppTextStyles {
AppTextStyles._();
static const profileCategory = TextStyle(
color: LightThemeColors.textColor,
fontSize: 16,
fontWeight: FontWeight.w500,
);
static const titleBig = TextStyle(
color: LightThemeColors.textColor,
fontSize: 24,
fontWeight: FontWeight.w700,
);
static const authTitle = TextStyle(
color: LightThemeColors.textColor,
fontSize: 20,
fontWeight: FontWeight.w700,
);
static const timer = TextStyle(
color: ThemeColors.timerRed,
fontSize: 12,
fontWeight: FontWeight.w400,
);
static const categoryName = TextStyle(
color: LightThemeColors.textColor,
fontSize: 14,
fontWeight: FontWeight.w500,
height: 1,
letterSpacing: 0,
);
static const bigTitle = TextStyle(
color: LightThemeColors.textColor,
fontSize: 20,
fontWeight: FontWeight.w600,
);
static const orderTimer = TextStyle(
color: ThemeColors.timerRed,
fontSize: 16,
fontWeight: FontWeight.w400,
);
static const timerStyle = TextStyle(
color: ThemeColors.timerRed,
fontSize: 16,
fontWeight: FontWeight.w400,
);
static const saleRed = TextStyle(
color: ThemeColors.timerRed,
fontSize: 16,
fontWeight: FontWeight.w700,
);
static const timerDesc = TextStyle(
color: ThemeColors.timerRed,
fontSize: 16,
fontWeight: FontWeight.w600,
);
static const statusText = TextStyle(
color: LightThemeColors.buttonColorText,
fontSize: 13,
fontWeight: FontWeight.w600,
);
static const language = TextStyle(
color: LightThemeColors.textColor,
fontSize: 14,
fontWeight: FontWeight.w400,
);
static const languageBig = TextStyle(
color: LightThemeColors.white,
fontSize: 16,
fontWeight: FontWeight.w500,
letterSpacing: 0,
);
static const authDesc = TextStyle(
color: LightThemeColors.secondaryText,
fontSize: 14,
fontWeight: FontWeight.w400,
);
static const timerBlue = TextStyle(
color: LightThemeColors.primaryColor,
fontSize: 14,
fontWeight: FontWeight.w500,
);
static const orderListTitle = TextStyle(
color: LightThemeColors.black40Transparent,
fontSize: 10,
fontWeight: FontWeight.w500,
height: 1,
);
static const status = TextStyle(
color: ThemeColors.green173text,
fontSize: 14,
fontWeight: FontWeight.w600,
height: 1,
letterSpacing: 0,
);
static const orderTitle = TextStyle(
color: LightThemeColors.textColor,
fontSize: 16,
fontWeight: FontWeight.w700,
);
static const statusNumber = TextStyle(
color: LightThemeColors.statusNumber,
fontSize: 12,
fontWeight: FontWeight.w400,
);
static const statusDesc = TextStyle(
color: LightThemeColors.textColor,
fontSize: 12,
fontWeight: FontWeight.w600,
);
static const secondaryText14 = TextStyle(
color: LightThemeColors.lightSecondary,
fontSize: 14,
fontWeight: FontWeight.w500,
);
}

View File

@@ -0,0 +1,14 @@
import 'package:cargocalculaterapp/core/theme/theme_data.dart';
import 'package:flutter/material.dart';
enum LightThemes { violetTheme }
enum DarkThemes { violetTheme }
Map<LightThemes, ThemeData> lightThemes = {
LightThemes.violetTheme: lightTheme,
};
Map<DarkThemes, ThemeData> darkThemes = {
DarkThemes.violetTheme: darkTheme,
};

View File

@@ -0,0 +1,273 @@
import 'package:flutter/material.dart';
class ThemeColors {
static const timerRed = Color(0xFFCF0000);
static const successInputSMS = Color(0xFF36B82C);
static const warningSurface = Color(0xFFFFEFE4);
static const green173Light = Color(0xFFC7FCF6);
static const green191Light = Color(0xFFE9FBFF);
static const warning = Color(0xFFEE5800);
static const green173text = Color(0xFF02685E);
static const green191text = Color(0xFF00668F);
}
class LightThemeColors extends ThemeColors {
static const dividerColor = Color(0x0dFFFFFF);
static const accentColor = Color(0xFF4275ba); // Neon Yellow
static const darkBackground = Color(0xFF171717); // Dark Grey
static const grey = Color(0xFF242424); // Grey
static const midGrey = Color(0xFF474747); // Mid Grey
static const lightGrey = Color(0xFF747474); // Light Grey
static const white = Color(0xFFffffff);
static const white60Transparent = Color(0x99FFFFFF);
static const white30Transparent = Color(0x4dFFFFFF);
static const white10Transparent = Color(0x1aFFFFFF);
static const white20Transparent = Color(0x33FFFFFF);
static const white40Transparent = Color(0x66FFFFFF);
static const errorColor = Color(0xFFCF0000);
///shimmer
static const backgroundGray = Color(0x80FFFFFF);
static const shimmerHighlight = Color(0xffffffff);
static const statusNumber = Color(0xff495057);
///new colors
static const primaryColor = Color(0xff0074B0);
static const textColor = Color(0xFF0C0C0C);
static const secondaryText = Color(0xFF85938E);
static const scaffoldBackgroundColor = Color(0xFFffffff);
static const borderColor = Color(0xFF707479);
static const edittextBackground = Color(0xFFF8FBFC);
static const buttonColorText = Color(0xffffffff);
static const disabledColor = Color(0x331783B2);
static const iconBackground = Color(0xffE3F3F6);
static const lightSecondary = Color(0xff858D93);
static const grayBackground = Color(0xffF8FBFC);
static const statusBackground = Color(0xffffffff);
static const lightBorder = Color(0xffE3E3E3);
static const black40Transparent = Color(0x66000000);
static const statusIconBackground = Color(0xffF1F3F5);
}
class DarkThemeColors {
static const dividerColor = Color(0x0dFFFFFF);
static const accentColor = Color(0xFF4275ba); // Neon Yellow
static const darkBackground = Color(0xFF171717); // Dark Grey
static const grey = Color(0xFF242424); // Grey
static const midGrey = Color(0xFF474747); // Mid Grey
static const lightGrey = Color(0xFF747474); // Light Grey
static const white = Colors.white;
static const white60Transparent = Color(0x99FFFFFF);
static const white30Transparent = Color(0x4dFFFFFF);
static const white10Transparent = Color(0x1aFFFFFF);
static const errorColor = Color(0xFFCF0000);
///new colors
static const primaryColor = Color(0xff1783B2);
static const textColor = Color(0xFFFFFFFF);
static const secondaryText = Color(0xFFC7C7C7);
static const scaffoldBackgroundColor = Color(0xFF171717);
static const borderColor = Color(0xFF707479);
static const edittextBackground = Color(0xFF000000);
static const buttonColorText = Color(0xffffffff);
static const disabledColor = Color(0x331783B2);
static const iconBackground = Color(0xff1A272D);
static const lightSecondary = Color(0xffc7c7c7);
static const grayBackground = Color(0xff000000);
static const statusBackground = Color(0xff1A272D);
static const lightBorder = Color(0xff252525);
static const statusIconBackground = Color(0xff000000);
}
@immutable
class AppThemeColors extends ThemeExtension<AppThemeColors> {
final Color scaffoldBackgroundColor;
final Color textColor;
final Color dividerColor;
final Color accentColor;
final Color darkBackground;
final Color grey;
final Color midGrey;
final Color lightGrey;
final Color white;
final Color white60Transparent;
final Color white30Transparent;
final Color white10Transparent;
final Color buttonColorText;
///newcolors
final Color primaryColor;
final Color secondaryText;
final Color borderColor;
final Color edittextBackground;
final Color iconBackground;
final Color lightSecondary;
final Color grayBackground;
final Color statusBackground;
final Color lightBorder;
final Color statusIconBackground;
const AppThemeColors({
required this.scaffoldBackgroundColor,
required this.textColor,
required this.dividerColor,
required this.accentColor,
required this.darkBackground,
required this.grey,
required this.midGrey,
required this.lightGrey,
required this.white,
required this.white60Transparent,
required this.white30Transparent,
required this.white10Transparent,
required this.buttonColorText,
required this.primaryColor,
required this.secondaryText,
required this.borderColor,
required this.edittextBackground,
required this.iconBackground,
required this.lightSecondary,
required this.grayBackground,
required this.statusBackground,
required this.lightBorder,
required this.statusIconBackground,
});
@override
ThemeExtension<AppThemeColors> copyWith({
Color? scaffoldBackgroundColor,
Color? textColor,
Color? dividerColor,
Color? accentColor,
Color? darkBackground,
Color? grey,
Color? midGrey,
Color? lightGrey,
Color? white,
Color? white60Transparent,
Color? white30Transparent,
Color? white10Transparent,
Color? buttonColorText,
Color? primaryColor,
Color? secondaryText,
Color? borderColor,
Color? edittextBackground,
Color? iconBackground,
Color? lightSecondary,
Color? grayBackground,
Color? statusBackground,
Color? lightBorder,
Color? statusIconBackground,
}) {
return AppThemeColors(
scaffoldBackgroundColor:
scaffoldBackgroundColor ?? this.scaffoldBackgroundColor,
textColor: textColor ?? this.textColor,
dividerColor: dividerColor ?? this.dividerColor,
accentColor: accentColor ?? this.accentColor,
darkBackground: darkBackground ?? this.darkBackground,
grey: grey ?? this.grey,
midGrey: midGrey ?? this.midGrey,
lightGrey: lightGrey ?? this.lightGrey,
white: white ?? this.white,
white60Transparent: white60Transparent ?? this.white60Transparent,
white30Transparent: white30Transparent ?? this.white30Transparent,
white10Transparent: white10Transparent ?? this.white10Transparent,
buttonColorText: buttonColorText ?? this.buttonColorText,
primaryColor: primaryColor ?? this.primaryColor,
secondaryText: secondaryText ?? this.secondaryText,
borderColor: borderColor ?? this.borderColor,
edittextBackground: edittextBackground ?? this.edittextBackground,
iconBackground: iconBackground ?? this.iconBackground,
lightSecondary: lightSecondary ?? this.lightSecondary,
grayBackground: grayBackground ?? this.grayBackground,
statusBackground: statusBackground ?? this.statusBackground,
lightBorder: lightBorder ?? this.lightBorder,
statusIconBackground: statusIconBackground ?? this.statusIconBackground,
);
}
@override
AppThemeColors lerp(ThemeExtension<AppThemeColors>? other, double t) {
if (other is! AppThemeColors) return this;
return AppThemeColors(
scaffoldBackgroundColor: Color.lerp(scaffoldBackgroundColor, other.scaffoldBackgroundColor, t)!,
textColor: Color.lerp(textColor, other.textColor, t)!,
dividerColor: Color.lerp(dividerColor, other.dividerColor, t)!,
accentColor: Color.lerp(accentColor, other.accentColor, t)!,
darkBackground: Color.lerp(darkBackground, other.darkBackground, t)!,
grey: Color.lerp(grey, other.grey, t)!,
midGrey: Color.lerp(midGrey, other.midGrey, t)!,
lightGrey: Color.lerp(lightGrey, other.lightGrey, t)!,
white: Color.lerp(white, other.white, t)!,
white60Transparent: Color.lerp(white60Transparent, other.white60Transparent, t)!,
white30Transparent: Color.lerp(white30Transparent, other.white30Transparent, t)!,
white10Transparent: Color.lerp(white10Transparent, other.white10Transparent, t)!,
buttonColorText: Color.lerp(buttonColorText, other.buttonColorText, t)!,
primaryColor: Color.lerp(primaryColor, other.primaryColor, t)!,
secondaryText: Color.lerp(secondaryText, other.secondaryText, t)!,
borderColor: Color.lerp(borderColor, other.borderColor, t)!,
edittextBackground: Color.lerp(edittextBackground, other.edittextBackground, t)!,
iconBackground: Color.lerp(iconBackground, other.iconBackground, t)!,
lightSecondary: Color.lerp(lightSecondary, other.lightSecondary, t)!,
grayBackground: Color.lerp(grayBackground, other.grayBackground, t)!,
statusBackground: Color.lerp(statusBackground, other.statusBackground, t)!,
lightBorder: Color.lerp(lightBorder, other.lightBorder, t)!,
statusIconBackground: Color.lerp(statusIconBackground, other.statusIconBackground, t)!,
);
}
static get light => const AppThemeColors(
scaffoldBackgroundColor: LightThemeColors.scaffoldBackgroundColor,
textColor: LightThemeColors.textColor,
dividerColor: LightThemeColors.dividerColor,
accentColor: LightThemeColors.accentColor,
darkBackground: LightThemeColors.darkBackground,
grey: LightThemeColors.grey,
midGrey: LightThemeColors.midGrey,
lightGrey: LightThemeColors.lightGrey,
white: LightThemeColors.white,
white60Transparent: LightThemeColors.white60Transparent,
white30Transparent: LightThemeColors.white30Transparent,
white10Transparent: LightThemeColors.white10Transparent,
buttonColorText: LightThemeColors.buttonColorText,
primaryColor: LightThemeColors.primaryColor,
secondaryText: LightThemeColors.secondaryText,
borderColor: LightThemeColors.borderColor,
edittextBackground: LightThemeColors.edittextBackground,
iconBackground: LightThemeColors.iconBackground,
lightSecondary: LightThemeColors.lightSecondary,
grayBackground: LightThemeColors.grayBackground,
statusBackground: LightThemeColors.statusBackground,
lightBorder: LightThemeColors.lightBorder,
statusIconBackground: LightThemeColors.statusIconBackground,
);
static get dark => const AppThemeColors(
scaffoldBackgroundColor: DarkThemeColors.scaffoldBackgroundColor,
textColor: DarkThemeColors.textColor,
dividerColor: DarkThemeColors.dividerColor,
accentColor: DarkThemeColors.accentColor,
darkBackground: DarkThemeColors.darkBackground,
grey: DarkThemeColors.grey,
midGrey: DarkThemeColors.midGrey,
lightGrey: DarkThemeColors.lightGrey,
white: DarkThemeColors.white,
white60Transparent: DarkThemeColors.white60Transparent,
white30Transparent: DarkThemeColors.white30Transparent,
white10Transparent: DarkThemeColors.white10Transparent,
buttonColorText: DarkThemeColors.buttonColorText,
primaryColor: DarkThemeColors.primaryColor,
secondaryText: DarkThemeColors.secondaryText,
borderColor: DarkThemeColors.borderColor,
edittextBackground: DarkThemeColors.edittextBackground,
iconBackground: DarkThemeColors.iconBackground,
lightSecondary: DarkThemeColors.lightSecondary,
grayBackground: DarkThemeColors.grayBackground,
statusBackground: DarkThemeColors.statusBackground,
lightBorder: DarkThemeColors.lightBorder,
statusIconBackground: DarkThemeColors.statusIconBackground,
);
}

View File

@@ -0,0 +1,434 @@
import 'package:cargocalculaterapp/core/theme/theme_text_style.dart';
import 'package:flutter/material.dart';
import 'colors/app_colors.dart';
final appTheme = ThemeData(
fontFamily: "Inter",
extensions: <ThemeExtension<dynamic>>[
AppThemeColors.light,
AppThemeColors.dark,
ThemeTextStyles.light,
ThemeTextStyles.dark,
],
useMaterial3: true,
applyElevationOverlayColor: true,
// disabledColor: ThemeColors.disabledColor,
// splashColor: ThemeColors.primary1Transparent,
// focusColor: ThemeColors.primaryColor,
// colorSchemeSeed: ThemeColors.primaryColor,
visualDensity: VisualDensity.standard,
materialTapTargetSize: MaterialTapTargetSize.padded,
pageTransitionsTheme: const PageTransitionsTheme(
builders: {
TargetPlatform.android: CupertinoPageTransitionsBuilder(),
TargetPlatform.iOS: CupertinoPageTransitionsBuilder(),
},
),
// textButtonTheme: TextButtonThemeData(
// style: ButtonStyle(
// padding: MaterialStateProperty.all<EdgeInsetsGeometry>(
// EdgeInsets.zero,
// ),
// ),
// ),
dividerTheme: const DividerThemeData(thickness: 1),
);
final lightTheme = appTheme.copyWith(
extensions: <ThemeExtension<dynamic>>[
AppThemeColors.light,
ThemeTextStyles.light,
],
scaffoldBackgroundColor: LightThemeColors.scaffoldBackgroundColor,
brightness: Brightness.light,
dividerTheme: appTheme.dividerTheme.copyWith(
color: LightThemeColors.dividerColor,
),
colorScheme: const ColorScheme.light(
secondary: LightThemeColors.white,
primary: LightThemeColors.accentColor,
),
// listTileTheme: const ListTileThemeData(
// minVerticalPadding: 14,
// minLeadingWidth: 16,
// horizontalTitleGap: 12,
// tileColor: LightThemeColors.textFieldBackGround,
// selectedColor: LightThemeColors.backgroundColor,
// selectedTileColor: LightThemeColors.backgroundColor,
// shape: RoundedRectangleBorder(
// borderRadius: AppUtils.kBorderRadius4,
// ),
// ),
tabBarTheme: TabBarThemeData(
labelColor: LightThemeColors.accentColor,
unselectedLabelColor: LightThemeColors.grey,
labelPadding: EdgeInsets.zero,
labelStyle: const TextStyle(fontSize: 11, fontWeight: FontWeight.w400),
unselectedLabelStyle: const TextStyle(
fontSize: 11,
fontWeight: FontWeight.w400,
),
indicator: const UnderlineTabIndicator(
borderSide: BorderSide(color: LightThemeColors.accentColor, width: 2.0),
),
overlayColor: WidgetStateProperty.resolveWith<Color>((states) {
return LightThemeColors.lightGrey;
}),
),
appBarTheme: const AppBarTheme(
elevation: 0,
centerTitle: true,
scrolledUnderElevation: 0,
foregroundColor: LightThemeColors.scaffoldBackgroundColor,
backgroundColor: LightThemeColors.white,
surfaceTintColor: LightThemeColors.scaffoldBackgroundColor,
shadowColor: Colors.black,
titleTextStyle: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w700,
color: LightThemeColors.textColor,
),
toolbarHeight: 56,
iconTheme: IconThemeData(color: LightThemeColors.primaryColor),
),
inputDecorationTheme: const InputDecorationTheme(
contentPadding: EdgeInsets.all(16),
alignLabelWithHint: true,
labelStyle: TextStyle(
color: LightThemeColors.white,
fontSize: 16,
fontWeight: FontWeight.w400,
),
hintStyle: TextStyle(
color: LightThemeColors.secondaryText,
fontSize: 16,
fontWeight: FontWeight.w500,
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(16)),
borderSide: BorderSide(color: LightThemeColors.errorColor),
),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(16)),
borderSide: BorderSide(color: LightThemeColors.borderColor),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(16)),
borderSide: BorderSide(color: LightThemeColors.borderColor),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(16)),
borderSide: BorderSide(color: LightThemeColors.primaryColor),
),
disabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(16)),
borderSide: BorderSide(color: LightThemeColors.white10Transparent),
),
focusedErrorBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(16)),
borderSide: BorderSide(color: LightThemeColors.errorColor),
),
filled: true,
isDense: true,
fillColor: LightThemeColors.edittextBackground,
floatingLabelAlignment: FloatingLabelAlignment.start,
floatingLabelBehavior: FloatingLabelBehavior.always,
),
elevatedButtonTheme: ElevatedButtonThemeData(
style: ButtonStyle(
overlayColor: WidgetStateProperty.resolveWith<Color?>((
Set<WidgetState> states,
) {
if (states.contains(WidgetState.hovered)) {
return LightThemeColors.errorColor;
}
return null;
}),
elevation: WidgetStateProperty.all<double>(0),
textStyle: WidgetStateProperty.all<TextStyle>(
const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w700,
color: LightThemeColors.textColor,
),
),
foregroundColor: WidgetStateProperty.resolveWith<Color>((states) {
if (states.contains(WidgetState.disabled)) {
return LightThemeColors.white;
} else {
return LightThemeColors.white;
}
}),
backgroundColor: WidgetStateProperty.resolveWith<Color>((states) {
if (states.contains(WidgetState.disabled)) {
return LightThemeColors.disabledColor;
} else {
return LightThemeColors.primaryColor;
}
}),
maximumSize: WidgetStateProperty.all<Size>(
const Size(double.infinity, 56),
),
minimumSize: WidgetStateProperty.all<Size>(
const Size(double.infinity, 56),
),
shape: WidgetStateProperty.all<RoundedRectangleBorder>(
const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(24)),
),
),
),
),
bottomNavigationBarTheme: const BottomNavigationBarThemeData(
backgroundColor: LightThemeColors.scaffoldBackgroundColor,
type: BottomNavigationBarType.fixed,
showSelectedLabels: true,
selectedLabelStyle: TextStyle(fontSize: 12, fontWeight: FontWeight.w500),
unselectedLabelStyle: TextStyle(fontSize: 12, fontWeight: FontWeight.w500),
unselectedItemColor: LightThemeColors.lightSecondary,
selectedItemColor: LightThemeColors.primaryColor,
selectedIconTheme: IconThemeData(size: 25),
unselectedIconTheme: IconThemeData(size: 25),
elevation: 2,
),
textButtonTheme: TextButtonThemeData(
style: ButtonStyle(
padding: WidgetStateProperty.all(
const EdgeInsets.symmetric(horizontal: 8, vertical: 8),
),
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
elevation: WidgetStateProperty.all<double>(2),
foregroundColor: WidgetStateProperty.resolveWith<Color>((states) {
return LightThemeColors.scaffoldBackgroundColor;
}),
backgroundColor: WidgetStateProperty.resolveWith<Color>((states) {
if (states.contains(WidgetState.disabled)) {
return Colors.transparent;
} else {
return Colors.transparent;
}
}),
maximumSize: WidgetStateProperty.all<Size>(
const Size(double.infinity, double.infinity),
),
minimumSize: WidgetStateProperty.all<Size>(
const Size(double.minPositive, double.minPositive),
),
shape: WidgetStateProperty.all<RoundedRectangleBorder>(
const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
),
),
textStyle: WidgetStateProperty.all<TextStyle>(
const TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
color: LightThemeColors.accentColor,
),
),
// overlayColor: WidgetStateProperty.resolveWith<Color>((states) {
// return LightThemeColors.lightGrey;
// }),
),
),
bottomSheetTheme: const BottomSheetThemeData(
backgroundColor: Colors.transparent,
// surfaceTintColor: Colors.transparent,
modalBackgroundColor: Colors.transparent,
modalElevation: 0,
elevation: 0,
),
);
final darkTheme = appTheme.copyWith(
extensions: <ThemeExtension<dynamic>>[
AppThemeColors.dark,
ThemeTextStyles.dark,
],
scaffoldBackgroundColor: DarkThemeColors.scaffoldBackgroundColor,
brightness: Brightness.dark,
dividerTheme: appTheme.dividerTheme.copyWith(
color: DarkThemeColors.dividerColor,
),
colorScheme: const ColorScheme.dark(secondary: Colors.white),
tabBarTheme: TabBarThemeData(
labelColor: DarkThemeColors.accentColor,
unselectedLabelColor: DarkThemeColors.grey,
labelPadding: EdgeInsets.zero,
labelStyle: const TextStyle(fontSize: 11, fontWeight: FontWeight.w400),
unselectedLabelStyle: const TextStyle(
fontSize: 11,
fontWeight: FontWeight.w400,
),
indicator: const UnderlineTabIndicator(
borderSide: BorderSide(color: DarkThemeColors.accentColor, width: 2.0),
),
overlayColor: WidgetStateProperty.resolveWith<Color>((states) {
return DarkThemeColors.lightGrey;
}),
),
appBarTheme: const AppBarTheme(
elevation: 0,
centerTitle: true,
scrolledUnderElevation: 0,
foregroundColor: DarkThemeColors.scaffoldBackgroundColor,
backgroundColor: DarkThemeColors.scaffoldBackgroundColor,
surfaceTintColor: DarkThemeColors.scaffoldBackgroundColor,
shadowColor: Colors.black,
titleTextStyle: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w700,
color: DarkThemeColors.textColor,
),
toolbarHeight: 56,
iconTheme: IconThemeData(color: DarkThemeColors.primaryColor),
),
inputDecorationTheme: const InputDecorationTheme(
alignLabelWithHint: true,
contentPadding: EdgeInsets.all(16),
labelStyle: TextStyle(
color: DarkThemeColors.textColor,
fontSize: 16,
fontWeight: FontWeight.w400,
),
hintStyle: TextStyle(
color: DarkThemeColors.secondaryText,
fontSize: 16,
fontWeight: FontWeight.w400,
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(16)),
borderSide: BorderSide(color: DarkThemeColors.errorColor),
),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(16)),
borderSide: BorderSide(color: DarkThemeColors.borderColor),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(16)),
borderSide: BorderSide(color: DarkThemeColors.borderColor),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(16)),
borderSide: BorderSide(color: DarkThemeColors.primaryColor),
),
disabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(16)),
borderSide: BorderSide(color: DarkThemeColors.white10Transparent),
),
focusedErrorBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(16)),
borderSide: BorderSide(color: DarkThemeColors.errorColor),
),
filled: true,
isDense: true,
fillColor: DarkThemeColors.edittextBackground,
floatingLabelAlignment: FloatingLabelAlignment.start,
floatingLabelBehavior: FloatingLabelBehavior.always,
),
elevatedButtonTheme: ElevatedButtonThemeData(
style: ButtonStyle(
overlayColor: WidgetStateProperty.resolveWith<Color?>((
Set<WidgetState> states,
) {
if (states.contains(WidgetState.hovered)) {
return DarkThemeColors.errorColor;
}
return null;
}),
elevation: WidgetStateProperty.all<double>(0),
textStyle: WidgetStateProperty.all<TextStyle>(
const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w700,
color: DarkThemeColors.buttonColorText,
),
),
foregroundColor: WidgetStateProperty.resolveWith<Color>((states) {
if (states.contains(WidgetState.disabled)) {
return DarkThemeColors.white60Transparent;
} else {
return DarkThemeColors.buttonColorText;
}
}),
backgroundColor: WidgetStateProperty.resolveWith<Color>((states) {
if (states.contains(WidgetState.disabled)) {
return DarkThemeColors.disabledColor;
} else {
return DarkThemeColors.primaryColor;
}
}),
maximumSize: WidgetStateProperty.all<Size>(
const Size(double.infinity, 56),
),
minimumSize: WidgetStateProperty.all<Size>(
const Size(double.infinity, 56),
),
shape: WidgetStateProperty.all<RoundedRectangleBorder>(
const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(24)),
),
),
),
),
bottomNavigationBarTheme: const BottomNavigationBarThemeData(
backgroundColor: DarkThemeColors.scaffoldBackgroundColor,
type: BottomNavigationBarType.fixed,
showSelectedLabels: true,
selectedLabelStyle: TextStyle(fontSize: 12, fontWeight: FontWeight.w500),
unselectedLabelStyle: TextStyle(fontSize: 12, fontWeight: FontWeight.w500),
unselectedItemColor: DarkThemeColors.lightSecondary,
selectedItemColor: DarkThemeColors.primaryColor,
selectedIconTheme: IconThemeData(size: 25),
unselectedIconTheme: IconThemeData(size: 25),
elevation: 2,
),
textButtonTheme: TextButtonThemeData(
style: ButtonStyle(
padding: WidgetStateProperty.all(
const EdgeInsets.symmetric(horizontal: 8, vertical: 8),
),
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
elevation: WidgetStateProperty.all<double>(2),
foregroundColor: WidgetStateProperty.resolveWith<Color>((states) {
return DarkThemeColors.scaffoldBackgroundColor;
}),
backgroundColor: WidgetStateProperty.resolveWith<Color>((states) {
if (states.contains(WidgetState.disabled)) {
return Colors.transparent;
} else {
return Colors.transparent;
}
}),
maximumSize: WidgetStateProperty.all<Size>(
const Size(double.infinity, double.infinity),
),
minimumSize: WidgetStateProperty.all<Size>(
const Size(double.minPositive, double.minPositive),
),
shape: WidgetStateProperty.all<RoundedRectangleBorder>(
const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
),
),
textStyle: WidgetStateProperty.all<TextStyle>(
const TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
color: DarkThemeColors.accentColor,
),
),
// overlayColor: WidgetStateProperty.resolveWith<Color>((states) {
// return DarkThemeColors.lightGrey;
// }),
),
),
bottomSheetTheme: const BottomSheetThemeData(
backgroundColor: Colors.transparent,
// surfaceTintColor: Colors.transparent,
modalBackgroundColor: Colors.transparent,
modalElevation: 0,
elevation: 0,
),
);

View File

@@ -0,0 +1,118 @@
import 'package:cargocalculaterapp/core/theme/colors/app_colors.dart';
import 'package:flutter/material.dart';
import 'app_text_styles.dart';
@immutable
class ThemeTextStyles extends ThemeExtension<ThemeTextStyles> {
final TextStyle profileCategory;
final TextStyle titleBig;
final TextStyle authTitle;
final TextStyle categoryName;
final TextStyle bigTitle;
final TextStyle statusText;
final TextStyle authDesc;
final TextStyle orderListTitle;
final TextStyle orderTitle;
final TextStyle statusNumber;
final TextStyle statusDesc;
final TextStyle secondaryText14;
@override
ThemeExtension<ThemeTextStyles> copyWith({
TextStyle? profileCategory,
TextStyle? titleBig,
TextStyle? authTitle,
TextStyle? categoryName,
TextStyle? bigTitle,
TextStyle? statusText,
TextStyle? authDesc,
TextStyle? orderListTitle,
TextStyle? orderTitle,
TextStyle? statusNumber,
TextStyle? statusDesc,
TextStyle? secondaryText14,
}) {
return ThemeTextStyles(
profileCategory: profileCategory ?? this.profileCategory,
titleBig: titleBig ?? this.titleBig,
authTitle: authTitle ?? this.authTitle,
categoryName: categoryName ?? this.categoryName,
bigTitle: bigTitle ?? this.bigTitle,
statusText: statusText ?? this.statusText,
authDesc: authDesc ?? this.authDesc,
orderListTitle: orderListTitle ?? this.orderListTitle,
orderTitle: orderTitle ?? this.orderTitle,
statusNumber: statusNumber ?? this.statusNumber,
statusDesc: statusDesc ?? this.statusDesc,
secondaryText14: secondaryText14 ?? this.secondaryText14,
);
}
const ThemeTextStyles({
required this.profileCategory,
required this.titleBig,
required this.authTitle,
required this.categoryName,
required this.bigTitle,
required this.statusText,
required this.authDesc,
required this.orderListTitle,
required this.orderTitle,
required this.statusNumber,
required this.statusDesc,
required this.secondaryText14,
});
static get light => const ThemeTextStyles(
profileCategory: AppTextStyles.profileCategory,
titleBig: AppTextStyles.titleBig,
authTitle: AppTextStyles.authTitle,
categoryName: AppTextStyles.categoryName,
bigTitle: AppTextStyles.bigTitle,
statusText: AppTextStyles.statusText,
authDesc: AppTextStyles.authDesc,
orderListTitle: AppTextStyles.orderListTitle,
orderTitle: AppTextStyles.orderTitle,
statusNumber: AppTextStyles.statusNumber,
statusDesc: AppTextStyles.statusDesc,
secondaryText14: AppTextStyles.secondaryText14,
);
static get dark => ThemeTextStyles(
profileCategory: AppTextStyles.profileCategory.copyWith(
color: DarkThemeColors.textColor,
),
titleBig: AppTextStyles.titleBig.copyWith(color: DarkThemeColors.textColor),
authTitle: AppTextStyles.authTitle.copyWith(color: DarkThemeColors.textColor),
categoryName: AppTextStyles.categoryName.copyWith(color: DarkThemeColors.textColor),
bigTitle: AppTextStyles.bigTitle.copyWith(color: DarkThemeColors.textColor),
statusText: AppTextStyles.statusText.copyWith(color: DarkThemeColors.buttonColorText),
authDesc: AppTextStyles.authDesc.copyWith(color: DarkThemeColors.secondaryText),
orderListTitle: AppTextStyles.orderListTitle.copyWith(color: DarkThemeColors.secondaryText),
orderTitle: AppTextStyles.orderTitle.copyWith(color: DarkThemeColors.textColor),
statusNumber: AppTextStyles.statusNumber.copyWith(color: DarkThemeColors.secondaryText),
statusDesc: AppTextStyles.statusDesc.copyWith(color: DarkThemeColors.textColor),
secondaryText14: AppTextStyles.secondaryText14.copyWith(color: DarkThemeColors.lightSecondary),
);
@override
ThemeTextStyles lerp(ThemeExtension<ThemeTextStyles>? other, double t) {
if (other is! ThemeTextStyles) return this;
return ThemeTextStyles(
profileCategory: TextStyle.lerp(profileCategory, other.profileCategory, t)!,
titleBig: TextStyle.lerp(titleBig, other.titleBig, t)!,
authTitle: TextStyle.lerp(authTitle, other.authTitle, t)!,
categoryName: TextStyle.lerp(categoryName, other.categoryName, t)!,
bigTitle: TextStyle.lerp(bigTitle, other.bigTitle, t)!,
statusText: TextStyle.lerp(statusText, other.statusText, t)!,
authDesc: TextStyle.lerp(authDesc, other.authDesc, t)!,
orderListTitle: TextStyle.lerp(orderListTitle, other.orderListTitle, t)!,
orderTitle: TextStyle.lerp(orderTitle, other.orderTitle, t)!,
statusNumber: TextStyle.lerp(statusNumber, other.statusNumber, t)!,
statusDesc: TextStyle.lerp(statusDesc, other.statusDesc, t)!,
secondaryText14: TextStyle.lerp(secondaryText14, other.secondaryText14, t)!,
);
}
}

View File

@@ -0,0 +1,14 @@
import 'package:dartz/dartz.dart';
import 'package:equatable/equatable.dart';
import '../error/failure.dart';
abstract class UseCase<Type, Params> {
Future<Either<Failure, Type>> call(Params params);
}
class NoParams extends Equatable {
const NoParams();
@override
List<Object?> get props => [];
}

View File

@@ -0,0 +1,484 @@
import 'package:flutter/material.dart';
import '../theme/colors/app_colors.dart';
class AppUtils {
AppUtils._();
static const kDividerR = Divider(
height: 1,
thickness: 1,
color: LightThemeColors.dividerColor,
);
static const kGap12 = SliverToBoxAdapter(child: kBoxHeight12);
static const kGap16 = SliverToBoxAdapter(child: kBoxHeight16);
static const kGap8 = SliverToBoxAdapter(child: kBoxHeight8);
static const kGap4 = SliverToBoxAdapter(child: kBoxHeight4);
static const kGap10 = SliverToBoxAdapter(child: kBoxHeight10);
static const kGap22 = SliverToBoxAdapter(child: kBoxHeight22);
static const kGap24 = SliverToBoxAdapter(child: kBoxHeight24);
static const kGapBox = SliverToBoxAdapter(child: SizedBox());
static const kBoxWith4 = SizedBox(width: 4);
static const kBoxWith8 = SizedBox(width: 8);
static const kBoxWith12 = SizedBox(width: 12);
/// divider
static const kDivider = Divider(
height: 2,
thickness: 2,
color: LightThemeColors.dividerColor,
);
static const kPad16Divider = Divider(
height: 2,
thickness: 2,
indent: 16,
color: LightThemeColors.dividerColor,
);
static const kGap16Divider = SliverToBoxAdapter(child: kPadHor16Divider);
static const kPadHor16Divider = Divider(
height: 1,
thickness: 1,
indent: 16,
endIndent: 16,
);
static const kPad60Divider = Padding(
padding: EdgeInsets.only(left: 60),
child: Divider(height: 1, thickness: 1),
);
/// spacer
static const kSpacer = Spacer();
/// Sizedbox
static const kBox = SizedBox.shrink();
static const kBoxHeight2 = SizedBox(height: 2);
static const kBoxHeight3 = SizedBox(height: 3);
static const kBoxHeight4 = SizedBox(height: 4);
static const kBoxHeight6 = SizedBox(height: 6);
static const kBoxHeight8 = SizedBox(height: 8);
static const kBoxHeight10 = SizedBox(height: 10);
static const kBoxHeight12 = SizedBox(height: 12);
static const kBoxHeight14 = SizedBox(height: 14);
static const kBoxHeight16 = SizedBox(height: 16);
static const kBoxHeight18 = SizedBox(height: 18);
static const kBoxHeight20 = SizedBox(height: 20);
static const kBoxHeight22 = SizedBox(height: 22);
static const kBoxHeight24 = SizedBox(height: 24);
static const kBoxHeight26 = SizedBox(height: 26);
static const kBoxHeight28 = SizedBox(height: 28);
static const kBoxHeight40 = SizedBox(height: 40);
static const kBoxHeight42 = SizedBox(height: 42);
static const kBoxHeight38 = SizedBox(height: 48);
static const kBoxHeight45 = SizedBox(height: 45);
static const kBoxHeight48 = SizedBox(height: 48);
static const kBoxHeight58 = SizedBox(height: 58);
static const kBoxHeight30 = SizedBox(height: 30);
static const kBoxHeight32 = SizedBox(height: 32);
static const kBoxHeight34 = SizedBox(height: 34);
static const kBoxHeight36 = SizedBox(height: 36);
static const kBoxHeight64 = SizedBox(height: 64);
static const kBoxHeight84 = SizedBox(height: 84);
static const kBoxHeight124 = SizedBox(height: 124);
static const kBoxHeight204 = SizedBox(height: 204);
static const kBoxWidth2 = SizedBox(width: 2);
static const kBoxWidth8 = SizedBox(width: 8);
static const kBoxWidth6 = SizedBox(width: 6);
static const kBoxWidth4 = SizedBox(width: 4);
static const kBoxWidth3 = SizedBox(width: 3);
static const kBoxWidth10 = SizedBox(width: 10);
static const kBoxWidth12 = SizedBox(width: 12);
static const kBoxWidth14 = SizedBox(width: 14);
static const kBoxWidth20 = SizedBox(width: 20);
static const kBoxWidth16 = SizedBox(width: 16);
static const kBoxWidth22 = SizedBox(width: 22);
static const kBoxWidth24 = SizedBox(width: 24);
static const kBoxWidth30 = SizedBox(width: 30);
static const kBoxWidth40 = SizedBox(width: 40);
static const kBoxWidth56 = SizedBox(width: 56);
static const kBoxWidth95 = SizedBox(width: 95);
/// padding
static const kPaddingAll4 = EdgeInsets.all(4);
static const kPaddingAll3 = EdgeInsets.all(3);
static const kPaddingAll2 = EdgeInsets.all(2);
static const kPaddingAll1 = EdgeInsets.all(1);
static const kPaddingHorizontal12Vertical8 = EdgeInsets.symmetric(
horizontal: 12.0,
vertical: 8,
);
static const kPaddingHorizontal12Vertical10 = EdgeInsets.symmetric(
horizontal: 12,
);
static const kPaddingVer10 = EdgeInsets.symmetric(vertical: 10);
static const kPaddingAll6 = EdgeInsets.all(6);
static const kPaddingHorizontal16Vertical8 = EdgeInsets.symmetric(
horizontal: 16.0,
vertical: 8,
);
static const kPaddingAll8 = EdgeInsets.all(8);
static const kPaddingAll12 = EdgeInsets.all(12);
static const kPaddingAll10 = EdgeInsets.all(10);
static const kPaddingAll16 = EdgeInsets.all(16);
static const kPaddingAll18 = EdgeInsets.all(18);
static const kPaddingAll20 = EdgeInsets.all(20);
static const kPaddingAllB16 = EdgeInsets.fromLTRB(16, 16, 16, 0);
static const kPaddingAll24 = EdgeInsets.all(24);
static const kPaddingHorizontal16 = EdgeInsets.symmetric(horizontal: 16);
static const kPaddingHorizontal16T0B8 = EdgeInsets.only(
left: 16,
right: 16,
bottom: 8,
top: 0,
);
static const kPaddingHorizontal16T0B16 = EdgeInsets.only(
left: 16,
right: 16,
bottom: 16,
top: 0,
);
static const kPaddingHorizontal32T32B20 = EdgeInsets.only(
left: 32,
right: 32,
bottom: 20,
top: 32,
);
static const kPaddingLTRB8 = EdgeInsets.only(
left: 16,
right: 16,
top: 16,
bottom: 8,
);
static const kPaddingL8T12R16B12 = EdgeInsets.only(
left: 12,
right: 16,
top: 12,
bottom: 8,
);
static const kPaddingLTR = EdgeInsets.only(left: 16, right: 16, top: 16);
static const kPaddingL37 = EdgeInsets.only(left: 37);
static const kPaddingT4R8B4 = EdgeInsets.only(right: 8, bottom: 4, top: 4);
static const kPaddingT24 = EdgeInsets.only(top: 24);
static const kPaddingR4 = EdgeInsets.only(right: 4);
static const kPaddingR10 = EdgeInsets.only(right: 10);
static const kPaddingR16 = EdgeInsets.only(right: 16);
static const kPaddingLT8RB = EdgeInsets.only(
left: 16,
right: 16,
top: 8,
bottom: 16,
);
static const kPaddingLT0RB = EdgeInsets.only(
left: 16,
right: 16,
top: 0,
bottom: 16,
);
static const kPadding12LTRB0 = EdgeInsets.only(
left: 12,
right: 12,
top: 12,
bottom: 0,
);
static const kPaddingTop10 = EdgeInsets.only(top: 10);
static const kPaddingTop15 = EdgeInsets.only(top: 15);
static const kPaddingTop21 = EdgeInsets.only(top: 21);
static const kPaddingTop24 = EdgeInsets.only(top: 24);
static const kPaddingTop28 = EdgeInsets.only(top: 28);
static const kPaddingTop20 = EdgeInsets.only(top: 40);
static const kPaddingL16R12 = EdgeInsets.only(left: 16, right: 12, bottom: 8);
static const kPaddingL16R12TB8 = EdgeInsets.only(
left: 16,
right: 12,
bottom: 8,
top: 8,
);
static const kPaddingL16R16T0B24 = EdgeInsets.only(
left: 16,
right: 16,
bottom: 24,
top: 0,
);
static const kPaddingL16R16T24B16 = EdgeInsets.only(
left: 16,
right: 16,
top: 24,
bottom: 16,
);
static const kPaddingL16R16T24B0 = EdgeInsets.only(
left: 16,
right: 16,
top: 24,
);
static const kPaddingL16R16T16B24 = EdgeInsets.only(
left: 16,
right: 16,
top: 16,
bottom: 24,
);
static const kPaddingL8T8 = EdgeInsets.only(left: 8, top: 8);
static const kPaddingL60 = EdgeInsets.only(left: 60);
static const kPaddingT20B24R16 = EdgeInsets.only(
top: 20,
bottom: 24,
right: 16,
);
static const kPaddingL16T20B24 = EdgeInsets.only(
left: 16,
top: 20,
bottom: 24,
);
static const kPaddingR20T16B16 = EdgeInsets.only(
right: 20,
top: 16,
bottom: 16,
);
static const kPaddingHor32Ver20 = EdgeInsets.symmetric(
horizontal: 32,
vertical: 20,
);
static const kPaddingHor16 = EdgeInsets.symmetric(horizontal: 16);
static const kPaddingHor4 = EdgeInsets.symmetric(horizontal: 4);
static const kPaddingHor6 = EdgeInsets.symmetric(horizontal: 6);
static const kPaddingVer12 = EdgeInsets.symmetric(vertical: 12);
static const kPaddingVer16 = EdgeInsets.symmetric(vertical: 16);
static const kPaddingVer24 = EdgeInsets.symmetric(vertical: 24);
static const kPaddingVer44 = EdgeInsets.symmetric(vertical: 44);
static const kPaddingHor18 = EdgeInsets.symmetric(horizontal: 18);
static const kPaddingHor20 = EdgeInsets.symmetric(horizontal: 20);
static const kPaddingHor24 = EdgeInsets.symmetric(horizontal: 24);
static const kPaddingHor28 = EdgeInsets.symmetric(horizontal: 28);
static const kPaddingHor12 = EdgeInsets.symmetric(horizontal: 12);
static const kPaddingHor10 = EdgeInsets.symmetric(horizontal: 10);
static const kPaddingHor32 = EdgeInsets.symmetric(horizontal: 32);
static const kPaddingHor34 = EdgeInsets.symmetric(horizontal: 34);
static const kPaddingHor36 = EdgeInsets.symmetric(horizontal: 36);
static const kPaddingHor38 = EdgeInsets.symmetric(horizontal: 38);
static const kPaddingHor44 = EdgeInsets.symmetric(horizontal: 44);
static const kPaddingVer8 = EdgeInsets.symmetric(vertical: 8);
static const kPaddingHor16Ver12 = EdgeInsets.symmetric(
horizontal: 16,
vertical: 12,
);
static const kPaddingHor12Ver16 = EdgeInsets.symmetric(
horizontal: 12,
vertical: 16,
);
static const kPaddingHor32Ver16 = EdgeInsets.symmetric(
horizontal: 32,
vertical: 16,
);
static const kPaddingHor16Ver8 = EdgeInsets.symmetric(
horizontal: 16,
vertical: 8,
);
static const kPaddingHor8Ver4 = EdgeInsets.symmetric(
horizontal: 8,
vertical: 4,
);
static const kPaddingHor8Ver5 = EdgeInsets.symmetric(
horizontal: 8,
vertical: 5,
);
static const kPaddingHor6Ver4 = EdgeInsets.symmetric(
horizontal: 6,
vertical: 4,
);
static const kPaddingHor12Ver8 = EdgeInsets.symmetric(
horizontal: 12,
vertical: 8,
);
static const kPaddingVer10Hor16 = EdgeInsets.symmetric(
vertical: 10,
horizontal: 16,
);
static const kPaddingVer12Hor18 = EdgeInsets.symmetric(
vertical: 8,
horizontal: 16,
);
static const kPaddingVer8Hor12 = EdgeInsets.symmetric(
vertical: 8,
horizontal: 12,
);
static const kPaddingVer10Hor12 = EdgeInsets.symmetric(
vertical: 10,
horizontal: 12,
);
static const kPaddingVer2Hor4 = EdgeInsets.symmetric(
vertical: 2,
horizontal: 4,
);
static const kPaddingVer2Hor8 = EdgeInsets.symmetric(
vertical: 2,
horizontal: 8,
);
static const kPaddingVer3Hor10 = EdgeInsets.symmetric(
vertical: 3,
horizontal: 10,
);
static const kPaddingVer2Hor10 = EdgeInsets.symmetric(
vertical: 2,
horizontal: 10,
);
static const kPaddingVer2Hor6 = EdgeInsets.symmetric(
vertical: 2,
horizontal: 6,
);
static const kPaddingVer5Hor2 = EdgeInsets.symmetric(
vertical: 5,
horizontal: 2,
);
static const kPaddingVer18Hor16 = EdgeInsets.symmetric(
vertical: 18,
horizontal: 16,
);
static const kPaddingVer24Hor16 = EdgeInsets.symmetric(
vertical: 24,
horizontal: 16,
);
static const kPaddingVer24Hor8 = EdgeInsets.symmetric(
vertical: 24,
horizontal: 8,
);
static const kPaddingVer14Hor12 = EdgeInsets.symmetric(
vertical: 14,
horizontal: 12,
);
static const kPaddingVer14Hor16 = EdgeInsets.symmetric(
vertical: 14,
horizontal: 16,
);
static const kPaddingVer16Hor24 = EdgeInsets.symmetric(
vertical: 16,
horizontal: 24,
);
static const kPaddingVer4Hor12 = EdgeInsets.symmetric(
vertical: 4,
horizontal: 12,
);
static const kPaddingVer4Hor16 = EdgeInsets.symmetric(
vertical: 4,
horizontal: 16,
);
static const kPaddingVer6Hor12 = EdgeInsets.symmetric(
vertical: 6,
horizontal: 12,
);
static const kPaddingVer12Hor14 = EdgeInsets.symmetric(
vertical: 12,
horizontal: 14,
);
static const kPaddingVer28Hor28 = EdgeInsets.symmetric(
vertical: 28,
horizontal: 28,
);
/// border radius
static const kRadius = Radius.zero;
static const kRadius8 = Radius.circular(8);
static const kRadius6 = Radius.circular(6);
static const kRadius12 = Radius.circular(12);
static const kBorderRadius = BorderRadius.all(Radius.circular(0));
static const kBorderRadius2 = BorderRadius.all(Radius.circular(2));
static const kBorderRadius4 = BorderRadius.all(Radius.circular(4));
static const kBorderRadius5 = BorderRadius.all(Radius.circular(5));
static const kBorderRadius6 = BorderRadius.all(Radius.circular(6));
static const kBorderRadius8 = BorderRadius.all(Radius.circular(8));
static const kBorderRadiusTop8 = BorderRadius.only(
topLeft: Radius.circular(8),
topRight: Radius.circular(8),
);
static const kBorderRadiusTop10 = BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10),
);
static const kBorderRadiusTop12 = BorderRadius.only(
topLeft: Radius.circular(12),
topRight: Radius.circular(12),
);
static const kBorderRadiusTop16 = BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16),
);
static const kBorderRadiusBottom16 = BorderRadius.only(
bottomLeft: Radius.circular(16),
bottomRight: Radius.circular(16),
);
static const kBorderRadiusTop24 = BorderRadius.only(
topLeft: Radius.circular(24),
topRight: Radius.circular(24),
);
static const kBorderRadiusBottom8 = BorderRadius.only(
bottomLeft: Radius.circular(8),
bottomRight: Radius.circular(8),
);
static const kBorderRadiusBottom10 = BorderRadius.only(
bottomLeft: Radius.circular(10),
bottomRight: Radius.circular(10),
);
static const kBorderRadiusTopBot12 = BorderRadius.only(
topRight: AppUtils.kRadius12,
bottomRight: AppUtils.kRadius12,
);
static const kBorderRadiusLeftTopBob12 = BorderRadius.only(
topLeft: AppUtils.kRadius12,
bottomLeft: AppUtils.kRadius12,
);
static const kBorderRadius12 = BorderRadius.all(Radius.circular(12));
static const kBorderRadius10 = BorderRadius.all(Radius.circular(10));
static const kBorderRadius16 = BorderRadius.all(Radius.circular(16));
static const kBorderRadius14 = BorderRadius.all(Radius.circular(14));
static const kBorderRadius24 = BorderRadius.all(Radius.circular(24));
static const kBorderRadius20 = BorderRadius.all(Radius.circular(20));
static const kBorderRadius32 = BorderRadius.all(Radius.circular(32));
static const kBorderRadius48 = BorderRadius.all(Radius.circular(48));
static const kBorderRadius64 = BorderRadius.all(Radius.circular(64));
// static const kBoxDecoration = BoxDecoration(
// borderRadius: AppUtils.kBorderRadius24,
// color: LightThemeColors.whiteBackground,
// );
// static const kBoxDecorationGray = BoxDecoration(
// borderRadius: AppUtils.kBorderRadius24,
// color: LightThemeColors.backgroundGray,
// );
//
// static const kBoxDecoration12 = BoxDecoration(
// borderRadius: AppUtils.kBorderRadius12,
// color: LightThemeColors.whiteBackground,
// );
// static const kBoxDecoration12BorderColor = BoxDecoration(
// borderRadius: AppUtils.kBorderRadius12,
// color: LightThemeColors.badgeGray,
// );
// static const kBoxDecoration12Gray = BoxDecoration(
// borderRadius: AppUtils.kBorderRadius12,
// color: LightThemeColors.scaffoldBackgroundColor,
// );
// static BoxDecoration kBoxDecoration12WhiteBorderRed = BoxDecoration(
// borderRadius: AppUtils.kBorderRadius12,
// color: LightThemeColors.whiteBackground,
// border: Border.all(color: LightThemeColors.red),
// );
// static const kBoxDecorationTop24 = BoxDecoration(
// color: LightThemeColors.white,
// borderRadius: AppUtils.kBorderRadiusTop24,
// );
// static const kBoxDecorationTop = BoxDecoration(
// borderRadius: BorderRadius.only(
// topLeft: Radius.circular(24),
// topRight: Radius.circular(24),
// ),
// color: LightThemeColors.whiteBackground,
// );
// static const kBoxDecorationBottom = BoxDecoration(
// borderRadius: BorderRadius.only(
// bottomLeft: Radius.circular(24),
// bottomRight: Radius.circular(24),
// ),
// color: LightThemeColors.whiteBackground,
// );
}

View File

@@ -0,0 +1,99 @@
import 'package:cargocalculaterapp/constants/constants.dart';
import 'package:cargocalculaterapp/core/extension/build_context_extension.dart';
import 'package:cargocalculaterapp/core/functions/base_finctions.dart';
import 'package:cargocalculaterapp/generated/l10n.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import '../../theme/app_text_styles.dart';
import '../../utils/app_utils.dart';
class CustomDropDown extends StatelessWidget {
const CustomDropDown({
super.key,
this.name,
required this.isRequired,
this.errorText,
this.isError,
this.style,
required this.onChange,
this.value,
});
final String? name;
final bool isRequired;
final String? errorText;
final bool? isError;
final TextStyle? style;
final String? value;
final Function(String?) onChange;
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (name?.isNotEmpty ?? false)
Text(name ?? '', style: style ?? context.text.categoryName),
AppUtils.kBoxWidth4,
if (isRequired) SvgPicture.asset("assets/svg/ic_required.svg"),
],
),
AppUtils.kBoxHeight8,
InputDecorator(
decoration: InputDecoration(
fillColor: context.color.white10Transparent,
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: context.color.borderColor,
),
borderRadius: AppUtils.kBorderRadius12,
),
contentPadding: AppUtils.kPaddingAll16,
),
child: DropdownButtonHideUnderline(
child: DropdownButton(
dropdownColor: context.color.grayBackground,
hint: Text(AppLocalization.current.warehouse,style: TextStyle(
color: context.color.secondaryText,
fontSize: 16,
fontWeight: FontWeight.w400,
),),
icon: Icon(
Icons.keyboard_arrow_down_outlined,
size: 24,
color: context.color.textColor,
),
isDense: true,
iconSize: 0,
value: value,
items:
AppConst.warehouseOptions.keys.map((entry) {
return DropdownMenuItem(
value: entry,
child: Text(
Functions.getTranslatedItem(
AppConst.warehouseOptions[entry],
context,
),
style: context.text.profileCategory,
),
);
}).toList(),
onChanged: onChange,
),
),
),
if (isError ?? false) AppUtils.kBoxHeight4,
if (isError ?? false)
Text(
errorText ?? "",
style: AppTextStyles.timer.copyWith(fontSize: 12),
),
],
);
}
}

View File

@@ -0,0 +1,24 @@
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import '../../theme/colors/app_colors.dart';
class CustomLoadingWidget extends StatelessWidget {
final Color? color;
const CustomLoadingWidget({super.key, this.color});
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Platform.isAndroid
? CircularProgressIndicator(
color: color ?? LightThemeColors.lightGrey,
)
: CupertinoActivityIndicator(color: color),
],
);
}
}

View File

@@ -0,0 +1,90 @@
import "dart:io";
import "package:cargocalculaterapp/core/theme/colors/app_colors.dart";
import "package:flutter/cupertino.dart";
import "package:flutter/material.dart";
import "dart:ui";
///
/// Wrap around any widget that makes an async call to show a modal progress
/// indicator while the async call is in progress.
///
/// HUD=Heads Up Display
///
class ModalProgressHUD extends StatelessWidget {
/// A required [bool] to toggle the modal overlay.
final bool inAsyncCall;
/// A [double] specifying the opacity of the modal overlay, defaults to 0.3
final double opacity;
/// A [Color] object which is assigned to the loading barrier, defaults to grey
final Color color;
/// A [Widget] which is shown at the center of the modal overlay,
/// defaults to the standard android spinner animation.
/// An [Offset] object which is applied to the [progressIndicator] when specified.
final Offset? offset;
/// A [bool] which controls whether the modal overlay can be dismissible when interated.
final bool dismissible;
/// A [Widget] over which the modal overlay is activated.
final Widget child;
/// A [double] value specifying the amount of background blur when progress hud is active.
final double blur;
const ModalProgressHUD({
super.key,
required this.inAsyncCall,
this.opacity = 0.3,
this.color = Colors.grey,
this.offset,
this.dismissible = false,
required this.child,
this.blur = 0.0,
});
@override
Widget build(BuildContext context) {
Widget layOutProgressIndicator;
if (offset == null) {
layOutProgressIndicator = Center(
child:
Platform.isIOS
? const CupertinoActivityIndicator()
: const CircularProgressIndicator(
color: LightThemeColors.accentColor,
),
);
} else {
layOutProgressIndicator = Positioned(
left: offset!.dx,
top: offset!.dy,
child:
Platform.isIOS
? const CupertinoActivityIndicator()
: const CircularProgressIndicator(
color: LightThemeColors.accentColor,
),
);
}
return Stack(
children: [
child,
if (inAsyncCall) ...[
BackdropFilter(
filter: ImageFilter.blur(sigmaX: blur, sigmaY: blur),
child: Opacity(
opacity: opacity,
child: ModalBarrier(dismissible: dismissible, color: color),
),
),
layOutProgressIndicator,
],
],
);
}
}

View File

@@ -0,0 +1,95 @@
import 'package:cargocalculaterapp/core/extension/extension.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import '../../utils/app_utils.dart';
typedef RatingChangeCallback = void Function(double rating)?;
const starPoints = 5;
class RatingBarWidget extends StatelessWidget {
final double rating;
final double iconsSize;
final Color activeRatingColor;
final Color inactiveRatingColor;
final RatingChangeCallback onRatingChanged;
final bool isAnimate;
final Widget separator;
final bool isSharp;
const RatingBarWidget({
super.key,
required this.rating,
this.iconsSize = 18,
this.activeRatingColor = const Color(0xffFFA047),
this.inactiveRatingColor = const Color(0xffCED5DF),
this.onRatingChanged,
this.isAnimate = false,
this.separator = AppUtils.kBoxWidth3,
this.isSharp = false,
});
@override
Widget build(BuildContext context) {
if (isAnimate) {
return TweenAnimationBuilder<double>(
duration: const Duration(milliseconds: 350),
curve: Curves.easeInOut,
tween: Tween<double>(begin: 0, end: rating),
builder: (_, value, __) {
return Row(
mainAxisSize: MainAxisSize.min,
children: List.generate(
10,
(index) => index.isEven
? buildStar(index.exactIndex, rating, isSharp)
: separator,
),
);
},
);
}
return Row(
mainAxisSize: MainAxisSize.min,
children: List.generate(
10,
(index) => index.isEven
? buildStar(index.exactIndex, rating, isSharp)
: separator,
),
);
}
Widget buildStar(int index, double rating, isSharp) {
Widget icon;
double present = rating - index;
icon = ShaderMask(
blendMode: BlendMode.srcIn,
shaderCallback: (bounds) {
return LinearGradient(
tileMode: TileMode.clamp,
colors: [activeRatingColor, inactiveRatingColor],
begin: Alignment.centerLeft,
end: Alignment.centerRight,
stops: [present, present],
).createShader(bounds);
},
child: SvgPicture.asset(
isSharp
? "assets/svg/ic_star_selected.svg"
: "assets/svg/ic_star_selected.svg",
height: iconsSize,
width: iconsSize,
),
);
return InkResponse(
onTap: onRatingChanged == null
? null
: () => onRatingChanged!(index + 1.0),
child: icon,
);
}
}

View File

@@ -0,0 +1,40 @@
import 'package:flutter/material.dart';
import 'package:shimmer/shimmer.dart';
import '../../theme/colors/app_colors.dart';
import '../../utils/app_utils.dart';
class ShimmerWidget extends StatelessWidget {
const ShimmerWidget({
super.key,
required this.width,
required this.height,
this.borderRadius = AppUtils.kBorderRadius6,
this.margin,
});
final double width;
final double height;
final BorderRadiusGeometry? borderRadius;
final EdgeInsetsGeometry? margin;
@override
Widget build(BuildContext context) {
return Shimmer.fromColors(
enabled: true,
baseColor:
Theme.of(context).brightness == Brightness.dark
? const Color(0x80FFFFFF)
: const Color(0xffF8F8F9),
highlightColor: LightThemeColors.shimmerHighlight,
child: Container(
width: width,
height: height,
margin: margin,
decoration: BoxDecoration(
color: LightThemeColors.white,
borderRadius: borderRadius,
),
),
);
}
}

View File

@@ -0,0 +1,108 @@
import 'package:cargocalculaterapp/core/extension/build_context_extension.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/svg.dart';
import '../../theme/app_text_styles.dart';
import '../../theme/colors/app_colors.dart';
import '../../utils/app_utils.dart';
class CustomTextFieldName extends StatelessWidget {
const CustomTextFieldName({
super.key,
this.name,
required this.hint,
this.readOnly = false,
this.onTap,
this.prefixWidget,
this.controller,
this.format,
this.inputType,
this.onchange,
this.style,
this.suffix,
this.errorText,
this.isError,
this.isRequired = false,
this.maxLines,
this.minLines,
this.inputStyle,
this.textCapitalization = TextCapitalization.sentences,
this.fillColor,
this.obscureText = false,
});
final String? name;
final String hint;
final bool readOnly;
final Function()? onTap;
final Widget? prefixWidget;
final TextEditingController? controller;
final List<TextInputFormatter>? format;
final TextInputType? inputType;
final bool isRequired;
final Function(String)? onchange;
final TextStyle? style;
final Widget? suffix;
final String? errorText;
final bool? isError;
final int? maxLines;
final int? minLines;
final TextStyle? inputStyle;
final TextCapitalization textCapitalization;
final Color? fillColor;
final bool obscureText;
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (name?.isNotEmpty ?? false)
Text(name ?? '', style: style ?? context.text.categoryName),
AppUtils.kBoxWidth4,
if (isRequired) SvgPicture.asset("assets/svg/ic_required.svg"),
],
),
AppUtils.kBoxHeight8,
TextField(
style: inputStyle ?? TextStyle(color: context.color.textColor),
keyboardType: inputType,
controller: controller,
onTap: onTap,
readOnly: readOnly,
onChanged: onchange,
inputFormatters: format,
maxLines: maxLines,
minLines: minLines,
obscureText: obscureText,
textCapitalization: textCapitalization,
decoration: InputDecoration(
fillColor: fillColor,
hintText: hint,
prefixIcon: prefixWidget,
suffixIcon: suffix,
focusedBorder: OutlineInputBorder(
borderRadius: AppUtils.kBorderRadius16,
borderSide: BorderSide(
color:
!(isError ?? false)
? context.color.accentColor
: ThemeColors.timerRed,
),
),
),
),
if (isError ?? false) AppUtils.kBoxHeight4,
if (isError ?? false)
Text(
errorText ?? "",
style: AppTextStyles.timer.copyWith(fontSize: 12),
),
],
);
}
}