-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: room detail data mock API 생성 * feat: room detail data type 추가 * feat: API 데이터 적용 * style: 안쓰는 prop 제거 * chore: type 수정 * chore: page naming 변경 * feat: memeber rank 컴포넌트 추가 * chore: tawilwind class 적용 * chore: API 컨벤션 수정 * chore: page 컴포넌트 naming 수정 * chore: component prop 수정 * feat: API 초기값 설정 * feat: certificationImage 타입 수정 * chore: app-container 스타일 적용 * feat: CertificationBottomSheet 컴포넌트 분리 * style: ImageList 컴포넌트 제거 * chore: CertifiactionImage 타입 수정 * feat: Image Input 이미지 업로드 및 미리보기 구현 * fix: 데이터 관련 type Error 해결 * design: navbar 스타일 수정 * chore: 변수, 타입, 예시 데이터 수정 * feat: bottomSheet 벗어날 시에 form 에러 초기화 * chore: 컴포넌트 export * fix: PR 리뷰 적용
- Loading branch information
1 parent
594af5d
commit edf42a6
Showing
10 changed files
with
249 additions
and
51 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
import { MouseEvent } from 'react'; | ||
import { useFormContext } from 'react-hook-form'; | ||
import { FormCertificationImage } from '../types/type'; | ||
import ImageInput from './ImageInput'; | ||
import { BottomSheet } from '@/shared/BottomSheet'; | ||
import { BottomSheetProps } from '@/shared/BottomSheet/components/BottomSheet'; | ||
|
||
const routine = [ | ||
{ | ||
routineId: 5, | ||
content: '물 마시기' | ||
}, | ||
{ | ||
routineId: 9, | ||
content: '아침 먹기' | ||
} | ||
]; | ||
const certificationImage = [ | ||
{ | ||
routineId: 5, | ||
// image: 'https://picsum.photos/200' | ||
image: null | ||
}, | ||
{ | ||
routineId: 9, | ||
// image: 'https://picsum.photos/200' | ||
image: null | ||
} | ||
]; | ||
|
||
interface CertificationBottomSheetProps { | ||
bottomSheetProps: BottomSheetProps; | ||
close: () => void; | ||
} | ||
|
||
const CertificationBottomSheet = ({ | ||
bottomSheetProps | ||
}: CertificationBottomSheetProps) => { | ||
const { watch, handleSubmit } = useFormContext<FormCertificationImage[]>(); | ||
|
||
const handleFormSubmit = async (data: FormCertificationImage[]) => { | ||
const formData = new FormData(); | ||
|
||
for (const [key, value] of Object.entries(data)) { | ||
if (value.file) { | ||
formData.append(`${routine[Number(key)].routineId}`, value.file[0]); | ||
} | ||
} | ||
// TODO : Form Data 전송 | ||
}; | ||
|
||
const handleEditButtonClick = (e: MouseEvent<HTMLButtonElement>) => { | ||
e.preventDefault(); | ||
const files = watch(); | ||
const formData = new FormData(); | ||
|
||
for (const [key, value] of Object.entries(files)) { | ||
if (value.file && value.file.length > 0) { | ||
formData.append(`${routine[Number(key)].routineId}`, value.file[0]); | ||
} | ||
} | ||
// TODO : Form Data 전송 | ||
}; | ||
|
||
return ( | ||
<BottomSheet | ||
{...bottomSheetProps} | ||
className="bg-light-main p-0 dark:bg-dark-main" | ||
> | ||
<div className="mx-8 mb-[1.88rem] mt-[1.71rem] font-IMHyemin-bold text-black dark:text-white"> | ||
<h1 className="mb-[1.27rem] font-IMHyemin-bold"> | ||
모든 칸을 채워주세요 | ||
</h1> | ||
<form | ||
onSubmit={handleSubmit(handleFormSubmit)} | ||
className="mb-8 grid grid-cols-2 gap-x-3 gap-y-[1.34rem] rounded-2xl text-black dark:text-white" | ||
id="certificationForm" | ||
> | ||
{routine.map(({ routineId, content }, idx) => { | ||
return ( | ||
<ImageInput | ||
key={routineId} | ||
content={content} | ||
image={certificationImage[idx].image} | ||
idx={idx} | ||
/> | ||
); | ||
})} | ||
</form> | ||
<span className="mb-[1rem] block font-IMHyemin-bold text-xs text-dark-gray"> | ||
다른 새들이 알아볼 수 있게 찍어주세요! | ||
</span> | ||
{certificationImage.filter((el) => el.image).length === | ||
routine.length ? ( | ||
<button | ||
type="button" | ||
className="btn dark:btn-dark-point btn-light-point w-full" | ||
onClick={handleEditButtonClick} | ||
form="certificationForm" | ||
> | ||
수정 | ||
</button> | ||
) : ( | ||
<button | ||
className="btn dark:btn-dark-point btn-light-point w-full" | ||
type="submit" | ||
form="certificationForm" | ||
> | ||
인증! | ||
</button> | ||
)} | ||
</div> | ||
</BottomSheet> | ||
); | ||
}; | ||
|
||
export default CertificationBottomSheet; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import { useState } from 'react'; | ||
import { useFormContext } from 'react-hook-form'; | ||
import clsx from 'clsx'; | ||
import { FormCertificationImage } from '../types/type'; | ||
import { Icon } from '@/shared/Icon'; | ||
|
||
interface ImageInputProps { | ||
content: string; | ||
image: string | null; | ||
idx: number; | ||
} | ||
|
||
const ImageInput = ({ content, image, idx }: ImageInputProps) => { | ||
const { | ||
register, | ||
formState: { errors }, | ||
clearErrors | ||
} = useFormContext<FormCertificationImage[]>(); | ||
const [imgSrc, setImgSrc] = useState(image); | ||
|
||
const saveFileImage = (fileBlob: File) => { | ||
const fileUrl = URL.createObjectURL(fileBlob); | ||
setImgSrc(fileUrl); | ||
}; | ||
|
||
return ( | ||
<div> | ||
<div | ||
className={clsx( | ||
'relative mb-1 h-0 w-full overflow-hidden rounded-2xl border border-dark-gray pb-[100%] shadow-[0_1px_4px_0px_rgba(0,0,0,0.2)]', | ||
{ | ||
'border-danger': errors[idx]?.file?.message | ||
} | ||
)} | ||
> | ||
<input | ||
type="file" | ||
id={content} | ||
{...register(`${idx}.file`, { | ||
required: '이미지를 넣어주세요' | ||
})} | ||
className="absolute left-0 top-0 h-full w-full before:block before:h-full before:w-full before:bg-white before:content-[''] after:absolute" | ||
onChange={(e) => { | ||
if (e.target.files) { | ||
saveFileImage(e.target.files[0]); | ||
clearErrors(`${idx}.file`); | ||
} | ||
}} | ||
/> | ||
<label | ||
htmlFor={content} | ||
className="absolute block h-full w-full" | ||
> | ||
{imgSrc ? ( | ||
<div | ||
className="h-full w-full bg-cover bg-center bg-no-repeat" | ||
style={{ backgroundImage: `url(${imgSrc})` }} | ||
/> | ||
) : ( | ||
<div> | ||
<Icon | ||
icon="FaPlus" | ||
size="4xl" | ||
className={clsx( | ||
'absolute left-[50%] top-[50%] block translate-x-[-50%] translate-y-[-50%] text-dark-gray' | ||
)} | ||
/> | ||
</div> | ||
)} | ||
</label> | ||
</div> | ||
<div> | ||
{errors[idx]?.file?.message && ( | ||
<span className="block font-IMHyemin-bold text-sm text-danger"> | ||
<>{errors[idx]?.file?.message}</> | ||
</span> | ||
)} | ||
<span className="block font-IMHyemin-bold text-sm">{content}</span> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default ImageInput; |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export { default as RoomNotice } from './components/RoomNotice'; | ||
export { default as RoomInfo } from './components/RoomInfo'; | ||
export { default as RoomWorkspace } from './components/RoomWorkspace'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export interface FormCertificationImage { | ||
file: null | FileList; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
export type CertificationImage = { | ||
routineId: number; | ||
image: string; | ||
image: string | null; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -69,7 +69,8 @@ export default { | |
}, | ||
zIndex: { | ||
bottomSheet: '100', | ||
toast: '110' | ||
toast: '110', | ||
navbar: '50' | ||
} | ||
} | ||
} | ||
|