Skip to content
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

지도/코스 검색 API 연동 , UI 스타일 수정 #222

Merged
merged 12 commits into from
Dec 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
<div align='center'>
<img src="https://github.com/user-attachments/assets/b30a96fe-c822-499d-942c-88e7ece72fb3" width=600 alt="오늘의 길">
<h3> 나만의 길을 따라 일상을 공유하다 🗺️ </h3>

<img src="https://github.com/user-attachments/assets/d1b124e0-682c-4665-a418-600e97d15a35" width=1000 alt="오늘의 길">
</div>

---
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/api/course/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,11 @@ export const getCourse = async (courseId: number) => {
return data;
};

export const getCourseList = async (pageParam: number) => {
export const getCourseList = async (pageParam: number, query?: string) => {
const { data } = await axiosInstance.get<CourseList>(END_POINTS.COURSES, {
params: {
page: pageParam,
query,
},
useAuth: false,
});
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/api/map/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,11 @@ export const createMap = async (baseMapData: Omit<BaseMap, 'mode'>) => {
return data.id;
};

export const getMapList = async (pageParam: number) => {
export const getMapList = async (pageParam: number, query?: string) => {
const { data } = await axiosInstance.get<MapList>(END_POINTS.MAPS, {
params: {
page: pageParam,
query,
},
useAuth: false,
});
Expand Down
35 changes: 35 additions & 0 deletions frontend/src/assets/empty.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions frontend/src/components/Banner/BannerSlider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const BannerSlider: React.FC<BannerSliderProps> = ({
speed: interval / 10,
slidesToShow: 1,
slidesToScroll: 1,
autoplay: true,
autoplaySpeed: interval,
};

Expand All @@ -39,6 +40,9 @@ const BannerSlider: React.FC<BannerSliderProps> = ({
{banners.map((banner, index) => (
<div key={index} className={'cursor-pointer'}>
<img
className={
'box-sizing:border-box h-full w-full rounded-md border-[1.5px] border-c_border_gray'
}
src={banner.imageUrl}
alt={`Banner ${index}`}
onClick={() => window.open(banner.redirectUrl, '_blank')}
Expand Down
42 changes: 0 additions & 42 deletions frontend/src/components/Map/CourseItem.tsx

This file was deleted.

40 changes: 0 additions & 40 deletions frontend/src/components/Map/CourseListPanel.tsx

This file was deleted.

4 changes: 2 additions & 2 deletions frontend/src/components/Map/MapDetailBoard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import SideContainer from '@/components/common/SideContainer';
import Marker from '@/components/Marker/Marker';
import DeleteMapButton from './DeleteMapButton';
import EditMapButton from './EditMapButton';
import MapThumbnail from './MapThumbnail';
import ListItemThumbnail from '@/components/common/List/ListItemThumbnail';

type MapDetailBoardProps = {
mapData: Map;
Expand Down Expand Up @@ -54,7 +54,7 @@ const MapDetailBoard = ({ mapData }: MapDetailBoardProps) => {
)}

{mapData.thumbnailUrl.startsWith('https://example') ? (
<MapThumbnail className="h-full w-full" />
<ListItemThumbnail className="h-full w-full" />
) : (
<img src={mapData.thumbnailUrl} className="object-cover"></img>
)}
Expand Down
38 changes: 0 additions & 38 deletions frontend/src/components/Map/MapItem.tsx

This file was deleted.

39 changes: 0 additions & 39 deletions frontend/src/components/Map/MapListPanel.tsx

This file was deleted.

12 changes: 12 additions & 0 deletions frontend/src/components/common/List/Course/CourseItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { MapItemType } from '@/types';
import ListItem from '@/components/common/List/ListItem';

type CourseItemProps = {
courseItem: MapItemType;
};

const CourseItem = ({ courseItem }: CourseItemProps) => {
return <ListItem item={courseItem} linkPrefix="course" />;
};

export default CourseItem;
39 changes: 39 additions & 0 deletions frontend/src/components/common/List/Course/CourseListPanel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React from 'react';

import { getCourseList } from '@/api/course';
import { useInfiniteScroll } from '@/hooks/useInfiniteScroll';
import { CourseList } from '@/types';

import CourseItem from './CourseItem';
import InfiniteListPanel from '@/components/common/List/InfiniteListPanel';

interface CourseListPanelProps {
query?: string;
}

const CourseListPanel: React.FC<CourseListPanelProps> = ({ query }) => {
const { data, ref } = useInfiniteScroll<CourseList>({
queryKey: ['courseList'],
queryFn: ({ pageParam }) => getCourseList(pageParam, query),
getNextPageParam: (lastPage) =>
lastPage.currentPage < lastPage.totalPages
? lastPage.currentPage + 1
: undefined,
fetchWithoutQuery: true,
});

const courseItems = data?.pages.flatMap((page) => page.courses) || [];

return (
<InfiniteListPanel
data={courseItems}
ref={ref}
renderItem={(course) => (
<CourseItem key={course.id} courseItem={course} />
)}
className="max-h-[700px] p-5"
/>
);
};

export default CourseListPanel;
41 changes: 41 additions & 0 deletions frontend/src/components/common/List/InfiniteListPanel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from 'react';
import emptyImage from '../../../assets/empty.svg';

interface InfiniteListPanelProps<T> {
data: T[] | undefined;
ref: React.Ref<HTMLDivElement>;
renderItem: (item: T) => React.ReactNode;
className?: string;
}

const InfiniteListPanel = <T,>({
data,
ref,
renderItem,
className,
}: InfiniteListPanelProps<T>) => {
return (
<div
ref={ref}
className={`scrollbar-thumb-rounded-lg relative mt-2 overflow-y-auto scrollbar-thin scrollbar-track-transparent scrollbar-thumb-gray-200 hover:scrollbar-track-gray-400 hover:scrollbar-thumb-gray-400 ${className}`}
>
{data && data.length > 0 ? (
<div className="mt-1 grid h-full w-full grid-cols-5 gap-8">
{data.map((item, index) => (
<React.Fragment key={index}>{renderItem(item)}</React.Fragment>
))}
</div>
) : (
<div className="flex h-full w-full items-center justify-center">
<img
src={emptyImage}
alt="리스트가 텅 비었습니다!"
className="w-100 object-contain py-10"
/>
</div>
)}
</div>
);
};

export default InfiniteListPanel;
57 changes: 57 additions & 0 deletions frontend/src/components/common/List/ListItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { Link } from 'react-router-dom';
import PinIcon from '@/components/PinIcon';
import React from 'react';
import ListItemThumbnail from '@/components/common/List/ListItemThumbnail';

type ListItemProps<T> = {
item: T;
linkPrefix: string;
};

const ListItem = <
T extends {
id: number;
title: string;
thumbnailUrl: string;
user: { profileImageUrl: string; nickname: string };
pinCount: number;
},
>({
item,
linkPrefix,
}: ListItemProps<T>) => {
return (
<Link to={`/${linkPrefix}/${item.id}`}>
<div className="h-50 flex flex-col gap-2 rounded-md border-[1.5px] border-gray-200 p-3">
<div className="aspect-[4/3] w-full overflow-hidden rounded-md bg-gray-100">
{item.thumbnailUrl.startsWith('https://example') ? (
<ListItemThumbnail className="h-full w-full object-cover" />
) : (
<img
src={item.thumbnailUrl}
className="h-full w-full object-cover"
alt={item.title}
/>
)}
</div>

<p className="truncate text-sm font-medium">{item.title}</p>

<div className="flex items-center gap-2">
<img
className="h-6 w-6 rounded-full"
src={item.user.profileImageUrl}
alt={item.user.nickname}
/>
<p className="text-xs text-gray-700">{item.user.nickname}</p>
<PinIcon className="h-4 w-4" fill="#DC1414" />
<div className="flex w-5 justify-center rounded-md border-[0.5px] border-gray-400 text-xs text-gray-500">
<p>{item.pinCount}</p>
</div>
</div>
</div>
</Link>
);
};

export default ListItem;
Loading
Loading