Skip to content

Commit

Permalink
Merge pull request #275 from prgrms-web-devcourse-final-project/feature/
Browse files Browse the repository at this point in the history
#235

feat: PostRegisterPage 컴포넌트 개발 (1차)
  • Loading branch information
y0unj1NoH authored Dec 6, 2024
2 parents f290ae4 + 1928c17 commit 80ab33e
Show file tree
Hide file tree
Showing 20 changed files with 614 additions and 112 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,14 @@
"dayjs": "^1.11.13",
"firebase": "^11.0.2",
"framer-motion": "^11.11.17",
"immer": "^10.1.1",
"loadsh": "^0.0.4",
"lodash-es": "^4.17.21",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-hook-form": "^7.53.2",
"react-icons": "^5.3.0",
"react-image-file-resizer": "^0.4.8",
"react-naver-maps": "^0.1.3",
"react-router-dom": "^6.28.0",
"react-select": "^5.8.3",
Expand Down
20 changes: 13 additions & 7 deletions src/components/molecules/UploadedImageCounter/styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,16 @@ export const ImageUploadWrapper: ReturnType<typeof styled.div> = styled.div`
height: 100%;
`;

export const UploadedImageCounterContainer: ReturnType<typeof styled.div> =
styled.div`
background-color: #d9d9d9;
text-align: center;
padding: 1rem;
position: relative;
`;
export const UploadedImageCounterContainer: ReturnType<
typeof styled.div
> = styled.div`
background-color: #d9d9d9;
text-align: center;
padding: 1rem;
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
`;
2 changes: 0 additions & 2 deletions src/components/organisms/PostImageItem/styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import { Body1Wrapper } from "components/atoms/Text/styled";

export const PostImageItemWrapper: ReturnType<typeof styled.div> = styled.div`
position: relative;
max-width: 100px;
${IconButtonWrapper} {
position: absolute;
top: 0;
Expand Down
44 changes: 35 additions & 9 deletions src/components/organisms/PostImageManager/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,44 +4,70 @@ import { PostImageItem } from "components/organisms";

import { PostImageManagerWrapper, PostImageListWrapper } from "./styled";
import { IImageInfo } from "types";
import { convertToWebP } from "utils";

interface IPostImageManagerProps {
/** ImageInfo 배열 (url: S3에 업로드 된 이미지 url, base64Url: 아직 S3에 올라가지 않아서 미리보기만 제공되는 url, file: 아직 안올라간 이미지들을 나중에 S3에 올리기 위해 필요한 file)*/
imageInfos: IImageInfo[];
/** imageInfos를 설정하는 함수 */
setImageInfos: React.Dispatch<React.SetStateAction<IImageInfo[]>>;
/** disabled 여부 */
disabled?: boolean;
}

export const PostImageManager = ({
imageInfos,
setImageInfos
setImageInfos,
disabled = false
}: IPostImageManagerProps) => {
const onChange = useCallback(
(file: File) => {
async (file: File) => {
if (disabled) return;
const resizedFile = await convertToWebP(file);
const reader = new FileReader();
reader.onload = (e) => {
const base64Url = e.target?.result as string;
const newImgData: IImageInfo = {
url: "",
base64Url,
file
file: resizedFile as File // 변환 파일
};
setImageInfos((prev) => [...prev, newImgData]);
};
reader.readAsDataURL(file);
reader.readAsDataURL(resizedFile as File);
},
[setImageInfos]
[setImageInfos, disabled]
);

/**
* 라이브러리 안쓴 성능 저하 버전
*/
// const onChangeLegacy = useCallback(
// async (file: File) => {
// if (disabled) return;
// const reader = new FileReader();
// reader.onload = (e) => {
// const base64Url = e.target?.result as string;
// const newImgData: IImageInfo = {
// base64Url,
// file
// };
// setImageInfos((prev) => [...prev, newImgData]);
// };
// reader.readAsDataURL(file);
// },
// [setImageInfos, disabled]
// );

const handleRemoveImage = useCallback(
(index: number) => {
if (disabled) return;
setImageInfos((prev) => prev.filter((_, i) => i !== index));
},
[setImageInfos]
[setImageInfos, disabled]
);

return (
<PostImageManagerWrapper>
<PostImageManagerWrapper disabled={disabled}>
<UploadedImageCounter
text="사진 등록"
currentCount={imageInfos.length}
Expand All @@ -51,7 +77,7 @@ export const PostImageManager = ({
{imageInfos.map((info, index) => (
<Fragment key={index}>
<PostImageItem
imgUrl={(info.url || info.base64Url) as string}
imgUrl={info.base64Url as string}
isThumbnail={index === 0}
onClick={() => handleRemoveImage(index)}
/>
Expand Down
32 changes: 32 additions & 0 deletions src/components/organisms/PostImageManager/stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ const meta: Meta<typeof PostImageManager> = {
setImageInfos: {
action: "setImageInfos",
description: "imageInfos를 설정하는 함수"
},
disabled: {
control: {
type: "boolean"
},
description: "비활성화 여부"
}
}
};
Expand Down Expand Up @@ -64,4 +70,30 @@ export const ImageExist: Story = {
}
};

export const Disabled: Story = {
args: {
imageInfos: [
{ url: "https://github.com/moypp.png", base64Url: "", file: undefined },
{ url: "https://github.com/ppyom.png", base64Url: "", file: undefined },
{ url: "https://github.com/moypp.png", base64Url: "", file: undefined },
{ url: "https://github.com/ppyom.png", base64Url: "", file: undefined }
]
},
render: (args) => {
const Component = () => {
const [imageInfos, setImageInfos] = useState<IImageInfo[]>(
args.imageInfos
);
return (
<PostImageManager
imageInfos={imageInfos}
setImageInfos={setImageInfos}
disabled={true}
/>
);
};
return <Component />;
}
};

export default meta;
32 changes: 29 additions & 3 deletions src/components/organisms/PostImageManager/styled.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,38 @@
import styled from "@emotion/styled";
import { UploadedImageCounterContainer } from "components/molecules/UploadedImageCounter/styled";
import { PostImageItemWrapper } from "components/organisms/PostImageItem/styled";
interface PostImageManagerWrapperProps {
disabled?: boolean;
}

export const PostImageManagerWrapper: ReturnType<
typeof styled.div
> = styled.div`
typeof styled.div<PostImageManagerWrapperProps>
> = styled.div<PostImageManagerWrapperProps>`
display: flex;
flex-wrap: nowrap;
overflow-x: auto;
width: 100%;
${({ disabled }) =>
disabled &&
`
& * {
pointer-events: none;
}
`}
${UploadedImageCounterContainer}, ${PostImageItemWrapper} {
width: 106px;
aspect-ratio: 1 / 1;
${({ disabled }) =>
disabled &&
`
filter: grayscale(1);
`}
}
`;

export const PostImageListWrapper: ReturnType<typeof styled.div> = styled.div`
display: flex;
`;

Loading

0 comments on commit 80ab33e

Please sign in to comment.