Skip to content

Commit

Permalink
feat(settings): show error alert to user if firebase fail in edit and…
Browse files Browse the repository at this point in the history
… 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
  • Loading branch information
emilielr authored Dec 17, 2024
1 parent 0daa9ff commit 558f6d4
Show file tree
Hide file tree
Showing 14 changed files with 354 additions and 182 deletions.
7 changes: 6 additions & 1 deletion tavla/app/(admin)/edit/[id]/components/Footer/actions.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use server'
import { isEmptyOrSpaces } from 'app/(admin)/edit/utils'
import { TFormFeedback } from 'app/(admin)/utils'
import {
hasBoardEditorAccess,
initializeAdminApp,
Expand All @@ -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('/')

Expand Down
29 changes: 22 additions & 7 deletions tavla/app/(admin)/edit/[id]/components/Footer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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 (
<form className="box flex flex-col" action={setFooter}>
<form className="box flex flex-col" action={footerFormAction}>
<div className="flex flex-row items-center gap-2">
<Heading3 margin="bottom">Infomelding</Heading3>

Expand Down Expand Up @@ -58,11 +68,16 @@ function Footer({
Vis infomelding fra organisasjonen.
</Switch>
)}
<div className="mt-4">
<FormError
{...getFormFeedbackForField('general', footerState)}
/>
</div>
</div>
<div className="flex flex-row mt-8 justify-end">
<SubmitButton
variant="secondary"
aria-label="Lagre kolonner"
aria-label="Lagre infomelding"
className="max-sm:w-full"
>
Lagre infomelding
Expand Down
24 changes: 20 additions & 4 deletions tavla/app/(admin)/edit/[id]/components/MetaSettings/Adress.tsx
Original file line number Diff line number Diff line change
@@ -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'
Expand All @@ -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 (
<form action={saveLocation} className="box flex flex-col">
<form action={saveLocationFormAction} className="box flex flex-col">
<div className="flex flex-row items-center gap-2">
<Heading3 margin="bottom">Adresse</Heading3>

Expand All @@ -50,6 +61,11 @@ function Address({ bid, location }: { bid: TBoardID; location?: TLocation }) {
/>
</ClientOnly>
</div>
<div className="mt-4">
<FormError
{...getFormFeedbackForField('general', locationState)}
/>
</div>
<div className="flex flex-row mt-8 justify-end">
<SubmitButton variant="secondary" className="max-sm:w-full">
Lagre adresse
Expand Down
48 changes: 48 additions & 0 deletions tavla/app/(admin)/edit/[id]/components/MetaSettings/FontSelect.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<form
action={fontFormAction}
className="box flex flex-col justify-between"
>
<Heading3 margin="bottom">Tekststørrelse </Heading3>
<FontChoiceChip font={font} />
<div className="mt-4">
<FormError {...getFormFeedbackForField('general', fontState)} />
</div>
<div className="flex flex-row mt-8 justify-end">
<SubmitButton variant="secondary" className="max-sm:w-full">
Lagre tekststørrelse
</SubmitButton>
</div>
</form>
)
}

export { FontSelect }
Original file line number Diff line number Diff line change
@@ -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 (
<form action={moveBordFormAction} 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
defaultChecked={personal}
onChange={() => setPersonal(!personal)}
name="personal"
>
Privat tavle
</Checkbox>
<div className="mt-4">
<FormError
{...getFormFeedbackForField('organization', moveBoardState)}
/>
<FormError
{...getFormFeedbackForField('general', moveBoardState)}
/>
</div>
<div className="flex flex-row mt-8 justify-end">
<SubmitButton variant="secondary" className="max-sm:w-full">
Lagre organisasjon
</SubmitButton>
</div>
</form>
)
}

export { Organization }
55 changes: 55 additions & 0 deletions tavla/app/(admin)/edit/[id]/components/MetaSettings/Title.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<form action={saveTitleFormAction} className="box flex flex-col">
<Heading3 margin="bottom">Navn</Heading3>
<div className="h-full">
<ClientOnlyTextField
name="name"
className="w-full"
defaultValue={title}
label="Navn på tavlen"
maxLength={50}
{...getFormFeedbackForField('name', titleState)}
/>
</div>
<div className="mt-4">
<FormError
{...getFormFeedbackForField('general', titleState)}
/>
</div>
<div className="flex flex-row justify-end mt-8">
<SubmitButton variant="secondary" className="max-sm:w-full">
Lagre navn
</SubmitButton>
</div>
</form>
)
}
export { Title }
29 changes: 19 additions & 10 deletions tavla/app/(admin)/edit/[id]/components/MetaSettings/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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()
Expand All @@ -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)
Expand All @@ -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()
Expand Down
Loading

0 comments on commit 558f6d4

Please sign in to comment.