Skip to content

Commit

Permalink
Merge branch 'develop/fe' of https://github.com/woowacourse-teams/202…
Browse files Browse the repository at this point in the history
…4-touroot into fix/fe/#563
  • Loading branch information
0jenn0 committed Oct 23, 2024
2 parents d8244a2 + 0b3b3ee commit 3ee5e5e
Show file tree
Hide file tree
Showing 99 changed files with 2,388 additions and 431 deletions.
2 changes: 1 addition & 1 deletion frontend/cypress/e2e/mainPage.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ describe("메인 페이지 테스트", () => {
});
}).as("getTravelogues");

cy.visit(ROUTE_PATHS_MAP.root);
cy.visit(ROUTE_PATHS_MAP.main);
});

describe("여행기 무한 스크롤 테스트", () => {
Expand Down
2 changes: 1 addition & 1 deletion frontend/cypress/support/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Cypress.Commands.add("simulateKakaoLogin", () => {

cy.wait("@loginOauthRequest");

cy.url().should("eq", `${Cypress.config().baseUrl}${ROUTE_PATHS_MAP.root}`);
cy.url().should("eq", `${Cypress.config().baseUrl}${ROUTE_PATHS_MAP.main}`);
});

Cypress.Commands.add("fillTravelPlanBasicInfo", (title, date) => {
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/apis/interceptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ const handleUserLogout = () => {
export const handleAPIError = async (error: AxiosError<ErrorResponse>) => {
if (
error.response?.status === HTTP_STATUS_CODE_MAP.UNAUTHORIZED &&
error.response.data.message === ERROR_MESSAGE_MAP.api.expiredToken
(error.response.data.message === ERROR_MESSAGE_MAP.api.expiredToken ||
error.response.data.message === ERROR_MESSAGE_MAP.api.invalidToken)
) {
try {
const user: UserResponse | null = JSON.parse(
Expand Down
Binary file added frontend/src/assets/webp/bigTturi.webp
Binary file not shown.
6 changes: 6 additions & 0 deletions frontend/src/assets/webp/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
export { default as ExcitedTturi } from "./excitedTturi.webp";
export { default as BigTturi } from "./bigTturi.webp";
export { default as MainPageImage } from "./mainPage.webp";
export { default as SpeechBubbleLeft } from "./speechBubbleLeft.webp";
export { default as SpeechBubbleRight } from "./speechBubbleRight.webp";
export { default as TravelogueDetailPageImage } from "./travelogueDetailPage.webp";
export { default as travelPlanDetailPageImage } from "./travelPlanDetailPage.webp";
Binary file added frontend/src/assets/webp/mainPage.webp
Binary file not shown.
Binary file added frontend/src/assets/webp/speechBubbleLeft.webp
Binary file not shown.
Binary file added frontend/src/assets/webp/speechBubbleRight.webp
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { css } from "@emotion/react";
import styled from "@emotion/styled";

export const Layout = styled.div`
Expand All @@ -19,3 +20,16 @@ export const TitleContainer = styled.div`
export const Title = styled.h2`
${({ theme }) => theme.typography.mobile.bodyBold}
`;

export const visualHiddenStyle = css`
overflow: hidden;
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
border: 0;
white-space: nowrap;
clip: rect(0, 0, 0, 0);
`;
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,13 @@ const AccordionTrigger = ({ children, onDeleteItem }: AccordionTriggerProps) =>

return (
<S.Layout onClick={() => handleToggleAccordion(label)}>
<div aria-live="assertive" css={S.visualHiddenStyle}>
{isClosed ? "아코디언이 열렸습니다." : "아코디언이 닫혔습니다."}
</div>
<S.TitleContainer>
<button>{isClosed ? <UpArrow /> : <DownArrow />}</button>
<button aria-label={isClosed ? `아코디언 열기` : `아코디언 닫기`}>
{isClosed ? <UpArrow /> : <DownArrow />}
</button>
<S.Title>{children}</S.Title>
</S.TitleContainer>
<IconButton
Expand Down
13 changes: 13 additions & 0 deletions frontend/src/components/common/Calendar/Calendar.styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,16 @@ export const WeekRow = styled.tr`
export const boldTextStyle = css`
font-weight: 700;
`;

export const visualHiddenStyle = css`
overflow: hidden;
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
border: 0;
white-space: nowrap;
clip: rect(0, 0, 0, 0);
`;
53 changes: 47 additions & 6 deletions frontend/src/components/common/Calendar/Calendar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,21 @@ const Calendar = ({
weekdays,
} = useCalendar();

const isPreventPreviousMonthMoveButton = today.getMonth() === calendarDetail.month;

const handleKeyDown = (
event: React.KeyboardEvent<HTMLElement>,
date: Date,
isSelectable: boolean,
) => {
if (event.key === "Enter" || event.key === " ") {
event.preventDefault();
if (isSelectable) {
onSelectDate(date);
}
}
};

return (
<S.Layout ref={calendarRef} {...props}>
<S.HeaderContainer>
Expand All @@ -43,17 +58,30 @@ const Calendar = ({
color={PRIMITIVE_COLORS.white}
iconType="prev-arrow"
onClick={prevMonth}
disabled={today.getMonth() === calendarDetail.month}
disabled={isPreventPreviousMonthMoveButton}
aria-label={"이전 달 이동 버튼"}
data-cy={CYPRESS_DATA_MAP.calendar.previousMonthMoveButton}
/>
<Text textType="detail" css={S.boldTextStyle} data-cy={CYPRESS_DATA_MAP.calendar.headTitle}>
{calendarDetail.year}{calendarDetail.month + 1}

<Text
aria-live="polite"
textType="detail"
css={S.boldTextStyle}
data-cy={CYPRESS_DATA_MAP.calendar.headTitle}
>
{`${calendarDetail.year}${calendarDetail.month + 1}월`}
{isPreventPreviousMonthMoveButton && (
<div aria-live="assertive" css={S.visualHiddenStyle}>
이전 달로 이동하는 버튼을 누를 수 없습니다.
</div>
)}
</Text>
<IconButton
size="12"
color={PRIMITIVE_COLORS.white}
iconType="next-arrow"
onClick={nextMonth}
aria-label="다음 달 이동 버튼"
data-cy={CYPRESS_DATA_MAP.calendar.nextMonthMoveButton}
/>
</S.HeaderContainer>
Expand All @@ -67,15 +95,28 @@ const Calendar = ({
<S.DaysGridContainer>
{calendarDetail.days.map(({ date, isCurrentMonth }) => {
const isSelectable = isCurrentMonth && date >= today;
const formattedDate = date.toLocaleDateString("ko-KR", {
year: "numeric",
month: "long",
day: "numeric",
});

return (
<S.DayCell
key={date.toString()}
$isCurrentMonth={isCurrentMonth}
$isSelectable={isSelectable}
onClick={() => isSelectable && onSelectDate(date)}
onKeyDown={(event) => handleKeyDown(event, date, isSelectable)}
tabIndex={isSelectable ? 0 : -1}
role="gridcell"
aria-selected={isSelectable}
aria-label={formattedDate}
data-cy={CYPRESS_DATA_MAP.calendar.dayCell}
$isCurrentMonth={isCurrentMonth}
$isSelectable={isSelectable}
>
<Text textType="detail">{isCurrentMonth ? date.getDate() : ""}</Text>
<Text tabIndex={-1} aria-hidden="true" textType="detail">
{isCurrentMonth ? date.getDate() : ""}
</Text>
</S.DayCell>
);
})}
Expand Down
2 changes: 0 additions & 2 deletions frontend/src/components/common/Carousel/Carousel.styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@ export const CarouselButton = styled.button`
background-color: rgb(0 0 0 / 50%);
transform: translateY(-50%);
cursor: pointer;
&:first-of-type {
left: 10px;
}
Expand Down
13 changes: 9 additions & 4 deletions frontend/src/components/common/Carousel/Carousel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { useState } from "react";

import { css } from "@emotion/react";

import VisuallyHidden from "@components/common/VisuallyHidden/VisuallyHidden";

import { NextArrow, PrevArrow } from "@assets/svg";

import * as S from "./Carousel.styled";
Expand Down Expand Up @@ -30,25 +32,28 @@ const Carousel = ({ imageUrls }: CarouselProps) => {

return (
<S.CarouselContainer>
<VisuallyHidden aria-live="assertive">{`총 ${imageUrls.length}개 중 ${currentIndex + 1}번째 여행 사진`}</VisuallyHidden>
<S.CarouselImageList css={carouselImageListStyling(currentIndex)}>
{imageUrls.map((imageUrl, index) => (
<S.CarouselImageItem key={imageUrl}>
<img src={imageUrl} alt={`travels place img ${index + 1}`} />
<img src={imageUrl} alt={`${index + 1}번째 여행 사진`} aria-hidden={true} />
</S.CarouselImageItem>
))}
</S.CarouselImageList>
<S.CarouselImageBadge>{`${currentIndex + 1} / ${imageUrls.length}`}</S.CarouselImageBadge>
<S.CarouselImageBadge
aria-hidden={true}
>{`${currentIndex + 1} / ${imageUrls.length}`}</S.CarouselImageBadge>
<S.CarouselButton
onClick={handleClickPrevButton}
aria-label="Previous image"
disabled={isFirstImage}
aria-label="이전 여행 사진"
>
<PrevArrow />
</S.CarouselButton>
<S.CarouselButton
onClick={handleClickNextButton}
aria-label="Next image"
disabled={isLastImage}
aria-label="다음 여행 사진"
>
<NextArrow />
</S.CarouselButton>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import React from "react";

import * as S from "./CharacterCount.styled";

interface CharacterCountProps {
interface CharacterCountProps extends React.ComponentPropsWithoutRef<"div"> {
count?: number;
maxCount?: number;
}

const CharacterCount = ({ count, maxCount }: CharacterCountProps) => {
const CharacterCount = ({ count, maxCount, ...props }: CharacterCountProps) => {
return (
<S.CharacterCountWrapper>
<S.CharacterCountWrapper {...props}>
{count && maxCount ? <S.CharacterCount>{`${count}/${maxCount}`}</S.CharacterCount> : null}
</S.CharacterCountWrapper>
);
Expand Down
8 changes: 7 additions & 1 deletion frontend/src/components/common/Checkbox/Checkbox.styled.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { css } from "@emotion/react";
import styled from "@emotion/styled";

import { PRIMITIVE_COLORS } from "@styles/tokens";
Expand All @@ -6,6 +7,7 @@ export const Layout = styled.label<{ $isChecked: boolean }>`
display: flex;
justify-content: center;
align-items: center;
position: relative;
width: 1.5rem;
height: 1.5rem;
border: ${({ theme, $isChecked }) => ($isChecked ? "none" : `1px solid ${theme.colors.border}`)};
Expand All @@ -16,5 +18,9 @@ export const Layout = styled.label<{ $isChecked: boolean }>`
`;

export const Checkbox = styled.input`
display: none;
opacity: 0;
`;

export const iconStyle = css`
position: absolute;
`;
4 changes: 3 additions & 1 deletion frontend/src/components/common/Checkbox/Checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ const Checkbox = ({
return (
<S.Layout $isChecked={isChecked ?? false}>
<S.Checkbox type="checkbox" {...props} />
{isChecked && <Icon size="15" color={PRIMITIVE_COLORS.white} iconType="check" />}
{isChecked && (
<Icon size="15" color={PRIMITIVE_COLORS.white} iconType="check" css={S.iconStyle} />
)}
</S.Layout>
);
};
Expand Down
1 change: 1 addition & 0 deletions frontend/src/components/common/Dropdown/Dropdown.styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export const Dropdown = styled.div<{ $size: DropdownSize; $position: DropdownPos
${({ $position }) => dropdownPosition[$position]}
${({ $size }) => dropdownSize[$size]}
gap: ${({ theme }) => theme.spacing.m};
z-index: ${({ theme }) => theme.zIndex.dropdown};
padding: 1.6rem;
border: 0.1rem solid ${({ theme }) => theme.colors.border};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ export const Layout = styled.div`
max-width: 48rem;
background-color: ${PRIMITIVE_COLORS.white};
transform: translateX(-3.2rem);
`;

export const StyledInput = styled.input`
Expand Down Expand Up @@ -106,3 +105,12 @@ export const ButtonContainer = styled.div`
margin-top: auto;
padding: 1.6rem;
`;

export const layoutStyle = css`
position: relative;
max-width: 48rem;
min-width: 28rem;
min-height: 100svh;
margin: 0 auto;
`;
Loading

0 comments on commit 3ee5e5e

Please sign in to comment.