Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Location step to organizer form #785

Merged
merged 28 commits into from
Jul 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
f8711cc
Add missing default value
Anahkiasen Jul 18, 2023
ccdac2e
Unify location handling in isLocationSet
Anahkiasen Jul 18, 2023
5ad0eed
Add Location step
Anahkiasen Jul 18, 2023
ed92998
Just pass all props for now
Anahkiasen Jul 18, 2023
79808ec
Add update organizer mutation
Anahkiasen Jul 18, 2023
3860543
Don't show non unique organizer URL error for same one as current
Anahkiasen Jul 18, 2023
18243da
Cleanup component a bit
Anahkiasen Jul 18, 2023
1a511d8
Do upsert on save
Anahkiasen Jul 18, 2023
ecf23d2
Make standard placeholders default
Anahkiasen Jul 18, 2023
966e785
More adaptations to LocationStep
Anahkiasen Jul 18, 2023
e454a2b
Use correct getters for location
Anahkiasen Jul 18, 2023
fabe9f7
Add location to initial form value
Anahkiasen Jul 18, 2023
d6db722
Add save button for once the org is created
Anahkiasen Jul 18, 2023
cf933bd
Add translations
Anahkiasen Jul 18, 2023
3c45735
Only pass address on updates
Anahkiasen Jul 18, 2023
b600bfb
Set validation status
Anahkiasen Jul 18, 2023
ffa9f80
Hide additional steps until after creation
Anahkiasen Jul 18, 2023
b45cd86
Only prefill location form attributes if done once
Anahkiasen Jul 18, 2023
85e64ea
Add section title translation
Anahkiasen Jul 18, 2023
2441e26
Rename OfferScore to FormScore to match broader usage
Anahkiasen Jul 18, 2023
faf1fb7
Only add 10 points for completed location
Anahkiasen Jul 18, 2023
3d078d4
Linting
Anahkiasen Jul 18, 2023
a1f207d
Update types
Anahkiasen Jul 18, 2023
4b420a9
Fix incorrect weight for description for organizers
Anahkiasen Jul 19, 2023
a993230
Update query to also get organizers
Anahkiasen Jul 19, 2023
953c9f6
Linting
Anahkiasen Jul 19, 2023
beb3004
Merge pull request #786 from cultuurnet/feature/III-5678
Anahkiasen Jul 19, 2023
2ed998f
Merge branch 'feature/III-4493' into feature/III-5677
Anahkiasen Jul 19, 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
36 changes: 36 additions & 0 deletions src/hooks/api/organizers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -251,11 +251,47 @@ const useCreateOrganizerMutation = (configuration: UseMutationOptions = {}) =>
...configuration,
});

type UpdateOrganizerArguments = CreateOrganizerArguments & {
organizerId: string;
};

const updateOrganizer = ({
headers,
url,
organizerId,
name,
address,
mainLanguage,
contact,
}: UpdateOrganizerArguments) =>
fetchFromApi({
path: `/organizers/${organizerId}`,
options: {
headers,
method: 'PUT',
body: JSON.stringify({
mainLanguage,
name,
url,
address,
contact,
}),
},
});

const useUpdateOrganizerMutation = (configuration: UseMutationOptions = {}) =>
useAuthenticatedMutation({
mutationFn: updateOrganizer,
mutationKey: 'organizers-update',
...configuration,
});

