diff --git a/api/room-dev.ts b/api/room-dev.ts index 59d44c9..e04fbe8 100644 --- a/api/room-dev.ts +++ b/api/room-dev.ts @@ -1,12 +1,12 @@ -import { Room, RoomPost } from '@/public/types/room'; +import { RoomDev, RoomPost } from '@/public/types/room'; import { fetchData } from './index-dev'; export const fetchRooms = async () => { - return fetchData('/api/room'); + return fetchData('/api/room'); }; export const fetchRoom = async (id: string) => { - return fetchData(`/api/room/${id}`); + return fetchData(`/api/room/${id}`); }; export const fetchPostRoom = async (data: RoomPost) => { diff --git a/api/room.ts b/api/room.ts index 803aa0b..6bbb975 100644 --- a/api/room.ts +++ b/api/room.ts @@ -1,6 +1,22 @@ -import { Furnishing } from '@/public/types/room'; +import { Furnishing, Room, RoomFile } from '@/public/types/room'; import { fetchData } from './index'; export const fetchFurnishings = async () => { return fetchData('/api/v1/furnishings'); }; + +export const uploadFile = async (file: File) => { + const formData = new FormData(); + formData.append('file', file); + return fetchData('/api/v1/files', { + method: 'POST', + body: formData, + }); +}; + +export const postRoom = async (room: Room) => { + return fetchData('/api/v1/rooms', { + method: 'POST', + body: JSON.stringify(room), + }); +}; diff --git a/components/Button/Button.module.scss b/components/Button/Button.module.scss index 966cb1c..4085f7c 100644 --- a/components/Button/Button.module.scss +++ b/components/Button/Button.module.scss @@ -41,7 +41,7 @@ } &.outlined { - @apply bg-g0 border border-solid border-g4 rounded-[2px] text-n700 font-semibold; + @apply bg-g0 border border-solid border-g4 rounded-[2px] font-semibold text-g5; } } .reset { diff --git a/components/File/FileUpload.tsx b/components/File/FileUpload.tsx index 084a4a9..9fa0023 100644 --- a/components/File/FileUpload.tsx +++ b/components/File/FileUpload.tsx @@ -3,6 +3,7 @@ import ImageUploading, { ImageListType } from 'react-images-uploading'; import Rectangle from '@/public/icons/rectangle.svg'; import RectangleCamera from '@/public/icons/rectangleCamera.svg'; import styles from '@/components/File/FileUpload.module.scss'; +import { UseFormRegisterReturn } from 'react-hook-form'; interface ImageComponentClickProps { imageSrc: string; @@ -12,18 +13,38 @@ interface ImageComponentClickProps { interface FileUploadProps { multiImage: boolean; callbackImageFn?: (imageList: ImageListType) => void; - InitImageComponent: React.ComponentType | null; + InitImageComponent?: React.ComponentType | null; style?: 'center' | 'left' | 'default'; + register: UseFormRegisterReturn; } -export default function FileUpload({ callbackImageFn, InitImageComponent, multiImage, style }: FileUploadProps) { +export default function FileUpload({ + callbackImageFn, + InitImageComponent, + multiImage, + style, + register, +}: FileUploadProps) { const [images, setImages] = React.useState([]); const maxNumber = 5; const onChange = (imageList: ImageListType) => { const lastImage = imageList.slice(-1); - multiImage ? setImages(imageList) : setImages(lastImage); + const customEvent = { + target: { + name: register.name, + value: lastImage, + }, + }; + + if (multiImage) { + customEvent.target.value = imageList; + setImages(imageList); + } else { + setImages(lastImage); + } callbackImageFn?.(imageList); + register.onChange(customEvent); }; return ( @@ -33,7 +54,7 @@ export default function FileUpload({ callbackImageFn, InitImageComponent, multiI {({ imageList, onImageUpload, onImageUpdate, onImageRemove, isDragging, dragProps }) => ( // write your building UI
- {InitImageComponent === null ? ( + {!InitImageComponent ? (
{ - (imageList || []).length < 5 && onImageUpload(); + if ((imageList || []).length < 5) { + onImageUpload(); + } }} /> void; } diff --git a/pages/api/room.ts b/pages/api/room.ts index bef8aa6..b94cb18 100644 --- a/pages/api/room.ts +++ b/pages/api/room.ts @@ -1,7 +1,7 @@ -import { ROOM_TYPE, Room } from '@/public/types/room'; +import { ROOM_TYPE, RoomDev } from '@/public/types/room'; import { NextApiRequest, NextApiResponse } from 'next'; -export default function handler(req: NextApiRequest, res: NextApiResponse) { +export default function handler(req: NextApiRequest, res: NextApiResponse) { const userInfo = { name: 'Dennis', image: 'https://source.unsplash.com/random', diff --git a/pages/api/room/[id].ts b/pages/api/room/[id].ts index 3c5582e..c617980 100644 --- a/pages/api/room/[id].ts +++ b/pages/api/room/[id].ts @@ -1,7 +1,7 @@ -import { ROOM_TYPE, Room } from '@/public/types/room'; +import { ROOM_TYPE, RoomDev } from '@/public/types/room'; import { NextApiRequest, NextApiResponse } from 'next'; -export default function handler(req: NextApiRequest, res: NextApiResponse) { +export default function handler(req: NextApiRequest, res: NextApiResponse) { const userInfo = { name: 'Dennis', image: 'https://source.unsplash.com/random', diff --git a/pages/index.tsx b/pages/index.tsx index b688c75..fc6d8ff 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react'; import 'tailwindcss/tailwind.css'; import RoomCard from '@/components/RoomCard/RoomCard'; import { fetchRooms } from '@/api/room-dev'; -import { Room } from '@/public/types/room'; +import { RoomDev } from '@/public/types/room'; import { NextPage, NextPageContext } from 'next'; import RoomListLayout from '@/components/layouts/RoomListLayout.tsx'; import FilterImg from '@/public/icons/filter.svg'; @@ -20,7 +20,7 @@ type HomeProps = NextPage & { function Home() { const commonTranslation = useTranslation('common'); - const [rooms, setRooms] = useState([]); + const [rooms, setRooms] = useState([]); const [filters, setFilters] = useState([]); // const [selectedOptions, setSelectedOptions] = useState([]); const [clickedChip, setClickedChip] = useState(''); diff --git a/pages/room/[id].tsx b/pages/room/[id].tsx index 8a3e0d6..ce08516 100644 --- a/pages/room/[id].tsx +++ b/pages/room/[id].tsx @@ -4,7 +4,7 @@ import { Swiper, SwiperSlide } from 'swiper/react'; import 'swiper/css'; import { fetchRoom } from '@/api/room-dev'; import { useRouter } from 'next/router'; -import { ROOM_TYPE, Room } from '@/public/types/room'; +import { ROOM_TYPE, RoomDev } from '@/public/types/room'; import { formatAge, formatDate, formatPrice } from '@/utils/transform'; import ArrowDown from '@/public/icons/arrow-down.svg'; import Pin from '@/public/icons/pin.svg'; @@ -22,7 +22,7 @@ export default function Login() { const { id } = router.query; const [currentSlide, setCurrentSlide] = React.useState(0); - const [room, setRoom] = React.useState(); + const [room, setRoom] = React.useState(); const age = room ? formatAge(room.userInfo.year) : 0; const [isShowDetail, setIsShowDetail] = React.useState(false); diff --git a/pages/room/add/step1.tsx b/pages/room/add/step1.tsx index 656456a..8cefb46 100644 --- a/pages/room/add/step1.tsx +++ b/pages/room/add/step1.tsx @@ -19,11 +19,11 @@ interface GuDong { const MAINTANANCE_FEE_OPTIONS = [ { value: 'yes', - label: 'YES', + label: 'Yes', }, { value: 'no', - label: 'NO', + label: 'No', }, ]; diff --git a/pages/room/add/step3.tsx b/pages/room/add/step3.tsx index c6290d7..9823b26 100644 --- a/pages/room/add/step3.tsx +++ b/pages/room/add/step3.tsx @@ -1,12 +1,114 @@ -import { useRouter } from 'next/router'; import React from 'react'; +import { ImageListType } from 'react-images-uploading'; +import { Stepper, Textarea, Typography, Button, Upload } from '@/components/index.tsx'; +import { FieldValues, SubmitHandler, useForm } from 'react-hook-form'; +import { useRouter } from 'next/router'; +import DefaultLayout from '@/components/layouts/DefaultLayout'; +import { postRoom, uploadFile } from '@/api/room'; +import useModal from '@/hooks/useModal'; +import styles from './add.module.scss'; export default function Step3() { + const { register, handleSubmit, watch } = useForm({ mode: 'onChange' }); + const router = useRouter(); const { query } = router; const step2Params = query.data ? JSON.parse(query.data as string) : {}; - console.log(step2Params); + const uploadPhoto = (photoList: ImageListType) => { + const uploadPromises = photoList.map(async (photo) => { + if (!photo.file) { + return null; + } + + const result = await uploadFile(photo.file); + return result; + }); + + return Promise.all(uploadPromises); + }; + + const { openModal, closeModal } = useModal(); - return
step3
; + const onSubmit: SubmitHandler = async (data) => { + const images = await uploadPhoto(data.images); + const formattedImages = images.map((image) => image?.id); + const params = { + ...step2Params, + imageIds: formattedImages, + description: data.description, + }; + + try { + const roomData = await postRoom(params); + + openModal({ + props: { + title: 'Congratulation!', + content: 'Your room is now added to the list!', + buttonType: 'default', + buttonName: 'Complete', + handleClose: () => { + router.push('/'); + closeModal(); + }, + hasCloseButton: true, + }, + }); + } catch (e) { + console.error(e); + } + }; + + return ( + <> + +
+
+ + Introduce your room + +
+
+
+
Room Photos
+
+
+
You can up load maximum 5 photos in total
+
+ + +
+ +
+ + About the house + +
+