diff --git a/assets/images/placeholderfood.png b/assets/images/placeholderfood.png new file mode 100644 index 0000000..8a69aed Binary files /dev/null and b/assets/images/placeholderfood.png differ diff --git a/lib/main.dart b/lib/main.dart index 94a29c2..d83b65b 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,28 +1,14 @@ -import 'package:cloud_firestore/cloud_firestore.dart'; - -import 'dart:developer'; - import 'package:flutter/material.dart'; import 'package:firebase_core/firebase_core.dart'; -import 'package:pdg_app/model/message.dart'; -import 'package:pdg_app/widgets/forms/main_text_field.dart'; import 'package:pdg_app/router/router.gr.dart'; import 'package:pdg_app/theme.dart'; import 'firebase_options.dart'; -import 'api/imessage.dart'; -import 'api/firebase_message.dart'; - void main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp( options: DefaultFirebaseOptions.currentPlatform, ); - IMessage msg = FirebaseMessage(FirebaseFirestore.instance); - - final m1 = Message(uid: '', fromId: 'alice', toId: 'bob', content: "HELLOW"); - msg.createMessage(m1); - log("test"); runApp(MyApp()); } @@ -47,54 +33,3 @@ class MyApp extends StatelessWidget { ); } } - -class MyHomePage extends StatefulWidget { - const MyHomePage({Key? key, required this.title}) : super(key: key); - - final String title; - - @override - State createState() => _MyHomePageState(); -} - -class _MyHomePageState extends State { - void _incrementCounter() { - setState(() {}); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text(widget.title), - ), - body: Center( - child: Padding( - padding: const EdgeInsets.all(20.0), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: const [ - MainTextField( - name: "Email", - icon: Icon(Icons.email_outlined), - keyboardType: TextInputType.emailAddress, - ), - SizedBox(height: 10), - MainTextField( - name: "Password", - icon: Icon(Icons.password), - obscureText: true, - keyboardType: TextInputType.emailAddress, - ), - ], - ), - ), - ), - floatingActionButton: FloatingActionButton( - onPressed: _incrementCounter, - tooltip: 'Increment', - child: const Icon(Icons.add), - ), - ); - } -} diff --git a/lib/router/router.dart b/lib/router/router.dart index 4983f39..7e9e761 100644 --- a/lib/router/router.dart +++ b/lib/router/router.dart @@ -1,4 +1,6 @@ import 'package:auto_route/auto_route.dart'; +import 'package:auto_route/empty_router_widgets.dart'; +import 'package:pdg_app/screens/add_meal.dart'; import 'package:pdg_app/screens/chat.dart'; import 'package:pdg_app/screens/diary.dart'; import 'package:pdg_app/screens/login.dart'; @@ -24,8 +26,19 @@ import '../screens/home.dart'; path: 'chat', ), AutoRoute( - page: DiaryScreen, + page: EmptyRouterPage, + name: "DiaryRouterPage", path: 'diary', + children: [ + AutoRoute( + path: '', + page: DiaryScreen, + ), + AutoRoute( + path: 'add', + page: AddMealScreen, + ), + ], ), AutoRoute( page: ProfileScreen, @@ -36,6 +49,7 @@ import '../screens/home.dart'; AutoRoute( page: LoginScreen, path: '/login', + initial: false, ), AutoRoute( page: RegisterScreen, diff --git a/lib/router/router.gr.dart b/lib/router/router.gr.dart index 7ffbf6a..7c7d9c5 100644 --- a/lib/router/router.gr.dart +++ b/lib/router/router.gr.dart @@ -11,76 +11,93 @@ // ignore_for_file: type=lint // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'package:auto_route/auto_route.dart' as _i7; -import 'package:flutter/material.dart' as _i8; +import 'package:auto_route/auto_route.dart' as _i9; +import 'package:auto_route/empty_router_widgets.dart' as _i5; +import 'package:flutter/material.dart' as _i10; +import '../screens/add_meal.dart' as _i8; import '../screens/chat.dart' as _i4; -import '../screens/diary.dart' as _i5; +import '../screens/diary.dart' as _i7; import '../screens/home.dart' as _i1; import '../screens/login.dart' as _i2; import '../screens/profile.dart' as _i6; import '../screens/register.dart' as _i3; -class AppRouter extends _i7.RootStackRouter { - AppRouter([_i8.GlobalKey<_i8.NavigatorState>? navigatorKey]) +class AppRouter extends _i9.RootStackRouter { + AppRouter([_i10.GlobalKey<_i10.NavigatorState>? navigatorKey]) : super(navigatorKey); @override - final Map pagesMap = { + final Map pagesMap = { HomeScreenRoute.name: (routeData) { - return _i7.MaterialPageX( + return _i9.MaterialPageX( routeData: routeData, child: const _i1.HomeScreen()); }, LoginScreenRoute.name: (routeData) { - return _i7.MaterialPageX( + return _i9.MaterialPageX( routeData: routeData, child: const _i2.LoginScreen()); }, RegisterScreenRoute.name: (routeData) { - return _i7.MaterialPageX( + return _i9.MaterialPageX( routeData: routeData, child: const _i3.RegisterScreen()); }, ChatScreenRoute.name: (routeData) { - return _i7.MaterialPageX( + return _i9.MaterialPageX( routeData: routeData, child: const _i4.ChatScreen()); }, - DiaryScreenRoute.name: (routeData) { - return _i7.MaterialPageX( - routeData: routeData, child: const _i5.DiaryScreen()); + DiaryRouterPage.name: (routeData) { + return _i9.MaterialPageX( + routeData: routeData, child: const _i5.EmptyRouterPage()); }, ProfileScreenRoute.name: (routeData) { - return _i7.MaterialPageX( + return _i9.MaterialPageX( routeData: routeData, child: const _i6.ProfileScreen()); + }, + DiaryScreenRoute.name: (routeData) { + return _i9.MaterialPageX( + routeData: routeData, child: const _i7.DiaryScreen()); + }, + AddMealScreenRoute.name: (routeData) { + return _i9.MaterialPageX( + routeData: routeData, child: const _i8.AddMealScreen()); } }; @override - List<_i7.RouteConfig> get routes => [ - _i7.RouteConfig('/#redirect', + List<_i9.RouteConfig> get routes => [ + _i9.RouteConfig('/#redirect', path: '/', redirectTo: '/home', fullMatch: true), - _i7.RouteConfig(HomeScreenRoute.name, path: '/home', children: [ - _i7.RouteConfig('#redirect', + _i9.RouteConfig(HomeScreenRoute.name, path: '/home', children: [ + _i9.RouteConfig('#redirect', path: '', parent: HomeScreenRoute.name, redirectTo: 'diary', fullMatch: true), - _i7.RouteConfig(ChatScreenRoute.name, + _i9.RouteConfig(ChatScreenRoute.name, path: 'chat', parent: HomeScreenRoute.name), - _i7.RouteConfig(DiaryScreenRoute.name, - path: 'diary', parent: HomeScreenRoute.name), - _i7.RouteConfig(ProfileScreenRoute.name, + _i9.RouteConfig(DiaryRouterPage.name, + path: 'diary', + parent: HomeScreenRoute.name, + children: [ + _i9.RouteConfig(DiaryScreenRoute.name, + path: '', parent: DiaryRouterPage.name), + _i9.RouteConfig(AddMealScreenRoute.name, + path: 'add', parent: DiaryRouterPage.name) + ]), + _i9.RouteConfig(ProfileScreenRoute.name, path: 'my', parent: HomeScreenRoute.name) ]), - _i7.RouteConfig(LoginScreenRoute.name, path: '/login'), - _i7.RouteConfig(RegisterScreenRoute.name, path: '/register'), - _i7.RouteConfig('*#redirect', + _i9.RouteConfig(LoginScreenRoute.name, path: '/login'), + _i9.RouteConfig(RegisterScreenRoute.name, path: '/register'), + _i9.RouteConfig('*#redirect', path: '*', redirectTo: '/home/diary', fullMatch: true) ]; } /// generated route for /// [_i1.HomeScreen] -class HomeScreenRoute extends _i7.PageRouteInfo { - const HomeScreenRoute({List<_i7.PageRouteInfo>? children}) +class HomeScreenRoute extends _i9.PageRouteInfo { + const HomeScreenRoute({List<_i9.PageRouteInfo>? children}) : super(HomeScreenRoute.name, path: '/home', initialChildren: children); static const String name = 'HomeScreenRoute'; @@ -88,7 +105,7 @@ class HomeScreenRoute extends _i7.PageRouteInfo { /// generated route for /// [_i2.LoginScreen] -class LoginScreenRoute extends _i7.PageRouteInfo { +class LoginScreenRoute extends _i9.PageRouteInfo { const LoginScreenRoute() : super(LoginScreenRoute.name, path: '/login'); static const String name = 'LoginScreenRoute'; @@ -96,7 +113,7 @@ class LoginScreenRoute extends _i7.PageRouteInfo { /// generated route for /// [_i3.RegisterScreen] -class RegisterScreenRoute extends _i7.PageRouteInfo { +class RegisterScreenRoute extends _i9.PageRouteInfo { const RegisterScreenRoute() : super(RegisterScreenRoute.name, path: '/register'); @@ -105,24 +122,41 @@ class RegisterScreenRoute extends _i7.PageRouteInfo { /// generated route for /// [_i4.ChatScreen] -class ChatScreenRoute extends _i7.PageRouteInfo { +class ChatScreenRoute extends _i9.PageRouteInfo { const ChatScreenRoute() : super(ChatScreenRoute.name, path: 'chat'); static const String name = 'ChatScreenRoute'; } /// generated route for -/// [_i5.DiaryScreen] -class DiaryScreenRoute extends _i7.PageRouteInfo { - const DiaryScreenRoute() : super(DiaryScreenRoute.name, path: 'diary'); +/// [_i5.EmptyRouterPage] +class DiaryRouterPage extends _i9.PageRouteInfo { + const DiaryRouterPage({List<_i9.PageRouteInfo>? children}) + : super(DiaryRouterPage.name, path: 'diary', initialChildren: children); - static const String name = 'DiaryScreenRoute'; + static const String name = 'DiaryRouterPage'; } /// generated route for /// [_i6.ProfileScreen] -class ProfileScreenRoute extends _i7.PageRouteInfo { +class ProfileScreenRoute extends _i9.PageRouteInfo { const ProfileScreenRoute() : super(ProfileScreenRoute.name, path: 'my'); static const String name = 'ProfileScreenRoute'; } + +/// generated route for +/// [_i7.DiaryScreen] +class DiaryScreenRoute extends _i9.PageRouteInfo { + const DiaryScreenRoute() : super(DiaryScreenRoute.name, path: ''); + + static const String name = 'DiaryScreenRoute'; +} + +/// generated route for +/// [_i8.AddMealScreen] +class AddMealScreenRoute extends _i9.PageRouteInfo { + const AddMealScreenRoute() : super(AddMealScreenRoute.name, path: 'add'); + + static const String name = 'AddMealScreenRoute'; +} diff --git a/lib/screens/add_meal.dart b/lib/screens/add_meal.dart new file mode 100644 index 0000000..adf631d --- /dev/null +++ b/lib/screens/add_meal.dart @@ -0,0 +1,415 @@ +import 'package:auto_route/auto_route.dart'; +import 'package:cross_file_image/cross_file_image.dart'; +import 'package:day_night_time_picker/day_night_time_picker.dart'; +import 'package:flutter/material.dart'; +import 'package:pdg_app/widgets/buttons/action_button.dart'; +import 'package:pdg_app/widgets/cards/main_card.dart'; +import 'package:pdg_app/widgets/forms/main_text_field.dart'; +import 'package:pdg_app/widgets/custom_icon_button.dart'; +import 'package:image_picker/image_picker.dart'; + +import '../widgets/slider_with_text.dart'; + +class AddMealScreen extends StatefulWidget { + const AddMealScreen({Key? key}) : super(key: key); + + @override + State createState() => _AddMealScreenState(); +} + +enum _TimeButtonEnum { + start, + end, + none, +} + +class _AddMealScreenState extends State { + double _hungerBeforeValue = 3; + double _hungerAfterValue = 3; + final ImagePicker _picker = ImagePicker(); + XFile? _image; + _TimeButtonEnum _timeValueToChange = _TimeButtonEnum.none; + bool _showModal = false; + TimeOfDay? _startTime; + TimeOfDay? _endTime; + + Future _takePicture() async { + final XFile? image = await _picker.pickImage(source: ImageSource.camera); + return image; + } + + Future _getPicture() async { + final XFile? image = await _picker.pickImage(source: ImageSource.gallery); + return image; + } + + @override + Widget build(BuildContext context) { + return AddMeal( + hungerBeforeValue: _hungerBeforeValue, + hungerAfterValue: _hungerAfterValue, + onHungerAfterChanged: (value) => setState(() { + _hungerAfterValue = value; + }), + onHungerBeforeChanged: (value) => setState(() { + _hungerBeforeValue = value; + }), + image: _image, + onCameraPressed: () async { + _image = await _takePicture(); + setState(() {}); + }, + onGalleryPressed: () async { + _image = await _getPicture(); + setState(() {}); + }, + onTimeSelected: (time) { + setState(() { + switch (_timeValueToChange) { + case _TimeButtonEnum.start: + _startTime = time; + break; + case _TimeButtonEnum.end: + _endTime = time; + break; + default: + break; + } + + _showModal = false; + _timeValueToChange = _TimeButtonEnum.none; + }); + }, + onTimeSelectCanceled: () { + setState(() { + _showModal = false; + _timeValueToChange = _TimeButtonEnum.none; + }); + }, + onStartTimeSelected: () { + setState(() { + _timeValueToChange = _TimeButtonEnum.start; + _showModal = true; + }); + }, + onEndTimeSelected: () { + setState(() { + _timeValueToChange = _TimeButtonEnum.end; + _showModal = true; + }); + }, + showTimePicker: _showModal, + startTimeText: _startTime?.format(context) ?? 'Start Time', + endTimeText: _endTime?.format(context) ?? 'End Time', + onValidatePressed: () => AutoRouter.of(context).pop(), + ); + } +} + +class AddMeal extends StatelessWidget { + final double _hungerBeforeValue; + final double _hungerAfterValue; + final void Function(double) _onHungerBeforeChanged; + final void Function(double) _onHungerAfterChanged; + final void Function() _onCameraPressed; + final void Function() _onGalleryPressed; + final XFile? _image; + final void Function(TimeOfDay) _onTimeSelected; + final void Function()? _onTimeSelectCanceled; + final void Function()? _onStartTimeSelected; + final void Function()? _onEndTimeSelected; + final bool _showTimePicker; + final String? _startTimeText; + final String? _endTimeText; + final void Function()? _onValidatePressed; + + const AddMeal({ + Key? key, + required double hungerBeforeValue, + required double hungerAfterValue, + required void Function(double) onHungerBeforeChanged, + required void Function(double) onHungerAfterChanged, + required void Function() onCameraPressed, + required void Function() onGalleryPressed, + required void Function(TimeOfDay) onTimeSelected, + void Function()? onStartTimeSelected, + void Function()? onEndTimeSelected, + void Function()? onTimeSelectCanceled, + void Function()? onValidatePressed, + bool showTimePicker = false, + String? startTimeText, + String? endTimeText, + XFile? image, + }) : _hungerBeforeValue = hungerBeforeValue, + _hungerAfterValue = hungerAfterValue, + _onHungerAfterChanged = onHungerAfterChanged, + _onHungerBeforeChanged = onHungerBeforeChanged, + _onCameraPressed = onCameraPressed, + _onGalleryPressed = onGalleryPressed, + _image = image, + _onTimeSelected = onTimeSelected, + _onTimeSelectCanceled = onTimeSelectCanceled, + _onStartTimeSelected = onStartTimeSelected, + _onEndTimeSelected = onEndTimeSelected, + _showTimePicker = showTimePicker, + _startTimeText = startTimeText, + _endTimeText = endTimeText, + _onValidatePressed = onValidatePressed, + super(key: key); + + @override + Widget build(BuildContext context) { + const double height = 250; + return Stack( + children: [ + Column( + children: [ + _Top( + height: height, + image: _image, + onCameraPressed: _onCameraPressed, + onGalleryPressed: _onGalleryPressed), + Expanded( + child: _ListView( + hungerAfterValue: _hungerAfterValue, + hungerBeforeValue: _hungerBeforeValue, + onHungerAfterChanged: _onHungerAfterChanged, + onHungerBeforeChanged: _onHungerBeforeChanged, + onEndTimePress: _onEndTimeSelected, + onStartTimePress: _onStartTimeSelected, + endTimeText: _endTimeText, + startTimeText: _startTimeText, + ), + ), + ], + ), + ActionButton( + icon: Icons.check, + onPressed: _onValidatePressed, + ), + if (_showTimePicker) + createInlinePicker( + value: TimeOfDay.now(), + onChange: _onTimeSelected, + onCancel: _onTimeSelectCanceled, + is24HrFormat: true, + blurredBackground: true, + ), + ], + ); + } +} + +class _Top extends StatelessWidget { + const _Top({ + Key? key, + required this.height, + required XFile? image, + required void Function() onCameraPressed, + required void Function() onGalleryPressed, + }) : _image = image, + _onCameraPressed = onCameraPressed, + _onGalleryPressed = onGalleryPressed, + super(key: key); + + final double height; + final XFile? _image; + final void Function() _onCameraPressed; + final void Function() _onGalleryPressed; + + @override + Widget build(BuildContext context) { + return SizedBox( + height: height, + child: Stack( + children: [ + Container( + height: height, + width: double.infinity, + decoration: BoxDecoration( + image: DecorationImage( + fit: BoxFit.cover, + image: _image == null + ? const AssetImage("assets/images/placeholderfood.png") + as ImageProvider + : XFileImage(_image!), + ), + ), + ), + _PictureSelectorLayout( + onCameraPress: _onCameraPressed, + onImageSelectPress: _onGalleryPressed, + ), + ], + ), + ); + } +} + +class _PictureSelectorLayout extends StatelessWidget { + final void Function()? _onCameraPress; + final void Function()? _onImageSelectPress; + + const _PictureSelectorLayout({ + Key? key, + void Function()? onCameraPress, + void Function()? onImageSelectPress, + }) : _onCameraPress = onCameraPress, + _onImageSelectPress = onImageSelectPress, + super(key: key); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + CustomIconButton( + icon: Icons.camera_alt, + onTap: _onCameraPress, + ), + const SizedBox(width: 8), + CustomIconButton( + icon: Icons.image, + onTap: _onImageSelectPress, + ), + ], + ), + ], + ), + ); + } +} + +class _ListView extends StatelessWidget { + final double _hungerBeforeValue; + final double _hungerAfterValue; + final void Function(double) _onHungerBeforeChanged; + final void Function(double) _onHungerAfterChanged; + final void Function()? _onStartTimePress; + final void Function()? _onEndTimePress; + final String? _startTimeText; + final String? _endTimeText; + + const _ListView({ + Key? key, + required double hungerBeforeValue, + required double hungerAfterValue, + required void Function(double) onHungerBeforeChanged, + required void Function(double) onHungerAfterChanged, + void Function()? onStartTimePress, + void Function()? onEndTimePress, + String? startTimeText, + String? endTimeText, + }) : _hungerBeforeValue = hungerBeforeValue, + _hungerAfterValue = hungerAfterValue, + _onHungerAfterChanged = onHungerAfterChanged, + _onHungerBeforeChanged = onHungerBeforeChanged, + _onStartTimePress = onStartTimePress, + _onEndTimePress = onEndTimePress, + _startTimeText = startTimeText, + _endTimeText = endTimeText, + super(key: key); + + List listViewContent(BuildContext context) => [ + Text( + "Add a meal", + style: Theme.of(context) + .textTheme + .headline1! + .copyWith(color: Colors.black), + ), + const MainTextField( + name: "Meal name", + icon: Icon( + Icons.label, + color: Colors.black, + ), + ), + _TimePickerbutton( + text: _startTimeText ?? "Start Time", + onTap: _onStartTimePress, + ), + _TimePickerbutton( + text: _endTimeText ?? "End Time", + onTap: _onEndTimePress, + ), + SliderWithText( + context: context, + text: "Rate your hunger before eating", + value: _hungerBeforeValue, + onChanged: _onHungerBeforeChanged, + labels: const [ + "encore faim", + "inconfort", + "léger inconfort", + "confort" + ]), + SliderWithText( + context: context, + text: "Rate your satiety after eating", + value: _hungerAfterValue, + onChanged: _onHungerAfterChanged, + labels: const [ + "encore faim", + "inconfort", + "léger inconfort", + "confort" + ]), + ]; + + @override + Widget build(BuildContext context) { + final listContent = listViewContent(context); + + return ListView.separated( + padding: const EdgeInsets.all(16.0), + physics: const BouncingScrollPhysics(), + itemCount: listContent.length, + itemBuilder: (context, index) => listContent[index], + separatorBuilder: (context, index) => const SizedBox(height: 10), + ); + } +} + +class _TimePickerbutton extends StatelessWidget { + final String _text; + final void Function()? _onTap; + + const _TimePickerbutton({ + Key? key, + required String text, + void Function()? onTap, + }) : _text = text, + _onTap = onTap, + super(key: key); + + @override + Widget build(BuildContext context) { + return InkWell( + onTap: _onTap, + child: MainCard( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 12.0, vertical: 15), + child: Row( + children: [ + const Icon(Icons.timer), + const SizedBox(width: 10), + Text( + _text, + style: Theme.of(context).textTheme.bodyText1!.copyWith( + color: const Color.fromARGB(255, 112, 112, 112), + fontSize: 15, + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/screens/diary.dart b/lib/screens/diary.dart index 980e3d8..e00e027 100644 --- a/lib/screens/diary.dart +++ b/lib/screens/diary.dart @@ -1,6 +1,8 @@ +import 'package:auto_route/auto_route.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:pdg_app/model/meal.dart'; +import 'package:pdg_app/router/router.gr.dart'; import 'package:pdg_app/widgets/cards/arrow_pic_card.dart'; import 'package:table_calendar/table_calendar.dart'; @@ -34,9 +36,12 @@ class DiaryScreen extends StatelessWidget { @override Widget build(BuildContext context) { - return const Diary( + return Diary( getDiariesForDay: _getEventsForDay, clientName: "Marie", + onAddPressed: () { + AutoRouter.of(context).navigate(const AddMealScreenRoute()); + }, ); } } @@ -47,6 +52,7 @@ class Diary extends StatefulWidget { final List Function(DateTime) getDiariesForDay; final String clientName; final String clientPicturePath; + final void Function()? _onAddPressed; const Diary({ this.screenWidth = 0, @@ -54,8 +60,10 @@ class Diary extends StatefulWidget { required this.getDiariesForDay, required this.clientName, this.clientPicturePath = "assets/images/default_user_pic.png", + void Function()? onAddPressed, Key? key, - }) : super(key: key); + }) : _onAddPressed = onAddPressed, + super(key: key); @override State createState() => _DiaryState(); @@ -149,7 +157,11 @@ class _DiaryState extends State { ) ], ), - if (widget.showActionButton) const ActionButton(icon: Icons.add) + if (widget.showActionButton) + ActionButton( + icon: Icons.add, + onPressed: widget._onAddPressed, + ) ]); } } diff --git a/lib/screens/home.dart b/lib/screens/home.dart index 4581edf..60ad96b 100644 --- a/lib/screens/home.dart +++ b/lib/screens/home.dart @@ -17,7 +17,7 @@ class _HomeScreenState extends State { return AutoTabsRouter( routes: const [ ChatScreenRoute(), - DiaryScreenRoute(), + DiaryRouterPage(), ProfileScreenRoute(), ], builder: (context, child, animation) { diff --git a/lib/screens/login.dart b/lib/screens/login.dart index 935826a..de29bd1 100644 --- a/lib/screens/login.dart +++ b/lib/screens/login.dart @@ -14,7 +14,7 @@ class LoginScreen extends StatelessWidget { Widget build(BuildContext context) { return Login( onLoginPress: () => - AutoRouter.of(context).navigate(const RegisterScreenRoute()), + AutoRouter.of(context).navigate(const AddMealScreenRoute()), onRegisterPress: () => AutoRouter.of(context).navigate(const RegisterScreenRoute()), ); diff --git a/lib/widgets/buttons/action_button.dart b/lib/widgets/buttons/action_button.dart index 8e80938..1cd388c 100644 --- a/lib/widgets/buttons/action_button.dart +++ b/lib/widgets/buttons/action_button.dart @@ -2,11 +2,14 @@ import 'package:flutter/material.dart'; class ActionButton extends StatelessWidget { final IconData icon; + final void Function()? _onPressed; const ActionButton({ required this.icon, + void Function()? onPressed, Key? key, - }) : super(key: key); + }) : _onPressed = onPressed, + super(key: key); @override Widget build(BuildContext context) { @@ -27,7 +30,7 @@ class ActionButton extends StatelessWidget { ], shape: BoxShape.circle), child: FloatingActionButton( backgroundColor: Theme.of(context).colorScheme.primary, - onPressed: (() => 1), + onPressed: _onPressed, elevation: 100, child: Icon(icon, color: Theme.of(context).colorScheme.onPrimary, size: 35), diff --git a/lib/widgets/cards/main_card.dart b/lib/widgets/cards/main_card.dart index ea53e53..74e0c8b 100644 --- a/lib/widgets/cards/main_card.dart +++ b/lib/widgets/cards/main_card.dart @@ -12,6 +12,7 @@ class MainCard extends StatelessWidget { Widget build(BuildContext context) { return Container( decoration: BoxDecoration( + color: Colors.white, boxShadow: const [ BoxShadow( color: Colors.black38, @@ -22,12 +23,7 @@ class MainCard extends StatelessWidget { ], borderRadius: BorderRadius.circular(15.0), ), - child: Card( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(15.0), - ), - child: child, - ), + child: child, ); } } diff --git a/lib/widgets/custom_icon_button.dart b/lib/widgets/custom_icon_button.dart new file mode 100644 index 0000000..44c5573 --- /dev/null +++ b/lib/widgets/custom_icon_button.dart @@ -0,0 +1,30 @@ +import 'package:flutter/material.dart'; + +import 'cards/main_card.dart'; + +class CustomIconButton extends StatelessWidget { + final IconData _icon; + final void Function()? _onTap; + + const CustomIconButton({ + Key? key, + required IconData icon, + void Function()? onTap, + }) : _icon = icon, + _onTap = onTap, + super(key: key); + + @override + Widget build(BuildContext context) { + return MainCard( + child: InkWell( + onTap: _onTap, + child: SizedBox( + height: 40, + width: 40, + child: Icon(_icon), + ), + ), + ); + } +} diff --git a/lib/widgets/forms/main_text_field.dart b/lib/widgets/forms/main_text_field.dart index 8632ebc..aadd5c1 100644 --- a/lib/widgets/forms/main_text_field.dart +++ b/lib/widgets/forms/main_text_field.dart @@ -61,7 +61,7 @@ class _MainTextFieldState extends State { decoration: InputDecoration( prefixIcon: IconTheme( data: const IconThemeData( - color: Colors.black38, + color: Color(0xFF5B5B5B), ), child: widget.icon, ), diff --git a/lib/widgets/slider_with_text.dart b/lib/widgets/slider_with_text.dart new file mode 100644 index 0000000..5152af4 --- /dev/null +++ b/lib/widgets/slider_with_text.dart @@ -0,0 +1,55 @@ +import 'package:flutter/material.dart'; + +import 'cards/main_card.dart'; + +class SliderWithText extends StatelessWidget { + const SliderWithText({ + Key? key, + required this.context, + required this.text, + required this.value, + required this.onChanged, + required this.labels, + }) : super(key: key); + + final BuildContext context; + final String text; + final double value; + final void Function(double p1)? onChanged; + final List labels; + + @override + Widget build(BuildContext context) { + return MainCard( + child: Column( + children: [ + Padding( + padding: const EdgeInsets.fromLTRB(13, 10, 13, 0), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + const Icon(Icons.local_dining), + const SizedBox(width: 10), + Text( + text, + style: Theme.of(context) + .textTheme + .bodyText1! + .copyWith(color: const Color(0xFF5B5B5B), fontSize: 15), + ), + ], + ), + ), + Slider( + value: value, + onChanged: onChanged, + divisions: labels.length - 1, + label: labels[value.floor()], + min: 0, + max: labels.length.toDouble() - 1, + ), + ], + ), + ); + } +} diff --git a/pubspec.lock b/pubspec.lock index 9e5e722..5feded8 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -176,6 +176,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.0.2" + cross_file: + dependency: transitive + description: + name: cross_file + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.3+1" + cross_file_image: + dependency: "direct main" + description: + name: cross_file_image + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" crypto: dependency: transitive description: @@ -204,6 +218,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.2.3" + day_night_time_picker: + dependency: "direct main" + description: + name: day_night_time_picker + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.2" device_frame: dependency: transitive description: @@ -384,6 +405,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.2.1" + flutter_plugin_android_lifecycle: + dependency: transitive + description: + name: flutter_plugin_android_lifecycle + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.7" flutter_test: dependency: "direct dev" description: flutter @@ -464,6 +492,41 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "4.0.1" + image_picker: + dependency: "direct main" + description: + name: image_picker + url: "https://pub.dartlang.org" + source: hosted + version: "0.8.5+3" + image_picker_android: + dependency: transitive + description: + name: image_picker_android + url: "https://pub.dartlang.org" + source: hosted + version: "0.8.5+2" + image_picker_for_web: + dependency: transitive + description: + name: image_picker_for_web + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.8" + image_picker_ios: + dependency: transitive + description: + name: image_picker_ios + url: "https://pub.dartlang.org" + source: hosted + version: "0.8.5+6" + image_picker_platform_interface: + dependency: transitive + description: + name: image_picker_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.6.1" intl: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index c77089a..aa7f29e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -44,6 +44,9 @@ dependencies: table_calendar: ^3.0.6 intl: ^0.17.0 uuid: ^3.0.6 + image_picker: ^0.8.5+3 + cross_file_image: ^1.0.0 + day_night_time_picker: ^1.1.2 google_nav_bar: ^5.0.6 dev_dependencies: