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
134 lines (113 loc) • 5.68 kB
JSX
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';
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;