mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-12 19:03:47 +00:00
chore: directory restructure
This commit is contained in:
committed by
Carlos Valente
parent
946b6717d2
commit
1edde03bb4
@@ -1,106 +0,0 @@
|
||||
@use '../../../theme/viewerDefs' as *;
|
||||
|
||||
.public-screen {
|
||||
margin: 0;
|
||||
box-sizing: border-box; /* reset */
|
||||
overflow: hidden;
|
||||
width: 100%; /* restrict the page width to viewport */
|
||||
height: 100vh;
|
||||
|
||||
font-family: var(--font-family-override, $viewer-font-family);
|
||||
background: var(--background-color-override, $viewer-background-color);
|
||||
color: var(--color-override, $viewer-color);
|
||||
gap: min(2vh, 16px);
|
||||
padding: min(2vh, 16px) clamp(16px, 10vw, 64px);
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 40vw;
|
||||
grid-template-rows: auto 12px 1fr auto;
|
||||
grid-template-areas:
|
||||
' header header header'
|
||||
' progress progress schedule-nav'
|
||||
' now now schedule'
|
||||
' info info schedule';
|
||||
|
||||
/* =================== HEADER + EXTRAS ===================*/
|
||||
|
||||
.project-header {
|
||||
grid-area: header;
|
||||
font-size: clamp(32px, 4.5vw, 64px);
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.logo {
|
||||
max-width: min(200px, 20vw);
|
||||
max-height: min(100px, 20vh);
|
||||
}
|
||||
|
||||
.clock-container {
|
||||
margin-left: auto;
|
||||
|
||||
.label {
|
||||
font-size: clamp(16px, 1.5vw, 24px);
|
||||
font-weight: 600;
|
||||
color: var(--label-color-override, $viewer-label-color);
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.time {
|
||||
font-size: clamp(32px, 3.5vw, 50px);
|
||||
color: var(--secondary-color-override, $viewer-secondary-color);
|
||||
letter-spacing: 0.05em;
|
||||
line-height: 0.95em;
|
||||
}
|
||||
}
|
||||
|
||||
/* =================== MAIN - NOW ===================*/
|
||||
|
||||
.now-container {
|
||||
grid-area: now;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: min(2vh, 16px);
|
||||
}
|
||||
|
||||
.event {
|
||||
background-color: var(--card-background-color-override, $viewer-card-bg-color);
|
||||
padding: 16px 24px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
/* =================== MAIN - SCHEDULE ===================*/
|
||||
|
||||
.schedule-container {
|
||||
grid-area: schedule;
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
margin-left: clamp(16px, 5vw, 64px);
|
||||
}
|
||||
|
||||
.schedule-nav-container {
|
||||
grid-area: schedule-nav;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.info {
|
||||
grid-area: info;
|
||||
display: flex;
|
||||
gap: max(1vw, 16px);
|
||||
overflow: hidden;
|
||||
|
||||
&__message {
|
||||
font-size: clamp(16px, 1.5vw, 24px);
|
||||
line-height: 1.3em;
|
||||
white-space: pre-line;
|
||||
overflow: hidden;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.qr {
|
||||
padding: 4px;
|
||||
background-color: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
import QRCode from 'react-qr-code';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import { AnimatePresence, motion } from 'framer-motion';
|
||||
import { CustomFields, OntimeEvent, ProjectData, Settings } from 'ontime-types';
|
||||
|
||||
import TitleCard from '../../../common/components/title-card/TitleCard';
|
||||
import ViewLogo from '../../../common/components/view-logo/ViewLogo';
|
||||
import ViewParamsEditor from '../../../common/components/view-params-editor/ViewParamsEditor';
|
||||
import { useWindowTitle } from '../../../common/hooks/useWindowTitle';
|
||||
import { ViewExtendedTimer } from '../../../common/models/TimeManager.type';
|
||||
import { formatTime, getDefaultFormat } from '../../../common/utils/time';
|
||||
import { useTranslation } from '../../../translation/TranslationProvider';
|
||||
import PublicSchedule from '../../../views/common/schedule/PublicSchedule';
|
||||
import { titleVariants } from '../common/animation';
|
||||
import SuperscriptTime from '../common/superscript-time/SuperscriptTime';
|
||||
import { getPropertyValue } from '../common/viewUtils';
|
||||
|
||||
import { getPublicOptions } from './public.options';
|
||||
|
||||
import './Public.scss';
|
||||
|
||||
export const MotionTitleCard = motion(TitleCard);
|
||||
|
||||
interface BackstageProps {
|
||||
customFields: CustomFields;
|
||||
general: ProjectData;
|
||||
isMirrored: boolean;
|
||||
publicEventNow: OntimeEvent | null;
|
||||
publicEventNext: OntimeEvent | null;
|
||||
time: ViewExtendedTimer;
|
||||
publicSelectedId: string | null;
|
||||
settings: Settings | undefined;
|
||||
}
|
||||
|
||||
export default function Public(props: BackstageProps) {
|
||||
const { customFields, general, isMirrored, publicEventNow, publicEventNext, time, publicSelectedId, settings } =
|
||||
props;
|
||||
|
||||
const { getLocalizedString } = useTranslation();
|
||||
const [searchParams] = useSearchParams();
|
||||
|
||||
useWindowTitle('Public Schedule');
|
||||
|
||||
const clock = formatTime(time.clock);
|
||||
const qrSize = Math.max(window.innerWidth / 15, 128);
|
||||
|
||||
const defaultFormat = getDefaultFormat(settings?.timeFormat);
|
||||
const publicOptions = getPublicOptions(defaultFormat, customFields);
|
||||
|
||||
const secondarySource = searchParams.get('secondary-src');
|
||||
const secondaryTextNext = getPropertyValue(publicEventNext, secondarySource);
|
||||
const secondaryTextNow = getPropertyValue(publicEventNow, secondarySource);
|
||||
|
||||
return (
|
||||
<div className={`public-screen ${isMirrored ? 'mirror' : ''}`} data-testid='public-view'>
|
||||
<ViewParamsEditor viewOptions={publicOptions} />
|
||||
<div className='project-header'>
|
||||
{general?.projectLogo && <ViewLogo name={general.projectLogo} className='logo' />}
|
||||
{general.title}
|
||||
<div className='clock-container'>
|
||||
<div className='label'>{getLocalizedString('common.time_now')}</div>
|
||||
<SuperscriptTime time={clock} className='time' />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='now-container'>
|
||||
<AnimatePresence>
|
||||
{publicEventNow && (
|
||||
<MotionTitleCard
|
||||
className='event now'
|
||||
key='now'
|
||||
variants={titleVariants}
|
||||
initial='hidden'
|
||||
animate='visible'
|
||||
exit='exit'
|
||||
label='now'
|
||||
title={publicEventNow.title}
|
||||
secondary={secondaryTextNow}
|
||||
/>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
|
||||
<AnimatePresence>
|
||||
{publicEventNext && (
|
||||
<MotionTitleCard
|
||||
className='event next'
|
||||
key='next'
|
||||
variants={titleVariants}
|
||||
initial='hidden'
|
||||
animate='visible'
|
||||
exit='exit'
|
||||
label='next'
|
||||
title={publicEventNext.title}
|
||||
secondary={secondaryTextNext}
|
||||
/>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</div>
|
||||
|
||||
<PublicSchedule selectedId={publicSelectedId} />
|
||||
|
||||
<div className='info'>
|
||||
{general.publicUrl && <QRCode value={general.publicUrl} size={qrSize} level='L' className='qr' />}
|
||||
{general.publicInfo && <div className='info__message'>{general.publicInfo}</div>}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
import { CustomFields } from 'ontime-types';
|
||||
|
||||
import {
|
||||
getTimeOption,
|
||||
makeOptionsFromCustomFields,
|
||||
OptionTitle,
|
||||
} from '../../../common/components/view-params-editor/constants';
|
||||
import { ViewOption } from '../../../common/components/view-params-editor/types';
|
||||
|
||||
export const getPublicOptions = (timeFormat: string, customFields: CustomFields): ViewOption[] => {
|
||||
const secondaryOptions = makeOptionsFromCustomFields(customFields, { note: 'Note' });
|
||||
|
||||
return [
|
||||
{ title: OptionTitle.ClockOptions, collapsible: true, options: [getTimeOption(timeFormat)] },
|
||||
{
|
||||
title: OptionTitle.DataSources,
|
||||
collapsible: true,
|
||||
options: [
|
||||
{
|
||||
id: 'secondary-src',
|
||||
title: 'Event secondary text',
|
||||
description: 'Select the data source for auxiliary text shown in now and next cards',
|
||||
type: 'option',
|
||||
values: secondaryOptions,
|
||||
defaultValue: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: OptionTitle.Schedule,
|
||||
collapsible: true,
|
||||
options: [
|
||||
{
|
||||
id: 'eventsPerPage',
|
||||
title: 'Events per page',
|
||||
description: 'Sets the number of events on the page, can cause overflow',
|
||||
type: 'number',
|
||||
placeholder: '8 (default)',
|
||||
},
|
||||
{
|
||||
id: 'hidePast',
|
||||
title: 'Hide past events',
|
||||
description: 'Scheduler will only show upcoming events',
|
||||
type: 'boolean',
|
||||
defaultValue: false,
|
||||
},
|
||||
{
|
||||
id: 'stopCycle',
|
||||
title: 'Stop cycling through event pages',
|
||||
description: 'Schedule will not auto-cycle through events',
|
||||
type: 'boolean',
|
||||
defaultValue: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
};
|
||||
Reference in New Issue
Block a user