first commit

This commit is contained in:
2026-03-24 15:03:35 +01:00
commit cdba16ebe8
162 changed files with 194406 additions and 0 deletions

View File

@@ -0,0 +1,132 @@
class AppConstants {
// API
static const String baseUrl = 'https://hha-app1.assecutor.de/hha';
static const int connectionTimeout = 30000;
static const int receiveTimeout = 30000;
// Database
static const String databaseName = 'hha_logistics.db';
static const int databaseVersion = 1;
// App Info
static const String appName = 'HHA Logistics';
static const String appVersion = '2.0.0';
// Sync
static const Duration syncInterval = Duration(minutes: 1);
static const Duration locationUpdateInterval = Duration(seconds: 30);
}
class ObjectStates {
static const String unknown = 'unknown';
static const String toDelivery = 'to_delivery';
static const String delivery = 'delivery';
static const String station = 'station';
static const String inFA = 'in_fa';
static const String inVS = 'in_vs';
static const String retFail = 'ret_fail';
static const String retFailFzg = 'ret_fail_fzg';
static const String retFailStk = 'ret_fail_stk';
static const String retGI = 'ret_gi';
static const String retGIFzg = 'ret_gi_fzg';
static const String retGIStk = 'ret_gi_stk';
static const String retDS = 'ret_ds';
static const String retDSFzg = 'ret_ds_fzg';
static const String retDSStk = 'ret_ds_stk';
static const String retDSErr = 'ret_ds_err';
static const String retDSEmpty = 'ret_ds_empty';
static const String finDS = 'fin_ds';
static const String finGI = 'fin_gi';
static const String finDSFail = 'fin_ds_fail';
static const String finDSErr = 'fin_ds_err';
static const String hdl = 'hdl';
static const String stkHadag = 'stk_hadag';
static const String finGITmp = 'fin_gi_tmp';
static const String retcGI = 'retc_gi';
static const String retcDS = 'retc_ds';
static const String retDSFix = 'ret_ds_fix';
static const String retFixStk = 'ret_fix_stk';
static const String finFix = 'fin_fix';
static const String trig = 'trig';
}
class TourTypes {
static const String stockStart = 'stock_start';
static const String stock = 'stock';
static const String start = 'start';
static const String station = 'st';
static const String hls = 'hls';
static const String vs = 'vs';
static const String stockEnd = 'stock_end';
static const String end = 'end';
static const String fsa = 'fsa';
static const String gi = 'gi';
static const String veh = 'veh';
static const String vehStart = 'veh_start';
static const String vehBulk = 'veh_bulk';
static const String vehVs = 'veh_vs';
static const String vehEnd = 'veh_end';
static const String menu = 'me';
}
class ObjectTypes {
static const String gk = 'gk'; // Geldkassette
static const String hp = 'hp'; // HP Patronen
static const String fr = 'fr'; // Fahrkartenrolle
static const String sb = 'sb'; // Safebag
static const String abs = 'abs'; // Abfallbehälter
static const String cntr = 'cntr'; // Container
}
class ObjectSubtypes {
// Geldkassetten
static const String meka = 'meka';
static const String mekb = 'mekb';
static const String mekc = 'mekc';
static const String mekd = 'mekd';
static const String beka = 'beka';
static const String bekb = 'bekb';
static const String bekc = 'bekc';
static const String bekd = 'bekd';
// HP Patronen
static const String hp1a = 'hp1a';
static const String hp1b = 'hp1b';
static const String hp1c = 'hp1c';
static const String hp2a = 'hp2a';
static const String hp2b = 'hp2b';
static const String hp2c = 'hp2c';
static const String hp3a = 'hp3a';
static const String hp3b = 'hp3b';
static const String hp3c = 'hp3c';
// Fahrkartenrollen
static const String fra = 'fra';
// Container
static const String cntra = 'cntra';
static const String cntrb = 'cntrb';
}
class CounterLabels {
static const Map<String, String> labels = {
'meka': 'MEK',
'beka': 'BEK',
'hp1a': 'H1',
'hp2a': 'H2',
'hp3a': 'H3',
'fra': 'P',
'sb': 'SB',
'abs': 'ABS',
'mekb': 'MEK-B',
'bekb': 'BEK-B',
'hp1b': 'H1-B',
'hp2b': 'H2-B',
'mekc': 'MEK-SST',
'bekc': 'BEK-SST',
'hp1c': 'H1-SST',
'hp2c': 'H2-SST',
'mekd': 'MEK-CR',
'bekd': 'BEK-CR',
};
}

