diff --git a/src/frontend/src/components/forms/ApiForm.tsx b/src/frontend/src/components/forms/ApiForm.tsx
new file mode 100644
index 0000000000..3279daf85e
--- /dev/null
+++ b/src/frontend/src/components/forms/ApiForm.tsx
@@ -0,0 +1,56 @@
+import { Modal } from '@mantine/core';
+import { useForm } from '@mantine/form';
+
+/* Definition of the ApiForm field component.
+ * - The 'name' attribute *must* be provided
+ * - All other attributes are optional, and may be provided by the API
+ * - However, they can be overridden by the user
+ */
+export type ApiFormField = {
+ name: string;
+ label?: string;
+ value?: any;
+ type?: string;
+ required?: boolean;
+ placeholder?: string;
+ help_text?: string;
+ icon?: string;
+ errors?: string[];
+};
+
+/**
+ * An ApiForm component is a modal form which is rendered dynamically,
+ * based on an API endpoint.
+ * @param url : The API endpoint to fetch the form from.
+ * @param fields : The fields to render in the form.
+ * @param opened : Whether the form is opened or not.
+ * @param onClose : A callback function to call when the form is closed.
+ * @param onFormSuccess : A callback function to call when the form is submitted successfully.
+ * @param onFormError : A callback function to call when the form is submitted with errors.
+ */
+export function ApiForm({
+ url,
+ title,
+ fields,
+ opened,
+ onClose,
+ onFormSuccess,
+ onFormError
+}: {
+ url: string;
+ title: string;
+ fields: ApiFormField[];
+ opened: boolean;
+ onClose?: () => void;
+ onFormSuccess?: () => void;
+ onFormError?: () => void;
+}) {
+ // Form state
+ const form = useForm({});
+
+ return (
+
+ Form data goes here
+
+ );
+}
diff --git a/src/frontend/src/pages/Index/Home.tsx b/src/frontend/src/pages/Index/Home.tsx
index a4d2922345..172b0d3471 100644
--- a/src/frontend/src/pages/Index/Home.tsx
+++ b/src/frontend/src/pages/Index/Home.tsx
@@ -1,10 +1,15 @@
import { Trans } from '@lingui/macro';
import { Group } from '@mantine/core';
+import { Button } from '@mantine/core';
+import { useState } from 'react';
+import { ApiForm } from '../../components/forms/ApiForm';
import { PlaceholderPill } from '../../components/items/Placeholder';
import { StylishText } from '../../components/items/StylishText';
export default function Home() {
+ const [formOpened, setFormOpened] = useState(false);
+
return (
<>
@@ -13,6 +18,19 @@ export default function Home() {
+ setFormOpened(false)}
+ />
+
>
);
}