mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-12 19:03:47 +00:00
76c8f8a4d5
* 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
194 lines
6.0 KiB
React
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>
|
|
);
|
|
}
|