Spaces:
Sleeping
Sleeping
Esteves Enzo
commited on
Commit
•
6294700
1
Parent(s):
cf5de83
GET methods are working. WIP
Browse files- app/[type]/[index]/page.tsx +8 -5
- components/editor/header.tsx +1 -1
- components/editor/index.tsx +10 -17
- components/editor/main/endpoint.tsx +11 -0
- components/editor/main/hooks/useRequest.ts +4 -1
- components/editor/main/index.tsx +3 -24
- components/editor/main/request.tsx +11 -13
- components/editor/main/response.tsx +2 -2
- components/editor/sidebar.tsx +4 -7
- components/input/input.tsx +38 -0
- components/input/toggle.tsx +53 -0
- components/loading/index.tsx +1 -1
- utils/axios.ts +5 -1
- utils/datas/api_collections.ts +76 -40
app/[type]/[index]/page.tsx
CHANGED
@@ -1,13 +1,16 @@
|
|
|
|
|
|
|
|
1 |
export default async function RouteAPI({
|
2 |
params: { index, type },
|
3 |
}: {
|
4 |
params: { index: string; type: string };
|
5 |
}) {
|
|
|
|
|
|
|
|
|
6 |
return (
|
7 |
-
<div>
|
8 |
-
<p className="text-white">
|
9 |
-
Number is: {index}. Type is {type}
|
10 |
-
</p>
|
11 |
-
</div>
|
12 |
);
|
13 |
}
|
|
|
1 |
+
import { EditorMain } from "@/components/editor/main";
|
2 |
+
import { API_COLLECTIONS } from "@/utils/datas/api_collections";
|
3 |
+
|
4 |
export default async function RouteAPI({
|
5 |
params: { index, type },
|
6 |
}: {
|
7 |
params: { index: string; type: string };
|
8 |
}) {
|
9 |
+
const endpoint = API_COLLECTIONS.find((col) => col.key === type)?.endpoints[
|
10 |
+
parseInt(index)
|
11 |
+
];
|
12 |
+
|
13 |
return (
|
14 |
+
<>{endpoint ? <EditorMain endpoint={endpoint} /> : <div>Not found</div>}</>
|
|
|
|
|
|
|
|
|
15 |
);
|
16 |
}
|
components/editor/header.tsx
CHANGED
@@ -6,7 +6,7 @@ export const EditorHeader = () => {
|
|
6 |
<header className="px-6 py-2.5 border border-slate-950 bg-slate-950 flex justify-between items-center">
|
7 |
<Image src={HFLogo} alt="Hugging Face Logo" width={34} height={34} />
|
8 |
<p className="text-gray-300 font-code text-sm font-semibold">
|
9 |
-
Hugging Face API
|
10 |
</p>
|
11 |
<div className="flex items-center justify-end gap-3">
|
12 |
<div className="bg-teal-600 w-3 h-3 rounded-full" />
|
|
|
6 |
<header className="px-6 py-2.5 border border-slate-950 bg-slate-950 flex justify-between items-center">
|
7 |
<Image src={HFLogo} alt="Hugging Face Logo" width={34} height={34} />
|
8 |
<p className="text-gray-300 font-code text-sm font-semibold">
|
9 |
+
Hugging Face Client REST API
|
10 |
</p>
|
11 |
<div className="flex items-center justify-end gap-3">
|
12 |
<div className="bg-teal-600 w-3 h-3 rounded-full" />
|
components/editor/index.tsx
CHANGED
@@ -1,17 +1,20 @@
|
|
1 |
"use client";
|
2 |
import { useState } from "react";
|
|
|
3 |
|
4 |
import { EditorHeader } from "./header";
|
5 |
import { EditorSidebar } from "./sidebar";
|
6 |
-
import {
|
7 |
-
import { ApiRoute } from "@/utils/type";
|
8 |
-
import { API_COLLECTIONS } from "@/utils/datas/api_collections";
|
9 |
|
10 |
export const Editor = ({ children }: any) => {
|
11 |
-
const [collections, setCollections] = useState<string[]>([
|
12 |
-
const
|
13 |
-
|
14 |
-
)
|
|
|
|
|
|
|
|
|
15 |
|
16 |
return (
|
17 |
<div className="bg-slate-950 w-full overflow-hidden shadow-xl h-[100vh]">
|
@@ -19,18 +22,8 @@ export const Editor = ({ children }: any) => {
|
|
19 |
<main className="flex h-full">
|
20 |
<EditorSidebar
|
21 |
collections={collections}
|
22 |
-
endpoint={endpoint}
|
23 |
onCollections={setCollections}
|
24 |
-
onEndpoint={setEndpoint}
|
25 |
/>
|
26 |
-
{/* {endpoint && (
|
27 |
-
<EditorMain
|
28 |
-
collections={collections}
|
29 |
-
endpoint={endpoint}
|
30 |
-
onCollections={setCollections}
|
31 |
-
onEndpoint={setEndpoint}
|
32 |
-
/>
|
33 |
-
)} */}
|
34 |
{children}
|
35 |
</main>
|
36 |
</div>
|
|
|
1 |
"use client";
|
2 |
import { useState } from "react";
|
3 |
+
import { useMount } from "react-use";
|
4 |
|
5 |
import { EditorHeader } from "./header";
|
6 |
import { EditorSidebar } from "./sidebar";
|
7 |
+
import { usePathname } from "next/navigation";
|
|
|
|
|
8 |
|
9 |
export const Editor = ({ children }: any) => {
|
10 |
+
const [collections, setCollections] = useState<string[]>([]);
|
11 |
+
const pathname = usePathname();
|
12 |
+
|
13 |
+
useMount(() => {
|
14 |
+
if (!pathname || pathname === "/") setCollections(["search"]);
|
15 |
+
const firstPath = pathname.split("/")[1];
|
16 |
+
if (firstPath) setCollections([firstPath]);
|
17 |
+
});
|
18 |
|
19 |
return (
|
20 |
<div className="bg-slate-950 w-full overflow-hidden shadow-xl h-[100vh]">
|
|
|
22 |
<main className="flex h-full">
|
23 |
<EditorSidebar
|
24 |
collections={collections}
|
|
|
25 |
onCollections={setCollections}
|
|
|
26 |
/>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
{children}
|
28 |
</main>
|
29 |
</div>
|
components/editor/main/endpoint.tsx
CHANGED
@@ -8,15 +8,23 @@ import { ApiRoute } from "@/utils/type";
|
|
8 |
export const Endpoint = ({
|
9 |
endpoint,
|
10 |
children,
|
|
|
11 |
}: {
|
12 |
endpoint: ApiRoute;
|
13 |
children: React.ReactElement;
|
|
|
14 |
}) => {
|
15 |
const path_formatted = useMemo(
|
16 |
() => splitStringBracket(endpoint.path),
|
17 |
[endpoint.path]
|
18 |
);
|
19 |
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
return (
|
21 |
<div className="bg-slate-900 w-full">
|
22 |
<div className="bg-slate-950/50 p-3 rounded-lg flex items-center justify-between">
|
@@ -34,6 +42,9 @@ export const Endpoint = ({
|
|
34 |
"text-slate-300": !isCustomizable,
|
35 |
})}
|
36 |
contentEditable={isCustomizable}
|
|
|
|
|
|
|
37 |
>
|
38 |
{p}
|
39 |
</p>
|
|
|
8 |
export const Endpoint = ({
|
9 |
endpoint,
|
10 |
children,
|
11 |
+
onChange,
|
12 |
}: {
|
13 |
endpoint: ApiRoute;
|
14 |
children: React.ReactElement;
|
15 |
+
onChange: (value: string) => void;
|
16 |
}) => {
|
17 |
const path_formatted = useMemo(
|
18 |
() => splitStringBracket(endpoint.path),
|
19 |
[endpoint.path]
|
20 |
);
|
21 |
|
22 |
+
const handleChange = (value: string, index: number) => {
|
23 |
+
const currentString = splitStringBracket(endpoint.path);
|
24 |
+
currentString[index] = value;
|
25 |
+
onChange(currentString.join(""));
|
26 |
+
};
|
27 |
+
|
28 |
return (
|
29 |
<div className="bg-slate-900 w-full">
|
30 |
<div className="bg-slate-950/50 p-3 rounded-lg flex items-center justify-between">
|
|
|
42 |
"text-slate-300": !isCustomizable,
|
43 |
})}
|
44 |
contentEditable={isCustomizable}
|
45 |
+
onBlur={(e) => {
|
46 |
+
handleChange(e.currentTarget.textContent as string, i);
|
47 |
+
}}
|
48 |
>
|
49 |
{p}
|
50 |
</p>
|
components/editor/main/hooks/useRequest.ts
CHANGED
@@ -9,6 +9,7 @@ export const useRequest = (endpoint: string, params: any) => {
|
|
9 |
|
10 |
const submit = async () => {
|
11 |
setLoading(true);
|
|
|
12 |
const url = new URL(endpoint, process.env.NEXT_PUBLIC_APP_APIURL);
|
13 |
if (params) {
|
14 |
const parameters = Object.entries(params).filter(
|
@@ -28,11 +29,13 @@ export const useRequest = (endpoint: string, params: any) => {
|
|
28 |
params: url.searchParams,
|
29 |
})
|
30 |
.then((res: any) => {
|
31 |
-
console.log("res ", res);
|
32 |
if (res.ok) {
|
33 |
setData(res.data);
|
34 |
}
|
35 |
})
|
|
|
|
|
|
|
36 |
.finally(() => setLoading(false));
|
37 |
};
|
38 |
|
|
|
9 |
|
10 |
const submit = async () => {
|
11 |
setLoading(true);
|
12 |
+
console.log(endpoint)
|
13 |
const url = new URL(endpoint, process.env.NEXT_PUBLIC_APP_APIURL);
|
14 |
if (params) {
|
15 |
const parameters = Object.entries(params).filter(
|
|
|
29 |
params: url.searchParams,
|
30 |
})
|
31 |
.then((res: any) => {
|
|
|
32 |
if (res.ok) {
|
33 |
setData(res.data);
|
34 |
}
|
35 |
})
|
36 |
+
.catch((err) => {
|
37 |
+
setData(err.data);
|
38 |
+
})
|
39 |
.finally(() => setLoading(false));
|
40 |
};
|
41 |
|
components/editor/main/index.tsx
CHANGED
@@ -1,3 +1,4 @@
|
|
|
|
1 |
import { useState } from "react";
|
2 |
|
3 |
import { ApiRoute } from "@/utils/type";
|
@@ -9,17 +10,7 @@ import { Response } from "./response";
|
|
9 |
import { useRequest } from "./hooks/useRequest";
|
10 |
import { useMount, useUpdateEffect } from "react-use";
|
11 |
|
12 |
-
export const EditorMain = ({
|
13 |
-
collections,
|
14 |
-
endpoint,
|
15 |
-
onCollections,
|
16 |
-
onEndpoint,
|
17 |
-
}: {
|
18 |
-
collections: string[];
|
19 |
-
endpoint: ApiRoute;
|
20 |
-
onCollections: (collections: string[]) => void;
|
21 |
-
onEndpoint: (endpoint: ApiRoute) => void;
|
22 |
-
}) => {
|
23 |
const [formattedEndpoint, setFormattedEndpoint] = useState<string>(
|
24 |
endpoint.path
|
25 |
);
|
@@ -42,18 +33,6 @@ export const EditorMain = ({
|
|
42 |
}
|
43 |
});
|
44 |
|
45 |
-
useUpdateEffect(() => {
|
46 |
-
if (endpoint?.path) {
|
47 |
-
setFormattedEndpoint(endpoint.path);
|
48 |
-
}
|
49 |
-
}, [endpoint.path]);
|
50 |
-
|
51 |
-
useUpdateEffect(() => {
|
52 |
-
if (endpoint?.parameters) {
|
53 |
-
setFormattedParameters(endpoint.parameters);
|
54 |
-
}
|
55 |
-
}, [endpoint.parameters]);
|
56 |
-
|
57 |
return (
|
58 |
<div className="flex-1 bg-slate-900/50 h-[calc(100%-56px)]">
|
59 |
<div className="h-full grid grid-cols-2">
|
@@ -66,7 +45,7 @@ export const EditorMain = ({
|
|
66 |
});
|
67 |
}}
|
68 |
>
|
69 |
-
<Endpoint endpoint={endpoint}>
|
70 |
<button
|
71 |
className="bg-indigo-500 hover:bg-indigo-500/80 text-white px-3 py-1 rounded-lg text-sm"
|
72 |
onClick={submit}
|
|
|
1 |
+
"use client";
|
2 |
import { useState } from "react";
|
3 |
|
4 |
import { ApiRoute } from "@/utils/type";
|
|
|
10 |
import { useRequest } from "./hooks/useRequest";
|
11 |
import { useMount, useUpdateEffect } from "react-use";
|
12 |
|
13 |
+
export const EditorMain = ({ endpoint }: { endpoint: ApiRoute }) => {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
const [formattedEndpoint, setFormattedEndpoint] = useState<string>(
|
15 |
endpoint.path
|
16 |
);
|
|
|
33 |
}
|
34 |
});
|
35 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
36 |
return (
|
37 |
<div className="flex-1 bg-slate-900/50 h-[calc(100%-56px)]">
|
38 |
<div className="h-full grid grid-cols-2">
|
|
|
45 |
});
|
46 |
}}
|
47 |
>
|
48 |
+
<Endpoint endpoint={endpoint} onChange={setFormattedEndpoint}>
|
49 |
<button
|
50 |
className="bg-indigo-500 hover:bg-indigo-500/80 text-white px-3 py-1 rounded-lg text-sm"
|
51 |
onClick={submit}
|
components/editor/main/request.tsx
CHANGED
@@ -1,3 +1,5 @@
|
|
|
|
|
|
1 |
import { ApiRoute } from "@/utils/type";
|
2 |
|
3 |
export const Request = ({
|
@@ -10,11 +12,11 @@ export const Request = ({
|
|
10 |
onChange: (key: string, value: string | boolean) => void;
|
11 |
}) => {
|
12 |
return (
|
13 |
-
<div className="h-full bg-slate-900 p-
|
14 |
{children}
|
15 |
{parameters && (
|
16 |
-
<div className="mt-6 grid grid-cols-
|
17 |
-
<p className="text-slate-
|
18 |
Optional parameters
|
19 |
</p>
|
20 |
{parameters &&
|
@@ -23,24 +25,20 @@ export const Request = ({
|
|
23 |
key={key}
|
24 |
className="flex items-center justify-between gap-2"
|
25 |
>
|
26 |
-
<p className="text-slate-300 text-sm">{key}</p>
|
27 |
{typeof value === "boolean" ? (
|
28 |
<div>
|
29 |
-
<
|
30 |
-
type="checkbox"
|
31 |
checked={value}
|
32 |
-
|
33 |
-
|
34 |
-
}
|
35 |
/>
|
36 |
</div>
|
37 |
) : (
|
38 |
-
<
|
39 |
value={value as string}
|
40 |
-
|
41 |
-
className="bg-slate-950/50 w-full rounded-md px-2 py-1 text-slate-100 outline-none placeholder:text-slate-600"
|
42 |
placeholder="value"
|
43 |
-
onChange={(e) => onChange(key, e
|
44 |
/>
|
45 |
)}
|
46 |
</div>
|
|
|
1 |
+
import { Toggle } from "@/components/input/toggle";
|
2 |
+
import { TextInput } from "@/components/input/input";
|
3 |
import { ApiRoute } from "@/utils/type";
|
4 |
|
5 |
export const Request = ({
|
|
|
12 |
onChange: (key: string, value: string | boolean) => void;
|
13 |
}) => {
|
14 |
return (
|
15 |
+
<div className="h-full bg-slate-900 p-5">
|
16 |
{children}
|
17 |
{parameters && (
|
18 |
+
<div className="mt-6 grid grid-cols-2 gap-6">
|
19 |
+
<p className="text-slate-200 uppercase text-xs font-semibold col-span-2">
|
20 |
Optional parameters
|
21 |
</p>
|
22 |
{parameters &&
|
|
|
25 |
key={key}
|
26 |
className="flex items-center justify-between gap-2"
|
27 |
>
|
|
|
28 |
{typeof value === "boolean" ? (
|
29 |
<div>
|
30 |
+
<Toggle
|
|
|
31 |
checked={value}
|
32 |
+
label={key}
|
33 |
+
onChange={(e) => onChange(key, e)}
|
|
|
34 |
/>
|
35 |
</div>
|
36 |
) : (
|
37 |
+
<TextInput
|
38 |
value={value as string}
|
39 |
+
label={key}
|
|
|
40 |
placeholder="value"
|
41 |
+
onChange={(e) => onChange(key, e)}
|
42 |
/>
|
43 |
)}
|
44 |
</div>
|
components/editor/main/response.tsx
CHANGED
@@ -1,10 +1,10 @@
|
|
1 |
import Highlight from "react-highlight";
|
2 |
-
import "node_modules/highlight.js/styles/
|
3 |
import { Loading } from "@/components/loading";
|
4 |
export const Response = ({ res, loading }: { res: any; loading: boolean }) => {
|
5 |
return (
|
6 |
<div className="overflow-auto h-full relative">
|
7 |
-
<Highlight className="json text-sm !bg-slate-950/10 !h-full !p-3">
|
8 |
{JSON.stringify(res ?? {}, null, 2)}
|
9 |
</Highlight>
|
10 |
{loading && (
|
|
|
1 |
import Highlight from "react-highlight";
|
2 |
+
import "node_modules/highlight.js/styles/night-owl.css";
|
3 |
import { Loading } from "@/components/loading";
|
4 |
export const Response = ({ res, loading }: { res: any; loading: boolean }) => {
|
5 |
return (
|
6 |
<div className="overflow-auto h-full relative">
|
7 |
+
<Highlight className="json text-sm !bg-slate-950/10 !h-full !p-3 !font-code !whitespace-pre-wrap">
|
8 |
{JSON.stringify(res ?? {}, null, 2)}
|
9 |
</Highlight>
|
10 |
{loading && (
|
components/editor/sidebar.tsx
CHANGED
@@ -6,18 +6,17 @@ import { API_COLLECTIONS } from "@/utils/datas/api_collections";
|
|
6 |
import { Method } from "@/components/method";
|
7 |
import { ApiRoute } from "@/utils/type";
|
8 |
import Link from "next/link";
|
|
|
9 |
|
10 |
export const EditorSidebar = ({
|
11 |
collections,
|
12 |
-
endpoint,
|
13 |
onCollections,
|
14 |
-
onEndpoint,
|
15 |
}: {
|
16 |
collections: string[];
|
17 |
-
endpoint: ApiRoute | null;
|
18 |
onCollections: (collections: string[]) => void;
|
19 |
-
onEndpoint: (endpoint: ApiRoute) => void;
|
20 |
}) => {
|
|
|
|
|
21 |
const handleSetActiveCollection = (key: string) => {
|
22 |
if (collections.includes(key)) {
|
23 |
onCollections(collections.filter((col) => col !== key));
|
@@ -64,11 +63,9 @@ export const EditorSidebar = ({
|
|
64 |
"text-slate-400 font-semibold text-xs flex items-center justify-start gap-2 rounded-md p-2.5 hover:bg-slate-600 hover:bg-opacity-10 cursor-pointer border-t border-b border-transparent select-none",
|
65 |
{
|
66 |
"bg-slate-600 bg-opacity-20 hover:!bg-opacity-20 !text-slate-200 border-b !border-b-slate-700/70 border-t !border-t-slate-800":
|
67 |
-
|
68 |
-
endpoint?.method === end.method,
|
69 |
}
|
70 |
)}
|
71 |
-
onClick={() => onEndpoint(end)}
|
72 |
>
|
73 |
<Method method={end.method} />
|
74 |
<p className="truncate">{end.path}</p>
|
|
|
6 |
import { Method } from "@/components/method";
|
7 |
import { ApiRoute } from "@/utils/type";
|
8 |
import Link from "next/link";
|
9 |
+
import { usePathname, useRouter } from "next/navigation";
|
10 |
|
11 |
export const EditorSidebar = ({
|
12 |
collections,
|
|
|
13 |
onCollections,
|
|
|
14 |
}: {
|
15 |
collections: string[];
|
|
|
16 |
onCollections: (collections: string[]) => void;
|
|
|
17 |
}) => {
|
18 |
+
const pathname = usePathname();
|
19 |
+
|
20 |
const handleSetActiveCollection = (key: string) => {
|
21 |
if (collections.includes(key)) {
|
22 |
onCollections(collections.filter((col) => col !== key));
|
|
|
63 |
"text-slate-400 font-semibold text-xs flex items-center justify-start gap-2 rounded-md p-2.5 hover:bg-slate-600 hover:bg-opacity-10 cursor-pointer border-t border-b border-transparent select-none",
|
64 |
{
|
65 |
"bg-slate-600 bg-opacity-20 hover:!bg-opacity-20 !text-slate-200 border-b !border-b-slate-700/70 border-t !border-t-slate-800":
|
66 |
+
pathname.includes(`/${collection.key}/${e}`),
|
|
|
67 |
}
|
68 |
)}
|
|
|
69 |
>
|
70 |
<Method method={end.method} />
|
71 |
<p className="truncate">{end.path}</p>
|
components/input/input.tsx
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import React, { ChangeEvent } from "react";
|
2 |
+
|
3 |
+
interface Props {
|
4 |
+
value: string;
|
5 |
+
onChange: (value: string) => void;
|
6 |
+
placeholder?: string;
|
7 |
+
label?: string;
|
8 |
+
}
|
9 |
+
|
10 |
+
export const TextInput: React.FC<Props> = ({
|
11 |
+
value,
|
12 |
+
onChange,
|
13 |
+
placeholder,
|
14 |
+
label,
|
15 |
+
}) => {
|
16 |
+
const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => {
|
17 |
+
const newValue = event.target.value;
|
18 |
+
// Only allow numbers or strings
|
19 |
+
if (/^[0-9a-zA-Z]*$/.test(newValue)) {
|
20 |
+
onChange(newValue);
|
21 |
+
}
|
22 |
+
};
|
23 |
+
|
24 |
+
return (
|
25 |
+
<div className="w-full relative grid grid-cols-1 gap-2.5">
|
26 |
+
<label className="text-slate-400 text-sm font-medium capitalize">
|
27 |
+
{label}:
|
28 |
+
</label>
|
29 |
+
<input
|
30 |
+
type="text"
|
31 |
+
value={value}
|
32 |
+
placeholder={placeholder}
|
33 |
+
onChange={handleInputChange}
|
34 |
+
className="transition-all duration-200 w-full h-full px-4 py-4 bg-slate-950/50 rounded-lg outline-none text-slate-200 placeholder:text-slate-600 focus:ring-4 focus:ring-indigo-600 focus:ring-opacity-40 border border-slate-950/50 focus:border-indigo-500"
|
35 |
+
/>
|
36 |
+
</div>
|
37 |
+
);
|
38 |
+
};
|
components/input/toggle.tsx
ADDED
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import classNames from "classnames";
|
2 |
+
import { useState } from "react";
|
3 |
+
import { useUpdateEffect } from "react-use";
|
4 |
+
|
5 |
+
interface Props {
|
6 |
+
label: string;
|
7 |
+
checked: boolean;
|
8 |
+
onChange: (checked: boolean) => void;
|
9 |
+
}
|
10 |
+
|
11 |
+
export const Toggle: React.FC<Props> = ({ label, onChange, checked }) => {
|
12 |
+
const [checkedState, setCheckedState] = useState(checked);
|
13 |
+
|
14 |
+
useUpdateEffect(() => onChange(checkedState), [checkedState]);
|
15 |
+
|
16 |
+
return (
|
17 |
+
<div className="w-full flex items-center justify-start gap-2.5">
|
18 |
+
<label className="text-slate-400 text-sm font-medium capitalize">
|
19 |
+
{label}:
|
20 |
+
</label>
|
21 |
+
<div
|
22 |
+
className={classNames(
|
23 |
+
"w-[52px] h-[24px] rounded-full p-[4px] relative cursor-pointer",
|
24 |
+
{
|
25 |
+
"bg-red-700": !checkedState,
|
26 |
+
"bg-blue-600": checkedState,
|
27 |
+
}
|
28 |
+
)}
|
29 |
+
onClick={() => setCheckedState(!checkedState)}
|
30 |
+
>
|
31 |
+
<div
|
32 |
+
className={classNames(
|
33 |
+
"rounded-full h-[16px] w-[16px] bg-slate-50 shadow-xl absolute top-[4px] transition-all duration-200",
|
34 |
+
{
|
35 |
+
"left-[4px]": checkedState,
|
36 |
+
"left-[31px]": !checkedState,
|
37 |
+
}
|
38 |
+
)}
|
39 |
+
/>
|
40 |
+
<p
|
41 |
+
className={classNames(
|
42 |
+
"text-white text-xs uppercase font-bold transition-all duration-200",
|
43 |
+
{
|
44 |
+
"text-right": checkedState,
|
45 |
+
}
|
46 |
+
)}
|
47 |
+
>
|
48 |
+
{checkedState ? "on" : "off"}
|
49 |
+
</p>
|
50 |
+
</div>
|
51 |
+
</div>
|
52 |
+
);
|
53 |
+
};
|
components/loading/index.tsx
CHANGED
@@ -12,7 +12,7 @@ export const Loading = ({ children }: { children: React.ReactElement }) => (
|
|
12 |
cy="12"
|
13 |
r="10"
|
14 |
stroke="currentColor"
|
15 |
-
|
16 |
></circle>
|
17 |
<path
|
18 |
className="opacity-75"
|
|
|
12 |
cy="12"
|
13 |
r="10"
|
14 |
stroke="currentColor"
|
15 |
+
strokeWidth="4"
|
16 |
></circle>
|
17 |
<path
|
18 |
className="opacity-75"
|
utils/axios.ts
CHANGED
@@ -1,7 +1,11 @@
|
|
1 |
import redaxios from 'redaxios';
|
2 |
|
3 |
const axios = redaxios.create({
|
4 |
-
baseURL: process.env.NEXT_PUBLIC_APP_APIURL
|
|
|
|
|
|
|
|
|
5 |
});
|
6 |
|
7 |
export default axios
|
|
|
1 |
import redaxios from 'redaxios';
|
2 |
|
3 |
const axios = redaxios.create({
|
4 |
+
baseURL: process.env.NEXT_PUBLIC_APP_APIURL,
|
5 |
+
headers: {
|
6 |
+
'Content-Type': 'application/json',
|
7 |
+
Authorization: `Bearer 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`,
|
8 |
+
},
|
9 |
});
|
10 |
|
11 |
export default axios
|
utils/datas/api_collections.ts
CHANGED
@@ -2,7 +2,8 @@ import { ApiCollection } from "@/utils/type";
|
|
2 |
|
3 |
export const API_COLLECTIONS: Array<ApiCollection> = [{
|
4 |
key: 'search',
|
5 |
-
endpoints: [
|
|
|
6 |
method: 'GET',
|
7 |
path: '/api/models',
|
8 |
parameters: {
|
@@ -35,51 +36,86 @@ export const API_COLLECTIONS: Array<ApiCollection> = [{
|
|
35 |
}
|
36 |
}, {
|
37 |
method: 'GET',
|
38 |
-
path: '/api/datasets/{repo_id}'
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
endpoints: [{
|
43 |
-
method: 'POST',
|
44 |
-
path: '/api/repos/create',
|
45 |
-
}, {
|
46 |
-
method: 'DELETE',
|
47 |
-
path: '/api/repos/delete'
|
48 |
-
}, {
|
49 |
-
method: 'PUT',
|
50 |
-
path: '/api/repos/{repo_type}/{repo_id}/settings'
|
51 |
}, {
|
52 |
-
method: 'POST',
|
53 |
-
path: '/api/repos/move'
|
54 |
-
}],
|
55 |
-
}, {
|
56 |
-
key: 'user',
|
57 |
-
endpoints: [{
|
58 |
method: 'GET',
|
59 |
-
path: '/api/
|
60 |
-
}],
|
61 |
-
}, {
|
62 |
-
key: 'collection',
|
63 |
-
endpoints: [{
|
64 |
-
method: 'POST',
|
65 |
-
path: '/api/collections',
|
66 |
}, {
|
67 |
method: 'GET',
|
68 |
-
path: '/api/
|
69 |
-
}, {
|
70 |
-
method: 'PATCH',
|
71 |
-
path: '/api/collections/{namespace}/{slug}-{id}'
|
72 |
}, {
|
73 |
-
method: '
|
74 |
-
path: '/api/
|
75 |
}, {
|
76 |
-
method: '
|
77 |
-
path: '/api/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
}, {
|
79 |
-
method: '
|
80 |
-
path: '/api/
|
81 |
}, {
|
82 |
-
method: '
|
83 |
-
path: '/api/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
}],
|
85 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
export const API_COLLECTIONS: Array<ApiCollection> = [{
|
4 |
key: 'search',
|
5 |
+
endpoints: [
|
6 |
+
{
|
7 |
method: 'GET',
|
8 |
path: '/api/models',
|
9 |
parameters: {
|
|
|
36 |
}
|
37 |
}, {
|
38 |
method: 'GET',
|
39 |
+
path: '/api/datasets/{repo_id}',
|
40 |
+
parameters: {
|
41 |
+
full: true,
|
42 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
}, {
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
method: 'GET',
|
45 |
+
path: '/api/datasets/{repo_id}/parquet'
|
|
|
|
|
|
|
|
|
|
|
|
|
46 |
}, {
|
47 |
method: 'GET',
|
48 |
+
path: '/api/datasets/{repo_id}/parquet/{config}/{split}/{n}.parquet'
|
|
|
|
|
|
|
49 |
}, {
|
50 |
+
method: 'GET',
|
51 |
+
path: '/api/datasets-tags-by-type'
|
52 |
}, {
|
53 |
+
method: 'GET',
|
54 |
+
path: '/api/spaces',
|
55 |
+
parameters: {
|
56 |
+
search: "",
|
57 |
+
author: "",
|
58 |
+
filter: "",
|
59 |
+
sort: "",
|
60 |
+
direction: "",
|
61 |
+
limit: 5,
|
62 |
+
full: true,
|
63 |
+
config: true
|
64 |
+
}
|
65 |
}, {
|
66 |
+
method: 'GET',
|
67 |
+
path: '/api/spaces/{repo_id}'
|
68 |
}, {
|
69 |
+
method: 'GET',
|
70 |
+
path: '/api/metrics'
|
71 |
+
}],
|
72 |
+
},
|
73 |
+
// {
|
74 |
+
// key: 'repo',
|
75 |
+
// endpoints: [{
|
76 |
+
// method: 'POST',
|
77 |
+
// path: '/api/repos/create',
|
78 |
+
// }, {
|
79 |
+
// method: 'DELETE',
|
80 |
+
// path: '/api/repos/delete'
|
81 |
+
// }, {
|
82 |
+
// method: 'PUT',
|
83 |
+
// path: '/api/repos/{repo_type}/{repo_id}/settings'
|
84 |
+
// }, {
|
85 |
+
// method: 'POST',
|
86 |
+
// path: '/api/repos/move'
|
87 |
+
// }],
|
88 |
+
// },
|
89 |
+
{
|
90 |
+
key: 'user',
|
91 |
+
endpoints: [{
|
92 |
+
method: 'GET',
|
93 |
+
path: '/api/whoami-v2',
|
94 |
}],
|
95 |
+
},
|
96 |
+
// {
|
97 |
+
// key: 'collection',
|
98 |
+
// endpoints: [{
|
99 |
+
// method: 'POST',
|
100 |
+
// path: '/api/collections',
|
101 |
+
// }, {
|
102 |
+
// method: 'GET',
|
103 |
+
// path: '/api/collections/{namespace}/{slug}-{id}'
|
104 |
+
// }, {
|
105 |
+
// method: 'PATCH',
|
106 |
+
// path: '/api/collections/{namespace}/{slug}-{id}'
|
107 |
+
// }, {
|
108 |
+
// method: 'DELETE',
|
109 |
+
// path: '/api/collections/{namespace}/{slug}-{id}'
|
110 |
+
// }, {
|
111 |
+
// method: 'POST',
|
112 |
+
// path: '/api/collections/{namespace}/{slug}-{id}/item'
|
113 |
+
// }, {
|
114 |
+
// method: 'PATCH',
|
115 |
+
// path: '/api/collections/{namespace}/{slug}-{id}/items/{item_id}'
|
116 |
+
// }, {
|
117 |
+
// method: 'DELETE',
|
118 |
+
// path: '/api/collections/{namespace}/{slug}-{id}/items/{item_id}'
|
119 |
+
// }],
|
120 |
+
// }
|
121 |
+
]
|