export {
useCreateOrganizerMutation,
useDeleteOrganizerByIdMutation,
useGetOrganizerByIdQuery,
useGetOrganizersByCreatorQuery,
useGetOrganizersByQueryQuery,
useGetOrganizersByWebsiteQuery,
useUpdateOrganizerMutation,
};
9 changes: 7 additions & 2 deletions src/i18n/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,9 @@
"not_found": "Diese Veranstaltung ist dem UiTPAS noch nicht bekannt."
}
},
"location": {
"title": "Standort"
},
"place": {
"add_new_label": "Ort nicht gefunden? Neuen Standort hinzufügen"
},
Expand Down Expand Up @@ -476,7 +479,8 @@
},
"title": {
"events": "Stellen Sie sicher, dass Ihr Publikum keine Informationen verpasst",
"places": "Stellen Sie sicher, dass Ihr Publikum keine Informationen verpasst"
"places": "Stellen Sie sicher, dass Ihr Publikum keine Informationen verpasst",
"organizers": "Stellen Sie sicher, dass Ihr Publikum keine Informationen verpasst"
},
"title_events": "Machen Sie dieses Ereignis zu etwas Besonderem",
"title_places": "Heben Sie diesen Standort hervor"
Expand Down Expand Up @@ -976,7 +980,8 @@
}
},
"step2": {
"description_tips": "Beschreiben Sie Ihre Organisation mit Begeisterung\nAn welche Zielgruppe richtet sich die Organisation?\nWelche Aktivitäten organisiert diese Organisation?"
"description_tips": "Beschreiben Sie Ihre Organisation mit Begeisterung\nAn welche Zielgruppe richtet sich die Organisation?\nWelche Aktivitäten organisiert diese Organisation?",
"save": "Speichern"
}
}
},
Expand Down
10 changes: 9 additions & 1 deletion src/i18n/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,9 @@
"not_found": "Cette activité n'est pas encore connue par UiTPAS."
}
},
"location": {
"title": "Lieu"
},
"place": {
"add_new_label": "Lieu introuvable ? Ajouter un nouveau lieu"
},
Expand Down Expand Up @@ -478,7 +481,8 @@
},
"title": {
"events": "Assurez-vous que votre public ne manque aucune information",
"places": "Assurez-vous que votre public ne manque aucune information"
"places": "Assurez-vous que votre public ne manque aucune information",
"organizers": "Assurez-vous que votre public ne manque aucune information"
}
},
"footer": {
Expand Down Expand Up @@ -978,6 +982,10 @@
"step2": {
"description_tips": "Décrivez avec enthousiasme votre organisation\nQuel public l'organisation cible-t-elle ?\nQuel type d'activités cette organisation organise-t-elle ?"
}
},
"step2": {
"description_tips": "Décrivez avec enthousiasme votre organisation\nQuel public l'organisation cible-t-elle ?\nQuel type d'activités cette organisation organise-t-elle ?",
"save": "Enregistrer"
}
},
"selectionTable": {
Expand Down
9 changes: 7 additions & 2 deletions src/i18n/nl.json
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,9 @@
"not_found": "Deze activiteit is nog niet gekend bij UiTPAS."
}
},
"location": {
"title": "Locatie"
},
"place": {
"add_new_label": "Locatie niet gevonden? Nieuwe locatie toevoegen"
},
Expand Down Expand Up @@ -478,7 +481,8 @@
},
"title": {
"events": "Zorg dat je publiek geen informatie mist",
"places": "Zorg dat je publiek geen informatie mist"
"places": "Zorg dat je publiek geen informatie mist",
"organizers": "Zorg dat je publiek geen informatie mist"
}
},
"footer": {
Expand Down Expand Up @@ -976,7 +980,8 @@
}
},
"step2": {
"description_tips": "Geef een enthousiaste omschrijving van je organisatie\nTot welke doelgroep richt de organisatie zich?\nWat voor activiteiten organiseert deze organisatie?"
"description_tips": "Geef een enthousiaste omschrijving van je organisatie\nTot welke doelgroep richt de organisatie zich?\nWat voor activiteiten organiseert deze organisatie?",
"save": "Bewaren"
}
}
},
Expand Down
4 changes: 2 additions & 2 deletions src/pages/create/OfferForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ const getAddress = (
};

