Skip to content

Commit

Permalink
Merge branch 'feat/v2' into feat/issue-90
Browse files Browse the repository at this point in the history
  • Loading branch information
Leejin-Yang committed Apr 20, 2024
2 parents 17db86e + 4685b8b commit ddacdda
Show file tree
Hide file tree
Showing 33 changed files with 307 additions and 150 deletions.
25 changes: 25 additions & 0 deletions src/components/Common/ShowAllButton/ShowAllButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Link } from 'react-router-dom';

import { moreIconWrapper, linkWrapper } from './showAllButton.css';

import { SvgIcon, Text } from '@/components/Common';
import { vars } from '@/styles/theme.css';

interface ShowAllButtonProps {
link: string;
}

const ShowAllButton = ({ link }: ShowAllButtonProps) => {
return (
<Link to={link} className={linkWrapper}>
<div className={moreIconWrapper}>
<SvgIcon variant="arrowRight" fill="none" stroke={vars.colors.gray5} />
</div>
<Text as="span" color="info" weight="semiBold" size="caption2">
전체보기
</Text>
</Link>
);
};

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

export const linkWrapper = style({
display: 'flex',
flexDirection: 'column',
gap: 12,
alignItems: 'center',
width: 45,
});

export const moreIconWrapper = style({
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
width: 40,
height: 40,
borderRadius: '50%',
background: vars.colors.secondary1,
});
2 changes: 1 addition & 1 deletion src/components/Common/TopBar/TopBar.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export const LeftTitleAndRegister: Story = {
return (
<TopBar {...args}>
<TopBar.LeftNavigationGroup title="타이틀" />
<TopBar.RegisterLink />
<TopBar.RegisterButton />
</TopBar>
);
},
Expand Down
16 changes: 9 additions & 7 deletions src/components/Common/TopBar/TopBar.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
import type { ComponentPropsWithoutRef } from 'react';
import { Link } from 'react-router-dom';

import { LeftNavigationWrapper, container, headerTitle, leftTitle } from './topBar.css';
import { LeftNavigationWrapper, container, headerTitle, leftTitle, register } from './topBar.css';
import SvgIcon from '../Svg/SvgIcon';
import Text from '../Text/Text';

import LogoImage from '@/assets/logo.svg';
import { PATH } from '@/constants/path';
import { vars } from '@/styles/theme.css';


interface TopBarProps {
children?: React.ReactNode;
title?: string;
link?: string;
state?: unknown;
}

type RegisterButtonProps = ComponentPropsWithoutRef<'button'>;

const TopBar = ({ children }: TopBarProps) => {
return <header className={container}>{children}</header>;
};
Expand Down Expand Up @@ -58,13 +60,13 @@ const SearchLink = () => {
);
};

