Skip to content

Commit

Permalink
create initial logic that creates user after onboarding
Browse files Browse the repository at this point in the history
  • Loading branch information
youngbryanyu committed Mar 7, 2024
1 parent 67a3b60 commit 3eec510
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 9 deletions.
4 changes: 2 additions & 2 deletions backend/src/features/users/models/userModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ export interface IUser extends BaseDocument<IUser> {
_id: string /* Use firebase UID */;
birthday: Date;
sex: number;
height: number /* store height in cm */;
weight: number /* store weight in kg */;
height: number /* store height in cm for precision over in */;
weight: number /* store weight in lbs for precision over kg */;
activityLevel: number;
weightGoal: number;
useMetric: boolean;
Expand Down
55 changes: 53 additions & 2 deletions frontend/lib/common/services/api/user_api_service.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:dio/dio.dart';
import 'package:frontend/common/http/http_client.dart';
import 'package:frontend/logging/logger.dart';
import 'package:intl/intl.dart';

/* Class for interacting with user related backend APIs */
class UserApiService {
Expand All @@ -20,11 +21,61 @@ class UserApiService {
if (response.statusCode == 500) {
// TODO: handle 500 status code
}

// TODO: handle other status codes
return null;
}
} catch (error) {
appLogger.info('Error while getting user from the backend:\n', error);
appLogger.info(
'Error occurred during GET /users/:userId request:\n', error);
rethrow;
}
}

static Future<void> createUser({
required String userId,
required DateTime birthday,
required int sex,
required int height,
required int weight,
required int activityLevel,
required int weightGoal,
required bool userMetric,
}) async {
// TODO: create function to compute recommended macros
try {
/* Call POST API */
final response = await dio.post(
'/users',
data: {
'userId': userId,
'birthday': DateFormat('yyyy-MM-dd').format(birthday.toUtc()),
'sex': sex,
'height': height,
'weight': weight,
'activityLevel': activityLevel,
'weightGoal': weightGoal,
'useMetric': userMetric,
'goals': {
'calories': 2000,
'protein': 200,
'fat': 60,
'carbohydrates': 200,
},
'updatedAt': DateTime.now().toUtc().toIso8601String(),
'createdAt': DateTime.now().toUtc().toIso8601String(),
},
);

if (response.statusCode == 201) {
/* Success, do nothing */
} else if (response.statusCode == 500) {
/* TODO: handle all status codes */
} else {
throw Error();
}
} catch (error) {
// TODO: handle errors
appLogger.info('Error occurred during POST /users request:\n', error);
rethrow;
}
}
Expand Down
60 changes: 56 additions & 4 deletions frontend/lib/features/onboarding/pages/enter_biometrics_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import 'package:flutter/cupertino.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/common/services/api/user_api_service.dart';
import 'package:frontend/features/auth/providers/auth_page_state_provider.dart';
import 'package:frontend/features/syncing/providers/syncing_page_state_provider.dart';
import 'package:frontend/logging/logger.dart';
import 'package:intl/intl.dart';

/* Enter biometrics page widget */
Expand All @@ -28,7 +31,15 @@ class _EnterBiometricsPageState extends ConsumerState<EnterBiometricsPage> {
'Very Active',
'Extremely Active'
];
final List<String> weightGoalOptions = ['Lose', 'Gain', 'Maintain'];
final List<String> weightGoalOptions = [
'Fast loss',
'Moderate loss',
'Slow loss',
'Maintain',
'Slow Gain',
'Moderate Gain',
'Fast Gain',
];

// TODO: set all values initially to "select, then enforce that they must be selected"
String selectedSex = 'Select';
Expand All @@ -39,13 +50,48 @@ class _EnterBiometricsPageState extends ConsumerState<EnterBiometricsPage> {
String selectedActivityLevel = 'Select';
String selectedWeightGoal = 'Select';

// TODO: remove this later, since we don't need a logout page
void signOutUser(WidgetRef ref) async {
FirebaseAuth.instance.signOut();
ref.read(authPageStateProvider.notifier).state = AuthPageState.login;
}

// TODO create input validation to ensure all fields must be filled in before continuing
void createUser(WidgetRef ref) async {
try {
/* Get uid */
final userId = FirebaseAuth.instance.currentUser?.uid;

/* Sign out if no user */
if (userId == null) {
signOutUser(ref);
return;
}

// TODO: add user to realm first

// TODO: notify user if not all data has been synced with server yet
/* Make HTTP request to create new user info */
// TODO: handle this error with HTTP on its own
await UserApiService.createUser(
userId: userId,
birthday: selectedBirthday!,
sex: sexOptions.indexOf(selectedSex),
height: selectedHeight,
weight: selectedWeight,
activityLevel: activityLevelOptions.indexOf(selectedActivityLevel),
weightGoal: weightGoalOptions.indexOf(selectedWeightGoal),
userMetric: selectedUnit == 'Imperial' ? false : true,
);

// TODO: move this to a central shared file
// TODO: navigate to home page, change to custom macros page later
ref.read(syncingPageStateProvider.notifier).state = SyncingPageState.home;
} catch (error) {
appLogger.info(
'Error occurred while syncing new user to server. Logging out:\n',
error,
); // TODO: fix handling of error
signOutUser(ref);
}
}

@override
Expand Down Expand Up @@ -159,12 +205,18 @@ class _EnterBiometricsPageState extends ConsumerState<EnterBiometricsPage> {
),
context,
),
SmallRoundButton(
title: "I'm finished",
onPressed: () {
createUser(ref);
}, // TODO: edit this button or use another one
),
SmallRoundButton(
title: "Logout",
onPressed: () {
signOutUser(ref);
},
)
),
],
),
),
Expand Down
2 changes: 1 addition & 1 deletion frontend/lib/features/syncing/pages/syncing_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class SyncingPage extends ConsumerWidget {
);
signOutUser(ref);
}
}
} // TODO: perhaps use individual try catch for HTTP so its not grouped into the same

@override
Widget build(BuildContext context, WidgetRef ref) {
Expand Down

0 comments on commit 3eec510

Please sign in to comment.