Skip to content

Commit

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

feat: ChatOverview 컴포넌트 개발
  • Loading branch information
JW-Ahn0 authored Nov 29, 2024
2 parents ed199e6 + 6af8636 commit 331cb76
Show file tree
Hide file tree
Showing 4 changed files with 254 additions and 0 deletions.
124 changes: 124 additions & 0 deletions src/components/organisms/ChatOverview/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import {} from "components/atoms";
import { TabItem } from "components/molecules";
import { ChatList } from "components/organisms";
import { ChatOverviewRootWrapper, ListWrapper, PanelWrapper } from "./styled";
import {
type Context,
createContext,
useContext,
useEffect,
useState
} from "react";

import { IChatItemProps } from "components/organisms/ChatItem";

interface IChatOverviewRootProps {
children: React.ReactNode;
}

interface IChatOverviewContextProps {
/** 선택된 인덱스 */
selectedIndex: number;
/** 선택된 인덱스 변경 함수 */
setSelectedIndex: React.Dispatch<React.SetStateAction<number>> | undefined;
}

const ChatOverviewContext: Context<IChatOverviewContextProps> =
createContext<IChatOverviewContextProps>({
selectedIndex: 0,
setSelectedIndex: undefined
});

/**
* ChatOverview 하위 컴포넌트에서 사용되는지 검사를 위한 훅
*/
const useChatOverview = () => {
const context = useContext(ChatOverviewContext);
if (!context) {
throw new Error("Modal Context 내에서만 사용 가능합니다.");
}
return context;
};

/* -------------------------------------------------------------------
* ChatOverview Root
* ------------------------------------------------------------------- */

const ChatOverviewRoot = ({ children }: IChatOverviewRootProps) => {
const [selectedIndex, setSelectedIndex] = useState(0);

const providerValue = { selectedIndex, setSelectedIndex };

return (
<ChatOverviewContext.Provider value={providerValue}>
<ChatOverviewRootWrapper>{children}</ChatOverviewRootWrapper>
</ChatOverviewContext.Provider>
);
};

/* -------------------------------------------------------------------
* List
* ------------------------------------------------------------------- */

const List = ({ children }: IChatOverviewRootProps) => {
return <ListWrapper>{children}</ListWrapper>;
};

/* -------------------------------------------------------------------
* Trigger
* ------------------------------------------------------------------- */

interface ITriggerProps {
index: number;
title: string;
}

const Trigger = ({ index, title }: ITriggerProps) => {
const { selectedIndex, setSelectedIndex } = useChatOverview();
const isActive = selectedIndex === index ? "active" : "default";

const onSelect = () => {
if (setSelectedIndex) {
setSelectedIndex(index);
}
};

return <TabItem state={isActive} title={title} onClick={onSelect}></TabItem>;
};

/* -------------------------------------------------------------------
* Panel
* ------------------------------------------------------------------- */

interface IPanelProps {
index: number;
chatItems: IChatItemProps[];
}

const Panel = ({ index, chatItems }: IPanelProps) => {
const { selectedIndex } = useChatOverview();
const isActive = selectedIndex === index;

return (
isActive && (
<PanelWrapper>
<ChatList chatItems={chatItems} />
</PanelWrapper>
)
);
};

/* -------------------------------------------------------------------
* Export
* ------------------------------------------------------------------- */

export const ChatOverview: typeof ChatOverviewRoot & {
List: typeof List;
Trigger: typeof Trigger;
Panel: typeof Panel;
} = Object.assign(ChatOverviewRoot, {
List: List,
Trigger: Trigger,
Panel: Panel
});

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

const meta: Meta = {
title: "Organisms/ChatOverview",
tags: ["autodocs"],
argTypes: {
allChatItems: {
control: "object",
description: "전체 채팅방 목록"
},
sellingChatItems: {
control: "object",
description: "판매 채팅방 목록"
},
buyingChatItems: {
control: "object",
description: "구매 채팅방 목록"
},
unreadChatItems: {
control: "object",
description: "읽지 않은 채팅방 목록"
}
}
};

type Story = StoryObj<typeof meta>;

const commonArgs: {
profileImgUrl: string;
itemImgUrl: string;
name: string;
onClick: () => void;
} = {
profileImgUrl: "https://github.com/moypp.png",
itemImgUrl: "https://github.com/ppyom.png",
name: "username",

onClick: () => console.log("chatItem 클릭")
};

export const Default: Story = {
args: {
allChatItems: [
{
...commonArgs,
lastMsg: "(판매) last message",
lastMsgCnt: 0,
lastMsgTime: "2024-11-26T06:24:31:22"
},
{
...commonArgs,
lastMsg: "(구매) last message",
lastMsgCnt: 100,
lastMsgTime: "2024-11-17T06:24:31:22"
},
{
...commonArgs,
lastMsg: "(구매) last message",
lastMsgCnt: 0,
lastMsgTime: "2024-11-17T06:24:31:22"
}
],
sellingChatItems: [
{
...commonArgs,
lastMsg: "(판매) last message",
lastMsgCnt: 0,
lastMsgTime: "2024-11-26T06:24:31:22"
}
],
buyingChatItems: [
{
...commonArgs,
lastMsg: "(구매) last message",
lastMsgCnt: 100,
lastMsgTime: "2024-11-26T06:24:31:22"
},
{
...commonArgs,
lastMsg: "(구매) last message",
lastMsgCnt: 0,
lastMsgTime: "2024-11-17T06:24:31:22"
}
],
unreadChatItems: [
{
...commonArgs,
lastMsg: "(구매) last message",
lastMsgCnt: 100,
lastMsgTime: "2024-11-26T06:24:31:22"
}
]
},
render: (args) => {
return (
<ChatOverview>
<ChatOverview.List>
<ChatOverview.Trigger index={0} title="전체" />
<ChatOverview.Trigger index={1} title="판매" />
<ChatOverview.Trigger index={2} title="구매" />
<ChatOverview.Trigger index={3} title="안 읽은 채팅방" />
</ChatOverview.List>
<ChatOverview.Panel index={0} chatItems={args.allChatItems} />
<ChatOverview.Panel index={1} chatItems={args.sellingChatItems} />
<ChatOverview.Panel index={2} chatItems={args.buyingChatItems} />
<ChatOverview.Panel index={3} chatItems={args.unreadChatItems} />
</ChatOverview>
);
}
};

export default meta;

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

export const ChatOverviewRootWrapper: ReturnType<
typeof styled.div
> = styled.div`
display: flex;
flex-direction: column;
`;

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

export const PanelWrapper: ReturnType<typeof styled.div> = styled.div``;

1 change: 1 addition & 0 deletions src/components/organisms/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export { SearchHistoryItem } from "./SearchHistoryItem";

export { ChatMessage } from "./ChatMessage";
export { ChatBubble } from "./ChatBubble";
export { ChatList } from "./ChatList";

0 comments on commit 331cb76

Please sign in to comment.