63 lines
2.0 KiB
TypeScript
63 lines
2.0 KiB
TypeScript
import { useState } from 'react';
|
|
import LoadingIndicator from './LoadingIndicator';
|
|
|
|
type InputTextProps = {
|
|
type: 'text' | 'number';
|
|
name: string;
|
|
value: string | number | null;
|
|
setValue:
|
|
| React.Dispatch<React.SetStateAction<string | null>>
|
|
| React.Dispatch<React.SetStateAction<number | null>>;
|
|
oldValue: string | number | null;
|
|
updateCallback: (arg0: string, arg1: string | boolean | number | null) => void;
|
|
};
|
|
|
|
const InputConfig = ({ type, name, value, setValue, oldValue, updateCallback }: InputTextProps) => {
|
|
const [loading, setLoading] = useState(false);
|
|
const [success, setSuccess] = useState(false);
|
|
|
|
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
if (type === 'number') {
|
|
const inputValue = e.target.value;
|
|
|
|
if (inputValue === '') {
|
|
setValue(null);
|
|
} else {
|
|
const numericValue = Number(inputValue);
|
|
(setValue as React.Dispatch<React.SetStateAction<number | null>>)(numericValue);
|
|
}
|
|
} else {
|
|
(setValue as React.Dispatch<React.SetStateAction<string | null>>)(e.target.value);
|
|
}
|
|
};
|
|
|
|
const handleUpdate = async (name: string, value: string | boolean | number | null) => {
|
|
setLoading(true);
|
|
setSuccess(false);
|
|
updateCallback(name, value);
|
|
setLoading(false);
|
|
setSuccess(true);
|
|
setTimeout(() => setSuccess(false), 3000);
|
|
};
|
|
|
|
return (
|
|
<div>
|
|
<input type={type} name={name} value={value ?? ''} onChange={handleChange} />
|
|
<div className="button-box">
|
|
{value !== null && value !== oldValue && (
|
|
<>
|
|
<button onClick={() => handleUpdate(name, value)}>Update</button>
|
|
{/* eslint-disable-next-line @typescript-eslint/no-explicit-any */}
|
|
<button onClick={() => setValue(oldValue as any)}>Cancel</button>
|
|
</>
|
|
)}
|
|
{oldValue !== null && <button onClick={() => handleUpdate(name, null)}>reset</button>}
|
|
{loading && <LoadingIndicator />}
|
|
{success && <span>✅</span>}
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default InputConfig;
|