-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WRFE-48] 래플/이벤트 수정 페이지 #50
base: dev
Are you sure you want to change the base?
Changes from 13 commits
b1720c2
7b6f33f
9e566e6
f0921fd
317bd1c
a80e3fc
83d1fb9
81487ba
09e2e82
c901c75
29d6cff
a9c6708
4e1f418
dc39c87
17b7a0f
1ff0234
825710c
3832569
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
'use client'; | ||
|
||
import { | ||
createRaffleSchema, | ||
type CreateRafflePayload, | ||
} from '@/entities/product/model'; | ||
import {Header} from '@/shared/ui'; | ||
import GenericForm from '@/shared/ui/form/GenericForm'; | ||
import {EditList} from '@/widgets/product-list/edit/ui'; | ||
import {zodResolver} from '@hookform/resolvers/zod'; | ||
import {Typography} from '@wraffle/ui'; | ||
|
||
// 조회 api 연결시 삭제할 코드 입니다 | ||
const product = { | ||
title: 'test Title', | ||
categoryId: '1', | ||
tagIds: [1, 2], | ||
images: ['/1', '/2', '/3'], | ||
price: '999999', | ||
startDate: new Date(), | ||
endDate: new Date(), | ||
announceAt: new Date(), | ||
winnerCount: '99', | ||
etc: 'test ETC', | ||
}; | ||
|
||
const Edit = ({ | ||
params: {id}, | ||
searchParams: {type}, | ||
}: { | ||
params: {id: string}; | ||
searchParams: {type: 'raffle' | 'event'}; | ||
}) => { | ||
const onSubmit = (data: CreateRafflePayload) => { | ||
console.log(data); | ||
}; | ||
|
||
return ( | ||
<div> | ||
<div className='my-5'> | ||
<Header withUnderline> | ||
<Header.Left> | ||
<Header.BackButton /> | ||
</Header.Left> | ||
<Header.Middle> | ||
<Typography className='text-sm font-semibold text-[#191F28]'> | ||
래플 수정 | ||
</Typography> | ||
</Header.Middle> | ||
</Header> | ||
</div> | ||
|
||
<GenericForm | ||
onSubmit={onSubmit} | ||
formOptions={{ | ||
mode: 'onSubmit', | ||
resolver: zodResolver(createRaffleSchema), | ||
defaultValues: product, | ||
}} | ||
> | ||
<EditList type={type} /> | ||
</GenericForm> | ||
</div> | ||
); | ||
}; | ||
|
||
export default Edit; |
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export {AddItemCard} from './ui/AddItemCard'; | ||
export {ImageCardWithDelete} from './ui/ImageCardWithDelete'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
'use client'; | ||
|
||
import clsx from 'clsx'; | ||
|
||
export const AddItemCard = ({ | ||
label, | ||
onClick, | ||
className, | ||
}: { | ||
label: string; | ||
onClick: () => void; | ||
className: string; | ||
}) => ( | ||
<button | ||
className={clsx( | ||
'relative flex aspect-square items-center justify-center rounded-lg border border-solid border-[#F5F5F7] bg-[#FAFAFB] text-sm font-medium text-[#ADB5BD]', | ||
className, | ||
)} | ||
onClick={onClick} | ||
> | ||
{label} | ||
</button> | ||
); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
'use client'; | ||
|
||
import clsx from 'clsx'; | ||
import Image from 'next/image'; | ||
|
||
export const ImageCardWithDelete = ({ | ||
url, | ||
onClick, | ||
className, | ||
}: { | ||
url: string; | ||
onClick: () => void; | ||
className: string; | ||
}) => ( | ||
<div | ||
className={clsx( | ||
'relative flex-none overflow-hidden rounded-lg bg-slate-100', | ||
className, | ||
)} | ||
> | ||
<button type='button' className='absolute right-2 top-2' onClick={onClick}> | ||
<Image src={'/icons/ic_close.svg'} alt='close' width={12} height={12} /> | ||
</button> | ||
<Image | ||
alt='thumbnail' | ||
width={160} | ||
height={160} | ||
src={url} | ||
className='h-full w-full object-cover' | ||
/> | ||
</div> | ||
); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
export const STARTDATE_IS_OVER_ENDDATE = { | ||
title: '유효하지 않은 날짜입니다.', | ||
description: '응모 시작 일정은 응모 마감 일정 이후로 설정해주세요.', | ||
duration: 5000, | ||
variant: 'warning', | ||
}; | ||
|
||
export const ENDDATE_IS_OVER_ANNOUNCEAT = { | ||
title: '유효하지 않은 날짜입니다.', | ||
description: '응모 마감 일정은 당첨자 발표 일정 이후로 설정해주세요.', | ||
duration: 5000, | ||
variant: 'warning', | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
export const validateDate = ( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. validateDate 보다는 이 날짜가 이전 날짜 보다 큰지를 보여주도록 함수 명에서 드러나면 좋을 것 같아요 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 17b7a0f |
||
date: Date | undefined, | ||
referenceDate: Date | undefined, | ||
) => { | ||
if (!date || !referenceDate) return true; | ||
if (date > referenceDate) { | ||
return false; | ||
} | ||
return true; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,24 @@ | ||
'use client'; | ||
|
||
import type {CreateEventPayload} from '../../../entities/product/model'; | ||
import {ENDDATE_IS_OVER_ANNOUNCEAT} from '../config/const'; | ||
import {validateDate} from '../config/validateDate'; | ||
import {useFormContext} from 'react-hook-form'; | ||
import {FormControl, FormField, FormItem, FormLabel} from '@/shared/ui'; | ||
import {CalendarForm, useToast} from '@wraffle/ui'; | ||
|
||
export const EndDateForm = ({ | ||
defaultValue, | ||
fromDate: startDate, | ||
referenceDate: announceAt, | ||
}: { | ||
defaultValue: Date; | ||
defaultValue: Date | undefined; | ||
fromDate: Date; | ||
referenceDate: Date | undefined; | ||
}) => { | ||
const {control} = useFormContext<CreateEventPayload>(); | ||
const {toast} = useToast(); | ||
|
||
return ( | ||
<FormField | ||
control={control} | ||
|
@@ -25,7 +30,13 @@ export const EndDateForm = ({ | |
<CalendarForm | ||
dateLabel='응모 마감 시간을 입력해주세요.' | ||
selected={defaultValue} | ||
setSelected={field.onChange} | ||
onSelect={date => { | ||
if (validateDate(date, announceAt)) { | ||
field.onChange(date); | ||
} else { | ||
toast(ENDDATE_IS_OVER_ANNOUNCEAT); | ||
} | ||
}} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ui에서 이 로직을 담당하는 것 보다는 onSelect를 외부에서 받아서 관리하는 방식이 좋아보일 것 같아요! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 1ff0234 |
||
fromDate={startDate} | ||
onClick={e => { | ||
if (!startDate) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,21 @@ | ||
'use client'; | ||
|
||
import type {CreateEventPayload} from '../../../entities/product/model'; | ||
import {STARTDATE_IS_OVER_ENDDATE} from '../config/const'; | ||
import {validateDate} from '../config/validateDate'; | ||
import {useFormContext} from 'react-hook-form'; | ||
import {FormControl, FormField, FormItem, FormLabel} from '@/shared/ui'; | ||
import {CalendarForm} from '@wraffle/ui'; | ||
import {CalendarForm, useToast} from '@wraffle/ui'; | ||
|
||
export const StartDateForm = ({defaultValue}: {defaultValue: Date}) => { | ||
export const StartDateForm = ({ | ||
defaultValue, | ||
referenceDate: endDate, | ||
}: { | ||
defaultValue: Date | undefined; | ||
referenceDate: Date | undefined; | ||
}) => { | ||
const {control} = useFormContext<CreateEventPayload>(); | ||
const {toast} = useToast(); | ||
return ( | ||
<FormField | ||
control={control} | ||
|
@@ -18,7 +27,13 @@ export const StartDateForm = ({defaultValue}: {defaultValue: Date}) => { | |
<CalendarForm | ||
dateLabel='응모 시작 시간을 입력해주세요.' | ||
selected={defaultValue} | ||
setSelected={field.onChange} | ||
onSelect={date => { | ||
if (validateDate(date, endDate)) { | ||
field.onChange(date); | ||
} else { | ||
toast(STARTDATE_IS_OVER_ENDDATE); | ||
} | ||
}} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 부분도 위와 동일 합니다! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 1ff0234 |
||
fromDate={new Date()} | ||
/> | ||
</FormControl> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export const Divider = () => { | ||
return <div className='h-1 w-full bg-[#F9FAFB]' />; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
혹시 interface를 따로 선언하지 않는 이유가 따로 있으신가요?
저는 보통
요런식으로 썼는데 interface 파일만 읽더라도 이 컴포넌트에서 대충 어느게 필요하겠구나에 대한
생각을 분리할 수 있어서 좋은 것 같았어요
이 부분에 대한 장현님의 생각은 어떠신가요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
interface를 따로 선언하지 않는 이유는
인터페이스로 분리할 때는 가독성이 떨어진다 느껴질 때 (ex. props로 받아오는게 많다거나, 복잡한 관계라던가..) 분리를 해서 사용해왔었는데,
'생각을 분리해 볼 수 있다' 와 같은 생각은 못해봤던 접근이어서 한번 생각해보겠습니다!
(이렇게 적었는데 밑에 훅 보니까 분리해서 사용했네요 ; 3개가 많다 생각하진 않는데)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
그럼 통일되는 편이 좋을 것 같아요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
825710c
수정 커밋입니다!
다른 코드를 보았을 때, interface로 분리된 코드가 많아서 통일시키는편이 좋을거 같아서 분리시켜두었습니다!