diff --git a/src/components/Form.tsx b/src/components/Form.tsx index 7c8b68f..72601cf 100644 --- a/src/components/Form.tsx +++ b/src/components/Form.tsx @@ -1,5 +1,7 @@ import React, { useEffect, useState } from "react"; import KeyValuePair from "./KeyValuePair"; +import KeyValuePair2 from "./KeyValuePair2"; + import JsonEditor from "./Editors"; import { FaPaperPlane } from "react-icons/fa6"; import { IoMdDownload } from "react-icons/io"; @@ -19,6 +21,7 @@ const Form: React.FC = ({ onSubmit, content, setisRefresh }) => { const [headers, setHeaders] = useState( content?.header ?? [{ key: "", value: "" }] ); + const [formData, setformData] = useState(content?.form_data ?? [{ key: "", value: "" }]); const [jsonBody, setJsonBody] = useState(content ?? {}); const [activeTab, setActiveTab] = useState("query-params"); @@ -39,27 +42,72 @@ const Form: React.FC = ({ onSubmit, content, setisRefresh }) => { setHeaders([...headers, { key: "", value: "" }]); setisSaved(false); }; + const handleAddFormData = () => { + setformData([...formData, { key: "", value: "" }]); + setisSaved(false); + }; + // const handleSubmit = (e: React.FormEvent) => { + // e.preventDefault(); + // const params = queryParams.reduce((acc, { key, value }) => { + // if (key) acc[key] = value; + // return acc; + // }, {} as Record); + + // const headerObj = headers.reduce((acc, { key, value }) => { + // if (key) acc[key] = value; + // return acc; + // }, {} as Record); + + // onSubmit({ + // method, + // url, + // params, + // headers: headerObj, + // data: jsonBody, + // }); + // }; const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); + + // Reduce query parameters and headers to objects const params = queryParams.reduce((acc, { key, value }) => { if (key) acc[key] = value; return acc; }, {} as Record); - + const headerObj = headers.reduce((acc, { key, value }) => { if (key) acc[key] = value; return acc; }, {} as Record); - + + // If formData is not empty, convert it to FormData + let data: Record | FormData; + if (formData.length > 0) { + data = new FormData(); + formData.forEach(({ key, value }) => { + if (key) { + if (value instanceof File) { + data.append(key, value); // Append file + } else { + data.append(key, value); // Append text + } + } + }); + } else { + data = jsonBody; // If formData is empty, use jsonBody + } + + // Call onSubmit with the appropriate data onSubmit({ method, url, params, headers: headerObj, - data: jsonBody, + data, }); }; + const handleRequestEditorChange = (value: string) => { setJsonBody(value); @@ -188,6 +236,19 @@ const Form: React.FC = ({ onSubmit, content, setisRefresh }) => { JSON +
  • + +
  • @@ -256,6 +317,32 @@ const Form: React.FC = ({ onSubmit, content, setisRefresh }) => { />
    )} + {activeTab === "form" && ( +
    + {formData.map((header, index) => ( + + ))} + +
    + )} diff --git a/src/components/KeyValuePair2.tsx b/src/components/KeyValuePair2.tsx new file mode 100644 index 0000000..70a6f7c --- /dev/null +++ b/src/components/KeyValuePair2.tsx @@ -0,0 +1,151 @@ +import React, { useState } from "react"; +import { FaCloudUploadAlt } from "react-icons/fa"; +import { FaArrowDown, FaXmark } from "react-icons/fa6"; + +interface KeyValuePairProps { + index: number; + pair: { key: string; value: string | File[]; type: "text" | "[]" }; + setPairs: React.Dispatch< + React.SetStateAction< + { key: string; value: string | File[]; type: "text" | "file" }[] + > + >; + pairs: { key: string; value: string | File[]; type: "text" | "file" }[]; + setisSaved: React.Dispatch>; +} + +const KeyValuePair: React.FC = ({ + index, + pair, + setPairs, + pairs, + setisSaved, +}) => { + const [type, settype] = useState("text"); + const handleKeyChange = (e: React.ChangeEvent) => { + const newPairs = [...pairs]; + newPairs[index] = { ...newPairs[index], key: e.target.value }; + setPairs(newPairs); + setisSaved(false); + }; + + const handleValueChange = (e: React.ChangeEvent) => { + const newPairs = [...pairs]; + if (type === "text") { + newPairs[index] = { ...newPairs[index], value: e.target.value }; + } else if (type === "file" && e.target.files) { + const files = Array.from(e.target.files); // Support multiple files + newPairs[index] = { ...newPairs[index], value: files }; + } + setPairs(newPairs); + setisSaved(false); + }; + + const handleTypeChange = (e: React.ChangeEvent) => { + const newPairs = [...pairs]; + settype(e.target.value); + newPairs[index] = { + ...newPairs[index], + type: e.target.value, + value: "", + }; + setPairs(newPairs); + setisSaved(false); + }; + const handleRemoveFile = (fileToRemove: File) => { + const newPairs = [...pairs]; + const updatedFiles = (newPairs[index].value as File[]).filter( + (file) => file !== fileToRemove + ); + newPairs[index] = { ...newPairs[index], value: updatedFiles }; + setPairs(newPairs); + setisSaved(false); + }; + const handleRemove = () => { + const newPairs = pairs.filter((_, i) => i !== index); + setPairs(newPairs); + setisSaved(false); + }; + + const handleFileClick = () => { + const fileInput = document.getElementById(`file-input-${index}`); + if (fileInput) { + fileInput.click(); + } + }; + return ( +
    + + + + + {type === "text" ? ( + + ) : ( +
    + + + {Array.isArray(pair.value) && pair.value.length > 0 && ( +
    + {pair.value.map((file, idx) => ( +
    + {file.name} + +
    + ))} +
    + )} +
    + )} + + +
    + ); +}; + +export default KeyValuePair;