Skip to content

Commit 84075fc

Browse files
authored
Merge pull request #65 from F-Code-Project-Mini/pages/submissions
Pages/submissions
2 parents 743fa38 + fb3e436 commit 84075fc

25 files changed

Lines changed: 1044 additions & 27 deletions

backend/prisma/schema.prisma

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ model Candidate {
5151
model Team {
5252
id String @id @default(uuid()) @db.VarChar(36)
5353
group Int @unique @db.Int
54-
name String? @unique @db.VarChar(255)
54+
name String? @unique @db.VarChar(255)
5555
mentorshipId String @map("mentorship_id") @db.VarChar(36)
5656
leaderId String? @unique @map("leader_id") @db.VarChar(36)
5757
topicId String @map("topic_id") @db.VarChar(36)
@@ -63,6 +63,7 @@ model Team {
6363
candidates Candidate[] @relation("CandidateToTeam")
6464
submissions Submission[]
6565
reports Report[]
66+
presents Present[]
6667
6768
@@map("teams")
6869
}
@@ -172,6 +173,22 @@ model BaremScore {
172173
@@map("scores")
173174
}
174175

176+
model Present {
177+
id String @id @default(uuid()) @db.VarChar(36)
178+
teamId String @map("team_id") @db.VarChar(36)
179+
180+
trialDate String @unique @map("trial_date") @db.VarChar(255)
181+
officialDate Json @map("offical_date") @db.Json
182+
183+
createdAt DateTime @default(now()) @map("created_at")
184+
updatedAt DateTime @updatedAt @map("updated_at")
185+
186+
// Quan hệ với model Team
187+
team Team @relation(fields: [teamId], references: [id])
188+
189+
@@map("presents")
190+
}
191+
175192
enum Role {
176193
CANDIDATE
177194
HOST

backend/src/controllers/team.controllers.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
import { ParamsDictionary } from "express-serve-static-core";
12
import { NextFunction, Request, Response } from "express";
23
import { RoleType } from "~/constants/enums";
34
import { HTTP_STATUS } from "~/constants/httpStatus";
45
import { ResponseClient } from "~/rules/response";
56
import teamService from "~/services/team.service";
7+
import { CreateSchedulePresent } from "~/rules/requests/team.request";
68

79
export const getAll = async (req: Request, res: Response, next: NextFunction) => {
810
try {
@@ -23,6 +25,27 @@ export const getAll = async (req: Request, res: Response, next: NextFunction) =>
2325
return next(error);
2426
}
2527
};
28+
export const createSchedulePresentation = async (
29+
req: Request<ParamsDictionary, {}, CreateSchedulePresent>,
30+
res: Response,
31+
next: NextFunction,
32+
) => {
33+
const userId = req.userId!;
34+
const { teamId, trialDate, officialDate } = req.body;
35+
try {
36+
const result = await teamService.createSchedulePresentation({
37+
userId,
38+
teamId,
39+
trialDate,
40+
officialDate,
41+
});
42+
return res
43+
.status(HTTP_STATUS.CREATED)
44+
.json(new ResponseClient({ message: "Tạo lịch trình thuyết trình thành công!", result }));
45+
} catch (error) {
46+
return next(error);
47+
}
48+
};
2649

2750
export const getDetail = async (req: Request<{ id: string }>, res: Response, next: NextFunction) => {
2851
try {

backend/src/repositories/team.repository.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import prisma from "~/configs/prisma";
22
import { paginate } from "~/utils/pagination";
33
import userRespository from "./user.repository";
44
import { RoleType } from "~/constants/enums";
5+
import Present from "~/schemas/present.schema";
56

67
class TeamRepository {
78
findWithPagination = async () => {
@@ -227,6 +228,25 @@ class TeamRepository {
227228
});
228229
return !!team;
229230
};
231+
232+
isTrialDateExists = async (trialDate: string) => {
233+
const team = await prisma.present.findFirst({
234+
where: {
235+
trialDate,
236+
},
237+
});
238+
return !!team;
239+
};
240+
241+
createPresentationSchedule = async (data: { teamId: string; trialDate: string; officialDate: string[] }) => {
242+
return prisma.present.create({
243+
data: new Present({
244+
teamId: data.teamId,
245+
trialDate: data.trialDate,
246+
officialDate: data.officialDate,
247+
}),
248+
});
249+
};
230250
}
231251

232252
const teamRepository = new TeamRepository();

backend/src/routes/team.routes.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const teamRouter = Router();
1414

1515
// teamRouter.get("/", auth, isRole([RoleType.ADMIN, RoleType.MENTOR]), validate(getAllSchema), teamController.getAll);
1616
teamRouter.get("/", auth, validate(getAllSchema), teamController.getAll);
17+
teamRouter.post("/present", auth, teamController.createSchedulePresentation);
1718

1819
teamRouter.get("/:id", auth, validate(idParamSchema), teamController.getDetail);
1920

@@ -59,4 +60,5 @@ teamRouter.get(
5960
// validate(uuidParamsAndBodySchema),
6061
teamController.getTeamsByMentor,
6162
);
63+
6264
export default teamRouter;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export interface CreateSchedulePresent {
2+
teamId: string;
3+
trialDate: string;
4+
officialDate: string[];
5+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { v4 as uuidv4 } from "uuid";
2+
3+
interface PresentType {
4+
id?: string;
5+
teamId: string;
6+
trialDate: string;
7+
officialDate: string[];
8+
createdAt?: Date;
9+
updatedAt?: Date;
10+
}
11+
12+
class Present {
13+
id: string;
14+
teamId: string;
15+
trialDate: string;
16+
officialDate: string[];
17+
createdAt: Date;
18+
updatedAt: Date;
19+
constructor(present: PresentType) {
20+
this.id = present.id || uuidv4();
21+
this.teamId = present.teamId;
22+
this.trialDate = present.trialDate;
23+
this.officialDate = present.officialDate;
24+
this.createdAt = present.createdAt || new Date();
25+
this.updatedAt = present.updatedAt || new Date();
26+
}
27+
}
28+
29+
export default Present;

backend/src/services/team.service.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,40 @@ class TeamService {
127127
const updated = await teamRepository.update(teamId, { name });
128128
return updated;
129129
}
130+
createSchedulePresentation = async ({
131+
userId,
132+
teamId,
133+
trialDate,
134+
officialDate,
135+
}: {
136+
userId: string;
137+
teamId: string;
138+
trialDate: string;
139+
officialDate: string[];
140+
}) => {
141+
// trial_date: chỉ có 1 nhóm được đăng ký, nên là check sự trùng lặp
142+
// check trial_date có bị trùng với nhóm khác không
143+
const isTrialDateExist = await teamRepository.isTrialDateExists(trialDate);
144+
if (isTrialDateExist) {
145+
throw new ErrorWithStatus({
146+
status: HTTP_STATUS.BAD_REQUEST,
147+
message: "Ngày thuyết trình thử đã được đăng ký bởi nhóm khác, vui lòng chọn ngày khác.",
148+
});
149+
}
150+
const isLeader = await teamRepository.isLeader(teamId, userId);
151+
if (!isLeader) {
152+
throw new ErrorWithStatus({
153+
status: HTTP_STATUS.FORBIDDEN,
154+
message: "Chỉ trưởng nhóm mới có quyền đăng ký lịch trình thuyết trình.",
155+
});
156+
}
157+
const created = await teamRepository.createPresentationSchedule({
158+
teamId,
159+
trialDate,
160+
officialDate,
161+
});
162+
return created;
163+
};
130164
// async getTeamByMentor(mentorId: string) {
131165
// const teams = await teamRepository.findByMentorId(mentorId);
132166
// return teams;

frontend/package-lock.json

Lines changed: 78 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
},
1212
"dependencies": {
1313
"@radix-ui/react-alert-dialog": "^1.1.15",
14+
"@radix-ui/react-checkbox": "^1.3.3",
1415
"@radix-ui/react-dialog": "^1.1.15",
16+
"@radix-ui/react-label": "^2.1.8",
1517
"@radix-ui/react-radio-group": "^1.3.8",
1618
"@radix-ui/react-select": "^2.2.6",
1719
"@radix-ui/react-slot": "^1.2.4",

frontend/src/App.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import AdminPage from "./pages/Admin";
1616
import ReportsPage from "./pages/Admin/Reports";
1717
import CandidatePages from "./pages/Admin/Candidates";
1818
import TeamPage from "./pages/Teams";
19+
import PresentPage from "./pages/Present";
1920
const App = () => {
2021
return (
2122
<BrowserRouter>
@@ -26,6 +27,7 @@ const App = () => {
2627
<Route path="teams" element={<TeamPage />} />
2728
<Route path="active/token/:token" element={<ActivePage />} />
2829
<Route path="submissions" element={<SubmissionsPage />} />
30+
<Route path="presents" element={<PresentPage />} />
2931

3032
{/* Role Judge */}
3133
<Route path="judge" element={<ProtectedRoute roleAccess={[USER_ROLE.JUDGE]} />}>

0 commit comments

Comments
 (0)