Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
'use client'

import classNames from 'classnames/bind'

import { QuestionStatusType } from '@/shared/types/questions'
import Avatar from '@/shared/ui/avatar'
import Label from '@/shared/ui/label'
import { formatDateTime } from '@/shared/utils/format'

import { QuestionCardProps } from '../../../_ui/question-card'
import styles from './styles.module.scss'

const cx = classNames.bind(styles)

type QuestionDetailCardType = 'question' | 'answer'

interface Props extends QuestionCardProps {
type?: QuestionDetailCardType
strategyName?: string
title?: string
status?: QuestionStatusType
isAuthor: boolean
onDelete?: () => void
}

const QuestionDetailCard = ({
profileImage,
nickname,
contents,
type = 'question',
status,
strategyName,
title = '답변',
createdAt,
isAuthor,
onDelete,
}: Props) => {
return (
<div className={cx('card-container')}>
<div className={cx('card-header')}>
{type === 'question' && (
<div className={cx('top-wrapper')}>
<strong className={cx('strategy-name')}>{strategyName}</strong>
<Label color={status === '답변 완료' ? 'indigo' : 'orange'}>{status}</Label>
</div>
)}
<h2 className={cx('title', type)}>{title}</h2>
<div className={cx('bottom-wrapper')}>
<div className={cx('avatar-wrapper')}>
<Avatar src={profileImage} size="medium" />
<span>{nickname}</span>
<span className={cx('created-at')}>ㅣ {formatDateTime(createdAt)}</span>
</div>
{isAuthor && (
<button type="button" className={cx('delete-button')} onClick={onDelete}>
삭제
</button>
)}
</div>
</div>
<div className={cx('card-contents')}>{contents}</div>
</div>
)
}

export default QuestionDetailCard
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { Meta, StoryFn } from '@storybook/react'

import QuestionDetailCard from '.'

const meta: Meta = {
title: 'Components/QuestionDetailCard',
component: QuestionDetailCard,
tags: ['autodocs'],
}

const Template: StoryFn<typeof QuestionDetailCard> = (args) => (
<div style={{ width: '900px', padding: '20px', backgroundColor: '#f8f9fa' }}>
<QuestionDetailCard {...args} />
</div>
)

export const Question = Template.bind({})
Question.args = {
type: 'question',
strategyName: '엄청난 전략',
title: '미국발 경제악화가 한국 증시에 미치는 영향은 무엇인가요?',
contents:
'안녕하세요. 주식투자를 시작하려고 하는데 미국의 경제 상황이 좋지 않다고 들었습니다. 이런 상황에서 한국 증시는 어떤 영향을 받을까요? 구체적인 설명 부탁드립니다.',
nickname: '투자초보',
profileImage: '',
createdAt: '2024-11-03T15:00:00',
status: '답변 대기',
isAuthor: false,
onDelete: () => alert('삭제 버튼 클릭'),
}

export const QuestionWithDeleteButton = Template.bind({})
QuestionWithDeleteButton.args = {
...Question.args,
isAuthor: true,
}

export const Answer = Template.bind({})
Answer.args = {
type: 'answer',
title: '답변',
contents:
'안녕하세요. 문의하신 내용에 대해 답변드리겠습니다. 미국과 한국 증시는 높은 상관관계를 보이고 있어 미국의 경제 상황이 한국 증시에 큰 영향을 미칠 수 있습니다. 구체적으로는...',
nickname: '전문가',
profileImage: '',
createdAt: '2024-11-03T16:30:00',
isAuthor: false,
onDelete: () => alert('삭제 버튼 클릭'),
}

export const AnswerWithDeleteButton = Template.bind({})
AnswerWithDeleteButton.args = {
...Answer.args,
isAuthor: true,
}

export default meta
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
@import '../../../_ui/question-card/card-mixins.scss';

.card-container {
@include card-base;
padding: 35px 40px;
}

.top-wrapper {
display: flex;
align-items: center;
justify-content: space-between;

.strategy-name {
@include card-subtitle;
}
}

.title {
@include card-title;
margin-bottom: 18px;

&.answer {
@include typo-b1;
}
}

.bottom-wrapper {
display: flex;
align-items: center;
justify-content: space-between;
padding-bottom: 12px;
margin-bottom: 24px;
border-bottom: 1px solid $color-gray-300;

.delete-button {
@include typo-c1;
background-color: transparent;
}
}

.avatar-wrapper {
@include avatar-group;

.created-at {
margin-left: -8px;
color: $color-gray-400;
}
}

.card-contents {
color: $color-gray-600;
@include typo-b3;
line-height: 140%;
}
40 changes: 40 additions & 0 deletions app/(dashboard)/my/questions/_ui/question-card/card-mixins.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
@mixin card-base {
padding: 24px 40px 16px;
border-radius: 8px;
background-color: $color-white;
}

@mixin card-subtitle {
@include typo-b2;
color: $color-orange-600;
}

@mixin card-created-at {
@include typo-b3;
color: $color-gray-400;
}

@mixin card-top {
display: flex;
align-items: center;
justify-content: space-between;
}

@mixin card-title {
margin: 12px 0 8px;
@include typo-h4;
}

@mixin card-bottom {
display: flex;
align-items: center;
justify-content: space-between;
}

@mixin avatar-group {
display: flex;
align-items: center;
gap: 16px;
color: $color-gray-600;
@include typo-b3;
}
9 changes: 6 additions & 3 deletions app/(dashboard)/my/questions/_ui/question-card/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@ import styles from './styles.module.scss'

const cx = classNames.bind(styles)

interface Props {
strategyName: string
title: string
export interface QuestionCardProps {
contents: string
nickname: string
profileImage?: string
createdAt: string
}

interface Props extends QuestionCardProps {
strategyName: string
title: string
status: QuestionStatusType
}

Expand Down
25 changes: 8 additions & 17 deletions app/(dashboard)/my/questions/_ui/question-card/styles.module.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@import './card-mixins.scss';

.card-container {
padding: 24px 40px 16px;
border-radius: 8px;
background-color: $color-white;
@include card-base;
}

.top-wrapper {
Expand All @@ -10,19 +10,16 @@
justify-content: space-between;

.strategy-name {
@include typo-b2;
color: $color-orange-600;
@include card-subtitle;
}

.created-at {
@include typo-b3;
color: $color-gray-400;
@include card-created-at;
}
}

.title {
margin: 12px 0 8px;
@include typo-h4;
@include card-title;
}

.contents {
Expand All @@ -33,15 +30,9 @@
}

.bottom-wrapper {
display: flex;
align-items: center;
justify-content: space-between;
@include card-bottom;
}

.avatar-wrapper {
display: flex;
align-items: center;
gap: 16px;
color: $color-gray-600;
@include typo-b3;
@include avatar-group;
}