mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-13 03:13:47 +00:00
c070389937
Every viewer page (Timer, Countdown, Backstage, Studio, Timeline, ProjectInfo, Operator) re-implemented the same data-loader flow by hand, each with a hard-coded, unlocalized error string and drifting empty-state styling. This centralizes that flow and elevates the shared presentation. - Add ViewDataBoundary: a single component that renders the shared loading, error and optional no-data states from a QueryStatus, so every view handles them the same obvious way. Refactor all seven view loaders through it. - Localize the error state via new common.fetch_error / common.fetch_error_hint keys (en + de/es/fr/it/pt), replacing the duplicated English literal with a two-line "Something went wrong / Please refresh the page" message. - Elevate the shared Empty component: legible viewer-secondary color (was 10% white), responsive title sizing, softened illustration, optional supporting subtitle line, and a reduced-motion-safe fade-in. - Unify loading: Cuesheet and the rundown table now use the animated Loader like every other view instead of an untranslated "Loading..." page. - Tidy up: EmptyTableBody uses Empty's text prop, drop Countdown's now-redundant size override, and remove a stray semicolon rendered in the ProjectInfo empty state. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vq5XLTSQhU9ckZmCSW2SEr
35 lines
1.1 KiB
TypeScript
35 lines
1.1 KiB
TypeScript
import { SupportedEntry } from 'ontime-types';
|
|
import { IoAdd } from 'react-icons/io5';
|
|
|
|
import { useTranslation } from '../../../translation/TranslationProvider';
|
|
import Button from '../buttons/Button';
|
|
import Empty from './Empty';
|
|
|
|
import style from './EmptyTableBody.module.scss';
|
|
|
|
interface EmptyTableBodyProps {
|
|
handleAddNew?: (type: SupportedEntry) => void;
|
|
}
|
|
|
|
export default function EmptyTableBody({ handleAddNew }: EmptyTableBodyProps) {
|
|
const { getLocalizedString } = useTranslation();
|
|
const text = getLocalizedString('common.no_data');
|
|
return (
|
|
<tbody className={style.emptyContainer}>
|
|
<tr>
|
|
<td colSpan={99} className={style.emptyCell}>
|
|
<Empty text={text} injectedStyles={{ marginTop: '5vh' }} />
|
|
{handleAddNew && (
|
|
<div className={style.inline}>
|
|
<Button onClick={() => handleAddNew(SupportedEntry.Event)} variant='primary' size='large'>
|
|
<IoAdd />
|
|
Create Event
|
|
</Button>
|
|
</div>
|
|
)}
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
);
|
|
}
|