Skip to content

Commit

Permalink
Merge branch 'develop' into feat/#62/cmp-popular-card
Browse files Browse the repository at this point in the history
  • Loading branch information
maylh authored Jan 15, 2025
2 parents 71fb7bd + 6280754 commit 8f6c2ae
Show file tree
Hide file tree
Showing 18 changed files with 584 additions and 3 deletions.
17 changes: 17 additions & 0 deletions src/components/card/reviewCard/cardInfo/CardInfo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import * as styles from './cardInfo.css';

interface CardInfoProps {
reviewName: string | null;
reviewDate: string;
}

const CardInfo = ({ reviewName, reviewDate }: CardInfoProps) => {
return (
<div className={styles.cardInfo}>
<p className={styles.reviewerName}>{reviewName || '네이버 블로그'}</p>
<p>{reviewDate}</p>
</div>
);
};

export default CardInfo;
20 changes: 20 additions & 0 deletions src/components/card/reviewCard/cardInfo/cardInfo.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import theme from '@styles/theme.css';
import { style } from '@vanilla-extract/css';

export const cardInfo = style({
display: 'flex',
justifyContent: 'space-between',

width: '100%',

...theme.FONTS.c6R13,
color: theme.COLORS.gray5,
});

export const reviewerName = style({
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
textAlign: 'left',
width: '12.6rem',
});
49 changes: 49 additions & 0 deletions src/components/card/reviewCard/reviewCard/ReviewCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import * as styles from './reviewCard.css';
import CardInfo from '../cardInfo/CardInfo';

interface ReviewCardProps {
reviewTitle: string;
reviewDate: string;
reviewName: string | null;
reviewLink: string;
reviewDescription?: string | null;
blogImage: string | null;
size: 'small' | 'large';
}

const ReviewCard = ({
reviewTitle,
reviewDate,
reviewName,
reviewLink,
reviewDescription,
blogImage,
size,
}: ReviewCardProps) => {
const handleButtonClick = () => {
window.location.href = reviewLink;
};

return (
<button className={styles.cardContainer({ size })} onClick={handleButtonClick}>
{blogImage ? (
<img className={styles.cardImage({ size })} src={blogImage} alt="thumbnail" />
) : (
<img
className={styles.cardImage({ size })}
src="/default-image.png"
alt="Default thumbnail"
/>
)}
<div className={styles.cardContent({ size })}>
<div>
<p className={styles.cardTitle({ size })}>{reviewTitle}</p>
{size == 'large' && <p className={styles.cardBody}>{reviewDescription}</p>}
</div>
<CardInfo reviewName={reviewName} reviewDate={reviewDate} />
</div>
</button>
);
};

export default ReviewCard;
111 changes: 111 additions & 0 deletions src/components/card/reviewCard/reviewCard/reviewCard.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import theme from '@styles/theme.css';
import { style } from '@vanilla-extract/css';
import { recipe } from '@vanilla-extract/recipes';

export const cardContainer = recipe({
base: {
overflow: 'hidden',
border: `1px solid ${theme.COLORS.gray2}`,
backgroundColor: theme.COLORS.white,
selectors: {
'&:hover': {
filter: 'brightness(96%)',
},
},
},
variants: {
size: {
small: {
width: '24rem',
height: '20rem',
borderRadius: 5,
},
large: {
width: '33.5rem',
height: '23.2rem',
borderRadius: 4,
},
},
},
});

export const cardImage = recipe({
base: {
objectFit: 'cover',
overflow: 'hidden',
backgroundSize: 'cover',
backgroundPosition: 'center',
width: '100%',
},
variants: {
size: {
small: {
height: '11.5rem',
},
large: {
height: '11.8rem',
},
},
},
});

export const cardContent = recipe({
base: {
display: 'flex',
flexDirection: 'column',
alignItems: 'flex-start',
padding: '0 1.2rem',
gap: '1.2rem',
},
variants: {
size: {
small: {
height: '8.5rem',
},
large: {
height: '11.4rem',
},
},
},
});

