Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ Desktop.ini
yarn.lock
package-lock.json
pnpm-lock.yaml
vercel.json

# Parcel, Rollup, and Webpack files
.cache/
Expand Down
31 changes: 31 additions & 0 deletions api/proxy/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
export default async function handler(req) {
const backendURL = `${process.env.VITE_BASE_URL}${req.url.replace("/api/proxy", "/api")}`;

try {
const response = await fetch(backendURL, {
method: req.method,
headers: {
...Object.fromEntries(req.headers), // 모든 원본 헤더 전달
host: new URL(process.env.VITE_BASE_URL).host, // 백엔드 호스트로 변경
},
body: ["GET", "HEAD"].includes(req.method) ? null : await req.text(), // GET, HEAD는 body 제거
});

return new Response(response.body, {
status: response.status,
headers: {
...Object.fromEntries(response.headers), // 응답 헤더 유지
"Access-Control-Allow-Origin": "*", // CORS 문제 해결
},
});
} catch (error) {
return new Response(JSON.stringify({ error: "Proxy request failed", details: error.message }), {
status: 500,
headers: { "Content-Type": "application/json" },
});
}
}

export const config = {
runtime: "edge",
};
4 changes: 4 additions & 0 deletions public/images/main/Calendar.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions public/images/main/history.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions public/images/main/historyactive.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions public/images/main/house.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions public/images/main/houseactive.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions public/images/main/my.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions public/images/main/myactive.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions public/images/main/warning.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 16 additions & 2 deletions src/components/common/choicemodal/ChoiceModal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,26 @@ export const ChoiceModal = ({ type, onClose, ContentTitle, ContentSemiTitle, Con
>
<S.TouchWrap />
<S.ModalContent>
{/* <S.Icon24 src={modalX}/> */}
<S.Icon24 src={modalX} onClick={onClose}/>

{type===1 &&<S.thinkEmoji src={ApplySuccess}/>}
{type===2 &&<S.thinkEmoji src={tryStart}/>}
{type===3 &&<S.thinkEmoji src={tryStart} $Type={type}/>}
{type===4 &&<S.thinkEmoji src={tryStart} $Type={type}/>}
{ContentTitle && <S.Title>{ContentTitle}</S.Title>}
{ContentSemiTitle && <S.SemiTitle>{ContentSemiTitle}</S.SemiTitle>}
{ContentSemiTitle && (
<S.TextWrap>
{Array.isArray(ContentSemiTitle) ? (
ContentSemiTitle.map((line, index) => (
<S.SemiTitle key={index}>{line}</S.SemiTitle>
))
) : (
ContentSemiTitle.split("\n").map((line, index) => (
<S.SemiTitle key={index}>{line}</S.SemiTitle>
))
)}
</S.TextWrap>
)}
{ContentContent && (
<>
{Array.isArray(ContentContent) ? (
Expand Down
14 changes: 13 additions & 1 deletion src/components/common/choicemodal/styled.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ export const Icon24 = styled.img`

export const thinkEmoji = styled.img`
width: 61px;

margin-bottom: ${({ $Type }) => ($Type===3) ? "1rem" : "0"};
`;

export const Title = styled.div`
Expand All @@ -54,10 +56,16 @@ export const Title = styled.div`
margin-bottom: 0.5rem;
`;

export const TextWrap = styled.div`
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 0.5rem;
`;

export const SemiTitle = styled.div`
${({ theme }) => theme.fonts.PretendardR}
font-size: 16px;
margin-bottom: 0.5rem;
`;

export const Contents = styled.div`
Expand Down Expand Up @@ -105,4 +113,8 @@ export const RightButton = styled.div`
background-color: ${({ theme }) => theme.colors.black};

cursor: pointer;
`;

export const DateWrap = styled.div`
display: flex;
`;
25 changes: 24 additions & 1 deletion src/components/layout/footer/mainfooter/MainFooter.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,32 @@
import * as S from "./styled";
import { useLocation } from "react-router-dom";
import useCustomNavigate from "@hooks/useCustomNavigate";

import house from "/images/main/house.svg";
import history from "/images/main/history.svg";
import my from "/images/main/my.svg";
import houseactive from "/images/main/houseactive.svg";
import historyactive from "/images/main/historyactive.svg";
import myactive from "/images/main/myactive.svg";

export const MainFooter = () => {
const location = useLocation();
const { goToPage } = useCustomNavigate();
return (
<S.Wrapper>

<S.ImageWrap>
<S.IconBox onClick={() => goToPage("/history")} $isActive={location.pathname === "/history"}>
<S.Icon36 src={location.pathname === "/history" ? historyactive : history} />
</S.IconBox>

<S.IconBox onClick={() => goToPage("/main")} $isActive={location.pathname === "/main"}>
<S.Icon36 src={location.pathname === "/main" ? houseactive : house} />
</S.IconBox>

<S.IconBox onClick={() => goToPage("/mypage")} $isActive={location.pathname === "/mypage"}>
<S.Icon36 src={location.pathname === "/mypage" ? myactive : my} />
</S.IconBox>
</S.ImageWrap>
</S.Wrapper>
)
}
34 changes: 31 additions & 3 deletions src/components/layout/footer/mainfooter/styled.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,39 @@
import styled from "styled-components";

export const Wrapper = styled.div`
position: absolute;
position: relative;
width: 100%;
height: 100px;
left: 0;
bottom: 0;

display: flex;
width: 100%;
height: 83px;
justify-content: center;
align-items: center;

background: ${({ theme }) => theme.colors.white};
box-shadow: 0px -4px 4px 0px rgba(0, 0, 0, 0.05);
`;

export const ImageWrap = styled.div`
display: flex;
width: 85%;
justify-content: space-between;
`;

export const IconBox = styled.div`
display: flex;
width: 32%;
height: 50px;

border-radius: 65px;
justify-content: center;
align-items: center;

background-color: ${({ theme, $isActive }) => $isActive ? theme.colors.black : theme.colors.lightbluegray};
cursor: pointer;
`;

export const Icon36 = styled.img`
width: 36px;
`;
70 changes: 24 additions & 46 deletions src/hooks/useSelect.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,42 +7,6 @@ const getTodayDate = () => {
return today.toISOString().split("T")[0];
};

const mockCardData = [
{
id: 1,
emoji: "🏔️",
title: "한라산 등반하기",
description: "한라산 정상까지 등반하며 자연을 느껴보세요.",
extra: [
{ id: 101, title: "등산 준비물", content: "나는 등산 짱 ㅋㅋ" },
{ id: 102, title: "소요 시간", content: "소요" }
],
backgroundColor: "#F9FFD6"
},
{
id: 2,
emoji: "📖",
title: "도서관에서 독서하기",
description: "조용한 도서관에서 책을 읽으며 집중하는 시간을 가져봐요.",
extra: [
{ id: 201, title: "추천 도서 목록", content: "도서" },
{ id: 202, title: "독서 시간", content: "시간" }
],
backgroundColor: "#FFE7E7"
},
{
id: 3,
emoji: "🍳",
title: "요리 도전하기",
description: "새로운 레시피로 요리에 도전해보세요.",
extra: [
{ id: 301, title: "필요한 재료", content: "필요한" },
{ id: 302, title: "조리법", content: "조리법" }
],
backgroundColor: "#D5DDFF"
}
];

export const useSelect = () => {
const { goToPage } = useCustomNavigate();

Expand All @@ -61,10 +25,25 @@ export const useSelect = () => {
const [endDate, setEndDate] = useState(getTodayDate());

useEffect(() => {
const shuffled = mockCardData.sort(() => 0.5 - Math.random()).slice(0, 3);
setCards(shuffled);
setSelectedCard(shuffled[1]);
setFlipped(new Array(shuffled.length).fill(false));
const fetchCards = async () => {
try {
// 1. 랜덤 카드 3장 조회
const randomResponse = await SelectService.getRandomCards();
if (!randomResponse.success) throw new Error(randomResponse.message);

// 2. 조회된 cardIds를 이용하여 개별 카드 정보 요청
const cardDetailsPromises = randomResponse.cardIds.map(id => SelectService.getCardById(id).then((card) => ({ ...card, id })));
const cardDetails = await Promise.all(cardDetailsPromises);

setCards(cardDetails);
setSelectedCard(cardDetails[1]); // 기본 선택 카드 설정
setFlipped(new Array(cardDetails.length).fill(false)); // 카드 뒷면 초기화
} catch (error) {
console.error("🚨 카드 불러오기 실패:", error);
}
};

fetchCards();
}, []);

const goToNextStep = () => setStep((prev) => prev + 1);
Expand Down Expand Up @@ -121,14 +100,13 @@ export const useSelect = () => {
}

const requestData = {
emoji: selectedCard.emoji,
title: selectedCard.title,
description: selectedCard.description,
cardId: selectedCard.id,
cover: selectedCard.cover,
startDate,
endDate,
extra: extraInputs,
backgroundColor: selectedBackgroundColor
endDate
};

console.log("✅ 보낼 데이터:", requestData);

try {
await SelectService.submitExperience(requestData);
Expand Down
Loading
Loading