Skip to content

Commit

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

feat: PostImageManager 컴포넌트 개발
  • Loading branch information
JW-Ahn0 authored Nov 28, 2024
2 parents 4113436 + 19043fc commit 52e9838
Show file tree
Hide file tree
Showing 7 changed files with 152 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/components/molecules/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ export { TabItem } from "./TabItem";
export { TabMenu } from "./TabMenu";
export { TextDividerList } from "./TextDividerList";
export { TextWithImage } from "./TextWithImage";
export { UploadedImageCounter } from "./UploadedImageCounter";
64 changes: 64 additions & 0 deletions src/components/organisms/PostImageManager/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { Fragment, useCallback, useEffect } from "react";
import { UploadedImageCounter } from "components/molecules";
import { PostImageItem } from "components/organisms";

import { PostImageManagerWrapper, PostImageListWrapper } from "./styled";
import { ImageInfo } from "types";

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

export const PostImageManager = ({
imageInfos,
setImageInfos
}: IPostImageManagerProps) => {
const onChange = useCallback(
(file: File) => {
const reader = new FileReader();
reader.onload = (e) => {
const base64Url = e.target?.result as string;
const newImgData: ImageInfo = {
url: "",
base64Url,
file
};
setImageInfos((prev) => [...prev, newImgData]);
};
reader.readAsDataURL(file);
},
[setImageInfos]
);

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

return (
<PostImageManagerWrapper>
<UploadedImageCounter
text="사진 등록"
currentCount={imageInfos.length}
onChange={onChange}
/>
<PostImageListWrapper>
{imageInfos.map((info, index) => (
<Fragment key={index}>
<PostImageItem
imgUrl={(info.url || info.base64Url) as string}
isThumbnail={index === 0}
onClick={() => handleRemoveImage(index)}
/>
</Fragment>
))}
</PostImageListWrapper>
</PostImageManagerWrapper>
);
};

68 changes: 68 additions & 0 deletions src/components/organisms/PostImageManager/stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { useState } from "react";
import type { Meta, StoryObj } from "@storybook/react";
import { PostImageManager } from ".";
import { ImageInfo } from "types";

const meta: Meta<typeof PostImageManager> = {
title: "Organisms/PostImageManager",
component: PostImageManager,
tags: ["autodocs"],
argTypes: {
imageInfos: {
control: {
type: "object"
},
description:
"ImageInfo 배열 (url: S3에 업로드 된 이미지 url, base64Url: 아직 S3에 올라가지 않아서 미리보기만 제공되는 url, file: 아직 안올라간 이미지들을 나중에 S3에 올리기 위해 필요한 file)"
},
setImageInfos: {
action: "setImageInfos",
description: "imageInfos를 설정하는 함수"
}
}
};

type Story = StoryObj<typeof meta>;

export const Default: Story = {
render: (args) => {
const Component = () => {
const [imageInfos, setImageInfos] = useState<ImageInfo[]>([]);
return (
<PostImageManager
imageInfos={imageInfos}
setImageInfos={setImageInfos}
/>
);
};
return <Component />;
}
};

export const ImageExist: 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<ImageInfo[]>(
args.imageInfos
);
return (
<PostImageManager
imageInfos={imageInfos}
setImageInfos={setImageInfos}
/>
);
};
return <Component />;
}
};

export default meta;

12 changes: 12 additions & 0 deletions src/components/organisms/PostImageManager/styled.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import styled from "@emotion/styled";

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

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

1 change: 1 addition & 0 deletions src/components/organisms/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { Map } from "./Map";
export { PostImageItem } from "./PostImageItem";
export { SearchHistoryItem } from "./SearchHistoryItem";
5 changes: 5 additions & 0 deletions src/types/image.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface ImageInfo {
url?: string;
base64Url?: string;
file?: File;
}
1 change: 1 addition & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from "./icon";
export * from "./image";
export * from "./map";
export * from "./selectOption";
export * from "./navMenu";
Expand Down

0 comments on commit 52e9838

Please sign in to comment.