refactor(nav): migrate header, dashboard chrome and discovery UI to v3
- Header/MobileBar: MenuRoot/Positioner/Content + Portal + Tooltip shims, ghost icon buttons, 2rem padded user/settings menus, hover token gray.700; MobileBar drawer API (open/onOpenChange/finalFocusEl) - FilterBar/ActiveFilters: DrawerRoot/CloseTrigger, Divider -> Separator, Tag shim, FixedSelect with typed handlers and width-preserving chakraStyles, blue active-filter pills untouched - Pagination: NumberInputRoot/Field + NativeSelect shims, first/last arrows back to double chevrons (LuChevronsLeft/Right), single chevrons kept for prev/next - Search/SearchModal, Home, NoGames, LoadingModal, DashboardLoadingModal: Dialog/Toaster-era props, gap/align/textAlign renames; App.test target content updated accordingly
This commit is contained in:
@@ -1,7 +1,8 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { useHookstate } from '@hookstate/core'
|
import { useHookstate } from '@hookstate/core'
|
||||||
import { gameDashboardState } from '../stateManagement/gameState'
|
import { gameDashboardState } from '../stateManagement/gameState'
|
||||||
import { Flex, Stack, HStack, Link, Spacer, Tag, TagCloseButton, TagLabel } from '@chakra-ui/react'
|
import { Flex, Stack, HStack, Link, Spacer } from '@chakra-ui/react'
|
||||||
|
import {Tag} from './ui/tag'
|
||||||
import getWithFilters from '../componentUtils/getWithFilters'
|
import getWithFilters from '../componentUtils/getWithFilters'
|
||||||
import {
|
import {
|
||||||
loadingState,
|
loadingState,
|
||||||
@@ -53,7 +54,7 @@ const ActiveFilters = () => {
|
|||||||
}} direction={{
|
}} direction={{
|
||||||
base: 'column',
|
base: 'column',
|
||||||
md: 'row'
|
md: 'row'
|
||||||
}} spacing={4}>
|
}} gap={4}>
|
||||||
{searchParams.length >= 1 && (
|
{searchParams.length >= 1 && (
|
||||||
<>
|
<>
|
||||||
<h2>Search: </h2>
|
<h2>Search: </h2>
|
||||||
@@ -61,11 +62,8 @@ const ActiveFilters = () => {
|
|||||||
size={'md'}
|
size={'md'}
|
||||||
borderRadius="full"
|
borderRadius="full"
|
||||||
variant="solid"
|
variant="solid"
|
||||||
colorScheme="blue"
|
colorPalette="blue"
|
||||||
>
|
onClose={async () => {
|
||||||
<TagLabel><Link
|
|
||||||
onMouseDown={() => setSearchModalOpen.set(true)}>{searchParams}</Link></TagLabel>
|
|
||||||
<TagCloseButton onMouseDown={async () => {
|
|
||||||
const newSearchParams = ""
|
const newSearchParams = ""
|
||||||
ChangeActiveFilterHeader(filters, newSearchParams, setShowFiltersModuleState)
|
ChangeActiveFilterHeader(filters, newSearchParams, setShowFiltersModuleState)
|
||||||
searchComplete.set(false)
|
searchComplete.set(false)
|
||||||
@@ -80,7 +78,9 @@ const ActiveFilters = () => {
|
|||||||
useRatingState,
|
useRatingState,
|
||||||
useSteamRatingState,
|
useSteamRatingState,
|
||||||
)
|
)
|
||||||
}} />
|
}}
|
||||||
|
><Link
|
||||||
|
onMouseDown={() => setSearchModalOpen.set(true)}>{searchParams}</Link>
|
||||||
</Tag>
|
</Tag>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
@@ -99,22 +99,20 @@ const ActiveFilters = () => {
|
|||||||
<>
|
<>
|
||||||
<HStack key={num}>
|
<HStack key={num}>
|
||||||
<h3 style={{ textTransform: 'capitalize' }}>{filter}</h3>
|
<h3 style={{ textTransform: 'capitalize' }}>{filter}</h3>
|
||||||
<HStack spacing={4}>
|
<HStack gap={4}>
|
||||||
{filters[filter as keyof typeof filters].split(',').map((item: string, index) => (
|
{filters[filter as keyof typeof filters].split(',').map((item: string, index) => (
|
||||||
<Tag
|
<Tag
|
||||||
size={'md'}
|
size={'md'}
|
||||||
key={index}
|
key={index}
|
||||||
borderRadius="full"
|
borderRadius="full"
|
||||||
variant="solid"
|
variant="solid"
|
||||||
colorScheme="blue"
|
colorPalette="blue"
|
||||||
>
|
onClose={() => removeFilters(filter, item)}
|
||||||
<TagLabel>{
|
>{
|
||||||
item.includes('lte')
|
item.includes('lte')
|
||||||
? item.replace('lte', '<= ')
|
? item.replace('lte', '<= ')
|
||||||
: item.includes('gte') ? item.replace('gte', '>= ')
|
: item.includes('gte') ? item.replace('gte', '>= ')
|
||||||
: item}
|
: item}
|
||||||
</TagLabel>
|
|
||||||
<TagCloseButton onMouseDown={() => removeFilters(filter, item)} />
|
|
||||||
</Tag>
|
</Tag>
|
||||||
))}
|
))}
|
||||||
</HStack>
|
</HStack>
|
||||||
|
|||||||
@@ -1,17 +1,12 @@
|
|||||||
import React, {MutableRefObject, useEffect} from 'react'
|
import React, {MutableRefObject, useEffect} from 'react'
|
||||||
import {
|
import {
|
||||||
Center,
|
Center,
|
||||||
Divider,
|
Separator,
|
||||||
Drawer,
|
Flex,
|
||||||
DrawerBody,
|
|
||||||
DrawerCloseButton,
|
|
||||||
DrawerContent,
|
|
||||||
DrawerFooter,
|
|
||||||
DrawerHeader,
|
|
||||||
DrawerOverlay, Flex,
|
|
||||||
Heading, Spacer,
|
Heading, Spacer,
|
||||||
Text,
|
Text,
|
||||||
} from '@chakra-ui/react'
|
} from '@chakra-ui/react'
|
||||||
|
import {DrawerBody, DrawerCloseTrigger, DrawerContent, DrawerFooter, DrawerHeader, DrawerRoot} from './ui/drawer'
|
||||||
import AdminMode from './authComponents/AdminMode'
|
import AdminMode from './authComponents/AdminMode'
|
||||||
import {StateMethods, useHookstate} from '@hookstate/core'
|
import {StateMethods, useHookstate} from '@hookstate/core'
|
||||||
import {tagState} from '../stateManagement/tagState'
|
import {tagState} from '../stateManagement/tagState'
|
||||||
@@ -25,7 +20,7 @@ import {
|
|||||||
} from '../componentUtils/SelectValues'
|
} from '../componentUtils/SelectValues'
|
||||||
import {retrieveTags} from '../componentUtils/retrieveTags'
|
import {retrieveTags} from '../componentUtils/retrieveTags'
|
||||||
import {gameDashboardState} from '../stateManagement/gameState'
|
import {gameDashboardState} from '../stateManagement/gameState'
|
||||||
import {Select} from 'chakra-react-select'
|
import {Select} from './FixedSelect'
|
||||||
import getWithFilters from '../componentUtils/getWithFilters'
|
import getWithFilters from '../componentUtils/getWithFilters'
|
||||||
import {loadingState, showFiltersModuleState} from '../stateManagement/loadingState'
|
import {loadingState, showFiltersModuleState} from '../stateManagement/loadingState'
|
||||||
import {adminMode} from '../stateManagement/userState'
|
import {adminMode} from '../stateManagement/userState'
|
||||||
@@ -99,26 +94,25 @@ function FilterBar({filterIsOpen, filterOnClose, btnRef}: Props) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Drawer
|
<DrawerRoot
|
||||||
isOpen={filterIsOpen}
|
open={filterIsOpen}
|
||||||
placement="right"
|
placement="end"
|
||||||
onClose={filterOnClose}
|
onOpenChange={(e) => { if (!e.open) filterOnClose() }}
|
||||||
finalFocusRef={btnRef}
|
finalFocusEl={() => btnRef.current as unknown as HTMLElement}
|
||||||
>
|
>
|
||||||
<DrawerOverlay/>
|
|
||||||
<DrawerContent>
|
<DrawerContent>
|
||||||
<DrawerCloseButton/>
|
<DrawerCloseTrigger/>
|
||||||
<DrawerHeader>
|
<DrawerHeader>
|
||||||
<Heading as={'h3'}>Filters</Heading>
|
<Heading as={'h3'}>Filters</Heading>
|
||||||
</DrawerHeader>
|
</DrawerHeader>
|
||||||
|
|
||||||
<DrawerBody>
|
<DrawerBody>
|
||||||
<AdminMode/>
|
<AdminMode/>
|
||||||
<Divider my={'3'}/>
|
<Separator borderColor="gray.200" my={'3'}/>
|
||||||
<Center>
|
<Center>
|
||||||
<ResetFilterButton/>
|
<ResetFilterButton/>
|
||||||
</Center>
|
</Center>
|
||||||
<Divider my={'3'}/>
|
<Separator borderColor="gray.200" my={'3'}/>
|
||||||
<Text mb={'1'} fontSize={'xl'}>Series</Text>
|
<Text mb={'1'} fontSize={'xl'}>Series</Text>
|
||||||
<Select
|
<Select
|
||||||
size={'sm'}
|
size={'sm'}
|
||||||
@@ -126,13 +120,13 @@ function FilterBar({filterIsOpen, filterOnClose, btnRef}: Props) {
|
|||||||
isClearable
|
isClearable
|
||||||
isMulti
|
isMulti
|
||||||
name="series"
|
name="series"
|
||||||
onChange={(event) => {
|
onChange={(event: any) => {
|
||||||
const value = event.map(a => a.value).join(',')
|
const value = event.map((a: any) => a.value).join(',')
|
||||||
changeFilters("series", value)
|
changeFilters("series", value)
|
||||||
}}
|
}}
|
||||||
options={tags.series}
|
options={tags.series}
|
||||||
/>
|
/>
|
||||||
<Divider my={'3'}/>
|
<Separator borderColor="gray.200" my={'3'}/>
|
||||||
<Flex mb={'1'}>
|
<Flex mb={'1'}>
|
||||||
<Text mb={'1'} fontSize={'xl'}>Rating</Text>
|
<Text mb={'1'} fontSize={'xl'}>Rating</Text>
|
||||||
<Spacer />
|
<Spacer />
|
||||||
@@ -140,13 +134,13 @@ function FilterBar({filterIsOpen, filterOnClose, btnRef}: Props) {
|
|||||||
size={'sm'}
|
size={'sm'}
|
||||||
defaultValue={ratingToSelectDefaultValue(useRatingState)}
|
defaultValue={ratingToSelectDefaultValue(useRatingState)}
|
||||||
name="rating"
|
name="rating"
|
||||||
onChange={(event) => {
|
onChange={(event: any) => {
|
||||||
if (event === null) return
|
if (event === null) return
|
||||||
setRatingState.set(event.value)
|
setRatingState.set(event.value)
|
||||||
}}
|
}}
|
||||||
options={ratingStateValues}
|
options={ratingStateValues}
|
||||||
chakraStyles={{
|
chakraStyles={{
|
||||||
container: (provided) => ({
|
container: (provided: any) => ({
|
||||||
...provided,
|
...provided,
|
||||||
width: "75px"
|
width: "75px"
|
||||||
})
|
})
|
||||||
@@ -158,13 +152,13 @@ function FilterBar({filterIsOpen, filterOnClose, btnRef}: Props) {
|
|||||||
defaultValue={filterToSelectDefaultValue("rating")}
|
defaultValue={filterToSelectDefaultValue("rating")}
|
||||||
isClearable
|
isClearable
|
||||||
name="rating"
|
name="rating"
|
||||||
onChange={(event) => {
|
onChange={(event: any) => {
|
||||||
if(event === null) return changeFilters("rating", "")
|
if(event === null) return changeFilters("rating", "")
|
||||||
changeFilters("rating", event.value)
|
changeFilters("rating", event.value)
|
||||||
}}
|
}}
|
||||||
options={ratingValues}
|
options={ratingValues}
|
||||||
/>
|
/>
|
||||||
<Divider my={'1'}/>
|
<Separator borderColor="gray.200" my={'1'}/>
|
||||||
<Flex mb={'1'}>
|
<Flex mb={'1'}>
|
||||||
<Text mb={'1'} fontSize={'xl'}>Steam Rating</Text>
|
<Text mb={'1'} fontSize={'xl'}>Steam Rating</Text>
|
||||||
<Spacer />
|
<Spacer />
|
||||||
@@ -172,13 +166,13 @@ function FilterBar({filterIsOpen, filterOnClose, btnRef}: Props) {
|
|||||||
size={'sm'}
|
size={'sm'}
|
||||||
defaultValue={ratingToSelectDefaultValue(useSteamRatingState)}
|
defaultValue={ratingToSelectDefaultValue(useSteamRatingState)}
|
||||||
name="steamRating"
|
name="steamRating"
|
||||||
onChange={(event) => {
|
onChange={(event: any) => {
|
||||||
if (event === null) return
|
if (event === null) return
|
||||||
setSteamRatingState.set(event.value)
|
setSteamRatingState.set(event.value)
|
||||||
}}
|
}}
|
||||||
options={ratingStateValues}
|
options={ratingStateValues}
|
||||||
chakraStyles={{
|
chakraStyles={{
|
||||||
container: (provided) => ({
|
container: (provided: any) => ({
|
||||||
...provided,
|
...provided,
|
||||||
width: "75px"
|
width: "75px"
|
||||||
})
|
})
|
||||||
@@ -190,13 +184,13 @@ function FilterBar({filterIsOpen, filterOnClose, btnRef}: Props) {
|
|||||||
defaultValue={filterToSelectDefaultValue("steamRating")}
|
defaultValue={filterToSelectDefaultValue("steamRating")}
|
||||||
isClearable
|
isClearable
|
||||||
name="steamRating"
|
name="steamRating"
|
||||||
onChange={(event) => {
|
onChange={(event: any) => {
|
||||||
if(event === null) return changeFilters("steamRating", "")
|
if(event === null) return changeFilters("steamRating", "")
|
||||||
changeFilters("steamRating", event.value)
|
changeFilters("steamRating", event.value)
|
||||||
}}
|
}}
|
||||||
options={ratingValues}
|
options={ratingValues}
|
||||||
/>
|
/>
|
||||||
<Divider my={'1'}/>
|
<Separator borderColor="gray.200" my={'1'}/>
|
||||||
<Text mb={'1'} fontSize={'xl'}>Play Status</Text>
|
<Text mb={'1'} fontSize={'xl'}>Play Status</Text>
|
||||||
<Select
|
<Select
|
||||||
size={'sm'}
|
size={'sm'}
|
||||||
@@ -204,13 +198,13 @@ function FilterBar({filterIsOpen, filterOnClose, btnRef}: Props) {
|
|||||||
isClearable
|
isClearable
|
||||||
isMulti
|
isMulti
|
||||||
name="playStatus"
|
name="playStatus"
|
||||||
onChange={(event) => {
|
onChange={(event: any) => {
|
||||||
const value = event.map(a => a.value).join(',')
|
const value = event.map((a: any) => a.value).join(',')
|
||||||
changeFilters("playStatus", value)
|
changeFilters("playStatus", value)
|
||||||
}}
|
}}
|
||||||
options={playStatusValues}
|
options={playStatusValues}
|
||||||
/>
|
/>
|
||||||
<Divider my={'1'}/>
|
<Separator borderColor="gray.200" my={'1'}/>
|
||||||
<Text mb={'1'} fontSize={'xl'}>Genres</Text>
|
<Text mb={'1'} fontSize={'xl'}>Genres</Text>
|
||||||
<Select
|
<Select
|
||||||
size={'sm'}
|
size={'sm'}
|
||||||
@@ -218,13 +212,13 @@ function FilterBar({filterIsOpen, filterOnClose, btnRef}: Props) {
|
|||||||
isClearable
|
isClearable
|
||||||
isMulti
|
isMulti
|
||||||
name="genre"
|
name="genre"
|
||||||
onChange={(event) => {
|
onChange={(event: any) => {
|
||||||
const value = event.map(a => a.value).join(',')
|
const value = event.map((a: any) => a.value).join(',')
|
||||||
changeFilters("genre", value)
|
changeFilters("genre", value)
|
||||||
}}
|
}}
|
||||||
options={tags.genres}
|
options={tags.genres}
|
||||||
/>
|
/>
|
||||||
<Divider my={'1'}/>
|
<Separator borderColor="gray.200" my={'1'}/>
|
||||||
<Text mb={'1'} fontSize={'xl'}>Operating System</Text>
|
<Text mb={'1'} fontSize={'xl'}>Operating System</Text>
|
||||||
<Select
|
<Select
|
||||||
size={'sm'}
|
size={'sm'}
|
||||||
@@ -232,13 +226,13 @@ function FilterBar({filterIsOpen, filterOnClose, btnRef}: Props) {
|
|||||||
isClearable
|
isClearable
|
||||||
isMulti
|
isMulti
|
||||||
name="os"
|
name="os"
|
||||||
onChange={(event) => {
|
onChange={(event: any) => {
|
||||||
const value = event.map(a => a.value).join(',')
|
const value = event.map((a: any) => a.value).join(',')
|
||||||
changeFilters("os", value)
|
changeFilters("os", value)
|
||||||
}}
|
}}
|
||||||
options={osValues}
|
options={osValues}
|
||||||
/>
|
/>
|
||||||
<Divider my={'1'}/>
|
<Separator borderColor="gray.200" my={'1'}/>
|
||||||
<Text mb={'1'} fontSize={'xl'}>Store</Text>
|
<Text mb={'1'} fontSize={'xl'}>Store</Text>
|
||||||
<Select
|
<Select
|
||||||
size={'sm'}
|
size={'sm'}
|
||||||
@@ -246,13 +240,13 @@ function FilterBar({filterIsOpen, filterOnClose, btnRef}: Props) {
|
|||||||
isClearable
|
isClearable
|
||||||
isMulti
|
isMulti
|
||||||
name="store"
|
name="store"
|
||||||
onChange={(event) => {
|
onChange={(event: any) => {
|
||||||
const value = event.map(a => a.value).join(',')
|
const value = event.map((a: any) => a.value).join(',')
|
||||||
changeFilters("store", value)
|
changeFilters("store", value)
|
||||||
}}
|
}}
|
||||||
options={tags.store}
|
options={tags.store}
|
||||||
/>
|
/>
|
||||||
<Divider my={'1'}/>
|
<Separator borderColor="gray.200" my={'1'}/>
|
||||||
<Text mb={'1'} fontSize={'xl'}>Controller Support</Text>
|
<Text mb={'1'} fontSize={'xl'}>Controller Support</Text>
|
||||||
<Select
|
<Select
|
||||||
size={'sm'}
|
size={'sm'}
|
||||||
@@ -260,13 +254,13 @@ function FilterBar({filterIsOpen, filterOnClose, btnRef}: Props) {
|
|||||||
isClearable
|
isClearable
|
||||||
isMulti
|
isMulti
|
||||||
name="controller"
|
name="controller"
|
||||||
onChange={(event) => {
|
onChange={(event: any) => {
|
||||||
const value = event.map(a => a.value).join(',')
|
const value = event.map((a: any) => a.value).join(',')
|
||||||
changeFilters("controller", value)
|
changeFilters("controller", value)
|
||||||
}}
|
}}
|
||||||
options={controllerValues}
|
options={controllerValues}
|
||||||
/>
|
/>
|
||||||
<Divider my={'1'}/>
|
<Separator borderColor="gray.200" my={'1'}/>
|
||||||
<Text mb={'1'} fontSize={'xl'}>Developer</Text>
|
<Text mb={'1'} fontSize={'xl'}>Developer</Text>
|
||||||
<Select
|
<Select
|
||||||
size={'sm'}
|
size={'sm'}
|
||||||
@@ -274,13 +268,13 @@ function FilterBar({filterIsOpen, filterOnClose, btnRef}: Props) {
|
|||||||
isClearable
|
isClearable
|
||||||
isMulti
|
isMulti
|
||||||
name="developer"
|
name="developer"
|
||||||
onChange={(event) => {
|
onChange={(event: any) => {
|
||||||
const value = event.map(a => a.value).join(',')
|
const value = event.map((a: any) => a.value).join(',')
|
||||||
changeFilters("developer", value)
|
changeFilters("developer", value)
|
||||||
}}
|
}}
|
||||||
options={tags.developer}
|
options={tags.developer}
|
||||||
/>
|
/>
|
||||||
<Divider my={'1'}/>
|
<Separator borderColor="gray.200" my={'1'}/>
|
||||||
<Text mb={'1'} fontSize={'xl'}>Publisher</Text>
|
<Text mb={'1'} fontSize={'xl'}>Publisher</Text>
|
||||||
<Select
|
<Select
|
||||||
size={'sm'}
|
size={'sm'}
|
||||||
@@ -288,13 +282,13 @@ function FilterBar({filterIsOpen, filterOnClose, btnRef}: Props) {
|
|||||||
isClearable
|
isClearable
|
||||||
isMulti
|
isMulti
|
||||||
name="publisher"
|
name="publisher"
|
||||||
onChange={(event) => {
|
onChange={(event: any) => {
|
||||||
const value = event.map(a => a.value).join(',')
|
const value = event.map((a: any) => a.value).join(',')
|
||||||
changeFilters("publisher", value)
|
changeFilters("publisher", value)
|
||||||
}}
|
}}
|
||||||
options={tags.publisher}
|
options={tags.publisher}
|
||||||
/>
|
/>
|
||||||
<Divider my={'1'}/>
|
<Separator borderColor="gray.200" my={'1'}/>
|
||||||
<Text mb={'1'} fontSize={'xl'}>Do you own the Soundtrack?</Text>
|
<Text mb={'1'} fontSize={'xl'}>Do you own the Soundtrack?</Text>
|
||||||
<Select
|
<Select
|
||||||
size={'sm'}
|
size={'sm'}
|
||||||
@@ -302,13 +296,13 @@ function FilterBar({filterIsOpen, filterOnClose, btnRef}: Props) {
|
|||||||
isClearable
|
isClearable
|
||||||
isMulti
|
isMulti
|
||||||
name="soundtrack"
|
name="soundtrack"
|
||||||
onChange={(event) => {
|
onChange={(event: any) => {
|
||||||
const value = event.map(a => a.value).join(',')
|
const value = event.map((a: any) => a.value).join(',')
|
||||||
changeFilters("soundtrack", value)
|
changeFilters("soundtrack", value)
|
||||||
}}
|
}}
|
||||||
options={yesNo}
|
options={yesNo}
|
||||||
/>
|
/>
|
||||||
<Divider my={'1'}/>
|
<Separator borderColor="gray.200" my={'1'}/>
|
||||||
<Text mb={'1'} fontSize={'xl'}>Does in work on Intel?</Text>
|
<Text mb={'1'} fontSize={'xl'}>Does in work on Intel?</Text>
|
||||||
<Select
|
<Select
|
||||||
size={'sm'}
|
size={'sm'}
|
||||||
@@ -316,13 +310,13 @@ function FilterBar({filterIsOpen, filterOnClose, btnRef}: Props) {
|
|||||||
isClearable
|
isClearable
|
||||||
isMulti
|
isMulti
|
||||||
name="intel"
|
name="intel"
|
||||||
onChange={(event) => {
|
onChange={(event: any) => {
|
||||||
const value = event.map(a => a.value).join(',')
|
const value = event.map((a: any) => a.value).join(',')
|
||||||
changeFilters("intel", value)
|
changeFilters("intel", value)
|
||||||
}}
|
}}
|
||||||
options={wineIntelValues}
|
options={wineIntelValues}
|
||||||
/>
|
/>
|
||||||
<Divider my={'1'}/>
|
<Separator borderColor="gray.200" my={'1'}/>
|
||||||
<Text mb={'1'} fontSize={'xl'}>Does is work with Wine?</Text>
|
<Text mb={'1'} fontSize={'xl'}>Does is work with Wine?</Text>
|
||||||
<Select
|
<Select
|
||||||
size={'sm'}
|
size={'sm'}
|
||||||
@@ -330,21 +324,21 @@ function FilterBar({filterIsOpen, filterOnClose, btnRef}: Props) {
|
|||||||
isClearable
|
isClearable
|
||||||
isMulti
|
isMulti
|
||||||
name="wine"
|
name="wine"
|
||||||
onChange={(event) => {
|
onChange={(event: any) => {
|
||||||
const value = event.map(a => a.value).join(',')
|
const value = event.map((a: any) => a.value).join(',')
|
||||||
changeFilters("wine", value)
|
changeFilters("wine", value)
|
||||||
}}
|
}}
|
||||||
options={wineIntelValues}
|
options={wineIntelValues}
|
||||||
/>
|
/>
|
||||||
<Divider my={'1'}/>
|
<Separator borderColor="gray.200" my={'1'}/>
|
||||||
</DrawerBody>
|
</DrawerBody>
|
||||||
|
|
||||||
<DrawerFooter>
|
<DrawerFooter>
|
||||||
|
|
||||||
</DrawerFooter>
|
</DrawerFooter>
|
||||||
</DrawerContent>
|
</DrawerContent>
|
||||||
</Drawer>
|
</DrawerRoot>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default FilterBar
|
export default FilterBar
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ export default function Footer() {
|
|||||||
return (
|
return (
|
||||||
<Box as='footer' role='contentinfo' mx='auto' maxW='7xl' py='12' px={{ base: '4', md: '8' }}>
|
<Box as='footer' role='contentinfo' mx='auto' maxW='7xl' py='12' px={{ base: '4', md: '8' }}>
|
||||||
<Stack>
|
<Stack>
|
||||||
<Stack direction="row" spacing="4" align="center" justify="space-between">
|
<Stack direction="row" gap="4" align="center" justify="space-between">
|
||||||
|
|
||||||
|
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import React, { useEffect } from 'react'
|
|||||||
import { gameDashboardState } from '../stateManagement/gameState'
|
import { gameDashboardState } from '../stateManagement/gameState'
|
||||||
import { loadingState } from '../stateManagement/loadingState'
|
import { loadingState } from '../stateManagement/loadingState'
|
||||||
import { useHookstate } from '@hookstate/core'
|
import { useHookstate } from '@hookstate/core'
|
||||||
import { Box, Center, Container, Divider, Heading, SimpleGrid, VStack } from '@chakra-ui/react'
|
import { Box, Center, Container, Separator, Heading, SimpleGrid, VStack } from '@chakra-ui/react'
|
||||||
import Pagination from './Pagination'
|
import Pagination from './Pagination'
|
||||||
import { NavLink } from 'react-router-dom'
|
import { NavLink } from 'react-router-dom'
|
||||||
import { adminMode } from '../stateManagement/userState'
|
import { adminMode } from '../stateManagement/userState'
|
||||||
@@ -33,34 +33,36 @@ const GameDashboard = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Container maxW="container.xl" mt="7">
|
<Container maxW="1280px" mt="7">
|
||||||
<Pagination />
|
<Pagination />
|
||||||
<ActiveFilters />
|
<ActiveFilters />
|
||||||
<Divider />
|
<Separator borderColor="gray.200" />
|
||||||
{!loaded ? <DashboardLoadingModal /> : games.count.totalGames === 0 ?
|
{!loaded ? <DashboardLoadingModal /> : games.count.totalGames === 0 ?
|
||||||
<Center h={'80vh'}>
|
<Center h={'80vh'}>
|
||||||
<VStack spacing={10}>
|
<VStack gap={10}>
|
||||||
<Heading as={'h1'} size={'3xl'}>No Results Found...</Heading>
|
<Heading as={'h1'} size={'3xl'}>No Results Found...</Heading>
|
||||||
<Divider />
|
<Separator borderColor="gray.200" />
|
||||||
{games.searchParams !== '' ?
|
{games.searchParams !== '' ?
|
||||||
<Box mt='10'>
|
<Box mt='10'>
|
||||||
<ResetFilterButton text='Clear Search and Filters' size='lg' variant='outline' colorScheme='blue' />
|
<ResetFilterButton text='Clear Search and Filters' size='lg' variant='outline' colorPalette='blue' />
|
||||||
</Box>
|
</Box>
|
||||||
:
|
:
|
||||||
<Box
|
<Box
|
||||||
rounded={'md'}
|
rounded={'md'}
|
||||||
as={NavLink}
|
asChild
|
||||||
border={'1px'}
|
borderWidth={'1px'} borderStyle={'solid'}
|
||||||
p={'3'}
|
p={'3'}
|
||||||
fontSize={'2xl'}
|
fontSize={'2xl'}
|
||||||
to="/games/create">
|
>
|
||||||
|
<NavLink to="/games/create">
|
||||||
Create a Game
|
Create a Game
|
||||||
|
</NavLink>
|
||||||
</Box>
|
</Box>
|
||||||
}
|
}
|
||||||
</VStack>
|
</VStack>
|
||||||
</Center>
|
</Center>
|
||||||
:
|
:
|
||||||
<SimpleGrid columns={{ base: 1, sm: 2, md: 3 }} spacing={10} style={{ marginTop: '3rem' }}>
|
<SimpleGrid columns={{ base: 1, sm: 2, md: 3 }} gap={10} style={{ marginTop: '3rem' }}>
|
||||||
{games.data.map((game) => (
|
{games.data.map((game) => (
|
||||||
<GameThumbnailContextMenu
|
<GameThumbnailContextMenu
|
||||||
key={game._id}
|
key={game._id}
|
||||||
@@ -68,7 +70,7 @@ const GameDashboard = () => {
|
|||||||
game={game} />
|
game={game} />
|
||||||
))}
|
))}
|
||||||
</SimpleGrid>}
|
</SimpleGrid>}
|
||||||
<Divider my={'1rem'} />
|
<Separator borderColor="gray.200" my={'1rem'} />
|
||||||
<Pagination />
|
<Pagination />
|
||||||
</Container>
|
</Container>
|
||||||
</>
|
</>
|
||||||
|
|||||||
+90
-92
@@ -9,27 +9,23 @@ import {
|
|||||||
Link,
|
Link,
|
||||||
HStack,
|
HStack,
|
||||||
Stack,
|
Stack,
|
||||||
useColorModeValue,
|
|
||||||
Menu,
|
Menu,
|
||||||
MenuButton,
|
Portal,
|
||||||
Avatar,
|
|
||||||
MenuList,
|
|
||||||
MenuItem,
|
|
||||||
MenuDivider,
|
|
||||||
Icon,
|
Icon,
|
||||||
useColorMode,
|
|
||||||
Text,
|
Text,
|
||||||
Center,
|
Center,
|
||||||
VStack,
|
VStack,
|
||||||
Tooltip,
|
Separator,
|
||||||
Divider,
|
|
||||||
Heading,
|
Heading,
|
||||||
Kbd,
|
Kbd,
|
||||||
Spacer,
|
Spacer,
|
||||||
useDisclosure,
|
useDisclosure,
|
||||||
useMediaQuery,
|
useMediaQuery,
|
||||||
} from '@chakra-ui/react'
|
} from '@chakra-ui/react'
|
||||||
import { AddIcon, HamburgerIcon, Search2Icon, SettingsIcon } from '@chakra-ui/icons'
|
import {useColorMode, useColorModeValue} from './ui/color-mode'
|
||||||
|
import {Tooltip} from './ui/tooltip'
|
||||||
|
import {Avatar} from './ui/avatar'
|
||||||
|
import { LuPlus, LuMenu, LuSearch, LuSettings } from 'react-icons/lu'
|
||||||
import SearchModal from './SearchModal'
|
import SearchModal from './SearchModal'
|
||||||
import { openAndCloseSearchDialogue } from '../stateManagement/loadingState'
|
import { openAndCloseSearchDialogue } from '../stateManagement/loadingState'
|
||||||
import AdminMode from './authComponents/AdminMode'
|
import AdminMode from './authComponents/AdminMode'
|
||||||
@@ -49,10 +45,10 @@ export default function NavBar() {
|
|||||||
const bgLink = useColorModeValue('gray.200', 'gray.700')
|
const bgLink = useColorModeValue('gray.200', 'gray.700')
|
||||||
const location = useLocation()
|
const location = useLocation()
|
||||||
const history = useNavigate()
|
const history = useNavigate()
|
||||||
const { isOpen: mobileIsOpen, onOpen: mobileOnOpen, onClose: mobileOnClose } = useDisclosure()
|
const { open: mobileIsOpen, onOpen: mobileOnOpen, onClose: mobileOnClose } = useDisclosure()
|
||||||
const { isOpen: filterIsOpen, onOpen: filterOnOpen, onClose: filterOnClose } = useDisclosure()
|
const { open: filterIsOpen, onOpen: filterOnOpen, onClose: filterOnClose } = useDisclosure()
|
||||||
const btnRef = React.useRef(null)
|
const btnRef = React.useRef(null)
|
||||||
const [isSmallerThan768] = useMediaQuery('(max-width: 768px)')
|
const [isSmallerThan768] = useMediaQuery(['(max-width: 768px)'])
|
||||||
|
|
||||||
const handleKeyPress = useCallback((event: any) => {
|
const handleKeyPress = useCallback((event: any) => {
|
||||||
if (event.ctrlKey === true && event.key === ',') {
|
if (event.ctrlKey === true && event.key === ',') {
|
||||||
@@ -95,13 +91,13 @@ export default function NavBar() {
|
|||||||
position={loadedPreferences.get().stickyNav ? "fixed" : "relative"}
|
position={loadedPreferences.get().stickyNav ? "fixed" : "relative"}
|
||||||
justifyContent={'space-between'}
|
justifyContent={'space-between'}
|
||||||
>
|
>
|
||||||
<HStack spacing={8} alignItems={'center'}>
|
<HStack gap={8} alignItems={'center'}>
|
||||||
<Box as={RouteLink} to="/">
|
<Box asChild>
|
||||||
Game Database
|
<RouteLink to="/">Game Database</RouteLink>
|
||||||
</Box>
|
</Box>
|
||||||
<HStack
|
<HStack
|
||||||
as={'nav'}
|
as={'nav'}
|
||||||
spacing={4}
|
gap={4}
|
||||||
display={{ base: 'none', md: 'flex' }}
|
display={{ base: 'none', md: 'flex' }}
|
||||||
>
|
>
|
||||||
<Link
|
<Link
|
||||||
@@ -112,9 +108,8 @@ export default function NavBar() {
|
|||||||
textDecoration: 'none',
|
textDecoration: 'none',
|
||||||
bg: bgLink,
|
bg: bgLink,
|
||||||
}}
|
}}
|
||||||
as={RouteLink}
|
asChild>
|
||||||
to="/games">
|
<RouteLink to="/games">Games</RouteLink>
|
||||||
Games
|
|
||||||
</Link>
|
</Link>
|
||||||
<Link
|
<Link
|
||||||
px={2}
|
px={2}
|
||||||
@@ -124,9 +119,8 @@ export default function NavBar() {
|
|||||||
textDecoration: 'none',
|
textDecoration: 'none',
|
||||||
bg: bgLink,
|
bg: bgLink,
|
||||||
}}
|
}}
|
||||||
as={RouteLink}
|
asChild>
|
||||||
to="/games/create">
|
<RouteLink to="/games/create">Create Game</RouteLink>
|
||||||
Create Game
|
|
||||||
</Link>
|
</Link>
|
||||||
</HStack>
|
</HStack>
|
||||||
</HStack>
|
</HStack>
|
||||||
@@ -135,7 +129,7 @@ export default function NavBar() {
|
|||||||
{isSmallerThan768 ?
|
{isSmallerThan768 ?
|
||||||
<>
|
<>
|
||||||
<Button ref={btnRef} onMouseDown={mobileIsOpen ? mobileOnClose : mobileOnOpen}>
|
<Button ref={btnRef} onMouseDown={mobileIsOpen ? mobileOnClose : mobileOnOpen}>
|
||||||
<HamburgerIcon/>
|
<LuMenu/>
|
||||||
</Button>
|
</Button>
|
||||||
<MobileBar mobileIsOpen={mobileIsOpen} mobileOnClose={mobileOnClose} btnRef={btnRef} bgLink={bgLink}
|
<MobileBar mobileIsOpen={mobileIsOpen} mobileOnClose={mobileOnClose} btnRef={btnRef} bgLink={bgLink}
|
||||||
user={user} colorMode={colorMode} toggleColorMode={toggleColorMode}/>
|
user={user} colorMode={colorMode} toggleColorMode={toggleColorMode}/>
|
||||||
@@ -144,7 +138,7 @@ export default function NavBar() {
|
|||||||
<Stack direction={'row'}>
|
<Stack direction={'row'}>
|
||||||
|
|
||||||
{ user.role === 'admin' && <AdminMode/>}
|
{ user.role === 'admin' && <AdminMode/>}
|
||||||
<Tooltip hasArrow mr={'2'} label={'Filters'} aria-label={'Filters'}>
|
<Tooltip showArrow content={'Filters'}>
|
||||||
<Button
|
<Button
|
||||||
rounded={'full'}
|
rounded={'full'}
|
||||||
bg={'transparent'}
|
bg={'transparent'}
|
||||||
@@ -164,7 +158,7 @@ export default function NavBar() {
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
<FilterBar filterIsOpen={filterIsOpen} filterOnClose={filterOnClose} btnRef={btnRef} filterLoadingState={filterLoadingState} />
|
<FilterBar filterIsOpen={filterIsOpen} filterOnClose={filterOnClose} btnRef={btnRef} filterLoadingState={filterLoadingState} />
|
||||||
|
|
||||||
<Tooltip hasArrow mr={'2'} label={'Search: ctrl+s'} aria-label={'Search'}>
|
<Tooltip showArrow content={'Search: ctrl+s'}>
|
||||||
<Button
|
<Button
|
||||||
rounded={'full'}
|
rounded={'full'}
|
||||||
onMouseDown={() => {
|
onMouseDown={() => {
|
||||||
@@ -173,77 +167,81 @@ export default function NavBar() {
|
|||||||
bg={'transparent'}
|
bg={'transparent'}
|
||||||
cursor={'pointer'}
|
cursor={'pointer'}
|
||||||
minW={0}>
|
minW={0}>
|
||||||
<Search2Icon/>
|
<LuSearch/>
|
||||||
</Button>
|
</Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Menu>
|
<Menu.Root>
|
||||||
<Tooltip hasArrow mr={'2'} label={'Settings'} aria-label={'Settings'}>
|
<Menu.Trigger asChild>
|
||||||
<MenuButton
|
<Button
|
||||||
as={Button}
|
|
||||||
rounded={'full'}
|
rounded={'full'}
|
||||||
variant={'transparent'}
|
variant={'ghost'}
|
||||||
cursor={'pointer'}
|
cursor={'pointer'}
|
||||||
minW={0}>
|
minW={0}>
|
||||||
<SettingsIcon/>
|
<Tooltip showArrow content={'Settings'}>
|
||||||
</MenuButton>
|
<LuSettings/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<MenuList alignItems={'center'}>
|
</Button>
|
||||||
<VStack>
|
</Menu.Trigger>
|
||||||
{/*<Button onMouseDown={toggleColorMode} w={'70%'}>*/}
|
<Portal>
|
||||||
{/* {colorMode === 'light' ? <MoonIcon/> : <SunIcon/>}*/}
|
<Menu.Positioner>
|
||||||
{/* {colorMode === 'light' ?*/}
|
<Menu.Content p={8}>
|
||||||
{/* <Text mt={'1'} ml={'2'}>Dark</Text> :*/}
|
<VStack alignItems={'center'}>
|
||||||
{/* <Text mt={'1'} ml={'2'}>Light</Text>}*/}
|
<Button
|
||||||
{/*</Button>*/}
|
variant={'solid'}
|
||||||
<Button
|
colorPalette={'blue'}
|
||||||
variant={'solid'}
|
size={'md'}
|
||||||
colorScheme={'blue'}
|
asChild
|
||||||
size={'md'}
|
w={'70%'}
|
||||||
leftIcon={<AddIcon/>}
|
>
|
||||||
as={RouteLink}
|
<RouteLink to="/games/create"><LuPlus/> <Text mt="1">Create Game</Text></RouteLink>
|
||||||
w={'70%'}
|
</Button>
|
||||||
to="/games/create">
|
<Separator/>
|
||||||
<Text mt="1">Create Game</Text>
|
<Heading as={'h3'} size={'md'}>Keyboard Shortcuts</Heading>
|
||||||
</Button>
|
<HStack><Text fontSize={'sm'}>Search:</Text><span><Kbd>ctrl</Kbd> + <Kbd>,</Kbd></span></HStack>
|
||||||
<Divider/>
|
<HStack><Text fontSize={'sm'}>Games Grid:</Text><span><Kbd>ctrl</Kbd> + <Kbd>.</Kbd></span></HStack>
|
||||||
<Heading as={'h3'} size={'md'}>Keyboard Shortcuts</Heading>
|
<HStack><Text fontSize={'sm'}>Create
|
||||||
<HStack><Text fontSize={'sm'}>Search:</Text><span><Kbd>ctrl</Kbd> + <Kbd>,</Kbd></span></HStack>
|
Game:</Text><span><Kbd>ctrl</Kbd> + <Kbd>/</Kbd></span></HStack>
|
||||||
<HStack><Text fontSize={'sm'}>Games Grid:</Text><span><Kbd>ctrl</Kbd> + <Kbd>.</Kbd></span></HStack>
|
</VStack>
|
||||||
<HStack><Text fontSize={'sm'}>Create
|
</Menu.Content>
|
||||||
Game:</Text><span><Kbd>ctrl</Kbd> + <Kbd>/</Kbd></span></HStack>
|
</Menu.Positioner>
|
||||||
</VStack>
|
</Portal>
|
||||||
</MenuList>
|
</Menu.Root>
|
||||||
</Menu>
|
<Menu.Root>
|
||||||
<Menu>
|
<Menu.Trigger asChild>
|
||||||
<Tooltip hasArrow mr={'2'} label={'User Info and Logout'} aria-label={'User Info'}>
|
<Button
|
||||||
<MenuButton
|
rounded={'full'}
|
||||||
as={Button}
|
variant={'ghost'}
|
||||||
rounded={'full'}
|
cursor={'pointer'}
|
||||||
variant={'transparent'}
|
minW={0}>
|
||||||
cursor={'pointer'}
|
<Tooltip showArrow content={'User Info and Logout'}>
|
||||||
minW={0}>
|
<Avatar size={'sm'} src={user.avatar} name={user.displayName} />
|
||||||
<Avatar size={'sm'} src={user.avatar}/>
|
</Tooltip>
|
||||||
</MenuButton>
|
</Button>
|
||||||
</Tooltip>
|
</Menu.Trigger>
|
||||||
<MenuList alignItems={'center'}>
|
<Portal>
|
||||||
<br/>
|
<Menu.Positioner>
|
||||||
<Center>
|
<Menu.Content p={8}>
|
||||||
<Avatar
|
<br/>
|
||||||
size={'2xl'}
|
<Center>
|
||||||
src={user.avatar}
|
<Avatar
|
||||||
/>
|
size={'2xl'}
|
||||||
</Center>
|
src={user.avatar}
|
||||||
<br/>
|
name={user.displayName}
|
||||||
<Center>
|
/>
|
||||||
<p>{user.displayName}</p>
|
</Center>
|
||||||
</Center>
|
<br/>
|
||||||
<br/>
|
<Center>
|
||||||
<MenuDivider/>
|
<p>{user.displayName}</p>
|
||||||
<MenuItem onClick={() => history('/profile')}>Preferences</MenuItem>
|
</Center>
|
||||||
<MenuItem onClick={() => logout()}><Icon as={MdOutlinePowerSettingsNew} mr={'2'}/> <Text
|
<br/>
|
||||||
mt={'1'}>Logout</Text></MenuItem>
|
<Menu.Separator/>
|
||||||
</MenuList>
|
<Menu.Item value="preferences" onSelect={() => history('/profile')}>Preferences</Menu.Item>
|
||||||
</Menu>
|
<Menu.Item value="logout" onSelect={() => logout()}><Icon as={MdOutlinePowerSettingsNew} mr={'2'}/> <Text
|
||||||
|
mt={'1'}>Logout</Text></Menu.Item>
|
||||||
|
</Menu.Content>
|
||||||
|
</Menu.Positioner>
|
||||||
|
</Portal>
|
||||||
|
</Menu.Root>
|
||||||
</Stack>
|
</Stack>
|
||||||
}
|
}
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|||||||
@@ -4,13 +4,13 @@ import { VStack, Image, Button, Heading, Flex, Center } from '@chakra-ui/react'
|
|||||||
|
|
||||||
const Home = () => {
|
const Home = () => {
|
||||||
return (
|
return (
|
||||||
<Flex align={'center'} bgGradient={'linear(to-br, #314755, #26a0da)'} height={'100vh'}>
|
<Flex align={'center'} bgImage={'linear-gradient(to bottom right, #314755, #26a0da)'} height={'100vh'}>
|
||||||
<Center w={'100%'}>
|
<Center w={'100%'}>
|
||||||
<VStack spacing={4} align={'center'} margin={'auto'}>
|
<VStack gap={4} align={'center'} margin={'auto'}>
|
||||||
<Image src="/assets/Logo.svg" alt="Games Database Logo"/>
|
<Image src="/assets/Logo.svg" alt="Games Database Logo"/>
|
||||||
<Heading as="h2" fontSize={'1.7em'} fontWeight={'normal'}>Welcome to your Games Database</Heading>
|
<Heading as="h2" fontSize={'1.7em'} fontWeight={'normal'}>Welcome to your Games Database</Heading>
|
||||||
<Button as={Link} to="/login" size='lg' variant='outline' fontSize='1.25rem'>
|
<Button asChild size='lg' variant='outline' fontSize='1.25rem'>
|
||||||
Login
|
<Link to="/login">Login</Link>
|
||||||
</Button>
|
</Button>
|
||||||
</VStack>
|
</VStack>
|
||||||
</Center>
|
</Center>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { Center, CircularProgress } from '@chakra-ui/react'
|
import { Center, ProgressCircle } from '@chakra-ui/react'
|
||||||
|
|
||||||
export default function LoadingModal() {
|
export default function LoadingModal() {
|
||||||
|
|
||||||
@@ -14,7 +14,12 @@ export default function LoadingModal() {
|
|||||||
bottom={'0'}
|
bottom={'0'}
|
||||||
left={'0'}
|
left={'0'}
|
||||||
>
|
>
|
||||||
<CircularProgress isIndeterminate color="blue.500"/>
|
<ProgressCircle.Root value={null} size="lg">
|
||||||
|
<ProgressCircle.Circle>
|
||||||
|
<ProgressCircle.Track />
|
||||||
|
<ProgressCircle.Range stroke="blue.500" />
|
||||||
|
</ProgressCircle.Circle>
|
||||||
|
</ProgressCircle.Root>
|
||||||
</Center>
|
</Center>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,19 +1,18 @@
|
|||||||
import React, { MutableRefObject } from 'react'
|
import React, { MutableRefObject } from 'react'
|
||||||
import {
|
import {
|
||||||
Avatar, Button, Center, ColorMode,
|
Button, Center,
|
||||||
Divider, Drawer,
|
Separator,
|
||||||
DrawerBody,
|
Drawer,
|
||||||
DrawerCloseButton,
|
Icon,
|
||||||
DrawerContent, DrawerFooter,
|
|
||||||
DrawerHeader,
|
|
||||||
DrawerOverlay, Icon,
|
|
||||||
Image, Link,
|
Image, Link,
|
||||||
Stack, Text,
|
Stack, Text,
|
||||||
} from '@chakra-ui/react'
|
} from '@chakra-ui/react'
|
||||||
|
import {DrawerBody, DrawerCloseTrigger, DrawerContent, DrawerFooter, DrawerHeader, DrawerRoot} from './ui/drawer'
|
||||||
|
import {Avatar} from './ui/avatar'
|
||||||
import AdminMode from './authComponents/AdminMode'
|
import AdminMode from './authComponents/AdminMode'
|
||||||
import { NavLink } from 'react-router-dom'
|
import { NavLink } from 'react-router-dom'
|
||||||
import Search from './Search'
|
import Search from './Search'
|
||||||
import { AddIcon } from '@chakra-ui/icons'
|
import { LuPlus } from 'react-icons/lu'
|
||||||
import { logout } from '../stateManagement/userState'
|
import { logout } from '../stateManagement/userState'
|
||||||
import User from '../models/user'
|
import User from '../models/user'
|
||||||
import { AiOutlineLogout } from 'react-icons/ai'
|
import { AiOutlineLogout } from 'react-icons/ai'
|
||||||
@@ -21,12 +20,13 @@ import {useHookstate} from "@hookstate/core";
|
|||||||
import {searchCompletedState} from "../stateManagement/loadingState";
|
import {searchCompletedState} from "../stateManagement/loadingState";
|
||||||
import {gameDashboardState} from "../stateManagement/gameState";
|
import {gameDashboardState} from "../stateManagement/gameState";
|
||||||
import ResetFilterButton from "./helperComponents/ResetFilterButton";
|
import ResetFilterButton from "./helperComponents/ResetFilterButton";
|
||||||
|
import type { ColorMode } from './ui/color-mode'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
mobileIsOpen: boolean
|
mobileIsOpen: boolean
|
||||||
mobileOnClose: () => void
|
mobileOnClose: () => void
|
||||||
btnRef: MutableRefObject<null>
|
btnRef: MutableRefObject<null>
|
||||||
bgLink: "gray.200" | "gray.700"
|
bgLink: string
|
||||||
user: User
|
user: User
|
||||||
colorMode: ColorMode
|
colorMode: ColorMode
|
||||||
toggleColorMode: () => void
|
toggleColorMode: () => void
|
||||||
@@ -37,15 +37,14 @@ function MobileBar({ mobileIsOpen, mobileOnClose, btnRef, bgLink, user }: Props)
|
|||||||
const gamesState = useHookstate(gameDashboardState)
|
const gamesState = useHookstate(gameDashboardState)
|
||||||
const games = gamesState.get()
|
const games = gamesState.get()
|
||||||
return (
|
return (
|
||||||
<Drawer
|
<DrawerRoot
|
||||||
isOpen={mobileIsOpen}
|
open={mobileIsOpen}
|
||||||
placement="right"
|
placement="end"
|
||||||
onClose={mobileOnClose}
|
onOpenChange={(e) => { if (!e.open) mobileOnClose() }}
|
||||||
finalFocusRef={btnRef}
|
finalFocusEl={() => btnRef.current as unknown as HTMLElement}
|
||||||
>
|
>
|
||||||
<DrawerOverlay/>
|
|
||||||
<DrawerContent>
|
<DrawerContent>
|
||||||
<DrawerCloseButton/>
|
<DrawerCloseTrigger/>
|
||||||
<DrawerHeader>
|
<DrawerHeader>
|
||||||
<Image maxW="15rem" src="/assets/Logo.svg" alt="Games Database Logo"/>
|
<Image maxW="15rem" src="/assets/Logo.svg" alt="Games Database Logo"/>
|
||||||
</DrawerHeader>
|
</DrawerHeader>
|
||||||
@@ -54,7 +53,7 @@ function MobileBar({ mobileIsOpen, mobileOnClose, btnRef, bgLink, user }: Props)
|
|||||||
<AdminMode />
|
<AdminMode />
|
||||||
<Stack
|
<Stack
|
||||||
as={'nav'}
|
as={'nav'}
|
||||||
spacing={4}
|
gap={4}
|
||||||
>
|
>
|
||||||
<Link
|
<Link
|
||||||
px={2}
|
px={2}
|
||||||
@@ -64,9 +63,8 @@ function MobileBar({ mobileIsOpen, mobileOnClose, btnRef, bgLink, user }: Props)
|
|||||||
textDecoration: 'none',
|
textDecoration: 'none',
|
||||||
bg: bgLink,
|
bg: bgLink,
|
||||||
}}
|
}}
|
||||||
as={NavLink}
|
asChild>
|
||||||
to="/games">
|
<NavLink to="/games"><Text textAlign={'right'}>Games</Text></NavLink>
|
||||||
<Text align={'right'}>Games</Text>
|
|
||||||
</Link>
|
</Link>
|
||||||
<Link
|
<Link
|
||||||
px={2}
|
px={2}
|
||||||
@@ -76,15 +74,14 @@ function MobileBar({ mobileIsOpen, mobileOnClose, btnRef, bgLink, user }: Props)
|
|||||||
textDecoration: 'none',
|
textDecoration: 'none',
|
||||||
bg: bgLink,
|
bg: bgLink,
|
||||||
}}
|
}}
|
||||||
as={NavLink}
|
asChild>
|
||||||
to="/games/create">
|
<NavLink to="/games/create"><Text textAlign={'right'}>Create Game</Text></NavLink>
|
||||||
<Text align={'right'}>Create Game</Text>
|
|
||||||
</Link>
|
</Link>
|
||||||
<Divider/>
|
<Separator/>
|
||||||
<Search/>
|
<Search/>
|
||||||
{searchCompleted.get() && <Text>Games Found: {games.count.totalGames}</Text>}
|
{searchCompleted.get() && <Text>Games Found: {games.count.totalGames}</Text>}
|
||||||
<Divider/>
|
<Separator/>
|
||||||
<Center><Avatar mr={'2'} size={'sm'} src={user.avatar}/><Text mt={1}>{user.displayName}</Text></Center>
|
<Center><Avatar mr={'2'} size={'sm'} src={user.avatar} name={user.displayName}/><Text mt={1}>{user.displayName}</Text></Center>
|
||||||
<Link
|
<Link
|
||||||
px={2}
|
px={2}
|
||||||
py={1}
|
py={1}
|
||||||
@@ -93,18 +90,10 @@ function MobileBar({ mobileIsOpen, mobileOnClose, btnRef, bgLink, user }: Props)
|
|||||||
textDecoration: 'none',
|
textDecoration: 'none',
|
||||||
bg: bgLink,
|
bg: bgLink,
|
||||||
}}
|
}}
|
||||||
as={NavLink}
|
asChild>
|
||||||
to="/profile">
|
<NavLink to="/profile"><Text textAlign={'right'}>Preferences</Text></NavLink>
|
||||||
<Text align={'right'}>Preferences</Text>
|
|
||||||
</Link>
|
</Link>
|
||||||
<Divider/>
|
<Separator/>
|
||||||
{/*<Button onMouseDown={toggleColorMode} ml={'auto'}>*/}
|
|
||||||
{/* {colorMode === 'light' ? <MoonIcon/> : <SunIcon/>}*/}
|
|
||||||
{/* {colorMode === 'light' ?*/}
|
|
||||||
{/* <Text mt={'1'} ml={'2'}>Dark</Text> :*/}
|
|
||||||
{/* <Text mt={'1'} ml={'2'}>Light</Text>}*/}
|
|
||||||
{/*</Button>*/}
|
|
||||||
{/*<Divider/>*/}
|
|
||||||
<ResetFilterButton />
|
<ResetFilterButton />
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
@@ -114,21 +103,20 @@ function MobileBar({ mobileIsOpen, mobileOnClose, btnRef, bgLink, user }: Props)
|
|||||||
<DrawerFooter>
|
<DrawerFooter>
|
||||||
<Button
|
<Button
|
||||||
variant={'solid'}
|
variant={'solid'}
|
||||||
colorScheme={'blue'}
|
colorPalette={'blue'}
|
||||||
size={'md'}
|
size={'md'}
|
||||||
leftIcon={<AddIcon/>}
|
asChild
|
||||||
as={NavLink}
|
|
||||||
mr={3}
|
mr={3}
|
||||||
to="/games/create">
|
>
|
||||||
<Text mt="1">Create Game</Text>
|
<NavLink to="/games/create"><LuPlus/> <Text mt="1">Create Game</Text></NavLink>
|
||||||
</Button>
|
</Button>
|
||||||
<Button onMouseDown={() => logout()}><Icon as={AiOutlineLogout} mr={'2'}/> <Text
|
<Button onMouseDown={() => logout()}><Icon as={AiOutlineLogout} mr={'2'}/> <Text
|
||||||
mt={'1'}>Logout</Text></Button>
|
mt={'1'}>Logout</Text></Button>
|
||||||
|
|
||||||
</DrawerFooter>
|
</DrawerFooter>
|
||||||
</DrawerContent>
|
</DrawerContent>
|
||||||
</Drawer>
|
</DrawerRoot>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default MobileBar
|
export default MobileBar
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ import { Center, Flex, Heading, Button, VStack } from '@chakra-ui/react'
|
|||||||
|
|
||||||
export default function NoGames() {
|
export default function NoGames() {
|
||||||
return (
|
return (
|
||||||
<Flex align={'center'} bgGradient={'linear(to-br, #314755, #26a0da)'} height={'100vh'}>
|
<Flex align={'center'} bgImage={'linear-gradient(to bottom right, #314755, #26a0da)'} height={'100vh'}>
|
||||||
<Center w={'100%'}>
|
<Center w={'100%'}>
|
||||||
<VStack spacing={4} align={'center'} margin={'auto'}>
|
<VStack gap={4} align={'center'} margin={'auto'}>
|
||||||
{<Heading as="h2">You have not added any games yet.</Heading>}
|
{<Heading as="h2">You have not added any games yet.</Heading>}
|
||||||
<Button as={Link} to='/games/create' size='lg' variant='outline' fontSize='1.25rem'>
|
<Button asChild size='lg' variant='outline' fontSize='1.25rem'>
|
||||||
Click here to add some!
|
<Link to='/games/create'>Click here to add some!</Link>
|
||||||
</Button>
|
</Button>
|
||||||
</VStack>
|
</VStack>
|
||||||
</Center>
|
</Center>
|
||||||
|
|||||||
@@ -4,24 +4,21 @@ import {
|
|||||||
Grid,
|
Grid,
|
||||||
GridItem,
|
GridItem,
|
||||||
IconButton,
|
IconButton,
|
||||||
NumberDecrementStepper,
|
|
||||||
NumberIncrementStepper,
|
|
||||||
NumberInput,
|
|
||||||
NumberInputField,
|
|
||||||
NumberInputStepper,
|
|
||||||
Select,
|
|
||||||
Text,
|
Text,
|
||||||
Tooltip,
|
Portal,
|
||||||
useColorModeValue,
|
|
||||||
useMediaQuery,
|
|
||||||
} from '@chakra-ui/react'
|
} from '@chakra-ui/react'
|
||||||
import { ArrowLeftIcon, ArrowRightIcon, ChevronLeftIcon, ChevronRightIcon } from '@chakra-ui/icons'
|
import {NumberInputRoot, NumberInputField} from './ui/number-input'
|
||||||
|
import { NativeSelect } from '@chakra-ui/react'
|
||||||
|
import { LuChevronLeft, LuChevronRight, LuChevronsLeft, LuChevronsRight } from 'react-icons/lu'
|
||||||
|
import {Tooltip} from './ui/tooltip'
|
||||||
import { useHookstate } from '@hookstate/core'
|
import { useHookstate } from '@hookstate/core'
|
||||||
import { gameDashboardState } from '../stateManagement/gameState'
|
import { gameDashboardState } from '../stateManagement/gameState'
|
||||||
import { loadingState } from '../stateManagement/loadingState'
|
import { loadingState } from '../stateManagement/loadingState'
|
||||||
import { adminMode } from '../stateManagement/userState'
|
import { adminMode } from '../stateManagement/userState'
|
||||||
import getWithFilters from '../componentUtils/getWithFilters'
|
import getWithFilters from '../componentUtils/getWithFilters'
|
||||||
import { ratingState, steamRatingState } from "../stateManagement/ratingState";
|
import { ratingState, steamRatingState } from "../stateManagement/ratingState";
|
||||||
|
import {useColorModeValue} from "./ui/color-mode";
|
||||||
|
import {useMediaQuery} from "@chakra-ui/react";
|
||||||
|
|
||||||
export default function Pagination() {
|
export default function Pagination() {
|
||||||
const gamesState = useHookstate(gameDashboardState)
|
const gamesState = useHookstate(gameDashboardState)
|
||||||
@@ -34,7 +31,7 @@ export default function Pagination() {
|
|||||||
const bg = useColorModeValue('gray.50', 'transparent')
|
const bg = useColorModeValue('gray.50', 'transparent')
|
||||||
const useRatingState = useHookstate(ratingState).get()
|
const useRatingState = useHookstate(ratingState).get()
|
||||||
const useSteamRatingState = useHookstate(steamRatingState).get()
|
const useSteamRatingState = useHookstate(steamRatingState).get()
|
||||||
const [isSmallerThan768] = useMediaQuery('(max-width: 768px)')
|
const [isSmallerThan768] = useMediaQuery(['(max-width: 768px)'])
|
||||||
|
|
||||||
const setPageSize = async (limit: number) => await getWithFilters(
|
const setPageSize = async (limit: number) => await getWithFilters(
|
||||||
gamesState,
|
gamesState,
|
||||||
@@ -99,22 +96,24 @@ export default function Pagination() {
|
|||||||
}}>
|
}}>
|
||||||
<GridItem area={"backArrows"}>
|
<GridItem area={"backArrows"}>
|
||||||
<Flex>
|
<Flex>
|
||||||
<Tooltip label="First Page">
|
<Tooltip content="First Page">
|
||||||
<IconButton
|
<IconButton
|
||||||
aria-label={'First Page'}
|
aria-label={'First Page'}
|
||||||
onMouseDown={() => gotoPage(0)}
|
onMouseDown={() => gotoPage(0)}
|
||||||
isDisabled={pageIndex <= 1}
|
disabled={pageIndex <= 1}
|
||||||
icon={<ArrowLeftIcon h={3} w={3} />}
|
|
||||||
mr={4}
|
mr={4}
|
||||||
/>
|
>
|
||||||
|
<LuChevronsLeft />
|
||||||
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip label="Previous Page">
|
<Tooltip content="Previous Page">
|
||||||
<IconButton
|
<IconButton
|
||||||
aria-label={'Previous Page'}
|
aria-label={'Previous Page'}
|
||||||
onMouseDown={previousPage}
|
onMouseDown={previousPage}
|
||||||
isDisabled={pageIndex <= 1}
|
disabled={pageIndex <= 1}
|
||||||
icon={<ChevronLeftIcon h={6} w={6} />}
|
>
|
||||||
/>
|
<LuChevronLeft />
|
||||||
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</Flex>
|
</Flex>
|
||||||
</GridItem>
|
</GridItem>
|
||||||
@@ -133,70 +132,79 @@ export default function Pagination() {
|
|||||||
{!isSmallerThan768 &&
|
{!isSmallerThan768 &&
|
||||||
<GridItem area={"goToPage"}>
|
<GridItem area={"goToPage"}>
|
||||||
<Text mb={'1'}>Go to Page:</Text>
|
<Text mb={'1'}>Go to Page:</Text>
|
||||||
<NumberInput
|
<NumberInputRoot
|
||||||
bg={bg}
|
bg={bg}
|
||||||
rounded={'md'}
|
rounded={'md'}
|
||||||
w={{ base: 20, md: 28 }}
|
w={{ base: 20, md: 28 }}
|
||||||
min={1}
|
min={1}
|
||||||
max={pageCount}
|
max={pageCount}
|
||||||
value={pageIndex}
|
value={String(pageIndex)}
|
||||||
onChange={(value) => {
|
onValueChange={(e) => {
|
||||||
const page = value ? Number(value) : 1
|
const page = e.value ? Number(e.value) : 1
|
||||||
gotoPage(page)
|
gotoPage(page)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<NumberInputField />
|
<NumberInputField
|
||||||
<NumberInputStepper>
|
borderWidth="1px"
|
||||||
<NumberIncrementStepper />
|
borderStyle="solid"
|
||||||
<NumberDecrementStepper />
|
borderColor={{ base: "gray.500", _invalid: "red.500" }}
|
||||||
</NumberInputStepper>
|
/>
|
||||||
</NumberInput>
|
</NumberInputRoot>
|
||||||
|
|
||||||
</GridItem>
|
</GridItem>
|
||||||
}
|
}
|
||||||
<GridItem area={"countPerPage"}>
|
<GridItem area={"countPerPage"}>
|
||||||
<Text mb={'1'}>Count Per Page:</Text>
|
<Text mb={'1'}>Count Per Page:</Text>
|
||||||
<Select
|
<NativeSelect.Root
|
||||||
ml={{
|
ml={{
|
||||||
base: '4',
|
base: '4',
|
||||||
md: '0'
|
md: '0'
|
||||||
}}
|
}}
|
||||||
bg={bg}
|
|
||||||
rounded={'md'}
|
|
||||||
w={{ base: 20, md: 32 }}
|
w={{ base: 20, md: 32 }}
|
||||||
value={pageSize}
|
|
||||||
onChange={(e) => {
|
|
||||||
setPageSize(Number(e.target.value))
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{[10, 20, 30, 40, 50].map((pageSize) => (
|
<NativeSelect.Field
|
||||||
<option key={pageSize} value={pageSize}>
|
rounded={'md'}
|
||||||
{pageSize}
|
borderWidth={'1px'}
|
||||||
</option>
|
borderStyle={'solid'}
|
||||||
))}
|
borderColor={'gray.500'}
|
||||||
</Select>
|
bg={bg}
|
||||||
|
value={pageSize}
|
||||||
|
onChange={(e: any) => {
|
||||||
|
setPageSize(Number(e.target.value))
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{[10, 20, 30, 40, 50].map((pageSize) => (
|
||||||
|
<option key={pageSize} value={pageSize}>
|
||||||
|
{pageSize}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</NativeSelect.Field>
|
||||||
|
<NativeSelect.Indicator />
|
||||||
|
</NativeSelect.Root>
|
||||||
</GridItem>
|
</GridItem>
|
||||||
<GridItem area={'gamesFound'}>
|
<GridItem area={'gamesFound'}>
|
||||||
<Text>Games Found: {games.count.totalGames}</Text>
|
<Text>Games Found: {games.count.totalGames}</Text>
|
||||||
</GridItem>
|
</GridItem>
|
||||||
<GridItem area={"forwardArrows"}>
|
<GridItem area={"forwardArrows"}>
|
||||||
<Flex justifySelf={'end'}>
|
<Flex justifySelf={'end'}>
|
||||||
<Tooltip label="Next Page">
|
<Tooltip content="Next Page">
|
||||||
<IconButton
|
<IconButton
|
||||||
aria-label={'Next Page'}
|
aria-label={'Next Page'}
|
||||||
onMouseDown={nextPage}
|
onMouseDown={nextPage}
|
||||||
isDisabled={pageIndex >= pageCount}
|
disabled={pageIndex >= pageCount}
|
||||||
icon={<ChevronRightIcon h={6} w={6} />}
|
>
|
||||||
/>
|
<LuChevronRight />
|
||||||
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip label="Last Page">
|
<Tooltip content="Last Page">
|
||||||
<IconButton
|
<IconButton
|
||||||
aria-label={'Last Page'}
|
aria-label={'Last Page'}
|
||||||
onMouseDown={() => gotoPage(pageCount)}
|
onMouseDown={() => gotoPage(pageCount)}
|
||||||
isDisabled={pageIndex >= pageCount}
|
disabled={pageIndex >= pageCount}
|
||||||
icon={<ArrowRightIcon h={3} w={3} />}
|
|
||||||
ml={4}
|
ml={4}
|
||||||
/>
|
>
|
||||||
|
<LuChevronsRight />
|
||||||
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</Flex>
|
</Flex>
|
||||||
</GridItem>
|
</GridItem>
|
||||||
|
|||||||
+18
-18
@@ -1,6 +1,7 @@
|
|||||||
import React, { FormEvent } from 'react'
|
import React, { FormEvent } from 'react'
|
||||||
import { Button, FormControl, Input, InputGroup, InputRightElement, useColorModeValue } from '@chakra-ui/react'
|
import { Button, Input, Group } from '@chakra-ui/react'
|
||||||
import { SearchIcon } from '@chakra-ui/icons'
|
import { Field } from './ui/field'
|
||||||
|
import { LuSearch } from 'react-icons/lu'
|
||||||
import { GameList } from '../models/game'
|
import { GameList } from '../models/game'
|
||||||
import { useHookstate } from '@hookstate/core'
|
import { useHookstate } from '@hookstate/core'
|
||||||
import { gameDashboardState } from '../stateManagement/gameState'
|
import { gameDashboardState } from '../stateManagement/gameState'
|
||||||
@@ -14,6 +15,7 @@ import { adminMode } from '../stateManagement/userState'
|
|||||||
import getWithFilters from '../componentUtils/getWithFilters'
|
import getWithFilters from '../componentUtils/getWithFilters'
|
||||||
import {ChangeActiveFilterHeader} from "../componentUtils/changeActiveFilterHeader";
|
import {ChangeActiveFilterHeader} from "../componentUtils/changeActiveFilterHeader";
|
||||||
import {ratingState, steamRatingState} from "../stateManagement/ratingState";
|
import {ratingState, steamRatingState} from "../stateManagement/ratingState";
|
||||||
|
import {useColorModeValue} from "./ui/color-mode";
|
||||||
|
|
||||||
export default function Search() {
|
export default function Search() {
|
||||||
const gamesState = useHookstate(gameDashboardState)
|
const gamesState = useHookstate(gameDashboardState)
|
||||||
@@ -54,16 +56,16 @@ export default function Search() {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<form onSubmit={handleSubmit}>
|
<form onSubmit={handleSubmit}>
|
||||||
<FormControl mb="3">
|
<Field mb="3">
|
||||||
<InputGroup>
|
<Group attached w="full">
|
||||||
<Input
|
<Input
|
||||||
autoFocus
|
autoFocus
|
||||||
id="searchParams"
|
id="searchParams"
|
||||||
name="searchParams"
|
name="searchParams"
|
||||||
bg={bg}
|
bg={bg}
|
||||||
type="text"
|
type="text"
|
||||||
border="1px"
|
borderWidth="1px" borderStyle="solid"
|
||||||
borderColor="gray.500"
|
borderColor={{ base: "gray.500", _invalid: "red.500" }}
|
||||||
rounded="md"
|
rounded="md"
|
||||||
placeholder="Search..."
|
placeholder="Search..."
|
||||||
value={games.searchParams}
|
value={games.searchParams}
|
||||||
@@ -71,18 +73,16 @@ export default function Search() {
|
|||||||
handleInputChange('searchParams', e.target.value)
|
handleInputChange('searchParams', e.target.value)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<InputRightElement>
|
<Button
|
||||||
<Button
|
loading={submitLoading}
|
||||||
isLoading={submitLoading}
|
type="submit"
|
||||||
type="submit"
|
colorPalette="blue"
|
||||||
colorScheme="blue"
|
>
|
||||||
>
|
<LuSearch/>
|
||||||
<SearchIcon/>
|
</Button>
|
||||||
</Button>
|
</Group>
|
||||||
</InputRightElement>
|
</Field>
|
||||||
</InputGroup>
|
|
||||||
</FormControl>
|
|
||||||
</form>
|
</form>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {
|
import { Dialog } from '@chakra-ui/react'
|
||||||
Modal, ModalBody, ModalCloseButton, ModalContent,
|
import {DialogBody, DialogCloseTrigger, DialogContent, DialogHeader, DialogRoot} from './ui/dialog'
|
||||||
ModalHeader,
|
|
||||||
} from '@chakra-ui/react'
|
|
||||||
import { useHookstate } from '@hookstate/core'
|
import { useHookstate } from '@hookstate/core'
|
||||||
import { openAndCloseSearchDialogue } from '../stateManagement/loadingState'
|
import { openAndCloseSearchDialogue } from '../stateManagement/loadingState'
|
||||||
import Search from './Search'
|
import Search from './Search'
|
||||||
@@ -16,14 +14,14 @@ export default function SearchModal() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal isOpen={isOpen} onClose={handleClose}>
|
<DialogRoot open={isOpen} onOpenChange={(e) => { if (!e.open) handleClose() }}>
|
||||||
<ModalContent>
|
<DialogContent>
|
||||||
<ModalHeader>Search</ModalHeader>
|
<DialogHeader>Search</DialogHeader>
|
||||||
<ModalCloseButton onMouseDown={() => handleClose()}/>
|
<DialogCloseTrigger onClick={() => handleClose()}/>
|
||||||
<ModalBody>
|
<DialogBody>
|
||||||
<Search />
|
<Search />
|
||||||
</ModalBody>
|
</DialogBody>
|
||||||
</ModalContent>
|
</DialogContent>
|
||||||
</Modal>
|
</DialogRoot>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { Center, CircularProgress } from '@chakra-ui/react'
|
import { Center, ProgressCircle } from '@chakra-ui/react'
|
||||||
|
|
||||||
export default function DashboardLoadingModal() {
|
export default function DashboardLoadingModal() {
|
||||||
|
|
||||||
@@ -9,7 +9,12 @@ export default function DashboardLoadingModal() {
|
|||||||
w="100%"
|
w="100%"
|
||||||
mt={'1rem'}
|
mt={'1rem'}
|
||||||
>
|
>
|
||||||
<CircularProgress isIndeterminate color="blue.500"/>
|
<ProgressCircle.Root value={null} size="md">
|
||||||
|
<ProgressCircle.Circle>
|
||||||
|
<ProgressCircle.Track />
|
||||||
|
<ProgressCircle.Range />
|
||||||
|
</ProgressCircle.Circle>
|
||||||
|
</ProgressCircle.Root>
|
||||||
</Center>
|
</Center>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -9,12 +9,12 @@ import { ratingState, steamRatingState } from "../../stateManagement/ratingState
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
text?: string
|
text?: string
|
||||||
size?: string
|
size?: "2xs" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl"
|
||||||
variant?: string
|
variant?: "solid" | "subtle" | "surface" | "outline" | "ghost" | "plain"
|
||||||
colorScheme?: string
|
colorPalette?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const ResetFilterButton = ({ text = "Reset Search and Filters", size = 'md', variant = 'solid', colorScheme = 'gray' }: Props) => {
|
const ResetFilterButton = ({ text = "Reset Search and Filters", size = 'md', variant = 'solid', colorPalette = 'gray' }: Props) => {
|
||||||
const gameState = useHookstate(gameDashboardState)
|
const gameState = useHookstate(gameDashboardState)
|
||||||
const games = gameState.get()
|
const games = gameState.get()
|
||||||
const admin = useHookstate(adminMode).get()
|
const admin = useHookstate(adminMode).get()
|
||||||
@@ -58,7 +58,7 @@ const ResetFilterButton = ({ text = "Reset Search and Filters", size = 'md', var
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Button onMouseDown={resetFilters} size={size} variant={variant} colorScheme={colorScheme}>
|
<Button onMouseDown={resetFilters} size={size} variant={variant} colorPalette={colorPalette}>
|
||||||
{text}
|
{text}
|
||||||
</Button>
|
</Button>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -9,17 +9,19 @@ const SteamAndDeckLogo = (props: ISteamAndDeckLogo) => {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Box
|
<Box
|
||||||
as="svg"
|
asChild
|
||||||
role="img"
|
|
||||||
width={props.size}
|
width={props.size}
|
||||||
height={props.size}
|
height={props.size}
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
viewBox="0 0 1080 1080"
|
|
||||||
fill="#1f2127"
|
|
||||||
_hover={{
|
_hover={{
|
||||||
fill: "brand.accent",
|
fill: "blue.500",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
<svg
|
||||||
|
role="img"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 1080 1080"
|
||||||
|
fill="#1f2127"
|
||||||
|
>
|
||||||
<title>SteamAndDeckLogo</title>
|
<title>SteamAndDeckLogo</title>
|
||||||
<path
|
<path
|
||||||
fill="url(#_Radial1)"
|
fill="url(#_Radial1)"
|
||||||
@@ -97,6 +99,7 @@ const SteamAndDeckLogo = (props: ISteamAndDeckLogo) => {
|
|||||||
<stop offset="1" stopColor="#00A6FF" stopOpacity="0.6"></stop>
|
<stop offset="1" stopColor="#00A6FF" stopOpacity="0.6"></stop>
|
||||||
</linearGradient>
|
</linearGradient>
|
||||||
</defs>
|
</defs>
|
||||||
|
</svg>
|
||||||
</Box>
|
</Box>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user