enzostvs HF staff commited on
Commit
ca0baae
1 Parent(s): 4f085f4

refacto snippet function

Browse files
components/editor/main/request.tsx CHANGED
@@ -41,8 +41,10 @@ export const Request = ({
41
 
42
  return (
43
  <div className="h-full bg-slate-900 pb-5 overflow-auto">
44
- {children}
45
- <Tabs active={tab} setActive={setTab} endpoint={endpoint} />
 
 
46
  <div className="px-4 xl:px-6">
47
  {tab === "parameters" && parameters && (
48
  <div className="mt-6 grid grid-cols-2 gap-6 w-full">
 
41
 
42
  return (
43
  <div className="h-full bg-slate-900 pb-5 overflow-auto">
44
+ <div className="top-0 sticky w-full backdrop-blur">
45
+ {children}
46
+ <Tabs active={tab} setActive={setTab} endpoint={endpoint} />
47
+ </div>
48
  <div className="px-4 xl:px-6">
49
  {tab === "parameters" && parameters && (
50
  <div className="mt-6 grid grid-cols-2 gap-6 w-full">
components/editor/main/snippet/curl.tsx CHANGED
@@ -1 +1,98 @@
1
- export const Curl = {};
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { ApiRoute } from "@/utils/type";
2
+ import classNames from "classnames";
3
+ import { useState } from "react";
4
+ import Highlight from "react-highlight";
5
+ import { BiCodeCurly, BiSolidCopy } from "react-icons/bi";
6
+ import { Options } from "redaxios";
7
+
8
+ export const CurlSnippet = ({
9
+ endpoint,
10
+ headers,
11
+ parameters,
12
+ body,
13
+ onCopyToClipboard,
14
+ }: {
15
+ endpoint: ApiRoute;
16
+ parameters?: Record<string, any>;
17
+ headers?: Record<string, any>;
18
+ body?: Options | undefined;
19
+ onCopyToClipboard: (e: string) => void;
20
+ }) => {
21
+ const [isCopied, setIsCopied] = useState<boolean>(false);
22
+
23
+ const generateCurlRequestFromEndpoint = () => {
24
+ const { method, path } = endpoint;
25
+ const fullpath = `${process.env.NEXT_PUBLIC_APP_APIURL}${path}`;
26
+
27
+ const removeEmptyValues = (data: Record<string, any>) => {
28
+ const formattedData = { ...data };
29
+ Object.entries(formattedData).forEach(([key, value]) => {
30
+ if (!value) {
31
+ delete formattedData[key];
32
+ }
33
+ });
34
+ return formattedData;
35
+ };
36
+
37
+ const Dict: Record<string, any> = {
38
+ GET: () => {
39
+ const filteredEmptyParameters = removeEmptyValues(parameters ?? {});
40
+
41
+ return `curl -X ${method} "${fullpath}?${new URLSearchParams(
42
+ filteredEmptyParameters
43
+ ).toString()}" \\
44
+ -H ${JSON.stringify(headers)}
45
+ `;
46
+ },
47
+ DELETE: () => {
48
+ return `curl -X ${method} "${fullpath}" \\
49
+ -H ${JSON.stringify(headers)} \\
50
+ -d ${JSON.stringify(body)}
51
+ `;
52
+ },
53
+ DEFAULT: () => {
54
+ return `curl -X ${method} "${fullpath}" \\
55
+ -H ${JSON.stringify(headers)}
56
+ -d ${JSON.stringify(body)}
57
+ `;
58
+ },
59
+ };
60
+
61
+ return Dict[method] ? Dict[method]() : Dict["DEFAULT"]();
62
+ };
63
+
64
+ const handleCopy = () => {
65
+ onCopyToClipboard(generateCurlRequestFromEndpoint());
66
+ setIsCopied(true);
67
+ setTimeout(() => {
68
+ setIsCopied(false);
69
+ }, 1000);
70
+ };
71
+
72
+ return (
73
+ <div className="bg-slate-950/50 rounded-xl overflow-hidden">
74
+ <header className="bg-slate-950 flex items-center justify-start px-5 py-4 uppercase gap-2 text-slate-300">
75
+ <BiCodeCurly className="text-xl" />
76
+ <p className="text-xs font-semibold">Curl</p>
77
+ </header>
78
+ <main className="px-6 py-6">
79
+ <Highlight className="curl text-xs font-code !bg-transparent !p-0 !whitespace-pre-wrap break-all !leading-relaxed">
80
+ {generateCurlRequestFromEndpoint()}
81
+ </Highlight>
82
+ <div className="flex justify-end relative" onClick={handleCopy}>
83
+ <BiSolidCopy className="text-slate-500 cursor-pointer hover:text-slate-300 transition-all duration-75" />
84
+ <div
85
+ className={classNames(
86
+ "bg-indigo-500/60 text-slate-100 text-xs font-semibold absolute bottom-0 right-0 z-10 rounded-lg px-2 py-1 pointer-events-none -translate-y-full transition-all duration-200",
87
+ {
88
+ "opacity-0": !isCopied,
89
+ }
90
+ )}
91
+ >
92
+ Copied!
93
+ </div>
94
+ </div>
95
+ </main>
96
+ </div>
97
+ );
98
+ };
components/editor/main/snippet/index.tsx CHANGED
@@ -1,31 +1,11 @@
1
- import { useState } from "react";
2
  import { useCopyToClipboard } from "react-use";
3
- import classNames from "classnames";
4
- import Highlight from "react-highlight";
5
  import { Options } from "redaxios";
6
- import {
7
- BiSolidCopy,
8
- BiLogoJavascript,
9
- BiLogoPython,
10
- BiCodeCurly,
11
- } from "react-icons/bi";
12
 
13
  import { ApiRoute } from "@/utils/type";
14
 
15
- const LANGUAGES = [
16
- {
17
- value: "curl",
18
- icon: <BiCodeCurly className=" text-xl text-slate-300" />,
19
- },
20
- {
21
- value: "javascript",
22
- icon: <BiLogoJavascript className=" text-xl text-yellow-500" />,
23
- },
24
- {
25
- value: "python",
26
- icon: <BiLogoPython className=" text-xl text-blue-500" />,
27
- },
28
- ];
29
 
30
  export const Snippet = ({
31
  endpoint,
@@ -39,127 +19,32 @@ export const Snippet = ({
39
  body?: Options | undefined;
40
  }) => {
41
  const [_, copyToClipboard] = useCopyToClipboard();
42
- const [isCopied, setIsCopied] = useState<boolean>(false);
43
 
44
- const generateRequestFromEndpoint = (language: string) => {
45
- const { method, path } = endpoint;
46
-
47
- const needBody = ["post", "put", "patch", "delete"].includes(
48
- method.toLocaleLowerCase()
49
- );
50
- const fullpath = `${process.env.NEXT_PUBLIC_APP_APIURL}${path}`;
51
-
52
- if (language === "curl") {
53
- if (needBody && body) {
54
- return (
55
- `curl -X ${method.toLocaleUpperCase()} ${fullpath}` +
56
- "\n" +
57
- ` -H 'Content-Type: application/json'` +
58
- "\n" +
59
- ` -H 'Authorization: ${headers?.Authorization}'` +
60
- "\n" +
61
- ` -d '${JSON.stringify(body, null, 2)}'`
62
- );
63
- }
64
-
65
- if (parameters) {
66
- return (
67
- `curl -X ${method.toLocaleUpperCase()} ${fullpath}?` +
68
- Object.entries(parameters)
69
- .map(([key, value]) => `${key}=${value}`)
70
- .join("&")
71
- );
72
- }
73
-
74
- return `curl -X ${method.toLocaleUpperCase()} ${fullpath}`;
75
- }
76
-
77
- if (language === "javascript") {
78
- if (needBody && body) {
79
- return `const response = await fetch("${fullpath}", {
80
- method: "${method.toLocaleUpperCase()}",
81
- headers: {
82
- "Content-Type": "application/json",
83
- "Authorization": "${headers?.Authorization}",
84
- },
85
- body: JSON.stringify(${JSON.stringify(body, null, 2)}),
86
- });`;
87
- }
88
- if (parameters) {
89
- return `const response = await fetch("${fullpath}?${Object.entries(
90
- parameters
91
- )
92
- .map(([key, value]) => `${key}=${value}`)
93
- .join("&")}", {
94
- method: "${method.toLocaleUpperCase()}",
95
- });`;
96
- }
97
- }
98
-
99
- if (language === "python") {
100
- if (needBody && body) {
101
- return `import requests
102
- response = requests.${method.toLocaleLowerCase()}(
103
- "${fullpath}",
104
- headers={
105
- Authorization: "${headers?.Authorization}",
106
- },
107
- json=${JSON.stringify(body, null, 2)})`;
108
- }
109
- if (parameters) {
110
- return `import requests
111
- response = requests.${method.toLocaleLowerCase()}("${fullpath}", params={
112
- ${Object.entries(parameters)
113
- .map(([key, value]) => `${key}: ${value}`)
114
- .join(",\n ")}
115
- })`;
116
- }
117
- }
118
-
119
- return "";
120
- };
121
-
122
- const handleCopyToClipboard = (language: string) => {
123
- copyToClipboard(generateRequestFromEndpoint(language));
124
- setIsCopied(true);
125
- setTimeout(() => {
126
- setIsCopied(false);
127
- }, 2000);
128
- };
129
 
130
  return (
131
  <div className="mt-8 grid grid-cols-1 gap-4 w-full">
132
- {LANGUAGES.map((lang, key) => (
133
- <div key={key} className="bg-slate-950/50 rounded-xl overflow-hidden">
134
- <header className="bg-slate-950 flex items-center justify-start px-5 py-4 uppercase gap-2">
135
- {lang.icon}
136
- <p className="text-slate-300 text-xs font-semibold">{lang.value}</p>
137
- </header>
138
- <main className="px-6 py-6">
139
- <Highlight
140
- className={`${lang.value} text-xs font-code !bg-transparent !p-0 !whitespace-pre-wrap break-all !leading-relaxed`}
141
- >
142
- {generateRequestFromEndpoint(lang.value)}
143
- </Highlight>
144
- <div
145
- className="flex justify-end relative"
146
- onClick={() => handleCopyToClipboard(lang.value)}
147
- >
148
- <BiSolidCopy className="text-slate-500 cursor-pointer hover:text-slate-300 transition-all duration-75" />
149
- <div
150
- className={classNames(
151
- "bg-indigo-500/60 text-slate-100 text-xs font-semibold absolute bottom-0 right-0 z-10 rounded-lg px-2 py-1 pointer-events-none -translate-y-full transition-all duration-200",
152
- {
153
- "opacity-0": !isCopied,
154
- }
155
- )}
156
- >
157
- Copied!
158
- </div>
159
- </div>
160
- </main>
161
- </div>
162
- ))}
163
  </div>
164
  );
165
  };
 
 
1
  import { useCopyToClipboard } from "react-use";
 
 
2
  import { Options } from "redaxios";
 
 
 
 
 
 
3
 
4
  import { ApiRoute } from "@/utils/type";
5
 
6
+ import { PythonSnippet } from "./python";
7
+ import { JavascriptSnippet } from "./javascript";
8
+ import { CurlSnippet } from "./curl";
 
 
 
 
 
 
 
 
 
 
 
9
 
10
  export const Snippet = ({
11
  endpoint,
 
19
  body?: Options | undefined;
20
  }) => {
21
  const [_, copyToClipboard] = useCopyToClipboard();
 
22
 
23
+ const handleCopyToClipboard = (snippet: string) => copyToClipboard(snippet);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
 
25
  return (
26
  <div className="mt-8 grid grid-cols-1 gap-4 w-full">
27
+ <CurlSnippet
28
+ endpoint={endpoint}
29
+ headers={headers}
30
+ body={body}
31
+ parameters={parameters}
32
+ onCopyToClipboard={handleCopyToClipboard}
33
+ />
34
+ <JavascriptSnippet
35
+ endpoint={endpoint}
36
+ headers={headers}
37
+ body={body}
38
+ parameters={parameters}
39
+ onCopyToClipboard={handleCopyToClipboard}
40
+ />
41
+ <PythonSnippet
42
+ endpoint={endpoint}
43
+ headers={headers}
44
+ body={body}
45
+ parameters={parameters}
46
+ onCopyToClipboard={handleCopyToClipboard}
47
+ />
 
 
 
 
 
 
 
 
 
 
48
  </div>
49
  );
50
  };
components/editor/main/snippet/javascript.tsx ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { ApiRoute } from "@/utils/type";
2
+ import classNames from "classnames";
3
+ import { useState } from "react";
4
+ import Highlight from "react-highlight";
5
+ import { BiLogoJavascript, BiSolidCopy } from "react-icons/bi";
6
+ import { Options } from "redaxios";
7
+
8
+ export const JavascriptSnippet = ({
9
+ endpoint,
10
+ headers,
11
+ parameters,
12
+ body,
13
+ onCopyToClipboard,
14
+ }: {
15
+ endpoint: ApiRoute;
16
+ parameters?: Record<string, any>;
17
+ headers?: Record<string, any>;
18
+ body?: Options | undefined;
19
+ onCopyToClipboard: (e: string) => void;
20
+ }) => {
21
+ const [isCopied, setIsCopied] = useState<boolean>(false);
22
+
23
+ const generateJavascriptRequestFromEndpoint = () => {
24
+ const { method, path } = endpoint;
25
+ const fullpath = `${process.env.NEXT_PUBLIC_APP_APIURL}${path}`;
26
+
27
+ const removeEmptyValues = (data: Record<string, any>) => {
28
+ const formattedData = { ...data };
29
+ Object.entries(formattedData).forEach(([key, value]) => {
30
+ if (!value) {
31
+ delete formattedData[key];
32
+ }
33
+ });
34
+ return formattedData;
35
+ };
36
+
37
+ const Dict: Record<string, any> = {
38
+ GET: () => {
39
+ const filteredEmptyParameters = removeEmptyValues(parameters ?? {});
40
+
41
+ return `const response = await fetch(
42
+ "${fullpath}?${new URLSearchParams(filteredEmptyParameters).toString()}",
43
+ {
44
+ method: "${method}",
45
+ headers: ${JSON.stringify(headers)}
46
+ }
47
+ )`;
48
+ },
49
+ DELETE: () => {
50
+ return `const response = await fetch(
51
+ "${fullpath}",
52
+ {
53
+ method: "${method}",
54
+ headers: ${JSON.stringify(headers)},
55
+ body: ${JSON.stringify(body)}
56
+ }
57
+ )`;
58
+ },
59
+ DEFAULT: () => {
60
+ return `const response = await fetch(
61
+ "${fullpath}",
62
+ {
63
+ method: "${method}",
64
+ headers: ${JSON.stringify(headers)},
65
+ body: ${JSON.stringify(body)}
66
+ }
67
+ )`;
68
+ },
69
+ };
70
+
71
+ return Dict[method] ? Dict[method]() : Dict["DEFAULT"]();
72
+ };
73
+
74
+ const handleCopy = () => {
75
+ onCopyToClipboard(generateJavascriptRequestFromEndpoint());
76
+ setIsCopied(true);
77
+ setTimeout(() => {
78
+ setIsCopied(false);
79
+ }, 1000);
80
+ };
81
+
82
+ return (
83
+ <div className="bg-slate-950/50 rounded-xl overflow-hidden">
84
+ <header className="bg-slate-950 flex items-center justify-start px-5 py-4 uppercase gap-2 text-yellow-500">
85
+ <BiLogoJavascript className="text-xl" />
86
+ <p className="text-xs font-semibold">Javascript</p>
87
+ </header>
88
+ <main className="px-6 py-6">
89
+ <Highlight className="javascript text-xs font-code !bg-transparent !p-0 !whitespace-pre-wrap break-all !leading-relaxed">
90
+ {generateJavascriptRequestFromEndpoint()}
91
+ </Highlight>
92
+ <div className="flex justify-end relative" onClick={handleCopy}>
93
+ <BiSolidCopy className="text-slate-500 cursor-pointer hover:text-slate-300 transition-all duration-75" />
94
+ <div
95
+ className={classNames(
96
+ "bg-indigo-500/60 text-slate-100 text-xs font-semibold absolute bottom-0 right-0 z-10 rounded-lg px-2 py-1 pointer-events-none -translate-y-full transition-all duration-200",
97
+ {
98
+ "opacity-0": !isCopied,
99
+ }
100
+ )}
101
+ >
102
+ Copied!
103
+ </div>
104
+ </div>
105
+ </main>
106
+ </div>
107
+ );
108
+ };
components/editor/main/snippet/python.tsx ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { ApiRoute } from "@/utils/type";
2
+ import classNames from "classnames";
3
+ import { useState } from "react";
4
+ import Highlight from "react-highlight";
5
+ import { BiLogoPython, BiSolidCopy } from "react-icons/bi";
6
+ import { Options } from "redaxios";
7
+
8
+ export const PythonSnippet = ({
9
+ endpoint,
10
+ headers,
11
+ parameters,
12
+ body,
13
+ onCopyToClipboard,
14
+ }: {
15
+ endpoint: ApiRoute;
16
+ parameters?: Record<string, any>;
17
+ headers?: Record<string, any>;
18
+ body?: Options | undefined;
19
+ onCopyToClipboard: (e: string) => void;
20
+ }) => {
21
+ const [isCopied, setIsCopied] = useState<boolean>(false);
22
+
23
+ const generatePythonRequestFromEndpoint = () => {
24
+ const { method, path } = endpoint;
25
+ const fullpath = `${process.env.NEXT_PUBLIC_APP_APIURL}${path}`;
26
+
27
+ const removeEmptyValues = (data: Record<string, any>) => {
28
+ const formattedData = { ...data };
29
+ Object.entries(formattedData).forEach(([key, value]) => {
30
+ if (!value) {
31
+ delete formattedData[key];
32
+ }
33
+ if (typeof value === "boolean") {
34
+ formattedData[key] = value ? "True" : "False";
35
+ }
36
+ });
37
+ return formattedData;
38
+ };
39
+
40
+ const Dict: Record<string, any> = {
41
+ GET: () => {
42
+ const filteredEmptyParameters = removeEmptyValues(parameters ?? {});
43
+
44
+ return `import requests
45
+ response = requests.get(
46
+ "${fullpath}",
47
+ params=${JSON.stringify(filteredEmptyParameters)},
48
+ headers=${JSON.stringify(headers)}
49
+ )`;
50
+ },
51
+ DELETE: () => {
52
+ const formattedBody = removeEmptyValues(body ?? {});
53
+ return `import requests
54
+ response = requests.delete(
55
+ "${fullpath}",
56
+ data=${JSON.stringify(formattedBody)},
57
+ headers=${JSON.stringify(headers)}
58
+ )`;
59
+ },
60
+ DEFAULT: () => {
61
+ const formattedBody = removeEmptyValues(body ?? {});
62
+ return `import requests
63
+ response = requests.${method.toLocaleLowerCase()}(
64
+ "${fullpath}",
65
+ json=${JSON.stringify(formattedBody)},
66
+ headers=${JSON.stringify(headers)}
67
+ )`;
68
+ },
69
+ };
70
+
71
+ return Dict[method] ? Dict[method]() : Dict["DEFAULT"]();
72
+ };
73
+
74
+ const handleCopy = () => {
75
+ onCopyToClipboard(generatePythonRequestFromEndpoint());
76
+ setIsCopied(true);
77
+ setTimeout(() => {
78
+ setIsCopied(false);
79
+ }, 1000);
80
+ };
81
+
82
+ return (
83
+ <div className="bg-slate-950/50 rounded-xl overflow-hidden">
84
+ <header className="bg-slate-950 flex items-center justify-start px-5 py-4 uppercase gap-2 text-blue-500">
85
+ <BiLogoPython className="text-xl" />
86
+ <p className="text-xs font-semibold">Python</p>
87
+ </header>
88
+ <main className="px-6 py-6">
89
+ <Highlight className="python text-xs font-code !bg-transparent !p-0 !whitespace-pre-wrap break-all !leading-relaxed">
90
+ {generatePythonRequestFromEndpoint()}
91
+ </Highlight>
92
+ <div className="flex justify-end relative" onClick={handleCopy}>
93
+ <BiSolidCopy className="text-slate-500 cursor-pointer hover:text-slate-300 transition-all duration-75" />
94
+ <div
95
+ className={classNames(
96
+ "bg-indigo-500/60 text-slate-100 text-xs font-semibold absolute bottom-0 right-0 z-10 rounded-lg px-2 py-1 pointer-events-none -translate-y-full transition-all duration-200",
97
+ {
98
+ "opacity-0": !isCopied,
99
+ }
100
+ )}
101
+ >
102
+ Copied!
103
+ </div>
104
+ </div>
105
+ </main>
106
+ </div>
107
+ );
108
+ };