Skip to content

Commit

Permalink
feat : 감정 키워드 선택 구현 (#85)
Browse files Browse the repository at this point in the history
* feat : emotion select

* fix : 선택한 감정을 담는 배열 수정
  • Loading branch information
kangminguu authored Oct 31, 2024
1 parent 2e50b5e commit 8fc5990
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/features/diary-write/emotion/model/type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { Emotions } from '@/shared/model/EmotionEnum';

export interface EmotionButtonGroupProps {
initialKeywords?: (Emotions | null)[];
onKeywordsChange?: (keywords: (Emotions | null)[]) => void;
}
21 changes: 21 additions & 0 deletions src/features/diary-write/emotion/ui/EmotionButtonGroup.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { Meta, StoryObj } from '@storybook/react';
import { EmotionButtonGroup } from './EmotionButtonGroup';
import { Emotions } from '@/shared/model/EmotionEnum'; // Emotions 타입을 임포트

const meta: Meta<typeof EmotionButtonGroup> = {
title: 'Features/DiaryWrite/EmotionButtonGroup',
component: EmotionButtonGroup,
tags: ['autodocs']
};

export default meta;
type Story = StoryObj<typeof EmotionButtonGroup>;

export const Default: Story = {
args: {
initialKeywords: [null, null, null, null, null],
onKeywordsChange: (e) => {
console.log(e);
}
}
};
48 changes: 48 additions & 0 deletions src/features/diary-write/emotion/ui/EmotionButtonGroup.styled.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import styled from 'styled-components';

export const EmotionButtonContainer = styled.div`
max-width: 960px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 30px;
`;

export const Container = styled.div`
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
gap: 30px;
`;

export const MainKeywordContainer = styled.div`
font-size: 14px;
font-family: 'Pretendard', sans-serif;
color: #8c8c8c;
display: flex;
flex-direction: column;
align-items: start;
gap: 0.5rem;
`;

export const SubKeywordContainer = styled.div`
font-size: 14px;
font-family: 'Pretendard', sans-serif;
color: #8c8c8c;
display: flex;
flex-direction: column;
align-items: start;
gap: 0.5rem;
`;

export const SubContainer = styled.div`
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
justify-content: start;
gap: 0.5rem;
`;
84 changes: 84 additions & 0 deletions src/features/diary-write/emotion/ui/EmotionButtonGroup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import React, { useState } from 'react';
import { EmotionButtonGroupProps } from '../model/type';
import {
Container,
EmotionButtonContainer,
MainKeywordContainer,
SubKeywordContainer,
SubContainer
} from './EmotionButtonGroup.styled';
import EmotionButtonList from '@/shared/EmotionButtonList/ui/EmotionButtonList';
import { KeywordButton } from '@/entities/KeywordButton/ui/KeywordButton';
import { Emotions } from '@/shared/model/EmotionEnum';

export const EmotionButtonGroup: React.FC<EmotionButtonGroupProps> = ({
initialKeywords = [null, null, null, null, null],
onKeywordsChange
}) => {
const [keywords, setKeywords] =
useState<(Emotions | null)[]>(initialKeywords);
const [activeButton, setActiveButton] = useState(0);

const handleClickKeyword = (index: number) => {
setActiveButton(index);
setKeywords((prevKeywords) => {
const newKeywords = [...prevKeywords];
newKeywords[index] = null;
if (onKeywordsChange) {
onKeywordsChange(newKeywords); // 키워드 변화 이벤트 호출
}
return newKeywords;
});
};

const handleClickEmotion = (selectedEmotions: Emotions[]) => {
const newEmotion = selectedEmotions[0];

if (keywords[activeButton] !== newEmotion) {
setKeywords((prevKeywords) => {
const newKeywords = [...prevKeywords];
newKeywords[activeButton] = newEmotion;
if (onKeywordsChange) {
onKeywordsChange(newKeywords); // 키워드 변화 이벤트 호출
}
return newKeywords;
});

setActiveButton(activeButton !== 4 ? activeButton + 1 : 0);
}
};

return (
<EmotionButtonContainer>
<Container>
<MainKeywordContainer>
대표 키워드
<KeywordButton
selectedEmotion={keywords[0]}
isActive={activeButton === 0}
onClick={() => handleClickKeyword(0)}
/>
</MainKeywordContainer>
<SubKeywordContainer>
서브 키워드
<SubContainer>
{[1, 2, 3, 4].map((index) => (
<KeywordButton
key={index}
selectedEmotion={keywords[index]}
isActive={activeButton === index}
onClick={() => handleClickKeyword(index)}
/>
))}
</SubContainer>
</SubKeywordContainer>
</Container>
<EmotionButtonList
onSelectionChange={handleClickEmotion}
maxSelections={1}
isPrimary
initialSelectedEmotions={[keywords[activeButton]]}
/>
</EmotionButtonContainer>
);
};

0 comments on commit 8fc5990

Please sign in to comment.