Skip to content

Commit a677599

Browse files
committed
Add Filters in Calendar Events and Highlights
1 parent e4ad662 commit a677599

File tree

7 files changed

+138
-25
lines changed

7 files changed

+138
-25
lines changed

.changeset/fair-falcons-wonder.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'mexit': patch
3+
---
4+
5+
Add Filter in Events and Highlights in Context Sidebar of Extension

apps/extension/src/Components/Sidebar/ContextInfoBar.tsx

+47-10
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,16 @@ import React, { useEffect, useMemo, useState } from 'react'
22

33
import { formatDistanceToNow } from 'date-fns'
44

5-
import { API_BASE_URLS, DrawerType, useCalendarStore, useHighlightStore, useLayoutStore } from '@mexit/core'
5+
import {
6+
API_BASE_URLS,
7+
CalendarEventFilterType,
8+
DrawerType,
9+
getMenuItem,
10+
MenuListItemType,
11+
useCalendarStore,
12+
useHighlightStore,
13+
useLayoutStore
14+
} from '@mexit/core'
615
import {
716
CenteredFlex,
817
DefaultMIcons,
@@ -12,16 +21,17 @@ import {
1221
Group,
1322
IconDisplay,
1423
List,
24+
Select,
1525
SidebarListFilter,
1626
SnippetCards,
1727
SpaceBetweenHorizontalFlex,
1828
StyledButton,
19-
Toggle,
2029
useCalendar,
2130
useInterval
2231
} from '@mexit/shared'
2332

2433
import { useSaveChanges } from '../../Hooks/useSaveChanges'
34+
import { getElementById } from '../../Utils/cs-utils'
2535

2636
import { GenericCard } from './GenericCard'
2737
import { HighlightGroups } from './HighlightGroup'
@@ -78,7 +88,9 @@ const CalendarEvent = ({ event }) => {
7888
}
7989

8090
const openMeetLink = (url?: string) => {
81-
window.open(url ?? event.links.meet, '_blank')
91+
const webLink = url ?? event.links.meet ?? event.links.event
92+
93+
window.open(webLink, '_blank')
8294
}
8395

8496
return (
@@ -91,7 +103,7 @@ const CalendarEvent = ({ event }) => {
91103
<FadeContainer flex={false} fade>
92104
<Group>
93105
<IconDisplay icon={DefaultMIcons.NOTE} onClick={openMeetingNote} />
94-
<IconDisplay icon={DefaultMIcons.WEB_LINK} onClick={openMeetLink} />
106+
<IconDisplay icon={DefaultMIcons.WEB_LINK} onClick={() => openMeetLink()} />
95107
</Group>
96108
</FadeContainer>
97109
) : (
@@ -107,6 +119,7 @@ const UpcomingEvents = () => {
107119
const [isFetching, setIsFetching] = useState(false)
108120

109121
const { getUpcomingEvents, getCalenderEvents, getCalendarAuth } = useCalendar()
122+
const [calendarEventFilter, setCalendarEventFilter] = useState<CalendarEventFilterType>('Upcoming')
110123
const calendarEvents = useCalendarStore((state) => state.events)
111124
const calendarToken = useCalendarStore((store) => store.tokens['GOOGLE_CAL'])
112125

@@ -141,18 +154,34 @@ const UpcomingEvents = () => {
141154
useInterval(fetchEvents, 30 * 60 * 1000)
142155

143156
const upcomingEvents = useMemo(() => {
144-
return getUpcomingEvents()
145-
}, [calendarEvents])
157+
return getUpcomingEvents(calendarEventFilter)
158+
}, [calendarEvents, calendarEventFilter])
146159

147160
const hasUpcomingEvents = upcomingEvents?.length > 0
148161

162+
const onClick = (event: MenuListItemType) => {
163+
setCalendarEventFilter(event.label as CalendarEventFilterType)
164+
}
165+
149166
return (
150-
<SidebarSection label="Upcoming Events" isLoading={isFetching} icon={DefaultMIcons.NOTIFICATION}>
167+
<SidebarSection
168+
label="Events"
169+
isLoading={isFetching}
170+
icon={DefaultMIcons.NOTIFICATION}
171+
rightComponent={
172+
<Select
173+
root={getElementById('ext-side-nav')}
174+
items={[
175+
getMenuItem('Upcoming', onClick, false),
176+
getMenuItem('Past', onClick, false),
177+
getMenuItem('All', onClick, false)
178+
]}
179+
/>
180+
}
181+
>
151182
{calendarToken && hasUpcomingEvents ? (
152183
<List $noMargin scrollable $maxHeight="140px">
153184
{upcomingEvents.map((event) => {
154-
const desc = event.description ? `: ${event.description}` : ''
155-
156185
return <CalendarEvent event={event} />
157186
})}
158187
</List>
@@ -198,7 +227,15 @@ const Highlights = () => {
198227
scrollable
199228
label="Captures"
200229
icon={DefaultMIcons.HIGHLIGHT}
201-
rightComponent={<Toggle size="small" onChange={setShowAll} text="All" />}
230+
rightComponent={
231+
<Select
232+
root={getElementById('ext-side-nav')}
233+
items={[
234+
getMenuItem('Page', () => setShowAll(false), false),
235+
getMenuItem('All', () => setShowAll(true), false)
236+
]}
237+
/>
238+
}
202239
>
203240
{pageHighlights?.length > 0 ? (
204241
<List $noMargin scrollable>

apps/extension/src/Components/Sidebar/HighlightGroup.tsx

+11-5
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
getFavicon,
1111
Highlight,
1212
Highlights,
13+
mog,
1314
useHighlightStore,
1415
useLayoutStore
1516
} from '@mexit/core'
@@ -153,13 +154,18 @@ export const HighlightGroups = ({ highlights, all }: { highlights: Highlights; a
153154
highlights.forEach((highlight) => {
154155
if (!highlight) return
155156

156-
const sourceUrl = new URL(highlight.properties?.sourceUrl)?.origin
157+
try {
158+
const sourceUrl = new URL(highlight.properties?.sourceUrl)?.origin
157159

158-
if (!groupedHighlights[sourceUrl]) {
159-
groupedHighlights[sourceUrl] = []
160-
}
160+
if (!groupedHighlights[sourceUrl]) {
161+
groupedHighlights[sourceUrl] = []
162+
}
161163

162-
groupedHighlights[sourceUrl].push(highlight)
164+
groupedHighlights[sourceUrl].push(highlight)
165+
} catch (err) {
166+
mog('Unable to group highlights', { highlight })
167+
console.error('Unable to group highlights', err)
168+
}
163169
})
164170

165171
return groupedHighlights

libs/core/src/Types/Calendar.ts

+2
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,5 @@ export type PersistAuth = {
1414
email: string
1515
expiresIn?: number
1616
}
17+
18+
export type CalendarEventFilterType = 'Upcoming' | 'Past' | 'All'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import React, { useState } from 'react'
2+
3+
import { MenuListItemType, MIcon } from '@mexit/core'
4+
5+
import { Group } from '../../Style/Layouts'
6+
import { ItemLabel, Menu, MenuItem } from '../FloatingElements'
7+
import { IconDisplay } from '../IconDisplay'
8+
import { getMIcon } from '../Icons'
9+
10+
interface SelectProps {
11+
items: MenuListItemType[]
12+
onClick?: (option: MenuListItemType) => void
13+
label?: string
14+
root?: any
15+
}
16+
17+
export const Select: React.FC<SelectProps> = ({ items, onClick, label = 'Select', root }) => {
18+
const [selected, setSelected] = useState(null)
19+
20+
const handleOnClick = (option: MenuListItemType) => {
21+
setSelected(option)
22+
if (onClick) onClick(option)
23+
else if (option.onSelect) option.onSelect(option)
24+
}
25+
26+
return (
27+
<Menu
28+
noHover
29+
noBackground
30+
root={root}
31+
values={
32+
<Group>
33+
<ItemLabel fontSize="small">{selected?.label ?? items?.at(0)?.label ?? label}</ItemLabel>
34+
<IconDisplay icon={getMIcon('ICON', 'bi:caret-down-fill')} size={10} />
35+
</Group>
36+
}
37+
>
38+
{items.map((op) => {
39+
return (
40+
<MenuItem
41+
fontSize="small"
42+
key={op.id}
43+
icon={op.icon as MIcon}
44+
onClick={(e) => handleOnClick(op)}
45+
label={op.label}
46+
/>
47+
)
48+
})}
49+
</Menu>
50+
)
51+
}

libs/shared/src/Components/index.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export * from './PreviewMeta'
2222
export * from './ProjectIcon'
2323
export * from './RelativeTime'
2424
export * from './Reminder'
25+
export * from './Select'
2526
export * from './ShareToggle'
2627
export * from './ShortenURL'
2728
export * from './TableWrapper'

libs/shared/src/Hooks/useCalendar.ts

+21-10
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { add, format, sub } from 'date-fns'
22

33
import {
44
API_BASE_URLS,
5+
CalendarEventFilterType,
56
generateNodeId,
67
getSlug,
78
MEETING_PREFIX,
@@ -111,20 +112,30 @@ export const useCalendar = () => {
111112
await getEvents(request)
112113
}
113114

114-
const getUpcomingEvents = () => {
115+
const getUpcomingEvents = (calendarEventFilter: CalendarEventFilterType) => {
115116
const now = new Date()
116117
const twoHoursFromNow = add(now, { hours: 2 })
117118
const events = useCalendarStore.getState().events
118119

119-
const todayEvents = events
120-
.filter((event) => {
121-
const start = new Date(event.times.start)
122-
console.log('START', { start, event, twoHoursFromNow, isStart: start <= twoHoursFromNow })
123-
return start <= twoHoursFromNow && start >= now
124-
})
125-
.sort((a, b) => b.times.start - a.times.start)
126-
127-
return todayEvents
120+
switch (calendarEventFilter) {
121+
case 'All':
122+
return events.sort((a, b) => b.times.start - a.times.start)
123+
case 'Past':
124+
return events
125+
.filter((event) => {
126+
const start = new Date(event.times.start)
127+
return start < now
128+
})
129+
.sort((a, b) => b.times.start - a.times.start)
130+
case 'Upcoming':
131+
default:
132+
return events
133+
.filter((event) => {
134+
const start = new Date(event.times.start)
135+
return start <= twoHoursFromNow && start >= now
136+
})
137+
.sort((a, b) => b.times.start - a.times.start)
138+
}
128139
}
129140

130141
const getCalendarAuth = async () => {

0 commit comments

Comments
 (0)