Skip to content

Commit

Permalink
Merge pull request #13 from City-of-Turku/feature/logout-functionality
Browse files Browse the repository at this point in the history
Feature/logout functionality
  • Loading branch information
juhomakkonen authored Apr 12, 2024
2 parents cd6f855 + 5e58eb7 commit 1e45c8a
Show file tree
Hide file tree
Showing 12 changed files with 78 additions and 55 deletions.
2 changes: 0 additions & 2 deletions src/components/Buttons/HomeButton/HomeButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { useIntl } from 'react-intl';
import { Link } from 'react-router-dom';
import { useAppDispatch, useAppSelector } from '../../../hooks/reduxHooks';
import userSlice from '../../../redux/slices/userSlice';
import { logoutUser } from '../../../utils/mobilityProfileAPI';

const HomeButton = () => {
const intl = useIntl();
Expand All @@ -17,7 +16,6 @@ const HomeButton = () => {

const endPoll = () => {
if (token?.length) {
logoutUser(token);
setIsLoggedIn(false);
}
return;
Expand Down
20 changes: 18 additions & 2 deletions src/components/Content/Content.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,28 @@
import React from 'react';
import { useAppSelector } from '../../hooks/reduxHooks';
import HomeButton from '../Buttons/HomeButton/HomeButton';
import ErrorComponent from '../Errors/ErrorComponent/ErrorComponent';
import Loading from '../Loading/Loading';
import QuestionForm from '../QuestionForm/QuestionForm';

const Content = () => {
const { isLoggedIn } = useAppSelector((state) => state.user);
const { isLoggedIn, isError } = useAppSelector((state) => state.user);

return <div className="content-inner">{isLoggedIn ? <QuestionForm /> : <Loading />}</div>;
const renderSecondaryContent = () => {
if (isError) {
return (
<ErrorComponent translationId="app.result.error">
<HomeButton />
</ErrorComponent>
);
} else {
return <Loading />;
}
};

return (
<div className="content-inner">{isLoggedIn ? <QuestionForm /> : renderSecondaryContent()}</div>
);
};

export default Content;
14 changes: 8 additions & 6 deletions src/components/Forms/EmailForm/EmailForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { useIntl } from 'react-intl';
import { useAppSelector } from '../../../hooks/reduxHooks';
import { EmailField } from '../../../types';
import { postSubscribeInfo } from '../../../utils/mobilityProfileAPI';
import ErrorText from '../../Typography/ErrorText/ErrorText';
import TextBasic from '../../Typography/TextBasic/TextBasic';

const EmailForm = () => {
Expand All @@ -15,9 +14,7 @@ const EmailForm = () => {
const intl = useIntl();

const { user } = useAppSelector((state) => state);
const resultId = user?.profileResult?.id;
const userId = user?.userId;
const token = user?.csrfToken;

const registerLink = 'https://rekisteri.turku.fi/Saabe_data';

Expand All @@ -33,7 +30,7 @@ const EmailForm = () => {

const onSubmit: SubmitHandler<EmailField> = (data) => {
if (userId?.length) {
postSubscribeInfo(data.email, resultId, setHasUserAnswered, setIsApiError, token);
postSubscribeInfo(data.email, userId, setHasUserAnswered, setIsApiError);
}
};

Expand Down Expand Up @@ -83,9 +80,14 @@ const EmailForm = () => {
<Button type="submit" role="button" disabled={hasUserAnswered} className="input-submit">
{intl.formatMessage({ id: 'app.input.submit.newsletter' })}
</Button>
{hasUserAnswered ? <TextBasic translationId="app.result.newsletter.success" /> : null}
{hasUserAnswered ? (
<TextBasic
translationId={
isApiError ? 'app.result.newsletter.error' : 'app.result.newsletter.success'
}
/>
) : null}
</div>
{isApiError ? <ErrorText /> : null}
</form>
</div>
</div>
Expand Down
31 changes: 7 additions & 24 deletions src/components/Forms/UserForm/UserForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@ const UserForm = ({ answerStatus, setAnswerStatus }: UserFormProps) => {
register,
handleSubmit,
formState: { errors },
watch,
} = useForm({
defaultValues: {
gender: null,
Expand All @@ -122,21 +121,17 @@ const UserForm = ({ answerStatus, setAnswerStatus }: UserFormProps) => {
optional_postal_code: null,
optional_postal_code_other: null,
is_interested_in_mobility: false,
is_filled_for_fun: false,
result_can_be_used: false,
},
});

const isInterestedInMobility = watch('is_interested_in_mobility');
const isForFun = watch('is_filled_for_fun');

/**
* Set disabled status of either select or text input so that user can't fill both at the same time.
* Select element is for those that live in Turku and text input is for those who don't.
* @param event
* @param setState
*/
const handlePostalCodes = (
const handlePostalCodeStates = (
event: { target: { value: string } },
setState: (a: boolean) => void,
) => {
Expand Down Expand Up @@ -247,7 +242,7 @@ const UserForm = ({ answerStatus, setAnswerStatus }: UserFormProps) => {
<select
{...register('postal_code', { required: false })}
role="listbox"
onChange={(event) => handlePostalCodes(event, setIsPostalCode)}
onChange={(event) => handlePostalCodeStates(event, setIsPostalCode)}
disabled={isPostalCodeOther}
aria-required="false"
aria-invalid={errors.postal_code ? true : false}
Expand Down Expand Up @@ -277,7 +272,7 @@ const UserForm = ({ answerStatus, setAnswerStatus }: UserFormProps) => {
{...register('postal_code_other', { required: false, maxLength: 10 })}
type="text"
maxLength={10}
onChange={(event) => handlePostalCodes(event, setIsPostalCodeOther)}
onChange={(event) => handlePostalCodeStates(event, setIsPostalCodeOther)}
disabled={isPostalCode}
aria-required="false"
aria-invalid={errors.postal_code_other ? true : false}
Expand Down Expand Up @@ -308,7 +303,7 @@ const UserForm = ({ answerStatus, setAnswerStatus }: UserFormProps) => {
required: false,
})}
role="listbox"
onChange={(event) => handlePostalCodes(event, setIsOptionalPostalCode)}
onChange={(event) => handlePostalCodeStates(event, setIsOptionalPostalCode)}
disabled={isOptionalPostalCodeOther}
aria-required="false"
aria-invalid={errors.optional_postal_code ? true : false}
Expand Down Expand Up @@ -338,7 +333,9 @@ const UserForm = ({ answerStatus, setAnswerStatus }: UserFormProps) => {
{...register('optional_postal_code_other', { required: false, maxLength: 10 })}
type="text"
maxLength={10}
onChange={(event) => handlePostalCodes(event, setIsOptionalPostalCodeOther)}
onChange={(event) =>
handlePostalCodeStates(event, setIsOptionalPostalCodeOther)
}
disabled={isOptionalPostalCode}
aria-required="false"
aria-invalid={errors.optional_postal_code_other ? true : false}
Expand Down Expand Up @@ -367,26 +364,12 @@ const UserForm = ({ answerStatus, setAnswerStatus }: UserFormProps) => {
{...register('is_interested_in_mobility', { required: false })}
aria-required="false"
aria-invalid={errors.is_interested_in_mobility ? true : false}
disabled={isForFun}
className="form-check-input"
/>
<label htmlFor="is_filled_for_fun" className="text-label">
{intl.formatMessage({ id: 'app.form.interestedInMobility.label' })}
</label>
</div>
<div className="mb-3 form-check container-sm center-text">
<input
type="checkbox"
{...register('is_filled_for_fun', { required: false })}
aria-required="false"
aria-invalid={errors.is_filled_for_fun ? true : false}
disabled={isInterestedInMobility}
className="form-check-input"
/>
<label htmlFor="is_filled_for_fun" className="text-label">
{intl.formatMessage({ id: 'app.form.filledForFun.label' })}
</label>
</div>
<div className="mb-3 form-check container-sm center-text">
<input
type="checkbox"
Expand Down
12 changes: 6 additions & 6 deletions src/components/Pages/HomePage/HomePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { sortQuestionsData } from '../../../utils/utils';

const HomePage = () => {
const dispatch = useAppDispatch();
const { setUserId, setCsrfToken, setIsLoggedIn } = bindActionCreators(
const { setUserId, setCsrfToken, setIsLoggedIn, setIsError } = bindActionCreators(
userSlice.actions,
dispatch,
);
Expand Down Expand Up @@ -69,13 +69,13 @@ const HomePage = () => {
};

const handleClick = async () => {
const userValues = await startPoll(setIsLoggedIn);
const dataStr = userValues?.data[0];
const iv = userValues?.data[1];
const userValues = await startPoll(setIsLoggedIn, setIsError);
const dataStr = userValues?.data?.[0];
const iv = userValues?.data?.[1];
const secretParse = window.atob(secret);
const key = CryptoJS.enc.Utf8.parse(secretParse);
const ivParsed = CryptoJS.enc.Base64.parse(iv);
const decrypted = decryptString(dataStr, key, ivParsed);
const ivParsed = iv ? CryptoJS.enc.Base64.parse(iv) : null;
const decrypted = ivParsed ? decryptString(dataStr, key, ivParsed) : '';
setUserId(userValues?.id);
setCsrfToken(decrypted);
};
Expand Down
8 changes: 8 additions & 0 deletions src/components/Pages/ResultPage/ResultPage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useEffect, useState } from 'react';
import { useIntl } from 'react-intl';
import { useAppSelector } from '../../../hooks/reduxHooks';
import { logoutUser } from '../../../utils/mobilityProfileAPI';
import useLocaleText from '../../../utils/useLocaleText';
import { renderLocaleValue } from '../../../utils/utils';
import HomeButton from '../../Buttons/HomeButton/HomeButton';
Expand All @@ -17,13 +18,20 @@ const ResultPage = () => {
const { user } = useAppSelector((state) => state);

const userResult = user.profileResult;
const token = user.csrfToken;

useEffect(() => {
if (!userResult || !userResult?.topic.length) {
setResultError(true);
}
}, [userResult]);

useEffect(() => {
if (token?.length) {
logoutUser(token);
}
}, [token]);

return (
<section className="container flex-center">
<div className="text-container">
Expand Down
1 change: 1 addition & 0 deletions src/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"app.postalcodes.error": "Postal codes couldn't be retrieved.",
"app.result.success": "Thank you for your answer.",
"app.result.newsletter.success": "You have subscribed to our newsletter.",
"app.result.newsletter.error": "An error occurred while sending the email address.",
"app.transport.car": "car",
"app.transport.motorbike": "moped or scooter",
"app.transport.bicycle": "bicycle or e-bicycle",
Expand Down
1 change: 1 addition & 0 deletions src/i18n/fi.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"app.postalcodes.error": "Postinumeroita ei voitu hakea.",
"app.result.success": "Kiitos vastauksestasi.",
"app.result.newsletter.success": "Olet tilannut uutiskirjeen.",
"app.result.newsletter.error": "Sähköpostin lähetyksessä tapahtui virhe.",
"app.transport.car": "auto",
"app.transport.motorbike": "mopo tai skootteri",
"app.transport.bicycle": "polkupyörä tai sähköpyörä",
Expand Down
1 change: 1 addition & 0 deletions src/i18n/sv.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"app.postalcodes.error": "Postnummer kunde inte hämtas.",
"app.result.success": "Tack för ditt svar.",
"app.result.newsletter.success": "Du har prenumererat på nyhetsbrevet.",
"app.result.newsletter.error": "Ett fel uppstod när e-postadressen skickades.",
"app.transport.car": "bil",
"app.transport.motorbike": "moped eller skoter",
"app.transport.bicycle": "cykel eller e-cykel",
Expand Down
5 changes: 5 additions & 0 deletions src/redux/slices/userSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export const initialState: User = {
description_en: '',
description_sv: '',
},
isError: false,
};

export const userSlice = createSlice({
Expand Down Expand Up @@ -58,6 +59,9 @@ export const userSlice = createSlice({
description_sv: '',
};
},
setIsError: (state, action: PayloadAction<boolean>) => {
state.isError = action.payload;
},
},
});

Expand All @@ -69,6 +73,7 @@ export const {
resetUserId,
resetCsrfToken,
resetProfileResult,
setIsError,
} = userSlice.actions;

export default userSlice;
2 changes: 1 addition & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ interface User {
csrfToken: string;
isLoggedIn: boolean;
profileResult: Result;
isError: boolean;
}

interface LocaleTextObject {
Expand Down Expand Up @@ -107,7 +108,6 @@ interface UserFormTypes {
postal_code_other?: string | null;
optional_postal_code?: string | null;
optional_postal_code_other?: string | null;
is_filled_for_fun: boolean;
result_can_be_used: boolean;
}

Expand Down
Loading

0 comments on commit 1e45c8a

Please sign in to comment.