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

Feature/euna/entire activity page #4

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
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
18 changes: 2 additions & 16 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,16 @@
import React from 'react';
import { ApolloProvider } from '@apollo/client';
import { ThemeProvider } from 'styled-components';
import GlobalStyle from './styles/globalStyle';
import client from './apollo/client';
import theme from './styles/theme';
import Slider from './components/Slider';

const dummyCardInfo = {
desc: 'μ™„λ²½ν•œ λ‰΄μš• νœ΄κ°€ κ³„νšν•˜κΈ°',
reviewCount: 139,
reviewRating: 4.99,
price: 11688,
nation: 'λ―Έκ΅­',
thumbnail:
'https://a0.muscache.com/im/pictures/lombard/MtTemplate-2496585-poster/original/e6de8fae-018d-4411-b0a3-81bbb6e4e5c3.jpeg',
};
import Router from './pages/Router';

function App() {
return (
<ApolloProvider client={client}>
<ThemeProvider theme={theme}>
<GlobalStyle />
<Slider
label="μ „ 세계 ν˜„μ§€ 호슀트의 도움을 λ°›μ•„ 여행을 κ³„νšν•΄λ³΄μ„Έμš”"
cardList={Array(10).fill(dummyCardInfo)}
/>
<Router />
</ThemeProvider>
</ApolloProvider>
);
Expand Down
13 changes: 9 additions & 4 deletions src/assets/svgIcons/Heart.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
function Heart() {
/* eslint-disable react/no-unused-prop-types */
export interface HeartProps {
height: string;
width: string;
stroke: string;
}

function Heart(props: HeartProps) {
return (
<svg
viewBox="0 0 32 32"
Expand All @@ -8,11 +15,9 @@ function Heart() {
focusable="false"
style={{
display: 'block',
height: '24px',
width: '24px',
stroke: 'white',
strokeWidth: 2,
overflow: 'visible',
...props,
}}
>
<path d="m16 28c7-4.733 14-10 14-17 0-1.792-.683-3.583-2.05-4.95-1.367-1.366-3.158-2.05-4.95-2.05-1.791 0-3.583.684-4.949 2.05l-2.051 2.051-2.05-2.051c-1.367-1.366-3.158-2.05-4.95-2.05-1.791 0-3.583.684-4.949 2.05-1.367 1.367-2.051 3.158-2.051 4.95 0 7 7 12.267 14 17z" />
Expand Down
2 changes: 1 addition & 1 deletion src/components/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ function Card(props: CardProps) {
<StCard>
<StImageBox url={thumbnail}>
<StLikeButton isLiked={isLiked} onClick={handleClickLike}>
<Heart />
<Heart width="24px" height="24px" stroke="white" />
</StLikeButton>
</StImageBox>
<StInformation>
Expand Down
117 changes: 117 additions & 0 deletions src/components/LoadingButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import styled, { keyframes } from 'styled-components';

const StIndicatorButton = styled.button`
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
margin: 0;

text-decoration: none;
border-color: black;
width: 93.48px;
height: 48px;
touch-action: manipulation;
font-family: 'Circular', -apple-system, 'BlinkMacSystemFont', 'Roboto', 'Helvetica Neue',
sans-serif;

border-radius: 8px;
border-width: 1px;
border-style: solid;
outline: none;

border: none;
background: #dddddd;
`;

const loader10g = keyframes`
0% {
background-color: rgba(255, 255, 255, 0.2);
}
25% {
background-color: rgba(255, 255, 255, 1);
}
50% {
background-color: rgba(255, 255, 255, 0.2);
}
75% {
background-color: rgba(255, 255, 255, 0.2);
}
100% {
background-color: rgba(255, 255, 255, 0.2);
}
`;

const loader10m = keyframes`
0% {
background-color: rgba(255, 255, 255, 0.2);
}
25% {
background-color: rgba(255, 255, 255, 0.2);
}
50% {
background-color: rgba(255, 255, 255, 1);
}
75% {
background-color: rgba(255, 255, 255, 0.2);
}
100% {
background-color: rgba(255, 255, 255, 0.2);
}`;

const loader10d = keyframes`
0% {
background-color: rgba(255, 255, 255, 0.2);
}
25% {
background-color: rgba(255, 255, 255, 0.2);
}
50% {
background-color: rgba(255, 255, 255, 0.2);
}
75% {
background-color: rgba(255, 255, 255, 1);
}
100% {
background-color: rgba(255, 255, 255, 0.2);
}`;

const StIndicator = styled.div`
position: relative;
width: 10px;
height: 10px;
border-radius: 10px;
animation: ${loader10m} 1.2s ease-in-out infinite;

::before {
content: '';
position: absolute;
top: 0px;
left: -20px;
height: 10px;
width: 10px;
border-radius: 10px;
animation: ${loader10g} 1.2s ease-in-out infinite;
}

::after {
content: '';
position: absolute;
top: 0px;
left: 20px;
height: 10px;
width: 10px;
border-radius: 10px;
animation: ${loader10d} 1.2s ease-in-out infinite;
}
`;

function LoadingButton() {
return (
<StIndicatorButton>
<StIndicator />
</StIndicatorButton>
);
}

export default LoadingButton;
135 changes: 135 additions & 0 deletions src/components/RecommendCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import { useState } from 'react';
import styled from 'styled-components';
import Star from '../assets/svgIcons/Star';
import Heart from '../assets/svgIcons/Heart';

const StWrapper = styled.div`
width: 320px;
height: 105px;

display: flex;
overflow: hidden;
background-color: #ffffff;

border-style: solid;
border-color: transparent;
border-radius: 12px;
border: 1px solid #dddddd;
`;

const StFlexbox = styled.div`
display: flex;
margin-bottom: 3px;
justify-content: space-between;
`;

const StImageBox = styled.div`
width: 64px;
margin: 12px;

img {
width: 100%;
height: 100%;
object-fit: fill;
border-radius: 8px;
}
`;

const StLikeButton = styled.button<{ isLiked: boolean }>`
background-color: transparent;
border: none;

& > svg {
fill: ${(props) => (props.isLiked ? '#FF385C' : '#FFFFFF')};
}
`;

const StStar = styled(Star)`
display: flex;
`;

const StInformation = styled.div`
width: calc(100% - 88px);

display: flex;
flex-direction: column;

padding-right: 16px;
padding-top: 16px;
padding-bottom: 8px;
`;

const StReviewRating = styled.span`
font-size: 12px;
font-weight: 300;
`;

const StReviewCount = styled.span`
font-size: 12px;
font-weight: 300;
color: ${({ theme }) => theme.colors.foggy};
`;

const StCardDesc = styled.p`
display: -webkit-box;
font-size: 14px;
line-height: 1.2em;

-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
white-space: normal;
word-wrap: break-word;

overflow: hidden;
text-overflow: ellipsis;
`;

const StHostName = styled.span`
font-size: 12px;
font-weight: 300;

margin-top: 3px;
margin-bottom: 2px;
`;

export interface RecommendCardProps {
desc: string;
reviewCount: number;
reviewRating: number;
thumbnail: string;
hostName: string;
isLiked: boolean;
}

function RecommendCard(props: RecommendCardProps) {
const { desc, reviewCount, reviewRating, thumbnail, isLiked: isDefaultLiked, hostName } = props;
const [isLiked, setIsLiked] = useState<boolean>(isDefaultLiked);

const handleClickLike = () => {
setIsLiked((prev) => !prev);
};

return (
<StWrapper>
<StImageBox>
<img src={thumbnail} alt={desc} />
</StImageBox>
<StInformation>
<StFlexbox style={{ alignItems: 'center' }}>
<div>
<StStar />
<StReviewRating>{reviewRating}</StReviewRating>
<StReviewCount>({reviewCount})</StReviewCount>
</div>
<StLikeButton isLiked={isLiked} onClick={handleClickLike}>
<Heart height="16px" width="16px" stroke="black" />
</StLikeButton>
</StFlexbox>
<StCardDesc>{desc}</StCardDesc>
<StHostName>호슀트:{hostName}</StHostName>
</StInformation>
</StWrapper>
);
}

export default RecommendCard;
41 changes: 41 additions & 0 deletions src/components/RecommendSlider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/* eslint-disable react/jsx-props-no-spreading */
import styled from 'styled-components';
import { Swiper, SwiperSlide } from 'swiper/react';
import { Scrollbar } from 'swiper';
import 'swiper/css';
import RecommendCard, { RecommendCardProps } from './RecommendCard';

const StContainer = styled.div`
.swiper-slide:first-child {
padding-left: 24px;
}
`;

interface RecommendSliderProps {
cardList: RecommendCardProps[];
onChangeIdx: (index: number) => void;
}

function RecommendSlider(props: RecommendSliderProps) {
const { cardList, onChangeIdx } = props;

return (
<StContainer>
<Swiper
slidesPerView="auto"
modules={[Scrollbar]}
scrollbar={{ draggable: true, el: null }}
spaceBetween={12}
onSlideChange={(e) => onChangeIdx(e.activeIndex)}
>
{cardList.map((cardInfo) => (
<SwiperSlide style={{ flexShrink: 'unset' }}>
<RecommendCard {...cardInfo} />
</SwiperSlide>
))}
</Swiper>
</StContainer>
);
}

export default RecommendSlider;
3 changes: 3 additions & 0 deletions src/pages/Detail.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function Detail() {
return <div>detail</div>;
}
Loading