UNPKG

leumas-universal-crud-react

Version:

Leumas Universal CRUD to a dynamic Endpoint, Setup your own Dynamic Endpoint and Use Leumas API to send to your MONGO clusters

473 lines (405 loc) 13.1 kB
import { LeumasBaseStyle, InputStyles, PasswordStyles, EmailStyles, NumberStyles, DateStyles, TextareaStyles, SelectStyles, SelectOptionStylexs, MultiSelectStyles, CheckboxStyles, AiModelsStyles, SliderStyles, NonChangeableTextStyles, FileUploadStyles, ImageUploadStyles, } from "../styles/baseStyles" import AceEditorWrapper from "../Editors/ACE/AceEditor" import AceSplitEditorWrapper from "../Editors/ACE/AceSplitEditorWrapper" import BarcodeGenerator from "../Generators/BarcodeGenerator"; import SerialCodeGenerator from "../Generators/SerialCodeGenerator"; import MetaMaskButton from "leumas-metamask-quickpay" // import UploaderToCloudinary from "../../helpers/UploaderToCloudinary"; function renderInputField({ inputField, formValues, handleInputChange, handleFileChange, styledInput, aiModels = [], setSearchTerm, selectedItemId, handleImageUpload, handleFileUpload, handleFolderUpload, handleCheckboxChange, }) { switch (inputField.type) { case 'password': return ( <> <label className="mx-2"><strong>{inputField?.label || "Enter Password"}</strong></label> <input className={`${LeumasBaseStyle} w-full`} type={"password"} name={inputField.name} placeholder={inputField.placeholder} value={formValues[inputField.name] || ''} onChange={handleInputChange} /> </> ); case 'email': return (<> <label className="mx-2"><strong>{inputField?.label || "Enter Email" }</strong></label> <div className="relative"> <div className="absolute inset-y-0 start-0 flex items-center ps-3.5 pointer-events-none"> <svg className="w-4 h-4 text-gray-500 dark:text-gray-400" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 16"> <path d="m10.036 8.278 9.258-7.79A1.979 1.979 0 0 0 18 0H2A1.987 1.987 0 0 0 .641.541l9.395 7.737Z"/> <path d="M11.241 9.817c-.36.275-.801.425-1.255.427-.428 0-.845-.138-1.187-.395L0 2.6V14a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V2.5l-8.759 7.317Z"/> </svg> </div> <input className={`bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full ps-10 p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500`} type={inputField.type} name={inputField.name} placeholder={inputField.placeholder} value={formValues[inputField.name] || ''} onChange={handleInputChange} /> </div> </> ); case 'text': return ( <> <label className="mx-2"><strong>{inputField?.label || "Text Input" }</strong></label> <input className={`${LeumasBaseStyle} w-full`} type={inputField.type} name={inputField.name} placeholder={inputField.placeholder} value={formValues[inputField.name] || ''} onChange={handleInputChange} /> </> ); case 'number': return ( <> <label className="mx-2"><strong>{inputField?.label || "Enter Number"}</strong></label> <input className={`${LeumasBaseStyle} w-full`} type={"number"} name={inputField.name} placeholder={inputField.placeholder} value={formValues[inputField.name] || ''} onChange={handleInputChange} /> </> ); case 'date': return ( <> <label className="mx-2"><strong>{inputField?.label || "Date of Birth" }</strong></label> <input className={`${LeumasBaseStyle} w-full`} type={inputField.type} name={inputField.name} placeholder={inputField.placeholder} value={formValues[inputField.name] || ''} onChange={handleInputChange} /> </> ); case 'textarea': return ( <> <label className="mx-2"><strong>{inputField?.label || "Enter Text" }</strong></label> <textarea className={`${LeumasBaseStyle} w-full max-h-64 min-h-32 p-4`} name={inputField.name} placeholder={inputField.placeholder} value={formValues[inputField.name] || ''} onChange={handleInputChange} /> </> ); case 'metamask': return ( <> <label className="mx-2"><strong>Metamask Wallet</strong></label> <MetaMaskButton onDataChange={(address) => { handleInputChange({ target: { name: inputField.name, value: address } }); }} /> </> ); case 'select': return ( <> <label className="mx-2"><strong>{inputField?.label || "Select Input"}</strong></label> <select className={`${LeumasBaseStyle} w-full`} name={inputField.name} value={formValues[inputField.name] || ''} onChange={handleInputChange} > <option value="" disabled>{inputField.placeholder}</option> {inputField.options.map((option, optIdx) => ( // Assuming `option` is a string, use it for both the value and the label <option key={optIdx} value={option}> {option} </option> ))} </select> </> ); case 'multiSelect': return ( <> <label className="mx-2"><strong>{inputField?.name || "Multi Select" }</strong></label> <select className={`${LeumasBaseStyle} w-full`} name={inputField.name} value={formValues[inputField.name] || ''} onChange={handleInputChange} multiple > <option className="bg-blue-400 text-white" value="">{inputField.placeholder}</option> {inputField.options.map((option, optIdx) => ( <option className="bg-blue-400 text-white" key={optIdx} value={option}> {option} </option> ))} </select> </> ); case 'checkbox': return ( <> <label className="mx-2"><strong>{inputField?.label || "Checkbox"}</strong></label> <div className="flex items-center py-2 justify-start px-4"> <label className="inline-flex items-center cursor-pointer"> <input className="sr-only peer" // Hide the checkbox visually but keep it accessible type="checkbox" name={inputField.name} checked={formValues[inputField.name] || false} // Ensures the checkbox reflects its current state onChange={handleCheckboxChange} // Handle changes to toggle the checkbox /> <span className="w-5 h-5 inline-flex justify-center items-center mr-2 rounded border border-gray-300 peer-checked:bg-blue-600 peer-checked:border-blue-600 peer-focus:ring peer-focus:ring-blue-500 peer-focus:ring-opacity-50 transition duration-150 ease-in-out"> <svg className="w-4 h-4 text-white hidden peer-checked:block" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M5 13l4 4L19 7"></path></svg> </span> {inputField.question || "True or False"} </label> </div> </> ); case 'AiModels': return ( <> <label className="mx-2"><strong>{inputField?.label || "Leumas AI Models" }</strong></label> <select className={`${LeumasBaseStyle} w-full`} name={inputField.name} value={formValues[inputField.name] || ''} onChange={handleInputChange} > <option value="">{inputField.placeholder}</option> {aiModels.map((model, idx) => ( <option className="bg-blue-400 text-white" key={idx} value={model.name}> {model.name} </option> ))} </select> </> ); case 'slider': return ( <> <label className="mx-2"><strong>{inputField?.label || "Slider"}</strong></label> <input className={`${LeumasBaseStyle} w-full`} type="range" name={inputField.name} min={inputField.min || '0'} max={inputField.max || '100'} // Ensure the value is set to the midpoint between min and max if not already defined in formValues value={formValues[inputField.name] || (Number(inputField.min || 0) + Number(inputField.max || 100)) / 2} onChange={handleInputChange} /> <div className="flex items-center justify-between w-full shadow-lg p-2 border rounded-lg px-4"> <p><strong>MIN : </strong>{inputField?.min || 0}</p> {/* Calculate and display the value as the midpoint between min and max or from formValues */} <p><strong>Value: </strong>{formValues[inputField.name] || (Number(inputField.min || 0) + Number(inputField.max || 100)) / 2}</p> <p><strong>MAX : </strong>{inputField?.max || 100}</p> </div> </> ); case 'hidden': return ( <input className={`${LeumasBaseStyle} w-full`} type="hidden" name={inputField.name} defaultValue={inputField.value} value={inputField.value} /> ); case 'owner': return ( <input className={`${LeumasBaseStyle} w-full`} type="hidden" name={inputField.name} value={inputField.value} // Assuming this is the user ID /> ); case 'nonChangeableText': return ( <> <label className="mx-2"><strong>{inputField?.label || "Non Changeable Text"}</strong></label> <input className={`${LeumasBaseStyle} w-full bg-gray-500 p-2`} readOnly name={inputField.name} value={inputField.value} // Assuming this is the user ID /> </> ); case 'fileUpload': return ( <> <label><strong>{inputField?.label || "Upload File"}</strong></label> <input className={`${LeumasBaseStyle} w-full`} type="file" name={inputField.name} accept={inputField.accept || "*"} // Allows dynamic declaration of accepted files onChange={handleFileUpload} /> {formValues[inputField.name] && ( <div className="mt-2"> <p>File uploaded successfully.</p> </div> )} </> ); case 'folderUpload': return ( <> <label><strong>{inputField?.label || "Upload Folder"}</strong></label> <input className={`${LeumasBaseStyle} w-full`} type="file" name={inputField.name} accept={inputField.accept || "*"} webkitdirectory="true" directory="true" onChange={handleFolderUpload} /> {/* Display the number of files and file details after folder upload */} {formValues[inputField.name] && ( <div className="mt-4"> <h3 className="font-bold text-lg mb-2">Uploaded Folder:</h3> <p className="mb-4">Total Files: {formValues[inputField.name].filesCount}</p> <ul className="w-full max-h-[300px] overflow-y-scroll border border-gray-200 rounded-lg shadow-md space-y-2 p-4"> {formValues[inputField.name].files.map((file, index) => ( <li key={index} className="border border-blue-800 rounded-md p-2 shadow-sm"> <p><strong>Name:</strong> {file.name}</p> <p><strong>Size:</strong> {file.size} bytes</p> <p><strong>Type:</strong> {file.type}</p> </li> ))} </ul> </div> )} </> ); case 'imageUpload': return ( <> <label><strong>{inputField?.label || "Upload Image"}</strong></label> <input className={`${LeumasBaseStyle} w-full`} type="file" name={inputField.name} accept="image/*" onChange={handleImageUpload} /> <label><strong>Uploaded Image</strong></label> {/* Use the state value for the image's blob URL as the src attribute */} {formValues[inputField.name] && <img src={formValues[inputField.name]} alt="Uploaded" style={{ maxWidth: '100%', maxHeight: '400px' }} />} </> ); case 'code': return ( <AceEditorWrapper name={inputField.name} value={formValues[inputField.name] || ''} onChange={handleInputChange} // Additional Ace Editor props can go here... /> ); case 'splitCode': return ( <AceSplitEditorWrapper name={inputField.name} value={formValues[inputField.name] || ''} onChange={handleInputChange} // Additional Split Editor props can go here... /> ); case 'serialCodeGenerator': return ( <SerialCodeGenerator name={inputField.name} value={formValues[inputField.name] || ''} onChange={handleInputChange} // Additional Split Editor props can go here... /> ); case 'barcodeGenerator': return ( <BarcodeGenerator name={inputField.name} value={formValues[inputField.name] || ''} onChange={handleInputChange} id={selectedItemId} // Additional Split Editor props can go here... /> ); default: return null; } } export default renderInputField; // case 'voice': // return ( // <MicComponent // name={inputField.name} // onChange={handleInputChange} // // Additional microphone component props can go here... // /> // ); // case 'image': // return ( // <UploaderToCloudinary // onUpload={(url) => { // handleInputChange({ // target: { name: inputField.name, value: url } // }); // }} // className={`${LeumasBaseStyle} w-full`} // type="file" // name={inputField.name} // accept={inputField.type === 'image' ? "image/*" : "*"} // onChange={handleInputChange} // /> // );