Skip to content

Commit ea38b7d

Browse files
committed
カードのの表面のデザイン
1 parent d6b5739 commit ea38b7d

File tree

1 file changed

+115
-66
lines changed

1 file changed

+115
-66
lines changed

web/components/Card.tsx

Lines changed: 115 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,128 @@
1+
import React, { useState, useRef, useEffect } from "react";
12
import ThreeSixtyIcon from "@mui/icons-material/ThreeSixty";
2-
import { Chip } from "@mui/material";
33
import type { User, UserID } from "common/types";
4-
import { useState } from "react";
5-
import NonEditableCoursesTable from "./course/NonEditableCoursesTable";
64
import UserAvatar from "./human/avatar";
5+
import NonEditableCoursesTable from "./course/NonEditableCoursesTable";
76

87
interface CardProps {
98
displayedUser: User;
109
comparisonUserId?: UserID;
1110
onFlip?: (isBack: boolean) => void;
1211
}
1312

13+
const interests = [
14+
"記号論理学",
15+
"量子力学",
16+
"離散数学",
17+
"プログラミング",
18+
"量子情報理論",
19+
"オペレーションズリサーチ",
20+
];
21+
22+
const CardFront = ({ displayedUser }: { displayedUser: User }) => {
23+
const containerRef = useRef<HTMLDivElement>(null);
24+
const [isHiddenInterestExist, setHiddenInterestExist] = useState(false);
25+
26+
useEffect(() => {
27+
const container = containerRef.current;
28+
if (!container) return;
29+
30+
const resizeObserver = new ResizeObserver(() => {
31+
calculateVisibleInterests();
32+
});
33+
34+
resizeObserver.observe(container);
35+
36+
calculateVisibleInterests(); // 初期計算
37+
38+
return () => resizeObserver.disconnect();
39+
}, []);
40+
41+
const calculateVisibleInterests = () => {
42+
const container = containerRef.current;
43+
if (!container) return;
44+
45+
const containerHeight = container.offsetHeight; // ここで高さを取得
46+
47+
// 一旦全てのバッジを非表示にする
48+
container.innerHTML = "";
49+
setHiddenInterestExist(false);
50+
51+
// interestsを入れるflexコンテナ
52+
const flexContainer = document.createElement("div");
53+
flexContainer.classList.add("flex", "flex-wrap", "gap-2");
54+
container.appendChild(flexContainer);
55+
56+
// interests配列をループしてバッジを作成
57+
interests.forEach((interest) => {
58+
// 新しい div 要素を作成
59+
const element = document.createElement("div");
60+
element.textContent = interest;
61+
62+
// スタイルを適用
63+
element.classList.add("badge", "badge-outline");
64+
element.style.overflow = "hidden";
65+
element.style.whiteSpace = "nowrap";
66+
element.style.textOverflow = "ellipsis";
67+
element.style.display = "inline-block";
68+
69+
// 要素がコンテナの高さを超えていない場合、表示
70+
if (flexContainer.offsetHeight + 20 <= containerHeight) {
71+
flexContainer.appendChild(element);
72+
} else {
73+
setHiddenInterestExist(true);
74+
}
75+
});
76+
77+
};
78+
79+
return (
80+
<div className="flex h-full flex-col justify-between gap-5 overflow-clip border-2 border-primary bg-secondary p-5">
81+
<div className="grid h-[20%] grid-cols-3 items-center">
82+
<UserAvatar pictureUrl={displayedUser.pictureUrl} width="9dvh" height="9dvh" />
83+
<div className="grid grid-rows-3 items-center col-span-2">
84+
<p className="col-span-3 font-bold text-1xl">{displayedUser.name}</p>
85+
<p className="col-span-3 text-1xl">{displayedUser.grade}</p>
86+
<p className="col-span-1 text-1xl">{displayedUser.faculty}</p>
87+
<p className="col-span-2 text-1xl">{displayedUser.department}</p>
88+
</div>
89+
</div>
90+
91+
<div ref={containerRef} className="h-[50%] overflow-hidden width-full">
92+
<div>
93+
</div>
94+
</div>
95+
96+
{isHiddenInterestExist && (
97+
<div className="badge badge-outline bg-gray-200 text-gray-700">
98+
And More
99+
</div>
100+
)}
101+
102+
<div className="flex justify-center">
103+
<ThreeSixtyIcon className="text-3xl" />
104+
</div>
105+
</div>
106+
);
107+
};
108+
109+
const CardBack = ({ displayedUser, comparisonUserId }: CardProps) => {
110+
return (
111+
<div className="flex h-full flex-col overflow-hidden border-2 border-primary bg-secondary p-4">
112+
<div className="flex justify-center">
113+
<p className="font-bold text-lg">{displayedUser?.name}</p>
114+
</div>
115+
<NonEditableCoursesTable
116+
userId={displayedUser.id}
117+
comparisonUserId={comparisonUserId}
118+
/>
119+
<div className="mt-4 flex justify-center">
120+
<ThreeSixtyIcon className="text-3xl" />
121+
</div>
122+
</div>
123+
);
124+
};
125+
14126
export function Card({ displayedUser, comparisonUserId, onFlip }: CardProps) {
15127
const [isDisplayingBack, setIsDisplayingBack] = useState(false);
16128

@@ -57,66 +169,3 @@ export function Card({ displayedUser, comparisonUserId, onFlip }: CardProps) {
57169
</div>
58170
);
59171
}
60-
61-
const CardFront = ({ displayedUser }: CardProps) => {
62-
return (
63-
<div className="flex h-full flex-col justify-between gap-5 overflow-hidden border-2 border-primary bg-secondary p-5">
64-
<div className="grid h-[30%] grid-cols-3 items-center">
65-
<UserAvatar
66-
pictureUrl={displayedUser.pictureUrl}
67-
width="10dvh"
68-
height="10dvh"
69-
/>
70-
<div className="col-span-2 ml-2 flex justify-center">
71-
<span className="font-bold text-4xl">{displayedUser.name}</span>
72-
</div>
73-
</div>
74-
<div className="grid grid-cols-6 items-center gap-4">
75-
<Chip label="学部" size="small" className="col-span-1" />
76-
<p className="col-span-5 text-xl">{displayedUser.faculty}</p>
77-
</div>
78-
<div className="grid grid-cols-6 items-center gap-4">
79-
<Chip label="学科" size="small" className="col-span-1" />
80-
<p
81-
className={`col-span-5 text-xl ${displayedUser.department.length > 7 ? "text-xs" : "text-2xl"}`}
82-
>
83-
{displayedUser.department}
84-
</p>
85-
</div>
86-
<div className="grid grid-cols-6 items-center gap-4">
87-
<Chip label="性別" size="small" className="col-span-1" />
88-
<p className="col-span-5 text-xl">{displayedUser.gender}</p>
89-
</div>
90-
<div className="grid grid-cols-6 items-center gap-4">
91-
<Chip label="学年" size="small" className="col-span-1" />
92-
<p className="col-span-5 text-xl">{displayedUser.grade}</p>
93-
</div>
94-
<div className="grid max-h-[32%] flex-1 grid-cols-6 gap-4">
95-
<Chip label="自己紹介" size="small" className="col-span-1 text-sm" />
96-
<p className="col-span-5 line-clamp-8 overflow-hidden text-sm">
97-
{displayedUser.intro}
98-
</p>
99-
</div>
100-
<div className="flex justify-center">
101-
<ThreeSixtyIcon className="text-3xl" />
102-
</div>
103-
</div>
104-
);
105-
};
106-
107-
const CardBack = ({ displayedUser, comparisonUserId }: CardProps) => {
108-
return (
109-
<div className="flex h-full flex-col overflow-hidden border-2 border-primary bg-secondary p-4">
110-
<div className="flex justify-center">
111-
<p className="font-bold text-lg">{displayedUser?.name}</p>
112-
</div>
113-
<NonEditableCoursesTable
114-
userId={displayedUser.id}
115-
comparisonUserId={comparisonUserId}
116-
/>
117-
<div className="mt-4 flex justify-center">
118-
<ThreeSixtyIcon className="text-3xl" />
119-
</div>
120-
</div>
121-
);
122-
};

0 commit comments

Comments
 (0)