diff --git a/dashboard/src/app/(inside)/client/create/page.tsx b/dashboard/src/app/(inside)/client/create/page.tsx
index 8b67099..f42fda6 100644
--- a/dashboard/src/app/(inside)/client/create/page.tsx
+++ b/dashboard/src/app/(inside)/client/create/page.tsx
@@ -1,3 +1,6 @@
+import { CreateClientForm } from '@/components/forms/client-form';
+import { createClient } from '@/lib/action/client';
+
export default async function CreateClientPage() {
return (
@@ -7,6 +10,7 @@ export default async function CreateClientPage() {
Configure your new OAuth2 Client.
+
);
}
\ No newline at end of file
diff --git a/dashboard/src/components/forms/client-form.tsx b/dashboard/src/components/forms/client-form.tsx
new file mode 100644
index 0000000..afaca44
--- /dev/null
+++ b/dashboard/src/components/forms/client-form.tsx
@@ -0,0 +1,276 @@
+'use client';
+
+import { z } from 'zod';
+import { clientFormSchema } from '@/lib/forms/client-form';
+import { useForm } from 'react-hook-form';
+import { zodResolver } from '@hookform/resolvers/zod';
+import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from '@/components/ui/form';
+import { Input } from '@/components/ui/input';
+import { Button } from '@/components/ui/button';
+import { kratos } from '@/ory';
+import { useEffect, useState } from 'react';
+import { Identity, OAuth2Client } from '@ory/client';
+import { AxiosResponse } from 'axios';
+import { AlertDialog, AlertDialogContent, AlertDialogHeader, AlertDialogTitle } from '@/components/ui/alert-dialog';
+import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
+import { useRouter } from 'next/navigation';
+import { Checkbox } from '@/components/ui/checkbox';
+
+interface CreateClientFormProps {
+ action: (data: z.infer) => Promise>;
+}
+
+export function CreateClientForm({ action }: CreateClientFormProps) {
+
+ const router = useRouter();
+ const [identity, setIdentity] = useState();
+
+ useEffect(() => {
+ kratos.toSession()
+ .then(response => response.data)
+ .then(session => setIdentity(session.identity));
+ }, []);
+
+ const form = useForm>({
+ resolver: zodResolver(clientFormSchema),
+ defaultValues: {
+ client_name: '',
+ owner: '',
+ scope: '',
+ skip: false,
+ logo_uri: '',
+ policy_uri: '',
+ tos_uri: '',
+ },
+ });
+
+ const [successDialogOpen, setSuccessDialogOpen] = useState(false);
+ const [createdClient, setCreatedClient] = useState();
+ const handleSubmit = async (data: z.infer) => {
+ await action(data)
+ .then((response) => {
+ console.log(response);
+ return response.data;
+ })
+ .then((client) => {
+ setCreatedClient(client);
+ setSuccessDialogOpen(true);
+ })
+ .catch((error) => {
+ console.error(error);
+ });
+ };
+
+ useEffect(() => {
+ form.setValue('owner', identity?.id ?? '');
+ }, [identity]);
+
+ return (
+ <>
+ {
+ createdClient && (
+ setSuccessDialogOpen(false)}>
+
+
+ Client created
+
+ Your client was created successfully. Make sure to safe the client secret!
+
+
+
+ )
+ }
+
+
+ >
+ );
+}
diff --git a/dashboard/src/lib/forms/client-form.ts b/dashboard/src/lib/forms/client-form.ts
new file mode 100644
index 0000000..b11378e
--- /dev/null
+++ b/dashboard/src/lib/forms/client-form.ts
@@ -0,0 +1,12 @@
+import { z } from 'zod';
+
+export const clientFormSchema = z.object({
+ access_token_strategy: z.string().default('opaque').readonly(),
+ client_name: z.string().min(1, 'Client name is required'),
+ owner: z.string().min(1, 'Owner is required'),
+ scope: z.string(),
+ skip: z.boolean(),
+ logo_uri: z.string().url(),
+ tos_uri: z.string().url(),
+ policy_uri: z.string().url(),
+});