More work on the new design
This commit is contained in:
@ -15,34 +15,24 @@ export function GridSelectorIcon(props: GridSelectorIconProps): JSX.Element {
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g clipPath="url(#clip0_1646_7379)">
|
||||
<g>
|
||||
<path
|
||||
d="M8.32487 0.170105H1.6582C0.967847 0.170105 0.408203 0.729749 0.408203 1.4201V8.08677C0.408203 8.77713 0.967847 9.33677 1.6582 9.33677H8.32487C9.01523 9.33677 9.57487 8.77713 9.57487 8.08677V1.4201C9.57487 0.729749 9.01523 0.170105 8.32487 0.170105Z"
|
||||
fill="#FFEA9F"
|
||||
fill={fillColor}
|
||||
/>
|
||||
<path
|
||||
d="M19.1582 0.170105H12.4915C11.8012 0.170105 11.2415 0.729749 11.2415 1.4201V8.08677C11.2415 8.77713 11.8012 9.33677 12.4915 9.33677H19.1582C19.8486 9.33677 20.4082 8.77713 20.4082 8.08677V1.4201C20.4082 0.729749 19.8486 0.170105 19.1582 0.170105Z"
|
||||
fill="#FFEA9F"
|
||||
fill={fillColor}
|
||||
/>
|
||||
<path
|
||||
d="M8.32487 11.0034H1.6582C0.967847 11.0034 0.408203 11.5631 0.408203 12.2534V18.9201C0.408203 19.6105 0.967847 20.1701 1.6582 20.1701H8.32487C9.01523 20.1701 9.57487 19.6105 9.57487 18.9201V12.2534C9.57487 11.5631 9.01523 11.0034 8.32487 11.0034Z"
|
||||
fill="#FFEA9F"
|
||||
fill={fillColor}
|
||||
/>
|
||||
<path
|
||||
d="M19.1582 11.0034H12.4915C11.8012 11.0034 11.2415 11.5631 11.2415 12.2534V18.9201C11.2415 19.6105 11.8012 20.1701 12.4915 20.1701H19.1582C19.8486 20.1701 20.4082 19.6105 20.4082 18.9201V12.2534C20.4082 11.5631 19.8486 11.0034 19.1582 11.0034Z"
|
||||
fill="#FFEA9F"
|
||||
fill={fillColor}
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_1646_7379">
|
||||
<rect
|
||||
width="20"
|
||||
height="20"
|
||||
fill="white"
|
||||
transform="translate(0.408203 0.172607)"
|
||||
/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
@ -15,30 +15,20 @@ export function ListSelectorIcon(props: ListSelectorIconProps): JSX.Element {
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g clipPath="url(#clip0_1646_7375)">
|
||||
<g>
|
||||
<path
|
||||
d="M19.1582 0.795105H1.6582C0.967847 0.795105 0.408203 1.35475 0.408203 2.0451V4.12844C0.408203 4.81879 0.967847 5.37844 1.6582 5.37844H19.1582C19.8486 5.37844 20.4082 4.81879 20.4082 4.12844V2.0451C20.4082 1.35475 19.8486 0.795105 19.1582 0.795105Z"
|
||||
fill="#6A6968"
|
||||
fill={fillColor}
|
||||
/>
|
||||
<path
|
||||
d="M19.1582 7.87845H1.6582C0.967847 7.87845 0.408203 8.43809 0.408203 9.12845V11.2118C0.408203 11.9021 0.967847 12.4618 1.6582 12.4618H19.1582C19.8486 12.4618 20.4082 11.9021 20.4082 11.2118V9.12845C20.4082 8.43809 19.8486 7.87845 19.1582 7.87845Z"
|
||||
fill="#6A6968"
|
||||
fill={fillColor}
|
||||
/>
|
||||
<path
|
||||
d="M19.1582 14.9618H1.6582C0.967847 14.9618 0.408203 15.5214 0.408203 16.2118V18.2951C0.408203 18.9855 0.967847 19.5451 1.6582 19.5451H19.1582C19.8486 19.5451 20.4082 18.9855 20.4082 18.2951V16.2118C20.4082 15.5214 19.8486 14.9618 19.1582 14.9618Z"
|
||||
fill="#6A6968"
|
||||
fill={fillColor}
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_1646_7375">
|
||||
<rect
|
||||
width="20"
|
||||
height="20"
|
||||
fill="white"
|
||||
transform="translate(0.408203 0.172607)"
|
||||
/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
@ -578,6 +578,7 @@ export function HomeFeedContainer(): JSX.Element {
|
||||
searchTerm={queryInputs.searchQuery}
|
||||
gridContainerRef={gridContainerRef}
|
||||
applySearchQuery={(searchQuery: string) => {
|
||||
console.log('TOP LEVEL SETTING QUERY INPUTS: ', searchQuery)
|
||||
setQueryInputs({
|
||||
...queryInputs,
|
||||
searchQuery,
|
||||
@ -781,8 +782,13 @@ function HomeFeedGrid(props: HomeFeedContentProps): JSX.Element {
|
||||
return (
|
||||
<VStack css={{ width: '100%', height: '100%' }}>
|
||||
<LibraryHeader
|
||||
layout={layout}
|
||||
updateLayout={updateLayout}
|
||||
searchTerm={props.searchTerm}
|
||||
applySearchQuery={props.applySearchQuery}
|
||||
applySearchQuery={(searchQuery: string) => {
|
||||
console.log('searching with searchQuery: ', searchQuery)
|
||||
props.applySearchQuery(searchQuery)
|
||||
}}
|
||||
/>
|
||||
<HStack css={{ width: '100%', height: '100%' }}>
|
||||
<SpanBox
|
||||
@ -792,7 +798,14 @@ function HomeFeedGrid(props: HomeFeedContentProps): JSX.Element {
|
||||
},
|
||||
}}
|
||||
>
|
||||
<LibraryFilterMenu />
|
||||
<LibraryFilterMenu
|
||||
setShowAddLinkModal={props.setShowAddLinkModal}
|
||||
searchTerm={props.searchTerm}
|
||||
applySearchQuery={(searchQuery: string) => {
|
||||
console.log('searching with searchQuery: ', searchQuery)
|
||||
props.applySearchQuery(searchQuery)
|
||||
}}
|
||||
/>
|
||||
</SpanBox>
|
||||
|
||||
<VStack
|
||||
|
||||
@ -2,6 +2,7 @@ import {
|
||||
InputHTMLAttributes,
|
||||
ReactNode,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react'
|
||||
@ -31,8 +32,16 @@ import { useGetSubscriptionsQuery } from '../../../lib/networking/queries/useGet
|
||||
import { useGetLabelsQuery } from '../../../lib/networking/queries/useGetLabelsQuery'
|
||||
import { Label } from '../../../lib/networking/fragments/labelFragment'
|
||||
import { Checkbox } from '@radix-ui/react-checkbox'
|
||||
import { LayoutType } from './HomeFeedContainer'
|
||||
|
||||
export function LibraryFilterMenu(): JSX.Element {
|
||||
type LibraryFilterMenuProps = {
|
||||
setShowAddLinkModal: (show: boolean) => void
|
||||
|
||||
searchTerm: string | undefined
|
||||
applySearchQuery: (searchTerm: string) => void
|
||||
}
|
||||
|
||||
export function LibraryFilterMenu(props: LibraryFilterMenuProps): JSX.Element {
|
||||
return (
|
||||
<>
|
||||
<Box
|
||||
@ -47,11 +56,13 @@ export function LibraryFilterMenu(): JSX.Element {
|
||||
pr: '15px',
|
||||
}}
|
||||
>
|
||||
<SavedSearches />
|
||||
<Subscriptions />
|
||||
<Labels />
|
||||
<SavedSearches {...props} />
|
||||
<Subscriptions {...props} />
|
||||
<Labels {...props} />
|
||||
|
||||
<AddLinkButton />
|
||||
<AddLinkButton
|
||||
showAddLinkModal={() => props.setShowAddLinkModal(true)}
|
||||
/>
|
||||
</Box>
|
||||
{/* This spacer pushes library content to the right of
|
||||
the fixed left side menu. */}
|
||||
@ -67,19 +78,45 @@ export function LibraryFilterMenu(): JSX.Element {
|
||||
)
|
||||
}
|
||||
|
||||
function SavedSearches(): JSX.Element {
|
||||
function SavedSearches(props: LibraryFilterMenuProps): JSX.Element {
|
||||
return (
|
||||
<MenuPanel title="Saved Searches">
|
||||
<FilterButton text="Inbox" selected={true} spaced={true} />
|
||||
<FilterButton text="Read Later" selected={false} spaced={true} />
|
||||
<FilterButton text="Today" selected={false} spaced={true} />
|
||||
<FilterButton text="Archived" selected={false} spaced={true} />
|
||||
<FilterButton
|
||||
text="Inbox"
|
||||
filterTerm="in:inbox"
|
||||
spaced={true}
|
||||
{...props}
|
||||
/>
|
||||
<FilterButton
|
||||
text="Read Later"
|
||||
filterTerm="in:inbox -label:Newsletter"
|
||||
spaced={true}
|
||||
{...props}
|
||||
/>
|
||||
<FilterButton
|
||||
text="Highlights"
|
||||
filterTerm="type:highlights"
|
||||
spaced={true}
|
||||
{...props}
|
||||
/>
|
||||
<FilterButton
|
||||
text="Files"
|
||||
filterTerm="type:file"
|
||||
spaced={true}
|
||||
{...props}
|
||||
/>
|
||||
<FilterButton
|
||||
text="Archived"
|
||||
filterTerm="in:archive"
|
||||
spaced={true}
|
||||
{...props}
|
||||
/>
|
||||
<Box css={{ height: '10px' }}></Box>
|
||||
</MenuPanel>
|
||||
)
|
||||
}
|
||||
|
||||
function Subscriptions(): JSX.Element {
|
||||
function Subscriptions(props: LibraryFilterMenuProps): JSX.Element {
|
||||
const { subscriptions } = useGetSubscriptionsQuery()
|
||||
const [viewAll, setViewAll] = useState(false)
|
||||
|
||||
@ -92,14 +129,21 @@ function Subscriptions(): JSX.Element {
|
||||
}}
|
||||
>
|
||||
{subscriptions.slice(0, viewAll ? undefined : 4).map((item) => {
|
||||
return <FilterButton key={item.id} text={item.name} selected={false} />
|
||||
return (
|
||||
<FilterButton
|
||||
key={item.id}
|
||||
filterTerm={`subscription:\"${item.name}\"`}
|
||||
text={item.name}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
<ViewAllButton state={viewAll} setState={setViewAll} />
|
||||
</MenuPanel>
|
||||
)
|
||||
}
|
||||
|
||||
function Labels(): JSX.Element {
|
||||
function Labels(props: LibraryFilterMenuProps): JSX.Element {
|
||||
const { labels } = useGetLabelsQuery()
|
||||
const [viewAll, setViewAll] = useState(false)
|
||||
|
||||
@ -112,7 +156,7 @@ function Labels(): JSX.Element {
|
||||
}}
|
||||
>
|
||||
{labels.slice(0, viewAll ? undefined : 4).map((item) => {
|
||||
return <LabelButton key={item.id} label={item} state="off" />
|
||||
return <LabelButton key={item.id} label={item} {...props} />
|
||||
})}
|
||||
<ViewAllButton state={viewAll} setState={setViewAll} />
|
||||
</MenuPanel>
|
||||
@ -185,10 +229,20 @@ function MenuPanel(props: MenuPanelProps): JSX.Element {
|
||||
type FilterButtonProps = {
|
||||
text: string
|
||||
spaced?: boolean
|
||||
selected: boolean
|
||||
|
||||
filterTerm: string
|
||||
searchTerm: string | undefined
|
||||
applySearchQuery: (searchTerm: string) => void
|
||||
}
|
||||
|
||||
function FilterButton(props: FilterButtonProps): JSX.Element {
|
||||
const selected = useMemo(() => {
|
||||
if (props.filterTerm === '' && !props.searchTerm) {
|
||||
return true
|
||||
}
|
||||
return props.searchTerm === props.filterTerm
|
||||
}, [props.searchTerm, props.filterTerm])
|
||||
|
||||
return (
|
||||
<Box
|
||||
css={{
|
||||
@ -197,12 +251,23 @@ function FilterButton(props: FilterButtonProps): JSX.Element {
|
||||
mb: props.spaced ? '10px' : '0px',
|
||||
width: '100%',
|
||||
height: '30px',
|
||||
backgroundColor: props.selected ? '#FFEA9F' : 'unset',
|
||||
backgroundColor: selected ? '#FFEA9F' : 'unset',
|
||||
fontSize: '16px',
|
||||
fontWeight: 'regular',
|
||||
color: '#3D3D3D',
|
||||
verticalAlign: 'middle',
|
||||
borderRadius: '3px',
|
||||
cursor: 'pointer',
|
||||
'&:hover': {
|
||||
backgroundColor: selected ? '#FFEA9F' : '#EBEBEB',
|
||||
},
|
||||
'&:active': {
|
||||
backgroundColor: '#FFEA9F',
|
||||
},
|
||||
}}
|
||||
onClick={(e) => {
|
||||
props.applySearchQuery(props.filterTerm)
|
||||
e.preventDefault()
|
||||
}}
|
||||
>
|
||||
{props.text}
|
||||
@ -212,10 +277,21 @@ function FilterButton(props: FilterButtonProps): JSX.Element {
|
||||
|
||||
type LabelButtonProps = {
|
||||
label: Label
|
||||
state: 'on' | 'off' | 'unset'
|
||||
searchTerm: string | undefined
|
||||
applySearchQuery: (searchTerm: string) => void
|
||||
}
|
||||
|
||||
function LabelButton(props: LabelButtonProps): JSX.Element {
|
||||
const state = useMemo(() => {
|
||||
const term = props.searchTerm ?? ''
|
||||
if (term.indexOf(`label:\"${props.label.name}\"`) >= 0) {
|
||||
console.log('returning true for: ', term)
|
||||
return 'on'
|
||||
}
|
||||
console.log('returning off for: ', term)
|
||||
return 'off'
|
||||
}, [props.searchTerm, props.label])
|
||||
|
||||
return (
|
||||
<HStack
|
||||
css={{
|
||||
@ -229,6 +305,9 @@ function LabelButton(props: LabelButtonProps): JSX.Element {
|
||||
verticalAlign: 'middle',
|
||||
borderRadius: '3px',
|
||||
m: '0px',
|
||||
'&:hover': {
|
||||
backgroundColor: '#EBEBEB',
|
||||
},
|
||||
}}
|
||||
alignment="center"
|
||||
distribution="start"
|
||||
@ -236,13 +315,36 @@ function LabelButton(props: LabelButtonProps): JSX.Element {
|
||||
<Circle size={9} color={props.label.color} weight="fill" />
|
||||
<SpanBox css={{ pl: '10px' }}>{props.label.name}</SpanBox>
|
||||
<SpanBox css={{ ml: 'auto' }}>
|
||||
<input type="checkbox" />
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={state === 'on'}
|
||||
onChange={(e) => {
|
||||
console.log('changing check state')
|
||||
if (e.target.checked) {
|
||||
props.applySearchQuery
|
||||
props.applySearchQuery(
|
||||
`${props.searchTerm} label:\"${props.label.name}\"`
|
||||
)
|
||||
} else {
|
||||
const query =
|
||||
props.searchTerm?.replace(
|
||||
`label:\"${props.label.name}\"`,
|
||||
''
|
||||
) ?? ''
|
||||
props.applySearchQuery(query)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</SpanBox>
|
||||
</HStack>
|
||||
)
|
||||
}
|
||||
|
||||
function AddLinkButton(): JSX.Element {
|
||||
type AddLinkButtonProps = {
|
||||
showAddLinkModal: () => void
|
||||
}
|
||||
|
||||
function AddLinkButton(props: AddLinkButtonProps): JSX.Element {
|
||||
return (
|
||||
<VStack
|
||||
css={{
|
||||
@ -266,6 +368,10 @@ function AddLinkButton(): JSX.Element {
|
||||
alignItems: 'center',
|
||||
fontWeight: '600',
|
||||
}}
|
||||
onClick={(e) => {
|
||||
props.showAddLinkModal()
|
||||
e.preventDefault()
|
||||
}}
|
||||
>
|
||||
<Plus size={16} weight="bold" />
|
||||
<SpanBox css={{ width: '10px' }}></SpanBox>Add Link
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import {
|
||||
InputHTMLAttributes,
|
||||
ReactNode,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useRef,
|
||||
useState,
|
||||
@ -8,7 +9,7 @@ import {
|
||||
import { StyledText } from '../../elements/StyledText'
|
||||
import { Box, HStack, SpanBox, VStack } from '../../elements/LayoutPrimitives'
|
||||
import { SearchIcon } from '../../elements/images/SearchIcon'
|
||||
import { theme } from '../../tokens/stitches.config'
|
||||
import { theme, ThemeId } from '../../tokens/stitches.config'
|
||||
import { Dropdown, DropdownOption } from '../../elements/DropdownElements'
|
||||
import { FormInput } from '../../elements/FormElements'
|
||||
import { searchBarCommands } from '../../../lib/keyboardShortcuts/navigationShortcuts'
|
||||
@ -20,48 +21,25 @@ import { OmnivoreFullLogo } from '../../elements/images/OmnivoreFullLogo'
|
||||
import { AvatarDropdown } from '../../elements/AvatarDropdown'
|
||||
import { ListSelectorIcon } from '../../elements/images/ListSelectorIcon'
|
||||
import { GridSelectorIcon } from '../../elements/images/GridSelectorIcon'
|
||||
import { LayoutType } from './HomeFeedContainer'
|
||||
import { DropdownMenu, HeaderDropdownAction } from '../../patterns/DropdownMenu'
|
||||
import { updateTheme } from '../../../lib/themeUpdater'
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
type LibrarySearchBarProps = {
|
||||
searchTerm?: string
|
||||
type LibraryHeaderProps = {
|
||||
layout: LayoutType
|
||||
updateLayout: (layout: LayoutType) => void
|
||||
|
||||
searchTerm: string | undefined
|
||||
applySearchQuery: (searchQuery: string) => void
|
||||
}
|
||||
|
||||
type LibraryFilter =
|
||||
| 'in:inbox'
|
||||
| 'in:all'
|
||||
| 'in:archive'
|
||||
| 'type:file'
|
||||
| 'type:highlights'
|
||||
| `saved:${string}`
|
||||
| `sort:read`
|
||||
|
||||
// get last week's date
|
||||
const recentlySavedStartDate = new Date(
|
||||
new Date().getTime() - 7 * 24 * 60 * 60 * 1000
|
||||
).toLocaleDateString('en-US')
|
||||
|
||||
const FOCUSED_BOXSHADOW = '0px 0px 2px 2px rgba(255, 234, 159, 0.56)'
|
||||
|
||||
const HEADER_HEIGHT = '105px'
|
||||
const MOBILE_HEIGHT = '44px'
|
||||
|
||||
export function LibraryHeader(props: LibrarySearchBarProps): JSX.Element {
|
||||
const [focused, setFocused] = useState(false)
|
||||
const inputRef = useRef<HTMLInputElement>(null)
|
||||
const [searchTerm, setSearchTerm] = useState(props.searchTerm || '')
|
||||
|
||||
useEffect(() => {
|
||||
setSearchTerm(props.searchTerm || '')
|
||||
}, [props.searchTerm])
|
||||
|
||||
useKeyboardShortcuts(
|
||||
searchBarCommands((action) => {
|
||||
if (action === 'focusSearchBar' && inputRef.current) {
|
||||
inputRef.current.select()
|
||||
}
|
||||
})
|
||||
)
|
||||
const MOBILE_HEIGHT = '48px'
|
||||
|
||||
export function LibraryHeader(props: LibraryHeaderProps): JSX.Element {
|
||||
return (
|
||||
<>
|
||||
<VStack
|
||||
@ -93,7 +71,10 @@ export function LibraryHeader(props: LibrarySearchBarProps): JSX.Element {
|
||||
>
|
||||
<LogoBox />
|
||||
<SearchBox {...props} />
|
||||
<ControlButtonBox />
|
||||
<ControlButtonBox
|
||||
layout={props.layout}
|
||||
updateLayout={props.updateLayout}
|
||||
/>
|
||||
</HStack>
|
||||
</VStack>
|
||||
{/* This spacer is put in to push library content down
|
||||
@ -111,10 +92,23 @@ export function LibraryHeader(props: LibrarySearchBarProps): JSX.Element {
|
||||
)
|
||||
}
|
||||
|
||||
function SearchBox(props: LibrarySearchBarProps): JSX.Element {
|
||||
type SearchBoxProps = {
|
||||
searchTerm: string | undefined
|
||||
applySearchQuery: (searchQuery: string) => void
|
||||
}
|
||||
|
||||
function SearchBox(props: SearchBoxProps): JSX.Element {
|
||||
const inputRef = useRef<HTMLInputElement | null>(null)
|
||||
const [focused, setFocused] = useState(false)
|
||||
const [searchTerm, setSearchTerm] = useState('')
|
||||
const [searchTerm, setSearchTerm] = useState(props.searchTerm ?? '')
|
||||
|
||||
useKeyboardShortcuts(
|
||||
searchBarCommands((action) => {
|
||||
if (action === 'focusSearchBar' && inputRef.current) {
|
||||
inputRef.current.select()
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
return (
|
||||
<Box
|
||||
@ -128,6 +122,7 @@ function SearchBox(props: LibrarySearchBarProps): JSX.Element {
|
||||
'@mdDown': {
|
||||
display: 'none',
|
||||
},
|
||||
boxShadow: focused ? FOCUSED_BOXSHADOW : 'unset',
|
||||
}}
|
||||
>
|
||||
<HStack
|
||||
@ -139,6 +134,10 @@ function SearchBox(props: LibrarySearchBarProps): JSX.Element {
|
||||
alignment="center"
|
||||
distribution="start"
|
||||
css={{ height: '100%', px: '15px' }}
|
||||
onClick={(e) => {
|
||||
inputRef.current?.focus()
|
||||
e.preventDefault()
|
||||
}}
|
||||
>
|
||||
<MagnifyingGlass
|
||||
size={20}
|
||||
@ -151,6 +150,7 @@ function SearchBox(props: LibrarySearchBarProps): JSX.Element {
|
||||
props.applySearchQuery(searchTerm || '')
|
||||
inputRef.current?.blur()
|
||||
}}
|
||||
style={{ width: '100%' }}
|
||||
>
|
||||
<FormInput
|
||||
ref={inputRef}
|
||||
@ -169,7 +169,7 @@ function SearchBox(props: LibrarySearchBarProps): JSX.Element {
|
||||
}}
|
||||
/>
|
||||
</form>
|
||||
{searchTerm ? (
|
||||
{props.searchTerm ? (
|
||||
<Button
|
||||
style="plainIcon"
|
||||
onClick={(event) => {
|
||||
@ -206,7 +206,9 @@ function SearchBox(props: LibrarySearchBarProps): JSX.Element {
|
||||
height: '28px',
|
||||
color: '#898989',
|
||||
}}
|
||||
// onClick={() => requestAnimationFrame(() => inputRef.current.focus())}
|
||||
onClick={() =>
|
||||
requestAnimationFrame(() => inputRef?.current?.focus())
|
||||
}
|
||||
// we can make it unreachable via keyboard as we have the same message for the SR label
|
||||
tabIndex={-1}
|
||||
>
|
||||
@ -240,8 +242,6 @@ function LogoBox(): JSX.Element {
|
||||
css={{
|
||||
ml: '20px',
|
||||
mr: '20px',
|
||||
height: '22px',
|
||||
width: '22px',
|
||||
'@md': {
|
||||
display: 'none',
|
||||
},
|
||||
@ -253,7 +253,57 @@ function LogoBox(): JSX.Element {
|
||||
)
|
||||
}
|
||||
|
||||
function ControlButtonBox(): JSX.Element {
|
||||
type ControlButtonBoxProps = {
|
||||
layout: LayoutType
|
||||
updateLayout: (layout: LayoutType) => void
|
||||
}
|
||||
|
||||
function ControlButtonBox(props: ControlButtonBoxProps): JSX.Element {
|
||||
const router = useRouter()
|
||||
|
||||
const headerDropdownActionHandler = useCallback(
|
||||
(action: HeaderDropdownAction) => {
|
||||
switch (action) {
|
||||
case 'apply-darker-theme':
|
||||
updateTheme(ThemeId.Darker)
|
||||
break
|
||||
case 'apply-dark-theme':
|
||||
updateTheme(ThemeId.Dark)
|
||||
break
|
||||
case 'apply-lighter-theme':
|
||||
updateTheme(ThemeId.Lighter)
|
||||
break
|
||||
case 'apply-light-theme':
|
||||
updateTheme(ThemeId.Light)
|
||||
break
|
||||
case 'navigate-to-install':
|
||||
router.push('/settings/installation')
|
||||
break
|
||||
case 'navigate-to-emails':
|
||||
router.push('/settings/emails')
|
||||
break
|
||||
case 'navigate-to-labels':
|
||||
router.push('/settings/labels')
|
||||
break
|
||||
case 'navigate-to-subscriptions':
|
||||
router.push('/settings/subscriptions')
|
||||
break
|
||||
case 'navigate-to-api':
|
||||
router.push('/settings/api')
|
||||
break
|
||||
case 'navigate-to-integrations':
|
||||
router.push('/settings/integrations')
|
||||
break
|
||||
case 'logout':
|
||||
// props.setShowLogoutConfirmation(true)
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
},
|
||||
[updateTheme, router]
|
||||
)
|
||||
|
||||
return (
|
||||
<>
|
||||
<HStack
|
||||
@ -271,9 +321,36 @@ function ControlButtonBox(): JSX.Element {
|
||||
},
|
||||
}}
|
||||
>
|
||||
<ListSelectorIcon />
|
||||
<GridSelectorIcon />
|
||||
<AvatarDropdown userInitials="JH" />
|
||||
<Button
|
||||
style="plainIcon"
|
||||
css={{ display: 'flex' }}
|
||||
onClick={(e) => {
|
||||
props.updateLayout('LIST_LAYOUT')
|
||||
e.preventDefault()
|
||||
}}
|
||||
>
|
||||
<ListSelectorIcon
|
||||
color={props.layout == 'GRID_LAYOUT' ? '#6A6968' : '#FFEA9F'}
|
||||
/>
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
style="plainIcon"
|
||||
css={{ display: 'flex' }}
|
||||
onClick={(e) => {
|
||||
props.updateLayout('GRID_LAYOUT')
|
||||
e.preventDefault()
|
||||
}}
|
||||
>
|
||||
<GridSelectorIcon
|
||||
color={props.layout == 'LIST_LAYOUT' ? '#6A6968' : '#FFEA9F'}
|
||||
/>
|
||||
</Button>
|
||||
<DropdownMenu
|
||||
username={'props.username'}
|
||||
triggerElement={<AvatarDropdown userInitials="JH" />}
|
||||
actionHandler={headerDropdownActionHandler}
|
||||
/>
|
||||
</HStack>
|
||||
|
||||
<HStack
|
||||
|
||||
Reference in New Issue
Block a user