current stand

This commit is contained in:
Myzel394 2022-11-17 21:51:20 +01:00
parent ff972478be
commit 89dae6ca0e
4 changed files with 203 additions and 27 deletions

View File

@ -130,6 +130,14 @@
"search": { "search": {
"label": "Search", "label": "Search",
"placeholder": "Search for names" "placeholder": "Search for names"
},
"searchFilter": {
"active": "Active",
"inactive": "Inactive"
},
"typeFilter": {
"custom": "Custom made",
"random": "Randomly generated"
} }
}, },
"actions": { "actions": {

View File

@ -1,14 +1,18 @@
import {AliasList, GetPageData, PaginationResult} from "~/server-types" import {AliasList, AliasType, GetPageData, PaginationResult} from "~/server-types"
import {client} from "~/constants/axios-client" import {client} from "~/constants/axios-client"
export interface GetAliasesData extends GetPageData { export interface GetAliasesData extends GetPageData {
query?: string query?: string
active?: boolean
type?: AliasType
} }
export default async function getAliases({ export default async function getAliases({
query, query,
size, size,
page, page,
active,
type,
}: GetAliasesData): Promise<PaginationResult<AliasList>> { }: GetAliasesData): Promise<PaginationResult<AliasList>> {
const {data} = await client.get(`${import.meta.env.VITE_SERVER_BASE_URL}/v1/alias`, { const {data} = await client.get(`${import.meta.env.VITE_SERVER_BASE_URL}/v1/alias`, {
withCredentials: true, withCredentials: true,
@ -16,6 +20,8 @@ export default async function getAliases({
query, query,
size, size,
page, page,
active,
aliasType: type,
}, },
}) })

View File

@ -11,7 +11,7 @@ export interface AliasTypeIndicatorProps {
type: AliasType type: AliasType
} }
const ALIAS_TYPE_ICON_MAP: Record<AliasType, ReactElement> = { export const ALIAS_TYPE_ICON_MAP: Record<AliasType, ReactElement> = {
[AliasType.RANDOM]: <FaRandom />, [AliasType.RANDOM]: <FaRandom />,
[AliasType.CUSTOM]: <FaHashtag />, [AliasType.CUSTOM]: <FaHashtag />,
} }

View File

@ -5,16 +5,45 @@ import {useTranslation} from "react-i18next"
import {useCopyToClipboard, useKeyPress, useUpdateEffect} from "react-use" import {useCopyToClipboard, useKeyPress, useUpdateEffect} from "react-use"
import {useQuery} from "@tanstack/react-query" import {useQuery} from "@tanstack/react-query"
import {Alert, Grid, InputAdornment, List, Snackbar, TextField} from "@mui/material" import {
Alert,
Chip,
Divider,
Grid,
InputAdornment,
List,
Snackbar,
TextField,
ToggleButton,
} from "@mui/material"
import {AliasList, PaginationResult} from "~/server-types" import {AliasList, AliasType, PaginationResult} from "~/server-types"
import {ErrorSnack, NoSearchResults, QueryResult, SimplePage, SuccessSnack} from "~/components" import {
ALIAS_TYPE_ICON_MAP,
ErrorSnack,
NoSearchResults,
QueryResult,
SimplePage,
SuccessSnack,
} from "~/components"
import {useIsAnyInputFocused} from "~/hooks" import {useIsAnyInputFocused} from "~/hooks"
import {CreateAliasButton} from "~/route-widgets/AliasesRoute/CreateAliasButton" import {CreateAliasButton} from "~/route-widgets/AliasesRoute/CreateAliasButton"
import AliasesListItem from "~/route-widgets/AliasesRoute/AliasesListItem" import AliasesListItem from "~/route-widgets/AliasesRoute/AliasesListItem"
import EmptyStateScreen from "~/route-widgets/AliasesRoute/EmptyStateScreen" import EmptyStateScreen from "~/route-widgets/AliasesRoute/EmptyStateScreen"
import getAliases from "~/apis/get-aliases" import getAliases from "~/apis/get-aliases"
enum SearchFilter {
All = "all",
Active = "active",
Inactive = "inactive",
}
enum TypeFilter {
All = "all",
Custom = "custom",
Random = "random",
}
export default function AliasesRoute(): ReactElement { export default function AliasesRoute(): ReactElement {
const {t} = useTranslation() const {t} = useTranslation()
@ -22,6 +51,8 @@ export default function AliasesRoute(): ReactElement {
const [queryValue, setQueryValue] = useState<string>("") const [queryValue, setQueryValue] = useState<string>("")
const [, startTransition] = useTransition() const [, startTransition] = useTransition()
const [showSearch, setShowSearch] = useState<boolean>(false) const [showSearch, setShowSearch] = useState<boolean>(false)
const [searchFilter, setSearchFilter] = useState<SearchFilter>(SearchFilter.All)
const [typeFilter, setTypeFilter] = useState<TypeFilter>(TypeFilter.All)
const [{value, error}, copyToClipboard] = useCopyToClipboard() const [{value, error}, copyToClipboard] = useCopyToClipboard()
const [isPressingControl] = useKeyPress("Shift") const [isPressingControl] = useKeyPress("Shift")
@ -30,15 +61,37 @@ export default function AliasesRoute(): ReactElement {
const isInCopyAddressMode = !isAnyInputFocused && !lockDisabledCopyMode && isPressingControl const isInCopyAddressMode = !isAnyInputFocused && !lockDisabledCopyMode && isPressingControl
const query = useQuery<PaginationResult<AliasList>, AxiosError>( const query = useQuery<PaginationResult<AliasList>, AxiosError>(
["get_aliases", queryValue], ["get_aliases", queryValue, searchFilter, typeFilter],
() => () =>
getAliases({ getAliases({
query: queryValue, query: queryValue,
active: (() => {
switch (searchFilter) {
case SearchFilter.All:
return undefined
case SearchFilter.Active:
return true
case SearchFilter.Inactive:
return false
}
})(),
type: (() => {
switch (typeFilter) {
case TypeFilter.All:
return undefined
case TypeFilter.Custom:
return AliasType.CUSTOM
case TypeFilter.Random:
return AliasType.RANDOM
}
})(),
}), }),
{ {
onSuccess: ({items}) => { onSuccess: ({items}) => {
if (items.length) { if (items.length) {
setShowSearch(true) setShowSearch(true)
setSearchFilter(SearchFilter.All)
setTypeFilter(TypeFilter.All)
} }
}, },
}, },
@ -55,26 +108,131 @@ export default function AliasesRoute(): ReactElement {
title={t("routes.AliasesRoute.title")} title={t("routes.AliasesRoute.title")}
pageOptionsActions={ pageOptionsActions={
showSearch && ( showSearch && (
<TextField <Grid container spacing={2} direction="column">
key="search" <Grid item>
value={searchValue} <TextField
onChange={event => { key="search"
setSearchValue(event.target.value) fullWidth
startTransition(() => { value={searchValue}
setQueryValue(event.target.value) onChange={event => {
}) setSearchValue(event.target.value)
}} startTransition(() => {
label={t("routes.AliasesRoute.pageActions.search.label")} setQueryValue(event.target.value)
placeholder={t("routes.AliasesRoute.pageActions.search.placeholder")} })
id="search" }}
InputProps={{ label={t("routes.AliasesRoute.pageActions.search.label")}
startAdornment: ( placeholder={t(
<InputAdornment position="start"> "routes.AliasesRoute.pageActions.search.placeholder",
<MdSearch /> )}
</InputAdornment> id="search"
), InputProps={{
}} startAdornment: (
/> <InputAdornment position="start">
<MdSearch />
</InputAdornment>
),
}}
/>
</Grid>
<Grid item>
<Grid container justifyContent="space-between">
<Grid item>
<Grid container spacing={1}>
<Grid item>
<Chip
label={t(
"routes.AliasesRoute.pageActions.searchFilter.active",
)}
variant={
searchFilter === SearchFilter.Active
? "filled"
: "outlined"
}
onClick={() =>
setSearchFilter(value => {
if (value === SearchFilter.Active) {
return SearchFilter.All
}
return SearchFilter.Active
})
}
/>
</Grid>
<Grid item>
<Chip
label={t(
"routes.AliasesRoute.pageActions.searchFilter.inactive",
)}
variant={
searchFilter === SearchFilter.Inactive
? "filled"
: "outlined"
}
onClick={() =>
setSearchFilter(value => {
if (value === SearchFilter.Inactive) {
return SearchFilter.All
}
return SearchFilter.Inactive
})
}
/>
</Grid>
</Grid>
</Grid>
<Grid item>
<Grid container spacing={1}>
<Grid item>
<Chip
icon={ALIAS_TYPE_ICON_MAP[AliasType.CUSTOM]}
label={t(
"routes.AliasesRoute.pageActions.typeFilter.custom",
)}
variant={
typeFilter === TypeFilter.Custom
? "filled"
: "outlined"
}
onClick={() =>
setTypeFilter(value => {
if (value === TypeFilter.Custom) {
return TypeFilter.All
}
return TypeFilter.Custom
})
}
/>
</Grid>
<Grid item>
<Chip
icon={ALIAS_TYPE_ICON_MAP[AliasType.RANDOM]}
label={t(
"routes.AliasesRoute.pageActions.typeFilter.random",
)}
variant={
typeFilter === TypeFilter.Random
? "filled"
: "outlined"
}
onClick={() =>
setTypeFilter(value => {
if (value === TypeFilter.Random) {
return TypeFilter.All
}
return TypeFilter.Random
})
}
/>
</Grid>
</Grid>
</Grid>
</Grid>
</Grid>
</Grid>
) )
} }
> >
@ -85,7 +243,11 @@ export default function AliasesRoute(): ReactElement {
<Grid item> <Grid item>
{(() => { {(() => {
if (aliases.length === 0) { if (aliases.length === 0) {
if (searchValue === "") { if (
searchValue === "" &&
searchFilter === SearchFilter.All &&
typeFilter === TypeFilter.All
) {
return <EmptyStateScreen /> return <EmptyStateScreen />
} else { } else {
return <NoSearchResults /> return <NoSearchResults />