diff --git a/.env b/.env new file mode 100644 index 0000000..c89c34d --- /dev/null +++ b/.env @@ -0,0 +1,6 @@ +# url = 'https://panti-asuhan.s-keytech.com/' +# api_url = 'https://panti-asuhan.s-keytech.com/api/' +# # url = 'http://172.29.85.181/panti_asuhan2/' +# # api_url = 'http://172.29.85.181/panti_asuhan2/api/' +url = 'http://20.20.20.25/panti_asuhan2/' +api_url = 'http://20.20.20.25/panti_asuhan2/api/' \ No newline at end of file diff --git a/android/build.gradle b/android/build.gradle index f7eb7f6..713d7f6 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -6,7 +6,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:7.3.0' + classpath 'com.android.tools.build:gradle:7.2.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } diff --git a/assets/logo.png b/assets/logo.png new file mode 100644 index 0000000..bb50e39 Binary files /dev/null and b/assets/logo.png differ diff --git a/lib/app/app.dart b/lib/app/app.dart new file mode 100644 index 0000000..58ebbbd --- /dev/null +++ b/lib/app/app.dart @@ -0,0 +1,35 @@ +import 'package:stacked_services/stacked_services.dart'; +import 'package:stacked/stacked_annotations.dart'; + +import '../services/http_services.dart'; +import '../services/my_easyloading.dart'; +import '../ui/views/daftar_user_ui/input_informasi_diri/input_informasi_diri_view.dart'; +import '../ui/views/daftar_user_ui/masukan_no_hp/masukan_no_hp_view.dart'; +import '../ui/views/daftar_user_ui/verifikasi_no_hp/verifikasi_no_hp_view.dart'; +import '../ui/views/login_user/login_user_view.dart'; +import '../ui/views/splash_screen/splash_screen_view.dart'; + +@StackedApp( + routes: [ + MaterialRoute(page: SplashScreenView, initial: true), + MaterialRoute(page: LoginUserView), + MaterialRoute(page: MasukanNoHpView), + MaterialRoute(page: VerifikasiNoHpView), + MaterialRoute(page: InputInformasiDiriView), + ], + // dialogs: [ + // StackedDialog(classType: AddSiswaDialogView), + // ], + dependencies: [ + LazySingleton(classType: NavigationService), + LazySingleton(classType: DialogService), + LazySingleton(classType: SnackbarService), + LazySingleton(classType: BottomSheetService), + // + + LazySingleton(classType: MyEasyLoading), + LazySingleton(classType: MyHttpServices), + ], + logger: StackedLogger(), +) +class App {} diff --git a/lib/app/app.locator.dart b/lib/app/app.locator.dart new file mode 100644 index 0000000..57e7a42 --- /dev/null +++ b/lib/app/app.locator.dart @@ -0,0 +1,35 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +// ************************************************************************** +// StackedLocatorGenerator +// ************************************************************************** + +// ignore_for_file: public_member_api_docs, implementation_imports, depend_on_referenced_packages + +import 'package:stacked_services/src/bottom_sheet/bottom_sheet_service.dart'; +import 'package:stacked_services/src/dialog/dialog_service.dart'; +import 'package:stacked_services/src/navigation/navigation_service.dart'; +import 'package:stacked_services/src/snackbar/snackbar_service.dart'; +import 'package:stacked_shared/stacked_shared.dart'; + +import '../services/http_services.dart'; +import '../services/my_easyloading.dart'; + +final locator = StackedLocator.instance; + +Future setupLocator({ + String? environment, + EnvironmentFilter? environmentFilter, +}) async { +// Register environments + locator.registerEnvironment( + environment: environment, environmentFilter: environmentFilter); + +// Register dependencies + locator.registerLazySingleton(() => NavigationService()); + locator.registerLazySingleton(() => DialogService()); + locator.registerLazySingleton(() => SnackbarService()); + locator.registerLazySingleton(() => BottomSheetService()); + locator.registerLazySingleton(() => MyEasyLoading()); + locator.registerLazySingleton(() => MyHttpServices()); +} diff --git a/lib/app/app.logger.dart b/lib/app/app.logger.dart new file mode 100644 index 0000000..26ab3f9 --- /dev/null +++ b/lib/app/app.logger.dart @@ -0,0 +1,159 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +// ************************************************************************** +// StackedLoggerGenerator +// ************************************************************************** + +// ignore_for_file: avoid_print, depend_on_referenced_packages + +/// Maybe this should be generated for the user as well? +/// +/// import 'package:customer_app/services/stackdriver/stackdriver_service.dart'; +import 'package:flutter/foundation.dart'; +import 'package:logger/logger.dart'; + +class SimpleLogPrinter extends LogPrinter { + final String className; + final bool printCallingFunctionName; + final bool printCallStack; + final List exludeLogsFromClasses; + final String? showOnlyClass; + + SimpleLogPrinter( + this.className, { + this.printCallingFunctionName = true, + this.printCallStack = false, + this.exludeLogsFromClasses = const [], + this.showOnlyClass, + }); + + @override + List log(LogEvent event) { + var color = PrettyPrinter.levelColors[event.level]; + var emoji = PrettyPrinter.levelEmojis[event.level]; + var methodName = _getMethodName(); + + var methodNameSection = + printCallingFunctionName && methodName != null ? ' | $methodName' : ''; + var stackLog = event.stackTrace.toString(); + var output = + '$emoji $className$methodNameSection - ${event.message}${event.error != null ? '\nERROR: ${event.error}\n' : ''}${printCallStack ? '\nSTACKTRACE:\n$stackLog' : ''}'; + + if (exludeLogsFromClasses + .any((excludeClass) => className == excludeClass) || + (showOnlyClass != null && className != showOnlyClass)) return []; + + final pattern = RegExp('.{1,800}'); // 800 is the size of each chunk + List result = []; + + for (var line in output.split('\n')) { + result.addAll(pattern.allMatches(line).map((match) { + if (kReleaseMode) { + return match.group(0)!; + } else { + return color!(match.group(0)!); + } + })); + } + + return result; + } + + String? _getMethodName() { + try { + final currentStack = StackTrace.current; + final formattedStacktrace = _formatStackTrace(currentStack, 3); + if (kIsWeb) { + final classNameParts = _splitClassNameWords(className); + return _findMostMatchedTrace(formattedStacktrace!, classNameParts) + .split(' ') + .last; + } else { + final realFirstLine = formattedStacktrace + ?.firstWhere((line) => line.contains(className), orElse: () => ""); + + final methodName = realFirstLine?.replaceAll('$className.', ''); + return methodName; + } + } catch (e) { + // There's no deliberate function call from our code so we return null; + return null; + } + } + + List _splitClassNameWords(String className) { + return className + .split(RegExp(r'(?=[A-Z])')) + .map((e) => e.toLowerCase()) + .toList(); + } + + /// When the faulty word exists in the begging this method will not be very usefull + String _findMostMatchedTrace( + List stackTraces, List keyWords) { + String match = stackTraces.firstWhere( + (trace) => _doesTraceContainsAllKeywords(trace, keyWords), + orElse: () => ''); + if (match.isEmpty) { + match = _findMostMatchedTrace( + stackTraces, keyWords.sublist(0, keyWords.length - 1)); + } + return match; + } + + bool _doesTraceContainsAllKeywords(String stackTrace, List keywords) { + final formattedKeywordsAsRegex = RegExp(keywords.join('.*')); + return stackTrace.contains(formattedKeywordsAsRegex); + } +} + +final stackTraceRegex = RegExp(r'#[0-9]+[\s]+(.+) \(([^\s]+)\)'); + +List? _formatStackTrace(StackTrace stackTrace, int methodCount) { + var lines = stackTrace.toString().split('\n'); + + var formatted = []; + var count = 0; + for (var line in lines) { + var match = stackTraceRegex.matchAsPrefix(line); + if (match != null) { + if (match.group(2)!.startsWith('package:logger')) { + continue; + } + var newLine = ("${match.group(1)}"); + formatted.add(newLine.replaceAll('', '()')); + if (++count == methodCount) { + break; + } + } else { + formatted.add(line); + } + } + + if (formatted.isEmpty) { + return null; + } else { + return formatted; + } +} + +Logger getLogger( + String className, { + bool printCallingFunctionName = true, + bool printCallstack = false, + List exludeLogsFromClasses = const [], + String? showOnlyClass, +}) { + return Logger( + printer: SimpleLogPrinter( + className, + printCallingFunctionName: printCallingFunctionName, + printCallStack: printCallstack, + showOnlyClass: showOnlyClass, + exludeLogsFromClasses: exludeLogsFromClasses, + ), + output: MultiOutput([ + if (!kReleaseMode) ConsoleOutput(), + ]), + ); +} diff --git a/lib/app/app.router.dart b/lib/app/app.router.dart new file mode 100644 index 0000000..cb37ba6 --- /dev/null +++ b/lib/app/app.router.dart @@ -0,0 +1,244 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +// ************************************************************************** +// StackedNavigatorGenerator +// ************************************************************************** + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'package:flutter/material.dart' as _i7; +import 'package:flutter/material.dart'; +import 'package:reza_app/ui/views/daftar_user_ui/input_informasi_diri/input_informasi_diri_view.dart' + as _i6; +import 'package:reza_app/ui/views/daftar_user_ui/masukan_no_hp/masukan_no_hp_view.dart' + as _i4; +import 'package:reza_app/ui/views/daftar_user_ui/verifikasi_no_hp/verifikasi_no_hp_view.dart' + as _i5; +import 'package:reza_app/ui/views/login_user/login_user_view.dart' as _i3; +import 'package:reza_app/ui/views/splash_screen/splash_screen_view.dart' as _i2; +import 'package:stacked/stacked.dart' as _i1; +import 'package:stacked_services/stacked_services.dart' as _i8; + +class Routes { + static const splashScreenView = '/'; + + static const loginUserView = '/login-user-view'; + + static const masukanNoHpView = '/masukan-no-hp-view'; + + static const verifikasiNoHpView = '/verifikasi-no-hp-view'; + + static const inputInformasiDiriView = '/input-informasi-diri-view'; + + static const all = { + splashScreenView, + loginUserView, + masukanNoHpView, + verifikasiNoHpView, + inputInformasiDiriView, + }; +} + +class StackedRouter extends _i1.RouterBase { + final _routes = <_i1.RouteDef>[ + _i1.RouteDef( + Routes.splashScreenView, + page: _i2.SplashScreenView, + ), + _i1.RouteDef( + Routes.loginUserView, + page: _i3.LoginUserView, + ), + _i1.RouteDef( + Routes.masukanNoHpView, + page: _i4.MasukanNoHpView, + ), + _i1.RouteDef( + Routes.verifikasiNoHpView, + page: _i5.VerifikasiNoHpView, + ), + _i1.RouteDef( + Routes.inputInformasiDiriView, + page: _i6.InputInformasiDiriView, + ), + ]; + + final _pagesMap = { + _i2.SplashScreenView: (data) { + return _i7.MaterialPageRoute( + builder: (context) => const _i2.SplashScreenView(), + settings: data, + ); + }, + _i3.LoginUserView: (data) { + return _i7.MaterialPageRoute( + builder: (context) => const _i3.LoginUserView(), + settings: data, + ); + }, + _i4.MasukanNoHpView: (data) { + return _i7.MaterialPageRoute( + builder: (context) => const _i4.MasukanNoHpView(), + settings: data, + ); + }, + _i5.VerifikasiNoHpView: (data) { + return _i7.MaterialPageRoute( + builder: (context) => const _i5.VerifikasiNoHpView(), + settings: data, + ); + }, + _i6.InputInformasiDiriView: (data) { + return _i7.MaterialPageRoute( + builder: (context) => const _i6.InputInformasiDiriView(), + settings: data, + ); + }, + }; + + @override + List<_i1.RouteDef> get routes => _routes; + @override + Map get pagesMap => _pagesMap; +} + +extension NavigatorStateExtension on _i8.NavigationService { + Future navigateToSplashScreenView([ + int? routerId, + bool preventDuplicates = true, + Map? parameters, + Widget Function(BuildContext, Animation, Animation, Widget)? + transition, + ]) async { + return navigateTo(Routes.splashScreenView, + id: routerId, + preventDuplicates: preventDuplicates, + parameters: parameters, + transition: transition); + } + + Future navigateToLoginUserView([ + int? routerId, + bool preventDuplicates = true, + Map? parameters, + Widget Function(BuildContext, Animation, Animation, Widget)? + transition, + ]) async { + return navigateTo(Routes.loginUserView, + id: routerId, + preventDuplicates: preventDuplicates, + parameters: parameters, + transition: transition); + } + + Future navigateToMasukanNoHpView([ + int? routerId, + bool preventDuplicates = true, + Map? parameters, + Widget Function(BuildContext, Animation, Animation, Widget)? + transition, + ]) async { + return navigateTo(Routes.masukanNoHpView, + id: routerId, + preventDuplicates: preventDuplicates, + parameters: parameters, + transition: transition); + } + + Future navigateToVerifikasiNoHpView([ + int? routerId, + bool preventDuplicates = true, + Map? parameters, + Widget Function(BuildContext, Animation, Animation, Widget)? + transition, + ]) async { + return navigateTo(Routes.verifikasiNoHpView, + id: routerId, + preventDuplicates: preventDuplicates, + parameters: parameters, + transition: transition); + } + + Future navigateToInputInformasiDiriView([ + int? routerId, + bool preventDuplicates = true, + Map? parameters, + Widget Function(BuildContext, Animation, Animation, Widget)? + transition, + ]) async { + return navigateTo(Routes.inputInformasiDiriView, + id: routerId, + preventDuplicates: preventDuplicates, + parameters: parameters, + transition: transition); + } + + Future replaceWithSplashScreenView([ + int? routerId, + bool preventDuplicates = true, + Map? parameters, + Widget Function(BuildContext, Animation, Animation, Widget)? + transition, + ]) async { + return replaceWith(Routes.splashScreenView, + id: routerId, + preventDuplicates: preventDuplicates, + parameters: parameters, + transition: transition); + } + + Future replaceWithLoginUserView([ + int? routerId, + bool preventDuplicates = true, + Map? parameters, + Widget Function(BuildContext, Animation, Animation, Widget)? + transition, + ]) async { + return replaceWith(Routes.loginUserView, + id: routerId, + preventDuplicates: preventDuplicates, + parameters: parameters, + transition: transition); + } + + Future replaceWithMasukanNoHpView([ + int? routerId, + bool preventDuplicates = true, + Map? parameters, + Widget Function(BuildContext, Animation, Animation, Widget)? + transition, + ]) async { + return replaceWith(Routes.masukanNoHpView, + id: routerId, + preventDuplicates: preventDuplicates, + parameters: parameters, + transition: transition); + } + + Future replaceWithVerifikasiNoHpView([ + int? routerId, + bool preventDuplicates = true, + Map? parameters, + Widget Function(BuildContext, Animation, Animation, Widget)? + transition, + ]) async { + return replaceWith(Routes.verifikasiNoHpView, + id: routerId, + preventDuplicates: preventDuplicates, + parameters: parameters, + transition: transition); + } + + Future replaceWithInputInformasiDiriView([ + int? routerId, + bool preventDuplicates = true, + Map? parameters, + Widget Function(BuildContext, Animation, Animation, Widget)? + transition, + ]) async { + return replaceWith(Routes.inputInformasiDiriView, + id: routerId, + preventDuplicates: preventDuplicates, + parameters: parameters, + transition: transition); + } +} diff --git a/lib/app/core/custom_base_view_model.dart b/lib/app/core/custom_base_view_model.dart new file mode 100755 index 0000000..e4a5e69 --- /dev/null +++ b/lib/app/core/custom_base_view_model.dart @@ -0,0 +1,16 @@ +import 'package:stacked/stacked.dart'; +import 'package:stacked_services/stacked_services.dart'; + +import '../app.locator.dart'; + +class CustomBaseViewModel extends BaseViewModel { + final dialogService = locator(); + final navigationService = locator(); + final bottomSheetService = locator(); + final snackbarService = locator(); + bool backPressed = true; + + void back() { + navigationService.back(); + } +} diff --git a/lib/app/mycd b/lib/app/mycd new file mode 100755 index 0000000..66f5995 --- /dev/null +++ b/lib/app/mycd @@ -0,0 +1,3 @@ +#!/bin/bash + +ffmpeg -i "rtsp://admin:admin123@192.168.2.109/cam/realmonitor?channel=1&subtype=1" -acodec copy -vcodec copy abcd.mp4 -y diff --git a/lib/app/themes/app_colors.dart b/lib/app/themes/app_colors.dart new file mode 100755 index 0000000..b863713 --- /dev/null +++ b/lib/app/themes/app_colors.dart @@ -0,0 +1,30 @@ +import 'dart:ui'; + +const Color mainColor = Color.fromARGB(255, 37, 88, 241); +const Color secondaryColor = Color(0xFFB72025); +const Color dangerColor = Color(0xFFFF4B68); +const Color warningColor = Color(0xFFFBFFA3); +const Color lightColor = Color(0xFFF4FAFE); +const Color lightGreyColor = Color(0xFFFCFCFC); +const Color stockColor = Color(0xFFEEF3F6); + +const Color backgroundColor = Color(0xFFE5E5E5); +const Color backgroundColor3 = Color(0xFFF6F7F8); + +const Color orangeColor = Color.fromARGB(255, 250, 145, 84); +const Color blueColor = Color(0xFF026AA2); +const Color greenColor = Color(0xFF2ABB52); +const Color redColor = Color(0xFFED1717); +const Color greyBlueColor = Color(0xFF363F72); + +const Color fontColor = Color(0xFF101828); +const Color fontSecondaryColor = Color(0xFF667085); +const Color fontParagraphColor = Color(0xFFB2B2B2); +const Color fontGrey = Color(0xFF1C1C1C); + +const Color mainGrey = Color(0xFF8991A4); +const Color secondaryGrey = Color(0xFFD0D5DD); +const Color thirdGrey = Color(0xFFF2F4F7); +const Color fourthGrey = Color(0xFF5C5C5C); +const Color fifthGrey = Color(0xFFEBEBEB); +const Color sixthGrey = Color(0xFF151515); diff --git a/lib/app/themes/app_text.dart b/lib/app/themes/app_text.dart new file mode 100644 index 0000000..092d154 --- /dev/null +++ b/lib/app/themes/app_text.dart @@ -0,0 +1,44 @@ +import 'package:flutter/material.dart'; + +import 'app_colors.dart'; + +const regularTextStyle = TextStyle( + fontFamily: 'Arial', + fontSize: 14, + fontWeight: FontWeight.w400, + color: fontColor); + +const italicTextStyle = TextStyle( + fontFamily: 'Arial', + fontSize: 14, + color: fontColor, + fontStyle: FontStyle.italic, +); + +const mediumTextStyle = TextStyle( + fontFamily: 'Arial', + fontSize: 14, + fontWeight: FontWeight.w500, + color: fontColor, +); + +const semiBoldTextStyle = TextStyle( + fontFamily: 'Arial', + fontSize: 14, + fontWeight: FontWeight.w600, + color: fontColor, +); + +const boldTextStyle = TextStyle( + fontFamily: 'Arial', + fontSize: 14, + fontWeight: FontWeight.w700, + color: fontColor, +); + +const extraBoldTextStyle = TextStyle( + fontFamily: 'Arial', + fontSize: 14, + fontWeight: FontWeight.w800, + color: fontColor, +); diff --git a/lib/app/themes/app_theme.dart b/lib/app/themes/app_theme.dart new file mode 100755 index 0000000..eefa661 --- /dev/null +++ b/lib/app/themes/app_theme.dart @@ -0,0 +1,124 @@ +import 'package:flutter/material.dart'; + +import 'app_colors.dart'; +import 'app_text.dart'; + +ThemeData appTheme = ThemeData( + useMaterial3: true, + primaryColor: mainColor, + scaffoldBackgroundColor: Colors.white, + canvasColor: Colors.white, + fontFamily: 'Poppins', + appBarTheme: AppBarTheme( + elevation: 0, + titleTextStyle: boldTextStyle.copyWith(fontSize: 16, color: fontGrey), + centerTitle: true, + ), + textTheme: TextTheme( + displayLarge: regularTextStyle.copyWith(fontSize: 32), + displayMedium: regularTextStyle.copyWith(fontSize: 20), + displaySmall: regularTextStyle.copyWith(fontSize: 18), + ), + elevatedButtonTheme: ElevatedButtonThemeData( + style: ElevatedButton.styleFrom( + backgroundColor: mainColor, + foregroundColor: Colors.white, + disabledBackgroundColor: mainColor.withOpacity(.3), + minimumSize: const Size(double.maxFinite, 58), + textStyle: boldTextStyle, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + shadowColor: Colors.transparent, + elevation: 0, + ), + ), + outlinedButtonTheme: OutlinedButtonThemeData( + style: OutlinedButton.styleFrom( + textStyle: boldTextStyle, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + side: const BorderSide( + color: mainColor, + width: 1, + ), + foregroundColor: mainColor, + // disabledForegroundColor: mainColor.withOpacity(.3), + minimumSize: const Size(double.maxFinite, 58), + ), + ), + textButtonTheme: TextButtonThemeData( + style: TextButton.styleFrom( + foregroundColor: mainColor, + disabledForegroundColor: mainColor.withOpacity(.3), + elevation: 0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + textStyle: semiBoldTextStyle, + shadowColor: Colors.transparent, + ), + ), + iconTheme: const IconThemeData( + color: mainColor, + ), + listTileTheme: ListTileThemeData( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + ), + checkboxTheme: CheckboxThemeData( + fillColor: MaterialStateProperty.all(mainColor), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(4), + ), + side: const BorderSide( + color: secondaryGrey, + width: 1, + ), + ), + radioTheme: RadioThemeData( + fillColor: MaterialStateProperty.all(mainColor), + ), + tabBarTheme: TabBarTheme( + labelColor: mainColor, + unselectedLabelColor: secondaryGrey, + labelStyle: boldTextStyle.copyWith(fontSize: 16), + unselectedLabelStyle: mediumTextStyle.copyWith(fontSize: 16), + ), + chipTheme: ChipThemeData( + backgroundColor: Colors.white, + disabledColor: Colors.white, + selectedColor: Colors.white, + secondarySelectedColor: Colors.white, + padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16), + side: const BorderSide(color: fifthGrey), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(6), + ), + labelStyle: regularTextStyle.copyWith(fontSize: 12, color: fontGrey), + secondaryLabelStyle: + regularTextStyle.copyWith(fontSize: 12, color: secondaryColor), + deleteIconColor: fontGrey, + showCheckmark: false, + ), + popupMenuTheme: PopupMenuThemeData( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + side: const BorderSide( + color: fifthGrey, + width: 1, + ), + ), + ), + colorScheme: const ColorScheme.light( + primary: mainColor, + secondary: secondaryColor, + onPrimary: Colors.white, + onSecondary: Colors.white, + error: dangerColor, + onError: dangerColor, + background: backgroundColor, + ).copyWith(background: Colors.white), +); diff --git a/lib/main.dart b/lib/main.dart index dda5554..3c48071 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,6 +1,16 @@ import 'package:flutter/material.dart'; +import 'package:flutter_dotenv/flutter_dotenv.dart'; +import 'package:flutter_easyloading/flutter_easyloading.dart'; +import 'package:stacked_services/stacked_services.dart'; -void main() { +import 'app/app.locator.dart'; +import 'app/app.router.dart'; +import 'app/themes/app_theme.dart'; + +Future main() async { + WidgetsFlutterBinding.ensureInitialized(); + await dotenv.load(fileName: ".env"); + await setupAllLocator(); runApp(const MyApp()); } @@ -11,115 +21,19 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - // This is the theme of your application. - // - // TRY THIS: Try running your application with "flutter run". You'll see - // the application has a blue toolbar. Then, without quitting the app, - // try changing the seedColor in the colorScheme below to Colors.green - // and then invoke "hot reload" (save your changes or press the "hot - // reload" button in a Flutter-supported IDE, or press "r" if you used - // the command line to start the app). - // - // Notice that the counter didn't reset back to zero; the application - // state is not lost during the reload. To reset the state, use hot - // restart instead. - // - // This works for code too, not just values: Most code changes can be - // tested with just a hot reload. - colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), - useMaterial3: true, - ), - home: const MyHomePage(title: 'Flutter Demo Home Page'), + title: 'Panti Asuhan Aisyiyah Abadi', + theme: appTheme, + debugShowCheckedModeBanner: false, + navigatorKey: StackedService.navigatorKey, + onGenerateRoute: StackedRouter().onGenerateRoute, + builder: EasyLoading.init(), ); } } -class MyHomePage extends StatefulWidget { - const MyHomePage({super.key, required this.title}); - - // This widget is the home page of your application. It is stateful, meaning - // that it has a State object (defined below) that contains fields that affect - // how it looks. - - // This class is the configuration for the state. It holds the values (in this - // case the title) provided by the parent (in this case the App widget) and - // used by the build method of the State. Fields in a Widget subclass are - // always marked "final". - - final String title; - - @override - State createState() => _MyHomePageState(); -} - -class _MyHomePageState extends State { - int _counter = 0; - - void _incrementCounter() { - setState(() { - // This call to setState tells the Flutter framework that something has - // changed in this State, which causes it to rerun the build method below - // so that the display can reflect the updated values. If we changed - // _counter without calling setState(), then the build method would not be - // called again, and so nothing would appear to happen. - _counter++; - }); - } - - @override - Widget build(BuildContext context) { - // This method is rerun every time setState is called, for instance as done - // by the _incrementCounter method above. - // - // The Flutter framework has been optimized to make rerunning build methods - // fast, so that you can just rebuild anything that needs updating rather - // than having to individually change instances of widgets. - return Scaffold( - appBar: AppBar( - // TRY THIS: Try changing the color here to a specific color (to - // Colors.amber, perhaps?) and trigger a hot reload to see the AppBar - // change color while the other colors stay the same. - backgroundColor: Theme.of(context).colorScheme.inversePrimary, - // Here we take the value from the MyHomePage object that was created by - // the App.build method, and use it to set our appbar title. - title: Text(widget.title), - ), - body: Center( - // Center is a layout widget. It takes a single child and positions it - // in the middle of the parent. - child: Column( - // Column is also a layout widget. It takes a list of children and - // arranges them vertically. By default, it sizes itself to fit its - // children horizontally, and tries to be as tall as its parent. - // - // Column has various properties to control how it sizes itself and - // how it positions its children. Here we use mainAxisAlignment to - // center the children vertically; the main axis here is the vertical - // axis because Columns are vertical (the cross axis would be - // horizontal). - // - // TRY THIS: Invoke "debug painting" (choose the "Toggle Debug Paint" - // action in the IDE, or press "p" in the console), to see the - // wireframe for each widget. - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Text( - 'You have pushed the button this many times:', - ), - Text( - '$_counter', - style: Theme.of(context).textTheme.headlineMedium, - ), - ], - ), - ), - floatingActionButton: FloatingActionButton( - onPressed: _incrementCounter, - tooltip: 'Increment', - child: const Icon(Icons.add), - ), // This trailing comma makes auto-formatting nicer for build methods. - ); - } +Future setupAllLocator() async { + await setupLocator(); + // setupDialogUi(); + // setupBottomsheetUi(); + // setupSnackbarUi(); } diff --git a/lib/services/http_services.dart b/lib/services/http_services.dart new file mode 100644 index 0000000..f2e4da5 --- /dev/null +++ b/lib/services/http_services.dart @@ -0,0 +1,35 @@ +import 'package:dio/dio.dart'; +import 'package:flutter_dotenv/flutter_dotenv.dart'; + +import '../app/app.logger.dart'; + +class MyHttpServices { + final log = getLogger('MyHttpServices'); + final _options = BaseOptions( + baseUrl: dotenv.env['api_url']!, + connectTimeout: const Duration(seconds: 120), + receiveTimeout: const Duration(seconds: 120), + ); + + late Dio _dio; + + MyHttpServices() { + _dio = Dio(_options); + } + + Future get(String path) async { + try { + return await _dio.get(path); + } on DioException { + rethrow; + } + } + + Future postWithFormData(String path, FormData formData) async { + try { + return await _dio.post(path, data: formData); + } on DioException { + rethrow; + } + } +} diff --git a/lib/services/my_easyloading.dart b/lib/services/my_easyloading.dart new file mode 100644 index 0000000..46cb062 --- /dev/null +++ b/lib/services/my_easyloading.dart @@ -0,0 +1,39 @@ +import 'package:flutter_easyloading/flutter_easyloading.dart'; + +class MyEasyLoading { + showLoading() { + EasyLoading.show( + status: 'loading...', + maskType: EasyLoadingMaskType.black, + dismissOnTap: false, + ); + } + + dismissLoading() { + EasyLoading.dismiss(); + } + + customLoading(String message) { + EasyLoading.show( + status: message, + maskType: EasyLoadingMaskType.black, + dismissOnTap: false, + ); + } + + showSuccess(String message) { + EasyLoading.showSuccess(message); + } + + showError(String message) { + EasyLoading.showError(message); + } + + showInfo(String message) { + EasyLoading.showInfo(message); + } + + showProgress(double progress, String status) { + EasyLoading.showProgress(progress, status: status); + } +} diff --git a/lib/services/other_function.dart b/lib/services/other_function.dart new file mode 100644 index 0000000..f58ea3e --- /dev/null +++ b/lib/services/other_function.dart @@ -0,0 +1,18 @@ +import 'package:intl/intl.dart'; + +class OtherFunction { + int umur(String tanggalLahir) { + // change tanggalLahir to DateTime + DateTime date = DateTime.parse(tanggalLahir); + // get current date + DateTime now = DateTime.now(); + // get difference in year + int year = now.year - date.year; + return year; + } + + String commaFormat(int number) { + final formatter = NumberFormat('#,###'); + return formatter.format(number); + } +} diff --git a/lib/ui/views/daftar_user_ui/input_informasi_diri/input_informasi_diri_view.dart b/lib/ui/views/daftar_user_ui/input_informasi_diri/input_informasi_diri_view.dart new file mode 100644 index 0000000..1a7050d --- /dev/null +++ b/lib/ui/views/daftar_user_ui/input_informasi_diri/input_informasi_diri_view.dart @@ -0,0 +1,31 @@ +import 'package:flutter/material.dart'; +import 'package:stacked/stacked.dart'; + +import './input_informasi_diri_view_model.dart'; + +class InputInformasiDiriView extends StatelessWidget { + const InputInformasiDiriView({super.key}); + + @override + Widget build(BuildContext context) { + return ViewModelBuilder.reactive( + viewModelBuilder: () => InputInformasiDiriViewModel(), + onViewModelReady: (InputInformasiDiriViewModel model) async { + await model.init(); + }, + builder: ( + BuildContext context, + InputInformasiDiriViewModel model, + Widget? child, + ) { + return const Scaffold( + body: Center( + child: Text( + 'InputInformasiDiriView', + ), + ), + ); + }, + ); + } +} diff --git a/lib/ui/views/daftar_user_ui/input_informasi_diri/input_informasi_diri_view_model.dart b/lib/ui/views/daftar_user_ui/input_informasi_diri/input_informasi_diri_view_model.dart new file mode 100644 index 0000000..e8e97b6 --- /dev/null +++ b/lib/ui/views/daftar_user_ui/input_informasi_diri/input_informasi_diri_view_model.dart @@ -0,0 +1,5 @@ +import 'package:reza_app/app/core/custom_base_view_model.dart'; + +class InputInformasiDiriViewModel extends CustomBaseViewModel { + Future init() async {} +} diff --git a/lib/ui/views/daftar_user_ui/masukan_no_hp/masukan_no_hp_view.dart b/lib/ui/views/daftar_user_ui/masukan_no_hp/masukan_no_hp_view.dart new file mode 100644 index 0000000..a9db29c --- /dev/null +++ b/lib/ui/views/daftar_user_ui/masukan_no_hp/masukan_no_hp_view.dart @@ -0,0 +1,96 @@ +import 'package:flutter/material.dart'; +import 'package:stacked/stacked.dart'; +import 'package:validatorless/validatorless.dart'; + +import '../../../../app/themes/app_colors.dart'; +import '../../../widgets/my_button.dart'; +import '../../../widgets/my_textformfield.dart'; +import './masukan_no_hp_view_model.dart'; + +class MasukanNoHpView extends StatelessWidget { + const MasukanNoHpView({super.key}); + + @override + Widget build(BuildContext context) { + return ViewModelBuilder.reactive( + viewModelBuilder: () => MasukanNoHpViewModel(), + onViewModelReady: (MasukanNoHpViewModel model) async { + await model.init(); + }, + builder: ( + BuildContext context, + MasukanNoHpViewModel model, + Widget? child, + ) { + return Scaffold( + appBar: AppBar( + title: const Text('PENDAFTARAN USER BARU', + style: TextStyle( + color: lightColor, + )), + backgroundColor: mainColor, + iconTheme: const IconThemeData( + color: + Colors.white), // Set the color of the back button to white + ), + body: WillPopScope( + onWillPop: () async { + return model.backPressed; + }, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 25), + child: Center( + child: Form( + key: model.formKey, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.asset( + 'assets/logo.png', + width: 100, + height: 100, + ), + const SizedBox(height: 15), + const Text( + 'Masukkan Nomor HP', + ), + const SizedBox(height: 16), + MyTextFormField( + maxLength: 13, + hintText: 'No. HP', + keyboardType: TextInputType.phone, + controller: model.noHpController, + validator: + Validatorless.required('No. HP tidak boleh kosong'), + ), + SizedBox( + width: MediaQuery.of(context).size.width * 0.5, + child: MyButton( + text: 'Selanjutnya', + onPressed: () { + // if noHpController length is less than 9, return + if (model.noHpController.text.length < 9) { + model.snackbarService.showSnackbar( + message: 'No. HP tidak boleh kurang dari 9'); + return; + } + + if (!model.formKey.currentState!.validate()) { + return; + } + model.log.i('Selanjutnya button pressed'); + model.selanjutnya(); + }, + ), + ), + ], + ), + ), + ), + ), + ), + ); + }, + ); + } +} diff --git a/lib/ui/views/daftar_user_ui/masukan_no_hp/masukan_no_hp_view_model.dart b/lib/ui/views/daftar_user_ui/masukan_no_hp/masukan_no_hp_view_model.dart new file mode 100644 index 0000000..2fa3089 --- /dev/null +++ b/lib/ui/views/daftar_user_ui/masukan_no_hp/masukan_no_hp_view_model.dart @@ -0,0 +1,26 @@ +import 'package:flutter/material.dart'; +import '../../../../app/app.locator.dart'; +import '../../../../app/app.router.dart'; + +import '../../../../app/app.logger.dart'; +import '../../../../app/core/custom_base_view_model.dart'; +import '../../../../services/my_easyloading.dart'; + +class MasukanNoHpViewModel extends CustomBaseViewModel { + final log = getLogger('MasukanNoHpViewModel'); + final _easyloading = locator(); + + TextEditingController noHpController = TextEditingController(); + GlobalKey formKey = GlobalKey(); + Future init() async {} + + selanjutnya() async { + _easyloading.customLoading("Menghantar Kode OTP \nke WhatsApp Anda"); + backPressed = false; + await Future.delayed(const Duration(seconds: 3)); + backPressed = true; + notifyListeners(); + _easyloading.dismissLoading(); + await navigationService.navigateToVerifikasiNoHpView(); + } +} diff --git a/lib/ui/views/daftar_user_ui/verifikasi_no_hp/verifikasi_no_hp_view.dart b/lib/ui/views/daftar_user_ui/verifikasi_no_hp/verifikasi_no_hp_view.dart new file mode 100644 index 0000000..3883915 --- /dev/null +++ b/lib/ui/views/daftar_user_ui/verifikasi_no_hp/verifikasi_no_hp_view.dart @@ -0,0 +1,31 @@ +import 'package:flutter/material.dart'; +import 'package:stacked/stacked.dart'; + +import './verifikasi_no_hp_view_model.dart'; + +class VerifikasiNoHpView extends StatelessWidget { + const VerifikasiNoHpView({super.key}); + + @override + Widget build(BuildContext context) { + return ViewModelBuilder.reactive( + viewModelBuilder: () => VerifikasiNoHpViewModel(), + onViewModelReady: (VerifikasiNoHpViewModel model) async { + await model.init(); + }, + builder: ( + BuildContext context, + VerifikasiNoHpViewModel model, + Widget? child, + ) { + return const Scaffold( + body: Center( + child: Text( + 'VerifikasiNoHpView', + ), + ), + ); + }, + ); + } +} diff --git a/lib/ui/views/daftar_user_ui/verifikasi_no_hp/verifikasi_no_hp_view_model.dart b/lib/ui/views/daftar_user_ui/verifikasi_no_hp/verifikasi_no_hp_view_model.dart new file mode 100644 index 0000000..2a8bed8 --- /dev/null +++ b/lib/ui/views/daftar_user_ui/verifikasi_no_hp/verifikasi_no_hp_view_model.dart @@ -0,0 +1,5 @@ +import 'package:reza_app/app/core/custom_base_view_model.dart'; + +class VerifikasiNoHpViewModel extends CustomBaseViewModel { + Future init() async {} +} diff --git a/lib/ui/views/login_user/login_user_view.dart b/lib/ui/views/login_user/login_user_view.dart new file mode 100644 index 0000000..3e6ba2e --- /dev/null +++ b/lib/ui/views/login_user/login_user_view.dart @@ -0,0 +1,104 @@ +import 'package:flutter/material.dart'; +import 'package:stacked/stacked.dart'; + +import '../../widgets/my_button.dart'; +import '../../widgets/my_textformfield.dart'; +import './login_user_view_model.dart'; + +class LoginUserView extends StatelessWidget { + const LoginUserView({super.key}); + + @override + Widget build(BuildContext context) { + return ViewModelBuilder.reactive( + viewModelBuilder: () => LoginUserViewModel(), + onViewModelReady: (LoginUserViewModel model) async { + await model.init(); + }, + builder: ( + BuildContext context, + LoginUserViewModel model, + Widget? child, + ) { + return Scaffold( + body: WillPopScope( + onWillPop: () async { + return model.backPressed; + }, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 25), + child: Center( + child: SingleChildScrollView( + child: Form( + key: model.formKey, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.asset( + 'assets/logo.png', + width: 200, + height: 200, + ), + const SizedBox(height: 16), + const Text( + 'Halaman Login', + style: TextStyle( + fontSize: 24, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 16), + MyTextFormField( + maxLength: 13, + hintText: 'No. HP', + keyboardType: TextInputType.phone, + controller: model.noHpController, + ), + const SizedBox(height: 16), + MyTextFormField( + hintText: 'Password', + obscureText: model.showPassword, + controller: model.passwordController, + suffixIcon: IconButton( + onPressed: () { + model.showPassword = !model.showPassword; + model.notifyListeners(); + }, + icon: Icon( + model.showPassword + ? Icons.visibility_off + : Icons.visibility, + ), + ), + ), + const SizedBox(height: 16), + MyButton( + text: 'Login', + onPressed: () { + model.log.i('Login button pressed'); + model.login(); + }, + ), + TextButton( + onPressed: () { + model.daftar(); + }, + child: const Text( + 'Belum punya akun? Daftar disini', + style: TextStyle( + fontSize: 16, + ), + ), + ), + ], + ), + ), + ), + ), + ), + ), + ); + }, + ); + } +} diff --git a/lib/ui/views/login_user/login_user_view_model.dart b/lib/ui/views/login_user/login_user_view_model.dart new file mode 100644 index 0000000..f356cd3 --- /dev/null +++ b/lib/ui/views/login_user/login_user_view_model.dart @@ -0,0 +1,36 @@ +import 'package:flutter/material.dart'; +import '../../../app/app.router.dart'; + +import '../../../app/app.locator.dart'; +import '../../../app/app.logger.dart'; +import '../../../app/core/custom_base_view_model.dart'; +import '../../../services/my_easyloading.dart'; + +class LoginUserViewModel extends CustomBaseViewModel { + final log = getLogger('LoginUserViewModel'); + final easyloading = locator(); + + TextEditingController noHpController = TextEditingController(); + TextEditingController passwordController = TextEditingController(); + GlobalKey formKey = GlobalKey(); + + bool showPassword = true; + + Future init() async {} + + login() async { + setBusy(true); + backPressed = false; + easyloading.showLoading(); + await Future.delayed(const Duration(seconds: 5)); + easyloading.dismissLoading(); + setBusy(false); + backPressed = true; + notifyListeners(); + // await navigationService.navigateToHomeView(); + } + + daftar() async { + await navigationService.navigateToMasukanNoHpView(); + } +} diff --git a/lib/ui/views/splash_screen/splash_screen_view.dart b/lib/ui/views/splash_screen/splash_screen_view.dart new file mode 100644 index 0000000..f27b608 --- /dev/null +++ b/lib/ui/views/splash_screen/splash_screen_view.dart @@ -0,0 +1,67 @@ +import 'package:flutter/material.dart'; +import 'package:stacked/stacked.dart'; + +import './splash_screen_view_model.dart'; + +class SplashScreenView extends StatelessWidget { + const SplashScreenView({super.key}); + + @override + Widget build(BuildContext context) { + return ViewModelBuilder.reactive( + viewModelBuilder: () => SplashScreenViewModel(), + onViewModelReady: (SplashScreenViewModel model) async { + await model.init(); + }, + builder: ( + BuildContext context, + SplashScreenViewModel model, + Widget? child, + ) { + return Scaffold( + body: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Expanded( + flex: 1, + child: SizedBox( + height: 20, + ), + ), + Expanded( + flex: 2, + child: Column( + children: [ + Center( + child: Image.asset( + 'assets/logo.png', + width: 200, + height: 200, + ), + ), + const Text( + 'Reza Table Reservation \n& Food Order', + style: TextStyle( + fontSize: 24, + fontWeight: FontWeight.bold, + ), + textAlign: TextAlign.center, + ), + ], + ), + ), + const SizedBox(height: 20), + const Text( + 'Alamat jalan jendral sudirman', + style: TextStyle( + fontSize: 16, + ), + ), + const SizedBox(height: 20), + ], + ), + ); + }, + ); + } +} diff --git a/lib/ui/views/splash_screen/splash_screen_view_model.dart b/lib/ui/views/splash_screen/splash_screen_view_model.dart new file mode 100644 index 0000000..6938079 --- /dev/null +++ b/lib/ui/views/splash_screen/splash_screen_view_model.dart @@ -0,0 +1,10 @@ +import 'package:reza_app/app/app.router.dart'; +import 'package:reza_app/app/core/custom_base_view_model.dart'; + +class SplashScreenViewModel extends CustomBaseViewModel { + Future init() async { + // after 2 second, navigate to login page + await Future.delayed(const Duration(seconds: 2)); + await navigationService.navigateToLoginUserView(); + } +} diff --git a/lib/ui/widgets/my_button.dart b/lib/ui/widgets/my_button.dart new file mode 100644 index 0000000..13fb767 --- /dev/null +++ b/lib/ui/widgets/my_button.dart @@ -0,0 +1,34 @@ +import 'package:flutter/material.dart'; + +import '../../app/themes/app_colors.dart'; + +class MyButton extends StatelessWidget { + const MyButton({ + Key? key, + required this.text, + this.onPressed, + }) : super(key: key); + + final String text; + final VoidCallback? onPressed; + + @override + Widget build(BuildContext context) { + return ElevatedButton( + style: ElevatedButton.styleFrom( + backgroundColor: mainColor, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(30), + ), + ), + onPressed: onPressed, + child: Text( + text, + style: const TextStyle( + color: backgroundColor, + fontSize: 18, + ), + ), + ); + } +} diff --git a/lib/ui/widgets/my_textformfield.dart b/lib/ui/widgets/my_textformfield.dart new file mode 100644 index 0000000..fe069bb --- /dev/null +++ b/lib/ui/widgets/my_textformfield.dart @@ -0,0 +1,91 @@ +import 'package:flutter/material.dart'; + +import '../../app/themes/app_colors.dart'; + +class MyTextFormField extends StatelessWidget { + const MyTextFormField({ + Key? key, + this.labelText, + this.hintText, + this.obscureText, + this.validator, + this.suffixIcon, + this.prefixIcon, + this.focusNode, + this.controller, + this.maxLines = 1, + this.onEditingComplete, + this.readOnly = false, + this.onTap, + this.keyboardType = TextInputType.text, + this.initialValue, + this.enabled = true, + this.maxLength, + }) : super(key: key); + + final String? labelText; + final String? hintText; + final bool? obscureText; + final FormFieldValidator? validator; + final Widget? suffixIcon; + final Widget? prefixIcon; + final FocusNode? focusNode; + final TextEditingController? controller; + final int maxLines; + final VoidCallback? onEditingComplete; + final bool readOnly; + final VoidCallback? onTap; + final TextInputType keyboardType; + final String? initialValue; + final bool enabled; + final int? maxLength; + + @override + Widget build(BuildContext context) { + return TextFormField( + maxLength: maxLength, + enabled: enabled, + initialValue: initialValue, + onEditingComplete: onEditingComplete, + maxLines: maxLines, + controller: controller, + focusNode: focusNode, + obscureText: obscureText ?? false, + readOnly: readOnly, + onTap: onTap, + keyboardType: keyboardType, + decoration: InputDecoration( + prefixIcon: prefixIcon, + suffixIcon: suffixIcon, + enabledBorder: const OutlineInputBorder( + borderRadius: BorderRadius.all(Radius.circular(25)), + borderSide: BorderSide( + color: mainColor, + ), + ), + focusedBorder: const OutlineInputBorder( + borderRadius: BorderRadius.all(Radius.circular(25)), + borderSide: BorderSide( + color: mainColor, + ), + ), + focusedErrorBorder: const OutlineInputBorder( + borderRadius: BorderRadius.all(Radius.circular(25)), + borderSide: BorderSide( + color: dangerColor, + ), + ), + errorBorder: const OutlineInputBorder( + borderRadius: BorderRadius.all(Radius.circular(25)), + borderSide: BorderSide( + color: dangerColor, + ), + ), + labelText: labelText, + hintText: hintText, + labelStyle: const TextStyle(color: fontColor), + ), + validator: validator, + ); + } +} diff --git a/pubspec.lock b/pubspec.lock index 3832970..b5bed82 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,6 +1,22 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + sha256: ae92f5d747aee634b87f89d9946000c2de774be1d6ac3e58268224348cd0101a + url: "https://pub.dev" + source: hosted + version: "61.0.0" + analyzer: + dependency: transitive + description: + name: analyzer + sha256: ea3d8652bda62982addfd92fdc2d0214e5f82e43325104990d4f4c4a2a313562 + url: "https://pub.dev" + source: hosted + version: "5.13.0" args: dependency: transitive description: @@ -25,6 +41,70 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.1" + build: + dependency: transitive + description: + name: build + sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + build_config: + dependency: transitive + description: + name: build_config + sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 + url: "https://pub.dev" + source: hosted + version: "1.1.1" + build_daemon: + dependency: transitive + description: + name: build_daemon + sha256: "5f02d73eb2ba16483e693f80bee4f088563a820e47d1027d4cdfe62b5bb43e65" + url: "https://pub.dev" + source: hosted + version: "4.0.0" + build_resolvers: + dependency: transitive + description: + name: build_resolvers + sha256: "6c4dd11d05d056e76320b828a1db0fc01ccd376922526f8e9d6c796a5adbac20" + url: "https://pub.dev" + source: hosted + version: "2.2.1" + build_runner: + dependency: "direct dev" + description: + name: build_runner + sha256: "10c6bcdbf9d049a0b666702cf1cee4ddfdc38f02a19d35ae392863b47519848b" + url: "https://pub.dev" + source: hosted + version: "2.4.6" + build_runner_core: + dependency: transitive + description: + name: build_runner_core + sha256: "6d6ee4276b1c5f34f21fdf39425202712d2be82019983d52f351c94aafbc2c41" + url: "https://pub.dev" + source: hosted + version: "7.2.10" + built_collection: + dependency: transitive + description: + name: built_collection + sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100" + url: "https://pub.dev" + source: hosted + version: "5.1.1" + built_value: + dependency: transitive + description: + name: built_value + sha256: "598a2a682e2a7a90f08ba39c0aaa9374c5112340f0a2e275f61b59389543d166" + url: "https://pub.dev" + source: hosted + version: "8.6.1" characters: dependency: transitive description: @@ -33,6 +113,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.0" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff + url: "https://pub.dev" + source: hosted + version: "2.0.3" clock: dependency: transitive description: @@ -41,6 +129,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.1" + code_builder: + dependency: transitive + description: + name: code_builder + sha256: "4ad01d6e56db961d29661561effde45e519939fdaeb46c351275b182eac70189" + url: "https://pub.dev" + source: hosted + version: "4.5.0" collection: dependency: transitive description: @@ -49,6 +145,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.17.2" + convert: + dependency: transitive + description: + name: convert + sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + url: "https://pub.dev" + source: hosted + version: "3.1.1" cross_file: dependency: transitive description: @@ -73,6 +177,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.5" + dart_style: + dependency: transitive + description: + name: dart_style + sha256: "1efa911ca7086affd35f463ca2fc1799584fb6aa89883cf0af8e3664d6a02d55" + url: "https://pub.dev" + source: hosted + version: "2.3.2" dio: dependency: "direct main" description: @@ -97,6 +209,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.2" + file: + dependency: transitive + description: + name: file + sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" + url: "https://pub.dev" + source: hosted + version: "7.0.0" file_selector_linux: dependency: transitive description: @@ -129,6 +249,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.9.3" + fixnum: + dependency: transitive + description: + name: fixnum + sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" + url: "https://pub.dev" + source: hosted + version: "1.1.0" flutter: dependency: "direct main" description: flutter @@ -192,6 +320,22 @@ packages: description: flutter source: sdk version: "0.0.0" + freezed_annotation: + dependency: transitive + description: + name: freezed_annotation + sha256: c3fd9336eb55a38cc1bbd79ab17573113a8deccd0ecbbf926cca3c62803b5c2d + url: "https://pub.dev" + source: hosted + version: "2.4.1" + frontend_server_client: + dependency: transitive + description: + name: frontend_server_client + sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612" + url: "https://pub.dev" + source: hosted + version: "3.2.0" get: dependency: transitive description: @@ -208,6 +352,14 @@ packages: url: "https://pub.dev" source: hosted version: "7.6.0" + glob: + dependency: transitive + description: + name: glob + sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63" + url: "https://pub.dev" + source: hosted + version: "2.1.2" google_fonts: dependency: "direct main" description: @@ -216,6 +368,14 @@ packages: url: "https://pub.dev" source: hosted version: "5.1.0" + graphs: + dependency: transitive + description: + name: graphs + sha256: aedc5a15e78fc65a6e23bcd927f24c64dd995062bcd1ca6eda65a3cff92a4d19 + url: "https://pub.dev" + source: hosted + version: "2.3.1" http: dependency: transitive description: @@ -224,6 +384,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.0" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b" + url: "https://pub.dev" + source: hosted + version: "3.2.1" http_parser: dependency: transitive description: @@ -304,6 +472,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.18.1" + io: + dependency: transitive + description: + name: io + sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e" + url: "https://pub.dev" + source: hosted + version: "1.0.4" js: dependency: transitive description: @@ -312,6 +488,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.6.7" + json_annotation: + dependency: transitive + description: + name: json_annotation + sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467 + url: "https://pub.dev" + source: hosted + version: "4.8.1" lints: dependency: transitive description: @@ -344,6 +528,22 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.1" + logger: + dependency: transitive + description: + name: logger + sha256: "7ad7215c15420a102ec687bb320a7312afd449bac63bfb1c60d9787c27b9767f" + url: "https://pub.dev" + source: hosted + version: "1.4.0" + logging: + dependency: transitive + description: + name: logging + sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" + url: "https://pub.dev" + source: hosted + version: "1.2.0" matcher: dependency: transitive description: @@ -384,6 +584,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.0" + otp_text_field: + dependency: "direct main" + description: + name: otp_text_field + sha256: "340b1ed135e1abe9fac0aaebe1c4e48147d95a3e29ecb03ae45ad63a7c28d65d" + url: "https://pub.dev" + source: hosted + version: "1.1.3" + package_config: + dependency: transitive + description: + name: package_config + sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" + url: "https://pub.dev" + source: hosted + version: "2.1.0" path: dependency: transitive description: @@ -472,6 +688,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" + pool: + dependency: transitive + description: + name: pool + sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" + url: "https://pub.dev" + source: hosted + version: "1.5.1" provider: dependency: transitive description: @@ -480,11 +704,59 @@ packages: url: "https://pub.dev" source: hosted version: "6.0.5" + pub_semver: + dependency: transitive + description: + name: pub_semver + sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + pubspec_parse: + dependency: transitive + description: + name: pubspec_parse + sha256: c63b2876e58e194e4b0828fcb080ad0e06d051cb607a6be51a9e084f47cb9367 + url: "https://pub.dev" + source: hosted + version: "1.2.3" + recase: + dependency: transitive + description: + name: recase + sha256: e4eb4ec2dcdee52dcf99cb4ceabaffc631d7424ee55e56f280bc039737f89213 + url: "https://pub.dev" + source: hosted + version: "4.1.0" + shelf: + dependency: transitive + description: + name: shelf + sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 + url: "https://pub.dev" + source: hosted + version: "1.4.1" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1" + url: "https://pub.dev" + source: hosted + version: "1.0.4" sky_engine: dependency: transitive description: flutter source: sdk version: "0.0.99" + source_gen: + dependency: transitive + description: + name: source_gen + sha256: fc0da689e5302edb6177fdd964efcb7f58912f43c28c2047a808f5bfff643d16 + url: "https://pub.dev" + source: hosted + version: "1.4.0" source_span: dependency: transitive description: @@ -509,6 +781,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.4.1" + stacked_generator: + dependency: "direct dev" + description: + name: stacked_generator + sha256: "52a06816caec8272b2111e247ec4484031b89858099b72073663b8e45282fb1e" + url: "https://pub.dev" + source: hosted + version: "1.4.0" stacked_services: dependency: "direct main" description: @@ -533,6 +813,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.1" + stream_transform: + dependency: transitive + description: + name: stream_transform + sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" + url: "https://pub.dev" + source: hosted + version: "2.1.0" string_scanner: dependency: transitive description: @@ -565,6 +853,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.6.0" + timing: + dependency: transitive + description: + name: timing + sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32" + url: "https://pub.dev" + source: hosted + version: "1.0.1" typed_data: dependency: transitive description: @@ -621,6 +917,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" + watcher: + dependency: transitive + description: + name: watcher + sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b + url: "https://pub.dev" + source: hosted + version: "2.4.0" win32: dependency: transitive description: @@ -645,6 +957,14 @@ packages: url: "https://pub.dev" source: hosted version: "6.3.0" + yaml: + dependency: transitive + description: + name: yaml + sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" + url: "https://pub.dev" + source: hosted + version: "3.1.2" sdks: dart: ">=3.1.0-163.1.beta <4.0.0" flutter: ">=3.7.0-0" diff --git a/pubspec.yaml b/pubspec.yaml index 7b7d543..5f8149e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -50,6 +50,7 @@ dependencies: # flutter_holo_date_picker: ^1.1.0 validatorless: ^1.2.3 intl: + otp_text_field: ^1.1.3 dev_dependencies: flutter_test: @@ -61,6 +62,9 @@ dev_dependencies: # package. See that file for information about deactivating specific lint # rules and activating additional ones. flutter_lints: ^2.0.0 + build_runner: + stacked_generator: + # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec @@ -74,8 +78,9 @@ flutter: uses-material-design: true # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg + assets: + - .env + - assets/logo.png # - images/a_dot_ham.jpeg # An image asset can refer to one or more resolution-specific "variants", see