feat: add loader

This commit is contained in:
SevicheCC 2023-06-07 17:50:50 +08:00
parent 409f35734a
commit 350fecc996
Signed by: SevicheCC
GPG key ID: C577000000000000
3 changed files with 37 additions and 19 deletions

View file

@ -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;

View file

@ -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 && (

View file

@ -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 ({