Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

5.1. 저장한 관광지/경로 목록 페이지 #30

Merged
merged 24 commits into from
Aug 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
937bac0
feat: myTripPage Router 추가
seondy Aug 13, 2024
8120d59
feat: myTripPage 마크업
seondy Aug 13, 2024
2172314
feat: myTripPage 마크업 추가 수정 #24
seondy Aug 13, 2024
409052d
feat: TabButton Style 분리 및 퍼블리싱 #24
seondy Aug 13, 2024
9e213e1
style: 공통 컴포넌트 Button Style 변경
seondy Aug 13, 2024
d6fb3c3
feat: AttractionItem Props 추가
seondy Aug 13, 2024
d34d88c
style: 5.1.1. 저장한 관광지 목록 페이지 퍼블리싱 #24
seondy Aug 13, 2024
dc5db13
style: maxWidth theme 추가
seondy Aug 14, 2024
698f7b0
style: delete icon svg 추가
seondy Aug 14, 2024
cb8d2c7
style: 5.1.2. 저장한 경로 목록 페이지 퍼블리싱 #24
seondy Aug 14, 2024
1c94ec8
style: global style max-width theme 변경
seondy Aug 14, 2024
84a3c1b
fix: 기존 Modal TempModal 변경
seondy Aug 14, 2024
0693cff
style: fixed width 대응 max-width 설정 변경
seondy Aug 14, 2024
c50bff0
feat: Modal 컴포넌트 생성 및 마크업 #25
seondy Aug 14, 2024
f98e3b6
style: AttractionItem Hover 스타일 + 불필요 여백 제거
seondy Aug 14, 2024
04d3bff
style: navigationbar homePage에 추가
seondy Aug 14, 2024
1b92580
feat: NavigationBar Routing 페이지 변경
seondy Aug 14, 2024
8797073
style: BackNaviBtn cursor pointer 변경
seondy Aug 14, 2024
ba6c9b2
fix: util line-height 오타 수정
seondy Aug 14, 2024
23842e5
style: Button 컴포넌트 기본 설정 변경
seondy Aug 14, 2024
d96f5e0
style: 공통 컴포넌트 - PopUp (Modal) 컴포넌트 퍼블리싱 #25
seondy Aug 14, 2024
e4e3080
refactor: 대체 텍스트 변경
seondy Aug 14, 2024
707cff3
feat: 공통 컴포넌트 - PopUp (Modal) 컴포넌트 테스트 #25
seondy Aug 14, 2024
23e89ca
Merge pull request #29 from gamgyul-code/feat/commonModal
seondy Aug 15, 2024
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
8 changes: 8 additions & 0 deletions gamgyul-front/public/images/Icon/delete.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions gamgyul-front/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import LocationFormPage from "./pages/LocationFormPage";
import { GlobalStyles } from "./style/global";
import { LanguageProvider } from "./contexts/LanguageContext"; // LanguageProvider 추가
import AttractionListPage from "./pages/AttractionListPage";
import MyTripPage from "./pages/MyTripPage";
function App() {
return (
<LanguageProvider>
Expand All @@ -24,6 +25,7 @@ function App() {
<Route path="/map" element={<MapPage />} />
<Route path="/complete" element={<CompletePage />} />
<Route path="/attractions/:id" element={<AttractionListPage />} />
<Route path="/trip" element={<MyTripPage />} />

{/* 추가 페이지 (임시) */}
<Route path="/theme" element={<ThemeFormPage />} />
Expand Down
84 changes: 44 additions & 40 deletions gamgyul-front/src/components/common/AttractionItem/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,8 @@ import { useEffect, useState } from "react";
import { applyFontStyles } from "../../../utils/fontStyles";

/** 관광지 아이템 컴포넌트 (분리 필요) */
const AttractionItem = ({ isChecked, onCheckChange }) => {
const AttractionItem = ({ onDelete, isChecked, onCheckChange, type }) => {
const [bookmark, setBookmark] = useState("off");
const [isModal, setIsModal] = useState(false);
// const type = "DELETE";
// const type = "CHECK";
const type = "BASIC";

useEffect(() => {}, []);

Expand All @@ -27,40 +23,37 @@ const AttractionItem = ({ isChecked, onCheckChange }) => {
console.log("임시 체크박스 클릭 핸들러입니다.");
};

/** 삭제 버튼 클릭 => 이후 추가 */
const handleDeleteClick = () => {
console.log("삭제 버튼을 클릭했습니다.");
};

return (
<AtrctItemContainer>
<AtrctItemInfo>
{type === "CHECK" && (
<StyledCheckBtn>
<img src={`/images/Icon/check_${bookmark}.svg`} alt="북마크버튼" onClick={() => handleCheckClick()} />
</StyledCheckBtn>
<AtrctItemContents>
<AtrctItemInfo>
{type === "CHECK" && (
<StyledCheckBtn>
<img src={`/images/Icon/check_${bookmark}.svg`} alt="체크버튼" onClick={() => handleCheckClick()} />
</StyledCheckBtn>
)}
<figure>
<img src="" alt="관광지 이미지" />
<figcaption>
<h3>리스트이름</h3>
<p>리스트내용</p>
</figcaption>
</figure>
</AtrctItemInfo>
{type === "DELETE" ? (
<StyledIconBtn>
<img src={`/images/Icon/delete.svg`} alt="삭제버튼" onClick={onDelete} />
</StyledIconBtn>
) : (
<StyledIconBtn>
<img
src={`/images/Icon/bookmark_${bookmark}.svg`}
alt="북마크버튼"
onClick={() => handleBookmarkClick(bookmark)}
/>
</StyledIconBtn>
)}
<figure>
<img src="" alt="관광지 이미지" />
<figcaption>
<h3>리스트이름</h3>
<p>리스트내용</p>
</figcaption>
</figure>
</AtrctItemInfo>
{type === "DELETE" ? (
<StyledIconBtn>
<img src={`/images/Icon/delete.svg`} alt="삭제버튼" onClick={() => handleDeleteClick()} />
</StyledIconBtn>
) : (
<StyledIconBtn>
<img
src={`/images/Icon/bookmark_${bookmark}.svg`}
alt="북마크버튼"
onClick={() => handleBookmarkClick(bookmark)}
/>
</StyledIconBtn>
)}
</AtrctItemContents>
</AtrctItemContainer>
);
};
Expand Down Expand Up @@ -91,20 +84,30 @@ const AtrctItemInfo = styled.section`
}
`;

/** 관광지 아이템 컴포넌트 스타일링 */
const AtrctItemContainer = styled.li`
const AtrctItemContents = styled.li`
width: 100%;
height: 90px;
border-bottom: 1px solid ${theme.color.sub2};
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid ${theme.color.sub2};
`;

/** 관광지 아이템 컴포넌트 스타일링 */
const AtrctItemContainer = styled.div`
padding: 0 20px;

&:hover {
background: #1eb17b0d;
}
`;

const StyledIconBtn = styled.button`
width: 24px;
height: 24px;
border: none;
background-color: inherit;
cursor: pointer;
`;

const StyledCheckBtn = styled.button`
Expand All @@ -114,8 +117,9 @@ const StyledCheckBtn = styled.button`
background-color: inherit;
margin-right: 16px;
& > img {
cursor: pointer;
width: 100%;
hegiht: 100%;
height: 100%;
}
`;

Expand Down
1 change: 1 addition & 0 deletions gamgyul-front/src/components/common/BackNaviBtn/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const StyledBackBtn = styled.button`
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;

width: 50px;
height: 50px;
Expand Down
13 changes: 13 additions & 0 deletions gamgyul-front/src/components/common/Button/TabButton.style.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import styled from "styled-components";
import { theme } from "../../../style/theme";
import { applyFontStyles } from "../../../utils/fontStyles";

export const TabButton = styled.button`
${({ fontSize }) => applyFontStyles(fontSize)}
background-color: inherit;
width: ${({ btnCnt }) => (btnCnt ? `${100 / btnCnt}%` : "auto")};
height: 48px;
border: none;
border-bottom: 3px solid ${({ isActive }) => (isActive ? theme.color.primary : theme.color.gray3)};
color: ${({ isActive }) => !isActive && theme.color.gray2};
`;
24 changes: 17 additions & 7 deletions gamgyul-front/src/components/common/Button/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,32 @@ import styled from "styled-components";
import { theme } from "../../../style/theme";
import { applyFontStyles } from "../../../utils/fontStyles";

const Button = ({ type, size, onClick, children, color, className, disabled, ...props }) => {
const Button = ({ type, size, onClick, children, color, className, disabled, isShadow, ...props }) => {
return (
<StyledButton type={type} size={size} onClick={onClick} color={color} className={className} disabled={disabled}>
<StyledButton
type={type}
size={size}
onClick={onClick}
color={color}
className={className}
disabled={disabled}
isShadow={isShadow}
>
{children}
</StyledButton>
);
};

const StyledButton = styled.button`
${applyFontStyles(theme.font.body1)}
${applyFontStyles(theme.font.body2)}
width: 100%;
height: ${({ type }) => (type === "small" ? "40px" : "64px")};
border-radius: 10px;
height: ${({ type }) => (type === "small" ? "42px" : "55px")};
border-radius: ${({ type }) => (type === "small" ? "10px" : "20px")};
border: 0;
cursor: ${({ disabled }) => (disabled ? "not-allowed" : "pointer")};
background-color: ${({ disabled }) => (disabled ? theme.color.grayscale_BF : theme.color.primary)};
color: ${theme.color.white};
background-color: ${({ disabled, color }) =>
disabled ? theme.color.gray2 : color === "gray" ? theme.color.white : theme.color.primary};
color: ${({ color }) => (color === "gray" ? theme.color.gray2 : theme.color.white)};
box-shadow: ${({ isShadow }) => (isShadow ? "0px 2px 2px 0px #00000033" : "none")};
`;
export default Button;
136 changes: 87 additions & 49 deletions gamgyul-front/src/components/common/Modal/index.jsx
Original file line number Diff line number Diff line change
@@ -1,73 +1,111 @@
import { StyledBody2Gray } from "../../../pages/MapDetailPage";
import { useState } from "react";
import styled from "styled-components";
import { theme } from "../../../style/theme";
import Button from "../Button";
import { styled } from "styled-components";
import { Link } from "react-router-dom";
import { applyFontStyles } from "../../../utils/fontStyles";
import Button from "../Button";

const Modal = ({ onClose, onClick, type }) => {
const [routeValue, setRouteValue] = useState("");
const isSaveButtonDisabled = type === "SAVE" && routeValue.trim() === "";
// 경로 삭제일 때 : 확인 => 경로 삭제 api 요청 / 취소 => 모달 닫기
// 경로 저장일 때 : 확인 => 경로 저장 api 요청 / 취소 => 모달 닫기

const Modal = ({ onClose }) => {
return (
<StyledOverlay>
<StyledModal>
<StyledBody1Text>You got a stamp!</StyledBody1Text>
<StyledStampWrap>
<img src="images/Stamp/stamp.svg" />
<StyledBody2Gray>영실기암</StyledBody2Gray>
</StyledStampWrap>
<Link to="/complete">
<Button type="small" onClick={onClose}>
Next
</Button>
</Link>
</StyledModal>
</StyledOverlay>
<ModalOverlayContainer>
<ModalContents>
{type === "DELETE" && <ModalDeleteH2>경로를 삭제 하시겠어요?</ModalDeleteH2>}
{type === "SAVE" && (
<ModalRoutesSection>
<h2>경로 이름</h2>
<p>경로를 저장하려면 이름이 필요합니다.</p>
<StyledInputBox
type="text"
id="route-input"
value={routeValue}
placeholder="이름을 입력해주세요."
onChange={(event) => setRouteValue(event.target.value)}
/>
</ModalRoutesSection>
)}
<div>
<StyledModalBtn type="small" onClick={onClose} color="gray">
취소
</StyledModalBtn>
<StyledModalBtn type="small" onClick={() => onClick(routeValue)} disabled={isSaveButtonDisabled}>
확인
</StyledModalBtn>
</div>
</ModalContents>
</ModalOverlayContainer>
);
};

/** body1 텍스트 스타일링 */
export const StyledBody1Text = styled.span`
${applyFontStyles(theme.font.body1)}
const ModalDeleteH2 = styled.h2`
width: 100%;
padding: 0 8px;
margin-top: 80px;
box-sizing: border-box;
text-align: center;
`;

/** 오버레이 스타일링 */
const StyledOverlay = styled.div`
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.3);
const ModalOverlayContainer = styled.div`
position: fixed;
height: 100%;
width: 100%;
max-width: ${theme.maxWidth};
display: flex;
justify-content: center;
align-items: center;
z-index: 999;
z-index: 9999;
background: #00000066;
`;

/** 모달 스타일링 */
const StyledModal = styled.div`
margin: 0 auto;
text-align: center;
width: 300px;
height: 300px;
padding: 20px;
border-radius: 10px;
const ModalContents = styled.div`
width: 100%;
min-height: 252px;
border-radius: 20px;
padding: 14px 16px;
box-sizing: border-box;
box-shadow: 0px 2px 10px 0px #0000001a;
max-width: calc(${theme.maxWidth} - 88px);
background-color: ${theme.color.white};
box-shadow: 0px 3.39px 16.94px 0px #0000001a;

display: flex;
flex-direction: column;
justify-content: space-between;

h2 {
${applyFontStyles(theme.font.subtitle)}
}

Button:last-child {
margin-right: 0;
}
`;

const StyledStampWrap = styled.div`
display: flex;
flex-direction: column;
align-items: center;
const StyledModalBtn = styled(Button)`
width: calc(50% - 4px);
margin-right: 8px;
`;

const ModalRoutesSection = styled.section`
margin: 10px 8px;
p {
${applyFontStyles(theme.font.body3)}
margin: 4px 0 28px 0;
}
`;

const StyledInputBox = styled.input`
${applyFontStyles(theme.font.body2)}
width: 100%;
height: 42px;
border: none;
border-bottom: 1px solid ${theme.color.primary};
box-sizing: border-box;
padding: 10px;

*:nth-child(1) {
width: 128px;
height: 128px;
margin-bottom: 8px;
&::placeholder {
color: ${theme.color.gray2};
}
`;

Expand Down
Loading