Esteves Enzo commited on
Commit
5916048
·
0 Parent(s):
.env ADDED
@@ -0,0 +1 @@
 
 
1
+ NEXT_PUBLIC_APP_APIURL=https://huggingface.co
.gitattributes ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip filter=lfs diff=lfs merge=lfs -text
34
+ *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
.gitignore ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2
+
3
+ # dependencies
4
+ /node_modules
5
+ /.pnp
6
+ .pnp.js
7
+
8
+ # testing
9
+ /coverage
10
+
11
+ # next.js
12
+ /.next/
13
+ /out/
14
+
15
+ # production
16
+ /build
17
+
18
+ # misc
19
+ .DS_Store
20
+ *.pem
21
+
22
+ # debug
23
+ npm-debug.log*
24
+ yarn-debug.log*
25
+ yarn-error.log*
26
+
27
+ # local env files
28
+ .env*.local
29
+
30
+ # vercel
31
+ .vercel
32
+
33
+ # typescript
34
+ *.tsbuildinfo
35
+ next-env.d.ts
Dockerfile ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Dockerfile
2
+
3
+ # Use an official Node.js runtime as the base image
4
+ FROM node:18
5
+
6
+ # Set the working directory in the container
7
+ WORKDIR /usr/src/app
8
+
9
+ # Copy package.json and package-lock.json to the container
10
+ COPY package.json package-lock.json ./
11
+
12
+ # Install dependencies
13
+ RUN npm install
14
+
15
+ # Copy the rest of the application files to the container
16
+ COPY . .
17
+
18
+ # Build the Next.js application for production
19
+ RUN npm run build
20
+
21
+ # Expose the application port (assuming your app runs on port 3000)
22
+ EXPOSE 3000
23
+
24
+ # Start the application
25
+ CMD ["npm", "start"]
README 2.md ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
2
+
3
+ ## Getting Started
4
+
5
+ First, run the development server:
6
+
7
+ ```bash
8
+ npm run dev
9
+ # or
10
+ yarn dev
11
+ # or
12
+ pnpm dev
13
+ # or
14
+ bun dev
15
+ ```
16
+
17
+ Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
18
+
19
+ You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
20
+
21
+ This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
22
+
23
+ ## Learn More
24
+
25
+ To learn more about Next.js, take a look at the following resources:
26
+
27
+ - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
28
+ - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
29
+
30
+ You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
31
+
32
+ ## Deploy on Vercel
33
+
34
+ The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
35
+
36
+ Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
README.md ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Hugging Face Client REST API
3
+ emoji: ⚡
4
+ colorFrom: blue
5
+ colorTo: indigo
6
+ sdk: docker
7
+ pinned: true
8
+ license: mit
9
+ ---
10
+
11
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
app/layout.tsx ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import type { Metadata } from "next";
2
+ import { Fira_Code, Inter } from "next/font/google";
3
+ import "@/assets/globals.css";
4
+
5
+ const inter = Inter({
6
+ subsets: ["latin"],
7
+ display: "swap",
8
+ variable: "--font-inter",
9
+ });
10
+
11
+ const fira_code = Fira_Code({
12
+ subsets: ["latin"],
13
+ display: "swap",
14
+ variable: "--font-fira-code",
15
+ });
16
+
17
+ export const metadata: Metadata = {
18
+ title: "Create Next App",
19
+ description: "Generated by create next app",
20
+ };
21
+
22
+ export default function RootLayout({
23
+ children,
24
+ }: {
25
+ children: React.ReactNode;
26
+ }) {
27
+ return (
28
+ <html lang="en" className={`${inter.variable} ${fira_code.variable}`}>
29
+ <body>
30
+ <div id="background__noisy" />
31
+ {children}
32
+ </body>
33
+ </html>
34
+ );
35
+ }
app/page.tsx ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Editor } from "@/components/editor";
2
+ import Image from "next/image";
3
+
4
+ export default function Home() {
5
+ return (
6
+ <section className="h-full">
7
+ <Editor />
8
+ </section>
9
+ );
10
+ }
assets/globals.css ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+
5
+ html, body {
6
+ @apply bg-gray-200 min-h-screen relative tracking-wide overflow-x-hidden;
7
+ z-index: 1;
8
+ }
9
+
10
+ #background__noisy {
11
+ @apply bg-blend-normal pointer-events-none opacity-80;
12
+ background-size: 25ww auto;
13
+ background-image: url('/background_noisy.webp');
14
+ z-index: -1;
15
+ @apply fixed w-screen h-screen top-0 left-0;
16
+ }
assets/hf-logo.svg ADDED
components/editor/header.tsx ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import HFLogo from "assets/hf-logo.svg";
2
+ import Image from "next/image";
3
+
4
+ export const EditorHeader = () => {
5
+ return (
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" />
13
+ <div className="bg-indigo-600 w-3 h-3 rounded-full" />
14
+ <div className="bg-purple-500 w-3 h-3 rounded-full" />
15
+ </div>
16
+ </header>
17
+ );
18
+ };
components/editor/index.tsx ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "use client";
2
+ import { useState } from "react";
3
+
4
+ import { EditorHeader } from "./header";
5
+ import { EditorSidebar } from "./sidebar";
6
+ import { EditorMain } from "./main";
7
+ import { ApiRoute } from "@/utils/type";
8
+ import { API_COLLECTIONS } from "@/utils/datas/api_collections";
9
+
10
+ export const Editor = () => {
11
+ const [collections, setCollections] = useState<string[]>(["search"]);
12
+ const [endpoint, setEndpoint] = useState<ApiRoute | null>(
13
+ API_COLLECTIONS[0].endpoints[0]
14
+ );
15
+
16
+ return (
17
+ <div className="bg-slate-950 w-full overflow-hidden shadow-xl h-[100vh]">
18
+ <EditorHeader />
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
+ </main>
35
+ </div>
36
+ );
37
+ };
components/editor/main/endpoint.tsx ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { useMemo } from "react";
2
+ import classNames from "classnames";
3
+
4
+ import { Method } from "@/components/method";
5
+ import { splitStringBracket } from "@/utils";
6
+ import { ApiRoute } from "@/utils/type";
7
+
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">
23
+ <div className="text-white text-sm flex items-center justify-start gap-2 w-full">
24
+ <Method method={endpoint.method} />
25
+ <div className="flex items-center justify-start gap-1">
26
+ {path_formatted.map((p, i) => {
27
+ const isCustomizable = p.includes("{") && p.includes("}");
28
+ return (
29
+ <p
30
+ key={i}
31
+ className={classNames("", {
32
+ "bg-indigo-600 !text-white px-1.5 rounded-md outline-none bg-opacity-80":
33
+ isCustomizable,
34
+ "text-slate-300": !isCustomizable,
35
+ })}
36
+ contentEditable={isCustomizable}
37
+ >
38
+ {p}
39
+ </p>
40
+ );
41
+ })}
42
+ </div>
43
+ </div>
44
+ {children}
45
+ </div>
46
+ </div>
47
+ );
48
+ };
components/editor/main/index.tsx ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { useState } from "react";
2
+
3
+ import { ApiRoute } from "@/utils/type";
4
+ import axios from "@/utils/axios";
5
+
6
+ import { Endpoint } from "./endpoint";
7
+ import { Request } from "./request";
8
+ import { Response } from "./response";
9
+
10
+ export const EditorMain = ({
11
+ collections,
12
+ endpoint,
13
+ onCollections,
14
+ onEndpoint,
15
+ }: {
16
+ collections: string[];
17
+ endpoint: ApiRoute;
18
+ onCollections: (collections: string[]) => void;
19
+ onEndpoint: (endpoint: ApiRoute) => void;
20
+ }) => {
21
+ const [formattedEndpoint, setFormattedEndpoint] = useState<string | null>(
22
+ null
23
+ );
24
+
25
+ const [response, setResponse] = useState<any | null>(null);
26
+
27
+ const handleRequest = async () => {
28
+ const url = new URL(endpoint.path, process.env.NEXT_PUBLIC_APP_APIURL);
29
+ if (endpoint?.parameters) {
30
+ const parameters = Object.entries(endpoint.parameters).filter(
31
+ ([key, value]) => value !== "" && value !== null
32
+ );
33
+ parameters.forEach(([key, value]) => {
34
+ url.searchParams.append(key, value as string);
35
+ });
36
+ }
37
+ console.log("url ", url);
38
+
39
+ axios
40
+ .get(url.pathname, {
41
+ params: url.searchParams,
42
+ })
43
+ .then((res: any) => {
44
+ console.log("res ", res);
45
+ if (res.ok) {
46
+ setResponse(res.data);
47
+ }
48
+ });
49
+ };
50
+
51
+ return (
52
+ <div className="flex-1 bg-slate-900/50 h-[calc(100%-56px)]">
53
+ <div className="h-full grid grid-cols-2">
54
+ <Request endpoint={endpoint}>
55
+ <Endpoint endpoint={endpoint}>
56
+ <button
57
+ className="bg-indigo-500 hover:bg-indigo-500/80 text-white px-3 py-1 rounded-lg text-sm"
58
+ onClick={handleRequest}
59
+ >
60
+ Send
61
+ </button>
62
+ </Endpoint>
63
+ </Request>
64
+ <Response res={response} />
65
+ </div>
66
+ </div>
67
+ );
68
+ };
components/editor/main/request.tsx ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { ApiRoute } from "@/utils/type";
2
+
3
+ export const Request = ({
4
+ endpoint,
5
+ children,
6
+ }: {
7
+ endpoint: ApiRoute;
8
+ children: React.ReactElement;
9
+ }) => {
10
+ return (
11
+ <div className="h-full bg-slate-900 p-4">
12
+ {children}
13
+ {endpoint?.parameters && (
14
+ <div className="mt-6 grid grid-cols-1 gap-4">
15
+ <p className="text-slate-400 uppercase text-xs font-semibold">
16
+ Optional parameters
17
+ </p>
18
+ {endpoint?.parameters &&
19
+ Object.entries(endpoint.parameters).map(([key, value]) => (
20
+ <div
21
+ key={key}
22
+ className="flex items-center justify-between gap-2"
23
+ >
24
+ <p className="text-slate-300 text-sm">{key}</p>
25
+ <input
26
+ value={value as string}
27
+ type="text"
28
+ className="bg-slate-950/50 w-full rounded-md px-2 py-1 text-slate-100 outline-none placeholder:text-slate-600"
29
+ placeholder="value"
30
+ />
31
+ </div>
32
+ ))}
33
+ </div>
34
+ )}
35
+ </div>
36
+ );
37
+ };
components/editor/main/response.tsx ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import Highlight from "react-highlight";
2
+ import "node_modules/highlight.js/styles/atom-one-dark.css";
3
+ export const Response = ({ res }: { res: any }) => {
4
+ return (
5
+ <div className="overflow-auto h-full">
6
+ <Highlight className="json text-sm !bg-slate-950/10 !h-full !p-3">
7
+ {JSON.stringify(res ?? {}, null, 2)}
8
+ </Highlight>
9
+ </div>
10
+ );
11
+ };
components/editor/sidebar.tsx ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "use client";
2
+ import { TbChevronDown } from "react-icons/tb";
3
+ import classNames from "classnames";
4
+
5
+ import { API_COLLECTIONS } from "@/utils/datas/api_collections";
6
+ import { Method } from "@/components/method";
7
+ import { ApiRoute } from "@/utils/type";
8
+
9
+ export const EditorSidebar = ({
10
+ collections,
11
+ endpoint,
12
+ onCollections,
13
+ onEndpoint,
14
+ }: {
15
+ collections: string[];
16
+ endpoint: ApiRoute | null;
17
+ onCollections: (collections: string[]) => void;
18
+ onEndpoint: (endpoint: ApiRoute) => void;
19
+ }) => {
20
+ const handleSetActiveCollection = (key: string) => {
21
+ if (collections.includes(key)) {
22
+ onCollections(collections.filter((col) => col !== key));
23
+ } else {
24
+ onCollections([...collections, key]);
25
+ }
26
+ };
27
+
28
+ // useUpdateEffect(() => {
29
+ // if (collections) {
30
+ // const first_endpoint = API_COLLECTIONS.find(
31
+ // (col) => col.key === collections
32
+ // )?.endpoints[0];
33
+ // if (first_endpoint) onEndpoint(first_endpoint);
34
+ // }
35
+ // }, [collections]);
36
+
37
+ return (
38
+ <ul className="min-w-[300px] max-w-sm w-full bg-slate-900 border-r border-slate-700/40 h-full overflow-auto">
39
+ {API_COLLECTIONS.map((collection, c) => (
40
+ <li key={collection.key} className="block w-full">
41
+ <div
42
+ className={classNames(
43
+ "p-4 border-b border-slate-700/70 text-slate-400 cursor-pointer hover:bg-slate-700/30 flex items-center justify-between transition-all duration-200 select-none active:bg-indigo-600 active:text-slate-100",
44
+ {
45
+ "bg-indigo-600 !text-slate-100 hover:!bg-indigo-600 !border-indigo-500":
46
+ collections.includes(collection.key),
47
+ }
48
+ )}
49
+ onClick={() => handleSetActiveCollection(collection.key)}
50
+ >
51
+ <p className="font-semibold uppercase text-xs flex items-center justify-between">
52
+ {collection.key} API
53
+ </p>
54
+ <TbChevronDown
55
+ className={classNames(
56
+ "text-slate-400 transition-all duration-200",
57
+ {
58
+ "transform rotate-180 !text-slate-100": collections.includes(
59
+ collection.key
60
+ ),
61
+ }
62
+ )}
63
+ />
64
+ </div>
65
+ {collections.includes(collection.key) && (
66
+ <div className="bg-slate-700/20 w-full p-3 border-b border-slate-700/70">
67
+ <ul className="w-full">
68
+ {collection.endpoints.map((end, e) => (
69
+ <li
70
+ key={e}
71
+ className={classNames(
72
+ "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",
73
+ {
74
+ "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":
75
+ endpoint?.path === end.path &&
76
+ endpoint?.method === end.method,
77
+ }
78
+ )}
79
+ onClick={() => onEndpoint(end)}
80
+ >
81
+ <Method method={end.method} />
82
+ <p className="truncate">{end.path}</p>
83
+ </li>
84
+ ))}
85
+ </ul>
86
+ </div>
87
+ )}
88
+ </li>
89
+ ))}
90
+ </ul>
91
+ );
92
+ };
components/method/index.tsx ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import classNames from "classnames";
2
+
3
+ export const Method = ({
4
+ method,
5
+ className,
6
+ }: {
7
+ method: string;
8
+ className?: string;
9
+ }) => (
10
+ <div
11
+ className={classNames(
12
+ `px-1 text-[10px] rounded text-slate-100 font-semibold inline-block ${className}`,
13
+ {
14
+ "bg-blue-500": method === "GET",
15
+ "bg-green-600": method === "POST",
16
+ "bg-yellow-600": method === "PUT" || method === "PATCH",
17
+ "bg-red-600": method === "DELETE",
18
+ }
19
+ )}
20
+ >
21
+ {method}
22
+ </div>
23
+ );
next.config.js ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ /** @type {import('next').NextConfig} */
2
+ const nextConfig = {}
3
+
4
+ module.exports = nextConfig
package-lock.json ADDED
The diff for this file is too large to render. See raw diff
 
