Skip to content

Commit c1b7d9d

Browse files
Merge pull request #46 from ut-code/filters
フィルターを追加しました
2 parents 934b847 + df58b40 commit c1b7d9d

File tree

4 files changed

+193
-0
lines changed

4 files changed

+193
-0
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* セメスターフィルターのコンポーネント
3+
*/
4+
5+
"use client";
6+
import React from "react";
7+
import { ClassType } from "@/app/type";
8+
import { FlagButton } from "../UI/FlagButton";
9+
10+
/**
11+
* クラス種別フィルターのプロパティ
12+
*/
13+
interface SemesterProp {
14+
selectedClassTypes?: ClassType[];
15+
setSelectedClassTypes: (classType: ClassType[]) => void;
16+
}
17+
18+
const ClassType1: ClassType[] = ["基礎", "要求", "主題", "展開"];
19+
const ClassType2: ClassType[] = ["L", "A", "B", "C", "D", "E", "F"];
20+
21+
/**
22+
* 種別フィルターのコンポーネント
23+
* @param prop 種別フィルターのプロパティ
24+
* @returns コンポーネント
25+
*/
26+
export const ClassTypeFilter: React.FC<SemesterProp> = (prop: SemesterProp) => {
27+
const selectedClassTypes = prop.selectedClassTypes ?? [];
28+
29+
// ボタンがクリックされたときの関数
30+
const onClick = (classType: ClassType) => {
31+
if (selectedClassTypes.includes(classType)) {
32+
// 既に含まれている場合、除外
33+
prop.setSelectedClassTypes(
34+
selectedClassTypes.filter((c) => c !== classType),
35+
);
36+
} else {
37+
// 含まれていた場合、追加
38+
prop.setSelectedClassTypes([...selectedClassTypes, classType]);
39+
}
40+
};
41+
42+
return (
43+
<div className="grid grid-cols-8 gap-2">
44+
{ClassType1.map((c) => (
45+
<FlagButton
46+
key={c}
47+
label={c}
48+
isSelected={selectedClassTypes.includes(c)}
49+
onClick={() => onClick(c)}
50+
className="col-span-2"
51+
/>
52+
))}
53+
54+
{ClassType2.map((c) => (
55+
<FlagButton
56+
key={c}
57+
label={c}
58+
isSelected={selectedClassTypes.includes(c)}
59+
onClick={() => onClick(c)}
60+
className="aspect-square col-span-1"
61+
/>
62+
))}
63+
</div>
64+
);
65+
};
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* フリーワード検索のコンポーネントを定義する
3+
*/
4+
5+
"use client";
6+
import React from "react";
7+
import Checkbox from "../UI/Checkbox";
8+
9+
/**
10+
* フリーワード検索のプロパティ
11+
*/
12+
interface FreewordProp {
13+
isFreewordForSyllabusDetail?: boolean;
14+
setFreewordTarget: (isFreewordForSyllabusDetail: boolean) => void;
15+
}
16+
17+
/**
18+
* フリーワード検索のコンポーネント
19+
* @param prop フリーワード検索のプロパティ
20+
* @returns コンポーネント
21+
*/
22+
export const Freeword: React.FC<FreewordProp> = (prop: FreewordProp) => {
23+
const isFreewordForSyllabusDetail = prop.isFreewordForSyllabusDetail ?? false;
24+
return (
25+
<div>
26+
<input
27+
className="text-lg w-72 block"
28+
placeholder={
29+
"検索対象 : " +
30+
(isFreewordForSyllabusDetail ? "授業情報全体" : "講義名")
31+
}
32+
/>
33+
<label className="flex items-center mt-2">
34+
<Checkbox
35+
checked={isFreewordForSyllabusDetail}
36+
onChange={prop.setFreewordTarget}
37+
className="mr-2"
38+
/>
39+
授業情報全体を検索
40+
</label>
41+
</div>
42+
);
43+
};
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* 履修登録済みか否かでフィルターするコンポーネント
3+
*/
4+
5+
"use client";
6+
import React from "react";
7+
import { FlagButton } from "../UI/FlagButton";
8+
9+
/**
10+
* 履修登録済みか否かのフィルターのプロパティ
11+
*/
12+
interface RegistrationFilterProp {
13+
showRegistered?: boolean; // 履修登録済みの講義を表示するか否か
14+
showNotRegistered?: boolean; // 未履修の講義を表示するか否か
15+
setShowRegistered: (
16+
showRegistered: boolean,
17+
showNotRegistered: boolean,
18+
) => void;
19+
}
20+
21+
/**
22+
* 履修登録済みか否かのフィルターのコンポーネント
23+
* @param prop フィルターのプロパティ
24+
* @returns コンポーネント
25+
*/
26+
export const RegistrationFilter: React.FC<RegistrationFilterProp> = (
27+
prop: RegistrationFilterProp,
28+
) => {
29+
const showRegistered = prop.showRegistered ?? true;
30+
const showNotRegistered = prop.showNotRegistered ?? true;
31+
32+
// ボタンがクリックされたときの関数
33+
const onClick = (showRegistered: boolean, showNotRegistered: boolean) => {
34+
prop.setShowRegistered(showRegistered, showNotRegistered);
35+
};
36+
37+
return (
38+
<div className="flex gap-2">
39+
<FlagButton
40+
label={"未"}
41+
isSelected={showNotRegistered}
42+
onClick={() => onClick(showRegistered, !showNotRegistered)}
43+
className="aspect-square" // 円形
44+
/>
45+
<FlagButton
46+
label={"済"}
47+
isSelected={showRegistered}
48+
onClick={() => onClick(!showRegistered, showNotRegistered)}
49+
className="aspect-square" // 円形
50+
/>
51+
</div>
52+
);
53+
};

