mirror of
https://github.com/Myzel394/kleckrelay-website.git
synced 2025-06-20 00:05:26 +02:00
current stand
This commit is contained in:
parent
ff972478be
commit
89dae6ca0e
@ -130,6 +130,14 @@
|
||||
"search": {
|
||||
"label": "Search",
|
||||
"placeholder": "Search for names"
|
||||
},
|
||||
"searchFilter": {
|
||||
"active": "Active",
|
||||
"inactive": "Inactive"
|
||||
},
|
||||
"typeFilter": {
|
||||
"custom": "Custom made",
|
||||
"random": "Randomly generated"
|
||||
}
|
||||
},
|
||||
"actions": {
|
||||
|
@ -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"
|
||||
|
||||
export interface GetAliasesData extends GetPageData {
|
||||
query?: string
|
||||
active?: boolean
|
||||
type?: AliasType
|
||||
}
|
||||
|
||||
export default async function getAliases({
|
||||
query,
|
||||
size,
|
||||
page,
|
||||
active,
|
||||
type,
|
||||
}: GetAliasesData): Promise<PaginationResult<AliasList>> {
|
||||
const {data} = await client.get(`${import.meta.env.VITE_SERVER_BASE_URL}/v1/alias`, {
|
||||
withCredentials: true,
|
||||
@ -16,6 +20,8 @@ export default async function getAliases({
|
||||
query,
|
||||
size,
|
||||
page,
|
||||
active,
|
||||
aliasType: type,
|
||||
},
|
||||
})
|
||||
|
||||
|
@ -11,7 +11,7 @@ export interface AliasTypeIndicatorProps {
|
||||
type: AliasType
|
||||
}
|
||||
|
||||
const ALIAS_TYPE_ICON_MAP: Record<AliasType, ReactElement> = {
|
||||
export const ALIAS_TYPE_ICON_MAP: Record<AliasType, ReactElement> = {
|
||||
[AliasType.RANDOM]: <FaRandom />,
|
||||
[AliasType.CUSTOM]: <FaHashtag />,
|
||||
}
|
||||
|
@ -5,16 +5,45 @@ import {useTranslation} from "react-i18next"
|
||||
import {useCopyToClipboard, useKeyPress, useUpdateEffect} from "react-use"
|
||||
|
||||
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 {ErrorSnack, NoSearchResults, QueryResult, SimplePage, SuccessSnack} from "~/components"
|
||||
import {AliasList, AliasType, PaginationResult} from "~/server-types"
|
||||
import {
|
||||
ALIAS_TYPE_ICON_MAP,
|
||||
ErrorSnack,
|
||||
NoSearchResults,
|
||||
QueryResult,
|
||||
SimplePage,
|
||||
SuccessSnack,
|
||||
} from "~/components"
|
||||
import {useIsAnyInputFocused} from "~/hooks"
|
||||
import {CreateAliasButton} from "~/route-widgets/AliasesRoute/CreateAliasButton"
|
||||
import AliasesListItem from "~/route-widgets/AliasesRoute/AliasesListItem"
|
||||
import EmptyStateScreen from "~/route-widgets/AliasesRoute/EmptyStateScreen"
|
||||
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 {
|
||||
const {t} = useTranslation()
|
||||
|
||||
@ -22,6 +51,8 @@ export default function AliasesRoute(): ReactElement {
|
||||
const [queryValue, setQueryValue] = useState<string>("")
|
||||
const [, startTransition] = useTransition()
|
||||
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 [isPressingControl] = useKeyPress("Shift")
|
||||
@ -30,15 +61,37 @@ export default function AliasesRoute(): ReactElement {
|
||||
const isInCopyAddressMode = !isAnyInputFocused && !lockDisabledCopyMode && isPressingControl
|
||||
|
||||
const query = useQuery<PaginationResult<AliasList>, AxiosError>(
|
||||
["get_aliases", queryValue],
|
||||
["get_aliases", queryValue, searchFilter, typeFilter],
|
||||
() =>
|
||||
getAliases({
|
||||
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}) => {
|
||||
if (items.length) {
|
||||
setShowSearch(true)
|
||||
setSearchFilter(SearchFilter.All)
|
||||
setTypeFilter(TypeFilter.All)
|
||||
}
|
||||
},
|
||||
},
|
||||
@ -55,26 +108,131 @@ export default function AliasesRoute(): ReactElement {
|
||||
title={t("routes.AliasesRoute.title")}
|
||||
pageOptionsActions={
|
||||
showSearch && (
|
||||
<TextField
|
||||
key="search"
|
||||
value={searchValue}
|
||||
onChange={event => {
|
||||
setSearchValue(event.target.value)
|
||||
startTransition(() => {
|
||||
setQueryValue(event.target.value)
|
||||
})
|
||||
}}
|
||||
label={t("routes.AliasesRoute.pageActions.search.label")}
|
||||
placeholder={t("routes.AliasesRoute.pageActions.search.placeholder")}
|
||||
id="search"
|
||||
InputProps={{
|
||||
startAdornment: (
|
||||
<InputAdornment position="start">
|
||||
<MdSearch />
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<Grid container spacing={2} direction="column">
|
||||
<Grid item>
|
||||
<TextField
|
||||
key="search"
|
||||
fullWidth
|
||||
value={searchValue}
|
||||
onChange={event => {
|
||||
setSearchValue(event.target.value)
|
||||
startTransition(() => {
|
||||
setQueryValue(event.target.value)
|
||||
})
|
||||
}}
|
||||
label={t("routes.AliasesRoute.pageActions.search.label")}
|
||||
placeholder={t(
|
||||
"routes.AliasesRoute.pageActions.search.placeholder",
|
||||
)}
|
||||
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>
|
||||
{(() => {
|
||||
if (aliases.length === 0) {
|
||||
if (searchValue === "") {
|
||||
if (
|
||||
searchValue === "" &&
|
||||
searchFilter === SearchFilter.All &&
|
||||
typeFilter === TypeFilter.All
|
||||
) {
|
||||
return <EmptyStateScreen />
|
||||
} else {
|
||||
return <NoSearchResults />
|
||||
|
Loading…
x
Reference in New Issue
Block a user