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 (
+
+ );
+}