UNPKG

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

135 lines (114 loc) 5.71 kB
import { useState } from 'react'; import { AtomSpinner } from "react-epic-spinners"; import { FaFile } from 'react-icons/fa'; import AceEditorWrapper from '../../../components/Editors/ACE/AceEditor'; import MultiPageForm from '../../../components/Forms/MultiPageForm'; import AiTrainingForms from '../../../components/Forms/exportTrainingForms'; import React from 'react'; const EditableControls = ({ onSave, onCancel }) => ( <> <button onClick={onSave} className="absolute top-2 right-2 bg-green-500 p-1 rounded-md text-white hover:bg-green-600"></button> <button onClick={onCancel} className="absolute top-2 right-10 bg-red-500 p-1 rounded-md text-white hover:bg-red-600">×</button> </> ); const EditableFileView = ({ value, tempValue, onFileChange }) => { if (tempValue && typeof tempValue === 'object') { return <img src={URL.createObjectURL(tempValue)} alt="Uploaded" className="w-12 h-12 rounded-full border-2 border-blue-500 hover:border-blue-600 transition-all duration-300" />; } if (value) { return ( <> <img src={value} alt="Stored" className="w-12 h-12 rounded-full border-2 border-blue-500 hover:border-blue-600 transition-all duration-300" /> <span className="material-icons ml-2">attach_file</span> <span className="truncate ml-2">{value.split('/').pop()}</span> </> ); } return ( <label className="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-3 inline-flex items-center cursor-pointer rounded"> <FaFile className="mr-2"/> Upload <input type="file" accept="image/*" onChange={onFileChange} className="hidden" /> </label> ); }; const EditableBubble = ({ label, value, onChange, type = "text", bgColor }) => { const [selectedFormKey, setSelectedFormKey] = useState(null); const [isEditing, setIsEditing] = useState(false); const [tempValue, setTempValue] = useState(value); const handleChange = () => { setIsEditing(false); onChange(tempValue); }; let widthClass = ""; switch (type) { case "AiTrainingForm": widthClass = "w-1/2"; break; case "AceEditor": widthClass = "w-1/3"; break; case "textarea": widthClass = "min-w-500px"; break; default: widthClass = "w-auto"; // let content determine width break; } return ( <div style={{ backgroundColor: bgColor }} className={`border-4 ${widthClass} border-red-600 relative shadow-xl h-full min-h-[180px] max-w-[500px] `} > {isEditing ? ( <div className=''> {type === "AiTrainingForm" && <div> {/* Dropdown for form selection */} <select onChange={(e) => setSelectedFormKey(e.target.value)} value={selectedFormKey}> <option value="" disabled>Select a form...</option> {Object.keys(AiTrainingForms).map((key) => ( <option key={key} value={key}> {key.charAt(0).toUpperCase() + key.slice(1)} {/* Convert key to Title Case */} </option> ))} </select> {/* Display form based on selection */} {selectedFormKey && <MultiPageForm pages={AiTrainingForms[selectedFormKey]} model={'YourModel'} endpoint={'YourEndpoint'} token={'YourToken'} AIMode={true} /> } </div> } {type === "AceEditor" && <AceEditorWrapper value={tempValue} onChange={setTempValue} className="" /> } {type === "input" && <input value={tempValue} onChange={e => setTempValue(e.target.value)} className="w-full p-2 border rounded-md shadow-sm focus:border-blue-500 focus:ring focus:ring-blue-200 focus:ring-opacity-50" />} {type === "textarea" && <textarea value={tempValue} onChange={e => setTempValue(e.target.value)} className="w-full p-2 border rounded-md shadow-sm focus:border-blue-500 focus:ring focus:ring-blue-200 focus:ring-opacity-50"></textarea>} {type === "file" && <EditableFileView value={value} tempValue={tempValue} onFileChange={e => setTempValue(e.target.files[0])} />} {type === "number" && <input type="number" value={tempValue} onChange={e => setTempValue(e.target.value)} className="w-full p-2 border rounded-md shadow-sm focus:border-blue-500 focus:ring focus:ring-blue-200 focus:ring-opacity-50" />} <EditableControls onSave={handleChange} onCancel={() => setIsEditing(false)} /> </div> ) : ( <> <div className="flex items-center flex-grow"> <span className="font-bold">{label}:</span> {type !== "file" && (value || value === 0) && <span className={type === "textarea" ? "truncate" : "font-bold ml-2"}>{value}</span>} {type === "file" && <EditableFileView value={value} tempValue={tempValue} onFileChange={null} />} </div> <button onClick={() => setIsEditing(true)} className="absolute top-2 right-2 bg-blue-500 p-1 rounded-md text-white">✎</button> </> )} </div> ); }; export default EditableBubble;