Skip to content

Commit

Permalink
FEAT: Add finish button and integrate with feedback screen (#180)
Browse files Browse the repository at this point in the history
  • Loading branch information
frederickbaier authored Jan 26, 2025
2 parents 5974977 + 2489a2e commit 68d91ce
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 41 deletions.
3 changes: 2 additions & 1 deletion app/src/constants/screens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ export enum Screens {
Favorite = 'Favorite',
NewPlay = 'NewPlay',
NewKid = 'NewKid',
History = 'History'
History = 'History',
Feedback = 'Feedback'
}

export enum Stacks {
Expand Down
7 changes: 7 additions & 0 deletions app/src/routes/AuthRoutes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Collections, Screens, fireAuth, fireStore } from '@src/constants';
import {
ActivityPlayer,
Favorite,
Feedback,
Home,
NewKid,
NewPlay,
Expand All @@ -30,6 +31,7 @@ export type AuthRoutesParams = {
[Screens.NewPlay]: undefined;
[Screens.NewKid]: undefined;
[Screens.History]: undefined;
[Screens.Feedback]: { activityId: string | undefined };
};

// Create a drawer navigator for authenticated routes
Expand Down Expand Up @@ -102,6 +104,11 @@ export const AuthRoutes: React.FC = () => {
component={NewKid}
options={{ headerShown: false, gestureHandlerProps: { enabled: false } }}
/>
<AuthDrawer.Screen
name={Screens.Feedback}
component={Feedback}
options={{ headerShown: false, gestureHandlerProps: { enabled: false } }}
/>
</AuthDrawer.Navigator>
);
};
75 changes: 48 additions & 27 deletions app/src/screens/ActivityPlayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ import type { AuthRoutesParams } from '@src/routes';
import type { AppNavigation } from '@src/types';
import {
IconBrain,
IconChevronCompactLeft,
IconHelp,
IconPlayerPause,
IconPlayerPlay,
IconPlayerTrackNext,
IconPlayerTrackPrev,
IconReload,
IconRepeat
IconRepeat,
IconXboxX
} from '@tabler/icons-react-native';
import { Audio } from 'expo-av';
import { httpsCallable } from 'firebase/functions';
Expand All @@ -31,6 +31,7 @@ iconWithClassName(IconPlayerPlay);
iconWithClassName(IconPlayerPause);
iconWithClassName(IconPlayerTrackNext);
iconWithClassName(IconPlayerTrackPrev);
iconWithClassName(IconXboxX);

export const ActivityPlayer: React.FC = () => {
const { navigate } = useNavigation<AppNavigation>();
Expand Down Expand Up @@ -124,6 +125,7 @@ export const ActivityPlayer: React.FC = () => {
const generateActivity = httpsCallable(fireFunction, 'ChorsGeneratorFlow');
await generateActivity({ activityId: params?.activityId });
await activity?.reload();
await sound.current.unloadAsync();
setIsPlaying(false);
setIsFinished(false);
setCurrentStep(0);
Expand All @@ -145,33 +147,22 @@ export const ActivityPlayer: React.FC = () => {
return <Loading heading='Loading activity' description='Please wait...' />;
}

const finishSession = () => {
navigate(Stacks.Auth, {
screen: Screens.Feedback,
params: { activityId: params?.activityId }
});
};

const isLastStep = currentStep === maxSteps - 1;

return (
<View className='flex flex-col flex-1 items-stretch p-6 gap-y-6'>
<View className='flex flex-row justify-between items-center gap-y-2'>
<Button
variant={'outline'}
size={'sm'}
onPress={() => navigate(Stacks.Auth, { screen: Screens.Home })}
>
<IconChevronCompactLeft className='text-base' size={16} />
</Button>
<Button variant={'outline'} size={'sm'} onPress={reloadActivity}>
<IconReload className='text-base' size={16} />
</Button>
</View>
<View className='flex flex-col flex-[3] items-center gap-y-4'>
<View className='flex flex-col items-center gap-y-2'>
<Text className='text-xl font-medium'>{activity?.data.activity.name}</Text>
<Text className='text-sm text-center'>{activity?.data.activity.description}</Text>
</View>
<View className='flex flex-row items-center gap-x-4'>
<Button variant={'secondary'} className='native:h-12 native:w-12 rounded-xl'>
<IconBrain className='text-base' size={20} />
</Button>
<Button variant={'secondary'} className='native:h-12 native:w-12 rounded-xl'>
<IconHelp className='text-base' size={20} />
</Button>
</View>
<LottieView
autoPlay={true}
loop={true}
Expand All @@ -197,7 +188,7 @@ export const ActivityPlayer: React.FC = () => {
<View className='flex flex-row items-center justify-center gap-x-12'>
<Button
variant={'secondary'}
className='native:h-20 native:w-20 rounded-xl'
className='native:h-20 native:w-24 rounded-xl'
disabled={currentStep === 0 || isReloading}
onPress={playPreviousAudio}
>
Expand Down Expand Up @@ -225,13 +216,43 @@ export const ActivityPlayer: React.FC = () => {
<IconPlayerPlay className='text-base text-primary-foreground' size={28} />
)}
</Button>
{isLastStep ? (
<Button
variant='secondary'
className='native:h-20 native:w-24 rounded-xl'
disabled={isPlaying}
onPress={finishSession}
>
<Text>Finish</Text>
</Button>
) : (
<Button
variant={'secondary'}
className='native:h-20 native:w-24 rounded-xl'
disabled={isLastStep || isReloading}
onPress={playNextAudio}
>
<IconPlayerTrackNext className='text-base' size={28} />
</Button>
)}
</View>
<View className='flex flex-row items-center justify-center gap-x-12 w-full'>
<View className='native:w-24' />
<Button
variant={'secondary'}
variant='destructive'
className='native:h-20 native:w-20 rounded-xl'
disabled={currentStep === maxSteps - 1 || isReloading}
onPress={playNextAudio}
disabled={isReloading}
onPress={() => navigate(Stacks.Auth, { screen: Screens.Home })}
>
<IconXboxX className='text-base text-primary-foreground' size={28} />
</Button>
<Button
variant='secondary'
className='native:h-20 native:w-24 rounded-xl'
disabled={isPlaying || isReloading}
onPress={reloadActivity}
>
<IconPlayerTrackNext className='text-base' size={28} />
<IconReload className='text-base' size={28} />
</Button>
</View>
</View>
Expand Down
25 changes: 16 additions & 9 deletions app/src/screens/Feedback.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,35 @@
import { useNavigation } from '@react-navigation/native';
import { type RouteProp, useNavigation, useRoute } from '@react-navigation/native';
import { Button, Text } from '@shadcn/components';
import { Brain, Home, ThumbsDown, ThumbsUp } from '@shadcn/icons';
import { Loading } from '@src/components';
import { FavouriteButton } from '@src/components/FavouriteButton';
import { Screens, Stacks } from '@src/constants';
import { Collections, fireAuth, fireStore } from '@src/constants';
import type { AuthRoutesParams } from '@src/routes';
import type { AppNavigation } from '@src/types';
import { doc, updateDoc } from 'firebase/firestore';
import LottieView from 'lottie-react-native';
import type React from 'react';
import { useEffect, useState } from 'react';
import { useAuthState } from 'react-firebase-hooks/auth';
import { TextInput, View } from 'react-native';
import { activityDocRefId } from './Onboarding';

export const Feedback: React.FC = () => {
const { navigate } = useNavigation<AppNavigation>();
const { reset } = useNavigation<AppNavigation>();
const [favourite, setFavourite] = useState<boolean>(false);
const { params } = useRoute<RouteProp<AuthRoutesParams>>();
const activityId = params?.activityId;
const [favourite, setFavorite] = useState<boolean>(false);
const [message, setMessage] = useState('');
const [feedbackSubmitted, setFeedbackSubmitted] = useState(false);
const [messageSubmitted, setMessageSubmitted] = useState(false);
const [user] = useAuthState(fireAuth);

if (!activityId) {
navigate(Stacks.Auth, { screen: Screens.Home });
return <Loading description={'Redirecting...'} />;
}

const saveInFirestore = async (data: object) => {
if (!user) {
console.error('User not authenticated');
Expand All @@ -33,7 +42,7 @@ export const Feedback: React.FC = () => {
Collections.Users,
userId,
Collections.Activities,
activityDocRefId
activityId
);
await updateDoc(activityDocRef, data);
} catch (error) {
Expand All @@ -42,16 +51,14 @@ export const Feedback: React.FC = () => {
};

const handleSubmit = async () => {
// Here you would typically send the message to your backend
console.log('Message submitted:', message);
saveInFirestore({ feedback_message: message });
saveInFirestore({ feedbackMessage: message });
setMessageSubmitted(true);
};

const handleFeedback = async (type: 'positive' | 'negative') => {
// Here you would typically send the feedback to your backend
console.log(`Feedback submitted: ${type}`);
saveInFirestore({ feedback_type: type });
saveInFirestore({ feedbackType: type });
setFeedbackSubmitted(true);
};

Expand Down Expand Up @@ -178,7 +185,7 @@ export const Feedback: React.FC = () => {
title={'Activity saved to favorites!'}
description={'You can view and replay this activity from your favorites!'}
active={favourite}
onPress={() => setFavourite(!favourite)}
onPress={() => setFavorite(!favourite)}
/>
</View>
</View>
Expand Down
8 changes: 4 additions & 4 deletions app/src/screens/NewKid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,13 @@ export const NewKid: React.FC = () => {
// Commit the batch
await batch.commit();

navigate(Stacks.Auth, {
screen: Screens.Profile
});

formikRef.current?.resetForm();
setIndex(0);
flatListRef.current?.scrollToIndex({ index: 0, animated: false });

navigate(Stacks.Auth, {
screen: Screens.Profile
});
} catch (error) {
console.error('Error saving data:', error);
}
Expand Down

0 comments on commit 68d91ce

Please sign in to comment.