style: small UI suggestion

This commit is contained in:
Carlos Valente
2023-12-15 22:25:26 +01:00
parent d2c6d46585
commit a6683fd2cd
3 changed files with 187 additions and 77 deletions
@@ -1,9 +1,11 @@
import { ChangeEvent, useEffect, useRef, useState } from 'react'; import { ChangeEvent, useEffect, useRef, useState } from 'react';
import { import {
Alert,
AlertDescription,
AlertIcon,
AlertTitle,
Button, Button,
Input, Input,
InputGroup,
InputRightAddon,
Modal, Modal,
ModalBody, ModalBody,
ModalCloseButton, ModalCloseButton,
@@ -13,10 +15,6 @@ import {
ModalOverlay, ModalOverlay,
Select, Select,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { IoArrowDownCircleOutline } from '@react-icons/all-files/io5/IoArrowDownCircleOutline';
import { IoArrowUpCircleOutline } from '@react-icons/all-files/io5/IoArrowUpCircleOutline';
import { IoCheckmarkCircleOutline } from '@react-icons/all-files/io5/IoCheckmarkCircleOutline';
import { IoCloseCircleOutline } from '@react-icons/all-files/io5/IoCloseCircleOutline';
import { useQueryClient } from '@tanstack/react-query'; import { useQueryClient } from '@tanstack/react-query';
import { OntimeRundown, ProjectData, UserFields } from 'ontime-types'; import { OntimeRundown, ProjectData, UserFields } from 'ontime-types';
@@ -34,8 +32,11 @@ import useSheet from '../../../common/hooks-query/useSheet';
import useSheetState from '../../../common/hooks-query/useSheetState'; import useSheetState from '../../../common/hooks-query/useSheetState';
import { projectDataPlaceholder } from '../../../common/models/ProjectData'; import { projectDataPlaceholder } from '../../../common/models/ProjectData';
import { userFieldsPlaceholder } from '../../../common/models/UserFields'; import { userFieldsPlaceholder } from '../../../common/models/UserFields';
import ModalLink from '../ModalLink';
import PreviewExcel from '../upload-modal/preview/PreviewExcel'; import PreviewExcel from '../upload-modal/preview/PreviewExcel';
import Step from './Step';
interface SheetsModalProps { interface SheetsModalProps {
onClose: () => void; onClose: () => void;
isOpen: boolean; isOpen: boolean;
@@ -180,18 +181,24 @@ export default function SheetsModal(props: SheetsModalProps) {
> >
<ModalOverlay /> <ModalOverlay />
<ModalContent> <ModalContent>
<ModalHeader>Sheets!</ModalHeader> <ModalHeader>Rundown from sheets</ModalHeader>
<ModalCloseButton /> <ModalCloseButton />
<ModalBody> <ModalBody>
{rundown && ( <Alert status='info' variant='ontime-on-light-info'>
<PreviewExcel <AlertIcon />
rundown={rundown ?? []} <div style={{ display: 'flex', flexDirection: 'column' }}>
project={project ?? projectDataPlaceholder} <AlertTitle>Sync with Google Sheets</AlertTitle>
userFields={userFields ?? userFieldsPlaceholder} <AlertDescription>
/> Add information here, maybe a link too. <br />
)} The save button is also confusing, can we clarify? should the push data and pull data not be the end
{!rundown && ( game buttons here?
<ModalLink href='our-docs'>For more information, see the docs</ModalLink>
</AlertDescription>
</div>
</Alert>
{!rundown ? (
<> <>
<Step step={1} title='Upload token' completed={Boolean(sheetState?.secret)} disabled={false}>
<Input <Input
ref={fileInputRef} ref={fileInputRef}
style={{ display: 'none' }} style={{ display: 'none' }}
@@ -200,64 +207,86 @@ export default function SheetsModal(props: SheetsModalProps) {
accept='.json' accept='.json'
data-testid='file-input' data-testid='file-input'
/> />
<div> <Button size='sm' variant='ontime-ghosted-on-light' onClick={handleClick}>
<Button onClick={handleClick}>Upload Client Secret</Button> Upload Client Secret
{sheetState?.secret ? 'have good secret' : 'no or bad secret'} </Button>
</div> </Step>
<div style={sheetState?.secret ? {} : { display: 'none' }}>
<Button variant='ontime-filled' padding='0 2em' onClick={handleAuthenticate}> <Step
step={2}
title='Authenticate with Google'
completed={Boolean(sheetState?.auth)}
disabled={!sheetState?.secret}
>
<Button
size='sm'
variant='ontime-ghosted-on-light'
onClick={handleAuthenticate}
disabled={!sheetState?.secret}
>
Authenticate Authenticate
</Button> </Button>
{sheetState?.auth ? 'You are authenticated' : 'You are not authenticated'} </Step>
</div>
<div style={sheetState?.auth ? {} : { display: 'none' }}> <Step step={3} title='Add Sheet ID' completed={Boolean(sheetState?.id)} disabled={!sheetState?.auth}>
<label htmlFor='sheetid'>Sheet ID</label> <label htmlFor='sheetid'>
<InputGroup size='sm'> Sheet ID
<Input <Input
type='text' type='text'
ref={sheetid} ref={sheetid}
id='sheetid' id='sheetid'
width='240px' size='sm'
textAlign='right'
variant='ontime-filled-on-light' variant='ontime-filled-on-light'
disabled={!sheetState?.auth}
/> />
<InputRightAddon> </label>
{sheetState?.id ? <IoCheckmarkCircleOutline color='green' /> : <IoCloseCircleOutline color='red' />} </Step>
</InputRightAddon>
</InputGroup> <Step
</div> step={4}
<div style={sheetState?.id ? {} : { display: 'none' }}> title='Select Worksheet to import'
<label htmlFor='worksheet'>Worksheet </label> completed={Boolean(sheetState?.auth)}
<Select ref={worksheet} size='sm' id='worksheet'> disabled={!sheetState?.worksheetOptions}
>
<label htmlFor='worksheet'>
Worksheet
<Select ref={worksheet} size='sm' id='worksheet' disabled={!sheetState?.worksheetOptions}>
{sheetState?.worksheetOptions?.map((value) => ( {sheetState?.worksheetOptions?.map((value) => (
<option key={value} value={value}> <option key={value} value={value}>
{value} {value}
</option> </option>
))} ))}
</Select> </Select>
</div> </label>
<br /> </Step>
<div style={sheetState?.worksheet ? {} : { display: 'none' }}>
<Step step={5} title='Upload / Download rundown' completed={false} disabled={!sheetState?.worksheet}>
<div style={{ display: 'flex', gap: '1em' }}>
<Button <Button
disabled={!sheetState?.worksheet} disabled={!sheetState?.worksheet}
variant='ontime-subtle-on-light' variant='ontime-ghosted-on-light'
padding='0 2em' padding='0 2em'
onClick={handlePullData} onClick={handlePullData}
rightIcon={<IoArrowDownCircleOutline />}
> >
Pull Rundown Push data
</Button> </Button>
<Button <Button
disabled={!sheetState?.worksheet} disabled={!sheetState?.worksheet}
variant='ontime-subtle-on-light' variant='ontime-ghosted-on-light'
padding='0 2em' padding='0 2em'
onClick={handlePushData} onClick={handlePushData}
rightIcon={<IoArrowUpCircleOutline />}
> >
Push Rundown Pull data
</Button> </Button>
</div> </div>
</Step>
</> </>
) : (
<PreviewExcel
rundown={rundown ?? []}
project={project ?? projectDataPlaceholder}
userFields={userFields ?? userFieldsPlaceholder}
/>
)} )}
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
@@ -0,0 +1,44 @@
@use '../../../theme/ontimeColours' as *;
.wrapper {
padding: 0.5rem;
}
.header {
width: 100%;
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 1rem;
padding-bottom: 1rem;
}
.step {
width: 1.25rem;
height: 1.25rem;
font-size: 0.75rem;
display: grid;
place-content: center;
background-color: $gray-900;
color: $ui-white;
border-radius: 99px;
}
.title {
display: inline;
color: $gray-500;
text-transform: uppercase;
}
.check {
color: $green-700;
}
.errorIcon {
color: $red-700;
}
.errorText {
color: $red-700;
font-size: 0.75rem;
}
@@ -0,0 +1,37 @@
import { PropsWithChildren, useState } from 'react';
import { IoCheckmark } from '@react-icons/all-files/io5/IoCheckmark';
import { IoClose } from '@react-icons/all-files/io5/IoClose';
import style from './Step.module.scss';
interface StepProps {
step: number;
title: string;
disabled: boolean;
completed: boolean;
error?: string;
}
export default function Step(props: PropsWithChildren<StepProps>) {
const { step, title, disabled, completed, error, children } = props;
const [collapsed, setCollapsed] = useState(disabled);
const handleCollapse = () => setCollapsed((prev) => !prev);
return (
<div className={style.wrapper}>
<div className={style.header} onClick={handleCollapse}>
<span className={style.step}>{step}</span>
<span className={style.title}>{title}</span>
{completed && <IoCheckmark className={style.check} />}
{error && <IoClose className={style.errorIcon} />}
</div>
{!collapsed && (
<>
{error && <div className={style.errorText}>{error}</div>}
{children}
</>
)}
</div>
);
}