Skip to content

Commit 3ce6f37

Browse files
committed
Merge branch 'feat-person-detailed-menu' of github.com:ut-code/CourseMate into daisy-ui/aster-void
2 parents 56f5fd5 + 32754f2 commit 3ce6f37

File tree

10 files changed

+300
-101
lines changed

10 files changed

+300
-101
lines changed

common/consts.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,20 @@ export const DAY_TO_JAPANESE_MAP = new Map<Day, string>([
1010
["sun", "日"],
1111
]);
1212

13-
export const ACTIVE_DAYS = ["mon", "tue", "wed", "thu", "fri", "sat"] as const;
13+
export const ACTIVE_DAYS = ["mon", "tue", "wed", "thu", "fri"] as const;
14+
15+
export const sortSlots = (
16+
slots: {
17+
day: "mon" | "tue" | "wed" | "thu" | "fri" | "sat" | "sun" | "other";
18+
period: number;
19+
}[],
20+
) => {
21+
const order = ["mon", "tue", "wed", "thu", "fri", "sat", "sun", "other"];
22+
return slots.sort((a, b) => {
23+
const dayComparison = order.indexOf(a.day) - order.indexOf(b.day);
24+
if (dayComparison !== 0) {
25+
return dayComparison;
26+
}
27+
return a.period - b.period;
28+
});
29+
};

server/src/seeds/test-data/data.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,27 +73,27 @@ export const courses = [
7373
{
7474
id: "10001",
7575
name: "国語八列",
76-
teacher: "足助太郎",
76+
teacher: "八十島漕郎",
7777
},
7878
{
7979
id: "10002",
8080
name: "数学八列",
81-
teacher: "足助太郎",
81+
teacher: "八十島漕郎",
8282
},
8383
{
8484
id: "10003",
8585
name: "英語八列",
86-
teacher: "足助太郎",
86+
teacher: "八十島漕郎",
8787
},
8888
{
8989
id: "10004",
9090
name: "理科八列",
91-
teacher: "足助太郎",
91+
teacher: "八十島漕郎",
9292
},
9393
{
9494
id: "10005",
9595
name: "社会八列",
96-
teacher: "足助太郎",
96+
teacher: "八十島漕郎",
9797
},
9898
];
9999