const RegisterLink = ({ link = '' }: TopBarProps) => {
const RegisterButton = ({ ...props }: RegisterButtonProps) => {
return (
<Link to={link}>
<Text size="caption1" color="disabled" weight="semiBold">
<button {...props}>
<Text as="span" size="caption1" weight="semiBold" className={register}>
등둝
</Text>
</Link>
</button>
);
};

Expand All @@ -85,7 +87,7 @@ TopBar.BackLink = BackLink;
TopBar.LeftNavigationGroup = LeftNavigationGroup;
TopBar.Title = Title;
TopBar.SearchLink = SearchLink;
TopBar.RegisterLink = RegisterLink;
TopBar.RegisterButton = RegisterButton;
TopBar.CloseButton = CloseButton;
TopBar.Spacer = Spacer;

Expand Down
8 changes: 8 additions & 0 deletions src/components/Common/TopBar/topBar.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,11 @@ export const headerTitle = style({
fontSize: 18,
fontWeight: 600,
});

export const register = style({
selectors: {
'button:disabled > &': {
color: vars.colors.text.disabled,
},
},
});
2 changes: 2 additions & 0 deletions src/components/Common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,5 @@ export { default as Badge } from './Badge/Badge';
export { default as WriteButton } from './WriteButton/WriteButton';
export { default as Text } from './Text/Text';
export { default as Indicator } from './Indicator/Indicator';
export { default as TopBar } from './TopBar/TopBar';
export { default as ShowAllButton } from './ShowAllButton/ShowAllButton';
35 changes: 21 additions & 14 deletions src/components/Product/ProductRecipeList/ProductRecipeList.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,41 @@
import { Link } from 'react-router-dom';

import { container, moreIcon, moreIconWrapper, moreItem, moreLink } from './productRecipeList.css';
import { container, moreItem, notFound, recipeLink } from './productRecipeList.css';

import { SvgIcon, Text } from '@/components/Common';
import SearchNotFoundImage from '@/assets/search-notfound.png';
import { Text, ShowAllButton } from '@/components/Common';
import { DefaultRecipeItem } from '@/components/Recipe';
import { PATH } from '@/constants/path';
import { useInfiniteProductRecipesQuery } from '@/hooks/queries/product';
import { vars } from '@/styles/theme.css';
import displaySlice from '@/utils/displaySlice';

interface ProductRecipeListProps {
productId: number;
productName: string;
}

const ProductRecipeList = ({ productId }: ProductRecipeListProps) => {
const ProductRecipeList = ({ productId, productName }: ProductRecipeListProps) => {
// μƒν’ˆμ—μ„œ 보여쀄 κΏ€μ‘°ν•© μ •λ ¬ 쑰건
const { data } = useInfiniteProductRecipesQuery(productId, 'favoriteCount,desc');

const recipes = data.pages.flatMap((page) => page.recipes);
const recipeToDisplay = displaySlice(true, recipes, 3);

if (recipes.length === 0) {
return null;
return (
<div className={notFound}>
<img src={SearchNotFoundImage} width={335} alt="검색 κ²°κ³Ό μ—†μŒ" />
<Text color="disabled" size="caption4">
아직 μž‘μ„±λœ 꿀쑰합이 μ—†μ–΄μš”
</Text>
<div style={{ height: '6px' }} />
<Link to={PATH.RECIPE} className={recipeLink}>
<Text as="span" color="sub" weight="semiBold" size="caption2">
κΏ€μ‘°ν•© μž‘μ„±ν•˜λŸ¬ κ°€κΈ°
</Text>
</Link>
</div>
);
}

return (
Expand All @@ -32,15 +47,7 @@ const ProductRecipeList = ({ productId }: ProductRecipeListProps) => {
))}
{recipeToDisplay.length < recipes.length && (
<li className={moreItem}>
{/*λ§ν¬λŠ” μƒν’ˆμ΄ ν¬ν•¨λœ κΏ€μ‘°ν•© κ²€μƒ‰κ²°κ³Όλ‘œ κ°€λŠ” 것이 λ§žμ„λ“―?*/}
<Link to={''} className={moreLink}>
<div className={moreIconWrapper}>
<SvgIcon variant="arrowLeft" className={moreIcon} fill="none" stroke={vars.colors.gray5} />
</div>
<Text as="span" color="info" weight="semiBold" size="caption2">
전체보기
</Text>
</Link>
<ShowAllButton link={`${PATH.SEARCH}/recipes?query=${productName}`} />
</li>
)}
</ul>
Expand Down
20 changes: 8 additions & 12 deletions src/components/Product/ProductRecipeList/productRecipeList.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,20 @@ export const moreItem = style({
minWidth: 108,
});

export const moreLink = style({
export const notFound = style({
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
gap: 6,
textAlign: 'center',
});

export const moreIconWrapper = style({
export const recipeLink = style({
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
width: 40,
height: 40,
marginBottom: 12,
borderRadius: '50%',
background: vars.colors.secondary1,
});

export const moreIcon = style({
transform: 'rotate(180deg)',
height: 34,
padding: '0 16px',
backgroundColor: vars.colors.gray2,
borderRadius: 44,
});
3 changes: 2 additions & 1 deletion src/components/Recipe/RecipeItem/RecipeItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
RECIPE_CARD_DEFAULT_IMAGE_URL_4,
RECIPE_CARD_DEFAULT_IMAGE_URL_5,
} from '@/constants/image';
import { PATH } from '@/constants/path';
import RecipeItemProvider from '@/contexts/RecipeItemContext';
import { useRecipeItemValueContext } from '@/hooks/context';
import type { Recipe } from '@/types/recipe';
Expand All @@ -50,7 +51,7 @@ const RecipeItem = ({ recipe, children }: RecipeItemProps) => {

return (
<RecipeItemProvider recipe={recipe}>
<Link to={`${id}`}>{children}</Link>
<Link to={`${PATH.RECIPE}/${id}`}>{children}</Link>
</RecipeItemProvider>
);
};
Expand Down
21 changes: 6 additions & 15 deletions src/components/Review/ReviewRegisterForm/ReviewRegisterForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,39 +8,28 @@ import StarRate from './StarRate/StarRate';
import RebuyCheckbox from '../RebuyCheckbox/RebuyCheckbox';

import { ImageUploader, SvgIcon, Text } from '@/components/Common';
import { MAX_DISPLAYED_TAGS_LENGTH, MIN_DISPLAYED_TAGS_LENGTH } from '@/constants';
import type { TagValue } from '@/contexts/ReviewFormContext';
import { useFormData, useImageUploader } from '@/hooks/common';
import { useReviewFormActionContext, useReviewFormValueContext } from '@/hooks/context';
import { useReviewRegisterFormMutation } from '@/hooks/queries/review';
import { vars } from '@/styles/theme.css';
import type { ReviewRequest } from '@/types/review';

const MIN_RATING_SCORE = 0;
const MIN_CONTENT_LENGTH = 0;

interface ReviewRegisterFormProps {
productId: number;
openBottomSheet: () => void;
}

const ReviewRegisterForm = ({ productId, openBottomSheet }: ReviewRegisterFormProps) => {
const { isImageUploading, previewImage, imageFile, uploadImage, deleteImage } = useImageUploader();
const { previewImage, imageFile, uploadImage, deleteImage } = useImageUploader();
const navigate = useNavigate();

const reviewFormValue = useReviewFormValueContext();
const { formValue: reviewFormValue } = useReviewFormValueContext();
const { handleReviewFormValue, resetReviewFormValue } = useReviewFormActionContext();
const { toast } = useToastActionContext();

const { mutate } = useReviewRegisterFormMutation(productId);

const isValid =
reviewFormValue.rating > MIN_RATING_SCORE &&
reviewFormValue.tags.length >= MIN_DISPLAYED_TAGS_LENGTH &&
reviewFormValue.tags.length <= MAX_DISPLAYED_TAGS_LENGTH &&
reviewFormValue.content.length > MIN_CONTENT_LENGTH &&
!isImageUploading;

const formValue: ReviewRequest = { ...reviewFormValue, tagIds: reviewFormValue.tags.map(({ id }) => id) };

const formData = useFormData<ReviewRequest>({
Expand Down Expand Up @@ -81,7 +70,7 @@ const ReviewRegisterForm = ({ productId, openBottomSheet }: ReviewRegisterFormPr
};

return (
<form onSubmit={handleSubmit}>
<form id="review-form" onSubmit={handleSubmit}>
<div>
<h2 className={itemTitle} tabIndex={0}>
사진 등둝
Expand All @@ -105,7 +94,9 @@ const ReviewRegisterForm = ({ productId, openBottomSheet }: ReviewRegisterFormPr
{reviewFormValue.tags.map((tag) => (
<li key={tag.id}>
<button type="button" onClick={handleTagSelect(tag)} className={tagButton}>
<Text as="span">{tag.name}</Text>
<Text as="span" size="caption2" weight="medium">
{tag.name}
</Text>
<SvgIcon variant="close2" width={8} height={8} fill="none" stroke={vars.colors.gray4} />
</button>
</li>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@ export const tagButton = style({
gap: 4,
height: 28,
padding: '0 6px',
fontSize: '1.3rem',
fontWeight: 500,
borderRadius: 4,
backgroundColor: vars.colors.gray2,
});
4 changes: 3 additions & 1 deletion src/components/Review/ReviewTagList/ReviewTagList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import { useReviewTagsQuery } from '@/hooks/queries/review';

const ReviewTagList = () => {
const { data: tagsData } = useReviewTagsQuery();
const { tags: selectedTags } = useReviewFormValueContext();
const {
formValue: { tags: selectedTags },
} = useReviewFormValueContext();
const { handleReviewFormValue } = useReviewFormActionContext();

const isChecked = (tag: TagValue) => selectedTags.some(({ id }) => id === tag.id);
Expand Down
13 changes: 11 additions & 2 deletions src/components/Review/ReviewTagSheet/ReviewTagSheet.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,29 @@
import { container, registerButton, registerButtonWrapper, section } from './reviewTagSheet.css';
import { closeWrapper, container, registerButton, registerButtonWrapper, section } from './reviewTagSheet.css';
import ReviewTagList from '../ReviewTagList/ReviewTagList';

import { SvgIcon } from '@/components/Common';
import { MAX_DISPLAYED_TAGS_LENGTH, MIN_DISPLAYED_TAGS_LENGTH } from '@/constants';
import { useReviewFormValueContext } from '@/hooks/context';
import { vars } from '@/styles/theme.css';

interface ReviewTagSheetProps {
close: () => void;
}

const ReviewTagSheet = ({ close }: ReviewTagSheetProps) => {
const { tags } = useReviewFormValueContext();
const {
formValue: { tags },
} = useReviewFormValueContext();

const isValid = tags.length >= MIN_DISPLAYED_TAGS_LENGTH && tags.length <= MAX_DISPLAYED_TAGS_LENGTH;

return (
<div className={container}>
<div className={closeWrapper}>
<button type="button" onClick={close}>
<SvgIcon variant="close2" stroke={vars.colors.black} width={20} height={20} />
</button>
</div>
<section className={section}>
<ReviewTagList />
</section>
Expand Down
12 changes: 10 additions & 2 deletions src/components/Review/ReviewTagSheet/reviewTagSheet.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,17 @@ export const container = style({
height: '100vh',
});

export const closeWrapper = style({
padding: '0 20px',
display: 'flex',
height: 50,
alignItems: 'center',
justifyContent: 'flex-end',
});

export const section = style({
padding: '50px 20px 70px',
marginBottom: 32,
padding: '0 20px',
margin: '16px 0 32px',
});

export const registerButtonWrapper = style({
Expand Down
Loading

0 comments on commit ddacdda

Please sign in to comment.