Skip to content

Commit

Permalink
Merge pull request #66 from soma-dalda/feat/#65
Browse files Browse the repository at this point in the history
[#65] 💄 👽 : API 변경에 따른 타입 변경 및 컴포넌트 구현
  • Loading branch information
jaewoong2 authored Oct 17, 2022
2 parents d1832b2 + aebe7ed commit 3674e1f
Show file tree
Hide file tree
Showing 11 changed files with 95 additions and 44 deletions.
2 changes: 1 addition & 1 deletion src/mocks/constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const MOCK_TEMPLATE: Template = {
userId: '1',
title: '기본 주문서',
required: true,
content: [
contentList: [
{
type: 'singleObjective',
question: '케이크 호수를 정해주세요.',
Expand Down
21 changes: 14 additions & 7 deletions src/pages/Order/components/blocks/Order.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,13 @@ const Order = () => {
return <LoadingPage />
}

const content = template?.content[current]
const content = template?.contentList[current]

return (
<Layout navigtaion={<NavigationWithArrow>{template?.title}</NavigationWithArrow>}>
{template?.content && (
{template?.contentList && (
<Stepper
steps={template?.content?.length}
steps={template?.contentList?.length}
current={current}
handleClickStep={handleClickStep}
/>
Expand All @@ -41,7 +42,7 @@ const Order = () => {
img={content.img}
detailType={content.type}
answer={order.answers[current]}
questionTitle={content.question}
questionTitle={`${content?.required && '(*)'} ${content.question}`}
options={content.options}
handleChangeOption={
content.type === 'multiObjective'
Expand All @@ -53,18 +54,24 @@ const Order = () => {
{content?.type === 'subjective' && (
<QuestionDescription
img={content.img}
questionTitle={content?.question}
questionTitle={`${content?.required && '(*)'} ${content.question}`}
handleChangeDescription={handleChangeTextArea(current)}
description={order.answers[current]}
/>
)}
</form>
{current + 1 === order.answers.length ? (
<OrderBottomLink active={Boolean(order.answers[current])} to="../pickup">
<OrderBottomLink
active={content?.required === false ? true : Boolean(order.answers[current])}
to="../pickup"
>
픽업 날짜 설정하기
</OrderBottomLink>
) : (
<OrderBottomLink active={Boolean(order.answers[current])} to={`#${current + 1}`}>
<OrderBottomLink
active={content?.required === false ? true : Boolean(order.answers[current])}
to={`#${current + 1}`}
>
다음
</OrderBottomLink>
)}
Expand Down
2 changes: 1 addition & 1 deletion src/pages/Order/context/OrderContextProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const OrderContextProvider = ({ children }: PropsWithChildren) => {
...prev,
companyId: data.userId,
templateId: id,
answers: Array(data?.content.length).fill(''),
answers: Array(data?.contentList.length).fill(''),
}))
},
onError: (err) => {
Expand Down
2 changes: 1 addition & 1 deletion src/pages/Orders/components/blocks/OrderConfirm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const OrderConfirm = () => {
<section className="mt-3 w-full">
<h2 className="mb-7 text-lg font-semibold">{order?.id}님의 주문요청</h2>
<section className="flex flex-col gap-7">
{template?.content.map((question, index) => (
{template?.contentList.map((question, index) => (
<Question
question={question.question}
answer={order?.templateResponses?.[index].answer}
Expand Down
13 changes: 11 additions & 2 deletions src/pages/Templates/components/atoms/CheckBox.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
import clsx from 'clsx'
import React from 'react'

const CheckBox = ({ id, children, ...props }: JSX.IntrinsicElements['input']) => {
const CheckBox = ({
id,
children,
labelClassName,
...props
}: JSX.IntrinsicElements['input'] & { labelClassName?: string }) => {
return (
<label htmlFor={id} className="flex items-center justify-end gap-1 p-2 text-xs">
<label
htmlFor={id}
className={clsx('flex items-center justify-end gap-1 p-2 text-xs', labelClassName)}
>
<input id={id} type="checkbox" {...props} />
<p>{children}</p>
</label>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,21 @@ import { CancleButton } from '@/components/atoms'
import React from 'react'
import useTemplateActionContext from '../../hooks/useTemplateActionContext'
import useTemplateValueContext from '../../hooks/useTemplateValueContext'
import CheckBox from '../atoms/CheckBox'
import QuestionImageUpload from './QuestionImageUpload'

type Props = {
index: number
}

const TemplateDescriptionQuestion = ({ index }: Props) => {
const { content } = useTemplateValueContext()
const { handleDeleteQuestion, handleUpdateQuestionTitle, handleUpdateImage } =
useTemplateActionContext()
const { contentList: content } = useTemplateValueContext()
const {
handleDeleteQuestion,
handleUpdateRequired,
handleUpdateQuestionTitle,
handleUpdateImage,
} = useTemplateActionContext()

return (
<section className="mt-8 flex w-full flex-col">
Expand All @@ -34,6 +39,13 @@ const TemplateDescriptionQuestion = ({ index }: Props) => {
onChange={handleUpdateQuestionTitle(index)}
/>
</div>
<CheckBox
id={`필수값-${index}`}
checked={content[index]?.required}
onChange={handleUpdateRequired(index)}
>
필수 질문
</CheckBox>
</section>
)
}
Expand Down
26 changes: 18 additions & 8 deletions src/pages/Templates/components/blocks/TemplateOptionQuestion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ type Props = {
}

const TemplateOptionQuestion = ({ index }: Props) => {
const { content } = useTemplateValueContext()
const { contentList: content } = useTemplateValueContext()
const {
handleUpdateQuestionTitle,
handleDeleteQuestion,
Expand All @@ -20,6 +20,7 @@ const TemplateOptionQuestion = ({ index }: Props) => {
handleAddOption,
handleUpdateImage,
handleUpdateDetailType,
handleUpdateRequired,
} = useTemplateActionContext()

const handleCheckboxChange = (e: React.ChangeEvent<HTMLInputElement>) => {
Expand Down Expand Up @@ -82,13 +83,22 @@ const TemplateOptionQuestion = ({ index }: Props) => {
옵션 추가
</button>
</div>
<CheckBox
id={`옵션타입-${index}`}
checked={content[index]?.type === 'singleObjective'}
onChange={handleCheckboxChange}
>
단일선택
</CheckBox>
<div className="flex w-full justify-end">
<CheckBox
id={`필수값-${index}`}
checked={content[index]?.required}
onChange={handleUpdateRequired(index)}
>
필수 질문
</CheckBox>
<CheckBox
id={`옵션타입-${index}`}
checked={content[index]?.type === 'singleObjective'}
onChange={handleCheckboxChange}
>
단일선택
</CheckBox>
</div>
</section>
)
}
Expand Down
2 changes: 1 addition & 1 deletion src/pages/Templates/components/pages/Template.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const Template = () => {
주문서 이름
</TemplateTitleInput>
{/* 질문 들 */}
<Questions content={template?.content ?? []} />
<Questions content={template?.contentList ?? []} />
{/* 주문서 바텀 */}
</form>
</Layout>
Expand Down
5 changes: 3 additions & 2 deletions src/pages/Templates/context/TemplateContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@ import { createContext } from 'react'

export const defaultValue: Template = {
id: '',
content: [],
contentList: [],
title: '',
userId: '',
required: true,
}

type TemplateAction = {
Expand Down Expand Up @@ -39,6 +38,7 @@ type TemplateAction = {
handleUpdateTemplate: (template: Template) => void
handleResetTemplate: () => void
handleUpdateImage: (index: number) => (imageUrl: string) => void
handleUpdateRequired: (index: number) => () => void
}

const defaultAction: TemplateAction = {
Expand All @@ -53,6 +53,7 @@ const defaultAction: TemplateAction = {
handleUpdateTemplate: () => {},
handleResetTemplate: () => {},
handleUpdateImage: () => () => {},
handleUpdateRequired: () => () => {},
}

export const TemplateValueContext = createContext(defaultValue)
Expand Down
43 changes: 27 additions & 16 deletions src/pages/Templates/context/TemplateContextProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,16 @@ const TemplateContextProvider = ({ children }: PropsWithChildren) => {
const handleUpdateImage = useCallback(
(index: number) => (imageUrl: string) => {
setTemplate((draft) => {
draft.content[index].img = imageUrl
draft.contentList[index].img = imageUrl
})
},
[]
)

const handleUpdateRequired = useCallback(
(index: number) => () => {
setTemplate((draft) => {
draft.contentList[index].required = !draft.contentList[index].required
})
},
[]
Expand All @@ -64,41 +73,41 @@ const TemplateContextProvider = ({ children }: PropsWithChildren) => {
const handleAddQuestion = useCallback((type: Question['type']) => {
setTemplate((draft) => {
if (type === 'multiObjective' || type === 'singleObjective') {
draft.content = [...draft.content, defaultOptionQuestion]
draft.contentList = [...draft.contentList, defaultOptionQuestion]
}
if (type === 'subjective') {
draft.content = [...draft.content, defaultDescriptionQuestion]
draft.contentList = [...draft.contentList, defaultDescriptionQuestion]
}
})
}, [])
const handleDeleteQuestion = useCallback((index: number) => {
setTemplate((draft) => {
draft.content = draft.content.filter((_, i) => i !== index)
draft.contentList = draft.contentList.filter((_, i) => i !== index)
})
}, [])
const handleUpdateQuestionTitle = useCallback(
(index: number) => (e: React.ChangeEvent<HTMLInputElement>) => {
setTemplate((draft) => {
draft.content[index].question = e.target.value
draft.contentList[index].question = e.target.value
})
},
[]
)
const handleAddOption = useCallback((index: number) => {
setTemplate((draft) => {
const content = draft.content[index]
if (content.type === 'multiObjective' || content.type === 'singleObjective') {
content.options = [...content.options, '']
const contentList = draft.contentList[index]
if (contentList.type === 'multiObjective' || contentList.type === 'singleObjective') {
contentList.options = [...contentList.options, '']
}
})
}, [])
const handleUpdateOption = useCallback(
({ contentIndex, optionIndex }: { contentIndex: number; optionIndex: number }) =>
(e: React.ChangeEvent<HTMLInputElement>) => {
setTemplate((draft) => {
const content = draft.content[contentIndex]
if (content.type === 'multiObjective' || content.type === 'singleObjective') {
content.options[optionIndex] = e.target.value
const contentList = draft.contentList[contentIndex]
if (contentList.type === 'multiObjective' || contentList.type === 'singleObjective') {
contentList.options[optionIndex] = e.target.value
}
})
},
Expand All @@ -108,9 +117,9 @@ const TemplateContextProvider = ({ children }: PropsWithChildren) => {
({ contentIndex, optionIndex }: { contentIndex: number; optionIndex: number }) =>
() => {
setTemplate((draft) => {
const content = draft.content[contentIndex]
if (content.type === 'multiObjective' || content.type === 'singleObjective') {
content.options = content.options.filter((_, i) => i !== optionIndex)
const contentList = draft.contentList[contentIndex]
if (contentList.type === 'multiObjective' || contentList.type === 'singleObjective') {
contentList.options = contentList.options.filter((_, i) => i !== optionIndex)
}
})
},
Expand All @@ -119,8 +128,8 @@ const TemplateContextProvider = ({ children }: PropsWithChildren) => {
const handleUpdateDetailType = useCallback(
({ contentIndex, detailType }: { contentIndex: number; detailType: Question['type'] }) => {
setTemplate((draft) => {
const content = draft.content[contentIndex]
content.type = detailType
const contentList = draft.contentList[contentIndex]
contentList.type = detailType
})
},
[]
Expand All @@ -136,6 +145,7 @@ const TemplateContextProvider = ({ children }: PropsWithChildren) => {
handleUpdateOption,
handleDeleteOption,
handleUpdateDetailType,
handleUpdateRequired,
handleUpdateTemplate,
handleResetTemplate,
handleUpdateImage,
Expand All @@ -152,6 +162,7 @@ const TemplateContextProvider = ({ children }: PropsWithChildren) => {
handleUpdateTemplate,
handleResetTemplate,
handleUpdateImage,
handleUpdateRequired,
]
)

Expand Down
5 changes: 3 additions & 2 deletions src/type/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,15 @@ export type OptionQuestion = {
question: string
img?: string
options: string[]
required?: boolean
}

export type DescriptionQuestion = {
type: DescriptionQuestionType
question: string
img?: string
options: null
required?: boolean
}

export type Question = OptionQuestion | DescriptionQuestion
Expand All @@ -67,8 +69,7 @@ export type Template = {
id: string
userId: string
title: string
content: Question[]
required?: boolean
contentList: Question[]
}

export type Templates = {
Expand Down

0 comments on commit 3674e1f

Please sign in to comment.