Add skeleton of FilterModal
This commit is contained in:
parent
43287a692c
commit
ef1f8e83d8
8 changed files with 228 additions and 74 deletions
|
|
@ -171,6 +171,11 @@
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.Spaced {
|
||||||
|
justify-content: space-between;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,19 @@
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.Button.Filter.Blended {
|
||||||
|
&:hover {
|
||||||
|
background: var(--button-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.Accessory svg {
|
||||||
|
fill: none;
|
||||||
|
stroke: var(--button-text);
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.shadow {
|
&.shadow {
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,15 @@ import React, { useState } from 'react'
|
||||||
import { useTranslation } from 'next-i18next'
|
import { useTranslation } from 'next-i18next'
|
||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
|
|
||||||
|
import FilterModal from '~components/FilterModal'
|
||||||
import RaidDropdown from '~components/RaidDropdown'
|
import RaidDropdown from '~components/RaidDropdown'
|
||||||
|
|
||||||
import './index.scss'
|
|
||||||
import Select from '~components/Select'
|
import Select from '~components/Select'
|
||||||
import SelectItem from '~components/SelectItem'
|
import SelectItem from '~components/SelectItem'
|
||||||
|
import Button from '~components/Button'
|
||||||
|
|
||||||
|
import FilterIcon from '~public/icons/Filter.svg'
|
||||||
|
|
||||||
|
import './index.scss'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
children: React.ReactNode
|
children: React.ReactNode
|
||||||
|
|
@ -32,6 +36,8 @@ const FilterBar = (props: Props) => {
|
||||||
const [recencyOpen, setRecencyOpen] = useState(false)
|
const [recencyOpen, setRecencyOpen] = useState(false)
|
||||||
const [elementOpen, setElementOpen] = useState(false)
|
const [elementOpen, setElementOpen] = useState(false)
|
||||||
|
|
||||||
|
const [filterModalOpen, setFilterModalOpen] = useState(false)
|
||||||
|
|
||||||
// Set up classes object for showing shadow on scroll
|
// Set up classes object for showing shadow on scroll
|
||||||
const classes = classNames({
|
const classes = classNames({
|
||||||
FilterBar: true,
|
FilterBar: true,
|
||||||
|
|
@ -66,6 +72,7 @@ const FilterBar = (props: Props) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
<div className={classes}>
|
<div className={classes}>
|
||||||
{props.children}
|
{props.children}
|
||||||
<div className="Filters">
|
<div className="Filters">
|
||||||
|
|
@ -139,8 +146,17 @@ const FilterBar = (props: Props) => {
|
||||||
{t('recency.last_year')}
|
{t('recency.last_year')}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
</Select>
|
</Select>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
className="Filter"
|
||||||
|
blended={true}
|
||||||
|
leftAccessoryIcon={<FilterIcon />}
|
||||||
|
onClick={() => setFilterModalOpen(true)}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<FilterModal open={filterModalOpen} onOpenChange={setFilterModalOpen} />
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
0
components/FilterModal/index.scss
Normal file
0
components/FilterModal/index.scss
Normal file
103
components/FilterModal/index.tsx
Normal file
103
components/FilterModal/index.tsx
Normal file
|
|
@ -0,0 +1,103 @@
|
||||||
|
import React, { useEffect, useState } from 'react'
|
||||||
|
import { getCookie, setCookie } from 'cookies-next'
|
||||||
|
import { useRouter } from 'next/router'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogTrigger,
|
||||||
|
DialogClose,
|
||||||
|
DialogTitle,
|
||||||
|
} from '~components/Dialog'
|
||||||
|
import DialogContent from '~components/DialogContent'
|
||||||
|
import Button from '~components/Button'
|
||||||
|
|
||||||
|
import type { DialogProps } from '@radix-ui/react-dialog'
|
||||||
|
|
||||||
|
import CrossIcon from '~public/icons/Cross.svg'
|
||||||
|
import './index.scss'
|
||||||
|
|
||||||
|
interface Props extends DialogProps {}
|
||||||
|
|
||||||
|
const FilterModal = (props: Props) => {
|
||||||
|
// Set up router
|
||||||
|
const router = useRouter()
|
||||||
|
const locale = router.locale
|
||||||
|
|
||||||
|
// Set up translation
|
||||||
|
const { t } = useTranslation('common')
|
||||||
|
|
||||||
|
// Refs
|
||||||
|
const headerRef = React.createRef<HTMLDivElement>()
|
||||||
|
const footerRef = React.createRef<HTMLDivElement>()
|
||||||
|
|
||||||
|
// States
|
||||||
|
const [filters, setFilters] = useState<{ [key: string]: any }>()
|
||||||
|
const [open, setOpen] = useState(false)
|
||||||
|
|
||||||
|
// Hooks
|
||||||
|
useEffect(() => {
|
||||||
|
if (props.open !== undefined) setOpen(props.open)
|
||||||
|
})
|
||||||
|
|
||||||
|
function sendFilters() {
|
||||||
|
openChange()
|
||||||
|
}
|
||||||
|
|
||||||
|
function openChange() {
|
||||||
|
if (open) {
|
||||||
|
setOpen(false)
|
||||||
|
if (props.onOpenChange) props.onOpenChange(false)
|
||||||
|
} else {
|
||||||
|
setOpen(true)
|
||||||
|
if (props.onOpenChange) props.onOpenChange(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onEscapeKeyDown(event: KeyboardEvent) {
|
||||||
|
event.preventDefault()
|
||||||
|
openChange()
|
||||||
|
}
|
||||||
|
|
||||||
|
function onOpenAutoFocus(event: Event) {
|
||||||
|
event.preventDefault()
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog open={open} onOpenChange={openChange}>
|
||||||
|
<DialogTrigger asChild>{props.children}</DialogTrigger>
|
||||||
|
<DialogContent
|
||||||
|
className="Search"
|
||||||
|
onEscapeKeyDown={onEscapeKeyDown}
|
||||||
|
onOpenAutoFocus={onOpenAutoFocus}
|
||||||
|
>
|
||||||
|
<div className="DialogHeader" ref={headerRef}>
|
||||||
|
<div className="DialogTop">
|
||||||
|
<DialogTitle className="DialogTitle">
|
||||||
|
{t('modals.filters.title')}
|
||||||
|
</DialogTitle>
|
||||||
|
</div>
|
||||||
|
<DialogClose className="DialogClose" asChild>
|
||||||
|
<span>
|
||||||
|
<CrossIcon />
|
||||||
|
</span>
|
||||||
|
</DialogClose>
|
||||||
|
</div>
|
||||||
|
<form>
|
||||||
|
<div className="Fields"></div>
|
||||||
|
<div className="DialogFooter" ref={footerRef}>
|
||||||
|
<div className="Buttons Spaced">
|
||||||
|
<Button blended={true} text={t('modals.filters.buttons.clear')} />
|
||||||
|
<Button
|
||||||
|
contained={true}
|
||||||
|
text={t('modals.filters.buttons.confirm')}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FilterModal
|
||||||
3
public/icons/Filter.svg
Normal file
3
public/icons/Filter.svg
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
<svg viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M2 1.5H12C12.2761 1.5 12.5 1.72386 12.5 2V3.46482C12.5 3.63199 12.4164 3.78811 12.2774 3.88084L12.5547 4.29687L12.2773 3.88084L8.66795 6.28711C8.25065 6.56531 8 7.03365 8 7.53518V10.4648C8 10.632 7.91645 10.7881 7.77735 10.8808L6 12.0657V7.53518C6 7.03365 5.74935 6.56531 5.33205 6.28711L1.72265 3.88084C1.58355 3.78811 1.5 3.63199 1.5 3.46482V2C1.5 1.72386 1.72386 1.5 2 1.5Z" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 458 B |
|
|
@ -206,6 +206,13 @@
|
||||||
"cancel": "Nevermind"
|
"cancel": "Nevermind"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"filters": {
|
||||||
|
"title": "Advanced filters",
|
||||||
|
"buttons": {
|
||||||
|
"confirm": "Save filters",
|
||||||
|
"clear": "Clear filters"
|
||||||
|
}
|
||||||
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"title": "Log in",
|
"title": "Log in",
|
||||||
"buttons": {
|
"buttons": {
|
||||||
|
|
|
||||||
|
|
@ -206,6 +206,13 @@
|
||||||
"cancel": "キャンセル"
|
"cancel": "キャンセル"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"filters": {
|
||||||
|
"title": "フィルター設定",
|
||||||
|
"buttons": {
|
||||||
|
"confirm": "フィルターを保存する",
|
||||||
|
"clear": "保存したフィルターをクリア"
|
||||||
|
}
|
||||||
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"title": "ログイン",
|
"title": "ログイン",
|
||||||
"buttons": {
|
"buttons": {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue