Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
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 |
-
|
| 45 |
-
|
|
|
|
|
|
|
| 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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
-
|
| 16 |
-
|
| 17 |
-
|
| 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
|
| 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 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
|
| 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 |
+
};
|