Skip to content

Commit

Permalink
Feat: Chat-284-카카오-로그인-api-연동 (#85)
Browse files Browse the repository at this point in the history
* Feat: userId localStorage에 저장

* Feat: 선택된 날짜로 날짜 선택 바텀시트 초기화

* Feat: 로그인 api 연동 최종

* Feat: 로그인 api 연동 최최종

* Fix: 통계 userId localStorage로부터 받아옴

* Refactor: loginApi 호출 수정

* Fix: 상세 userId localStorage로부터 받아옴

* Fix: 태그 userId localStorage로부터 받아옴

* Fix: diaryList userId localStorage로부터 받아옴

* Fix: home userId localStoage로부터 받아옴

* Feat: 사용자 이름 서버로부터 받아옴

* Feat: localStorage에 userId가 없을 때 예외 처리 추가

* Refactor: 안쓰는 userId 변수 제거

* Style: console.log 제거
  • Loading branch information
somin-jeong authored Feb 18, 2024
1 parent 09ae6d4 commit c3496fe
Show file tree
Hide file tree
Showing 22 changed files with 194 additions and 161 deletions.
5 changes: 3 additions & 2 deletions src/apis/aiChatApi.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { HTTP_URL } from '.';
import { getUserId } from '../utils/user';

export const getChatData = async (userId: number, chatId: string) => {
export const getChatData = async (chatId: string) => {
const res = await fetch(
`${HTTP_URL}/chat/get?userId=${userId}&chatId=${chatId}`,
`${HTTP_URL}/chat/get?userId=${getUserId()}&chatId=${chatId}`,
);
const data = await res.json();
return data;
Expand Down
21 changes: 11 additions & 10 deletions src/apis/analysisApi.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { HTTP_URL } from '.';
import { getUserId } from '../utils/user';

export interface frequentTagType {
category: string;
Expand All @@ -13,25 +14,25 @@ export interface frequentAiType {
percentage: number;
}

export const getFrequentTags = async (memberId: number, type: string) => {
const res = await fetch(
`${HTTP_URL}/diary/tags?memberId=${memberId}&type=${type}`,
);
const data = res.json();
return data;
export const getFrequentTags = async (type: string) => {
const res = await fetch(
`${HTTP_URL}/diary/tags?memberId=${getUserId()}&type=${type}`,
);
const data = res.json();
return data;
};

export const getFrequentAis = async (memberId: number, type: string) => {
export const getFrequentAis = async (type: string) => {
const res = await fetch(
`${HTTP_URL}/chat/sender?memberId=${memberId}&type=${type}`,
`${HTTP_URL}/chat/sender?memberId=${getUserId()}&type=${type}`,
);
const data = res.json();
return data;
};

export const getTagDetailRanking = async (memberId: number, type: string) => {
export const getTagDetailRanking = async (type: string) => {
const res = await fetch(
`${HTTP_URL}/diary/tags/detail?memberId=${memberId}&type=${type}`,
`${HTTP_URL}/diary/tags/detail?memberId=${getUserId()}&type=${type}`,
);
const data = res.json();
return data;
Expand Down
9 changes: 5 additions & 4 deletions src/apis/diaryDetailApi.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { HTTP_URL } from '.';
import { getUserId } from '../utils/user';

export interface DiaryDetailType {
userId: number;
Expand All @@ -12,9 +13,9 @@ export interface DiaryDetailType {
newImgFile?: File[]; // 프론트 디버깅용 -> 서버에 전달 X
}

export const getDiaryDetail = async (userId: number, diaryDate: string) => {
export const getDiaryDetail = async (diaryDate: string) => {
const res = await fetch(
`${HTTP_URL}/diary/detail?user_id=${userId}&diary_date=${diaryDate}`,
`${HTTP_URL}/diary/detail?user_id=${getUserId()}&diary_date=${diaryDate}`,
);

if (!res.ok) {
Expand All @@ -39,14 +40,14 @@ export const modifyDiaryDetail = async (newData: FormData) => {
return data;
};

export const deleteDiary = async (userId: number, diaryDate: string) => {
export const deleteDiary = async (diaryDate: string) => {
const res = await fetch(`${HTTP_URL}/diary/delete`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
userId: userId,
userId: getUserId(),
diaryDate: diaryDate,
}),
});
Expand Down
9 changes: 3 additions & 6 deletions src/apis/diaryListApi.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import { HTTP_URL } from '.';
import { getUserId } from '../utils/user';

export const getDiaryList = async (
userId: number,
year: number,
month: number,
) => {
export const getDiaryList = async (year: number, month: number) => {
const res = await fetch(
`${HTTP_URL}/diary/monthly/list?user_id=${userId}&year=${year}&month=${month}`,
`${HTTP_URL}/diary/monthly/list?user_id=${getUserId()}&year=${year}&month=${month}`,
);
const data = await res.json();
return data;
Expand Down
7 changes: 4 additions & 3 deletions src/apis/home.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { HTTP_URL } from '.';
import { getUserId } from '../utils/user';

export const getCalendarData = async (month: string) => {
const res = await fetch(`${HTTP_URL}/chat/chat?memberId=1&month=${month}`);
const res = await fetch(`${HTTP_URL}/chat/chat?memberId=${getUserId()}&month=${month}`);
const data = await res.json();
return data;
};

export const getDiaryStreakDate = async (memberId: number) => {
const res = await fetch(`${HTTP_URL}/diary/streak?memberId=${memberId}`);
export const getDiaryStreakDate = async () => {
const res = await fetch(`${HTTP_URL}/diary/streak?memberId=${getUserId()}`);
const data = await res.json();
return data;
};
7 changes: 7 additions & 0 deletions src/apis/loginApi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { HTTP_URL } from '.';

export const login = async (code: string) => {
const res = await fetch(`${HTTP_URL}/kakao/login?code=${code}`);
const data = await res.json();
return data;
};
4 changes: 2 additions & 2 deletions src/apis/tagApi.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { HTTP_URL } from '.';
import { getUserId } from '../utils/user';

export const getDiaryListByTag = async (
memberId: number,
tagName: string[],
) => {
const tagParams = tagName.map((tag) => `tagName=${tag}`).join('&');
const res = await fetch(
`${HTTP_URL}/diary/list/tag?userId=${memberId}&${tagParams}`,
`${HTTP_URL}/diary/list/tag?userId=${getUserId()}&${tagParams}`,
);
const data = await res.json();
return data;
Expand Down
130 changes: 69 additions & 61 deletions src/components/common/BottomSheets/DateSelect/DatePicker.tsx
Original file line number Diff line number Diff line change
@@ -1,69 +1,77 @@
import { useState, useRef, useEffect } from "react";
import { useState, useRef, useEffect } from 'react';
import styles from './DatePicker.module.scss';

interface ScrollPickerProps {
list: (string | number)[];
onSelectedChange?: (selected: string | number) => void;
list: (string | number)[];
onSelectedChange?: (selected: string | number) => void;
prevSelected?: number;
}

const DatePicker = ({ list, onSelectedChange }: ScrollPickerProps) => {
const SCROLL_DEBOUNCE_TIME = 100; // 스크롤 이벤트의 디바운스 시간을 설정합니다

const newList = ["", ...list, ""];
const ref = useRef<HTMLUListElement>(null);
const [selected, setSelected] = useState(1);
const itemRefs = useRef<(HTMLLIElement | null)[]>([]);
const timerRef = useRef<NodeJS.Timeout | null>(null);
const ITEM_HEIGHT = 44;

const handleScroll = () => {
if (ref.current) {
// 스크롤 이벤트가 발생할 때마다 이전에 설정된 디바운스 타이머를 초기화합니다.
clearTimeout(timerRef.current!);

// 스크롤 위치가 맨 앞의 빈 문자열을 가리키지 않게합니다.
if (ref.current.scrollTop < ITEM_HEIGHT) {
ref.current.scrollTop = ITEM_HEIGHT;
}

// 일정시간이 지난 후에 스크롤 위치를 계산 및 이동합니다.
timerRef.current = setTimeout(() => {
const index = Math.floor(
(ref.current!.scrollTop + ITEM_HEIGHT / 2) / ITEM_HEIGHT,
);

// 맨 앞, 뒤 값일 경우 무시
if (list[index] !== "") {
setSelected(index);
itemRefs.current[index]?.scrollIntoView({
behavior: "smooth",
block: "center",
});
onSelectedChange && onSelectedChange(newList[index]);
}
}, SCROLL_DEBOUNCE_TIME);
}
}

useEffect(() => {
if (ref.current) {
ref.current.scrollTop = selected * ITEM_HEIGHT;
const DatePicker = ({
list,
onSelectedChange,
prevSelected,
}: ScrollPickerProps) => {
const SCROLL_DEBOUNCE_TIME = 100; // 스크롤 이벤트의 디바운스 시간을 설정합니다

const newList = ['', ...list, ''];
const ref = useRef<HTMLUListElement>(null);
const [selected, setSelected] = useState(1);
const itemRefs = useRef<(HTMLLIElement | null)[]>([]);
const timerRef = useRef<NodeJS.Timeout | null>(null);
const ITEM_HEIGHT = 44;

const handleScroll = () => {
if (ref.current) {
// 스크롤 이벤트가 발생할 때마다 이전에 설정된 디바운스 타이머를 초기화합니다.
clearTimeout(timerRef.current!);

// 스크롤 위치가 맨 앞의 빈 문자열을 가리키지 않게합니다.
if (ref.current.scrollTop < ITEM_HEIGHT) {
ref.current.scrollTop = ITEM_HEIGHT;
}

// 일정시간이 지난 후에 스크롤 위치를 계산 및 이동합니다.
timerRef.current = setTimeout(() => {
const index = Math.floor(
(ref.current!.scrollTop + ITEM_HEIGHT / 2) / ITEM_HEIGHT,
);

// 맨 앞, 뒤 값일 경우 무시
if (list[index] !== '') {
setSelected(index);
itemRefs.current[index]?.scrollIntoView({
behavior: 'smooth',
block: 'center',
});
onSelectedChange && onSelectedChange(newList[index]);
}
}, []);
}, SCROLL_DEBOUNCE_TIME);
}
};

return (
<ul className={styles.List} ref={ref} onScroll={handleScroll}>
<div className={styles.ListCenter}></div>
{newList.map((item, index) => (
<li className={`${styles.Date} ${(index === selected) ? styles.Selected : styles.Unselected}`}
key={index}
ref={(el) => (itemRefs.current[index] = el)}
>
{item}
</li>
))}
</ul>
);
}
useEffect(() => {
if (ref.current && prevSelected) {
ref.current.scrollTop = selected * ITEM_HEIGHT * prevSelected;
}
}, []);

return (
<ul className={styles.List} ref={ref} onScroll={handleScroll}>
<div className={styles.ListCenter}></div>
{newList.map((item, index) => (
<li
className={`${styles.Date} ${
index === selected ? styles.Selected : styles.Unselected
}`}
key={index}
ref={(el) => (itemRefs.current[index] = el)}
>
{item}
</li>
))}
</ul>
);
};

export default DatePicker;
export default DatePicker;
47 changes: 13 additions & 34 deletions src/components/common/BottomSheets/DateSelect/DateSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import styles from './DateSelector.module.scss';
import BottomModal from '../BottomModal';
import DatePicker from './DatePicker';
import ConfirmButton from '../../Buttons/ConfirmBtn/ConfirmButton';
import useDateStore from '../../../../stores/dateStore';
import { da } from 'date-fns/locale';

interface DateSelectorProps {
clickOuter: React.Dispatch<React.SetStateAction<boolean>>;
Expand All @@ -21,31 +23,9 @@ const DateSelector = ({
isOpen,
onSelectDate,
}: DateSelectorProps) => {
const [year, setYear] = useState('');
const [month, setMonth] = useState('');
const [day, setDay] = useState('');
const { year, month, day, setYear, setMonth, setDay } = useDateStore();

const yearList = [
'2000년',
'2001년',
'2002년',
'2003년',
'2004년',
'2005년',
'2006년',
'2007년',
'2008년',
'2009년',
'2010년',
'2011년',
'2012년',
'2013년',
'2014년',
'2015년',
'2016년',
'2017년',
'2018년',
'2019년',
'2020년',
'2021년',
'2022년',
Expand Down Expand Up @@ -101,23 +81,22 @@ const DateSelector = ({
];

const handleChangeYear = (selectedItem: string | number) => {
setYear(selectedItem as string);
const yearFormattedString = selectedItem as string;
setYear(Number(yearFormattedString.replace(/[^0-9]/g, '')));
};

const handleChangeMonth = (selectedItem: string | number) => {
setMonth(selectedItem as string);
const monthFormattedString = selectedItem as string;
setMonth(Number(monthFormattedString.replace(/[^0-9]/g, '')));
};

const handleChangeDay = (selectedItem: string | number) => {
setDay(selectedItem as string);
const dayFormattedString = selectedItem as string;
setMonth(Number(dayFormattedString.replace(/[^0-9]/g, '')));
};

const onClickConfirmButton = () => {
const yearFormattedString = year.replace(/[^0-9]/g, '');
const monthFormattedString = month.replace(/[^0-9]/g, '');
const dayFormattedString = day.replace(/[^0-9]/g, '');

onSelectDate(Number(yearFormattedString), Number(monthFormattedString), Number(dayFormattedString));
onSelectDate(Number(year), Number(month), Number(day));
};

return (
Expand All @@ -130,10 +109,10 @@ const DateSelector = ({
<div className={styles.SelectDate}>년/월 선택</div>
)}
<div className={styles.DatePicker}>
<DatePicker list={yearList} onSelectedChange={handleChangeYear} />
<DatePicker list={monthList} onSelectedChange={handleChangeMonth} />
<DatePicker list={yearList} prevSelected={year-2019} onSelectedChange={handleChangeYear} />
<DatePicker list={monthList} prevSelected={month} onSelectedChange={handleChangeMonth} />
{isFullDate ? (
<DatePicker list={dayList} onSelectedChange={handleChangeDay} />
<DatePicker list={dayList} prevSelected={day} onSelectedChange={handleChangeDay} />
) : (
<></>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const HomeProfileHeader = ({ diaryStreakDate }: IProps) => {
className={styles.UserProfile}
/>
<div className={styles.UserInfo}>
<span className={styles.Nickname}>예랑쟤랑</span>
<span className={styles.Nickname}>{localStorage.getItem("nickname")}</span>
<div className={styles.StartDate}>
꾸준히 일기 쓴 지 {diaryStreakDate?.diaryStreakDate}일 째에요
</div>
Expand Down
Loading

0 comments on commit c3496fe

Please sign in to comment.