From ae0fc58569945434182abda2f985383515ca92f0 Mon Sep 17 00:00:00 2001
From: SevicheCC <91365763+Sevichecc@users.noreply.github.com>
Date: Tue, 6 Jun 2023 00:31:36 +0800
Subject: [PATCH] feat: useCreateApp hook
---
app/page.tsx | 37 ++++++++++--
components/DataDisplay.tsx | 43 ++++++++++++++
components/InputForm.tsx | 80 ++++---------------------
components/ScopeItem.tsx | 2 +-
components/ScopeSection.tsx | 7 ++-
components/ui/card.tsx | 79 +++++++++++++++++++++++++
components/ui/table.tsx | 114 ++++++++++++++++++++++++++++++++++++
hooks/useCreateApp.ts | 54 +++++++++++++++++
lib/types.ts | 27 +++++++++
lib/utils.ts | 38 ++++++++++++
10 files changed, 402 insertions(+), 79 deletions(-)
create mode 100644 components/DataDisplay.tsx
create mode 100644 components/ui/card.tsx
create mode 100644 components/ui/table.tsx
create mode 100644 hooks/useCreateApp.ts
create mode 100644 lib/types.ts
diff --git a/app/page.tsx b/app/page.tsx
index 7efde3b..dcb852d 100644
--- a/app/page.tsx
+++ b/app/page.tsx
@@ -1,15 +1,40 @@
import InputForm from "@/components/InputForm";
import ClientOnly from "@/components/ClientOnly";
+import {
+ Card,
+ CardContent,
+ CardDescription,
+ CardFooter,
+ CardHeader,
+ CardTitle,
+} from "@/components/ui/card";
+import DataDisplay from "@/components/DataDisplay";
export default function Home() {
return (
-
- M-OAuth
-
-
-
-
+
+
+
+ M-OAuth
+ Card Description
+
+
+
+
+
+
+
+ {/*
+ Card Footer
+ */}
+
+
+
+
+
+
+
);
}
diff --git a/components/DataDisplay.tsx b/components/DataDisplay.tsx
new file mode 100644
index 0000000..c752519
--- /dev/null
+++ b/components/DataDisplay.tsx
@@ -0,0 +1,43 @@
+'use client'
+
+import useCreateApp from "@/hooks/useCreateApp";
+import { Table, TableBody, TableCaption, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
+import { AppEntry } from "../lib/types";
+
+interface DataDisplayProps {
+ appEntry: AppEntry;
+}
+
+const renderTableRow = (label: string, value: string | undefined) => (
+
+ {label}
+ {value}
+
+);
+
+const DataDisplay = () => {
+ const { appEntry } = useCreateApp();
+
+ return (
+
+ A list of your recent invoices.
+
+
+ Data Name
+ Value
+
+
+
+ {renderTableRow("ID", appEntry?.id)}
+ {renderTableRow("Name", appEntry?.name)}
+ {renderTableRow("Website", appEntry?.website || '')}
+ {renderTableRow("Redirect URI", appEntry?.redirectUri)}
+ {renderTableRow("Client ID", appEntry?.clientId)}
+ {renderTableRow("Client Secret", appEntry?.clientSecret)}
+ {renderTableRow("Vapid Key", appEntry?.vapidKey)}
+
+
+ );
+};
+
+export default DataDisplay;
diff --git a/components/InputForm.tsx b/components/InputForm.tsx
index cd7f782..2ea5c1a 100644
--- a/components/InputForm.tsx
+++ b/components/InputForm.tsx
@@ -1,10 +1,10 @@
"use client";
-
import * as z from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import { Button } from "@/components/ui/button";
+import { Input } from "@/components/ui/input";
import {
Form,
FormControl,
@@ -14,66 +14,10 @@ import {
FormLabel,
FormMessage,
} from "@/components/ui/form";
-import { Input } from "@/components/ui/input";
-import {
- READ_SCOPES,
- WRITE_SCOPES,
- ADMIN_READ_SCOPES,
- ADMIN_WRITE_SCOPES,
-} from "@/lib/utils";
-import ScopeSection from "./ScopeSection";
-export type MethodType =
- | "read"
- | "write"
- | "follow"
- | "crypto"
- | "follow"
- | "admin"
- | "push";
-export interface ScopeInfo {
- method: MethodType;
- label: string;
- scopes?: string[] | string[][];
- description: string;
-}
-
-const scopesInfo: ScopeInfo[] = [
- {
- method: "read",
- label: "Read",
- scopes: READ_SCOPES,
- description: "read account's data",
- },
- {
- method: "write",
- label: "Write",
- scopes: WRITE_SCOPES,
- description: "modify account's data",
- },
- {
- method: "admin",
- label: "Admin",
- scopes: [ADMIN_READ_SCOPES, ADMIN_WRITE_SCOPES],
- description: "read all data on the server",
- },
- {
- method: "follow",
- label: "Follow",
- description: "modify account relationships,deprecated in 3.5.0 and newer.",
- },
- {
- method: "push",
- label: "Push",
- description: "receive push notifications",
- },
-
- {
- method: "crypto",
- label: "Crypto",
- description: "use end-to-end encryption",
- },
-];
+import ScopeSection from "@/components/ScopeSection";
+import { scopesInfo } from "@/lib/utils";
+import useCreateApp from "@/hooks/useCreateApp";
const formSchema = z.object({
instance: z.string().trim(),
@@ -83,25 +27,23 @@ const formSchema = z.object({
website: z.string().url().trim().optional(),
});
+export type FormSchema = z.infer;
+
const InputForm = () => {
- const form = useForm>({
+ const { createApp } = useCreateApp();
+ const form = useForm({
resolver: zodResolver(formSchema),
defaultValues: {
instance: "https://",
clientName: "",
redirectUris: "",
- scopes: [],
+ scopes: ["read"],
},
});
- function onSubmit(values: z.infer) {
- const scopes = values.scopes?.join(" ");
- console.log(scopes);
- }
-
return (
);
diff --git a/components/ScopeItem.tsx b/components/ScopeItem.tsx
index 0bc7f8c..1c7ac81 100644
--- a/components/ScopeItem.tsx
+++ b/components/ScopeItem.tsx
@@ -1,7 +1,7 @@
"use client";
-import { MethodType } from "./InputForm";
import { Checkbox } from "@/components/ui/checkbox";
+import { MethodType } from "@/lib/types";
interface ScopeCheckboxProps {
scope: string;
diff --git a/components/ScopeSection.tsx b/components/ScopeSection.tsx
index 70f2a14..b124ef5 100644
--- a/components/ScopeSection.tsx
+++ b/components/ScopeSection.tsx
@@ -1,5 +1,6 @@
"use client";
+import { ChevronsUpDown } from "lucide-react";
import { Checkbox } from "@/components/ui/checkbox";
import {
Collapsible,
@@ -7,10 +8,10 @@ import {
CollapsibleTrigger,
} from "@/components/ui/collapsible";
import { Button } from "@/components/ui/button";
-import { ChevronsUpDown } from "lucide-react";
+import ScopeItem from "@/components/ScopeItem";
+
+import { ScopeInfo } from "@/lib/types";
-import { ScopeInfo } from "./InputForm";
-import ScopeItem from "./ScopeItem";
interface ScopeSectionProps {
info: ScopeInfo;
field: any;
diff --git a/components/ui/card.tsx b/components/ui/card.tsx
new file mode 100644
index 0000000..dff04b6
--- /dev/null
+++ b/components/ui/card.tsx
@@ -0,0 +1,79 @@
+import * as React from "react"
+
+import { cn } from "@/lib/utils"
+
+const Card = React.forwardRef<
+ HTMLDivElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+))
+Card.displayName = "Card"
+
+const CardHeader = React.forwardRef<
+ HTMLDivElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+))
+CardHeader.displayName = "CardHeader"
+
+const CardTitle = React.forwardRef<
+ HTMLParagraphElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+))
+CardTitle.displayName = "CardTitle"
+
+const CardDescription = React.forwardRef<
+ HTMLParagraphElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+))
+CardDescription.displayName = "CardDescription"
+
+const CardContent = React.forwardRef<
+ HTMLDivElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+))
+CardContent.displayName = "CardContent"
+
+const CardFooter = React.forwardRef<
+ HTMLDivElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+))
+CardFooter.displayName = "CardFooter"
+
+export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
diff --git a/components/ui/table.tsx b/components/ui/table.tsx
new file mode 100644
index 0000000..bb3a87f
--- /dev/null
+++ b/components/ui/table.tsx
@@ -0,0 +1,114 @@
+import * as React from "react"
+
+import { cn } from "@/lib/utils"
+
+const Table = React.forwardRef<
+ HTMLTableElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+))
+Table.displayName = "Table"
+
+const TableHeader = React.forwardRef<
+ HTMLTableSectionElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+))
+TableHeader.displayName = "TableHeader"
+
+const TableBody = React.forwardRef<
+ HTMLTableSectionElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+))
+TableBody.displayName = "TableBody"
+
+const TableFooter = React.forwardRef<
+ HTMLTableSectionElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+))
+TableFooter.displayName = "TableFooter"
+
+const TableRow = React.forwardRef<
+ HTMLTableRowElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+))
+TableRow.displayName = "TableRow"
+
+const TableHead = React.forwardRef<
+ HTMLTableCellElement,
+ React.ThHTMLAttributes
+>(({ className, ...props }, ref) => (
+ |
+))
+TableHead.displayName = "TableHead"
+
+const TableCell = React.forwardRef<
+ HTMLTableCellElement,
+ React.TdHTMLAttributes
+>(({ className, ...props }, ref) => (
+ |
+))
+TableCell.displayName = "TableCell"
+
+const TableCaption = React.forwardRef<
+ HTMLTableCaptionElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+))
+TableCaption.displayName = "TableCaption"
+
+export {
+ Table,
+ TableHeader,
+ TableBody,
+ TableFooter,
+ TableHead,
+ TableRow,
+ TableCell,
+ TableCaption,
+}
diff --git a/hooks/useCreateApp.ts b/hooks/useCreateApp.ts
new file mode 100644
index 0000000..9ed10d6
--- /dev/null
+++ b/hooks/useCreateApp.ts
@@ -0,0 +1,54 @@
+import { FormSchema } from "@/components/InputForm";
+import { useCallback, useState } from "react";
+import { AppEntry } from "@/lib/types";
+
+type MError = {
+ error: string;
+};
+
+const useCreateApp = () => {
+ const [appEntry, setAppEntry] = useState();
+
+ const createApp = useCallback(
+ async ({
+ instance,
+ website,
+ clientName,
+ redirectUris,
+ scopes,
+ }: FormSchema) => {
+ const app = {
+ website,
+ client_name: clientName,
+ redirect_uris: redirectUris,
+ scopes: scopes?.join(" "),
+ };
+
+ console.log("app,", app);
+ try {
+ let request = await fetch(`${instance}/api/v1/apps`, {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify(app),
+ });
+
+ if (!request.ok || request.status === 424) {
+ throw new Error((await request.json()).error);
+ }
+ setAppEntry(await request.json());
+ } catch (error) {
+ throw new Error((error as MError).error);
+ }
+ },
+ []
+ );
+ console.log(appEntry);
+ return {
+ appEntry,
+ createApp,
+ };
+};
+
+export default useCreateApp;
diff --git a/lib/types.ts b/lib/types.ts
new file mode 100644
index 0000000..e98d67d
--- /dev/null
+++ b/lib/types.ts
@@ -0,0 +1,27 @@
+export type MethodType =
+ | "read"
+ | "write"
+ | "follow"
+ | "crypto"
+ | "follow"
+ | "admin"
+ | "push";
+
+export interface ScopeInfo {
+ method: MethodType;
+ label: string;
+ scopes?: string[] | string[][];
+ description: string;
+}
+
+ export interface AppEntry {
+ id: string;
+ name: string;
+ website: string | null;
+ redirectUri: string;
+ clientId: string;
+ clientSecret: string;
+ vapidKey: string;
+ }
+
+
\ No newline at end of file
diff --git a/lib/utils.ts b/lib/utils.ts
index b95e62c..cb8928c 100644
--- a/lib/utils.ts
+++ b/lib/utils.ts
@@ -1,5 +1,6 @@
import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";
+import { ScopeInfo } from "./types";
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
@@ -53,3 +54,40 @@ export const ADMIN_WRITE_SCOPES = [
"admin:write:email_domain_blocks",
"admin:write:canonical_email_blocks",
];
+
+export const scopesInfo: ScopeInfo[] = [
+ {
+ method: "read",
+ label: "Read",
+ scopes: READ_SCOPES,
+ description: "read account's data",
+ },
+ {
+ method: "write",
+ label: "Write",
+ scopes: WRITE_SCOPES,
+ description: "modify account's data",
+ },
+ {
+ method: "admin",
+ label: "Admin",
+ scopes: [ADMIN_READ_SCOPES, ADMIN_WRITE_SCOPES],
+ description: "read all data on the server",
+ },
+ {
+ method: "follow",
+ label: "Follow",
+ description: "modify account relationships,deprecated in 3.5.0 and newer.",
+ },
+ {
+ method: "push",
+ label: "Push",
+ description: "receive push notifications",
+ },
+
+ {
+ method: "crypto",
+ label: "Crypto",
+ description: "use end-to-end encryption",
+ },
+];