forked from dmm-com/pagoda
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathListCategoryPage.tsx
125 lines (116 loc) · 3.98 KB
/
ListCategoryPage.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import AddIcon from "@mui/icons-material/Add";
import {
Box,
Button,
Container,
Grid,
List,
ListItem,
ListItemButton,
ListItemText,
Typography,
} from "@mui/material";
import React, { FC, useState } from "react";
import { Link, useNavigate } from "react-router";
import { CategoryListHeader } from "components/category/CategoryListHeader";
import { AironeBreadcrumbs } from "components/common/AironeBreadcrumbs";
import { PageHeader } from "components/common/PageHeader";
import { PaginationFooter } from "components/common/PaginationFooter";
import { SearchBox } from "components/common/SearchBox";
import { useAsyncWithThrow } from "hooks";
import { usePage } from "hooks/usePage";
import { aironeApiClient } from "repository";
import { entityEntriesPath, newCategoryPath, topPath } from "routes/Routes";
import { EntityListParam } from "services/Constants";
import { normalizeToMatch } from "services/StringUtil";
export const ListCategoryPage: FC = () => {
const navigate = useNavigate();
const [toggle, setToggle] = useState(false);
// variable to store search query
const params = new URLSearchParams(location.search);
const [query, setQuery] = useState<string>(params.get("query") ?? "");
const [page, changePage] = usePage();
// request handler when user specify query
const handleChangeQuery = (newQuery?: string) => {
changePage(1);
setQuery(newQuery ?? "");
navigate({
pathname: location.pathname,
search: newQuery ? `?query=${newQuery}` : "",
});
};
const categories = useAsyncWithThrow(async () => {
return await aironeApiClient.getCategories(page, query);
}, [page, query, toggle]);
return (
<Box>
<AironeBreadcrumbs>
<Typography component={Link} to={topPath()}>
Top
</Typography>
<Typography color="textPrimary">カテゴリ一覧</Typography>
</AironeBreadcrumbs>
<PageHeader title={"カテゴリ一覧"}></PageHeader>
<Container>
{/* Show control menus to filter and create category */}
<Box display="flex" justifyContent="space-between" mb="16px">
<Box width="600px">
<SearchBox
placeholder="カテゴリを絞り込む"
defaultValue={query}
onKeyPress={(e) => {
e.key === "Enter" &&
handleChangeQuery(
normalizeToMatch((e.target as HTMLInputElement).value ?? "")
);
}}
/>
</Box>
<Button
variant="contained"
color="secondary"
component={Link}
to={newCategoryPath()}
sx={{ height: "48px", borderRadius: "24px" }}
>
<AddIcon /> 新規カテゴリを作成
</Button>
</Box>
{/* Context of Category */}
<Grid container spacing={3}>
{categories.value?.results.map((category) => (
<Grid item md={4} key={category.id}>
<List
subheader={
<CategoryListHeader
category={category}
setToggle={() => setToggle(!toggle)}
/>
}
>
<Box sx={{ overflowY: "scroll", maxHeight: 300 }}>
{category.models.map((models) => (
<ListItem disablePadding key={models.id}>
<ListItemButton
component={Link}
to={entityEntriesPath(models.id)}
>
<ListItemText primary={models.name} />
</ListItemButton>
</ListItem>
))}
</Box>
</List>
</Grid>
))}
</Grid>
<PaginationFooter
count={categories.value?.count ?? 0}
maxRowCount={EntityListParam.MAX_ROW_COUNT}
page={page}
changePage={changePage}
/>
</Container>
</Box>
);
};