-
Notifications
You must be signed in to change notification settings - Fork 2
[Feature] 메인 화면 API 연결 #96
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
6e983be
ec6d06a
ed6ad3f
9e61971
a7dc908
9df3483
3b98c27
3f9d4ab
914dbdf
4315e1a
c1b8da1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| import type { IDateCourseSavedCountResponse } from '../../types/home/dateCourse'; | ||
| import { axiosInstance } from '../axiosInstance'; | ||
|
|
||
| // 데이트 코스 저장 횟수 조회 API | ||
| export const getDateCourseSavedCount = async (): Promise<IDateCourseSavedCountResponse> => { | ||
| try { | ||
| const response = await axiosInstance.get('/api/v1/logs/datecourses/saved-count'); | ||
| return response.data; | ||
| } catch { | ||
| throw new Error('데이트 코스 저장 횟수를 가져오는데 실패했습니다.'); | ||
| } | ||
yeonjin719 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| }; | ||
yeonjin719 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| import type { TMonthlyDatePlaceResponse } from '../../types/home/datePlace'; | ||
| import { axiosInstance } from '../axiosInstance'; | ||
yeonjin719 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| export const getMonthlyDatePlaceStates = async (): Promise<TMonthlyDatePlaceResponse> => { | ||
| const { data } = await axiosInstance.get('/api/v1/logs/dateplaces/monthly'); | ||
| return data; | ||
| }; | ||
yeonjin719 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
yeonjin719 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| import type { TGetDateTimeStats, TMonthlyDatePlaceResponse } from '../../types/home/datePlace'; | ||
| import { axiosInstance } from '../axiosInstance'; | ||
|
|
||
| // 월별 데이트 장소 수 조회 API | ||
| export const getMonthlyDatePlaceStats = async (): Promise<TMonthlyDatePlaceResponse> => { | ||
| try { | ||
| const response = await axiosInstance.get('/api/v1/logs/dateplaces/monthly'); | ||
| return response.data; | ||
| } catch { | ||
| throw new Error('월별 데이트 장소 통계를 가져오는데 실패했습니다.'); | ||
| } | ||
| }; | ||
yeonjin719 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
yeonjin719 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| export const getDateTimeStats = async (): Promise<TGetDateTimeStats> => { | ||
| const { data } = await axiosInstance.get('/api/v1/logs/datecourses/average'); | ||
| return data; | ||
| }; | ||
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| import type { TWeeklyKeywordResponse } from '../../types/home/keyword'; | ||
| import { axiosInstance } from '../axiosInstance'; | ||
|
|
||
| // 이번 주 인기 키워드 조회 API | ||
| export const getWeeklyKeywords = async (): Promise<TWeeklyKeywordResponse> => { | ||
| const { data } = await axiosInstance.get('/api/v1/logs/keyword/weekly'); | ||
| return data; | ||
| }; | ||
yeonjin719 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,8 @@ | ||||||||||
| import type { TUserGradeResponse } from '../../types/home/level'; | ||||||||||
| import { axiosInstance } from '../axiosInstance'; | ||||||||||
|
|
||||||||||
| // 사용자 등급 조회 API | ||||||||||
| export const getUserGrade = async (): Promise<TUserGradeResponse> => { | ||||||||||
| const { data } = await axiosInstance.get('/api/v1/members/grade'); | ||||||||||
| return data; | ||||||||||
|
Comment on lines
+7
to
+8
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick (assertive) Axios 제네릭으로 응답 타입 안전성 강화 응답 타입을 제네릭으로 명시하면 data의 타입 안정성이 올라갑니다. 아래처럼 변경을 권장합니다. - const { data } = await axiosInstance.get('/api/v1/members/grade');
+ const { data } = await axiosInstance.get<TUserGradeResponse>('/api/v1/members/grade');📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||
| }; | ||||||||||
yeonjin719 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,8 @@ | ||||||||||||||||||
| import type { TPatchUserRegionRequest, TPatchUserRegionResponse } from '@/types/home/region'; | ||||||||||||||||||
|
|
||||||||||||||||||
| import { axiosInstance } from '@/api/axiosInstance'; | ||||||||||||||||||
|
|
||||||||||||||||||
| export const patchUserRegion = async ({ regionId }: TPatchUserRegionRequest): Promise<TPatchUserRegionResponse> => { | ||||||||||||||||||
| const { data } = await axiosInstance.patch('/api/v1/regions/users', { regionId }); | ||||||||||||||||||
| return data; | ||||||||||||||||||
yeonjin719 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
| }; | ||||||||||||||||||
coderabbitai[bot] marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
Comment on lines
+5
to
+8
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick (assertive) Axios 제네릭으로 응답 타입 명시 응답 타입을 명확히 지정해 런타임 이슈를 컴파일 타임에 방지하는 것을 권장합니다. export const patchUserRegion = async ({ regionId }: TPatchUserRegionRequest): Promise<TPatchUserRegionResponse> => {
- const { data } = await axiosInstance.patch('/api/v1/regions/users', { regionId });
+ const { data } = await axiosInstance.patch<TPatchUserRegionResponse>('/api/v1/regions/users', { regionId });
return data;
};📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| import type { | ||
| TGetPrecipitationRequest, | ||
| TGetPrecipitationResponse, | ||
| TGetWeeklyWeatheerRecommendationRequest, | ||
| TGetWeeklyWeatheerRecommendationResponse, | ||
| } from '@/types/home/weather'; | ||
yeonjin719 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| import { axiosInstance } from '../axiosInstance'; | ||
|
|
||
| // 주간 날씨 추천 조회 API | ||
| export const getWeeklyWeatherRecommendation = async ({ | ||
| regionId, | ||
| startDate, | ||
| }: TGetWeeklyWeatheerRecommendationRequest): Promise<TGetWeeklyWeatheerRecommendationResponse> => { | ||
| const { data } = await axiosInstance.get(`/api/v1/weather/${regionId}/weekly`, { params: { startDate: startDate } }); | ||
| return data; | ||
yeonjin719 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| }; | ||
| export const getPrecipitation = async ({ regionId, startDate }: TGetPrecipitationRequest): Promise<TGetPrecipitationResponse> => { | ||
| const { data } = await axiosInstance.get(`/api/v1/weather/${regionId}/precipitation`, { params: { startDate: startDate } }); | ||
| return data; | ||
| }; | ||
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -6,6 +6,8 @@ import DateCourseSearchFilterModal from '@/components/modal/dateCourseSearchFilt | |||||||
| import ErrorModal from '@/components/modal/errorModal'; | ||||||||
| import SettingsModal from '@/components/modal/SettingModal'; | ||||||||
|
|
||||||||
| import RegionModal from '../modal/regionModal'; | ||||||||
|
|
||||||||
|
Comment on lines
+9
to
+10
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick (assertive) 경로 alias 일관성 유지 제안 다른 모달들은 절대 경로 alias('@/components/...')를 사용하고 있는데, RegionModal만 상대 경로를 사용합니다. 팀 규칙에 맞춰 alias로 통일하면 가독성과 유지보수성이 좋아집니다. 적용 예시: -import RegionModal from '../modal/regionModal';
+import RegionModal from '@/components/modal/regionModal';📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||
| import useModalStore from '@/store/useModalStore'; | ||||||||
|
|
||||||||
| // 모달 타입 정의 -> 만약 다른 모달을 추가하고 싶다면 여기에 타입을 추가하고, MODAL_COMPONENTS에 컴포넌트를 추가하면 됩니다. | ||||||||
|
|
@@ -15,13 +17,15 @@ export const MODAL_TYPES = { | |||||||
| DateCourseSearchFilterModal: 'DateCourseSearchFilterModal', | ||||||||
| SettingsModal: 'SettingsModal', //설정 모달 추가 | ||||||||
| AlarmModal: 'AlarmModal', | ||||||||
| RegionModal: 'RegionModal', | ||||||||
| }; | ||||||||
|
|
||||||||
| export const MODAL_COMPONENTS = { | ||||||||
| [MODAL_TYPES.ErrorModal]: ErrorModal, | ||||||||
| [MODAL_TYPES.DateCourseSearchFilterModal]: DateCourseSearchFilterModal, | ||||||||
| [MODAL_TYPES.SettingsModal]: SettingsModal, | ||||||||
| [MODAL_TYPES.AlarmModal]: AlarmModal, | ||||||||
| [MODAL_TYPES.RegionModal]: RegionModal, | ||||||||
| }; | ||||||||
|
Comment on lines
23
to
29
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick (assertive) MODAL_COMPONENTS에 명시적 타입 지정 권장 현재 예시(제안 코드): import type { ComponentType } from 'react';
type ModalBaseProps = { onClose: () => void } & Record<string, any>;
export const MODAL_COMPONENTS: Record<ModalType, ComponentType<ModalBaseProps>> = {
[MODAL_TYPES.ErrorModal]: ErrorModal,
[MODAL_TYPES.DateCourseSearchFilterModal]: DateCourseSearchFilterModal,
[MODAL_TYPES.SettingsModal]: SettingsModal,
[MODAL_TYPES.AlarmModal]: AlarmModal,
[MODAL_TYPES.RegionModal]: RegionModal,
};🤖 Prompt for AI Agents |
||||||||
|
|
||||||||
| export default function ModalProvider() { | ||||||||
|
|
||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -12,21 +12,25 @@ const slides = [ | |||||||||||||||||||||||||||||||
| title: '서울 성수동 : 옛것과 새로운 것이 교차하는 하루', | ||||||||||||||||||||||||||||||||
| description: '1960년대부터 조성된 오래된 공장 건물과 최근 벽돌 건물들의 분위기', | ||||||||||||||||||||||||||||||||
| tags: ['#활발한 활동', '#레트로 감성', '#서울 핫플'], | ||||||||||||||||||||||||||||||||
| img: scroll, | ||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||
yeonjin719 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||
| title: '한강 자전거 데이트 : 바람 따라 달리는 낭만', | ||||||||||||||||||||||||||||||||
| description: '도심 속 자연을 만끽하며 힐링 타임', | ||||||||||||||||||||||||||||||||
| tags: ['#운동 데이트', '#자연과 함께', '#저녁노을'], | ||||||||||||||||||||||||||||||||
| img: scroll, | ||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||
| title: '이태원 세계 음식 투어 : 입 안 가득 여행', | ||||||||||||||||||||||||||||||||
| description: '세계 각국의 맛을 한 자리에서 즐기기', | ||||||||||||||||||||||||||||||||
| tags: ['#미식가 커플', '#이국적인 분위기', '#도심 속 여행'], | ||||||||||||||||||||||||||||||||
| img: scroll, | ||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||
| title: '북촌 한옥마을 산책 : 전통의 미를 따라 걷기', | ||||||||||||||||||||||||||||||||
| description: '골목골목 숨어있는 사진 명소', | ||||||||||||||||||||||||||||||||
| tags: ['#한옥', '#조용한 산책', '#전통과 현대'], | ||||||||||||||||||||||||||||||||
| img: scroll, | ||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||
| ]; | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
|
|
@@ -52,11 +56,11 @@ function Banner() { | |||||||||||||||||||||||||||||||
| setCurrentIndex((prevIndex) => (prevIndex + 1) % slides.length); | ||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| const { title, description, tags } = slides[currentIndex]; | ||||||||||||||||||||||||||||||||
| const { title, description, tags, img } = slides[currentIndex]; | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||
| <div className="relative w-full"> | ||||||||||||||||||||||||||||||||
| <img src={scroll} alt="배너" className="w-full h-[450px] object-cover" /> | ||||||||||||||||||||||||||||||||
| <img src={img} alt="배너" className="w-full h-[450px] object-cover" /> | ||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 배너 이미지에 기본 fallback 적용 + 접근성 향상(alt 동적화)
- const { title, description, tags, img } = slides[currentIndex];
+ const { title, description, tags } = slides[currentIndex];- <img src={img} alt="배너" className="w-full h-[450px] object-cover" />
+ <img src={slides[currentIndex].img ?? scroll} alt={title} className="w-full h-[450px] object-cover" />📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
yeonjin719 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||
| {/* 내용 */} | ||||||||||||||||||||||||||||||||
| <div className="absolute inset-0 flex flex-col justify-start px-4 sm:px-12 py-10 text-white z-10"> | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,8 +1,18 @@ | ||||||||||||||||||||||||||||||
| import React from 'react'; | ||||||||||||||||||||||||||||||
| import { useNavigate } from 'react-router-dom'; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| import { useDateCourseSavedCount } from '@/hooks/home/useDateCourseStats'; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| import MainCard from './mainCard'; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| import ArchiveBlank from '@/assets/icons/Archive_Blank.svg?react'; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| function DateCourseStore() { | ||||||||||||||||||||||||||||||
| const navigate = useNavigate(); | ||||||||||||||||||||||||||||||
| const { data, isLoading, error } = useDateCourseSavedCount(); | ||||||||||||||||||||||||||||||
| if (error) { | ||||||||||||||||||||||||||||||
| navigate('/error'); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
yeonjin719 marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 렌더 단계에서 navigate 호출은 부작용이므로 useEffect로 이동하세요 렌더 중 적용 예시(diff): - if (error) {
- navigate('/error');
- }
+ React.useEffect(() => {
+ if (error) {
+ navigate('/error', { replace: true });
+ }
+ }, [error, navigate]);
+ if (error) {
+ return null;
+ }📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||
| <MainCard> | ||||||||||||||||||||||||||||||
| <div className="flex flex-col px-4 sm:px-8 lg:px-[20px] py-8 lg:py-[28px] h-full justify-center"> | ||||||||||||||||||||||||||||||
|
|
@@ -11,11 +21,16 @@ function DateCourseStore() { | |||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||
| <div className="flex text-sm sm:text-base lg:text-m bold-medium text-[#616161] mb-1">내 데이트 코스를</div> | ||||||||||||||||||||||||||||||
| <div className="flex gap-1 items-center"> | ||||||||||||||||||||||||||||||
| <div className="text-lg sm:text-xl font-bold text-primary-700 whitespace-nowrap">2,345명</div> | ||||||||||||||||||||||||||||||
| {isLoading ? ( | ||||||||||||||||||||||||||||||
| <div className="text-lg sm:text-xl font-bold text-primary-700 whitespace-nowrap">로딩...</div> | ||||||||||||||||||||||||||||||
| ) : ( | ||||||||||||||||||||||||||||||
| <div className="text-lg sm:text-xl font-bold text-primary-700 whitespace-nowrap">{data?.result.count}명</div> | ||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||
yeonjin719 marked this conversation as resolved.
Show resolved
Hide resolved
Comment on lines
+22
to
+26
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick (assertive) 데이터 미도착 시 'undefined명' 노출 가능성 및 숫자 포매팅 개선 데이터가 일시적으로 없을 때 적용 예시(diff): - <div className="text-lg sm:text-xl font-bold text-primary-700 whitespace-nowrap">{data?.result.count}명</div>
+ <div className="text-lg sm:text-xl font-bold text-primary-700 whitespace-nowrap">
+ {(data?.result.count ?? 0).toLocaleString()}명
+ </div>📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||
| <div className="text-sm sm:text-base lg:text-m bold-medium text-[#616161] whitespace-nowrap">이 저장했어요.</div> | ||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||
| </MainCard> | ||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| export default DateCourseStore; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| export default React.memo(DateCourseStore); | ||||||||||||||||||||||||||||||
yeonjin719 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
coderabbitai[bot] marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,34 +1,36 @@ | ||
| import React, { useMemo } from 'react'; | ||
|
|
||
| import { useMontlyPlaceStates } from '@/hooks/home/useDatePlaceStates'; | ||
yeonjin719 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| import MainCard from '@/components/home/mainCard'; | ||
|
|
||
| function DateLocation() { | ||
| const { data } = useMontlyPlaceStates(); | ||
| const maxCount = useMemo(() => { | ||
| return data?.result?.datePlaceLogList?.reduce((max, cur) => Math.max(max, cur.count), 0) ?? 0; | ||
| }, [data]); | ||
yeonjin719 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| return ( | ||
| <MainCard> | ||
| <div className="py-[28px] flex flex-col"> | ||
| <div className="text-xl font-bold text-[#616161] mb-6">WithTime에 등록된 데이트 장소 수</div> | ||
| <div className="flex items-end gap-8 w-full justify-center"> | ||
| <div className="flex flex-col items-center"> | ||
| <span className="text-xs text-default-gray-500 mb-1">230</span> | ||
| <div className="h-16 w-10 bg-default-gray-400 mb-2 flex items-start justify-center" /> | ||
| <div className="text-default-gray-500 mt-1">2022</div> | ||
| </div> | ||
| <div className="flex flex-col items-center"> | ||
| <span className="text-xs text-default-gray-500 mb-1">430</span> | ||
| <div className="h-24 w-10 bg-default-gray-400 mb-2 flex items-start justify-center" /> | ||
| <div className="text-default-gray-500 mt-1">2023</div> | ||
| </div> | ||
| <div className="flex flex-col items-center"> | ||
| <span className="text-xs text-default-gray-500 mb-1">830</span> | ||
| <div className="h-36 w-10 bg-default-gray-400 mb-2 flex items-start justify-center" /> | ||
| <div className="text-default-gray-500 mt-1">2024</div> | ||
| </div> | ||
| <div className="flex flex-col items-center"> | ||
| <span className="text-xs text-default-gray-500 mb-1">1,230</span> | ||
| <div className="h-48 w-10 bg-default-gray-400 mb-2 flex items-start justify-center" /> | ||
| <div className="text-default-gray-500 mt-1">2025</div> | ||
| </div> | ||
| {data?.result.datePlaceLogList.map((graph, idx) => { | ||
| // 비율 계산 | ||
| const height = maxCount ? (graph.count / maxCount) * 200 : 0; // 최대 높이 200px 기준 | ||
| return ( | ||
yeonjin719 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| <div className="flex flex-col items-center" key={idx}> | ||
| <span className="text-xs text-default-gray-500 mb-1">{graph.count}</span> | ||
| <div | ||
| className="w-10 bg-default-gray-400 mb-2 flex items-start justify-center transition-all duration-300" | ||
| style={{ height: `${height}px` }} | ||
| /> | ||
yeonjin719 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| <div className="text-default-gray-500 mt-1">{graph.month}월</div> | ||
| </div> | ||
| ); | ||
| })} | ||
yeonjin719 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| </div> | ||
yeonjin719 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| </div> | ||
| </MainCard> | ||
| ); | ||
| } | ||
| export default DateLocation; | ||
| export default React.memo(DateLocation); | ||
Uh oh!
There was an error while loading. Please reload this page.