11import React , { useState } from "react" ;
2+ import { useMutation } from "@tanstack/react-query" ;
23import { Calendar , Clock , Send } from "lucide-react" ;
34import { Button } from "~/components/ui/button" ;
45import { RadioGroup , RadioGroupItem } from "~/components/ui/radio-group" ;
56import { Checkbox } from "~/components/ui/checkbox" ;
67import { Label } from "~/components/ui/label" ;
78
9+ import TeamApi from "~/api-requests/team.requests" ;
10+ import Notification from "~/utils/notification" ;
11+ import { useAppSelector } from "~/hooks/useRedux" ;
12+ import type { AxiosError } from "axios" ;
13+ import ConfirmRegister from "./ConfirmRegister" ;
14+
815interface TimeSlots {
916 [ date : string ] : string [ ] ;
1017}
1118
12- // Thời gian thuyết trình thử - mỗi ngày 4 slot
1319const trialTimeSlots : TimeSlots = {
1420 "17/01/2026" : [ "7:00 - 7:45" , "8:00 - 8:45" , "9:00 - 9:45" , "10:00 - 10:45" ] ,
1521 "18/01/2026" : [ "7:00 - 7:45" , "8:00 - 8:45" , "9:00 - 9:45" , "10:00 - 10:45" ] ,
1622 "19/01/2026" : [ "7:00 - 7:45" , "8:00 - 8:45" , "9:00 - 9:45" , "10:00 - 10:45" ] ,
1723 "20/01/2026" : [ "7:00 - 7:45" , "8:00 - 8:45" , "9:00 - 9:45" , "10:00 - 10:45" ] ,
1824} ;
1925
20- // Thời gian thuyết trình chính thức - mỗi ngày 2 slot
2126const officialTimeSlots : TimeSlots = {
2227 "17/01/2026" : [ "13:00 - 13:45" , "14:00 - 14:45" ] ,
2328 "18/01/2026" : [ "13:00 - 13:45" , "14:00 - 14:45" ] ,
@@ -26,8 +31,30 @@ const officialTimeSlots: TimeSlots = {
2631} ;
2732
2833const FormRegisterPresent = ( ) => {
34+ const userInfo = useAppSelector ( ( state ) => state . user . userInfo ) ;
35+ const teamId = userInfo . candidate ?. teamId || "" ;
36+
2937 const [ trialSlot , setTrialSlot ] = useState < string > ( "" ) ;
3038 const [ officialSlots , setOfficialSlots ] = useState < string [ ] > ( [ ] ) ;
39+ const [ showConfirmDialog , setShowConfirmDialog ] = useState ( false ) ;
40+
41+ const registerMutation = useMutation ( {
42+ mutationFn : ( data : { teamId : string ; trialDate : string ; officialDate : string [ ] } ) =>
43+ TeamApi . createSchedulePresentation ( data ) ,
44+ onError : ( error : AxiosError < { message ?: string } > ) => {
45+ console . log ( error ) ;
46+ Notification . error ( {
47+ text : error . response ?. data ?. message || "Đăng ký thời gian thuyết trình thất bại!" ,
48+ } ) ;
49+ } ,
50+ onSuccess : ( ) => {
51+ Notification . success ( {
52+ text : "Đăng ký thời gian thuyết trình thành công!" ,
53+ } ) ;
54+ setTrialSlot ( "" ) ;
55+ setOfficialSlots ( [ ] ) ;
56+ } ,
57+ } ) ;
3158
3259 const handleOfficialSlotChange = ( slot : string ) => {
3360 setOfficialSlots ( ( prev ) => {
@@ -40,11 +67,16 @@ const FormRegisterPresent = () => {
4067
4168 const handleSubmit = async ( e : React . FormEvent ) => {
4269 e . preventDefault ( ) ;
43- console . log ( {
44- trialSlot,
45- officialSlots,
70+ setShowConfirmDialog ( true ) ;
71+ } ;
72+
73+ const handleConfirmSubmit = ( ) => {
74+ registerMutation . mutate ( {
75+ teamId,
76+ trialDate : trialSlot || "" ,
77+ officialDate : officialSlots ,
4678 } ) ;
47- // TODO: Implement API call
79+ setShowConfirmDialog ( false ) ;
4880 } ;
4981
5082 return (
@@ -70,8 +102,15 @@ const FormRegisterPresent = () => {
70102 </ div >
71103 < p className = "text-sm text-gray-600" >
72104 Chọn < span className = "font-semibold" > MỘT</ span > khung giờ để thuyết trình thử nghiệm và nhận
73- phản hồi
105+ phản hồi từ mentor.
74106 </ p >
107+ < div className = "rounded-md border-l-4 border-blue-400 bg-blue-50 p-3" >
108+ < p className = "text-xs text-blue-800" >
109+ < span className = "font-semibold" > Lưu ý:</ span > Chỉ có{ " " }
110+ < span className = "font-bold" > 10 slot</ span > thuyết trình thử cho toàn bộ các nhóm. Mỗi nhóm
111+ chỉ được chọn 1 khung giờ tham gia.
112+ </ p >
113+ </ div >
75114
76115 < RadioGroup value = { trialSlot } onValueChange = { setTrialSlot } >
77116 { Object . entries ( trialTimeSlots ) . map ( ( [ date , slots ] ) => (
@@ -104,7 +143,6 @@ const FormRegisterPresent = () => {
104143
105144 < div className = "border-t border-gray-200" > </ div >
106145
107- { /* Official Presentation */ }
108146 < div className = "space-y-4" >
109147 < div className = "flex items-center gap-2" >
110148 < Clock className = "h-5 w-5 text-green-600" />
@@ -117,6 +155,13 @@ const FormRegisterPresent = () => {
117155 Chọn < span className = "font-semibold text-green-700" > NHIỀU</ span > khung giờ bạn có thể tham gia
118156 thuyết trình chính thức
119157 </ p >
158+ < div className = "rounded-md border-l-4 border-green-400 bg-green-50 p-3" >
159+ < p className = "text-xs text-green-800" >
160+ < span className = "font-semibold" > Lưu ý:</ span > Tất cả các nhóm đều được quyền tham gia thuyết
161+ trình chính thức. Vui lòng chọn < span className = "font-bold" > TẤT CẢ</ span > các khung giờ mà{ " " }
162+ < span className = "font-bold" > TẤT CẢ</ span > thành viên trong nhóm có thể tham gia được.
163+ </ p >
164+ </ div >
120165
121166 < div className = "space-y-4" >
122167 { Object . entries ( officialTimeSlots ) . map ( ( [ date , slots ] ) => (
@@ -147,22 +192,29 @@ const FormRegisterPresent = () => {
147192 </ div >
148193 </ div >
149194
150- { /* Submit Button */ }
151195 < div className = "flex items-center gap-3 border-t border-gray-200/70 pt-5" >
152196 < Button
153197 type = "submit"
154198 className = "group flex items-center gap-2 transition-all hover:shadow-md"
155- disabled = { officialSlots . length === 0 }
199+ disabled = { officialSlots . length === 0 || registerMutation . isPending }
156200 >
157201 < Send className = "h-4 w-4 transition-transform group-hover:translate-x-0.5" />
158- Đăng ký
202+ { registerMutation . isPending ? "Đang đăng ký..." : " Đăng ký" }
159203 </ Button >
160204 < p className = "text-xs text-gray-500" >
161205 < span className = "font-semibold text-red-600" > Lưu ý:</ span > Bạn phải chọn ít nhất 1 khung giờ cho
162206 thuyết trình chính thức
163207 </ p >
164208 </ div >
165209 </ form >
210+
211+ < ConfirmRegister
212+ handleConfirmSubmit = { handleConfirmSubmit }
213+ showConfirmDialog = { showConfirmDialog }
214+ setShowConfirmDialog = { setShowConfirmDialog }
215+ trialSlot = { trialSlot }
216+ officialSlots = { officialSlots }
217+ />
166218 </ section >
167219 ) ;
168220} ;
0 commit comments