src/app/components/FilterUI/FilterUI.tsx

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ import { ClassType, Evaluation, Semester } from "@/app/type";
88
import { SemestersCheckbox } from "./FilterComponents/Semester";
99
import { FilterCard } from "./UI/FilterCard";
1010
import { EvaluationFilter } from "./FilterComponents/Evaluation";
11+
import { Freeword } from "./FilterComponents/Freeword";
12+
import { RegistrationFilter } from "./FilterComponents/RegistrationFilter";
13+
import { ClassTypeFilter } from "./FilterComponents/ClassType";
1114

1215
/**
1316
* フィルタの型定義
@@ -32,6 +35,15 @@ export const FilterUI: React.FC = () => {
3235

3336
return (
3437
<div className="flex gap-8 flex-wrap">
38+
<FilterCard title={"フリーワード検索"}>
39+
<Freeword
40+
isFreewordForSyllabusDetail={filter.isFreewordForSyllabusDetail}
41+
setFreewordTarget={(isFreewordForSyllabusDetail) =>
42+
setFilter({ ...filter, isFreewordForSyllabusDetail })
43+
}
44+
/>
45+
</FilterCard>
46+
3547
<FilterCard title={"セメスター"}>
3648
<SemestersCheckbox
3749
selectedSemesters={filter.semesters}
@@ -53,6 +65,26 @@ export const FilterUI: React.FC = () => {
5365
}
5466
/>
5567
</FilterCard>
68+
69+
<FilterCard title={"種別"}>
70+
<ClassTypeFilter
71+
selectedClassTypes={filter.classTypes}
72+
setSelectedClassTypes={(classTypes: ClassType[]) =>
73+
setFilter({ ...filter, classTypes })
74+
}
75+
/>
76+
</FilterCard>
77+
78+
<FilterCard title={"履修登録済み"}>
79+
<RegistrationFilter
80+
showRegistered={filter.showRegistered}
81+
showNotRegistered={filter.showNotRegistered}
82+
setShowRegistered={(
83+
showRegistered: boolean,
84+
showNotRegistered: boolean,
85+
) => setFilter({ ...filter, showRegistered, showNotRegistered })}
86+
/>
87+
</FilterCard>
5688
</div>
5789
);
5890
};

0 commit comments

Comments
 (0)