Files
ontime/apps/client/src/features/modals/EventSettingsModal.jsx
T
Carlos Valente 76c8f8a4d5 V2 ws store (#310)
* Update TimerService.ts

* refactor: message service publishes to store

* refactor: several type improvements

* V2 ws store wss (#309)

* refactor: shared logging types

* refactor: simplify message service consumption

* refactor: create discrete logging system

* refactor: move socket.io > websocket
2023-03-15 22:06:47 +01:00

194 lines
6.0 KiB
React

import { useCallback, useEffect, useState } from 'react';
import { FormLabel, Input, ModalBody, Textarea } from '@chakra-ui/react';
import { useEmitLog } from '@/common/stores/logger';
import { postEventData } from '../../common/api/eventDataApi';
import useEventData from '../../common/hooks-query/useEventData';
import { eventDataPlaceholder } from '../../common/models/EventData';
import { inputProps } from './modalHelper';
import SubmitContainer from './SubmitContainer';
import style from './Modals.module.scss';
export default function SettingsModal() {
const { data, status, refetch } = useEventData();
const { emitError } = useEmitLog();
const [formData, setFormData] = useState(eventDataPlaceholder);
const [changed, setChanged] = useState(false);
const [submitting, setSubmitting] = useState(false);
/**
* Set formdata from server state
*/
useEffect(() => {
if (data == null) return;
if (changed) return;
setFormData({
title: data.title,
publicUrl: data.publicUrl,
publicInfo: data.publicInfo,
backstageUrl: data.backstageUrl,
backstageInfo: data.backstageInfo,
endMessage: data.endMessage,
});
}, [changed, data]);
/**
* Validate and submit data
*/
const submitHandler = useCallback(
async (event) => {
event.preventDefault();
setSubmitting(true);
try {
await postEventData(formData);
} catch (error) {
emitError(`Error saving event settings: ${error}`);
} finally {
await refetch();
setChanged(false);
}
setSubmitting(false);
},
[emitError, formData, refetch],
);
/**
* Reverts local state equals to server state
*/
const revert = useCallback(async () => {
setChanged(false);
await refetch();
}, [refetch]);
/**
* Handles change of input field in local state
* @param {string} field - object parameter to update
* @param {string} value - new object parameter value
*/
const handleChange = useCallback(
(field, value) => {
const temp = { ...formData };
temp[field] = value;
setFormData(temp);
setChanged(true);
},
[formData],
);
return (
<ModalBody className={style.modalBody}>
<p className={style.notes}>
Options related to the running event
<br />
Affects rendered views
</p>
<form onSubmit={submitHandler}>
<div className={style.modalFields}>
<div className={style.hSeparator}>Event Data</div>
<div className={style.spacedEntry}>
<FormLabel htmlFor='title'>Event Title</FormLabel>
<Input
{...inputProps}
maxLength={35}
name='title'
placeholder='Event Title'
value={formData.title}
onChange={(event) => handleChange('title', event.target.value)}
/>
</div>
<div className={style.hSeparator}>Additional Screen Info</div>
<div className={style.spacedEntry}>
<FormLabel htmlFor='publicUrl'>
Public URL
<span className={style.labelNote}>
<br />
QR code to be shown on public screens
</span>
</FormLabel>
<Input
{...inputProps}
name='publicUrl'
placeholder='www.getontime.no'
value={formData.publicUrl}
onChange={(event) => handleChange('publicUrl', event.target.value)}
/>
</div>
<div className={style.spacedEntry}>
<FormLabel htmlFor='pubInfo'>
Public Info
<span className={style.labelNote}>
<br />
Information to be shown on public screens
</span>
</FormLabel>
<Textarea
{...inputProps}
name='pubInfo'
placeholder='Information to be shown on public screens'
value={formData.publicInfo}
onChange={(event) => handleChange('publicInfo', event.target.value)}
/>
</div>
<div className={style.spacedEntry}>
<FormLabel htmlFor='backstageUrl'>
Backstage URL
<span className={style.labelNote}>
<br />
QR to be shown on backstage screens
</span>
</FormLabel>
<Input
{...inputProps}
name='backstageUrl'
placeholder='www.getontime.no'
value={formData.backstageUrl}
onChange={(event) => handleChange('backstageUrl', event.target.value)}
/>
</div>
<div className={style.spacedEntry}>
<FormLabel htmlFor='backstageInfo'>
Backstage Info
<span className={style.labelNote}>
<br />
Information to be shown on backstage screens
</span>
</FormLabel>
<Textarea
{...inputProps}
name='backstageInfo'
placeholder='Information to be shown on backstage screens'
resize={false}
value={formData.backstageInfo}
onChange={(event) => handleChange('backstageInfo', event.target.value)}
/>
</div>
<div className={style.spacedEntry}>
<FormLabel htmlFor='endMessage'>
End Message
<span className={style.labelNote}>
<br />
Shown on presenter view when time is finished
</span>
</FormLabel>
<Input
{...inputProps}
maxLength={30}
name='endMessage'
placeholder='Empty message shows elapsed time'
value={formData.endMessage}
onChange={(event) => handleChange('endMessage', event.target.value)}
/>
</div>
</div>
<SubmitContainer revert={revert} submitting={submitting} changed={changed} status={status} />
</form>
</ModalBody>
);
}