From 558f6d48c82e26b0cab9307bfc90705570101e3a Mon Sep 17 00:00:00 2001 From: emilielr <43408175+emilielr@users.noreply.github.com> Date: Tue, 17 Dec 2024 12:18:12 +0100 Subject: [PATCH] feat(settings): show error alert to user if firebase fail in edit and organization (#1760) * feat(error): show alert box instead of toast * feat(edit): show error to user if firebase fail * feat(organization): add alert on firebase error * chore(): rename variables * chore(): remove unused function * chore(): remove unneccessary if * chore(): refactor moveboard function --- .../edit/[id]/components/Footer/actions.ts | 7 +- .../edit/[id]/components/Footer/index.tsx | 29 +++-- .../[id]/components/MetaSettings/Adress.tsx | 24 +++- .../components/MetaSettings/FontSelect.tsx | 48 ++++++++ .../components/MetaSettings/Organization.tsx | 84 +++++++++++++ .../[id]/components/MetaSettings/Title.tsx | 55 +++++++++ .../[id]/components/MetaSettings/actions.ts | 29 +++-- .../[id]/components/MetaSettings/index.tsx | 116 +----------------- .../[id]/components/ThemeSelect/index.tsx | 7 +- .../components/CountiesSelect/index.tsx | 28 ++++- .../components/DefaultColumns/index.tsx | 19 +-- .../components/FontSelect/index.tsx | 29 ++++- .../organizations/components/Footer/index.tsx | 43 +++++-- tavla/app/(admin)/utils/index.ts | 18 --- 14 files changed, 354 insertions(+), 182 deletions(-) create mode 100644 tavla/app/(admin)/edit/[id]/components/MetaSettings/FontSelect.tsx create mode 100644 tavla/app/(admin)/edit/[id]/components/MetaSettings/Organization.tsx create mode 100644 tavla/app/(admin)/edit/[id]/components/MetaSettings/Title.tsx diff --git a/tavla/app/(admin)/edit/[id]/components/Footer/actions.ts b/tavla/app/(admin)/edit/[id]/components/Footer/actions.ts index 29b74ddf3..d958832da 100644 --- a/tavla/app/(admin)/edit/[id]/components/Footer/actions.ts +++ b/tavla/app/(admin)/edit/[id]/components/Footer/actions.ts @@ -1,5 +1,6 @@ 'use server' import { isEmptyOrSpaces } from 'app/(admin)/edit/utils' +import { TFormFeedback } from 'app/(admin)/utils' import { hasBoardEditorAccess, initializeAdminApp, @@ -13,7 +14,11 @@ import * as Sentry from '@sentry/nextjs' initializeAdminApp() -export async function setFooter(bid: TBoardID, data: FormData) { +export async function setFooter( + state: TFormFeedback | undefined, + bid: TBoardID, + data: FormData, +) { const access = hasBoardEditorAccess(bid) if (!access) return redirect('/') diff --git a/tavla/app/(admin)/edit/[id]/components/Footer/index.tsx b/tavla/app/(admin)/edit/[id]/components/Footer/index.tsx index 9f54d54f1..6e0fbb6a8 100644 --- a/tavla/app/(admin)/edit/[id]/components/Footer/index.tsx +++ b/tavla/app/(admin)/edit/[id]/components/Footer/index.tsx @@ -6,10 +6,11 @@ import { Heading3 } from '@entur/typography' import { SubmitButton } from 'components/Form/SubmitButton' import { TBoardID, TFooter } from 'types/settings' import { setFooter as setFooterAction } from './actions' -import { useState } from 'react' +import { useActionState, useState } from 'react' import { Tooltip } from '@entur/tooltip' import ClientOnlyTextField from 'app/components/NoSSR/TextField' -import { fireToastFeedback } from 'app/(admin)/utils' +import { getFormFeedbackForField, TFormFeedback } from 'app/(admin)/utils' +import { FormError } from 'app/(admin)/components/FormError' function Footer({ bid, @@ -23,13 +24,22 @@ function Footer({ const { addToast } = useToast() const [override, setOverride] = useState(footer?.override ?? false) - const setFooter = async (data: FormData) => { - const result = await setFooterAction(bid, data) - fireToastFeedback(addToast, result, 'Infomelding lagret!') + const setFooter = async ( + state: TFormFeedback | undefined, + data: FormData, + ) => { + const formFeedback = await setFooterAction(state, bid, data) + + if (!formFeedback) { + addToast('Infomelding lagret!') + } + return formFeedback } + const [footerState, footerFormAction] = useActionState(setFooter, undefined) + return ( -
+
Infomelding @@ -58,11 +68,16 @@ function Footer({ Vis infomelding fra organisasjonen. )} +
+ +
Lagre infomelding diff --git a/tavla/app/(admin)/edit/[id]/components/MetaSettings/Adress.tsx b/tavla/app/(admin)/edit/[id]/components/MetaSettings/Adress.tsx index e5b70abeb..24b3a07c9 100644 --- a/tavla/app/(admin)/edit/[id]/components/MetaSettings/Adress.tsx +++ b/tavla/app/(admin)/edit/[id]/components/MetaSettings/Adress.tsx @@ -1,13 +1,16 @@ +'use client' import { useToast } from '@entur/alert' import { SearchableDropdown } from '@entur/dropdown' import { ValidationInfoFilledIcon } from '@entur/icons' import { Tooltip } from '@entur/tooltip' import { Heading3 } from '@entur/typography' +import { FormError } from 'app/(admin)/components/FormError' import { saveLocation as saveLocationAction } from 'app/(admin)/edit/[id]/components/MetaSettings/actions' import { usePointSearch } from 'app/(admin)/hooks/usePointSearch' -import { fireToastFeedback } from 'app/(admin)/utils' +import { getFormFeedbackForField } from 'app/(admin)/utils' import ClientOnly from 'app/components/NoSSR/ClientOnly' import { SubmitButton } from 'components/Form/SubmitButton' +import { useActionState } from 'react' import { TLocation } from 'types/meta' import { TBoardID } from 'types/settings' @@ -18,12 +21,20 @@ function Address({ bid, location }: { bid: TBoardID; location?: TLocation }) { const { addToast } = useToast() const saveLocation = async () => { - const result = await saveLocationAction(bid, selectedPoint?.value) - fireToastFeedback(addToast, result, 'Adresse oppdatert!') + const formFeedback = await saveLocationAction(bid, selectedPoint?.value) + if (!formFeedback) { + addToast('Adresse oppdatert!') + } + return formFeedback } + const [locationState, saveLocationFormAction] = useActionState( + saveLocation, + undefined, + ) + return ( - +
Adresse @@ -50,6 +61,11 @@ function Address({ bid, location }: { bid: TBoardID; location?: TLocation }) { />
+
+ +
Lagre adresse diff --git a/tavla/app/(admin)/edit/[id]/components/MetaSettings/FontSelect.tsx b/tavla/app/(admin)/edit/[id]/components/MetaSettings/FontSelect.tsx new file mode 100644 index 000000000..8e177ef50 --- /dev/null +++ b/tavla/app/(admin)/edit/[id]/components/MetaSettings/FontSelect.tsx @@ -0,0 +1,48 @@ +'use client' +import { Heading3 } from '@entur/typography' +import { SubmitButton } from 'components/Form/SubmitButton' +import { TFontSize } from 'types/meta' +import { saveFont as saveFontAction } from './actions' +import { TBoardID } from 'types/settings' +import { useToast } from '@entur/alert' +import { FontChoiceChip } from './FontChoiceChip' +import { useActionState } from 'react' +import { getFormFeedbackForField, TFormFeedback } from 'app/(admin)/utils' +import { FormError } from 'app/(admin)/components/FormError' + +function FontSelect({ bid, font }: { bid: TBoardID; font: TFontSize }) { + const { addToast } = useToast() + + const saveFont = async ( + state: TFormFeedback | undefined, + data: FormData, + ) => { + const formFeedback = await saveFontAction(bid, data) + if (!formFeedback) { + addToast('Tekststørrelse lagret!') + } + return formFeedback + } + + const [fontState, fontFormAction] = useActionState(saveFont, undefined) + + return ( + + Tekststørrelse + +
+ +
+
+ + Lagre tekststørrelse + +
+ + ) +} + +export { FontSelect } diff --git a/tavla/app/(admin)/edit/[id]/components/MetaSettings/Organization.tsx b/tavla/app/(admin)/edit/[id]/components/MetaSettings/Organization.tsx new file mode 100644 index 000000000..eb0b90dd0 --- /dev/null +++ b/tavla/app/(admin)/edit/[id]/components/MetaSettings/Organization.tsx @@ -0,0 +1,84 @@ +'use client' +import { Dropdown } from '@entur/dropdown' +import { Checkbox } from '@entur/form' +import { Heading3 } from '@entur/typography' +import { FormError } from 'app/(admin)/components/FormError' +import { useOrganizations } from 'app/(admin)/hooks/useOrganizations' +import { getFormFeedbackForField } from 'app/(admin)/utils' +import ClientOnly from 'app/components/NoSSR/ClientOnly' +import { SubmitButton } from 'components/Form/SubmitButton' +import { useState, useActionState } from 'react' +import { TBoardID, TOrganization } from 'types/settings' +import { moveBoard as moveBoardAction } from './actions' +import { useToast } from '@entur/alert' + +function Organization({ + bid, + organization, +}: { + bid: TBoardID + organization?: TOrganization +}) { + const { addToast } = useToast() + + const { organizations, selectedOrganization, setSelectedOrganization } = + useOrganizations(organization) + const [personal, setPersonal] = useState(organization ? false : true) + + const moveBoard = async () => { + const formFeedback = await moveBoardAction( + bid, + personal, + selectedOrganization?.value.id, + organization?.id, + ) + if (!formFeedback) { + addToast('Tavlen ble flyttet til organisasjon!') + } + return formFeedback + } + + const [moveBoardState, moveBordFormAction] = useActionState( + moveBoard, + undefined, + ) + return ( +
+ Organisasjon + + + + setPersonal(!personal)} + name="personal" + > + Privat tavle + +
+ + +
+
+ + Lagre organisasjon + +
+
+ ) +} + +export { Organization } diff --git a/tavla/app/(admin)/edit/[id]/components/MetaSettings/Title.tsx b/tavla/app/(admin)/edit/[id]/components/MetaSettings/Title.tsx new file mode 100644 index 000000000..adfc98dd1 --- /dev/null +++ b/tavla/app/(admin)/edit/[id]/components/MetaSettings/Title.tsx @@ -0,0 +1,55 @@ +'use client' +import { useToast } from '@entur/alert' +import { Heading3 } from '@entur/typography' +import { getFormFeedbackForField, TFormFeedback } from 'app/(admin)/utils' +import ClientOnlyTextField from 'app/components/NoSSR/TextField' +import { SubmitButton } from 'components/Form/SubmitButton' +import { useActionState } from 'react' +import { saveTitle as saveTitleAction } from './actions' +import { TBoardID } from 'types/settings' +import { FormError } from 'app/(admin)/components/FormError' + +function Title({ bid, title }: { bid: TBoardID; title: string }) { + const { addToast } = useToast() + + const saveTitle = async ( + state: TFormFeedback | undefined, + data: FormData, + ) => { + const formFeedback = await saveTitleAction(state, bid, data) + if (!formFeedback) { + addToast('Navnet på tavlen er lagret!') + } + return formFeedback + } + const [titleState, saveTitleFormAction] = useActionState( + saveTitle, + undefined, + ) + return ( +
+ Navn +
+ +
+
+ +
+
+ + Lagre navn + +
+
+ ) +} +export { Title } diff --git a/tavla/app/(admin)/edit/[id]/components/MetaSettings/actions.ts b/tavla/app/(admin)/edit/[id]/components/MetaSettings/actions.ts index f356bafde..e6d70d685 100644 --- a/tavla/app/(admin)/edit/[id]/components/MetaSettings/actions.ts +++ b/tavla/app/(admin)/edit/[id]/components/MetaSettings/actions.ts @@ -8,7 +8,7 @@ import { } from 'app/(admin)/utils/firebase' import admin, { firestore } from 'firebase-admin' import { revalidatePath } from 'next/cache' -import { redirect } from 'next/navigation' +import { notFound, redirect } from 'next/navigation' import { TFontSize, TLocation } from 'types/meta' import { TBoard, TBoardID, TOrganizationID } from 'types/settings' import { getWalkingDistanceTile } from '../../actions' @@ -76,13 +76,13 @@ export async function saveFont(bid: TBoardID, data: FormData) { } export async function saveLocation(bid: TBoardID, location?: TLocation) { - if (!bid) return getFormFeedbackForError() - const access = await hasBoardEditorAccess(bid) if (!access) return redirect('/') const board = await getBoard(bid) - if (!board) return getFormFeedbackForError('board/not-found') + if (!board) { + return notFound() + } try { await firestore() @@ -116,7 +116,8 @@ async function getTilesWithDistance(board: TBoard, location?: TLocation) { export async function moveBoard( bid: TBoardID, - oid?: TOrganizationID, + personal: boolean, + toOrganization: TOrganizationID | undefined, fromOrganization?: TOrganizationID, ) { const user = await getUserFromSessionCookie() @@ -125,10 +126,18 @@ export async function moveBoard( const access = await hasBoardOwnerAccess(bid) if (!access) return redirect('/') - if (fromOrganization && !(await userCanEditOrganization(fromOrganization))) - return redirect('/') + if (!personal && !toOrganization) + return getFormFeedbackForError('create/organization-missing') - if (oid && !(await userCanEditOrganization(oid))) return redirect('/') + if (fromOrganization) { + const canEdit = await userCanEditOrganization(fromOrganization) + if (!canEdit) return redirect('/') + } + + if (toOrganization) { + const canEdit = await userCanEditOrganization(toOrganization) + if (!canEdit) return redirect('/') + } try { if (fromOrganization) @@ -142,10 +151,10 @@ export async function moveBoard( .doc(user.uid) .update({ owner: admin.firestore.FieldValue.arrayRemove(bid) }) - if (oid) + if (toOrganization) await firestore() .collection('organizations') - .doc(oid) + .doc(toOrganization) .update({ boards: admin.firestore.FieldValue.arrayUnion(bid) }) else await firestore() diff --git a/tavla/app/(admin)/edit/[id]/components/MetaSettings/index.tsx b/tavla/app/(admin)/edit/[id]/components/MetaSettings/index.tsx index 615cd5883..51ac4c98d 100644 --- a/tavla/app/(admin)/edit/[id]/components/MetaSettings/index.tsx +++ b/tavla/app/(admin)/edit/[id]/components/MetaSettings/index.tsx @@ -1,28 +1,10 @@ -'use client' -import { Checkbox } from '@entur/form' -import { Heading3 } from '@entur/typography' import { TMeta } from 'types/meta' -import { - moveBoard as moveBoardAction, - saveFont as saveFontAction, - saveTitle as saveTitleAction, -} from './actions' import { TBoardID, TOrganization } from 'types/settings' -import { FontChoiceChip } from './FontChoiceChip' -import { SubmitButton } from 'components/Form/SubmitButton' import { Address } from './Adress' import { DEFAULT_BOARD_NAME } from 'app/(admin)/utils/constants' -import { useToast } from '@entur/alert' -import { Dropdown } from '@entur/dropdown' -import { useOrganizations } from 'app/(admin)/hooks/useOrganizations' -import { useActionState, useState } from 'react' -import { - TFormFeedback, - fireToastFeedback, - getFormFeedbackForField, -} from 'app/(admin)/utils' -import ClientOnlyTextField from 'app/components/NoSSR/TextField' -import ClientOnly from 'app/components/NoSSR/ClientOnly' +import { Organization } from './Organization' +import { FontSelect } from './FontSelect' +import { Title } from './Title' function MetaSettings({ bid, @@ -33,98 +15,12 @@ function MetaSettings({ meta: TMeta organization?: TOrganization }) { - const { addToast } = useToast() - const { organizations, selectedOrganization, setSelectedOrganization } = - useOrganizations(organization) - const [personal, setPersonal] = useState(organization ? false : true) - - const saveTitleWithParams = async ( - state: TFormFeedback | undefined, - data: FormData, - ) => { - const result = await saveTitleAction(state, bid, data) - fireToastFeedback(addToast, result, 'Tittel oppdatert!') - return result - } - const [titleState, saveTitle] = useActionState( - saveTitleWithParams, - undefined, - ) - - const saveFont = async (data: FormData) => { - const result = await saveFontAction(bid, data) - fireToastFeedback(addToast, result, 'Tekststørrelse lagret!') - } - - const moveBoard = async () => { - const result = await moveBoardAction( - bid, - personal ? undefined : selectedOrganization?.value.id, - organization?.id, - ) - fireToastFeedback(addToast, result, 'Organisasjon lagret!') - } - return ( <> -
- Navn -
- -
-
- - Lagre navn - -
-
+ <Address bid={bid} location={meta?.location} /> - <form - action={saveFont} - className="box flex flex-col justify-between" - > - <Heading3 margin="bottom">Tekststørrelse </Heading3> - <FontChoiceChip font={meta?.fontSize ?? 'medium'} /> - <div className="flex flex-row mt-8 justify-end"> - <SubmitButton variant="secondary" className="max-sm:w-full"> - Lagre tekststørrelse - </SubmitButton> - </div> - </form> - <form action={moveBoard} className="box flex flex-col"> - <Heading3 margin="bottom">Organisasjon</Heading3> - <ClientOnly> - <Dropdown - items={organizations} - label="Dine organisasjoner" - selectedItem={selectedOrganization} - onChange={setSelectedOrganization} - clearable - className="mb-4" - aria-required="true" - disabled={personal} - /> - </ClientOnly> - <Checkbox - checked={personal} - onChange={() => setPersonal(!personal)} - name="personal" - > - Privat tavle - </Checkbox> - <div className="flex flex-row mt-8 justify-end"> - <SubmitButton variant="secondary" className="max-sm:w-full"> - Lagre organisasjon - </SubmitButton> - </div> - </form> + <FontSelect bid={bid} font={meta?.fontSize ?? 'medium'} /> + <Organization bid={bid} organization={organization} /> </> ) } diff --git a/tavla/app/(admin)/edit/[id]/components/ThemeSelect/index.tsx b/tavla/app/(admin)/edit/[id]/components/ThemeSelect/index.tsx index e3b47464c..00e637b10 100644 --- a/tavla/app/(admin)/edit/[id]/components/ThemeSelect/index.tsx +++ b/tavla/app/(admin)/edit/[id]/components/ThemeSelect/index.tsx @@ -7,7 +7,6 @@ import { Heading3 } from '@entur/typography' import { useToast } from '@entur/alert' import { themeToDropdownItem, themes } from 'app/(admin)/edit/utils' import { setTheme as setThemeAction } from './actions' -import { fireToastFeedback } from 'app/(admin)/utils' function ThemeSelect({ board }: { board: TBoard }) { const [selectedTheme, setSelectedTheme] = @@ -17,11 +16,13 @@ function ThemeSelect({ board }: { board: TBoard }) { const { addToast } = useToast() const setTheme = async () => { - const result = await setThemeAction( + const formFeedback = await setThemeAction( board.id ?? '', selectedTheme?.value ?? 'dark', ) - fireToastFeedback(addToast, result, 'Fargetema lagret!') + if (!formFeedback) { + addToast('Fargetema lagret!') + } } return ( diff --git a/tavla/app/(admin)/organizations/components/CountiesSelect/index.tsx b/tavla/app/(admin)/organizations/components/CountiesSelect/index.tsx index 4edb5f840..6789eff76 100644 --- a/tavla/app/(admin)/organizations/components/CountiesSelect/index.tsx +++ b/tavla/app/(admin)/organizations/components/CountiesSelect/index.tsx @@ -7,7 +7,9 @@ import { setCounties as setCountiesAction } from './actions' import { Heading2, Paragraph } from '@entur/typography' import { useToast } from '@entur/alert' import { SubmitButton } from 'components/Form/SubmitButton' -import { fireToastFeedback } from 'app/(admin)/utils' +import { useActionState } from 'react' +import { getFormFeedbackForField, TFormFeedback } from 'app/(admin)/utils' +import { FormError } from 'app/(admin)/components/FormError' function CountiesSelect({ oid, @@ -19,11 +21,22 @@ function CountiesSelect({ const { counties } = useCountiesSearch(oid) const { addToast } = useToast() - const setCounties = async (data: FormData) => { - const result = await setCountiesAction(oid, data) - fireToastFeedback(addToast, result, 'Fylker lagret!') + const setCounties = async ( + state: TFormFeedback | undefined, + data: FormData, + ) => { + const formFeedback = await setCountiesAction(oid, data) + if (!formFeedback) { + addToast('Fylker lagret!') + } + return formFeedback } + const [countiesState, countiesFormAction] = useActionState( + setCounties, + undefined, + ) + return ( <div className="box flex flex-col gap-1"> <Heading2>Fylker</Heading2> @@ -31,7 +44,7 @@ function CountiesSelect({ Velg hvilke fylker som skal være standard når det opprettes en ny tavle. </Paragraph> - <form action={setCounties}> + <form action={countiesFormAction}> <div className="grid grid-cols-2 md:grid-cols-3 gap-x-2"> {counties() .sort( @@ -54,6 +67,11 @@ function CountiesSelect({ </Checkbox> ))} </div> + <div className="mt-4"> + <FormError + {...getFormFeedbackForField('general', countiesState)} + /> + </div> <div className="flex flex-row w-full mt-8 justify-end"> <SubmitButton variant="secondary" diff --git a/tavla/app/(admin)/organizations/components/DefaultColumns/index.tsx b/tavla/app/(admin)/organizations/components/DefaultColumns/index.tsx index 997100197..fc195b4ee 100644 --- a/tavla/app/(admin)/organizations/components/DefaultColumns/index.tsx +++ b/tavla/app/(admin)/organizations/components/DefaultColumns/index.tsx @@ -24,18 +24,20 @@ function DefaultColumns({ const { addToast } = useToast() const [open, setIsOpen] = useState(false) - const handleSaveColumns = async ( + const saveColumns = async ( state: TFormFeedback | undefined, data: FormData, ) => { - const result = await saveColumnsAction(state, oid, data) - if (result === undefined) { + const formFeedback = await saveColumnsAction(state, oid, data) + if (!formFeedback) { addToast('Kolonner lagret!') } - - return result + return formFeedback } - const [state, saveColumns] = useActionState(handleSaveColumns, undefined) + const [state, saveColumnsFormAction] = useActionState( + saveColumns, + undefined, + ) return ( <div className="box flex flex-col gap-1"> @@ -64,7 +66,7 @@ function DefaultColumns({ <ColumnModal isOpen={open} setIsOpen={setIsOpen} /> - <form action={saveColumns}> + <form action={saveColumnsFormAction}> <div className="flex flex-row flex-wrap gap-4"> {Object.entries(Columns).map(([key, information]) => ( <FilterChip @@ -79,8 +81,9 @@ function DefaultColumns({ </FilterChip> ))} </div> - <div className="mt-8" aria-live="polite"> + <div className="mt-4" aria-live="polite"> <FormError {...getFormFeedbackForField('column', state)} /> + <FormError {...getFormFeedbackForField('general', state)} /> </div> <div className="flex flex-row w-full mt-8 justify-end"> <SubmitButton diff --git a/tavla/app/(admin)/organizations/components/FontSelect/index.tsx b/tavla/app/(admin)/organizations/components/FontSelect/index.tsx index 3f1dce269..b440134fc 100644 --- a/tavla/app/(admin)/organizations/components/FontSelect/index.tsx +++ b/tavla/app/(admin)/organizations/components/FontSelect/index.tsx @@ -6,7 +6,9 @@ import { SubmitButton } from 'components/Form/SubmitButton' import { useToast } from '@entur/alert' import { TOrganizationID } from 'types/settings' import { Heading2, Paragraph } from '@entur/typography' -import { fireToastFeedback } from 'app/(admin)/utils' +import { useActionState } from 'react' +import { getFormFeedbackForField, TFormFeedback } from 'app/(admin)/utils' +import { FormError } from 'app/(admin)/components/FormError' function FontSelect({ oid, @@ -17,11 +19,22 @@ function FontSelect({ }) { const { addToast } = useToast() - const setFontSize = async (data: FormData) => { - const result = await setFontSizeAction(oid, data) - fireToastFeedback(addToast, result, 'Tekststørrelse lagret!') + const setFontSize = async ( + state: TFormFeedback | undefined, + data: FormData, + ) => { + const formFeedback = await setFontSizeAction(oid, data) + if (!formFeedback) { + addToast('Tekststørrelse lagret!') + } + return formFeedback } + const [fontState, fontSizeFormAction] = useActionState( + setFontSize, + undefined, + ) + return ( <div className="box flex flex-col gap-1"> <Heading2>Tekststørrelse</Heading2> @@ -31,10 +44,14 @@ function FontSelect({ </Paragraph> <form className="flex flex-col justify-between h-full" - action={setFontSize} + action={fontSizeFormAction} > <FontChoiceChip font={font ?? 'medium'} /> - + <div className="mt-4"> + <FormError + {...getFormFeedbackForField('general', fontState)} + /> + </div> <div className="flex flex-row w-full mt-8 justify-end"> <SubmitButton variant="secondary" diff --git a/tavla/app/(admin)/organizations/components/Footer/index.tsx b/tavla/app/(admin)/organizations/components/Footer/index.tsx index 897e65fdf..12fbd9bc9 100644 --- a/tavla/app/(admin)/organizations/components/Footer/index.tsx +++ b/tavla/app/(admin)/organizations/components/Footer/index.tsx @@ -5,29 +5,52 @@ import { SubmitButton } from 'components/Form/SubmitButton' import { TOrganizationID } from 'types/settings' import { setFooter as setFooterAction } from './actions' import ClientOnlyTextField from 'app/components/NoSSR/TextField' -import { fireToastFeedback } from 'app/(admin)/utils' +import { useActionState } from 'react' +import { FormError } from 'app/(admin)/components/FormError' +import { getFormFeedbackForField, TFormFeedback } from 'app/(admin)/utils' function Footer({ oid, footer }: { oid?: TOrganizationID; footer?: string }) { const { addToast } = useToast() - const setOrgFooter = async (data: FormData) => { - const result = await setFooterAction(oid, data) - fireToastFeedback(addToast, result, 'Infomelding lagret!') + const setOrgFooter = async ( + state: TFormFeedback | undefined, + data: FormData, + ) => { + const formFeedback = await setFooterAction(oid, data) + if (!formFeedback) { + addToast('Infomelding lagret!') + } + return formFeedback } + const [orgFooterState, orgFooterFormAction] = useActionState( + setOrgFooter, + undefined, + ) + return ( - <form className="box flex flex-col gap-1 " action={setOrgFooter}> + <form className="box flex flex-col gap-1 " action={orgFooterFormAction}> <Heading2>Infomelding</Heading2> <Paragraph> Skriv en kort tekst som skal vises nederst i tavlen. </Paragraph> <div className="flex flex-col justify-between h-full"> - <ClientOnlyTextField - label="Infomelding" - name="footer" - defaultValue={footer ?? ''} - /> + <div> + <ClientOnlyTextField + label="Infomelding" + name="footer" + defaultValue={footer ?? ''} + /> + <div className="mt-4"> + <FormError + {...getFormFeedbackForField( + 'general', + orgFooterState, + )} + /> + </div> + </div> <div className="flex flex-row w-full mt-8 justify-end"> <SubmitButton variant="secondary" diff --git a/tavla/app/(admin)/utils/index.ts b/tavla/app/(admin)/utils/index.ts index 4b8663f0d..2093e39d6 100644 --- a/tavla/app/(admin)/utils/index.ts +++ b/tavla/app/(admin)/utils/index.ts @@ -1,4 +1,3 @@ -import { AddToastPayload } from '@entur/alert/dist/ToastProvider' import { VariantType } from '@entur/form' import { FirebaseError } from 'firebase/app' import { TOrganization, TUserID } from 'types/settings' @@ -265,23 +264,6 @@ export function getFormFeedbackForError( } } -export function fireToastFeedback( - addToast: (payload: AddToastPayload | string) => void, - formFeedback: TFormFeedback | undefined, - successMessage: string, -) { - if (formFeedback === undefined) { - addToast(successMessage) - } else if (formFeedback.form_type === 'general') { - const content = - getFormFeedbackForField('general', formFeedback)?.feedback || '' - addToast({ - content: content, - variant: 'info', - }) - } -} - export function userInOrganization( uid?: TUserID, organization?: TOrganization,