From d2e5bcc4cb00089e2662fe56175faeeec4fc40a8 Mon Sep 17 00:00:00 2001 From: Ben Grant Date: Mon, 17 May 2021 18:52:00 +1000 Subject: [PATCH] Rounder corners, thicker borders, highlight highest availability --- .../AvailabilityEditor/AvailabilityEditor.tsx | 5 ++- .../AvailabilityViewer/AvailabilityViewer.tsx | 7 +++- .../availabilityViewerStyle.ts | 34 ++++++++++++++++--- .../GoogleCalendar/GoogleCalendar.tsx | 6 +++- .../src/components/Legend/Legend.tsx | 10 +++++- .../src/components/Legend/legendStyle.ts | 10 ++++++ .../src/components/Settings/Settings.tsx | 10 ++++++ .../components/ToggleField/ToggleField.tsx | 3 +- .../src/pages/Event/eventStyle.ts | 4 +++ crabfit-frontend/src/stores/index.ts | 2 ++ 10 files changed, 81 insertions(+), 10 deletions(-) diff --git a/crabfit-frontend/src/components/AvailabilityEditor/AvailabilityEditor.tsx b/crabfit-frontend/src/components/AvailabilityEditor/AvailabilityEditor.tsx index f6b1085..5153588 100644 --- a/crabfit-frontend/src/components/AvailabilityEditor/AvailabilityEditor.tsx +++ b/crabfit-frontend/src/components/AvailabilityEditor/AvailabilityEditor.tsx @@ -87,7 +87,10 @@ const AvailabilityEditor = ({ {isSpecificDates && {parsedDate.format('MMM D')}} {parsedDate.format('ddd')} - + 1} + > {timeLabels.map((timeLabel, y) => { if (!timeLabel.time) return null; if (!times.includes(`${timeLabel.time}-${date}`)) { diff --git a/crabfit-frontend/src/components/AvailabilityViewer/AvailabilityViewer.tsx b/crabfit-frontend/src/components/AvailabilityViewer/AvailabilityViewer.tsx index 1d7cbf4..4a0e313 100644 --- a/crabfit-frontend/src/components/AvailabilityViewer/AvailabilityViewer.tsx +++ b/crabfit-frontend/src/components/AvailabilityViewer/AvailabilityViewer.tsx @@ -46,6 +46,7 @@ const AvailabilityViewer = ({ }) => { const [tooltip, setTooltip] = useState(null); const timeFormat = useSettingsStore(state => state.timeFormat); + const highlight = useSettingsStore(state => state.highlight); const [filteredPeople, setFilteredPeople] = useState([]); const [touched, setTouched] = useState(false); const [tempFocus, setTempFocus] = useState(null); @@ -118,7 +119,10 @@ const AvailabilityViewer = ({ {isSpecificDates && {parsedDate.format('MMM D')}} {parsedDate.format('ddd')} - + 1} + > {timeLabels.map((timeLabel, i) => { if (!timeLabel.time) return null; if (!times.includes(`${timeLabel.time}-${date}`)) { @@ -140,6 +144,7 @@ const AvailabilityViewer = ({ aria-label={peopleHere.join(', ')} maxPeople={tempFocus !== null ? 1 : Math.min(max, filteredPeople.length)} minPeople={tempFocus !== null ? 0 : Math.min(min, filteredPeople.length)} + highlight={highlight} onMouseEnter={(e) => { const cellBox = e.currentTarget.getBoundingClientRect(); const wrapperBox = wrapper?.current?.getBoundingClientRect() ?? { x: 0, y: 0 }; diff --git a/crabfit-frontend/src/components/AvailabilityViewer/availabilityViewerStyle.ts b/crabfit-frontend/src/components/AvailabilityViewer/availabilityViewerStyle.ts index 31d5155..cb9960e 100644 --- a/crabfit-frontend/src/components/AvailabilityViewer/availabilityViewerStyle.ts +++ b/crabfit-frontend/src/components/AvailabilityViewer/availabilityViewerStyle.ts @@ -36,6 +36,19 @@ export const Times = styled.div` display: flex; flex-direction: column; background-color: ${props => props.theme.text}; + border-top: 1px solid transparent; + border-bottom: 1px solid transparent; + + ${props => props.borderLeft && ` + border-left: 1px solid transparent; + border-top-left-radius: 3px; + border-bottom-left-radius: 3px; + `} + ${props => props.borderRight && ` + border-right: 1px solid transparent; + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; + `} `; export const DateLabel = styled.label` @@ -56,6 +69,7 @@ export const Time = styled.div` height: 10px; margin: 1px; background-color: ${props => props.theme.background}; + background-origin: border-box; ${props => props.time.slice(2, 4) !== '00' && ` margin-top: -1px; @@ -66,10 +80,20 @@ export const Time = styled.div` border-top: 2px dotted ${props.theme.text}; `} - background-image: linear-gradient( - ${props => `${props.theme.primary}${Math.round((props.peopleCount/props.maxPeople)*255).toString(16)}`}, - ${props => `${props.theme.primary}${Math.round((props.peopleCount/props.maxPeople)*255).toString(16)}`} - ); + ${props => props.highlight && props.peopleCount === props.maxPeople ? ` + background-image: repeating-linear-gradient( + 45deg, + ${props.theme.primary}, + ${props.theme.primary} 4.3px, + ${props.theme.primaryDark} 4.3px, + ${props.theme.primaryDark} 8.6px + ); + ` : ` + background-image: linear-gradient( + ${`${props.theme.primary}${Math.round((props.peopleCount/props.maxPeople)*255).toString(16)}`}, + ${`${props.theme.primary}${Math.round((props.peopleCount/props.maxPeople)*255).toString(16)}`} + ); + `} `; export const Spacer = styled.div` @@ -174,7 +198,7 @@ export const Person = styled.button` ${props => props.filtered && ` background: ${props.theme.primary}; - color: ${props.theme.background}; + color: #FFFFFF; border-color: ${props.theme.primary}; `} `; diff --git a/crabfit-frontend/src/components/GoogleCalendar/GoogleCalendar.tsx b/crabfit-frontend/src/components/GoogleCalendar/GoogleCalendar.tsx index 7031326..f4f38b8 100644 --- a/crabfit-frontend/src/components/GoogleCalendar/GoogleCalendar.tsx +++ b/crabfit-frontend/src/components/GoogleCalendar/GoogleCalendar.tsx @@ -48,6 +48,9 @@ const GoogleCalendar = ({ timeZone, timeMin, timeMax, onImport }) => { const importAvailability = () => { setFreeBusyLoading(true); + gtag('event', 'google_cal_sync', { + 'event_category': 'event', + }); window.gapi.client.calendar.freebusy.query({ timeMin, timeMax, @@ -145,11 +148,12 @@ const GoogleCalendar = ({ timeZone, timeMin, timeMax, onImport }) => { )} {calendars !== undefined && ( <> - Importing will overwrite your currently inputted availability + Importing will overwrite your current availability diff --git a/crabfit-frontend/src/components/Legend/Legend.tsx b/crabfit-frontend/src/components/Legend/Legend.tsx index 978d317..f26fe71 100644 --- a/crabfit-frontend/src/components/Legend/Legend.tsx +++ b/crabfit-frontend/src/components/Legend/Legend.tsx @@ -1,4 +1,5 @@ import { useTheme } from '@emotion/react'; +import { useSettingsStore } from 'stores'; import { Wrapper, @@ -15,16 +16,23 @@ const Legend = ({ ...props }) => { const theme = useTheme(); + const highlight = useSettingsStore(state => state.highlight); + const setHighlight = useSettingsStore(state => state.setHighlight); return ( - onSegmentFocus(null)}> + onSegmentFocus(null)} + onClick={() => setHighlight(!highlight)} + title="Click to highlight highest availability" + > {[...Array(max+1-min).keys()].map(i => i+min).map(i => onSegmentFocus(i)} /> )} diff --git a/crabfit-frontend/src/components/Legend/legendStyle.ts b/crabfit-frontend/src/components/Legend/legendStyle.ts index 3d53896..7ca7f67 100644 --- a/crabfit-frontend/src/components/Legend/legendStyle.ts +++ b/crabfit-frontend/src/components/Legend/legendStyle.ts @@ -39,4 +39,14 @@ export const Bar = styled.div` export const Grade = styled.div` flex: 1; background-color: ${props => props.color}; + + ${props => props.highlight && ` + background-image: repeating-linear-gradient( + 45deg, + ${props.theme.primary}, + ${props.theme.primary} 4.5px, + ${props.theme.primaryDark} 4.5px, + ${props.theme.primaryDark} 9px + ); + `} `; diff --git a/crabfit-frontend/src/components/Settings/Settings.tsx b/crabfit-frontend/src/components/Settings/Settings.tsx index 576dd39..53e8b84 100644 --- a/crabfit-frontend/src/components/Settings/Settings.tsx +++ b/crabfit-frontend/src/components/Settings/Settings.tsx @@ -58,6 +58,16 @@ const Settings = () => { value={store.theme} onChange={value => store.setTheme(value)} /> + + store.setHighlight(value === 'On')} + /> ); diff --git a/crabfit-frontend/src/components/ToggleField/ToggleField.tsx b/crabfit-frontend/src/components/ToggleField/ToggleField.tsx index 83aa3b7..1ac0ff4 100644 --- a/crabfit-frontend/src/components/ToggleField/ToggleField.tsx +++ b/crabfit-frontend/src/components/ToggleField/ToggleField.tsx @@ -11,13 +11,14 @@ const ToggleField = ({ label, id, name, + title = '', options = [], value, onChange, ...props }) => ( - {label && {label}} + {label && {label}} {options.map(option => diff --git a/crabfit-frontend/src/pages/Event/eventStyle.ts b/crabfit-frontend/src/pages/Event/eventStyle.ts index 2727b99..d9c7033 100644 --- a/crabfit-frontend/src/pages/Event/eventStyle.ts +++ b/crabfit-frontend/src/pages/Event/eventStyle.ts @@ -72,6 +72,10 @@ export const LoginForm = styled.form` } @media (max-width: 400px) { grid-template-columns: 1fr; + + & div:last-child { + --btn-width: 100%; + } } `; diff --git a/crabfit-frontend/src/stores/index.ts b/crabfit-frontend/src/stores/index.ts index 28b128d..39bfac4 100644 --- a/crabfit-frontend/src/stores/index.ts +++ b/crabfit-frontend/src/stores/index.ts @@ -6,10 +6,12 @@ export const useSettingsStore = create(persist( weekStart: 0, timeFormat: '12h', theme: 'System', + highlight: false, setWeekStart: weekStart => set({ weekStart }), setTimeFormat: timeFormat => set({ timeFormat }), setTheme: theme => set({ theme }), + setHighlight: highlight => set({ highlight }), }), { name: 'crabfit-settings' }, ));