web/app/edit/courses/page.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,16 @@ export default function EditCourses() {
1212
const error = state.current === "error" ? state.error : null;
1313

1414
return (
15-
<div className="mx-auto my-0 flex h-full max-w-[350] flex-col p-5 text-center">
15+
<div className="mx-auto my-0 flex h-full max-w-[350] flex-col p-2 text-center">
1616
<h1 className="mb-2 text-xl">授業編集</h1>
1717
{loading ? (
1818
<FullScreenCircularProgress />
1919
) : error ? (
2020
<p>Error: {error.message}</p>
2121
) : data ? (
22-
<>
22+
<div className="flex-1 p-2">
2323
<EditableCoursesTable userId={data.id} />
24-
</>
24+
</div>
2525
) : (
2626
<p>データがありません。</p>
2727
)}

web/app/edit/layout.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ export default function EditPageLayout({
88
}) {
99
return (
1010
<NavigateByAuthState type="toLoginForUnauthenticated">
11-
<Header title="編集/Edit" />
12-
<div className="absolute top-14 right-0 left-0 overflow-y-auto sm:top-16">
13-
{children}
11+
<div className="flex h-screen flex-col">
12+
<Header title="編集/Edit" />
13+
<div className="mt-14 flex-1 sm:mt-16">{children}</div>
1414
</div>
1515
</NavigateByAuthState>
1616
);
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
import { DAY_TO_JAPANESE_MAP, sortSlots } from "common/consts";
2+
import type { UserWithCoursesAndSubjects } from "common/types";
3+
import { useState } from "react";
4+
import { MdClose } from "react-icons/md";
5+
import { MdOpenInNew } from "react-icons/md";
6+
import { MdArrowBack } from "react-icons/md";
7+
import NonEditableCoursesTable from "~/components/course/NonEditableCoursesTable";
8+
9+
type Props = {
10+
onClose: () => void;
11+
displayedUser: UserWithCoursesAndSubjects;
12+
currentUser: UserWithCoursesAndSubjects;
13+
};
14+
15+
export default function PersonDetailedMenu({
16+
onClose,
17+
displayedUser,
18+
currentUser,
19+
}: Props) {
20+
const [menuStatus, setMenuStatus] = useState<"detailedInfo" | "coursesTable">(
21+
"detailedInfo",
22+
);
23+
24+
return (
25+
<dialog
26+
id="dialog"
27+
className="modal modal-open modal-bottom sm:modal-middle p-0"
28+
>
29+
<div className="modal-box p-0">
30+
<div className="sticky top-0 bg-white p-2">
31+
<form method="dialog">
32+
<div className="relative flex items-center justify-center">
33+
<button
34+
type="button"
35+
className="btn btn-sm btn-circle btn-ghost absolute top-0 left-0"
36+
onClick={onClose}
37+
>
38+
<MdClose className="text-2xl" />
39+
</button>
40+
<h3 className="text-lg">
41+
{displayedUser.name}
42+
{menuStatus === "detailedInfo" ? "詳細情報" : "時間割表"}
43+
</h3>
44+
<span />
45+
</div>
46+
</form>
47+
</div>
48+
{menuStatus === "detailedInfo" ? (
49+
<div className="p-4">
50+
<div>
51+
<span className="text-gray-500 text-xs">名前</span>
52+
<p className="text-lg">{displayedUser.name}</p>
53+
</div>
54+
<div className="divider m-0" />
55+
<div>
56+
<span className="text-gray-500 text-xs">性別</span>
57+
<p className="text-lg">{displayedUser.gender}</p>
58+
</div>
59+
<div className="divider m-0" />
60+
<div>
61+
<span className="text-gray-500 text-xs">自己紹介</span>
62+
<p className="text-md">{displayedUser.intro}</p>
63+
</div>
64+
<div className="divider m-0" />
65+
<div>
66+
<div className="mt-0.5 mb-1 flex items-center justify-between">
67+
<span className="text-gray-500 text-xs">講義</span>
68+
<button
69+
type="button"
70+
className="btn btn-xs font-normal text-primary"
71+
onClick={() => setMenuStatus("coursesTable")}
72+
>
73+
<MdOpenInNew className="mr-[-4px]" />
74+
時間割表を確認
75+
</button>
76+
</div>
77+
<div className="flex flex-col gap-1">
78+
{displayedUser.courses.map(
79+
(course) =>
80+
course.name && (
81+
<div
82+
key={course.id}
83+
className={`flex gap-0.5 rounded-md px-2 py-1 text-md ${
84+
currentUser.courses.some((c) => c.id === course.id)
85+
? "bg-[#FFF1BF]"
86+
: "bg-[#F7FCFF]"
87+
}`}
88+
>
89+
<span className="w-[12vh]">
90+
{sortSlots(course.slots)
91+
.map(
92+
(slot) =>
93+
`${DAY_TO_JAPANESE_MAP.get(slot.day)}${slot.period}`,
94+
)
95+
.join("・")}
96+
</span>
97+
<span className="flex-1">
98+
{course.name} ({course.teacher}){" "}
99+
</span>
100+
<span>{course.id}</span>
101+
</div>
102+
),
103+
)}
104+
</div>
105+
</div>
106+
<div className="divider m-0" />
107+
<div>
108+
<span className="text-gray-500 text-xs">興味分野</span>
109+
<div className="flex flex-wrap gap-2">
110+
{displayedUser.interestSubjects.map(
111+
(subject) =>
112+
subject.name && (
113+
<span
114+
key={subject.id}
115+
className={`rounded-md px-2 py-0.5 text-md text-primary ${
116+
currentUser.interestSubjects.some(
117+
(s) => s.id === subject.id,
118+
)
119+
? "bg-[#FFF1BF]"
120+
: "bg-[#F7FCFF]"
121+
}`}
122+
>
123+
#{subject.name}
124+
</span>
125+
),
126+
)}
127+
</div>
128+
</div>
129+
</div>
130+
) : (
131+
<div className="flex h-[80vh] flex-col">
132+
<div className="flex justify-end pr-2">
133+
<button
134+
type="button"
135+
className="btn btn-xs font-normal text-primary"
136+
onClick={() => setMenuStatus("detailedInfo")}
137+
>
138+
<MdArrowBack className="mr-[-4px]" />
139+
詳細情報に戻る
140+
</button>
141+
</div>
142+
<div className="flex-1 p-2 pb-6">
143+
<NonEditableCoursesTable
144+
userId={displayedUser.id}
145+
comparisonUserId={currentUser.id}
146+
/>
147+
</div>
148+
</div>
149+
)}
150+
</div>
151+
</dialog>
152+
);
153+
}

web/app/home/page.tsx

Lines changed: 47 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,13 @@ import { Card } from "~/components/Card";
1111
import { DraggableCard } from "~/components/DraggableCard";
1212
import FullScreenCircularProgress from "~/components/common/FullScreenCircularProgress";
1313
import { NavigateByAuthState } from "~/components/common/NavigateByAuthState";
14+
import PersonDetailedMenu from "./components/PersonDetailedMenu";
1415

1516
export default function Home() {
1617
const { data, error } = useRecommended();
1718
const controls = useAnimation();
1819
const [clickedButton, setClickedButton] = useState<string>("");
20+
const [openDetailedMenu, setOpenDetailedMenu] = useState(false);
1921
const {
2022
state: { data: currentUser },
2123
} = useAboutMe();
@@ -88,34 +90,54 @@ export default function Home() {
8890
<NavigateByAuthState type="toLoginForUnauthenticated">
8991
<div className="flex h-full flex-col items-center justify-center">
9092
{displayedUser && (
91-
<div className="flex h-full flex-col items-center justify-center">
92-
{nextUser && (
93-
<div className="relative h-full w-full">
94-
<div className="-translate-x-4 -translate-y-4 inset-0 z-0 mt-4 transform">
95-
<Card displayedUser={nextUser} currentUser={currentUser} />
93+
<>
94+
<div className="flex h-full flex-col items-center justify-center">
95+
{nextUser && (
96+
<div className="relative h-full w-full">
97+
<div className="-translate-x-4 -translate-y-4 inset-0 z-0 mt-4 transform">
98+
<Card displayedUser={nextUser} currentUser={currentUser} />
99+
</div>
100+
<motion.div
101+
animate={controls}
102+
className="absolute inset-0 z-10 mt-4 flex items-center justify-center"
103+
>
104+
<DraggableCard
105+
displayedUser={displayedUser}
106+
currentUser={currentUser}
107+
onSwipeLeft={reject}
108+
onSwipeRight={accept}
109+
clickedButton={clickedButton}
110+
/>
111+
</motion.div>
96112
</div>
97-
<motion.div
98-
animate={controls}
99-
className="absolute inset-0 z-10 mt-4 flex items-center justify-center"
100-
>
101-
<DraggableCard
102-
displayedUser={displayedUser}
103-
currentUser={currentUser}
104-
onSwipeLeft={reject}
105-
onSwipeRight={accept}
106-
clickedButton={clickedButton}
107-
/>
108-
</motion.div>
113+
)}
114+
<button
115+
type="button"
116+
onClick={() => setOpenDetailedMenu(!openDetailedMenu)}
117+
>
118+
てすと
119+
</button>
120+
<div className="button-container mt-4 mb-4 flex w-full justify-center space-x-8">
121+
<CloseButton
122+
onclick={onClickClose}
123+
icon={<CloseIconStyled />}
124+
/>
125+
<GoodButton
126+
onclick={onClickHeart}
127+
icon={<FavoriteIconStyled />}
128+
/>
109129
</div>
110-
)}
111-
<div className="button-container mt-4 mb-4 flex w-full justify-center space-x-8">
112-
<CloseButton onclick={onClickClose} icon={<CloseIconStyled />} />
113-
<GoodButton
114-
onclick={onClickHeart}
115-
icon={<FavoriteIconStyled />}
116-
/>
117130
</div>
118-
</div>
131+
{openDetailedMenu && (
132+
<PersonDetailedMenu
133+
onClose={() => {
134+
setOpenDetailedMenu(false);
135+
}}
136+
displayedUser={displayedUser}
137+
currentUser={currentUser}
138+
/>
139+
)}
140+
</>
119141
)}
120142
</div>
121143
</NavigateByAuthState>

web/components/Card.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -183,10 +183,12 @@ const CardBack = ({ displayedUser, currentUser }: CardProps) => {
183183
<div className="flex justify-center">
184184
<p className="font-bold text-lg">{displayedUser?.name}</p>
185185
</div>
186-
<NonEditableCoursesTable
187-
userId={displayedUser.id}
188-
comparisonUserId={currentUser.id}
189-
/>
186+
<div className="flex-1">
187+
<NonEditableCoursesTable
188+
userId={displayedUser.id}
189+
comparisonUserId={currentUser.id}
190+
/>
191+
</div>
190192
<div className="mt-4 flex justify-center">
191193
<ThreeSixtyIcon className="text-3xl" />
192194
</div>

0 commit comments

Comments
 (0)