diff --git a/src/App.tsx b/src/App.tsx index ae998d6..edee26e 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,6 +2,7 @@ import { createBrowserRouter, RouterProvider } from 'react-router-dom'; import { Notifications } from './components/Notifications'; import { Home } from './pages/Home'; import { MainLayout } from './pages/MainLayout'; +import { NewScheme } from './pages/NewScheme'; import { Schemes } from './pages/Schemes'; const routes = createBrowserRouter([ @@ -10,7 +11,11 @@ const routes = createBrowserRouter([ element: , children: [ { index: true, element: }, - { path: 'schemes', element: }, + { + path: 'schemes', + element: , + children: [{ path: 'new', element: }], + }, ], }, ]); diff --git a/src/pages/NewScheme.module.css b/src/pages/NewScheme.module.css new file mode 100644 index 0000000..c9aecb6 --- /dev/null +++ b/src/pages/NewScheme.module.css @@ -0,0 +1,28 @@ +@layer pages { + .create_scheme_form_layout { + width: 100%; + padding: calc(var(--spacing) * 10) calc(var(--spacing) * 8); + display: flex; + flex-direction: column; + gap: calc(var(--spacing) * 6); + .form_row { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: var(--spacing-xxs); + label { + font-size: var(--font-size-xs); + } + .name_input { + min-width: 20em; + } + .description_input { + min-width: 50em; + } + .error_message { + color: var(--color-danger); + font-size: var(--font-size-xs); + } + } + } +} diff --git a/src/pages/NewScheme.tsx b/src/pages/NewScheme.tsx new file mode 100644 index 0000000..5ccfd97 --- /dev/null +++ b/src/pages/NewScheme.tsx @@ -0,0 +1,46 @@ +import cx from 'clsx'; +import { isEmpty, isNil } from 'lodash-es'; +import { useActionState } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { useCreateScheme } from '../stores/schemes'; +import styles from './NewScheme.module.css'; + +export function NewScheme() { + const createScheme = useCreateScheme(); + const navigate = useNavigate(); + const [errors, formAction] = useActionState((prevState, formData) => { + try { + const name = formData.get('name') as string; + if (isNil(name) || isEmpty(name)) { + throw { name: 'Name is required' }; + } + const description = (formData.get('description') ?? null) as string | null; + const newId = createScheme(name, description); + navigate(`../${newId}`); + } catch (error) { + return error; + } + return {}; + }, {}); + + return ( +
+
+ + + {errors.name &&
{errors.name}
} +
+
+ +