diff --git a/frontend/src/components/TermsAndConditions.tsx b/frontend/src/components/TermsAndConditions.tsx new file mode 100644 index 000000000..b9c25dc47 --- /dev/null +++ b/frontend/src/components/TermsAndConditions.tsx @@ -0,0 +1,27 @@ +import { FunctionComponent } from 'react' +import CloseIcon from './alert/CloseIcon' + +interface Props { + close: () => void +} + +const TermsAndConditions: FunctionComponent = ({ close }) => { + return ( +
+
+ { + close() + }} + /> +
+
+

Terms & Conditions

+ Placeholder text for terms and conitions +
+
+ ) +} + +export default TermsAndConditions diff --git a/frontend/src/hooks/useUser.tsx b/frontend/src/hooks/useUser.tsx new file mode 100644 index 000000000..e5e61a4f1 --- /dev/null +++ b/frontend/src/hooks/useUser.tsx @@ -0,0 +1,23 @@ +import { headers, SERVER_URL, throwOnProblem } from './useAuth' + +const updateTermsAndConditions = ({ + id, + termsAndConditionsAcceptedAt, +}: { + id: number + termsAndConditionsAcceptedAt: Date +}) => + fetch(`${SERVER_URL}/user/termsandcond/${id}`, { + credentials: 'include', + method: 'PATCH', + headers: { + ...headers, + }, + body: JSON.stringify(termsAndConditionsAcceptedAt), + }).then(throwOnProblem(`Updating terms and conditions failed!`)) + +export const useUser = () => { + return { + updateTermsAndConditions, + } +} diff --git a/frontend/src/pages/groups/GroupCreatePage.tsx b/frontend/src/pages/groups/GroupCreatePage.tsx index f3263bdf2..7d116a5c5 100644 --- a/frontend/src/pages/groups/GroupCreatePage.tsx +++ b/frontend/src/pages/groups/GroupCreatePage.tsx @@ -1,6 +1,7 @@ import { FunctionComponent } from 'react' import { useNavigate } from 'react-router-dom' import { useAuth } from '../../hooks/useAuth' +import { useUser } from '../../hooks/useUser' import LayoutWithNav from '../../layouts/LayoutWithNav' import { AllGroupsDocument, @@ -12,8 +13,9 @@ import { setEmptyFieldsToUndefined } from '../../utils/setEmptyFieldsToUndefined import GroupForm from './GroupForm' const GroupCreatePage: FunctionComponent = () => { - const { refreshMe } = useAuth() + const { refreshMe, me: profile } = useAuth() const navigate = useNavigate() + const user = useUser() const [addGroup, { loading: mutationIsLoading, error: mutationError }] = useCreateGroupMutation() @@ -30,6 +32,14 @@ const GroupCreatePage: FunctionComponent = () => { refetchQueries: [{ query: AllGroupsDocument }], }) + // updated user with termsAndConditionsAcceptedAt time + if (profile != undefined) { + user.updateTermsAndConditions({ + id: profile.id, + termsAndConditionsAcceptedAt: input.termsAndConditionsAcceptedAt, + }) + } + // Because we cache the association between a group captain and their // group, we need to refresh that association when they create their first // group. @@ -65,6 +75,7 @@ const GroupCreatePage: FunctionComponent = () => { onSubmit={onSubmit} isLoading={mutationIsLoading} submitButtonLabel="Create group" + renderTermsAndConditions={true} /> diff --git a/frontend/src/pages/groups/GroupEditPage.tsx b/frontend/src/pages/groups/GroupEditPage.tsx index 38682697f..727bf5d8f 100644 --- a/frontend/src/pages/groups/GroupEditPage.tsx +++ b/frontend/src/pages/groups/GroupEditPage.tsx @@ -75,6 +75,7 @@ const GroupEditPage: FunctionComponent = () => { submitButtonLabel="Save changes" onSubmit={onSubmit} defaultValues={originalGroupData} + renderTermsAndConditions={false} /> diff --git a/frontend/src/pages/groups/GroupForm.tsx b/frontend/src/pages/groups/GroupForm.tsx index c1936c976..6404fa61c 100644 --- a/frontend/src/pages/groups/GroupForm.tsx +++ b/frontend/src/pages/groups/GroupForm.tsx @@ -3,12 +3,14 @@ import { PropsWithChildren, ReactNode, useEffect, + useState, } from 'react' import { useForm } from 'react-hook-form' import Button from '../../components/Button' import SelectField from '../../components/forms/SelectField' import TextArea from '../../components/forms/TextArea' import TextField from '../../components/forms/TextField' +import TermsAndConditions from '../../components/TermsAndConditions' import { GROUP_TYPE_OPTIONS } from '../../data/constants' import { useAuth } from '../../hooks/useAuth' import { useCountries } from '../../hooks/useCountries' @@ -16,6 +18,7 @@ import { useRegions } from '../../hooks/useRegions' import { GroupCreateInput, GroupQuery, GroupType } from '../../types/api-types' import { formatRegion } from '../../utils/format' import { stripIdAndTypename } from '../../utils/types' +import TermsAndCondCheckbox from './TermsAndCondCheckbox' interface Props { /** @@ -35,6 +38,11 @@ interface Props { * The callback triggered when the user submits the form */ onSubmit: (input: GroupCreateInput) => void + /** + * If true, checkbox for terms and conditions will be displayed + * We don't want to display checkbox terms and conditions on update page + */ + renderTermsAndConditions: boolean } /** @@ -44,6 +52,10 @@ const GroupForm: FunctionComponent> = (props) => { const { me: profile } = useAuth() const countries = useCountries() const regions = useRegions() + const [showTermsAndCond, setShowTermsAndCond] = useState(false) + const [timeTcChecked, setTimeTcChecked] = useState(null) + + console.log(profile) const { register, @@ -73,6 +85,10 @@ const GroupForm: FunctionComponent> = (props) => { input.groupType = GroupType.Regular } + if (timeTcChecked !== null) { + //input.termsAndConditionsAcceptedAt = timeTcChecked + } + props.onSubmit({ ...input, // FIXME: for some reasons, servingRegions will be `false` in no item is selected @@ -81,8 +97,32 @@ const GroupForm: FunctionComponent> = (props) => { }) }) + function handleTcChange() { + if (timeTcChecked === null) { + setTimeTcChecked(new Date()) + } else { + setTimeTcChecked(null) + } + } + + let termsAndConditions + if (props.renderTermsAndConditions) { + termsAndConditions = ( + + ) + } else { + termsAndConditions = null + } + return (
+ {showTermsAndCond ? ( + setShowTermsAndCond(false)} /> + ) : null}
> = (props) => { register={register} errors={errors} /> + {termsAndConditions}
@@ -199,7 +240,10 @@ const GroupForm: FunctionComponent> = (props) => { variant="primary" type="submit" className="mt-6" - disabled={props.isLoading} + disabled={ + props.isLoading || + (timeTcChecked === null && props.renderTermsAndConditions) + } > {props.submitButtonLabel} diff --git a/frontend/src/pages/groups/TermsAndCondCheckbox.tsx b/frontend/src/pages/groups/TermsAndCondCheckbox.tsx new file mode 100644 index 000000000..b79c9f778 --- /dev/null +++ b/frontend/src/pages/groups/TermsAndCondCheckbox.tsx @@ -0,0 +1,33 @@ +import { FunctionComponent } from 'react' +import CheckboxField from '../../components/forms/CheckboxField' + +interface Props { + timeTcChecked: Date | null + handleTcChange: () => void + setShowTermsAndCond: (tc: boolean) => void +} + +const TermsAndCondCheckbox: FunctionComponent = ({ + timeTcChecked, + handleTcChange, + setShowTermsAndCond, +}) => { + return ( + + ) +} + +export default TermsAndCondCheckbox