View File

@@ -0,0 +1,70 @@
import 'package:equatable/equatable.dart';
abstract class Failure extends Equatable {
final String message;
final String? code;
const Failure({
required this.message,
this.code,
});
@override
List<Object?> get props => [message, code];
}
class ServerFailure extends Failure {
const ServerFailure({
required super.message,
super.code,
});
}
class CacheFailure extends Failure {
const CacheFailure({
required super.message,
super.code,
});
}
class NetworkFailure extends Failure {
const NetworkFailure({
required super.message,
super.code,
});
}
class ValidationFailure extends Failure {
const ValidationFailure({
required super.message,
super.code,
});
}
class NotFoundFailure extends Failure {
const NotFoundFailure({
required super.message,
super.code,
});
}
class UnauthorizedFailure extends Failure {
const UnauthorizedFailure({
required super.message,
super.code,
});
}
class BarcodeFailure extends Failure {
const BarcodeFailure({
required super.message,
super.code,
});
}
class SyncFailure extends Failure {
const SyncFailure({
required super.message,
super.code,
});
}

View File

@@ -0,0 +1,273 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_fonts/google_fonts.dart';
class AppTheme {
// Brand Colors - HHA Corporate Colors
static const Color hhaRed = Color(0xFFE3001B);
static const Color hhaDarkRed = Color(0xFFB30015);
static const Color hhaLightRed = Color(0xFFFF4D5E);
// State Colors
static const Color stateDelivery = Color(0xFFB3B3B3);
static const Color stateStation = Color(0xFFFFDD00);
static const Color stateInFA = Color(0xFF9CDA7A);
static const Color stateRetFail = Color(0xFFFF9081);
static const Color stateRetDS = Color(0xFFAFE0ED);
static const Color stateRetGI = Color(0xFFAFE0ED);
static const Color stateFinDS = Color(0xFF29B7FB);
static const Color stateFinGI = Color(0xFF25BAFC);
static const Color stateInVS = Color(0xFFFAE14B);
// Functional Colors
static const Color success = Color(0xFF4CAF50);
static const Color warning = Color(0xFFFF9800);
static const Color error = Color(0xFFE3001B);
static const Color info = Color(0xFF2196F3);
// Neutral Colors
static const Color white = Color(0xFFFFFFFF);
static const Color background = Color(0xFFF5F5F5);
static const Color surface = Color(0xFFFFFFFF);
static const Color cardBackground = Color(0xFFFAFAFA);
static const Color divider = Color(0xFFE0E0E0);
// Text Colors
static const Color textPrimary = Color(0xFF212121);
static const Color textSecondary = Color(0xFF757575);
static const Color textTertiary = Color(0xFF9E9E9E);
static const Color textOnDark = Color(0xFFFFFFFF);
static ThemeData get lightTheme {
return ThemeData(
useMaterial3: true,
colorScheme: const ColorScheme.light(
primary: hhaRed,
primaryContainer: hhaLightRed,
onPrimaryContainer: white,
secondary: Color(0xFF2196F3),
onSurface: textPrimary,
surfaceContainerHighest: background,
error: error,
),
scaffoldBackgroundColor: background,
appBarTheme: AppBarTheme(
elevation: 0,
centerTitle: true,
backgroundColor: hhaRed,
foregroundColor: white,
titleTextStyle: GoogleFonts.inter(
fontSize: 20,
fontWeight: FontWeight.w600,
color: white,
),
systemOverlayStyle: const SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
statusBarIconBrightness: Brightness.light,
),
),
cardTheme: CardThemeData(
elevation: 2,
shadowColor: Colors.black.withValues(alpha: 26),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
color: surface,
),
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
elevation: 0,
backgroundColor: hhaRed,
foregroundColor: white,
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
textStyle: GoogleFonts.inter(
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
),
outlinedButtonTheme: OutlinedButtonThemeData(
style: OutlinedButton.styleFrom(
foregroundColor: hhaRed,
side: const BorderSide(color: hhaRed, width: 2),
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
textStyle: GoogleFonts.inter(
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
),
textButtonTheme: TextButtonThemeData(
style: TextButton.styleFrom(
foregroundColor: hhaRed,
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
textStyle: GoogleFonts.inter(
fontSize: 14,
fontWeight: FontWeight.w600,
),
),
),
floatingActionButtonTheme: const FloatingActionButtonThemeData(
backgroundColor: hhaRed,
foregroundColor: white,
elevation: 4,
),
inputDecorationTheme: InputDecorationTheme(
filled: true,
fillColor: surface,
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: const BorderSide(color: divider),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: const BorderSide(color: divider),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: const BorderSide(color: hhaRed, width: 2),
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: const BorderSide(color: error, width: 2),
),
labelStyle: GoogleFonts.inter(
fontSize: 14,
color: textSecondary,
),
hintStyle: GoogleFonts.inter(
fontSize: 14,
color: textTertiary,
),
),
chipTheme: ChipThemeData(
backgroundColor: background,
selectedColor: hhaRed.withValues(alpha: 26),
labelStyle: GoogleFonts.inter(fontSize: 12),
secondaryLabelStyle: GoogleFonts.inter(
fontSize: 12,
color: hhaRed,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
listTileTheme: ListTileThemeData(
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
),
dividerTheme: const DividerThemeData(
color: divider,
thickness: 1,
space: 1,
),
textTheme: _textTheme,
fontFamily: GoogleFonts.inter().fontFamily,
);
}
static TextTheme get _textTheme {
return TextTheme(
displayLarge: GoogleFonts.inter(
fontSize: 32,
fontWeight: FontWeight.bold,
color: textPrimary,
),
displayMedium: GoogleFonts.inter(
fontSize: 28,
fontWeight: FontWeight.bold,
color: textPrimary,
),
displaySmall: GoogleFonts.inter(
fontSize: 24,
fontWeight: FontWeight.bold,
color: textPrimary,
),
headlineLarge: GoogleFonts.inter(
fontSize: 22,
fontWeight: FontWeight.w600,
color: textPrimary,
),
headlineMedium: GoogleFonts.inter(
fontSize: 20,
fontWeight: FontWeight.w600,
color: textPrimary,
),
headlineSmall: GoogleFonts.inter(
fontSize: 18,
fontWeight: FontWeight.w600,
color: textPrimary,
),
titleLarge: GoogleFonts.inter(
fontSize: 16,
fontWeight: FontWeight.w600,
color: textPrimary,
),
titleMedium: GoogleFonts.inter(
fontSize: 14,
fontWeight: FontWeight.w600,
color: textPrimary,
),
titleSmall: GoogleFonts.inter(
fontSize: 12,
fontWeight: FontWeight.w600,
color: textSecondary,
),
bodyLarge: GoogleFonts.inter(
fontSize: 16,
fontWeight: FontWeight.normal,
color: textPrimary,
),
bodyMedium: GoogleFonts.inter(
fontSize: 14,
fontWeight: FontWeight.normal,
color: textPrimary,
),
bodySmall: GoogleFonts.inter(
fontSize: 12,
fontWeight: FontWeight.normal,
color: textSecondary,
),
labelLarge: GoogleFonts.inter(
fontSize: 14,
fontWeight: FontWeight.w500,
color: textPrimary,
),
labelMedium: GoogleFonts.inter(
fontSize: 12,
fontWeight: FontWeight.w500,
color: textSecondary,
),
labelSmall: GoogleFonts.inter(
fontSize: 10,
fontWeight: FontWeight.w500,
color: textTertiary,
),
);
}
}
extension ColorExtension on Color {
Color darken([double amount = .1]) {
assert(amount >= 0 && amount <= 1);
final hsl = HSLColor.fromColor(this);
final hslDark = hsl.withLightness((hsl.lightness - amount).clamp(0.0, 1.0));
return hslDark.toColor();
}
Color lighten([double amount = .1]) {
assert(amount >= 0 && amount <= 1);
final hsl = HSLColor.fromColor(this);
final hslLight = hsl.withLightness((hsl.lightness + amount).clamp(0.0, 1.0));
return hslLight.toColor();
}
}