package.json ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "client-api",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "scripts": {
6
+ "dev": "next dev",
7
+ "build": "next build",
8
+ "start": "next start",
9
+ "lint": "next lint"
10
+ },
11
+ "dependencies": {
12
+ "classnames": "^2.3.2",
13
+ "next": "13.5.6",
14
+ "react": "^18",
15
+ "react-dom": "^18",
16
+ "react-highlight": "^0.15.0",
17
+ "react-icons": "^4.11.0",
18
+ "react-use": "^17.4.0",
19
+ "redaxios": "^0.5.1"
20
+ },
21
+ "devDependencies": {
22
+ "@types/node": "^20",
23
+ "@types/react": "^18",
24
+ "@types/react-dom": "^18",
25
+ "@types/react-highlight": "^0.12.7",
26
+ "autoprefixer": "^10",
27
+ "eslint": "^8",
28
+ "eslint-config-next": "13.5.6",
29
+ "postcss": "^8",
30
+ "tailwindcss": "^3",
31
+ "typescript": "^5"
32
+ }
33
+ }
postcss.config.js ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ module.exports = {
2
+ plugins: {
3
+ tailwindcss: {},
4
+ autoprefixer: {},
5
+ },
6
+ }
public/background_noisy.webp ADDED
tailwind.config.ts ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import type { Config } from 'tailwindcss'
2
+
3
+ const config: Config = {
4
+ content: [
5
+ './pages/**/*.{js,ts,jsx,tsx,mdx}',
6
+ './components/**/*.{js,ts,jsx,tsx,mdx}',
7
+ './app/**/*.{js,ts,jsx,tsx,mdx}',
8
+ ],
9
+ theme: {
10
+ fontFamily: {
11
+ sans: ['var(--font-inter)', 'sans-serif'],
12
+ code: ['var(--font-fira-code)', 'monospace'],
13
+ }
14
+ },
15
+ plugins: [],
16
+ }
17
+ export default config
tsconfig.json ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "compilerOptions": {
3
+ "target": "es5",
4
+ "lib": ["dom", "dom.iterable", "esnext"],
5
+ "allowJs": true,
6
+ "skipLibCheck": true,
7
+ "strict": true,
8
+ "noEmit": true,
9
+ "esModuleInterop": true,
10
+ "module": "esnext",
11
+ "moduleResolution": "bundler",
12
+ "resolveJsonModule": true,
13
+ "isolatedModules": true,
14
+ "jsx": "preserve",
15
+ "incremental": true,
16
+ "plugins": [
17
+ {
18
+ "name": "next"
19
+ }
20
+ ],
21
+ "paths": {
22
+ "@/*": ["./*"]
23
+ }
24
+ },
25
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
26
+ "exclude": ["node_modules"]
27
+ }
utils/axios.ts ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
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
utils/datas/api_collections.ts ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 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: {
9
+ search: "",
10
+ author: "",
11
+ filter: "",
12
+ sort: "",
13
+ direction: "",
14
+ limit: 10,
15
+ full: true,
16
+ config: true
17
+ }
18
+ }, {
19
+ method: 'GET',
20
+ path: '/api/models/{repo_id}'
21
+ }, {
22
+ method: 'GET',
23
+ path: '/api/models-tags-by-type'
24
+ }, {
25
+ method: 'GET',
26
+ path: '/api/datasets'
27
+ }, {
28
+ method: 'GET',
29
+ path: '/api/datasets/{repo_id}'
30
+ }],
31
+ }, {
32
+ key: 'repo',
33
+ endpoints: [{
34
+ method: 'POST',
35
+ path: '/api/repos/create',
36
+ }, {
37
+ method: 'DELETE',
38
+ path: '/api/repos/delete'
39
+ }, {
40
+ method: 'PUT',
41
+ path: '/api/repos/{repo_type}/{repo_id}/settings'
42
+ }, {
43
+ method: 'POST',
44
+ path: '/api/repos/move'
45
+ }],
46
+ }, {
47
+ key: 'user',
48
+ endpoints: [{
49
+ method: 'GET',
50
+ path: '/api/whoami-v2',
51
+ }],
52
+ }, {
53
+ key: 'collection',
54
+ endpoints: [{
55
+ method: 'POST',
56
+ path: '/api/collections',
57
+ }, {
58
+ method: 'GET',
59
+ path: '/api/collections/{namespace}/{slug}-{id}'
60
+ }, {
61
+ method: 'PATCH',
62
+ path: '/api/collections/{namespace}/{slug}-{id}'
63
+ }, {
64
+ method: 'DELETE',
65
+ path: '/api/collections/{namespace}/{slug}-{id}'
66
+ }, {
67
+ method: 'POST',
68
+ path: '/api/collections/{namespace}/{slug}-{id}/item'
69
+ }, {
70
+ method: 'PATCH',
71
+ path: '/api/collections/{namespace}/{slug}-{id}/items/{item_id}'
72
+ }, {
73
+ method: 'DELETE',
74
+ path: '/api/collections/{namespace}/{slug}-{id}/items/{item_id}'
75
+ }],
76
+ }]
utils/index.ts ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ export const splitStringBracket = (str: string): string[] => {
2
+ // Split string by bracket but keep the bracket
3
+ const result = str.split(/(\{.*?\})/g)
4
+ return result.filter((item) => item !== '')
5
+ }
utils/type.ts ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ export interface ApiCollection {
2
+ key: string
3
+ endpoints: Array<ApiRoute>
4
+ }
5
+
6
+ export interface ApiRoute {
7
+ method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH'
8
+ path: string,
9
+ parameters?: any
10
+ }