const parseLocationAttributes = (
offer: Offer,
offer: Offer | Organizer,
language: SupportedLanguage,
mainLanguage: SupportedLanguage,
) => {
Expand All @@ -131,7 +131,7 @@ const parseLocationAttributes = (
postalCode: postalCode,
place: isEvent(offer) ? offer.location : undefined,
country: addressCountry,
...(isPlace(offer) && { streetAndNumber: streetAddress }),
...(!isEvent(offer) && { streetAndNumber: streetAddress }),
...(isEvent(offer) &&
!!offer.onlineUrl && { onlineUrl: offer.onlineUrl }),
},
Expand Down
76 changes: 60 additions & 16 deletions src/pages/organizers/create/OrganizerForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,16 @@ import { URL_REGEX } from '@/constants/Regex';
import {
useCreateOrganizerMutation,
useGetOrganizerByIdQuery,
useUpdateOrganizerMutation,
} from '@/hooks/api/organizers';
import { SupportedLanguage, SupportedLanguages } from '@/i18n/index';
import { parseLocationAttributes } from '@/pages/create/OfferForm';
import {
additionalInformationStepConfiguration,
AdditionalInformationStepVariant,
} from '@/pages/steps/AdditionalInformationStep';
import { useParseStepConfiguration } from '@/pages/steps/hooks/useParseStepConfiguration';
import { locationStepConfiguration } from '@/pages/steps/LocationStep';
import { Steps, StepsConfiguration } from '@/pages/steps/Steps';
import { Organizer } from '@/types/Organizer';
import { Button, ButtonVariants } from '@/ui/Button';
Expand Down Expand Up @@ -42,8 +45,11 @@ const configurations = [
typeAndThemeStepConfiguration,
{
...additionalInformationStepConfiguration,
shouldShowStep: () => true,
shouldShowStep: (form) =>
form.getValues('nameAndUrl.name') && form.getValues('nameAndUrl.url'),
variant: AdditionalInformationStepVariant.ORGANIZER,
name: 'location' as StepsConfiguration['name'],
defaultValue: locationStepConfiguration.defaultValue,
},
];

Expand All @@ -55,12 +61,20 @@ const OrganizerForm = (props) => {

const { handleSubmit, formState, getValues, reset } = form;

const organizerId = useMemo(
const urlOrganizerId = useMemo(
() => query.organizerId as string,
[query.organizerId],
);

const convertOrganizerToFormData = (organizer: Organizer) => {
const locationAttributes = !organizer?.address
? {}
: parseLocationAttributes(
organizer,
i18n.language as SupportedLanguage,
organizer.mainLanguage as SupportedLanguage,
);

return {
nameAndUrl: {
name: getLanguageObjectOrFallback(
Expand All @@ -69,14 +83,15 @@ const OrganizerForm = (props) => {
) as string,
url: organizer.url,
},
...locationAttributes,
};
};

// const toast = useToast(toastConfiguration);

// TODO better type query
const getOrganizerByIdQuery = useGetOrganizerByIdQuery(
{ id: organizerId },
{ id: urlOrganizerId },
{
onSuccess: (organizer: Organizer) => {
reset(convertOrganizerToFormData(organizer), {
Expand All @@ -90,21 +105,41 @@ const OrganizerForm = (props) => {
const organizer = getOrganizerByIdQuery?.data;

const createOrganizerMutation = useCreateOrganizerMutation();
const updateOrganizerMutation = useUpdateOrganizerMutation();

const createOrganizer = async ({ onSuccess }) => {
const { organizerId } = await createOrganizerMutation.mutateAsync({
const upsertOrganizer = async ({ onSuccess }) => {
let mutation = createOrganizerMutation;
let attributes: { [key: string]: any } = {
name: getValues('nameAndUrl.name'),
url: getValues('nameAndUrl.url'),
mainLanguage: i18n.language,
});
};

if (urlOrganizerId) {
mutation = updateOrganizerMutation;
attributes = {
...attributes,
organizerId: urlOrganizerId,
address: {
[i18n.language]: {
addressCountry: getValues('location.country'),
addressLocality: getValues('location.municipality.name'),
postalCode: getValues('location.municipality.zip'),
streetAddress: getValues('location.streetAndNumber'),
},
},
};
}

const { organizerId } = await mutation.mutateAsync(attributes);

onSuccess(organizerId);
};

const hasErrors = Object.keys(formState.errors).length > 0;

const onSuccess = () => {
createOrganizer({
upsertOrganizer({
onSuccess: async (organizerId) =>
await push(`/organizers/${organizerId}/edit`),
});
Expand All @@ -118,21 +153,30 @@ const OrganizerForm = (props) => {
<Page.Content spacing={5} alignItems="flex-start">
<Steps
scope={scope}
offerId={organizerId}
offerId={urlOrganizerId}
mainLanguage={SupportedLanguages.NL}
configurations={configurations}
onChangeSuccess={() => ({})}
form={form}
/>
</Page.Content>
<Page.Footer>
<Button
disabled={hasErrors || !formState.isDirty}
variant={ButtonVariants.PRIMARY}
onClick={handleSubmit(onSuccess)}
>
{t('organizers.create.step1.save')}
</Button>
{urlOrganizerId ? (
<Button
disabled={hasErrors}
variant={ButtonVariants.PRIMARY}
onClick={handleSubmit(onSuccess)}
>
{t('organizers.create.step2.save')}
</Button>
) : (
<Button
disabled={hasErrors || !formState.isDirty}
variant={ButtonVariants.PRIMARY}
onClick={handleSubmit(onSuccess)}
>
{t('organizers.create.step1.save')}
</Button>
)}
</Page.Footer>
</Page>
);
Expand Down
10 changes: 7 additions & 3 deletions src/pages/organizers/create/steps/UrlStep.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useRouter } from 'next/router';
import { FormEvent, useEffect, useMemo } from 'react';
import { Controller, useWatch } from 'react-hook-form';
import { Trans, useTranslation } from 'react-i18next';
Expand All @@ -11,6 +12,7 @@ import { FormElement } from '@/ui/FormElement';
import { Input } from '@/ui/Input';
import { getStackProps, Stack, StackProps } from '@/ui/Stack';
import { getLanguageObjectOrFallback } from '@/utils/getLanguageObjectOrFallback';
import { parseOfferId } from '@/utils/parseOfferId';
import { prefixUrlWithHttps } from '@/utils/url';

type UrlStepProps = StackProps & StepProps;
Expand All @@ -26,6 +28,7 @@ const UrlStep = ({
name,
...props
}: UrlStepProps) => {
const { query } = useRouter();
const { t, i18n } = useTranslation();

const [watchedUrl] = useWatch({
Expand All @@ -46,10 +49,11 @@ const UrlStep = ({

const isUrlAlreadyTaken = errors.nameAndUrl?.url?.type === 'not_unique';

console.log({ existingOrganizer });

useEffect(() => {
if (existingOrganizer) {
if (
existingOrganizer &&
parseOfferId(existingOrganizer['@id']) !== query.organizerId
) {
console.log('should set error');
setError('nameAndUrl.url', { type: 'not_unique' });
return;
Expand Down
Loading
Loading