mirror of
https://github.com/Steffo99/festa.git
synced 2024-12-22 14:44:21 +00:00
Capture onSubmit to save the form
This commit is contained in:
parent
8f934e70f2
commit
2e69a0f963
4 changed files with 56 additions and 46 deletions
|
@ -1,45 +1,54 @@
|
||||||
import { Event } from "@prisma/client"
|
import { Event } from "@prisma/client"
|
||||||
import { useCallback, useMemo } from "react"
|
import { Dispatch, useMemo } from "react"
|
||||||
import { KeyedMutator } from "swr"
|
import { KeyedMutator } from "swr"
|
||||||
|
import { UsePromise } from "../../generic/loading/promise"
|
||||||
import { ViewContent } from "../../generic/views/content"
|
import { ViewContent } from "../../generic/views/content"
|
||||||
|
|
||||||
|
|
||||||
export type EventsActionViewProps = {
|
export type EventsActionViewProps = {
|
||||||
data: Event,
|
data: Event,
|
||||||
mutate: KeyedMutator<Event>,
|
mutate: KeyedMutator<Event>,
|
||||||
|
save: UsePromise<void, void>,
|
||||||
|
setEditing: Dispatch<boolean>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export const EventsActionEdit = ({ data, mutate }: EventsActionViewProps) => {
|
export const EventsActionEdit = ({ data, mutate, save, setEditing }: EventsActionViewProps) => {
|
||||||
const name = data.name
|
const name = data.name
|
||||||
const description = data.description
|
const description = data.description
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ViewContent
|
<form onSubmit={e => {
|
||||||
title={
|
e.preventDefault()
|
||||||
useMemo(
|
save.run()
|
||||||
() => (
|
setEditing(false)
|
||||||
<input
|
}}>
|
||||||
type="text"
|
<ViewContent
|
||||||
value={name}
|
title={
|
||||||
onChange={e => mutate((prev) => ({ ...prev!, name: e.target.value }), { revalidate: false })}
|
useMemo(
|
||||||
/>
|
() => (
|
||||||
),
|
<input
|
||||||
[mutate, name]
|
type="text"
|
||||||
)
|
value={name}
|
||||||
}
|
onChange={e => mutate((prev) => ({ ...prev!, name: e.target.value }), { revalidate: false })}
|
||||||
content={<>
|
/>
|
||||||
{useMemo(
|
),
|
||||||
() => (
|
[mutate, name]
|
||||||
<textarea
|
)
|
||||||
rows={12}
|
}
|
||||||
value={description}
|
content={<>
|
||||||
onChange={e => mutate((prev) => ({ ...prev!, description: e.target.value }), { revalidate: false })}
|
{useMemo(
|
||||||
/>
|
() => (
|
||||||
),
|
<textarea
|
||||||
[mutate, description]
|
rows={12}
|
||||||
)}
|
value={description}
|
||||||
</>}
|
onChange={e => mutate((prev) => ({ ...prev!, description: e.target.value }), { revalidate: false })}
|
||||||
/>
|
/>
|
||||||
|
),
|
||||||
|
[mutate, description]
|
||||||
|
)}
|
||||||
|
</>}
|
||||||
|
/>
|
||||||
|
</form>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,14 +11,16 @@ export type EventsActionViewProps = {
|
||||||
|
|
||||||
export const EventsActionView = memo(({ data }: EventsActionViewProps) => {
|
export const EventsActionView = memo(({ data }: EventsActionViewProps) => {
|
||||||
return (
|
return (
|
||||||
<ViewContent
|
<form>
|
||||||
title={<div style={{ padding: "10px" }}>
|
<ViewContent
|
||||||
{data.name}
|
title={<div style={{ padding: "10px" }}>
|
||||||
</div>}
|
{data.name}
|
||||||
content={<div>
|
</div>}
|
||||||
<FestaMarkdownRenderer code={data.description} />
|
content={<div>
|
||||||
</div>}
|
<FestaMarkdownRenderer code={data.description} />
|
||||||
/>
|
</div>}
|
||||||
|
/>
|
||||||
|
</form>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
EventsActionView.displayName = "EventsActionView"
|
EventsActionView.displayName = "EventsActionView"
|
|
@ -1,6 +1,6 @@
|
||||||
import { faAsterisk, faPencil, faSave } from "@fortawesome/free-solid-svg-icons"
|
import { faAsterisk, faPencil, faSave } from "@fortawesome/free-solid-svg-icons"
|
||||||
import { useTranslation } from "next-i18next"
|
import { useTranslation } from "next-i18next"
|
||||||
import { usePromise, UsePromiseStatus } from "../../generic/loading/promise"
|
import { UsePromise, usePromise, UsePromiseStatus } from "../../generic/loading/promise"
|
||||||
import { FestaIcon } from "../../generic/renderers/fontawesome"
|
import { FestaIcon } from "../../generic/renderers/fontawesome"
|
||||||
import { Tool } from "../../generic/toolbar/tool"
|
import { Tool } from "../../generic/toolbar/tool"
|
||||||
import cursor from "../../../styles/cursor.module.css"
|
import cursor from "../../../styles/cursor.module.css"
|
||||||
|
@ -11,19 +11,17 @@ import { Dispatch } from "react"
|
||||||
export type ToolToggleEditingProps = {
|
export type ToolToggleEditingProps = {
|
||||||
editing: boolean,
|
editing: boolean,
|
||||||
setEditing: Dispatch<boolean>,
|
setEditing: Dispatch<boolean>,
|
||||||
save: () => Promise<void>,
|
save: UsePromise<void, void>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ToolBar {@link Tool} which allows the user to start editing an event and then save their changes.
|
* ToolBar {@link Tool} which allows the user to start editing an event and then save their changes.
|
||||||
*/
|
*/
|
||||||
export function ToolToggleEditing({ editing, setEditing, save: upperSave }: ToolToggleEditingProps) {
|
export function ToolToggleEditing({ editing, setEditing, save }: ToolToggleEditingProps) {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
const { run: save, status: saveStatus } = usePromise<void, void>(upperSave)
|
if (save.status === UsePromiseStatus.PENDING) {
|
||||||
|
|
||||||
if (saveStatus === UsePromiseStatus.PENDING) {
|
|
||||||
return (
|
return (
|
||||||
<Tool
|
<Tool
|
||||||
aria-label={t("toolToggleEditingSaving")}
|
aria-label={t("toolToggleEditingSaving")}
|
||||||
|
@ -39,7 +37,7 @@ export function ToolToggleEditing({ editing, setEditing, save: upperSave }: Tool
|
||||||
<Tool
|
<Tool
|
||||||
aria-label={t("toolToggleEditingSave")}
|
aria-label={t("toolToggleEditingSave")}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
save()
|
save.run()
|
||||||
setEditing(false)
|
setEditing(false)
|
||||||
}}
|
}}
|
||||||
className={mood.positive}
|
className={mood.positive}
|
||||||
|
|
|
@ -17,6 +17,7 @@ import { useAxios } from '../../components/auth/requests'
|
||||||
import { database } from '../../utils/prismaClient'
|
import { database } from '../../utils/prismaClient'
|
||||||
import { EventsActionEdit } from '../../components/events/actions/edit'
|
import { EventsActionEdit } from '../../components/events/actions/edit'
|
||||||
import { EventsActionView } from '../../components/events/actions/view'
|
import { EventsActionView } from '../../components/events/actions/view'
|
||||||
|
import { usePromise } from '../../components/generic/loading/promise'
|
||||||
|
|
||||||
|
|
||||||
export async function getServerSideProps(context: NextPageContext) {
|
export async function getServerSideProps(context: NextPageContext) {
|
||||||
|
@ -46,13 +47,13 @@ const PageEvent: NextPage<PageEventProps> = ({ slug, fallbackData }) => {
|
||||||
const { data, mutate } = useSWR<Event>(`/api/events/${slug}`, { fallbackData, revalidateOnFocus: eventEditing, revalidateOnReconnect: eventEditing, refreshInterval: eventEditing ? 0 : 30000 })
|
const { data, mutate } = useSWR<Event>(`/api/events/${slug}`, { fallbackData, revalidateOnFocus: eventEditing, revalidateOnReconnect: eventEditing, refreshInterval: eventEditing ? 0 : 30000 })
|
||||||
const [auth,] = useDefinedContext(AuthContext)
|
const [auth,] = useDefinedContext(AuthContext)
|
||||||
|
|
||||||
const save = useCallback(
|
const save = usePromise<void, void>(useCallback(
|
||||||
async () => {
|
async () => {
|
||||||
const response = await axios.patch<Event>(`/api/events/${slug}`, data!)
|
const response = await axios.patch<Event>(`/api/events/${slug}`, data!)
|
||||||
mutate(response.data, { revalidate: false })
|
mutate(response.data, { revalidate: false })
|
||||||
},
|
},
|
||||||
[axios, data, mutate, slug]
|
[axios, data, mutate, slug]
|
||||||
)
|
))
|
||||||
|
|
||||||
const eventName = data?.name ?? slug
|
const eventName = data?.name ?? slug
|
||||||
const eventPostcard = data?.postcard || defaultPostcard
|
const eventPostcard = data?.postcard || defaultPostcard
|
||||||
|
@ -75,7 +76,7 @@ const PageEvent: NextPage<PageEventProps> = ({ slug, fallbackData }) => {
|
||||||
}
|
}
|
||||||
</ToolBar>
|
</ToolBar>
|
||||||
{eventEditing ?
|
{eventEditing ?
|
||||||
<EventsActionEdit data={data!} mutate={mutate} />
|
<EventsActionEdit data={data!} mutate={mutate} save={save} setEditing={eventSetEditing} />
|
||||||
:
|
:
|
||||||
<EventsActionView data={data!} />
|
<EventsActionView data={data!} />
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue