Add selection control buttons
This commit is contained in:
parent
ebdf2cf52c
commit
7535a2a61e
|
|
@ -0,0 +1,5 @@
|
||||||
|
.selectionControls {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1em;
|
||||||
|
}
|
||||||
|
|
@ -1,12 +1,14 @@
|
||||||
import { Fragment, useCallback, useRef, useState } from 'react'
|
import { Fragment, useCallback, useRef, useState } from 'react'
|
||||||
|
|
||||||
|
import Button from '/src/components/Button/Button'
|
||||||
import Content from '/src/components/Content/Content'
|
import Content from '/src/components/Content/Content'
|
||||||
import GoogleCalendar from '/src/components/GoogleCalendar/GoogleCalendar'
|
import GoogleCalendar from '/src/components/GoogleCalendar/GoogleCalendar'
|
||||||
import { usePalette } from '/src/hooks/usePalette'
|
import { usePalette } from '/src/hooks/usePalette'
|
||||||
import { useTranslation } from '/src/i18n/client'
|
import { useTranslation } from '/src/i18n/client'
|
||||||
import { calculateTable, makeClass, parseSpecificDate } from '/src/utils'
|
import { calculateTable, makeClass, parseSpecificDate } from '/src/utils'
|
||||||
|
|
||||||
import styles from '../AvailabilityViewer/AvailabilityViewer.module.scss'
|
import styles from './AvailabilityEditor.module.scss'
|
||||||
|
import viewerStyles from '../AvailabilityViewer/AvailabilityViewer.module.scss'
|
||||||
import Skeleton from '../AvailabilityViewer/components/Skeleton/Skeleton'
|
import Skeleton from '../AvailabilityViewer/components/Skeleton/Skeleton'
|
||||||
|
|
||||||
interface AvailabilityEditorProps {
|
interface AvailabilityEditorProps {
|
||||||
|
|
@ -35,7 +37,14 @@ const AvailabilityEditor = ({ times, timezone, value = [], onChange, table }: Av
|
||||||
const palette = usePalette(2)
|
const palette = usePalette(2)
|
||||||
|
|
||||||
return <>
|
return <>
|
||||||
<Content isCentered>{t('you.info')}</Content>
|
<Content isCentered>
|
||||||
|
<div>{t('you.info')}</div>
|
||||||
|
<div className={styles.selectionControls}>
|
||||||
|
<Button isSmall onClick={() => onChange(times)}>{t('you.select_all')}</Button>
|
||||||
|
<Button isSmall onClick={() => onChange([])}>{t('you.select_none')}</Button>
|
||||||
|
<Button isSmall onClick={() => onChange(times.filter(t => !value.includes(t)))}>{t('you.select_invert')}</Button>
|
||||||
|
</div>
|
||||||
|
</Content>
|
||||||
{times[0].length === 13 && <Content>
|
{times[0].length === 13 && <Content>
|
||||||
<div style={{ display: 'flex', flexWrap: 'wrap', alignItems: 'center', justifyContent: 'center', gap: 12 }}>
|
<div style={{ display: 'flex', flexWrap: 'wrap', alignItems: 'center', justifyContent: 'center', gap: 12 }}>
|
||||||
<GoogleCalendar
|
<GoogleCalendar
|
||||||
|
|
@ -48,13 +57,13 @@ const AvailabilityEditor = ({ times, timezone, value = [], onChange, table }: Av
|
||||||
</div>
|
</div>
|
||||||
</Content>}
|
</Content>}
|
||||||
|
|
||||||
<div className={styles.wrapper}>
|
<div className={viewerStyles.wrapper}>
|
||||||
<div>
|
<div>
|
||||||
<div className={styles.heatmap}>
|
<div className={viewerStyles.heatmap}>
|
||||||
<div className={styles.timeLabels}>
|
<div className={viewerStyles.timeLabels}>
|
||||||
{table?.rows.map((row, i) =>
|
{table?.rows.map((row, i) =>
|
||||||
<div className={styles.timeSpace} key={i}>
|
<div className={viewerStyles.timeSpace} key={i}>
|
||||||
{row && <label className={styles.timeLabel}>
|
{row && <label className={viewerStyles.timeLabel}>
|
||||||
{row.label}
|
{row.label}
|
||||||
</label>}
|
</label>}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -62,12 +71,12 @@ const AvailabilityEditor = ({ times, timezone, value = [], onChange, table }: Av
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{table?.columns.map((column, x) => <Fragment key={x}>
|
{table?.columns.map((column, x) => <Fragment key={x}>
|
||||||
{column ? <div className={styles.dateColumn}>
|
{column ? <div className={viewerStyles.dateColumn}>
|
||||||
{column.header.dateLabel && <label className={styles.dateLabel}>{column.header.dateLabel}</label>}
|
{column.header.dateLabel && <label className={viewerStyles.dateLabel}>{column.header.dateLabel}</label>}
|
||||||
<label className={styles.dayLabel}>{column.header.weekdayLabel}</label>
|
<label className={viewerStyles.dayLabel}>{column.header.weekdayLabel}</label>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
className={styles.times}
|
className={viewerStyles.times}
|
||||||
data-border-left={x === 0 || table.columns.at(x - 1) === null}
|
data-border-left={x === 0 || table.columns.at(x - 1) === null}
|
||||||
data-border-right={x === table.columns.length - 1 || table.columns.at(x + 1) === null}
|
data-border-right={x === table.columns.length - 1 || table.columns.at(x + 1) === null}
|
||||||
>
|
>
|
||||||
|
|
@ -75,7 +84,7 @@ const AvailabilityEditor = ({ times, timezone, value = [], onChange, table }: Av
|
||||||
if (y === column.cells.length - 1) return null
|
if (y === column.cells.length - 1) return null
|
||||||
|
|
||||||
if (!cell) return <div
|
if (!cell) return <div
|
||||||
className={makeClass(styles.timeSpace, styles.grey)}
|
className={makeClass(viewerStyles.timeSpace, viewerStyles.grey)}
|
||||||
key={y}
|
key={y}
|
||||||
title={t<string>('greyed_times')}
|
title={t<string>('greyed_times')}
|
||||||
/>
|
/>
|
||||||
|
|
@ -87,7 +96,7 @@ const AvailabilityEditor = ({ times, timezone, value = [], onChange, table }: Av
|
||||||
|
|
||||||
return <div
|
return <div
|
||||||
key={y}
|
key={y}
|
||||||
className={makeClass(styles.time, selecting.length === 0 && styles.editable)}
|
className={makeClass(viewerStyles.time, selecting.length === 0 && viewerStyles.editable)}
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: isSelected ? palette[1].string : palette[0].string,
|
backgroundColor: isSelected ? palette[1].string : palette[0].string,
|
||||||
'--hover-color': isSelected ? palette[0].highlight : palette[1].highlight,
|
'--hover-color': isSelected ? palette[0].highlight : palette[1].highlight,
|
||||||
|
|
@ -131,7 +140,7 @@ const AvailabilityEditor = ({ times, timezone, value = [], onChange, table }: Av
|
||||||
/>
|
/>
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
</div> : <div className={styles.columnSpacer} />}
|
</div> : <div className={viewerStyles.columnSpacer} />}
|
||||||
</Fragment>) ?? <Skeleton isSpecificDates={times[0].length === 13} />}
|
</Fragment>) ?? <Skeleton isSpecificDates={times[0].length === 13} />}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.slim {
|
.slim {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue