Disable login form while loading
This commit is contained in:
parent
8d9a8cf868
commit
e49a7e8c97
17
frontend/src/app/[id]/loading.tsx
Normal file
17
frontend/src/app/[id]/loading.tsx
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
import EventAvailabilities from '/src/app/[id]/EventAvailabilities'
|
||||||
|
import Content from '/src/components/Content/Content'
|
||||||
|
|
||||||
|
import styles from './page.module.scss'
|
||||||
|
|
||||||
|
const Loading = async () => <>
|
||||||
|
<Content>
|
||||||
|
<h1 className={styles.name}><span className={styles.bone} /></h1>
|
||||||
|
<div className={styles.date}><span className={styles.bone} /></div>
|
||||||
|
<div className={styles.info}><span className={styles.bone} style={{ width: '20em' }} /></div>
|
||||||
|
<div className={styles.info}><span className={styles.bone} style={{ width: '20em' }} /></div>
|
||||||
|
</Content>
|
||||||
|
|
||||||
|
<EventAvailabilities />
|
||||||
|
</>
|
||||||
|
|
||||||
|
export default Loading
|
||||||
|
|
@ -6,7 +6,7 @@ import { Temporal } from '@js-temporal/polyfill'
|
||||||
|
|
||||||
import Content from '/src/components/Content/Content'
|
import Content from '/src/components/Content/Content'
|
||||||
import Copyable from '/src/components/Copyable/Copyable'
|
import Copyable from '/src/components/Copyable/Copyable'
|
||||||
import { EventResponse, getEvent } from '/src/config/api'
|
import { getEvent } from '/src/config/api'
|
||||||
import { useTranslation } from '/src/i18n/server'
|
import { useTranslation } from '/src/i18n/server'
|
||||||
import { makeClass, relativeTimeFormat } from '/src/utils'
|
import { makeClass, relativeTimeFormat } from '/src/utils'
|
||||||
|
|
||||||
|
|
@ -27,7 +27,10 @@ export const generateMetadata = async ({ params }: PageProps): Promise<Metadata>
|
||||||
}
|
}
|
||||||
|
|
||||||
const Page = async ({ params }: PageProps) => {
|
const Page = async ({ params }: PageProps) => {
|
||||||
const event = getEvent(params.id)
|
const event = await getEvent(params.id).catch(() => undefined)
|
||||||
|
if (!event) notFound()
|
||||||
|
|
||||||
|
const { t, i18n } = await useTranslation(['common', 'event'])
|
||||||
|
|
||||||
return <>
|
return <>
|
||||||
<Suspense
|
<Suspense
|
||||||
|
|
@ -38,33 +41,24 @@ const Page = async ({ params }: PageProps) => {
|
||||||
<div className={styles.info}><span className={styles.bone} style={{ width: '20em' }} /></div>
|
<div className={styles.info}><span className={styles.bone} style={{ width: '20em' }} /></div>
|
||||||
</Content>}
|
</Content>}
|
||||||
>
|
>
|
||||||
<EventMeta event={event} />
|
<Content>
|
||||||
|
<h1 className={styles.name}>{event.name}</h1>
|
||||||
|
<span
|
||||||
|
className={styles.date}
|
||||||
|
title={Temporal.Instant.fromEpochSeconds(event.created_at).toLocaleString(i18n.language, { dateStyle: 'long' })}
|
||||||
|
>{t('common:created', { date: relativeTimeFormat(Temporal.Instant.fromEpochSeconds(event.created_at), i18n.language) })}</span>
|
||||||
|
|
||||||
|
<Copyable className={styles.info}>
|
||||||
|
{`https://crab.fit/${event.id}`}
|
||||||
|
</Copyable>
|
||||||
|
<p className={makeClass(styles.info, styles.noPrint)}>
|
||||||
|
<Trans i18nKey="event:nav.shareinfo" t={t} i18n={i18n}>_<a href={`mailto:?subject=${encodeURIComponent(t('event:nav.email_subject', { event_name: event.name }))}&body=${encodeURIComponent(`${t('event:nav.email_body')} https://crab.fit/${event.id}`)}`}>_</a>_</Trans>
|
||||||
|
</p>
|
||||||
|
</Content>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
|
|
||||||
<EventAvailabilities event={await event.catch(() => undefined)} />
|
<EventAvailabilities event={event} />
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
|
||||||
const EventMeta = async (props: { event: Promise<EventResponse> }) => {
|
|
||||||
const event = await props.event.catch(() => undefined)
|
|
||||||
if (!event) notFound()
|
|
||||||
|
|
||||||
const { t, i18n } = await useTranslation(['common', 'event'])
|
|
||||||
|
|
||||||
return <Content>
|
|
||||||
<h1 className={styles.name}>{event.name}</h1>
|
|
||||||
<span
|
|
||||||
className={styles.date}
|
|
||||||
title={Temporal.Instant.fromEpochSeconds(event.created_at).toLocaleString(i18n.language, { dateStyle: 'long' })}
|
|
||||||
>{t('common:created', { date: relativeTimeFormat(Temporal.Instant.fromEpochSeconds(event.created_at), i18n.language) })}</span>
|
|
||||||
|
|
||||||
<Copyable className={styles.info}>
|
|
||||||
{`https://crab.fit/${event.id}`}
|
|
||||||
</Copyable>
|
|
||||||
<p className={makeClass(styles.info, styles.noPrint)}>
|
|
||||||
<Trans i18nKey="event:nav.shareinfo" t={t} i18n={i18n}>_<a href={`mailto:?subject=${encodeURIComponent(t('event:nav.email_subject', { event_name: event.name }))}&body=${encodeURIComponent(`${t('event:nav.email_body')} https://crab.fit/${event.id}`)}`}>_</a>_</Trans>
|
|
||||||
</p>
|
|
||||||
</Content>
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Page
|
export default Page
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,7 @@ const Login = ({ eventId, user, onChange }: LoginProps) => {
|
||||||
type="text"
|
type="text"
|
||||||
isInline
|
isInline
|
||||||
required
|
required
|
||||||
|
disabled={!eventId}
|
||||||
{...register('username')}
|
{...register('username')}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
@ -85,13 +86,14 @@ const Login = ({ eventId, user, onChange }: LoginProps) => {
|
||||||
label={t('form.password')}
|
label={t('form.password')}
|
||||||
type="password"
|
type="password"
|
||||||
isInline
|
isInline
|
||||||
|
disabled={!eventId}
|
||||||
{...register('password')}
|
{...register('password')}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
disabled={isLoading}
|
disabled={isLoading || !eventId}
|
||||||
>{t('form.button')}</Button>
|
>{t('form.button')}</Button>
|
||||||
</form>
|
</form>
|
||||||
<Error onClose={() => setError(undefined)}>{error}</Error>
|
<Error onClose={() => setError(undefined)}>{error}</Error>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue