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

feat: 리뷰 작성 폼 개편 #77

Merged
merged 28 commits into from
Apr 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
e3ce366
feat: 사진 아이콘 추가
Leejin-Yang Apr 6, 2024
3ed0173
feat: 이미지 업로더 개편
Leejin-Yang Apr 6, 2024
d23ce06
feat: 별점 작성 개편
Leejin-Yang Apr 6, 2024
5d15c1a
feat: 리뷰 설명 개편
Leejin-Yang Apr 6, 2024
b52185d
refactor: 안 쓰는 스타일 파일 삭제
Leejin-Yang Apr 6, 2024
4de7de7
feat: 재구매 체크박스 개편
Leejin-Yang Apr 6, 2024
ab164c6
feat: 재구매 타이틀 추가
Leejin-Yang Apr 6, 2024
c07090d
feat: 태그 선택 바텀시트 열기 버튼 추가
Leejin-Yang Apr 7, 2024
1bdbe2b
feat: 태그 선택 구현
Leejin-Yang Apr 7, 2024
1406cd2
feat: 태그 최대 3개 선택 구현
Leejin-Yang Apr 7, 2024
799d27c
feat: 체크 되어 있는 태그 스타일
Leejin-Yang Apr 7, 2024
965ec0e
feat: 선택 태그 폼에서 렌더링
Leejin-Yang Apr 7, 2024
1bd6ac9
feat: 폼에서 태그 삭제
Leejin-Yang Apr 7, 2024
13d95f6
refactor: 안 쓰는 컴포넌트 삭제
Leejin-Yang Apr 7, 2024
33a8460
feat: 태그 선택 바텀시트 컴포넌트 추가
Leejin-Yang Apr 7, 2024
f82ce90
feat: 리뷰 등록 페이지 추가
Leejin-Yang Apr 7, 2024
f69dd1f
feat: 태그 바텀시트 prop 추가
Leejin-Yang Apr 7, 2024
66bdc9c
Merge branch 'feat/v2' into feat/issue-76
Leejin-Yang Apr 14, 2024
cb12015
refactor: 리뷰 태그 바텀시트 index export
Leejin-Yang Apr 14, 2024
6b75925
refactor: Text 컴포넌트 사용
Leejin-Yang Apr 14, 2024
52b8820
style: 태그 조건 이름 수정
Leejin-Yang Apr 14, 2024
b5885e3
feat: 태그 선택 최소 조건 추가
Leejin-Yang Apr 14, 2024
504fe9f
feat: 태그 선택 바텀시트 높이 추가
Leejin-Yang Apr 14, 2024
635a3a5
refactor: Text 컴포넌트 사용
Leejin-Yang Apr 14, 2024
c6e707f
feat: 이미지 업로더 스타일 개편
Leejin-Yang Apr 14, 2024
1415476
feat: 리뷰 설명 에러 처리
Leejin-Yang Apr 14, 2024
bb068d2
feat: 설명 에러 메시지 추가 구현
Leejin-Yang Apr 14, 2024
37176a1
feat: 리뷰 태그 바텀시트 스토리 추가
Leejin-Yang Apr 14, 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
20 changes: 20 additions & 0 deletions .storybook/preview-body.html
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,11 @@
d="M20.2 4.683a1.013 1.013 0 0 1 0 1.438L9.008 17.317a1.013 1.013 0 0 1-1.437 0L1.8 11.55a1.017 1.017 0 0 1 1.437-1.437l5.045 5.045L18.758 4.683a1.013 1.013 0 0 1 1.437 0h.005z"
/>
</symbol>
<symbol id="picture" viewBox="0 0 28 29">
<path
d="M1.977 5.125v19.25h23.625V5.125H1.977zm1.687 1.75h20.25v12.168l-4.456-4.648-.606-.63-3.824 3.966-4.851-5.086-.607-.63-5.906 6.126V6.875zm16.875 1.75c-.933 0-1.687.783-1.687 1.75s.754 1.75 1.687 1.75 1.688-.783 1.688-1.75-.755-1.75-1.688-1.75zM9.57 14.505l7.752 8.12H3.664V20.63l5.906-6.125zm9.282 1.75l5.062 5.25v1.12h-4.192l-3.507-3.664 2.637-2.707z"
/>
</symbol>
<symbol id="recipe" viewBox="0 0 22 26">
<path
d="M20.675 12.44c-.324-.604-.643-1.123-.868-1.533a5.058 5.058 0 0 1-.256-.516.808.808 0 0 1-.068-.244v-.005.001a.311.311 0 0 1 .054-.168.344.344 0 0 1 .116-.096.83.83 0 0 1 .135-.06l.096.045.25-.053c.53-.111.904-.529.904-1.011V7.733c0-.813-.743-1.47-1.662-1.471h-2.668c-.23-.425-.717-.72-1.284-.72h-4.035c-.567 0-1.053.296-1.284.72H8.23c-.203-.737-.762-2.216-2.261-4.017A8.064 8.064 0 0 0 4.489.91 5.94 5.94 0 0 0 3.376.287 3.487 3.487 0 0 0 2.051 0 2.454 2.454 0 0 0 .86.297a1.61 1.61 0 0 0-.664.677A1.779 1.779 0 0 0 0 1.801c0 .34.086.68.259.998.172.316.436.61.799.825.818.483 1.589 1.076 2.155 1.67.32.332.564.665.73.968h-.019c-.917 0-1.66.658-1.66 1.47v1.064c0 .487.381.907.915 1.014l.267.053.076-.04a.78.78 0 0 1 .112.049.363.363 0 0 1 .128.1.31.31 0 0 1 .057.173v.001a.77.77 0 0 1-.068.245c-.095.239-.296.596-.544 1.022-.742 1.285-1.904 3.225-1.905 5.645 0 .157.004.316.015.477.13 2.033.929 4.141 2.613 5.762C5.61 24.92 8.183 26.006 11.65 26c3.468.006 6.04-1.08 7.722-2.703 1.684-1.62 2.482-3.73 2.614-5.762.01-.161.014-.32.014-.477 0-1.844-.677-3.409-1.325-4.618zm-1.012-4.707v.866c-.221.026-.471.1-.733.245-.048.026-.093.064-.14.096h-1.937V7.48h2.523c.159 0 .287.113.287.253zM1.82 2.61a.886.886 0 0 1-.324-.342.991.991 0 0 1-.122-.468.7.7 0 0 1 .07-.318.346.346 0 0 1 .14-.151.938.938 0 0 1 .466-.115c.206 0 .464.057.742.173.417.171.864.469 1.238.775.374.304.68.62.831.802.97 1.167 1.5 2.17 1.786 2.87.058.142.104.269.144.385H5.405c-.216-.6-.628-1.168-1.142-1.712-.67-.702-1.525-1.356-2.442-1.899zm1.818 5.986v-.864c0-.14.128-.253.285-.254H9.96v1.46H4.512c-.062-.041-.124-.088-.188-.12a2.03 2.03 0 0 0-.685-.222zm16.974 8.869c-.115 1.804-.83 3.64-2.253 5.006-1.425 1.363-3.554 2.305-6.71 2.31-3.154-.005-5.283-.947-6.709-2.31-1.423-1.365-2.137-3.202-2.251-5.006a6.281 6.281 0 0 1-.014-.408c0-1.575.582-2.958 1.193-4.096.305-.57.615-1.074.862-1.521.123-.225.231-.435.315-.643.082-.208.146-.414.147-.652l-.002-.083a1.497 1.497 0 0 0-.06-.312h4.83v2.925c0 .531.49.962 1.09.962.6 0 1.091-.43 1.091-.962v-.621c0-.531.49-.966 1.09-.966.602 0 1.092.435 1.092.966v1.838c0 .617.564 1.12 1.265 1.12.696 0 1.265-.503 1.265-1.12V9.751h1.318c-.03.1-.052.203-.06.31l-.003.085c.002.239.065.444.148.652.147.362.367.74.616 1.171.749 1.286 1.756 3.022 1.753 5.09 0 .134-.003.27-.012.407z"
Expand Down Expand Up @@ -373,6 +378,21 @@
</clipPath>
</defs>
</symbol>
<symbol id="error" viewBox="0 0 13 13">
<g clipPath="url(#a)">
<path
fill="#FD4545"
fillRule="evenodd"
d="M1.523 1.185c.24-.241.568-.377.909-.377h8.571a1.286 1.286 0 0 1 1.286 1.286v8.571a1.286 1.286 0 0 1-1.286 1.286H4.2l-3.377.844a.429.429 0 0 1-.51-.551l.834-2.505V2.094c0-.341.136-.668.377-.91zm5.789 2.019a.536.536 0 1 0-1.072 0V6.34a.536.536 0 1 0 1.072 0V3.204zM5.92 9.021a.855.855 0 1 1 1.71 0 .855.855 0 0 1-1.71 0z"
clipRule="evenodd"
/>
</g>
<defs>
<clipPath id="a">
<path fill="#fff" d="M0 0h12v12H0z" transform="translate(.29 .808)" />
</clipPath>
</defs>
</symbol>
</svg>
</div>
<div id="dialog-container"></div>
Expand Down
69 changes: 30 additions & 39 deletions src/components/Common/ImageUploader/ImageUploader.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import { Button, useToastActionContext } from '@fun-eat/design-system';
import { useToastActionContext } from '@fun-eat/design-system';
import type { ChangeEventHandler } from 'react';
import styled from 'styled-components';

