Skip to content
Draft
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
46dd53c
cp-159: + survey navigation parameter and survey screen enum
BrianSammit Sep 19, 2023
3a88d5b
cp-159: + add pages with more steps to the survey
BrianSammit Sep 19, 2023
d9b25bc
cp-159: + fix bug of white background color in nested stack and fix p…
BrianSammit Sep 19, 2023
1f313f8
cp-159: + get the journaling step data and send it to the back-end
BrianSammit Sep 19, 2023
c9f40e5
cp-159: + get the feeling steps data and send it to the back-end
BrianSammit Sep 19, 2023
4fe01dd
cp-159: + get the goals steps data and send it to the back-end
BrianSammit Sep 19, 2023
1b29104
cp-159: + get the worries steps data and send it to the back-end
BrianSammit Sep 19, 2023
9224ce5
cp-159: + get the worries steps data and send it to the back-end
BrianSammit Sep 19, 2023
1c4e8d7
cp-159: + get the meditation steps data and send it to the back-end
BrianSammit Sep 19, 2023
3ac21bd
Merge branch 'development' into task/cp-159-add-more-steps-survey
iamAlinaaa Sep 20, 2023
6538027
cp-159: + add a component for reuse in screens and move the stack sur…
BrianSammit Sep 26, 2023
011cec8
cp-159: + redux slice to manage the state of the survey
BrianSammit Sep 26, 2023
8bc5bb9
cp-159: + the data receive from each step and update the slice
BrianSammit Sep 26, 2023
a7fb50c
cp-159: + collect the data from steps and send it
BrianSammit Sep 27, 2023
f94cc12
Merge branch 'task/cp-159-add-more-steps-survey' of https://github.co…
BrianSammit Sep 28, 2023
f686892
Merge branch 'development' of https://github.com/BinaryStudioAcademy/…
BrianSammit Sep 28, 2023
2c3c0b3
cp-159: + all steps to survey and fix styles
BrianSammit Sep 28, 2023
a502750
cp-159: * fix misspelling that generate bug sending data to back end
BrianSammit Sep 28, 2023
b872bfc
cp-159: + form for one option and and validation
BrianSammit Sep 29, 2023
3758042
cp-159: * merge conflicts
BrianSammit Sep 29, 2023
3e9d897
Merge branch 'development' into task/cp-159-add-more-steps-survey
BrianSammit Sep 29, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions frontend/src/pages/surveys/survey.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ const Survey: React.FC = () => {
void dispatch(
authActions.createUserSurvey({
userId: userId,
journaling_experience: [],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use camel case here

feelings: [],
goals: [],
worries: [],
meditation_experience: [],
preferences: options,
}),
);
Expand Down
13 changes: 11 additions & 2 deletions mobile/src/libs/components/app/app.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'fast-text-encoding';

import { NavigationContainer } from '@react-navigation/native';
import { DefaultTheme, NavigationContainer } from '@react-navigation/native';
import React from 'react';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import SplashScreen from 'react-native-splash-screen';
Expand All @@ -14,6 +14,15 @@ import { Root as RootNavigation } from '#navigations/navigations';
import { SPLASH_SCREEN_HIDE_TIMEOUT } from './libs/constants';
import { styles } from './styles';

// Prevent white background color on nested navigation stack
const theme = {
...DefaultTheme,
colors: {
...DefaultTheme.colors,
background: 'transparent',
},
};

const App: React.FC = () => {
useEffect(() => {
// To prevent white screen after splash screen disappears
Expand All @@ -29,7 +38,7 @@ const App: React.FC = () => {
return (
<StoreProvider store={store.instance}>
<GestureHandlerRootView style={styles.root}>
<NavigationContainer>
<NavigationContainer theme={theme}>
<RootNavigation />
</NavigationContainer>
<Toast />
Expand Down
1 change: 1 addition & 0 deletions mobile/src/libs/enums/enums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export {
MeditationScreenName,
ProfileScreenName,
RootScreenName,
SurveyScreenName,
} from './navigation/navigation';
export { AppColor } from './ui/ui';
export {
Expand Down
1 change: 1 addition & 0 deletions mobile/src/libs/enums/navigation/navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export { MainScreenName } from './main-screen-name.enum';
export { MeditationScreenName } from './meditation-screen-name.enum';
export { ProfileScreenName } from './profile-screen-name.enum';
export { RootScreenName } from './root-screen-name.enum';
export { SurveyScreenName } from './survey-screen-name.enum';
10 changes: 10 additions & 0 deletions mobile/src/libs/enums/navigation/survey-screen-name.enum.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const SurveyScreenName = {
PREFERENCES: 'preferences',
FEELINGS: 'feeling',
GOALS: 'goals',
WORRIES: 'worries',
MEDITATION_EXPERIENCE: 'meditation experience',
JOURNALING_EXPERIENCE: 'journaling experience',
} as const;

export { SurveyScreenName };
1 change: 1 addition & 0 deletions mobile/src/libs/types/navigation/navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ export { type NavigationItem } from './navigation-item.type';
export { type NavigationScreenProperties } from './navigation-screen-properties.type';
export { type ProfileNavigationParameterList } from './profile-navigation-parameter-list.type';
export { type RootNavigationParameterList } from './root-navigation-parameter-list.type';
export { type SurveyNavigationParameterList } from './survey-navigation-parameter-list.type';
export { type TabNavigationParameterList } from './tab-navigation-parameter-list.type';
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { type SurveyScreenName } from '#libs/enums/enums';

type SurveyNavigationParameterList = {
[SurveyScreenName.PREFERENCES]: undefined | object;
[SurveyScreenName.FEELINGS]: undefined | object;
[SurveyScreenName.GOALS]: undefined | object;
[SurveyScreenName.WORRIES]: undefined | object;
[SurveyScreenName.MEDITATION_EXPERIENCE]: undefined | object;
[SurveyScreenName.JOURNALING_EXPERIENCE]: undefined | object;
Comment on lines +4 to +9
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Provide more specific types

};

export { type SurveyNavigationParameterList };
1 change: 1 addition & 0 deletions mobile/src/libs/types/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export {
type NavigationScreenProperties,
type ProfileNavigationParameterList,
type RootNavigationParameterList,
type SurveyNavigationParameterList,
type TabNavigationParameterList,
} from './navigation/navigation';
export {
Expand Down
124 changes: 124 additions & 0 deletions mobile/src/screens/survey/components/feelings-step/feelings-step.tsx
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Create a generic component for reusing, it is not a good practise of your approach

Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import { type RouteProp } from '@react-navigation/native';
import { type NativeStackNavigationProp } from '@react-navigation/native-stack';
import React from 'react';

import { Button, Input, ScrollView, Text } from '#libs/components/components';
import { SurveyScreenName } from '#libs/enums/enums';
import {
useAppForm,
useCallback,
useFormController,
useNavigation,
} from '#libs/hooks/hooks';
import { type SurveyNavigationParameterList } from '#libs/types/types';
import {
getSurveyCategories,
type SurveyInputDto,
surveyInputValidationSchema,
} from '#packages/survey/survey';
import {
DEFAULT_SURVEY_PAYLOAD,
FEELING_CATEGORIES,
TEXTAREA_ROWS_COUNT,
} from '#screens/survey/libs/constants';

import { SurveyCategory } from '../components';
import { styles } from './styles';

type FeelingsStepProperties = {
route: RouteProp<
SurveyNavigationParameterList,
typeof SurveyScreenName.FEELINGS
>;
};

type FeelingsStepInitialParameters = {
setFeelingsSurvey: (payload: string[]) => void;
};

const FeelingsStep: React.FC<FeelingsStepProperties> = ({ route }) => {
const { setFeelingsSurvey } = route.params as FeelingsStepInitialParameters;
const navigation =
useNavigation<NativeStackNavigationProp<SurveyNavigationParameterList>>();

const { control, errors, isValid, handleSubmit } = useAppForm<SurveyInputDto>(
{
defaultValues: DEFAULT_SURVEY_PAYLOAD,
validationSchema: surveyInputValidationSchema,
},
);
const {
field: { onChange: onCategoryChange, value: categoriesValue },
} = useFormController({
name: 'preferences',
control,
});
const hasOther = categoriesValue.includes('Other');
const handleFieldChange = useCallback(
(option: string) => {
if (categoriesValue.includes(option)) {
onCategoryChange(
categoriesValue.filter((category) => {
return category !== option;
}),
);

return;
}

onCategoryChange([...categoriesValue, option]);
},
[categoriesValue, onCategoryChange],
);

const handleSurveySubmit = useCallback(
(payload: SurveyInputDto) => {
setFeelingsSurvey(getSurveyCategories(payload));
},
[setFeelingsSurvey],
);

const handleContinue = (): void => {
navigation.navigate(SurveyScreenName.GOALS);
void handleSubmit(handleSurveySubmit)();
};

const handleBack = (): void => {
navigation.navigate(SurveyScreenName.PREFERENCES);
};

return (
<ScrollView
style={styles.surveyContainer}
showsVerticalScrollIndicator={false}
>
<Text style={styles.titleText}>How have you been feeling lately?</Text>
{FEELING_CATEGORIES.map((category) => {
return (
<SurveyCategory
key={category}
onChange={handleFieldChange}
label={category}
/>
);
})}
{hasOther && (
<Input
control={control}
errors={errors}
name="other"
placeholder="Enter your preferences"
rowsCount={TEXTAREA_ROWS_COUNT}
/>
)}
<Button
label="Continue"
onPress={handleContinue}
isDisabled={!isValid}
type="outlined"
/>
<Button label="Go back" onPress={handleBack} type="solid" />
</ScrollView>
);
};
export { FeelingsStep };
32 changes: 32 additions & 0 deletions mobile/src/screens/survey/components/feelings-step/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { StyleSheet } from 'react-native';

import { AppColor } from '#libs/enums/enums';

const styles = StyleSheet.create({
surveyContainer: {
flex: 1,
marginTop: 40,
paddingHorizontal: 55,
},
otherTextInput: {
backgroundColor: AppColor.BLUE_100_ALPHA_70,
borderRadius: 8,
padding: 8,
borderWidth: 1,
marginBottom: 20,
borderColor: AppColor.WHITE,
color: AppColor.BLUE_300,
fontSize: 16,
},
titleText: {
fontSize: 22,
color: AppColor.WHITE,
marginBottom: 30,
marginTop: 30,
},
placeholder: {
color: AppColor.WHITE,
},
});

export { styles };
126 changes: 126 additions & 0 deletions mobile/src/screens/survey/components/goals-step/goals-step.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import { type RouteProp } from '@react-navigation/native';
import { type NativeStackNavigationProp } from '@react-navigation/native-stack';
import React from 'react';

import { Button, Input, ScrollView, Text } from '#libs/components/components';
import { SurveyScreenName } from '#libs/enums/enums';
import {
useAppForm,
useCallback,
useFormController,
useNavigation,
} from '#libs/hooks/hooks';
import { type SurveyNavigationParameterList } from '#libs/types/types';
import {
getSurveyCategories,
type SurveyInputDto,
surveyInputValidationSchema,
} from '#packages/survey/survey';
import {
DEFAULT_SURVEY_PAYLOAD,
GOALS_CATEGORIES,
TEXTAREA_ROWS_COUNT,
} from '#screens/survey/libs/constants';

import { SurveyCategory } from '../components';
import { styles } from './styles';

type GoalsStepProperties = {
route: RouteProp<
SurveyNavigationParameterList,
typeof SurveyScreenName.GOALS
>;
};

type GoalsStepInitialParameters = {
setGoalsSurvey: (payload: string[]) => void;
};

const GoalsStep: React.FC<GoalsStepProperties> = ({ route }) => {
const { setGoalsSurvey } = route.params as GoalsStepInitialParameters;
const navigation =
useNavigation<NativeStackNavigationProp<SurveyNavigationParameterList>>();

const { control, errors, isValid, handleSubmit } = useAppForm<SurveyInputDto>(
{
defaultValues: DEFAULT_SURVEY_PAYLOAD,
validationSchema: surveyInputValidationSchema,
},
);
const {
field: { onChange: onCategoryChange, value: categoriesValue },
} = useFormController({
name: 'preferences',
control,
});
const hasOther = categoriesValue.includes('Other');
const handleFieldChange = useCallback(
(option: string) => {
if (categoriesValue.includes(option)) {
onCategoryChange(
categoriesValue.filter((category) => {
return category !== option;
}),
);

return;
}

onCategoryChange([...categoriesValue, option]);
},
[categoriesValue, onCategoryChange],
);

const handleSurveySubmit = useCallback(
(payload: SurveyInputDto) => {
setGoalsSurvey(getSurveyCategories(payload));
},
[setGoalsSurvey],
);

const handleContinue = (): void => {
navigation.navigate(SurveyScreenName.WORRIES);
void handleSubmit(handleSurveySubmit)();
};

const handleBack = (): void => {
navigation.navigate(SurveyScreenName.FEELINGS);
};

return (
<ScrollView
style={styles.surveyContainer}
showsVerticalScrollIndicator={false}
>
<Text style={styles.titleText}>
What do you want to achive with CalmPal?
</Text>
{GOALS_CATEGORIES.map((category) => {
return (
<SurveyCategory
key={category}
onChange={handleFieldChange}
label={category}
/>
);
})}
{hasOther && (
<Input
control={control}
errors={errors}
name="other"
placeholder="Enter your preferences"
rowsCount={TEXTAREA_ROWS_COUNT}
/>
)}
<Button
label="Continue"
onPress={handleContinue}
isDisabled={!isValid}
type="outlined"
/>
<Button label="Go back" onPress={handleBack} type="solid" />
</ScrollView>
);
};
export { GoalsStep };
Loading