export const cardTitle = recipe({
base: {
overflow: 'hidden',
textOverflow: 'ellipsis',
textAlign: 'left',
},
variants: {
size: {
small: {
display: '-webkit-box',
WebkitBoxOrient: 'vertical',
WebkitLineClamp: 2,
height: '4.2rem',
marginTop: '0.6rem',
...theme.FONTS.c1Sb15,
},
large: {
marginTop: '1rem',
marginBottom: '0.4rem',
whiteSpace: 'nowrap',
width: '31.1rem',
...theme.FONTS.h3Sb18,
},
},
},
});

export const cardBody = style({
display: '-webkit-box',
WebkitBoxOrient: 'vertical',
WebkitLineClamp: 2,
height: '3.6rem',

overflow: 'hidden',
textOverflow: 'ellipsis',
textAlign: 'left',

...theme.FONTS.c2R14,
color: theme.COLORS.gray8,
});
44 changes: 44 additions & 0 deletions src/components/card/templeStayCard/InfoSection.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import theme from '@styles/theme.css';
import { style } from '@vanilla-extract/css';

export const infoBox = style({
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-around',
width: '16.3rem',
});

export const hashTag = style({
width: '100%',
height: '1.7rem',

color: theme.COLORS.gray5,
...theme.FONTS.c5M13,
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
});

export const title = style({
width: '100%',
height: '4.9rem',
alignContent: 'center',

color: theme.COLORS.black,
...theme.FONTS.h5Sb16,

overflow: 'hidden',
display: '-webkit-box',
WebkitBoxOrient: 'vertical',
WebkitLineClamp: 2,
textOverflow: 'ellipsis',
});

export const tagBox = style({
display: 'flex',
gap: '0.6rem',
width: '100%',
height: '2.1rem',

marginTop: '0.8rem',
});
30 changes: 30 additions & 0 deletions src/components/card/templeStayCard/InfoSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import Tag from '@components/common/tag/Tag';

import * as styles from './InfoSection.css';

interface InfoSectionProps {
templeName: string;
templestayName: string;
tag: string;
region: string;
type: string;
}

const InfoSection = ({ templeName, templestayName, tag, region, type }: InfoSectionProps) => {
return (
<section className={styles.infoBox}>
<div>
<h2 className={styles.hashTag}>#{tag}</h2>
<h2 className={styles.title}>
{templeName} {templestayName}
</h2>
</div>
<div className={styles.tagBox}>
<Tag color="brown" label={region} />
<Tag color="blue" label={type} />
</div>
</section>
);
};

export default InfoSection;
60 changes: 60 additions & 0 deletions src/components/card/templeStayCard/TempleStayCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import InfoSection from '@components/card/templeStayCard/InfoSection';
import FlowerIcon from '@components/common/icon/flowerIcon/FlowerIcon';
import { useState } from 'react';

import * as styles from './templeStayCard.css';

interface TempleStayCardProps {
id: number;
templeName: string;
templestayName: string;
tag: string;
region: string;
type: string;
imgUrl: string;
liked: boolean;
layout: 'vertical' | 'horizontal';
}

const TempleStayCard = ({
templeName,
templestayName,
tag,
region,
type,
imgUrl,
liked,
layout,
}: TempleStayCardProps) => {
const [isWished, setIsWished] = useState(liked);
const isHorizontal = layout === 'horizontal';

const onClickWishBtn = () => {
setIsWished((prev) => !prev);
};

return (
<article className={isHorizontal ? styles.horizontalContainer : styles.verticalContainer}>
<section className={isHorizontal ? styles.horizontalImgSection : styles.verticalImgSection}>
<img
className={isHorizontal ? styles.horizontalImage : styles.verticalImage}
src={imgUrl}
alt={templeName + ' 대표사진'}
/>
<button className={styles.wishBtn} onClick={onClickWishBtn}>
<FlowerIcon isActive={isWished} />
</button>
</section>

<InfoSection
templeName={templeName}
templestayName={templestayName}
tag={tag}
region={region}
type={type}
/>
</article>
);
};

export default TempleStayCard;
Loading

0 comments on commit 8f6c2ae

Please sign in to comment.