Skip to content

Commit

Permalink
Merge pull request #174 from zestlee1106/feature/api-fix
Browse files Browse the repository at this point in the history
Feature/api fix
  • Loading branch information
zestlee1106 authored Sep 30, 2023
2 parents 93bb79d + 3bfcad7 commit 55c363b
Show file tree
Hide file tree
Showing 19 changed files with 538 additions and 129 deletions.
15 changes: 2 additions & 13 deletions api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,16 @@ export const fetchData = async <T>(url: string, options?: RequestInit): Promise<
const response = await fetch(`${baseURL}${url}`, options);

if (response.status === 204) {
// error is: "Type 'null' is not assignable to type 'T'."
return null;
}

if (!response.ok) {
throw new Error('Failed to fetch data');
}

// TODO:나중에 삭제
try {
const data = await response.json();
return data;
} catch (e) {
if (response.status === 200) {
return null;
}
throw Error('에러 응답값이 없습니다');
}
const data = await response.json();
return data;
} catch (error) {
console.error(error);
throw new Error('Failed to fetch data');
throw new Error('Failed to fetch data', error as Error);
}
};
14 changes: 14 additions & 0 deletions api/room-dev.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Room, RoomPost } from '@/public/types/room';
import { fetchData } from './index-dev';

export const fetchRooms = async () => {
return fetchData<Room[]>('/api/room');
};

export const fetchRoom = async (id: string) => {
return fetchData<Room>(`/api/room/${id}`);
};

export const fetchPostRoom = async (data: RoomPost) => {
return fetchData<RoomPost>(`/api/v1/rooms`);
};
17 changes: 4 additions & 13 deletions api/room.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,6 @@
import { Room, RoomPost } from '@/public/types/room';
import { fetchData } from './index-dev';
import { Furnishing } from '@/public/types/room';
import { fetchData } from './index';


export const fetchRooms = async () => {
return fetchData<Room[]>('/api/room');
};

