mirror of
https://github.com/Sevichecc/m-oauth.git
synced 2025-05-29 00:49:13 +08:00
feat: add loader
This commit is contained in:
parent
409f35734a
commit
350fecc996
3 changed files with 37 additions and 19 deletions
|
@ -1,7 +1,9 @@
|
||||||
"use client";
|
"use client";
|
||||||
import * as z from "zod";
|
import * as z from "zod";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { Dispatch, SetStateAction, useState } from "react";
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import { Loader2 } from "lucide-react";
|
||||||
|
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
|
@ -14,11 +16,11 @@ import {
|
||||||
FormLabel,
|
FormLabel,
|
||||||
FormMessage,
|
FormMessage,
|
||||||
} from "@/components/ui/form";
|
} from "@/components/ui/form";
|
||||||
|
|
||||||
import ScopeSection from "@/components/scopes/ScopeSection";
|
import ScopeSection from "@/components/scopes/ScopeSection";
|
||||||
|
import { AppInfo } from "@/components/FormContainer";
|
||||||
|
|
||||||
import { scopesInfo } from "@/lib/scopes";
|
import { scopesInfo } from "@/lib/scopes";
|
||||||
import { Dispatch, SetStateAction } from "react";
|
import { Credentials } from "@/lib/types";
|
||||||
import { AppInfo } from "./FormContainer";
|
|
||||||
|
|
||||||
const formSchema = z.object({
|
const formSchema = z.object({
|
||||||
instanceUrl: z.string().url().trim(),
|
instanceUrl: z.string().url().trim(),
|
||||||
|
@ -29,12 +31,18 @@ const formSchema = z.object({
|
||||||
});
|
});
|
||||||
|
|
||||||
export type FormSchema = z.infer<typeof formSchema>;
|
export type FormSchema = z.infer<typeof formSchema>;
|
||||||
interface InputFormProps {
|
interface CreateAppFormProps {
|
||||||
createApp: ({}: FormSchema) => Promise<void>;
|
createApp: ({}: FormSchema) => Promise<void>;
|
||||||
setAppInfo: Dispatch<SetStateAction<AppInfo>>;
|
setAppInfo: Dispatch<SetStateAction<AppInfo>>;
|
||||||
|
credentials: Credentials | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
const InputForm: React.FC<InputFormProps> = ({ createApp, setAppInfo }) => {
|
const CreateAppForm: React.FC<CreateAppFormProps> = ({
|
||||||
|
createApp,
|
||||||
|
setAppInfo,
|
||||||
|
credentials,
|
||||||
|
}) => {
|
||||||
|
const [isSubmitted, setIsSubmitted] = useState(false);
|
||||||
const form = useForm<FormSchema>({
|
const form = useForm<FormSchema>({
|
||||||
resolver: zodResolver(formSchema),
|
resolver: zodResolver(formSchema),
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
|
@ -42,11 +50,13 @@ const InputForm: React.FC<InputFormProps> = ({ createApp, setAppInfo }) => {
|
||||||
clientName: "",
|
clientName: "",
|
||||||
redirectUris: "urn:ietf:wg:oauth:2.0:oob",
|
redirectUris: "urn:ietf:wg:oauth:2.0:oob",
|
||||||
scopes: ["read"],
|
scopes: ["read"],
|
||||||
|
website: ""
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const onSubmit = async (values: FormSchema) => {
|
const onSubmit = async (values: FormSchema) => {
|
||||||
setAppInfo(values);
|
setAppInfo(values);
|
||||||
|
setIsSubmitted(true);
|
||||||
await createApp(values);
|
await createApp(values);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -115,7 +125,7 @@ const InputForm: React.FC<InputFormProps> = ({ createApp, setAppInfo }) => {
|
||||||
<code className="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-xs font-semibold">
|
<code className="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-xs font-semibold">
|
||||||
urn:ietf:wg:oauth:2.0:oob
|
urn:ietf:wg:oauth:2.0:oob
|
||||||
</code>{" "}
|
</code>{" "}
|
||||||
for local tests or for getting access token
|
for local tests or to obtaining an access token.
|
||||||
</FormDescription>
|
</FormDescription>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
@ -150,11 +160,19 @@ const InputForm: React.FC<InputFormProps> = ({ createApp, setAppInfo }) => {
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<Button type="submit" className="w-ful">
|
|
||||||
Submit
|
{!credentials && isSubmitted ? (
|
||||||
</Button>
|
<Button disabled className="w-ful">
|
||||||
|
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
||||||
|
Please wait
|
||||||
|
</Button>
|
||||||
|
) : (
|
||||||
|
<Button type="submit" className="w-ful">
|
||||||
|
Submit
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
</form>
|
</form>
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
export default InputForm;
|
export default CreateAppForm;
|
|
@ -1,6 +1,7 @@
|
||||||
"use client";
|
"use client";
|
||||||
import { useState, useEffect, useRef } from "react";
|
|
||||||
import InputForm from "@/components/InputForm";
|
import { useState } from "react";
|
||||||
|
import CreateAppForm from "@/components/CreatAppForm";
|
||||||
import ResultTable from "@/components/tables/ResultTable";
|
import ResultTable from "@/components/tables/ResultTable";
|
||||||
import useCreateApp from "@/hooks/useCreateApp";
|
import useCreateApp from "@/hooks/useCreateApp";
|
||||||
import {
|
import {
|
||||||
|
@ -10,7 +11,7 @@ import {
|
||||||
CardHeader,
|
CardHeader,
|
||||||
CardTitle,
|
CardTitle,
|
||||||
} from "@/components/ui/card";
|
} from "@/components/ui/card";
|
||||||
import { FormSchema } from "@/components/InputForm";
|
import { FormSchema } from "@/components/CreatAppForm";
|
||||||
|
|
||||||
export type AppInfo = Pick<FormSchema, "instanceUrl" | "scopes">;
|
export type AppInfo = Pick<FormSchema, "instanceUrl" | "scopes">;
|
||||||
|
|
||||||
|
@ -22,7 +23,6 @@ const FormContainer = () => {
|
||||||
scopes: [""],
|
scopes: [""],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Card className="mt-5">
|
<Card className="mt-5">
|
||||||
|
@ -31,7 +31,7 @@ const FormContainer = () => {
|
||||||
<CardDescription>Card Description</CardDescription>
|
<CardDescription>Card Description</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<InputForm createApp={createApp} setAppInfo={setAppInfo} />
|
<CreateAppForm createApp={createApp} setAppInfo={setAppInfo} credentials={credentials}/>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
{credentials && (
|
{credentials && (
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { FormSchema } from "@/components/InputForm";
|
import { FormSchema } from "@/components/CreatAppForm";
|
||||||
import { useCallback, useState } from "react";
|
import { useCallback, useState } from "react";
|
||||||
import { AppEntry, MError } from "@/lib/types";
|
import { Credentials, MError } from "@/lib/types";
|
||||||
|
|
||||||
const useCreateApp = () => {
|
const useCreateApp = () => {
|
||||||
const [credentials, setCredentials] = useState<AppEntry>();
|
const [credentials, setCredentials] = useState<Credentials>();
|
||||||
|
|
||||||
const createApp = useCallback(
|
const createApp = useCallback(
|
||||||
async ({
|
async ({
|
||||||
|
|
Loading…
Reference in a new issue