leumas-private-shared
Version:
Private React JSX Package For Leumas Shared Components, Headers, Footers, Asides, Login Pages, API Key Manager and much more. Styles and everything reusable to avoid DRY code across all of our subdomains
475 lines (406 loc) • 13.1 kB
JSX
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 "../Metamask/MetaMaskButton"
import React from 'react';
// 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}
// />
// );