Skip to content

Commit 0eaa1cf

Browse files
committed
feat: add team information and notifications components, enhance header with team link
1 parent df82b13 commit 0eaa1cf

6 files changed

Lines changed: 164 additions & 101 deletions

File tree

frontend/src/components/Header/Candidate.tsx

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,10 @@
11
import { NavLink } from "./NavLink";
22
import { ServerCrash } from "lucide-react";
3-
// import { useLocation } from "react-router";
4-
// import Helper from "~/utils/helper";
53

64
const CandidateHeader = () => {
75
// const location = useLocation();
86
return (
97
<>
10-
{/* <li id="submissions">
11-
<NavLink
12-
url="/submissions"
13-
name="Nộp đề tài"
14-
Icon={Send}
15-
active={Helper.isActive(location.pathname, "/submissions")}
16-
/>
17-
</li> */}
18-
198
<li>
209
<NavLink url="https://discord.gg/WvudrJaYD" name="Hỗ trợ" Icon={ServerCrash} target="_blank" />
2110
</li>

frontend/src/components/Header/index.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { BadgeQuestionMark, ChevronDown, House, Menu, X } from "lucide-react";
1+
import { BadgeQuestionMark, ChevronDown, House, Menu, Users, X } from "lucide-react";
22
import { Link, useLocation } from "react-router";
33
import useAuth from "~/hooks/useAuth";
44
import { useState, useRef, useEffect } from "react";
@@ -61,6 +61,14 @@ const Header = () => {
6161
active={Helper.isActive(location.pathname, "/")}
6262
/>
6363
</li>
64+
<li id="submissions">
65+
<NavLink
66+
url="/teams"
67+
name="Danh sách nhóm"
68+
Icon={Users}
69+
active={Helper.isActive(location.pathname, "/teams")}
70+
/>
71+
</li>
6472
{isLogin && user.role === USER_ROLE.CANDIDATE && <CandidateHeader />}
6573
{isLogin && user.role === USER_ROLE.ADMIN && <AdminHeader />}
6674
</ul>
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { BookOpen, Calendar, Clock } from "lucide-react";
2+
import React from "react";
3+
4+
const InfoPresent = ({ team }: { team: TeamType }) => {
5+
return (
6+
<div className="overflow-hidden rounded-lg border border-amber-200/60 bg-gradient-to-br from-amber-50/50 to-white shadow-xs transition-all">
7+
<div className="border-b border-amber-200/60 bg-gradient-to-br from-amber-50/80 to-white px-5 py-4">
8+
<h3 className="flex items-center gap-2 text-sm font-semibold text-gray-900">
9+
<Calendar className="h-4 w-4 text-amber-600" />
10+
Lịch thuyết trình
11+
</h3>
12+
</div>
13+
<div className="space-y-3 px-5 py-4">
14+
<div className="flex items-start gap-3">
15+
<div className="flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-lg bg-amber-100/50 text-amber-600">
16+
<Calendar className="h-4 w-4" />
17+
</div>
18+
<div className="flex-1">
19+
<p className="text-xs font-medium text-gray-500">Ngày</p>
20+
<p className="mt-0.5 text-xs font-semibold text-gray-900 italic">Chưa mở</p>
21+
</div>
22+
</div>
23+
<div className="flex items-start gap-3">
24+
<div className="flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-lg bg-amber-100/50 text-amber-600">
25+
<Clock className="h-4 w-4" />
26+
</div>
27+
<div className="flex-1">
28+
<p className="text-xs font-medium text-gray-500">Giờ</p>
29+
<p className="mt-0.5 text-xs font-semibold text-gray-900 italic">Chưa mở</p>
30+
</div>
31+
</div>
32+
<div className="flex items-start gap-3">
33+
<div className="flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-lg bg-amber-100/50 text-amber-600">
34+
<BookOpen className="h-4 w-4" />
35+
</div>
36+
<div className="flex-1">
37+
<p className="text-xs font-medium text-gray-500">Địa điểm</p>
38+
<p className="mt-0.5 text-xs font-semibold text-gray-900 italic">Chưa mở</p>
39+
</div>
40+
</div>
41+
</div>
42+
</div>
43+
);
44+
};
45+
46+
export default InfoPresent;
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { BookOpen, User } from "lucide-react";
2+
import React from "react";
3+
import type { TeamType } from "~/types/team.types";
4+
5+
const TopicTeam = ({ team }: { team: TeamType }) => {
6+
return (
7+
<div className="overflow-hidden rounded-lg border border-gray-200/70 bg-white shadow-xs transition-all">
8+
<div className="border-b border-gray-200/70 bg-gradient-to-br from-gray-50/80 to-white px-5 py-4">
9+
<h3 className="flex items-center gap-2 text-sm font-semibold text-gray-900">
10+
<BookOpen className="text-primary h-4 w-4" />
11+
Thông tin nhóm
12+
</h3>
13+
</div>
14+
<div className="space-y-3 px-5 py-4">
15+
<div className="flex items-start gap-3">
16+
<div className="bg-primary/10 text-primary flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-lg">
17+
<BookOpen className="h-4 w-4" />
18+
</div>
19+
<div className="flex-1">
20+
<p className="text-xs font-medium text-gray-500">Đề tài</p>
21+
<p className="text-primary mt-0.5 text-sm leading-relaxed font-semibold">
22+
{team.topic?.title || "Chưa có đề tài"}
23+
</p>
24+
{team.topic?.filePath && (
25+
<a
26+
href={team.topic.filePath}
27+
target="_blank"
28+
rel="noopener noreferrer"
29+
className="text-primary mt-1 inline-block text-xs font-medium hover:underline"
30+
>
31+
Xem chi tiết đề tài →
32+
</a>
33+
)}
34+
</div>
35+
</div>
36+
<div className="flex items-start gap-3">
37+
<div className="bg-primary/10 text-primary flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-lg">
38+
<User className="h-4 w-4" />
39+
</div>
40+
<div className="flex-1">
41+
<p className="text-xs font-medium text-gray-500">Mentor</p>
42+
<p className="text-primary mt-0.5 text-sm font-semibold">
43+
{team.mentorship?.mentor?.fullName || "Chưa có mentor"}
44+
</p>
45+
</div>
46+
</div>
47+
</div>
48+
</div>
49+
);
50+
};
51+
52+
export default TopicTeam;
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
const Notification = () => {
2+
return (
3+
<div
4+
className="mb-6 rounded-lg border border-blue-300/60 bg-gradient-to-r from-blue-50 to-indigo-50 px-5 py-4 shadow-xs"
5+
role="alert"
6+
>
7+
<div className="flex items-center gap-3">
8+
<div className="flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-blue-500 text-white">
9+
<span className="text-sm font-bold">i</span>
10+
</div>
11+
<div className="flex-1">
12+
<p className="text-sm font-semibold text-blue-700">Ghi chú</p>
13+
<ul className="mt-2.5 space-y-2">
14+
<li className="flex items-center gap-2 text-sm text-gray-700">
15+
<span className="h-1.5 w-1.5 shrink-0 rounded-full bg-blue-500"></span>
16+
<span>
17+
Các bạn sẽ có cơ hội <strong>tìm hiểu khả năng của nhau</strong> thông qua quá trình làm
18+
việc nhóm.
19+
</span>
20+
</li>
21+
<li className="flex items-center gap-2 text-sm text-gray-700">
22+
<span className="h-1.5 w-1.5 shrink-0 rounded-full bg-blue-500"></span>
23+
<span>
24+
Đề tài sẽ được phân công dựa trên <strong>năng lực và thế mạnh</strong> của từng thành
25+
viên.
26+
</span>
27+
</li>
28+
<li className="flex items-center gap-2 text-sm text-gray-700">
29+
<span className="h-1.5 w-1.5 shrink-0 rounded-full bg-blue-500"></span>
30+
<span>
31+
Mỗi nhóm sẽ có <strong>1-2 người có kinh nghiệm</strong> để định hướng và hỗ trợ các
32+
thành viên khác.
33+
</span>
34+
</li>
35+
<li className="flex items-center gap-2 text-sm text-gray-700">
36+
<span className="h-1.5 w-1.5 shrink-0 rounded-full bg-blue-500"></span>
37+
<span>
38+
Đây là cơ hội để <strong>học hỏi công nghệ mới</strong> và phát triển kỹ năng làm việc
39+
nhóm.
40+
</span>
41+
</li>
42+
</ul>
43+
</div>
44+
</div>
45+
</div>
46+
);
47+
};
48+
49+
export default Notification;

frontend/src/pages/Teams/index.tsx

Lines changed: 8 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
import { BookOpen, User, Calendar, Clock } from "lucide-react";
21
import BadgeLeader from "~/components/BadgeLeader";
32
import { useQuery } from "@tanstack/react-query";
43
import TeamApi from "~/api-requests/team.requests";
54
import Loading from "~/components/Loading";
5+
import TopicTeam from "./InfoTeam";
6+
import InfoPresent from "./InfoPresent";
7+
import Notification from "./Notification";
68

79
const TeamPage = () => {
810
const { data: teams, isLoading } = useQuery({
@@ -12,17 +14,18 @@ const TeamPage = () => {
1214
return res.result;
1315
},
1416
});
15-
if (isLoading) <Loading />;
17+
if (isLoading) return <Loading />;
1618

1719
return (
1820
<>
1921
<section className="mb-6 sm:mb-8">
2022
<h1 className="text-2xl font-bold tracking-tight text-gray-900 sm:text-3xl">Danh sách các nhóm</h1>
2123
<p className="mt-2 text-sm text-gray-600">
22-
Xem thông tin các nhóm tham gia Challenge vòng 3. Tổng cộng:{" "}
24+
Danh sách thông tin các nhóm tham gia Challenge 3. Tổng cộng:{" "}
2325
<span className="text-primary font-semibold">{teams?.length || 0}</span> nhóm
2426
</p>
2527
</section>
28+
<Notification />
2629

2730
<section className="space-y-8">
2831
{teams?.map((team, index) => (
@@ -98,92 +101,8 @@ const TeamPage = () => {
98101
</div>
99102

100103
<div className="col-span-1 space-y-2 lg:col-span-4">
101-
<div className="overflow-hidden rounded-lg border border-gray-200/70 bg-white shadow-xs transition-all">
102-
<div className="border-b border-gray-200/70 bg-gradient-to-br from-gray-50/80 to-white px-5 py-4">
103-
<h3 className="flex items-center gap-2 text-sm font-semibold text-gray-900">
104-
<BookOpen className="text-primary h-4 w-4" />
105-
Thông tin nhóm
106-
</h3>
107-
</div>
108-
<div className="space-y-3 px-5 py-4">
109-
<div className="flex items-start gap-3">
110-
<div className="bg-primary/10 text-primary flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-lg">
111-
<BookOpen className="h-4 w-4" />
112-
</div>
113-
<div className="flex-1">
114-
<p className="text-xs font-medium text-gray-500">Đề tài</p>
115-
<p className="text-primary mt-0.5 text-sm leading-relaxed font-semibold">
116-
{team.topic?.title || "Chưa có đề tài"}
117-
</p>
118-
{team.topic?.filePath && (
119-
<a
120-
href={team.topic.filePath}
121-
target="_blank"
122-
rel="noopener noreferrer"
123-
className="text-primary mt-1 inline-block text-xs font-medium hover:underline"
124-
>
125-
Xem chi tiết đề tài →
126-
</a>
127-
)}
128-
</div>
129-
</div>
130-
<div className="flex items-start gap-3">
131-
<div className="bg-primary/10 text-primary flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-lg">
132-
<User className="h-4 w-4" />
133-
</div>
134-
<div className="flex-1">
135-
<p className="text-xs font-medium text-gray-500">Mentor</p>
136-
<p className="text-primary mt-0.5 text-sm font-semibold">
137-
{team.mentorship?.mentor?.fullName || "Chưa có mentor"}
138-
</p>
139-
</div>
140-
</div>
141-
</div>
142-
</div>
143-
144-
<div className="overflow-hidden rounded-lg border border-amber-200/60 bg-gradient-to-br from-amber-50/50 to-white shadow-xs transition-all">
145-
<div className="border-b border-amber-200/60 bg-gradient-to-br from-amber-50/80 to-white px-5 py-4">
146-
<h3 className="flex items-center gap-2 text-sm font-semibold text-gray-900">
147-
<Calendar className="h-4 w-4 text-amber-600" />
148-
Lịch thuyết trình
149-
</h3>
150-
</div>
151-
<div className="space-y-3 px-5 py-4">
152-
<div className="flex items-start gap-3">
153-
<div className="flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-lg bg-amber-100/50 text-amber-600">
154-
<Calendar className="h-4 w-4" />
155-
</div>
156-
<div className="flex-1">
157-
<p className="text-xs font-medium text-gray-500">Ngày</p>
158-
<p className="mt-0.5 text-xs font-semibold text-gray-900 italic">
159-
Chưa mở
160-
</p>
161-
</div>
162-
</div>
163-
<div className="flex items-start gap-3">
164-
<div className="flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-lg bg-amber-100/50 text-amber-600">
165-
<Clock className="h-4 w-4" />
166-
</div>
167-
<div className="flex-1">
168-
<p className="text-xs font-medium text-gray-500">Giờ</p>
169-
<p className="mt-0.5 text-xs font-semibold text-gray-900 italic">
170-
Chưa mở
171-
</p>
172-
</div>
173-
</div>
174-
<div className="flex items-start gap-3">
175-
<div className="flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-lg bg-amber-100/50 text-amber-600">
176-
<BookOpen className="h-4 w-4" />
177-
</div>
178-
<div className="flex-1">
179-
<p className="text-xs font-medium text-gray-500">Địa điểm</p>
180-
<p className="mt-0.5 text-xs font-semibold text-gray-900 italic">
181-
Chưa mở
182-
</p>
183-
</div>
184-
</div>
185-
</div>
186-
</div>
104+
<TopicTeam team={team} />
105+
<InfoPresent team={team} />
187106
</div>
188107
</div>
189108
</>

0 commit comments

Comments
 (0)