diff --git a/src/App.tsx b/src/App.tsx
index 2f45c335..2ee94504 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -19,7 +19,7 @@ import { CouponRegistration } from './pages/coupon-registration';
import { Main } from './pages/main';
import Room from './pages/room-management';
import RoomRegistration from './pages/room-registration';
-import { RoomUpdate } from './pages/room-update';
+import RoomUpdate from './pages/room-update';
import { RootLayout } from './layout';
import './App.less';
import { RoomLayout } from '@components/room/room-layout';
@@ -90,10 +90,12 @@ function App() {
element={}
/>
- }
- />
+ }>
+ }
+ />
+
} />
diff --git a/src/api/room/index.ts b/src/api/room/index.ts
index 178c1142..d245e5d5 100644
--- a/src/api/room/index.ts
+++ b/src/api/room/index.ts
@@ -1,12 +1,11 @@
import { Response } from '@/types/api';
import { instance } from '..';
import {
- RoomListData,
+ RoomListResponseData,
RoomData,
RoomPostResponseData,
AccommodationData,
} from './type';
-import { useParams } from 'react-router-dom';
export const ROOM_API = {
addRoom: (data: RoomData, accommodationId: string) =>
@@ -16,10 +15,10 @@ export const ROOM_API = {
data,
},
),
- // getRoom: (params: RoomAddParams) =>
- // instance.get>('/api/rooms/list/{accommodationId}?pageSize={pageSize}&pageNum={pageNum}', {
- // data: params,
- // }),
+ getRoomList: (accommodationId: string) =>
+ instance.get>(
+ `/api/rooms/list/${accommodationId}?pageSize={pageSize}&pageNum={pageNum}`,
+ ),
// editRoom: (params: RoomEditParams) =>
// instance.patch>('/api/rooms/{roomId}', params),
};
diff --git a/src/api/room/type.ts b/src/api/room/type.ts
index 0630cbc8..ac332301 100644
--- a/src/api/room/type.ts
+++ b/src/api/room/type.ts
@@ -1,4 +1,19 @@
-export type RoomListData = {
+export type onFinishValues = {
+ 'room-name': string;
+ price: string;
+ defaultCapacity: number;
+ maxCapacity: number;
+ checkInTime: moment.Moment;
+ checkOutTime: moment.Moment;
+ count: number;
+};
+
+export type RoomListResponseData = {
+ pageNum: number;
+ pageSize: number;
+ totalPages: number;
+ totalElements: number;
+ isLast: boolean;
rooms: RoomData[];
};
diff --git a/src/assets/data/roomListData.json b/src/assets/data/roomListData.json
new file mode 100644
index 00000000..62815262
--- /dev/null
+++ b/src/assets/data/roomListData.json
@@ -0,0 +1,121 @@
+{
+ "message": "성공적으로 객실 목록을 조회 했습니다.",
+ "data": {
+ "pageNum": 1,
+ "pageSize": 5,
+ "totalPages": 2,
+ "totalElements": 8,
+ "isLast": false,
+ "rooms": [
+ {
+ "id": 286,
+ "name": "봄",
+ "basePrice": 100000,
+ "discountPrice": 80000,
+ "defaultCapacity": 2,
+ "maxCapacity": 6,
+ "checkInTime": "15:00",
+ "checkOutTime": "12:00",
+ "status": "SELLING",
+ "count": 5,
+ "images": [
+ {
+ "url": "pension_room2_2.webp"
+ },
+ {
+ "url": "pension_room2_1.webp"
+ }
+ ],
+ "coupons": [
+ {
+ "id": 56,
+ "name": "10% 할인",
+ "price": 90000
+ },
+ {
+ "id": 57,
+ "name": "2000원 할인",
+ "price": 80000
+ }
+ ],
+ "options": {
+ "airCondition": true,
+ "tv": true,
+ "internet": true
+ }
+ },
+ {
+ "id": 286,
+ "name": "봄",
+ "basePrice": 100000,
+ "discountPrice": 80000,
+ "defaultCapacity": 2,
+ "maxCapacity": 6,
+ "checkInTime": "15:00",
+ "checkOutTime": "12:00",
+ "count": 5,
+ "images": [
+ {
+ "fileName": "pension_room2_2.webp"
+ },
+ {
+ "fileName": "pension_room2_1.webp"
+ }
+ ],
+ "coupons": [
+ {
+ "id": 56,
+ "name": "10% 할인",
+ "price": 90000
+ },
+ {
+ "id": 57,
+ "name": "2000원 할인",
+ "price": 80000
+ }
+ ],
+ "options": {
+ "airCondition": true,
+ "tv": true,
+ "internet": true
+ }
+ },
+ {
+ "id": 286,
+ "name": "봄",
+ "basePrice": 100000,
+ "discountPrice": 80000,
+ "defaultCapacity": 2,
+ "maxCapacity": 6,
+ "checkInTime": "15:00",
+ "checkOutTime": "12:00",
+ "count": 5,
+ "images": [
+ {
+ "fileName": "pension_room2_2.webp"
+ },
+ {
+ "fileName": "pension_room2_1.webp"
+ }
+ ],
+ "coupons": [
+ {
+ "id": 56,
+ "name": "10% 할인",
+ "price": 90000
+ },
+ {
+ "id": 57,
+ "name": "2000원 할인",
+ "price": 80000
+ }
+ ],
+ "options": {
+ "airCondition": true,
+ "tv": true,
+ "internet": true
+ }
+ }
+ ]
+ }
+}
diff --git a/src/components/init/ButtonContainer.tsx b/src/components/init/ButtonContainer.tsx
index c489ad4e..783806c6 100644
--- a/src/components/init/ButtonContainer.tsx
+++ b/src/components/init/ButtonContainer.tsx
@@ -14,6 +14,7 @@ export const ButtonContainer = ({
isValid,
}: ButtonContainerProps) => {
const navigate = useNavigate();
+
const handlePreviousClick = () => {
if (window.location.pathname === ROUTES.INIT_ACCOMMODATION_REGISTRATION)
navigate(ROUTES.INIT);
diff --git a/src/components/room/room-buttons/index.tsx b/src/components/room/room-buttons/index.tsx
index f4eb5ad0..13343696 100644
--- a/src/components/room/room-buttons/index.tsx
+++ b/src/components/room/room-buttons/index.tsx
@@ -17,21 +17,16 @@ export const ButtonContainer = ({
return (
- {buttonStyle === 'register' && (
+ {
<>
이전
-
- {buttonStyle === 'register' ? '등록 요청' : '수정 요청'}
+
+ {buttonStyle === 'register' ? '등록 요청' : '수정 완료'}
>
- )}
+ }
);
};
@@ -39,17 +34,9 @@ export const ButtonContainer = ({
export const StyledWrapper = styled.div`
width: 100%;
- display: ${(props) =>
- props.$buttonStyle === 'register' || props.$buttonStyle === 'edit'
- ? 'grid'
- : 'block'};
- grid-template-columns: ${(props) =>
- props.$buttonStyle === 'register'
- ? '1fr 2.5fr'
- : props.$buttonStyle === 'edit'
- ? 'auto'
- : 'none'};
- gap: ${(props) => (props.$buttonStyle === 'register' ? '10px' : '0')};
+ display: grid;
+ grid-template-columns: 1fr 2.5fr;
+ gap: 10px;
`;
export const StyledButton = styled(Button)`
diff --git a/src/components/room/room-buttons/type.ts b/src/components/room/room-buttons/type.ts
index 947d7f2b..e32c332e 100644
--- a/src/components/room/room-buttons/type.ts
+++ b/src/components/room/room-buttons/type.ts
@@ -1,8 +1,8 @@
export type ButtonContainerProps = {
- buttonStyle: 'register' | 'edit';
+ buttonStyle: 'register' | 'update';
isValid: boolean;
};
export type ButtonContainerStyledWrapperProps = {
- $buttonStyle: 'register' | 'edit';
+ $buttonStyle: 'register' | 'update';
};
diff --git a/src/components/room/room-layout/index.tsx b/src/components/room/room-layout/index.tsx
index f80ba1b9..7aa23524 100644
--- a/src/components/room/room-layout/index.tsx
+++ b/src/components/room/room-layout/index.tsx
@@ -20,12 +20,16 @@ export const RoomLayout = () => {
},
};
- const currentRoute = Object.keys(routeConfig).find(
- (route) => location.pathname === route,
+ const currentRouteKey = Object.keys(routeConfig).find((routeKey) =>
+ location.pathname.includes(routeKey),
);
- const { pageTitle = '객실 추가 등록' } =
- routeConfig[currentRoute as keyof typeof routeConfig] || {};
+ const currentRouteConfig =
+ routeConfig[currentRouteKey as keyof typeof routeConfig];
+
+ const pageTitle = currentRouteConfig
+ ? currentRouteConfig.pageTitle
+ : '객실 추가 등록';
return (
{
+ const [isOnSale, setIsOnSale] = useState(true);
+
+ const handleInputChange = (isOnSale: boolean) => {
+ setIsOnSale(!isOnSale);
+ return;
+ };
+
+ return (
+
+
+
+ 객실 상태
+
+
+
+
+
+
+
+
+ {!isOnSale ? '판매 중' : '판매 중지'}
+
+
+
+
+ );
+};
+
+const StyledInputWrapper = styled.div`
+ margin-bottom: 35px;
+
+ .ant-form-item-control {
+ width: 100%;
+ }
+
+ .ant-input {
+ font-size: 16px;
+ }
+`;
+
+const StyledTextBoxWrapper = styled.div`
+ margin-bottom: 24px;
+ margin-right: 12px;
+
+ &:last-child {
+ margin-right: 0;
+ }
+`;
+
+const StyledRow = styled.div`
+ height: 30px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+`;
+
+const StyledDesc = styled.div`
+ display: flex;
+ align-items: center;
+ margin-bottom: 16px;
+`;
+
+const StyledSwitch = styled(Switch)`
+ margin-right: 7px;
+`;
diff --git a/src/hooks/room/useAddRoom.ts b/src/hooks/room/useAddRoom.ts
deleted file mode 100644
index 641834fe..00000000
--- a/src/hooks/room/useAddRoom.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import { useAddRoom } from '@queries/room';
-
-// export const postRoomData = () => {
-// useAddRoom();
-// onSuccess: (response) => {
-// console.log('postRoomData, hooks, success');
-// },
-// };
diff --git a/src/layout.tsx b/src/layout.tsx
index d5b01448..8dc77bef 100644
--- a/src/layout.tsx
+++ b/src/layout.tsx
@@ -7,16 +7,20 @@ import { colors } from '@/constants/colors';
export const RootLayout = () => {
const location = useLocation();
const currentRoute = location.pathname;
+ const isRoomRegistrationRoute = currentRoute.includes(
+ ROUTES.ROOM_REGISTRATION,
+ );
+ const isRoomUpdateRoute = currentRoute.includes(ROUTES.ROOM_UPDATE);
+
+ const shouldApplyGrayBackground =
+ isRoomRegistrationRoute || isRoomUpdateRoute;
return (
Header
diff --git a/src/mocks/handlers.ts b/src/mocks/handlers.ts
index cbb9e6ab..cb9a6359 100644
--- a/src/mocks/handlers.ts
+++ b/src/mocks/handlers.ts
@@ -25,7 +25,7 @@ import {
buyCouponResolver,
getCouponRoomListResolver,
} from './coupon-registration';
-import { postRoomResolver } from './room';
+import { postRoomResolver, getRoomListResolver } from './room';
const email = 'ivegaeul@naver.com';
const verificationCode = '020924';
@@ -70,4 +70,8 @@ export const handlers = [
http.delete('/api/points/charges/1', deleteOrderCancelResolver),
http.post(`/api/rooms/${accommodationId}`, postRoomResolver),
+ http.get(
+ `/api/rooms/list/${accommodationId}?pageSize={pageSize}&pageNum={pageNum}`,
+ getRoomListResolver,
+ ),
];
diff --git a/src/mocks/room/index.ts b/src/mocks/room/index.ts
index e3e14e40..542d0ae8 100644
--- a/src/mocks/room/index.ts
+++ b/src/mocks/room/index.ts
@@ -1,6 +1,11 @@
import { HttpResponse } from 'msw';
import roomData from '@assets/data/roomData.json';
+import roomListData from '@assets/data/roomListData.json';
export const postRoomResolver = () => {
return HttpResponse.json(roomData, { status: 200 });
};
+
+export const getRoomListResolver = () => {
+ return HttpResponse.json(roomListData, { status: 200 });
+};
diff --git a/src/pages/room-management/index.tsx b/src/pages/room-management/index.tsx
index ec7d7e7a..2e41dcb9 100644
--- a/src/pages/room-management/index.tsx
+++ b/src/pages/room-management/index.tsx
@@ -2,21 +2,49 @@ import RoomCard from '../../components/room/room-card';
import { Card, Button, Row } from 'antd';
import { TextBox } from '@components/text-box';
import styled from 'styled-components';
-import { colors } from '@/constants/colors';
+import { useNavigate, useParams } from 'react-router-dom';
+import { useGetRoomList } from '@queries/room';
+import { ROUTES } from '@/constants/routes';
const RoomManagement = () => {
+ const navigate = useNavigate();
+ const { accommodationId: tempAccommodationId } = useParams();
+ const accommodationId = tempAccommodationId || '';
+ const { data, isLoading, error } = useGetRoomList(accommodationId);
+
+ console.log(data);
+ // const { getList } = useGetRoomList(accommodationId as string, {
+ // onSuccess() {
+ // console.log(data)
+ // // message.success({
+ // // content: '등록되었습니다',
+ // // className: 'coupon-message',
+ // // });
+ // // navigate(`/${accommodationId}${ROUTES.ROOM}`);
+ // // setSelectedImages([]);
+ // // setSelectedOptions({
+ // // airCondition: false,
+ // // tv: false,
+ // // internet: false,
+ // // });
+ // }
+ // });
+
return (
-
-
- 객실 관리
-
-
-
- + 객실추가
+
+
+
+ 객실 관리
-
-
+ navigate(`/${accommodationId}/room/registration`)}
+ >
+ + 객실추가
+
+
+
);
@@ -36,11 +64,15 @@ const StyledTitleButton = styled(Row)`
margin-bottom: 16px;
`;
-const StyledAddRoomButton = styled(Button)`
- border-radius: 2px;
- background: ${colors.primary};
- color: white;
+const StyledButton = styled(Button)`
+ font-size: 18px;
+ font-weight: 700;
+
display: flex;
align-items: center;
- justify-content: center;
+ margin-top: 2px;
+`;
+
+const StyledFixedTitle = styled.div`
+ // position: fixed;
`;
diff --git a/src/pages/room-registration/index.tsx b/src/pages/room-registration/index.tsx
index ea3e8c1a..30ef610e 100644
--- a/src/pages/room-registration/index.tsx
+++ b/src/pages/room-registration/index.tsx
@@ -9,19 +9,23 @@ import { PriceContainer } from '@components/room/price-container';
import { CapacityContainer } from '@components/room/capacity-container';
import { CountContainer } from '@components/room/num-of-rooms-container';
import { TimeContainer } from '@components/room/time-container';
-import { useRecoilState } from 'recoil';
+import { useRecoilState, useRecoilValue } from 'recoil';
import {
checkedRoomOptions,
selectedInitRoomFilesState,
} from '@stores/init/atoms';
-import { RoomData } from '@api/room/type';
+import { RoomData, onFinishValues } from '@api/room/type';
import { useAddRoom } from '@queries/room';
import { useNavigate, useParams } from 'react-router-dom';
+import { capacityHasError, priceHasError } from '@stores/room/atoms';
+import { useState, useEffect } from 'react';
import { ROUTES } from '@/constants/routes';
import { AxiosError } from 'axios';
const RoomRegistration = () => {
- const isValid = true;
+ const navigate = useNavigate();
+ const [isValid, setIsValid] = useState(false);
+
const roomOptions = {
tv: 'TV',
airCondition: '에어컨',
@@ -29,7 +33,6 @@ const RoomRegistration = () => {
};
const { accommodationId } = useParams();
- const navigate = useNavigate();
const [form] = Form.useForm();
const { mutate } = useAddRoom(accommodationId as string, {
@@ -38,8 +41,8 @@ const RoomRegistration = () => {
content: '등록되었습니다',
});
navigate(`/${accommodationId}${ROUTES.ROOM}`);
- setSelectedInitRoomFiles([]);
- setSelectedInitRoomOptions({
+ setSelectedImages([]);
+ setSelectedOptions({
airCondition: false,
tv: false,
internet: false,
@@ -51,13 +54,18 @@ const RoomRegistration = () => {
},
});
- const [selectedImages, setSelectedInitRoomFiles] = useRecoilState(
+ const [selectedImages, setSelectedImages] = useRecoilState(
selectedInitRoomFilesState,
);
- const [selectedOptions, setSelectedInitRoomOptions] =
+ const [selectedOptions, setSelectedOptions] =
useRecoilState(checkedRoomOptions);
- const onFinish = (value: any) => {
+ const [sameRoomName, setSameRoomName] = useState(false);
+ const [recoilUpdated, setRecoilUpdated] = useState(false);
+ const priceError = useRecoilValue(priceHasError);
+ const capacityError = useRecoilValue(capacityHasError);
+
+ const onFinish = (value: onFinishValues) => {
const data: RoomData = {
name: value['room-name'],
price: parseInt(value['price'].replace(',', '')),
@@ -69,26 +77,63 @@ const RoomRegistration = () => {
options: selectedOptions,
images: selectedImages,
};
+ setRecoilUpdated(true);
mutate(data);
};
- // async (formData: RoomData) => {
- // try {
- // //postRoomData(formData);
- // //const res = await axios.post('', formData);
- // const res = useAddRoom;
- // console.log('Success:', res.data);
- // } catch (error) {
- // console.log(error);
- // }
- // };
+
+ const areFormFieldsValid = () => {
+ const values = form.getFieldsValue();
+
+ const conditions =
+ values['room-name'] &&
+ values['price'] &&
+ values['checkInTime'] &&
+ values['checkOutTime'] &&
+ selectedImages.length !== 0;
+
+ console.log(
+ values['room-name'],
+ values['price'],
+ values['checkInTime'],
+ values['checkOutTime'],
+ selectedImages.length,
+ );
+
+ return (
+ !form.getFieldsError().some(({ errors }) => errors.length) &&
+ conditions &&
+ !priceError &&
+ !capacityError
+ );
+ };
+
+ useEffect(() => {
+ setIsValid(areFormFieldsValid());
+ }, [
+ form,
+ selectedImages,
+ selectedOptions,
+ priceError,
+ capacityError,
+ recoilUpdated,
+ ]);
+
+ const handleFormValuesChange = () => {
+ setIsValid(areFormFieldsValid());
+ };
return (
-