From 0bde3a28706bda89ded9883a8a3a106d9b7d10d6 Mon Sep 17 00:00:00 2001 From: Young Yu Date: Mon, 4 Mar 2024 23:30:58 -0800 Subject: [PATCH] add empty biometric setup page --- .../buttons/small_round_button.dart | 30 ++++++++ .../auth/pages/auth_page_selector.dart | 3 +- .../lib/features/home/pages/home_page.dart | 2 + .../pages/enter_biometrics_page.dart | 69 +++++++++++++++++++ .../pages/onboarding_page_selector.dart | 3 + .../onboarding/pages/welcome_page.dart | 31 +++++---- .../onboarding_page_state_provider.dart | 3 + .../features/syncing/pages/syncing_page.dart | 6 ++ .../syncing/pages/syncing_page_selector.dart | 2 +- .../syncing_page_state_provider.dart | 6 +- 10 files changed, 138 insertions(+), 17 deletions(-) create mode 100644 frontend/lib/common/components/buttons/small_round_button.dart create mode 100644 frontend/lib/features/onboarding/pages/enter_biometrics_page.dart diff --git a/frontend/lib/common/components/buttons/small_round_button.dart b/frontend/lib/common/components/buttons/small_round_button.dart new file mode 100644 index 0000000..a32c3df --- /dev/null +++ b/frontend/lib/common/components/buttons/small_round_button.dart @@ -0,0 +1,30 @@ +import 'package:flutter/material.dart'; + +/* A small round button holding any text */ +class SmallRoundButton extends StatelessWidget { + final String title; + final VoidCallback onPressed; + + const SmallRoundButton({ + super.key, + required this.title, + required this.onPressed, + }); + + @override + Widget build(BuildContext context) { + return ElevatedButton( + onPressed: onPressed, + style: ElevatedButton.styleFrom( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(25.0), + ), + backgroundColor: Theme.of(context).colorScheme.primary, + ), + child: Text( + title, + style: Theme.of(context).textTheme.labelLarge, + ), + ); + } +} diff --git a/frontend/lib/features/auth/pages/auth_page_selector.dart b/frontend/lib/features/auth/pages/auth_page_selector.dart index 8ec2cfe..c434d7f 100644 --- a/frontend/lib/features/auth/pages/auth_page_selector.dart +++ b/frontend/lib/features/auth/pages/auth_page_selector.dart @@ -40,8 +40,7 @@ class AuthPageSelector extends ConsumerWidget { } } else { /* User is logged in */ - return const SyncingPageSelector(); - // return HomePage(); + return const SyncingPageSelector(); /* Always sync when app starts */ } }, loading: () => const CircularProgressIndicator(), diff --git a/frontend/lib/features/home/pages/home_page.dart b/frontend/lib/features/home/pages/home_page.dart index 6271aa6..3137d36 100644 --- a/frontend/lib/features/home/pages/home_page.dart +++ b/frontend/lib/features/home/pages/home_page.dart @@ -17,6 +17,8 @@ class HomePage extends ConsumerWidget { ref.read(authPageStateProvider.notifier).state = AuthPageState.login; // TODO: notify user if not all data has been synced with server yet + + // TODO: move this to a central shared file } @override diff --git a/frontend/lib/features/onboarding/pages/enter_biometrics_page.dart b/frontend/lib/features/onboarding/pages/enter_biometrics_page.dart new file mode 100644 index 0000000..47a5fa0 --- /dev/null +++ b/frontend/lib/features/onboarding/pages/enter_biometrics_page.dart @@ -0,0 +1,69 @@ +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:frontend/common/components/buttons/small_round_button.dart'; +import 'package:frontend/features/auth/providers/auth_page_state_provider.dart'; + +class EnterBiometricsPage extends ConsumerWidget { + const EnterBiometricsPage({super.key}); + + void signOutUser(WidgetRef ref) async { + FirebaseAuth.instance.signOut(); + ref.read(authPageStateProvider.notifier).state = AuthPageState.login; + + // TODO: notify user if not all data has been synced with server yet + + // TODO: move this to a central shared file + } + + @override + Widget build(BuildContext context, WidgetRef ref) { + /* Get the screen height */ + double screenHeight = MediaQuery.of(context).size.height; + // Controllers for form fields + final TextEditingController birthdayController = TextEditingController(); + // Add controllers for other fields as needed + + return Scaffold( + appBar: AppBar( + backgroundColor: Theme.of(context).colorScheme.background, + title: Text( + "Profile Setup", + style: Theme.of(context).textTheme.displaySmall, + )), + body: SafeArea( + child: SingleChildScrollView( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text( + "Birthday", + style: TextStyle(fontSize: 16), + ), + TextField( + controller: birthdayController, + decoration: const InputDecoration( + hintText: 'YYYY-MM-DD', + ), + ), + // Add other fields (sex, height, weight, etc.) here + SizedBox(height: screenHeight * .01), + + /* Save button */ + Align( + alignment: Alignment.centerRight, + child: SmallRoundButton( + title: "Save", + onPressed: () { + signOutUser(ref); + }, + ), + ) + ], + ), + ), + ), + ); + } +} diff --git a/frontend/lib/features/onboarding/pages/onboarding_page_selector.dart b/frontend/lib/features/onboarding/pages/onboarding_page_selector.dart index 62017a9..6050487 100644 --- a/frontend/lib/features/onboarding/pages/onboarding_page_selector.dart +++ b/frontend/lib/features/onboarding/pages/onboarding_page_selector.dart @@ -2,6 +2,7 @@ import "package:flutter/material.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:frontend/features/home/pages/home_page_selector.dart"; +import "package:frontend/features/onboarding/pages/enter_biometrics_page.dart"; import "package:frontend/features/onboarding/pages/welcome_page.dart"; import "package:frontend/features/onboarding/providers/onboarding_page_state_provider.dart"; @@ -21,6 +22,8 @@ class OnboardingPageSelector extends ConsumerWidget { switch (pageState) { case OnboardingPageState.welcome: return const WelcomePage(); + case OnboardingPageState.enterBiometrics: + return const EnterBiometricsPage(); default: return const HomePageSelector(); } diff --git a/frontend/lib/features/onboarding/pages/welcome_page.dart b/frontend/lib/features/onboarding/pages/welcome_page.dart index d2ef1f9..10fb7e1 100644 --- a/frontend/lib/features/onboarding/pages/welcome_page.dart +++ b/frontend/lib/features/onboarding/pages/welcome_page.dart @@ -1,7 +1,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:frontend/features/syncing/providers/syncing_page_state_provider.dart'; +import 'package:frontend/common/components/buttons/small_round_button.dart'; +import 'package:frontend/features/onboarding/providers/onboarding_page_state_provider.dart'; +/* Welcome page shown before user onboards */ class WelcomePage extends ConsumerWidget { const WelcomePage({super.key}); @@ -19,23 +21,26 @@ class WelcomePage extends ConsumerWidget { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - const Text( + /* Title text */ + Text( "Let's get you set up", - style: TextStyle( - fontSize: 24, - fontWeight: FontWeight.bold, - ), + style: Theme.of(context).textTheme.displayLarge, ), SizedBox(height: screenHeight * .01), - ElevatedButton( - // TODO: navigate to next page instead of home + Text( + "Looks like you haven't set up your profile yet", + style: Theme.of(context).textTheme.bodyMedium, + ), + SizedBox(height: screenHeight * .01), + + /* Next page button */ + SmallRoundButton( + title: "Next", onPressed: () { - ref.read(syncingPageStateProvider.notifier).state = - SyncingPageState.home; + ref.read(onboardingPageStateProvider.notifier).state = + OnboardingPageState.enterBiometrics; }, - child: const Text('Next'), - // TODO create button (use auth buttom) - ), + ) ], ), ), diff --git a/frontend/lib/features/onboarding/providers/onboarding_page_state_provider.dart b/frontend/lib/features/onboarding/providers/onboarding_page_state_provider.dart index f170dfd..39f13d6 100644 --- a/frontend/lib/features/onboarding/providers/onboarding_page_state_provider.dart +++ b/frontend/lib/features/onboarding/providers/onboarding_page_state_provider.dart @@ -3,6 +3,9 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; /* States for which auth page the user is on */ enum OnboardingPageState { welcome, + enterBiometrics, + finishOnboarding, + customMacros, } /* Listen for state changes for which onboarding page the user is on */ diff --git a/frontend/lib/features/syncing/pages/syncing_page.dart b/frontend/lib/features/syncing/pages/syncing_page.dart index 9ba53ee..e11de5f 100644 --- a/frontend/lib/features/syncing/pages/syncing_page.dart +++ b/frontend/lib/features/syncing/pages/syncing_page.dart @@ -4,6 +4,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:frontend/common/services/api/user_api_service.dart'; import 'package:frontend/common/services/realm/user_realm_service.dart'; import 'package:frontend/features/auth/providers/auth_page_state_provider.dart'; +import 'package:frontend/features/onboarding/providers/onboarding_page_state_provider.dart'; import 'package:frontend/features/syncing/providers/syncing_page_state_provider.dart'; import 'package:frontend/logging/logger.dart'; @@ -36,6 +37,8 @@ class SyncingPage extends ConsumerWidget { if (userData == null) { ref.read(syncingPageStateProvider.notifier).state = SyncingPageState.onboarding; + ref.read(onboardingPageStateProvider.notifier).state = + OnboardingPageState.welcome; return; } @@ -70,6 +73,7 @@ class SyncingPage extends ConsumerWidget { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ + /* Loading circle*/ const CircularProgressIndicator(), SizedBox(height: screenHeight * .01), Text( @@ -80,6 +84,8 @@ class SyncingPage extends ConsumerWidget { ), ), SizedBox(height: screenHeight * .01), + + /* Cancel button */ GestureDetector( onTap: () { signOutUser(ref); diff --git a/frontend/lib/features/syncing/pages/syncing_page_selector.dart b/frontend/lib/features/syncing/pages/syncing_page_selector.dart index fe49101..5527127 100644 --- a/frontend/lib/features/syncing/pages/syncing_page_selector.dart +++ b/frontend/lib/features/syncing/pages/syncing_page_selector.dart @@ -28,7 +28,7 @@ class SyncingPageSelector extends ConsumerWidget { case SyncingPageState.home: return const HomePageSelector(); default: - return const HomePageSelector(); + return const SyncingPage(); } } } diff --git a/frontend/lib/features/syncing/providers/syncing_page_state_provider.dart b/frontend/lib/features/syncing/providers/syncing_page_state_provider.dart index 8edde94..ef23f41 100644 --- a/frontend/lib/features/syncing/providers/syncing_page_state_provider.dart +++ b/frontend/lib/features/syncing/providers/syncing_page_state_provider.dart @@ -1,7 +1,11 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; /* States for which syncing page the user is on */ -enum SyncingPageState { syncing, onboarding, home } +enum SyncingPageState { + syncing, + onboarding, + home, +} /* Listen for state changes for which onboarding page the user is on */ final syncingPageStateProvider = StateProvider((ref) {