feat: recreate form link (layout + create)

This commit is contained in:
Sonny
2024-11-01 19:58:48 +01:00
committed by Sonny
parent 6d568b133f
commit d66e92adbc
5 changed files with 163 additions and 1 deletions

View File

@@ -17,7 +17,7 @@ export default class LinksController {
async showCreatePage({ auth, inertia }: HttpContext) { async showCreatePage({ auth, inertia }: HttpContext) {
const collections = const collections =
await this.collectionsController.getCollectionsByAuthorId(auth.user!.id); await this.collectionsController.getCollectionsByAuthorId(auth.user!.id);
return inertia.render('links/create', { collections }); return inertia.render('mantine/links/create', { collections });
} }
async store({ auth, request, response }: HttpContext) { async store({ auth, request, response }: HttpContext) {

View File

@@ -34,6 +34,7 @@
"description": "Description", "description": "Description",
"visibility": "Visibility", "visibility": "Visibility",
"visibility-warning": "The content will be visible to everyone", "visibility-warning": "The content will be visible to everyone",
"url": "URL",
"create": "Create", "create": "Create",
"update": "Update", "update": "Update",
"delete": "Delete", "delete": "Delete",

View File

@@ -34,6 +34,7 @@
"description": "Description", "description": "Description",
"visibility": "Visibilité", "visibility": "Visibilité",
"visibility-warning": "Le contenu sera visible par tout le monde", "visibility-warning": "Le contenu sera visible par tout le monde",
"url": "URL",
"create": "Créer", "create": "Créer",
"update": "Mettre à jour", "update": "Mettre à jour",
"delete": "Supprimer", "delete": "Supprimer",

View File

@@ -0,0 +1,109 @@
import { Checkbox, Select, TextInput } from '@mantine/core';
import { FormEvent } from 'react';
import { useTranslation } from 'react-i18next';
import BackToDashboard from '~/components/common/navigation/back_to_dashboard';
import useSearchParam from '~/hooks/use_search_param';
import {
FormLayoutProps,
MantineFormLayout,
} from '~/mantine/layouts/mantine_form_layout';
import { Collection } from '~/types/app';
export type FormLinkData = {
name: string;
description: string | null;
url: string;
favorite: boolean;
collectionId: Collection['id'];
};
interface FormLinkProps extends FormLayoutProps {
data: FormLinkData;
errors?: Record<string, Array<string>>;
collections: Collection[];
disableInputs?: boolean;
setData: (name: string, value: any) => void;
handleSubmit: () => void;
}
export default function MantineFormLink({
data,
errors,
collections,
disableInputs = false,
setData,
handleSubmit,
...props
}: FormLinkProps) {
const { t } = useTranslation('common');
const collectionId =
Number(useSearchParam('collectionId')) ?? collections?.[0].id;
const onSubmit = (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();
handleSubmit();
};
return (
<MantineFormLayout
handleSubmit={onSubmit}
collectionId={collectionId}
{...props}
>
<BackToDashboard>
<TextInput
label={t('form.name')}
placeholder={t('form.name')}
onChange={({ target }) => setData('name', target.value)}
value={data.name}
readOnly={disableInputs}
error={errors?.name}
mt="md"
autoFocus
required
/>
<TextInput
label={t('form.url')}
placeholder={t('form.url')}
onChange={({ target }) => setData('url', target.value)}
value={data.url ?? undefined}
readOnly={disableInputs}
error={errors?.link}
mt="md"
required
/>
<TextInput
label={t('form.description')}
placeholder={t('form.description')}
onChange={({ target }) => setData('description', target.value)}
value={data.description ?? undefined}
readOnly={disableInputs}
error={errors?.description}
mt="md"
/>
<Select
label={t('collection.collections')}
placeholder={t('collection.collections')}
data={collections.map(({ id, name }) => ({
label: name,
value: id.toString(),
}))}
onChange={(value) => setData('collectionId', value)}
value={data.collectionId.toString()}
mt="md"
searchable
required
/>
<Checkbox
label={t('favorite')}
onChange={({ target }) => setData('favorite', target.checked)}
checked={data.favorite}
error={errors?.favorite}
disabled={disableInputs}
mt="md"
/>
</BackToDashboard>
</MantineFormLayout>
);
}

View File

@@ -0,0 +1,51 @@
import { useForm } from '@inertiajs/react';
import { route } from '@izzyjs/route/client';
import { useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import useSearchParam from '~/hooks/use_search_param';
import { isValidHttpUrl } from '~/lib/navigation';
import MantineFormLink from '~/mantine/components/form/mantine_form_link';
import { Collection } from '~/types/app';
export default function CreateLinkPage({
collections,
}: {
collections: Collection[];
}) {
const { t } = useTranslation('common');
const collectionId =
Number(useSearchParam('collectionId')) ?? collections[0].id;
const { data, setData, submit, processing } = useForm({
name: '',
description: '',
url: '',
favorite: false,
collectionId,
});
const canSubmit = useMemo<boolean>(
() =>
data.name !== '' &&
isValidHttpUrl(data.url) &&
data.favorite !== null &&
data.collectionId !== null &&
!processing,
[data, processing]
);
const handleSubmit = () => {
const { method, url } = route('link.create');
submit(method, url);
};
return (
<MantineFormLink
title={t('link.create')}
textSubmitButton={t('form.create')}
canSubmit={canSubmit}
data={data}
setData={setData}
handleSubmit={handleSubmit}
collections={collections}
/>
);
}