export const fetchRoom = async (id: string) => {
return fetchData<Room>(`/api/room/${id}`);
export const fetchFurnishings = async () => {
return fetchData<Furnishing[]>('/api/v1/furnishings');
};

export const fetchPostRoom = async(data: RoomPost) => {
return fetchData<RoomPost>(`/api/v1/rooms`);
}
4 changes: 4 additions & 0 deletions components/Calendar/Calendar.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,7 @@
.warning {
@apply text-a1 font-pretendard text-[14px] h-[14px] mt-[4px];
}

.top-position {
@apply absolute bottom-[50px];
}
21 changes: 17 additions & 4 deletions components/Calendar/Calendar.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useCallback, useEffect, useRef, useState } from 'react';
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import ReactCalendar from 'react-calendar';
import { FieldError, UseFormRegisterReturn } from 'react-hook-form';
import { format, parse } from 'date-fns';
Expand Down Expand Up @@ -26,6 +26,7 @@ export default function Calendar({ placeholder, register, error, disabled, value
const calendarRef = useRef<HTMLDivElement | null>(null);
const [dateValue, setDateValue] = useState<string>(value || '');
const [originDateValue, setOriginDateValue] = useState<string>(value || '');
const [scrollPosition, setScrollPosition] = useState<number>(0);

useEffect(() => {
const handleClickOutside = (e: MouseEvent) => {
Expand All @@ -34,6 +35,12 @@ export default function Calendar({ placeholder, register, error, disabled, value
}
};

if (calendarRef.current) {
const elementRect = calendarRef.current.getBoundingClientRect();

setScrollPosition(window.innerHeight - Number(elementRect?.bottom));
}

// 마운트 시 이벤트 등록
document.addEventListener('click', handleClickOutside);

Expand All @@ -45,6 +52,7 @@ export default function Calendar({ placeholder, register, error, disabled, value

const toggleCalendar = () => {
setIsCalendarShow((state) => !state);
setScrollPosition(window.scrollY || document.documentElement.scrollTop);
handleCalendarShow?.(!isCalendarShow);
};

Expand All @@ -69,14 +77,15 @@ export default function Calendar({ placeholder, register, error, disabled, value
setOriginDateValue(dateValue);
register.onChange(customEvent);
toggleCalendar();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [dateValue, register]);

const valueToDisplay = dateValue ? parse(dateValue, 'MM-dd-yyyy', new Date()) : '';

return (
<div className="relative w-full" ref={calendarRef}>
<input
className={`${styles.input} ${hasError ? styles.error : ''} ${disabled ? 'bg-g2': 'bg-g0'} `}
className={`${styles.input} ${hasError ? styles.error : ''} ${disabled ? 'bg-g2' : 'bg-g0'} `}
placeholder={placeholder}
disabled={disabled}
onClick={toggleCalendar}
Expand All @@ -85,15 +94,19 @@ export default function Calendar({ placeholder, register, error, disabled, value
{...register}
/>
{isCalendarShow && (
<div className="border-[#bdbdbd] border-[1px] absolute bg-g0">
<div
className={`border-[#bdbdbd] border-[1px] absolute bg-g0 ${
scrollPosition < 450 ? styles['top-position'] : ''
}`}
>
<ReactCalendar
value={valueToDisplay}
onChange={changeDate}
prev2Label={null}
next2Label={null}
maxDetail="month"
minDetail="month"
calendarType="US" // 일요일부터 시작하도록 한다
calendarType="gregory" // 일요일부터 시작하도록 한다
formatShortWeekday={(locale, date) => ['S', 'M', 'T', 'W', 'T', 'F', 'S'][date.getDay()]}
formatDay={(locale, date) => format(date, 'd')}
formatMonthYear={(locale, date) => format(date, 'MMMM yyyy')}
Expand Down
1 change: 0 additions & 1 deletion components/Filter/Filter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import styles from './Filter.module.scss';
import { Option } from '../Select/Select';
import Calendar from '../Calendar/Calendar';


const TYPE_OF_HOUSING = [
{
value: 'studioChecked',
Expand Down
22 changes: 20 additions & 2 deletions components/Input/Input.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useMemo, useState } from 'react';
import React, { ChangeEvent, useMemo, useState } from 'react';
import { FieldError, UseFormRegisterReturn } from 'react-hook-form';
import styles from './Input.module.scss';

Expand All @@ -20,20 +20,38 @@ function Input({ placeholder, register, type, error, maxLength, disabled }: Inpu
}
return type;
}, [type, isPasswordShow]);
const [inputValue, setInputValue] = useState('' as string);

const togglePasswordVisibility = () => {
setIsPasswordShow((state) => !state);
};

const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
const { value } = e.target;

setInputValue(value === '0' ? '' : value);

const customEvent = {
target: {
name: register.name,
value: value === '0' ? '' : value,
},
};

register.onChange(customEvent);
};

return (
<div className="relative w-full">
<input
className={`${styles.input} ${hasError ? styles.error : ''} ${disabled ? 'bg-g2': 'bg-g0'}`}
className={`${styles.input} ${hasError ? styles.error : ''} ${disabled ? 'bg-g2' : 'bg-g0'}`}
placeholder={placeholder}
type={inputType}
maxLength={maxLength}
disabled={disabled}
{...register}
onChange={handleChange}
value={inputValue}
/>
<button
className="absolute inset-y-0 right-0 flex items-center mx-4 text-gray-600 h-fit pt-[12px]"
Expand Down
66 changes: 66 additions & 0 deletions components/MultiButton/MultiButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import React, { useCallback, useEffect, useMemo } from 'react';
import { UseFormRegisterReturn } from 'react-hook-form';
import Button from '../Button/Button';
import { Option } from '../Radio/Radio';

interface MultiButtonProps {
options: Option[];
register: UseFormRegisterReturn;
onChange?: (value: string) => void;
}

function MultiButton({ options, register }: MultiButtonProps) {
const [selected, setSelected] = React.useState<Option>();

const handleButtonClick = (value: string) => {
const selectedButton = options.find((option) => option.value === value);

if (!selectedButton) {
return;
}

setSelected(selectedButton);
};

const getButtonColor = useCallback(
(value: string) => {
return selected?.value === value ? 'r1' : 'outlined';
},
[selected]
);

useEffect(() => {
const customEvent = {
target: {
name: register.name,
value: selected,
},
};
register.onChange(customEvent);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [selected]);

useEffect(() => {
setSelected(options[0]);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

return (
<div className={`mb-3 grid gap-0 grid-cols-${options.length}`}>
{options.map((option, index) => (
<div key={`option-${index}`} className="col-span-1">
<Button
size="lg"
type="button"
onClick={() => handleButtonClick(option.value)}
color={getButtonColor(option.value)}
>
{option.label}
</Button>
</div>
))}
</div>
);
}

export default MultiButton;
2 changes: 1 addition & 1 deletion components/Radio/Radio.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import React, { ChangeEvent } from 'react';
import { UseFormRegisterReturn } from 'react-hook-form';

interface Option {
export interface Option {
value: string;
label: string;
}
Expand Down
1 change: 0 additions & 1 deletion components/layouts/RoomListLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import Header from '@/components/Header/Header.tsx';
import useModal from '@/hooks/useModal.ts';
import Step1 from '@/pages/room/addRoom/step1.tsx';


interface AppLayoutProps {
children: ReactNode;
}
Expand Down
22 changes: 11 additions & 11 deletions pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useEffect, useState } from 'react';
import 'tailwindcss/tailwind.css';
import RoomCard from '@/components/RoomCard/RoomCard';
import { fetchRooms } from '@/api/room';
import { fetchRooms } from '@/api/room-dev';
import { Room } from '@/public/types/room';
import { NextPage, NextPageContext } from 'next';
import RoomListLayout from '@/components/layouts/RoomListLayout.tsx';
Expand Down Expand Up @@ -43,7 +43,7 @@ function Home() {
setFilters(() => [...resultFilter]);
};

const makeSubmitParam = (data: FieldValues) : FilterType => {
const makeSubmitParam = (data: FieldValues): FilterType => {
const typeOfHousings = ['studioChecked', 'bedFlatsChecked', 'shareHouseChecked'];
const furnishings = [
'bedChecked',
Expand All @@ -56,15 +56,15 @@ function Home() {
'doorLockChecked',
'tvChecked',
'kitchenetteChecked',
'heaterChecked'
'heaterChecked',
];

let typeOfHousing = false;
let furnishing = false;
let monthRent = false;
let deposit = false;
let location = false;
let dateAvailable = false
let dateAvailable = false;

// typeOfHousing 중 하나라도 체크되면 true
typeOfHousings.forEach((key) => {
Expand Down Expand Up @@ -139,20 +139,20 @@ function Home() {
let result = false;
if ((clickedChip || '') !== '' && filters.length > 1) {
result = filters[0] === option;
} else if (filters.length === 1 ) {
result = option === filters[0]
} else if (filters.length === 1) {
result = option === filters[0];
}
return result;
};
// 옵션 제거 시 실행될 함수
const handleOptionRemove = (option: string, index: number) => {
const resultFilters = filters.filter( (item) => item !== option);
const resultFilters = filters.filter((item) => item !== option);
setFilters(() => [...resultFilters]);

// 선택된 칩이 없거나 클릭된 칩이 삭제된 칩인 경우에 맨 처음 칩을 clickedChip으로 설정
//if ((clickedChip || '' ) === '' || selectedOptions.length !== filters.length) {
if ((clickedChip || '' ) === '') {
setClickedChip(filters?.[0]);
// if ((clickedChip || '' ) === '' || selectedOptions.length !== filters.length) {
if ((clickedChip || '') === '') {
setClickedChip(filters?.[0]);
}
};

Expand Down Expand Up @@ -184,7 +184,7 @@ function Home() {
</Typography>
{rooms.map((room, idx) => (
// Nav 영역 맨 마지막 부분 잘리는 문제로 추가
<div className={`mt-[20px] ${rooms.length-1 === idx ? 'mb-[83px]': ''}`} key={`room-${idx}`}>
<div className={`mt-[20px] ${rooms.length - 1 === idx ? 'mb-[83px]' : ''}`} key={`room-${idx}`}>
<RoomCard room={room} onClick={() => handleCardClick(idx)} />
</div>
))}
Expand Down
1 change: 0 additions & 1 deletion pages/login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ export const getStaticProps = async ({ locale }: GetStaticPropsContext) => ({
});

export default function Login() {
const router = useRouter();
const { t } = useTranslation('common');
const {
handleSubmit,
Expand Down
2 changes: 1 addition & 1 deletion pages/room/[id].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useEffect } from 'react';
import { Button, Header, Space } from '@/components/index.tsx';
import { Swiper, SwiperSlide } from 'swiper/react';
import 'swiper/css';
import { fetchRoom } from '@/api/room';
import { fetchRoom } from '@/api/room-dev';
import { useRouter } from 'next/router';
import { ROOM_TYPE, Room } from '@/public/types/room';
import { formatAge, formatDate, formatPrice } from '@/utils/transform';
Expand Down
3 changes: 3 additions & 0 deletions pages/room/add/add.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.sub-header {
@apply font-pretendard font-semibold text-[16px];
}
Loading

0 comments on commit 55c363b

Please sign in to comment.