Skip to content

Commit dcb207a

Browse files
committed
refac: move data handling out of table
1 parent e9110c6 commit dcb207a

File tree

2 files changed

+60
-48
lines changed

2 files changed

+60
-48
lines changed

web/app/search/page.tsx

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
"use client";
22

33
import type React from "react";
4-
import { useState } from "react";
4+
import { useMemo, useState } from "react";
5+
import { useAll, useMatched, useMyID, usePendingFromMe } from "~/api/user";
6+
import FullScreenCircularProgress from "~/components/common/FullScreenCircularProgress";
57
import Search from "~/components/search/search";
68
import Table from "~/components/search/table";
79

@@ -15,12 +17,58 @@ export default function SearchPage({
1517
}) {
1618
const [query, setQuery] = useState<string>(searchParams?.query ?? "");
1719

20+
const {
21+
state: { data },
22+
} = useAll();
23+
const {
24+
state: { data: myId },
25+
} = useMyID();
26+
const initialData = useMemo(() => {
27+
return data?.filter((item) => item.id !== myId && item.id !== 0) ?? null;
28+
}, [data, myId]);
29+
const users = query
30+
? initialData?.filter((user) =>
31+
user.name.toLowerCase().includes(query.toLowerCase()),
32+
)
33+
: initialData;
34+
35+
const {
36+
state: { data: matches },
37+
} = useMatched();
38+
39+
const {
40+
state: { data: pending },
41+
} = usePendingFromMe();
42+
43+
// リクエストを送ってない人のみリクエスト送信可能
44+
// FIXME: O(n^2) | n = count(users) なのでめっちゃ計算コストかかる。なんとかして。
45+
const canRequest = (userId: number) =>
46+
!matches?.some((match) => match.id === userId) &&
47+
!pending?.some((pending) => pending.id === userId);
48+
49+
const [searchQuery__interest, setSearchQuery__interest] = useState<
50+
string | null
51+
>(null);
52+
setSearchQuery__interest; // TODO: use this in some UI
53+
54+
const filteredUsers = users
55+
// this is O(count(users) * count(avg(count(interests))) * count(avg(len(interests.name)))). very bad.
56+
?.filter(
57+
(u) =>
58+
searchQuery__interest === null ||
59+
u.interestSubjects.some((i) => i.name.includes(searchQuery__interest)),
60+
);
61+
1862
return (
1963
<div className="flex min-h-screen justify-center ">
2064
<div className="w-full">
2165
<h2 className="m-5 mb-4 font-bold text-2xl">ユーザー検索</h2>
2266
<Search placeholder="検索" setSearchString={setQuery} />
23-
<Table query={query} />
67+
{filteredUsers ? (
68+
<Table users={filteredUsers} canRequest={canRequest} />
69+
) : (
70+
<FullScreenCircularProgress />
71+
)}
2472
</div>
2573
</div>
2674
);

web/components/search/table.tsx

Lines changed: 10 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,21 @@
11
"use client";
2-
import { useMemo, useState } from "react";
2+
import type { UserID, UserWithCoursesAndSubjects } from "common/types";
33
import request from "~/api/request";
4-
import { useAll, useMatched, useMyID, usePendingFromMe } from "~/api/user";
5-
import { useModal } from "../common/modal/ModalProvider";
4+
import { useModal } from "~/components/common/modal/ModalProvider";
65
import { HumanListItem } from "../human/humanListItem";
76

8-
export default function UserTable({ query }: { query: string }) {
7+
export default function UserTable({
8+
users,
9+
canRequest,
10+
}: {
11+
users: UserWithCoursesAndSubjects[];
12+
canRequest: (id: UserID) => boolean;
13+
}) {
914
const { openModal } = useModal();
10-
const {
11-
state: { data },
12-
} = useAll();
13-
const {
14-
state: { data: myId },
15-
} = useMyID();
16-
const initialData = useMemo(() => {
17-
return data?.filter((item) => item.id !== myId && item.id !== 0) ?? null;
18-
}, [data, myId]);
19-
const users = query
20-
? initialData?.filter((user) =>
21-
user.name.toLowerCase().includes(query.toLowerCase()),
22-
)
23-
: initialData;
24-
25-
const {
26-
state: { data: matches },
27-
} = useMatched();
28-
29-
const {
30-
state: { data: pending },
31-
} = usePendingFromMe();
32-
33-
// リクエストを送ってない人のみリクエスト送信可能
34-
// FIXME: O(n^2) | n = count(users) なのでめっちゃ計算コストかかる。なんとかして。
35-
const canRequest = (userId: number) =>
36-
!matches?.some((match) => match.id === userId) &&
37-
!pending?.some((pending) => pending.id === userId);
38-
39-
const [searchQuery__interest, setSearchQuery__interest] = useState<
40-
string | null
41-
>(null);
42-
setSearchQuery__interest; // TODO: use this in some UI
43-
44-
const filteredUsers = users
45-
// this is O(count(users) * count(avg(count(interests))) * count(avg(len(interests.name)))). very bad.
46-
?.filter(
47-
(u) =>
48-
searchQuery__interest === null ||
49-
u.interestSubjects.some((i) => i.name.includes(searchQuery__interest)),
50-
);
5115

5216
return (
5317
<div>
54-
{filteredUsers?.map((user) => (
18+
{users?.map((user) => (
5519
<HumanListItem
5620
key={user.id}
5721
id={user.id}

0 commit comments

Comments
 (0)