Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions src/app/components/FilterUI/FilterComponents/ClassType.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* セメスターフィルターのコンポーネント
*/

"use client";
import React from "react";
import { ClassType } from "@/app/type";
import { FlagButton } from "../UI/FlagButton";

/**
* クラス種別フィルターのプロパティ
*/
interface SemesterProp {
selectedClassTypes?: ClassType[];
setSelectedClassTypes: (classType: ClassType[]) => void;
}

const ClassType1: ClassType[] = ["基礎", "要求", "主題", "展開"];
const ClassType2: ClassType[] = ["L", "A", "B", "C", "D", "E", "F"];

/**
* 種別フィルターのコンポーネント
* @param prop 種別フィルターのプロパティ
* @returns コンポーネント
*/
export const ClassTypeFilter: React.FC<SemesterProp> = (prop: SemesterProp) => {
const selectedClassTypes = prop.selectedClassTypes ?? [];

// ボタンがクリックされたときの関数
const onClick = (classType: ClassType) => {
if (selectedClassTypes.includes(classType)) {
// 既に含まれている場合、除外
prop.setSelectedClassTypes(
selectedClassTypes.filter((c) => c !== classType),
);
} else {
// 含まれていた場合、追加
prop.setSelectedClassTypes([...selectedClassTypes, classType]);
}
};

return (
<div className="grid grid-cols-8 gap-2">
{ClassType1.map((c) => (
<FlagButton
key={c}
label={c}
isSelected={selectedClassTypes.includes(c)}
onClick={() => onClick(c)}
className="col-span-2"
/>
))}

{ClassType2.map((c) => (
<FlagButton
key={c}
label={c}
isSelected={selectedClassTypes.includes(c)}
onClick={() => onClick(c)}
className="aspect-square col-span-1"
/>
))}
</div>
);
};
43 changes: 43 additions & 0 deletions src/app/components/FilterUI/FilterComponents/Freeword.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* フリーワード検索のコンポーネントを定義する
*/

"use client";
import React from "react";
import Checkbox from "../UI/Checkbox";

/**
* フリーワード検索のプロパティ
*/
interface FreewordProp {
isFreewordForSyllabusDetail?: boolean;
setFreewordTarget: (isFreewordForSyllabusDetail: boolean) => void;
}

/**
* フリーワード検索のコンポーネント
* @param prop フリーワード検索のプロパティ
* @returns コンポーネント
*/
export const Freeword: React.FC<FreewordProp> = (prop: FreewordProp) => {
const isFreewordForSyllabusDetail = prop.isFreewordForSyllabusDetail ?? false;
return (
<div>
<input
className="text-lg w-72 block"
placeholder={
"検索対象 : " +
(isFreewordForSyllabusDetail ? "授業情報全体" : "講義名")
}
/>
<label className="flex items-center mt-2">
<Checkbox
checked={isFreewordForSyllabusDetail}
onChange={prop.setFreewordTarget}
className="mr-2"
/>
授業情報全体を検索
</label>
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* 履修登録済みか否かでフィルターするコンポーネント
*/

"use client";
import React from "react";
import { FlagButton } from "../UI/FlagButton";

/**
* 履修登録済みか否かのフィルターのプロパティ
*/
interface RegistrationFilterProp {
showRegistered?: boolean; // 履修登録済みの講義を表示するか否か
showNotRegistered?: boolean; // 未履修の講義を表示するか否か
setShowRegistered: (
showRegistered: boolean,
showNotRegistered: boolean,
) => void;
}

/**
* 履修登録済みか否かのフィルターのコンポーネント
* @param prop フィルターのプロパティ
* @returns コンポーネント
*/
export const RegistrationFilter: React.FC<RegistrationFilterProp> = (
prop: RegistrationFilterProp,
) => {
const showRegistered = prop.showRegistered ?? true;
const showNotRegistered = prop.showNotRegistered ?? true;

// ボタンがクリックされたときの関数
const onClick = (showRegistered: boolean, showNotRegistered: boolean) => {
prop.setShowRegistered(showRegistered, showNotRegistered);
};

return (
<div className="flex gap-2">
<FlagButton
label={"未"}
isSelected={showNotRegistered}
onClick={() => onClick(showRegistered, !showNotRegistered)}
className="aspect-square" // 円形
/>
<FlagButton
label={"済"}
isSelected={showRegistered}
onClick={() => onClick(!showRegistered, showNotRegistered)}
className="aspect-square" // 円形
/>
</div>
);
};
32 changes: 32 additions & 0 deletions src/app/components/FilterUI/FilterUI.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import { ClassType, Evaluation, Semester } from "@/app/type";
import { SemestersCheckbox } from "./FilterComponents/Semester";
import { FilterCard } from "./UI/FilterCard";
import { EvaluationFilter } from "./FilterComponents/Evaluation";
import { Freeword } from "./FilterComponents/Freeword";
import { RegistrationFilter } from "./FilterComponents/RegistrationFilter";
import { ClassTypeFilter } from "./FilterComponents/ClassType";

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

return (
<div className="flex gap-8 flex-wrap">
<FilterCard title={"フリーワード検索"}>
<Freeword
isFreewordForSyllabusDetail={filter.isFreewordForSyllabusDetail}
setFreewordTarget={(isFreewordForSyllabusDetail) =>
setFilter({ ...filter, isFreewordForSyllabusDetail })
}
/>
</FilterCard>

<FilterCard title={"セメスター"}>
<SemestersCheckbox
selectedSemesters={filter.semesters}
Expand All @@ -53,6 +65,26 @@ export const FilterUI: React.FC = () => {
}
/>
</FilterCard>

<FilterCard title={"種別"}>
<ClassTypeFilter
selectedClassTypes={filter.classTypes}
setSelectedClassTypes={(classTypes: ClassType[]) =>
setFilter({ ...filter, classTypes })
}
/>
</FilterCard>

<FilterCard title={"履修登録済み"}>
<RegistrationFilter
showRegistered={filter.showRegistered}
showNotRegistered={filter.showNotRegistered}
setShowRegistered={(
showRegistered: boolean,
showNotRegistered: boolean,
) => setFilter({ ...filter, showRegistered, showNotRegistered })}
/>
</FilterCard>
</div>
);
};
Loading