1
0
Fork 0
mirror of https://github.com/pawelmalak/flame.git synced 2025-07-19 11:39:36 +02:00
flame/client/src/components/Apps/AppForm/AppForm.tsx

217 lines
5.7 KiB
TypeScript
Raw Normal View History

2021-07-28 12:36:03 +02:00
import { useState, useEffect, ChangeEvent, SyntheticEvent } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { NewApp } from '../../../interfaces';
2021-06-23 15:27:46 +02:00
import classes from './AppForm.module.css';
import { ModalForm, InputGroup, Button } from '../../UI';
2021-11-08 23:40:30 +01:00
import { inputHandler, newAppTemplate } from '../../../utility';
import { bindActionCreators } from 'redux';
import { actionCreators } from '../../../store';
import { State } from '../../../store/reducers';
interface Props {
modalHandler: () => void;
}
export const AppForm = ({ modalHandler }: Props): JSX.Element => {
const { appInUpdate } = useSelector((state: State) => state.apps);
const dispatch = useDispatch();
const { addApp, updateApp, setEditApp } = bindActionCreators(
actionCreators,
dispatch
);
const [useCustomIcon, toggleUseCustomIcon] = useState<boolean>(false);
2021-06-23 15:27:46 +02:00
const [customIcon, setCustomIcon] = useState<File | null>(null);
2021-11-08 23:40:30 +01:00
const [formData, setFormData] = useState<NewApp>(newAppTemplate);
2021-05-22 17:03:32 +02:00
useEffect(() => {
if (appInUpdate) {
2021-05-22 17:03:32 +02:00
setFormData({
...appInUpdate,
2021-08-06 15:15:54 +02:00
});
2021-05-26 13:13:56 +02:00
} else {
2021-11-08 23:40:30 +01:00
setFormData(newAppTemplate);
2021-05-22 17:03:32 +02:00
}
}, [appInUpdate]);
2021-05-22 17:03:32 +02:00
2021-11-08 23:40:30 +01:00
const inputChangeHandler = (
e: ChangeEvent<HTMLInputElement | HTMLSelectElement>,
options?: { isNumber?: boolean; isBool?: boolean }
) => {
inputHandler<NewApp>({
e,
options,
setStateHandler: setFormData,
state: formData,
2021-08-06 15:15:54 +02:00
});
};
2021-06-23 15:27:46 +02:00
const fileChangeHandler = (e: ChangeEvent<HTMLInputElement>): void => {
if (e.target.files) {
setCustomIcon(e.target.files[0]);
}
2021-08-06 15:15:54 +02:00
};
2021-06-23 15:27:46 +02:00
const formSubmitHandler = (e: SyntheticEvent<HTMLFormElement>): void => {
e.preventDefault();
2021-05-22 17:03:32 +02:00
2021-07-28 11:36:48 +02:00
const createFormData = (): FormData => {
const data = new FormData();
2021-10-05 17:08:37 +02:00
2021-06-23 15:27:46 +02:00
if (customIcon) {
data.append('icon', customIcon);
2021-07-28 11:36:48 +02:00
}
2021-07-28 11:36:48 +02:00
data.append('name', formData.name);
data.append('description', formData.description);
2021-07-28 11:36:48 +02:00
data.append('url', formData.url);
data.append('isPublic', `${formData.isPublic ? 1 : 0}`);
2021-06-23 15:27:46 +02:00
2021-07-28 11:36:48 +02:00
return data;
2021-08-06 15:15:54 +02:00
};
2021-06-23 15:27:46 +02:00
if (!appInUpdate) {
2021-07-28 11:36:48 +02:00
if (customIcon) {
const data = createFormData();
addApp(data);
2021-06-23 15:27:46 +02:00
} else {
addApp(formData);
2021-06-23 15:27:46 +02:00
}
2021-05-22 17:03:32 +02:00
} else {
2021-07-28 11:36:48 +02:00
if (customIcon) {
const data = createFormData();
updateApp(appInUpdate.id, data);
2021-07-28 11:36:48 +02:00
} else {
updateApp(appInUpdate.id, formData);
modalHandler();
2021-07-28 11:36:48 +02:00
}
2021-05-22 17:03:32 +02:00
}
2021-11-08 23:40:30 +01:00
setFormData(newAppTemplate);
setEditApp(null);
2021-08-06 15:15:54 +02:00
};
return (
<ModalForm modalHandler={modalHandler} formHandler={formSubmitHandler}>
2021-11-08 23:40:30 +01:00
{/* NAME */}
<InputGroup>
<label htmlFor="name">App name</label>
<input
2021-10-05 17:08:37 +02:00
type="text"
name="name"
id="name"
placeholder="Bookstack"
required
value={formData.name}
2021-10-05 17:08:37 +02:00
onChange={(e) => inputChangeHandler(e)}
/>
</InputGroup>
2021-11-08 23:40:30 +01:00
{/* URL */}
<InputGroup>
2021-10-05 17:08:37 +02:00
<label htmlFor="url">App URL</label>
<input
2021-10-05 17:08:37 +02:00
type="text"
name="url"
id="url"
placeholder="bookstack.example.com"
required
value={formData.url}
2021-10-05 17:08:37 +02:00
onChange={(e) => inputChangeHandler(e)}
/>
</InputGroup>
2021-11-08 23:40:30 +01:00
{/* DESCRIPTION */}
<InputGroup>
<label htmlFor="description">App description</label>
<input
type="text"
name="description"
id="description"
placeholder="My self-hosted app"
value={formData.description}
onChange={(e) => inputChangeHandler(e)}
/>
<span>
Optional - If description is not set, app URL will be displayed
</span>
</InputGroup>
2021-11-08 23:40:30 +01:00
{/* ICON */}
2021-08-06 15:15:54 +02:00
{!useCustomIcon ? (
2021-06-23 15:27:46 +02:00
// use mdi icon
2021-08-06 15:15:54 +02:00
<InputGroup>
<label htmlFor="icon">App icon</label>
2021-08-06 15:15:54 +02:00
<input
2021-10-05 17:08:37 +02:00
type="text"
name="icon"
id="icon"
placeholder="book-open-outline"
2021-08-06 15:15:54 +02:00
required
value={formData.icon}
2021-10-05 17:08:37 +02:00
onChange={(e) => inputChangeHandler(e)}
2021-08-06 15:15:54 +02:00
/>
<span>
Use icon name from MDI or pass a valid URL.
2021-10-05 17:08:37 +02:00
<a href="https://materialdesignicons.com/" target="blank">
2021-08-06 15:15:54 +02:00
{' '}
Click here for reference
</a>
</span>
<span
onClick={() => toggleUseCustomIcon(!useCustomIcon)}
className={classes.Switch}
>
Switch to custom icon upload
</span>
</InputGroup>
) : (
2021-06-23 15:27:46 +02:00
// upload custom icon
2021-08-06 15:15:54 +02:00
<InputGroup>
2021-10-05 17:08:37 +02:00
<label htmlFor="icon">App Icon</label>
2021-08-06 15:15:54 +02:00
<input
2021-10-05 17:08:37 +02:00
type="file"
name="icon"
id="icon"
2021-08-06 15:15:54 +02:00
required
2021-10-05 17:08:37 +02:00
onChange={(e) => fileChangeHandler(e)}
2021-11-20 14:18:42 +01:00
accept=".jpg,.jpeg,.png,.svg,.ico"
2021-08-06 15:15:54 +02:00
/>
<span
2021-10-05 17:08:37 +02:00
onClick={() => {
setCustomIcon(null);
toggleUseCustomIcon(!useCustomIcon);
}}
2021-08-06 15:15:54 +02:00
className={classes.Switch}
>
Switch to MDI
</span>
</InputGroup>
)}
2021-11-08 23:40:30 +01:00
{/* VISIBILITY */}
<InputGroup>
<label htmlFor="isPublic">App visibility</label>
<select
id="isPublic"
name="isPublic"
value={formData.isPublic ? 1 : 0}
onChange={(e) => inputChangeHandler(e, { isBool: true })}
>
<option value={1}>Visible (anyone can access it)</option>
<option value={0}>Hidden (authentication required)</option>
</select>
</InputGroup>
{!appInUpdate ? (
2021-08-06 15:15:54 +02:00
<Button>Add new application</Button>
) : (
<Button>Update application</Button>
)}
</ModalForm>
2021-08-06 15:15:54 +02:00
);
};