mirror of
https://github.com/Sonny93/my-links.git
synced 2025-12-09 15:05:35 +00:00
feat: recreate form link (layout + create)
This commit is contained in:
@@ -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) {
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
109
inertia/mantine/components/form/mantine_form_link.tsx
Normal file
109
inertia/mantine/components/form/mantine_form_link.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
}
|
||||||
51
inertia/pages/mantine/links/create.tsx
Normal file
51
inertia/pages/mantine/links/create.tsx
Normal 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}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user