import { container, deleteButton, image, imageWrapper, uploadInput, uploadLabel } from './imageUploader.css';
import SvgIcon from '../Svg/SvgIcon';
import Text from '../Text/Text';

import { IMAGE_MAX_SIZE } from '@/constants';
import { useEnterKeyDown } from '@/hooks/common';
import { vars } from '@/styles/theme.css';

interface ReviewImageUploaderProps {
previewImage: string;
Expand Down Expand Up @@ -32,45 +36,32 @@ const ImageUploader = ({ previewImage, uploadImage, deleteImage }: ReviewImageUp
};

return (
<>
{previewImage ? (
<PreviewImageWrapper>
<img src={previewImage} alt="업로드한 사진" width={200} />
<Button type="button" customWidth="80px" color="primary" weight="bold" variant="filled" onClick={deleteImage}>
삭제하기
</Button>
</PreviewImageWrapper>
) : (
<ImageUploadLabel tabIndex={0} onKeyDown={handleKeydown} aria-label="사진 업로드 버튼" aria-hidden>
+
<input ref={inputRef} type="file" accept="image/*" onChange={handleImageUpload} />
</ImageUploadLabel>
<div className={container}>
<label
className={previewImage ? uploadLabel.uploaded : uploadLabel.default}
tabIndex={0}
onKeyDown={handleKeydown}
aria-label="사진 업로드 버튼"
aria-hidden
>
<SvgIcon variant="picture" width={28} height={28} fill={vars.colors.gray2} />
{previewImage && (
<Text as="span" size="caption4" color="disabled" weight="medium">
사진 변경하기
</Text>
)}
<input className={uploadInput} ref={inputRef} type="file" accept="image/*" onChange={handleImageUpload} />
</label>
{previewImage && (
<div className={imageWrapper}>
<img src={previewImage} className={image} width={80} height={80} alt="업로드한 사진" />
<button type="button" className={deleteButton} onClick={deleteImage}>
<SvgIcon variant="close2" width={10} height={10} fill="none" stroke={vars.colors.white} />
</button>
</div>
)}
</>
</div>
);
};

export default ImageUploader;

const ImageUploadLabel = styled.label`
display: flex;
justify-content: center;
align-items: center;
width: 92px;
height: 95px;
border: 1px solid ${({ theme }) => theme.borderColors.disabled};
border-radius: ${({ theme }) => theme.borderRadius.xs};
background: ${({ theme }) => theme.colors.gray1};
cursor: pointer;

& > input {
display: none;
}
`;

const PreviewImageWrapper = styled.div`
display: flex;
flex-direction: column;
gap: 20px;
align-items: center;
`;
56 changes: 56 additions & 0 deletions src/components/Common/ImageUploader/imageUploader.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { vars } from '@/styles/theme.css';
import { style, styleVariants } from '@vanilla-extract/css';

export const container = style({
display: 'flex',
gap: 8,
});

export const uploadLabelBase = style({
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
width: 80,
height: 80,
borderRadius: 6,
cursor: 'pointer',
});

export const uploadLabel = styleVariants({
default: [uploadLabelBase, { backgroundColor: vars.colors.background.category }],
uploaded: [
uploadLabelBase,
{ backgroundColor: vars.colors.background.default, border: `1px solid ${vars.colors.border.default}` },
],
});

export const uploadInput = style({
display: 'none',
});

export const imageWrapper = style({
position: 'relative',
width: 80,
height: 80,
});

export const image = style({
objectFit: 'cover',
borderRadius: 6,
});

export const deleteButton = style({
position: 'absolute',
top: 4,
right: 4,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
width: 18,
height: 18,
borderRadius: '50%',
backgroundColor: vars.colors.black,
opacity: 0.5,
cursor: 'pointer',
});
2 changes: 2 additions & 0 deletions src/components/Common/Svg/SvgIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export const SVG_ICON_VARIANTS = [
'star2',
'review2',
'check2',
'picture',
'recipe',
'list',
'member',
Expand Down Expand Up @@ -45,6 +46,7 @@ export const SVG_ICON_VARIANTS = [
'heartFilled',
'close2',
'disk',
'error',
] as const;
export type SvgIconVariant = (typeof SVG_ICON_VARIANTS)[number];

Expand Down
18 changes: 18 additions & 0 deletions src/components/Common/Svg/SvgSprite.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,9 @@ const SvgSprite = () => {
<symbol id="check2" viewBox="0 0 22 22">
<path d="M20.2 4.683a1.013 1.013 0 0 1 0 1.438L9.008 17.317a1.013 1.013 0 0 1-1.437 0L1.8 11.55a1.017 1.017 0 0 1 1.437-1.437l5.045 5.045L18.758 4.683a1.013 1.013 0 0 1 1.437 0h.005z" />
</symbol>
<symbol id="picture" viewBox="0 0 28 29">
<path d="M1.977 5.125v19.25h23.625V5.125H1.977zm1.687 1.75h20.25v12.168l-4.456-4.648-.606-.63-3.824 3.966-4.851-5.086-.607-.63-5.906 6.126V6.875zm16.875 1.75c-.933 0-1.687.783-1.687 1.75s.754 1.75 1.687 1.75 1.688-.783 1.688-1.75-.755-1.75-1.688-1.75zM9.57 14.505l7.752 8.12H3.664V20.63l5.906-6.125zm9.282 1.75l5.062 5.25v1.12h-4.192l-3.507-3.664 2.637-2.707z" />
</symbol>
<symbol id="recipe" viewBox="0 0 22 26">
<path d="M20.675 12.44c-.324-.604-.643-1.123-.868-1.533a5.058 5.058 0 0 1-.256-.516.808.808 0 0 1-.068-.244v-.005.001a.311.311 0 0 1 .054-.168.344.344 0 0 1 .116-.096.83.83 0 0 1 .135-.06l.096.045.25-.053c.53-.111.904-.529.904-1.011V7.733c0-.813-.743-1.47-1.662-1.471h-2.668c-.23-.425-.717-.72-1.284-.72h-4.035c-.567 0-1.053.296-1.284.72H8.23c-.203-.737-.762-2.216-2.261-4.017A8.064 8.064 0 0 0 4.489.91 5.94 5.94 0 0 0 3.376.287 3.487 3.487 0 0 0 2.051 0 2.454 2.454 0 0 0 .86.297a1.61 1.61 0 0 0-.664.677A1.779 1.779 0 0 0 0 1.801c0 .34.086.68.259.998.172.316.436.61.799.825.818.483 1.589 1.076 2.155 1.67.32.332.564.665.73.968h-.019c-.917 0-1.66.658-1.66 1.47v1.064c0 .487.381.907.915 1.014l.267.053.076-.04a.78.78 0 0 1 .112.049.363.363 0 0 1 .128.1.31.31 0 0 1 .057.173v.001a.77.77 0 0 1-.068.245c-.095.239-.296.596-.544 1.022-.742 1.285-1.904 3.225-1.905 5.645 0 .157.004.316.015.477.13 2.033.929 4.141 2.613 5.762C5.61 24.92 8.183 26.006 11.65 26c3.468.006 6.04-1.08 7.722-2.703 1.684-1.62 2.482-3.73 2.614-5.762.01-.161.014-.32.014-.477 0-1.844-.677-3.409-1.325-4.618zm-1.012-4.707v.866c-.221.026-.471.1-.733.245-.048.026-.093.064-.14.096h-1.937V7.48h2.523c.159 0 .287.113.287.253zM1.82 2.61a.886.886 0 0 1-.324-.342.991.991 0 0 1-.122-.468.7.7 0 0 1 .07-.318.346.346 0 0 1 .14-.151.938.938 0 0 1 .466-.115c.206 0 .464.057.742.173.417.171.864.469 1.238.775.374.304.68.62.831.802.97 1.167 1.5 2.17 1.786 2.87.058.142.104.269.144.385H5.405c-.216-.6-.628-1.168-1.142-1.712-.67-.702-1.525-1.356-2.442-1.899zm1.818 5.986v-.864c0-.14.128-.253.285-.254H9.96v1.46H4.512c-.062-.041-.124-.088-.188-.12a2.03 2.03 0 0 0-.685-.222zm16.974 8.869c-.115 1.804-.83 3.64-2.253 5.006-1.425 1.363-3.554 2.305-6.71 2.31-3.154-.005-5.283-.947-6.709-2.31-1.423-1.365-2.137-3.202-2.251-5.006a6.281 6.281 0 0 1-.014-.408c0-1.575.582-2.958 1.193-4.096.305-.57.615-1.074.862-1.521.123-.225.231-.435.315-.643.082-.208.146-.414.147-.652l-.002-.083a1.497 1.497 0 0 0-.06-.312h4.83v2.925c0 .531.49.962 1.09.962.6 0 1.091-.43 1.091-.962v-.621c0-.531.49-.966 1.09-.966.602 0 1.092.435 1.092.966v1.838c0 .617.564 1.12 1.265 1.12.696 0 1.265-.503 1.265-1.12V9.751h1.318c-.03.1-.052.203-.06.31l-.003.085c.002.239.065.444.148.652.147.362.367.74.616 1.171.749 1.286 1.756 3.022 1.753 5.09 0 .134-.003.27-.012.407z" />
</symbol>
Expand Down Expand Up @@ -333,6 +336,21 @@ const SvgSprite = () => {
</clipPath>
</defs>
</symbol>
<symbol id="error" viewBox="0 0 13 13">
<g clipPath="url(#a)">
<path
fill="#FD4545"
fillRule="evenodd"
d="M1.523 1.185c.24-.241.568-.377.909-.377h8.571a1.286 1.286 0 0 1 1.286 1.286v8.571a1.286 1.286 0 0 1-1.286 1.286H4.2l-3.377.844a.429.429 0 0 1-.51-.551l.834-2.505V2.094c0-.341.136-.668.377-.91zm5.789 2.019a.536.536 0 1 0-1.072 0V6.34a.536.536 0 1 0 1.072 0V3.204zM5.92 9.021a.855.855 0 1 1 1.71 0 .855.855 0 0 1-1.71 0z"
clipRule="evenodd"
/>
</g>
<defs>
<clipPath id="a">
<path fill="#fff" d="M0 0h12v12H0z" transform="translate(.29 .808)" />
</clipPath>
</defs>
</symbol>
</svg>
);
};
Expand Down
33 changes: 26 additions & 7 deletions src/components/Review/RebuyCheckbox/RebuyCheckbox.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
import { Checkbox } from '@fun-eat/design-system';
import type { ChangeEventHandler } from 'react';

import { check, checkbox, container } from './rebuyCheckbox.css';
import { itemTitle } from '../ReviewRegisterForm/reviewRegisterForm.css';

import { SvgIcon, Text } from '@/components/Common';
import { useEnterKeyDown } from '@/hooks/common';
import { useReviewFormActionContext } from '@/hooks/context';
import { vars } from '@/styles/theme.css';

interface RebuyCheckboxProps {
isRebuy: boolean;
}

const RebuyCheckbox = () => {
const RebuyCheckbox = ({ isRebuy }: RebuyCheckboxProps) => {
const { handleReviewFormValue } = useReviewFormActionContext();
const { inputRef, labelRef, handleKeydown } = useEnterKeyDown();

Expand All @@ -13,11 +21,22 @@ const RebuyCheckbox = () => {
};

return (
<p onKeyDown={handleKeydown}>
<Checkbox ref={labelRef} inputRef={inputRef} weight="bold" onChange={handleRebuy} tabIndex={0}>
재구매할 생각이 있으신가요?
</Checkbox>
</p>
<>
<h2 className={itemTitle} tabIndex={0}>
재구매 여부
</h2>
<p onKeyDown={handleKeydown}>
<label className={container} ref={labelRef}>
<input type="checkbox" className={checkbox} ref={inputRef} onChange={handleRebuy} tabIndex={0} />
<span className={isRebuy ? check.checked : check.default} aria-hidden>
<SvgIcon variant="check2" width={10} height={10} fill={isRebuy ? vars.colors.primary : vars.colors.white} />
</span>
<Text as="span" weight="semiBold">
재구매할 생각이 있어요
</Text>
</label>
</p>
</>
);
};

Expand Down
27 changes: 27 additions & 0 deletions src/components/Review/RebuyCheckbox/rebuyCheckbox.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { vars } from '@/styles/theme.css';
import { style, styleVariants } from '@vanilla-extract/css';

export const container = style({
display: 'inline-flex',
alignItems: 'center',
gap: 8,
cursor: 'pointer',
});

export const checkbox = style({
display: 'none',
});

const checkBase = style({
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
width: 17,
height: 17,
borderRadius: '50%',
});

export const check = styleVariants({
default: [checkBase, { backgroundColor: vars.colors.icon.light }],
checked: [checkBase, { backgroundColor: vars.colors.black }],
});
Loading
Loading