diff --git a/src/pages/SchedulePage.jsx b/src/pages/SchedulePage.jsx index d07252424be88fbde75afc6a183f179e801093b9..5febb0c456c23ac76f8814bde2560b0a18733f0b 100644 --- a/src/pages/SchedulePage.jsx +++ b/src/pages/SchedulePage.jsx @@ -7,6 +7,7 @@ import { fetchAllSchedules, updateSchedule, } from "../api/schedule"; +import Button from "../components/Button"; const generateTimeSlots = () => { const timeSlots = []; @@ -80,16 +81,16 @@ const days = ["월", "화", "수", "목", "금", "토", "일"]; // ]; const colorClasses = [ - 'bg-indigo-300 hover:bg-indigo-400', - 'bg-purple-300 hover:bg-purple-400', - 'bg-pink-300 hover:bg-pink-400', - 'bg-blue-300 hover:bg-blue-400', - 'bg-green-300 hover:bg-green-400', - 'bg-yellow-300 hover:bg-yellow-400', - 'bg-red-300 hover:bg-red-400', - 'bg-orange-300 hover:bg-orange-400', - 'bg-teal-300 hover:bg-teal-400', - 'bg-cyan-300 hover:bg-cyan-400', + "bg-indigo-300 hover:bg-indigo-400", + "bg-purple-300 hover:bg-purple-400", + "bg-pink-300 hover:bg-pink-400", + "bg-blue-300 hover:bg-blue-400", + "bg-green-300 hover:bg-green-400", + "bg-yellow-300 hover:bg-yellow-400", + "bg-red-300 hover:bg-red-400", + "bg-orange-300 hover:bg-orange-400", + "bg-teal-300 hover:bg-teal-400", + "bg-cyan-300 hover:bg-cyan-400", ]; const SchedulePage = () => { const timeSlots = generateTimeSlots(); @@ -123,13 +124,13 @@ const SchedulePage = () => { initializeSchedules(); - // 임시 코드 + // 임시 코드 // setSchedules(dummySchedules); }, []); useEffect(() => { const newColorMap = new Map(); - schedules.forEach(schedule => { + schedules.forEach((schedule) => { if (!newColorMap.has(schedule.title)) { newColorMap.set( schedule.title, @@ -279,7 +280,7 @@ const SchedulePage = () => { const getColorForTitle = (title) => { if (!titleColorMap.has(title)) { const newColor = colorClasses[titleColorMap.size % colorClasses.length]; - setTitleColorMap(prev => new Map(prev).set(title, newColor)); + setTitleColorMap((prev) => new Map(prev).set(title, newColor)); return newColor; } return titleColorMap.get(title); @@ -291,7 +292,9 @@ const SchedulePage = () => { const hour = Math.floor(timeSlotIndex / 4); const minute = (timeSlotIndex % 4) * 15; const day = days[dayIndex]; - const time = `${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}`; + const time = `${hour.toString().padStart(2, "0")}:${minute + .toString() + .padStart(2, "0")}`; return `${day} ${time}`; }; @@ -300,26 +303,29 @@ const SchedulePage = () => { const schedule = schedules.find((s) => s.time_indices.includes(slotIndex)); const isSelected = selectedSlots.includes(slotIndex); - const isFirstSlot = schedule && + const isFirstSlot = + schedule && !schedule.time_indices.includes(slotIndex - 1) && Math.floor((slotIndex - 1) / 96) === Math.floor(slotIndex / 96); - const isLastSlot = schedule && + const isLastSlot = + schedule && !schedule.time_indices.includes(slotIndex + 1) && Math.floor((slotIndex + 1) / 96) === Math.floor(slotIndex / 96); return ( <div key={slotIndex} - className={`p-2 border ${schedule - ? `${getColorForTitle(schedule.title)} text-white - ${!isFirstSlot && !isLastSlot ? 'border-t-0 border-b-0' : ''} - ${!isFirstSlot ? 'border-t-0' : ''} - ${!isLastSlot ? 'border-b-0' : ''}` - : isSelected + className={`p-2 border ${ + schedule + ? `${getColorForTitle(schedule.title)} text-white + ${!isFirstSlot && !isLastSlot ? "border-t-0 border-b-0" : ""} + ${!isFirstSlot ? "border-t-0" : ""} + ${!isLastSlot ? "border-b-0" : ""}` + : isSelected ? "bg-primary-100 border-primary-300" : "bg-grayscale-50" - } cursor-pointer`} + } cursor-pointer`} onClick={() => handleSlotClick(slotIndex)} > {isFirstSlot ? schedule?.title : ""} @@ -336,9 +342,9 @@ const SchedulePage = () => { <div className="min-h-screen bg-grayscale-50"> {/* Toggle View/Edit Mode */} <div className="flex items-center justify-between p-4 bg-white shadow"> - <h1 className="heading-1">Schedule</h1> + <h1 className="heading-2">내 시간표</h1> <label className="flex items-center space-x-3 cursor-pointer"> - <span className="title-1 text-primary-500">Edit Mode</span> + <span className="title-1 text-primary-500">수정 모드</span> <div className={`relative w-12 h-6 rounded-full transition-colors ${ isEditMode ? "bg-primary-500" : "bg-grayscale-300" @@ -360,14 +366,14 @@ const SchedulePage = () => { {/* 더보기 버튼 */} <div className="flex justify-center mt-4"> - <Label - theme="indigo" - size="lg" - className="cursor-pointer" + <Button + theme="white" + size="sm" + className="w-full mx-4 hover:bg-grayscale-50" onClick={() => setShowAllTimeSlot(!showAllTimeSlot)} > {showAllTimeSlot ? "시간 접기" : "전체 시간 보기"} - </Label> + </Button> </div> {/* Schedule Grid */} @@ -379,7 +385,10 @@ const SchedulePage = () => { Time </div> {days.map((day) => ( - <div key={day} className="p-2 font-bold text-center select-none bg-grayscale-200"> + <div + key={day} + className="p-2 font-bold text-center select-none bg-grayscale-200" + > {day} </div> ))} @@ -406,7 +415,7 @@ const SchedulePage = () => { {/* Sticky Container in Edit Mode */} {isEditMode && ( - <div className="fixed bottom-0 right-0 flex items-center justify-center w-full z-10"> + <div className="fixed bottom-0 right-0 z-10 flex items-center justify-center w-full"> <div className="transform transition-transform w-full max-w-[768px] tablet:rounded-2xl bg-primary-100/90 backdrop-blur-sm p-6 text-center shadow-lg"> {selectedSlots.length === 0 && selectedSchedule ? ( <div className="flex flex-col items-center justify-center w-full"> @@ -458,35 +467,50 @@ const SchedulePage = () => { type="text" value={newTitle} onChange={(e) => setNewTitle(e.target.value)} - placeholder="Enter title" - className="w-full p-2 mb-4 border rounded shadow-input-box" + placeholder="스케줄 제목" + className="w-full p-2 px-4 mb-4 border rounded-full shadow-input-box" /> <div className="flex items-center justify-center mb-4 space-x-4"> - <label className="flex items-center space-x-2"> - <input - type="radio" - name="is_fixed" - value={true} - checked={isFixed === true} - onChange={() => setIsFixed(true)} - /> - <span className="body-1">고정 스케줄</span> - </label> - <label className="flex items-center space-x-2"> - <input - type="radio" - name="is_fixed" - value={false} - checked={isFixed === false} - onChange={() => setIsFixed(false)} - /> - <span className="body-1">유동 스케줄</span> - </label> + <div className="flex items-center space-x-4"> + <label className="flex items-center cursor-pointer"> + <input + type="radio" + name="is_fixed" + value={true} + checked={isFixed === true} + onChange={() => setIsFixed(true)} + className="hidden peer" + /> + <div className="flex items-center justify-center w-5 h-5 border-2 border-gray-400 rounded-full peer-checked:border-tertiary-500 peer-checked:bg-tertiary-500"> + <div className="w-2.5 h-2.5 bg-white rounded-full peer-checked:bg-white"></div> + </div> + <span className="ml-2 text-sm font-medium peer-checked:text-tertiary-500"> + 고정 스케줄 + </span> + </label> + + <label className="flex items-center cursor-pointer"> + <input + type="radio" + name="is_fixed" + value={false} + checked={isFixed === false} + onChange={() => setIsFixed(false)} + className="hidden peer" + /> + <div className="flex items-center justify-center w-5 h-5 border-2 border-gray-400 rounded-full peer-checked:border-primary-500 peer-checked:bg-primary-500"> + <div className="w-2.5 h-2.5 bg-white rounded-full peer-checked:bg-white"></div> + </div> + <span className="ml-2 text-sm font-medium peer-checked:text-primary-500"> + 유동 스케줄 + </span> + </label> + </div> </div> - <div className="mb-4 body-1"> - <span>선택된 시간:</span> + <span className="heading-4">선택된 시간</span> + <div className="flex flex-wrap gap-1 p-2 m-2 border rounded-lg body-1 border-primary-500"> {selectedSlots.map((time_idx) => ( - <Label key={time_idx} theme="indigo" size="sm"> + <Label key={time_idx} theme="solid" size="sm"> {convertIndexToTime(time_idx)} </Label> ))} @@ -499,19 +523,23 @@ const SchedulePage = () => { 수정 완료 </button> ) : ( - <div className="flex justify-center mt-4 space-x-4"> - <button - className="px-4 py-2 font-bold text-white rounded bg-tertiary-900" + <div className="flex justify-center w-full mt-4 space-x-2"> + <Button + theme="indigo" + size="md" + className="flex-1" onClick={() => handleCancelSchedule()} > 취소 - </button> - <button - className="px-4 py-2 font-bold text-white rounded bg-gradient-pink" + </Button> + <Button + theme="pink" + size="md" + className="flex-1" onClick={() => handleCreateSchedule()} > 추가 - </button> + </Button> </div> )} </>