diff --git a/front/src/pages/diet/api.js b/front/src/pages/diet/api.js index 2805e94a53e796894dab92c728f480185c41e0e7..993a1568b264f0e6943ef75d12981159f02b0126 100644 --- a/front/src/pages/diet/api.js +++ b/front/src/pages/diet/api.js @@ -24,6 +24,7 @@ const getDietData = async (date = null, start_date = null, end_date = null) => { method: 'GET', headers: { 'Content-Type': 'application/json', + 'Authorization': `Bearer ${localStorage.getItem('accessToken')}` }, }); }; @@ -33,10 +34,11 @@ const getUserData = async (fields = []) => { if (fields.length > 0) { queryParams.append('fields', fields.join(',')); } - return await fetchWithOptions(`api/user/profile?${queryParams.toString()}`), { + return await fetchWithOptions(`api/user/profile?${queryParams.toString()}`), { method: 'GET', headers: { 'Content-Type': 'application/json', + 'Authorization': `Bearer ${localStorage.getItem('accessToken')}` }, }; } @@ -46,6 +48,7 @@ const createDiet = async ({ date, mealtime, food_id, grams }) => { method: 'POST', headers: { 'Content-Type': 'application/json', + 'Authorization': `Bearer ${localStorage.getItem('accessToken')}` }, body: JSON.stringify({ date, mealtime, food_id, grams }), }); @@ -56,6 +59,7 @@ const deleteDiet = async ({ date, mealtime, food_id }) => { method: 'DELETE', headers: { 'Content-Type': 'application/json', + 'Authorization': `Bearer ${localStorage.getItem('accessToken')}` }, body: JSON.stringify({ date, mealtime, food_id }), }); diff --git a/front/src/pages/routine/progress.css b/front/src/pages/routine/Progress.css similarity index 100% rename from front/src/pages/routine/progress.css rename to front/src/pages/routine/Progress.css diff --git a/front/src/pages/routine/progress.jsx b/front/src/pages/routine/Progress.jsx similarity index 100% rename from front/src/pages/routine/progress.jsx rename to front/src/pages/routine/Progress.jsx diff --git a/front/src/pages/routine/video.jsx b/front/src/pages/routine/Video.jsx similarity index 97% rename from front/src/pages/routine/video.jsx rename to front/src/pages/routine/Video.jsx index 411539f8efd58641e8578d38ee9fa21f9254800c..381d28d321694a5025f5c3d70d38417c9f73d79a 100644 --- a/front/src/pages/routine/video.jsx +++ b/front/src/pages/routine/Video.jsx @@ -1,125 +1,125 @@ -import React, { useState, useEffect, useRef } from "react"; -import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd"; -import truncateText from './truncateText'; -import "./Video.css"; - -function Video({ - routine, - onRoutineChange, - onVideoClick, - isActive, - currentIndex, - isRest, - restSeconds, -}) { - const [exercises, setExercises] = useState(routine.exercises); // 루틴 운동 목록 - const [isDragging, setIsDragging] = useState(false); // 드래그 여부 - const videoRefs = useRef([]); - - useEffect(() => { - setExercises(routine.exercises); - }, [routine]); - - /* - 운동 변경시 해당 운동 화면 중앙으로 위치 - */ - useEffect(() => { - const targetIndex = isRest ? currentIndex - 1 : currentIndex; - if (videoRefs.current[targetIndex]) { - videoRefs.current[targetIndex].scrollIntoView({ - behavior: "smooth", - block: "center", - }); - } - - }, [currentIndex, isRest]); - - const handleDragStart = () => { - setIsDragging(true); - }; - - /* - 드래그 종료시 드래그 한 블록을 놓은 위치로 순서 변경 - 선택한 블록을 updateExercises에서 제거하여 movedItem에 저장 - moveItem을 놓은 위치에 삽입하여 Exercises로 최종 업데이트 - */ - const handleDragEnd = (result) => { - setIsDragging(false); - - if (!result.destination) return; - - const updatedExercises = Array.from(exercises); - const [movedItem] = updatedExercises.splice(result.source.index, 1); - updatedExercises.splice(result.destination.index, 0, movedItem); - setExercises(updatedExercises); - onRoutineChange(updatedExercises); - }; - - /* - 운동 클릭시 해당 영상 링크 오픈 - */ - const handleVideoClick = (exercise) => { - window.open(exercise.link, "_blank", "noopener,noreferrer"); - onVideoClick(exercise); - }; - - return ( - <DragDropContext onDragStart={handleDragStart} onDragEnd={handleDragEnd}> - <Droppable droppableId="video-list"> - {(provided) => ( - <div - id="video-container" - ref={provided.innerRef} - {...provided.droppableProps} - > - {exercises.map((exercise, index) => ( - <React.Fragment key={exercise.title}> - <Draggable - draggableId={exercise.title} - index={index} - isDragDisabled={isActive} - > - {(provided) => ( - <div - ref={(el) => { - provided.innerRef(el); - videoRefs.current[index] = el; - }} - {...provided.draggableProps} - {...provided.dragHandleProps} - onClick={() => handleVideoClick(exercise)} - className={`video-info ${currentIndex === index && !isRest - ? "highlighted" - : "" - }`} - > - <img src={exercise.thumbnail} alt={exercise.title} /> - <div className="video-title">{truncateText(exercise.title, 80)}</div> - </div> - )} - </Draggable> - {index < exercises.length - 1 && ( - <div - className={`rest-period ${currentIndex - 1 === index && isRest - ? "highlighted-rest" - : "" - }`} - style={{ - visibility: isDragging ? "hidden" : "visible", - }} - - > - {restSeconds}초 - Rest Period - </div> - )} - </React.Fragment> - ))} - {provided.placeholder} - </div> - )} - </Droppable> - </DragDropContext> - ); -} - -export default Video; +import React, { useState, useEffect, useRef } from "react"; +import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd"; +import truncateText from './truncateText'; +import "./Video.css"; + +function Video({ + routine, + onRoutineChange, + onVideoClick, + isActive, + currentIndex, + isRest, + restSeconds, +}) { + const [exercises, setExercises] = useState(routine.exercises); // 루틴 운동 목록 + const [isDragging, setIsDragging] = useState(false); // 드래그 여부 + const videoRefs = useRef([]); + + useEffect(() => { + setExercises(routine.exercises); + }, [routine]); + + /* + 운동 변경시 해당 운동 화면 중앙으로 위치 + */ + useEffect(() => { + const targetIndex = isRest ? currentIndex - 1 : currentIndex; + if (videoRefs.current[targetIndex]) { + videoRefs.current[targetIndex].scrollIntoView({ + behavior: "smooth", + block: "center", + }); + } + + }, [currentIndex, isRest]); + + const handleDragStart = () => { + setIsDragging(true); + }; + + /* + 드래그 종료시 드래그 한 블록을 놓은 위치로 순서 변경 + 선택한 블록을 updateExercises에서 제거하여 movedItem에 저장 + moveItem을 놓은 위치에 삽입하여 Exercises로 최종 업데이트 + */ + const handleDragEnd = (result) => { + setIsDragging(false); + + if (!result.destination) return; + + const updatedExercises = Array.from(exercises); + const [movedItem] = updatedExercises.splice(result.source.index, 1); + updatedExercises.splice(result.destination.index, 0, movedItem); + setExercises(updatedExercises); + onRoutineChange(updatedExercises); + }; + + /* + 운동 클릭시 해당 영상 링크 오픈 + */ + const handleVideoClick = (exercise) => { + window.open(exercise.link, "_blank", "noopener,noreferrer"); + onVideoClick(exercise); + }; + + return ( + <DragDropContext onDragStart={handleDragStart} onDragEnd={handleDragEnd}> + <Droppable droppableId="video-list"> + {(provided) => ( + <div + id="video-container" + ref={provided.innerRef} + {...provided.droppableProps} + > + {exercises.map((exercise, index) => ( + <React.Fragment key={exercise.title}> + <Draggable + draggableId={exercise.title} + index={index} + isDragDisabled={isActive} + > + {(provided) => ( + <div + ref={(el) => { + provided.innerRef(el); + videoRefs.current[index] = el; + }} + {...provided.draggableProps} + {...provided.dragHandleProps} + onClick={() => handleVideoClick(exercise)} + className={`video-info ${currentIndex === index && !isRest + ? "highlighted" + : "" + }`} + > + <img src={exercise.thumbnail} alt={exercise.title} /> + <div className="video-title">{truncateText(exercise.title, 80)}</div> + </div> + )} + </Draggable> + {index < exercises.length - 1 && ( + <div + className={`rest-period ${currentIndex - 1 === index && isRest + ? "highlighted-rest" + : "" + }`} + style={{ + visibility: isDragging ? "hidden" : "visible", + }} + + > + {restSeconds}초 - Rest Period + </div> + )} + </React.Fragment> + ))} + {provided.placeholder} + </div> + )} + </Droppable> + </DragDropContext> + ); +} + +export default Video;