From f93968c3eb8fa167c8da87bd915a85f863739e00 Mon Sep 17 00:00:00 2001 From: Arthur Jamet Date: Thu, 4 Jan 2024 11:33:11 +0100 Subject: [PATCH] Front: Add Username for Guest Mode --- front/API.ts | 4 +- front/components/UI/LogoutButtonCC.tsx | 4 +- front/components/UI/ScaffoldAuth.tsx | 58 ++++++++++++++++-------- front/components/forms/guestForm.tsx | 63 ++++++++++++++++++++++++++ front/components/forms/signupform.tsx | 5 +- front/i18n/Translations.ts | 3 ++ 6 files changed, 114 insertions(+), 23 deletions(-) create mode 100644 front/components/forms/guestForm.tsx diff --git a/front/API.ts b/front/API.ts index af7597c..e15b423 100644 --- a/front/API.ts +++ b/front/API.ts @@ -187,12 +187,12 @@ export default class API { }); } - public static async createAndGetGuestAccount(): Promise { + public static async createAndGetGuestAccount(username: string): Promise { return API.fetch( { route: '/auth/guest', method: 'POST', - body: undefined, + body: { username }, }, { handler: AccessTokenResponseHandler } ) diff --git a/front/components/UI/LogoutButtonCC.tsx b/front/components/UI/LogoutButtonCC.tsx index bb54105..c81ae21 100644 --- a/front/components/UI/LogoutButtonCC.tsx +++ b/front/components/UI/LogoutButtonCC.tsx @@ -9,6 +9,7 @@ import SignUpForm from '../../components/forms/signupform'; import API, { APIError } from '../../API'; import PopupCC from './PopupCC'; import { StyleProp, ViewStyle } from 'react-native'; +import { useQuery } from '../../Queries'; const handleSubmit = async (username: string, password: string, email: string) => { try { @@ -36,6 +37,7 @@ const LogoutButtonCC = ({ }: LogoutButtonCCProps) => { const dispatch = useDispatch(); const [isVisible, setIsVisible] = useState(false); + const user = useQuery(API.getUserInfo); return ( <> @@ -54,7 +56,7 @@ const LogoutButtonCC = ({ isVisible={isVisible} setIsVisible={setIsVisible} > - + void): Promise => { - const apiAccess = await API.createAndGetGuestAccount(); +const handleGuestLogin = async ( + username: string, + apiSetter: (accessToken: string) => void +): Promise => { + const apiAccess = await API.createAndGetGuestAccount(username); apiSetter(apiAccess); return translate('loggedIn'); }; @@ -38,6 +43,7 @@ const ScaffoldAuth: FunctionComponent = ({ const dispatch = useDispatch(); const toast = useToast(); const colorScheme = useColorScheme(); + const [guestModalIsOpen, openGuestModal] = useState(false); const [logo] = useAssets( colorScheme == 'light' ? require('../../assets/icon_light.png') @@ -85,21 +91,35 @@ const ScaffoldAuth: FunctionComponent = ({ { - try { - handleGuestLogin((accessToken: string) => { - dispatch(setAccessToken(accessToken)); - }); - } catch (error) { - if (error instanceof APIError) { - toast.show({ description: translate(error.userMessage) }); - return; - } - toast.show({ description: error as string }); - } - }} + onPress={() => openGuestModal(true)} /> + + { + return handleGuestLogin(username, (accessToken: string) => { + dispatch(setAccessToken(accessToken)); + }) + .catch((error) => { + if (error instanceof APIError) { + toast.show({ + description: translate(error.userMessage), + }); + return; + } + toast.show({ description: error as string }); + }) + .then(() => { + openGuestModal(false); + return translate('loggedIn'); + }); + }} + /> + = ({ title={translate('continuewithgoogle')} onPress={() => Linking.openURL(`${API.baseUrl}/auth/login/google`)} /> - or + + + Promise; +} + +const validationSchemas = { + username: string().required('Username is required'), +}; + +const GuestForm = ({ onSubmit }: GuestFormProps) => { + const [formData, setFormData] = React.useState({ + username: { + value: '', + error: null as string | null, + }, + }); + + const toast = useToast(); + const layout = useWindowDimensions(); + + return ( + + { + let error: null | string = null; + validationSchemas.username + .validate(t) + .catch((e) => (error = e.message)) + .finally(() => { + setFormData({ ...formData, username: { value: t, error } }); + }); + }} + /> + { + onSubmit(formData.username.value).catch((e) => { + toast.show({ description: e as string }); + }); + }} + /> + + ); +}; + +export default GuestForm; diff --git a/front/components/forms/signupform.tsx b/front/components/forms/signupform.tsx index 0e1e429..c32d205 100644 --- a/front/components/forms/signupform.tsx +++ b/front/components/forms/signupform.tsx @@ -10,13 +10,14 @@ import ButtonBase from '../UI/ButtonBase'; import Spacer from '../UI/Spacer'; interface SignupFormProps { + defaultValues: Partial<{ username: string }>; onSubmit: (username: string, password: string, email: string) => Promise; } -const SignUpForm = ({ onSubmit }: SignupFormProps) => { +const SignUpForm = ({ onSubmit, defaultValues }: SignupFormProps) => { const [formData, setFormData] = React.useState({ username: { - value: '', + value: defaultValues.username || '', error: null as string | null, }, password: { diff --git a/front/i18n/Translations.ts b/front/i18n/Translations.ts index 44f751c..f6c1fbe 100644 --- a/front/i18n/Translations.ts +++ b/front/i18n/Translations.ts @@ -1,5 +1,6 @@ export const en = { error: 'Error', + or: 'or', guestMode: 'Guest Mode', downloadAPK: 'Download Android App', goBackHome: 'Go Back Home', @@ -323,6 +324,7 @@ export const en = { export const fr: typeof en = { error: 'Erreur', + or: 'ou', downloadAPK: "Télécharger l'App Android", guestMode: 'Mode Invité', goBackHome: "Retourner à l'accueil", @@ -646,6 +648,7 @@ export const fr: typeof en = { export const sp: typeof en = { error: 'Error', + or: 'u', downloadAPK: 'Descarga la Aplicación de Android', guestMode: 'Modo Invitado', anErrorOccured: 'ocurrió un error',