-
{item.title}
+
-
{`By. ${item.ownerNickname}`}
{item?.ownerProfileImage ? (
)}
+
{item.ownerNickname}
+
{`Ver.${item.version}`}
+
+
+
{item.title}
+
{item.description}
-
-
-
- {commonLocale[language].more}
-
-
)}
);
- })
- ) : (
-
-
-
- )}
+ })}
);
}
-export default ListRecommendation;
+export default FeedLists;
diff --git a/src/components/exploreComponents/FollowButton.tsx b/src/components/exploreComponents/FollowButton.tsx
index 885f4cb3..4aa4e339 100644
--- a/src/components/exploreComponents/FollowButton.tsx
+++ b/src/components/exploreComponents/FollowButton.tsx
@@ -11,7 +11,7 @@ import { QUERY_KEYS } from '@/lib/constants/queryKeys';
import { UserType } from '@/lib/types/userProfileType';
import toasting from '@/lib/utils/toasting';
import toastMessage, { MAX_FOLLOWING } from '@/lib/constants/toastMessage';
-import * as styles from './UsersRecommendation.css';
+import * as styles from './RecommendedUsers.css';
import useBooleanOutput from '@/hooks/useBooleanOutput';
import Modal from '@/components/Modal/Modal';
diff --git a/src/components/exploreComponents/ListsRecommendation.css.ts b/src/components/exploreComponents/ListsRecommendation.css.ts
index a5d78138..d3469839 100644
--- a/src/components/exploreComponents/ListsRecommendation.css.ts
+++ b/src/components/exploreComponents/ListsRecommendation.css.ts
@@ -6,6 +6,7 @@ export const listBackground = createVar();
export const wrapperOuter = style({
padding: '0 16px 70px',
+ marginTop: '12px',
display: 'flex',
flexDirection: 'column',
@@ -38,14 +39,14 @@ const listWrapperHoverAnimation = keyframes({
export const listWrapper = style({
width: '100%',
marginBottom: '35px',
- padding: '44px 24px 14px',
+ padding: '30px 24px 14px',
position: 'relative',
display: 'flex',
flexDirection: 'column',
borderRadius: '24px',
- backgroundColor: listBackground,
+ backgroundColor: '#fff',
':hover': {
animation: `${listWrapperHoverAnimation} 0.1s forwards`,
@@ -53,65 +54,64 @@ export const listWrapper = style({
},
});
-export const labelsWrapper = style({
+export const listTopWrapper = style({
display: 'flex',
- gap: '8px',
-});
-
-export const labelWrapper = style({
- marginRight: '8px',
+ alignItems: 'center',
+ justifyContent: 'space-between',
});
-export const categoryWrapper = style({
- marginBottom: '11px',
+export const version = style({
+ padding: '6px 12px',
- display: 'flex',
- justifyContent: 'flex-start',
- alignItems: 'center',
+ fontWeight: '400',
+ letterSpacing: '-3%',
+ fontSize: '1.4rem',
+ color: '#3D95FF',
+ backgroundColor: '#EEF6FF',
+ borderRadius: '20px',
});
export const listInformationWrapper = style({
- marginBottom: '23px',
+ marginBottom: '20px',
display: 'flex',
flexDirection: 'column',
});
-export const listTitle = style([
- headlineSmall,
- {
- color: vars.color.black,
- wordBreak: 'break-word',
- },
-]);
+export const listTitle = style({
+ color: '#3E4455',
+ wordBreak: 'break-word',
+ fontWeight: '700',
+ fontSize: '2rem',
+ letterSpacing: '-3%',
+});
-export const listDescription = style([
- bodyMedium,
- {
- marginTop: '13px',
+export const listDescription = style({
+ marginTop: '13px',
- color: vars.color.gray9,
- wordBreak: 'break-word',
- },
-]);
+ fontWeight: '400',
+ fontSize: '1.6rem',
+ color: '#3E4455',
+ wordBreak: 'break-word',
+});
export const ownerInformationWrapper = style({
display: 'flex',
- justifyContent: 'flex-end',
+ justifyContent: 'flex-start',
alignItems: 'center',
gap: '8px',
});
-export const ownerNicknameText = style([
- bodySmall,
- {
- color: vars.color.black,
- },
-]);
+export const ownerNicknameText = style({
+ color: '#676B75',
+ fontSize: '1.6rem',
+ fontWeight: '500',
+ letterSpacing: '-3%',
+});
export const profileImageWrapper = style({
- width: '30px',
- height: '30px',
+ width: '40px',
+ height: '40px',
position: 'relative',
});
@@ -129,27 +129,6 @@ export const simpleListWrapper = style({
flexDirection: 'column',
gap: '10px',
- borderRadius: '15px',
- border: `1px solid ${vars.color.gray5}`,
+ borderTop: `1px solid ${vars.color.gray5}`,
backgroundColor: vars.color.white,
});
-
-export const showMoreButtonWrapper = style({
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'center',
- gap: '3px',
-
- cursor: 'pointer',
-});
-
-export const showMoreButton = style([
- labelSmall,
- {
- color: vars.color.gray9,
- },
-]);
-
-export const noData = style({
- margin: '20px 0 70px',
-});
diff --git a/src/components/exploreComponents/UsersRecommendation.css.ts b/src/components/exploreComponents/RecommendedUsers.css.ts
similarity index 56%
rename from src/components/exploreComponents/UsersRecommendation.css.ts
rename to src/components/exploreComponents/RecommendedUsers.css.ts
index f49c3db5..f997f770 100644
--- a/src/components/exploreComponents/UsersRecommendation.css.ts
+++ b/src/components/exploreComponents/RecommendedUsers.css.ts
@@ -6,15 +6,15 @@ export const wrapper = style({
padding: '0 16px',
});
-export const sectionTitle = style([
- headlineSmall,
- {
- fontWeight: 600,
- },
-]);
+export const sectionTitle = style({
+ color: '#323A43',
+ fontSize: '1.8rem',
+ fontWeight: 700,
+ letterSpacing: '-0.54px',
+});
export const titleWrapper = style({
- marginBottom: '26px',
+ marginBottom: '12px',
display: 'flex',
alignItems: 'baseline',
@@ -22,11 +22,11 @@ export const titleWrapper = style({
});
export const recommendUsersListWrapper = style({
- marginBottom: '30px',
+ marginBottom: '12px',
display: 'flex',
alignItems: 'center',
- gap: '6px',
+ gap: '20px',
overflowX: 'scroll',
'::-webkit-scrollbar': {
@@ -36,7 +36,7 @@ export const recommendUsersListWrapper = style({
export const recommendUserWrapper = style({
padding: '12px 9px',
- width: '160px',
+ width: '122px',
height: 'auto',
position: 'relative',
@@ -46,9 +46,6 @@ export const recommendUserWrapper = style({
alignItems: 'center',
flexGrow: 0,
flexShrink: 0,
-
- borderRadius: '5px',
- border: `1px solid ${vars.color.gray5}`,
});
export const closeButton = style({
@@ -58,9 +55,9 @@ export const closeButton = style({
});
export const imageWrapper = style({
- marginBottom: '13px',
- width: '110px',
- height: '110px',
+ marginBottom: '10px',
+ width: '122px',
+ height: '122px',
position: 'relative',
});
@@ -72,33 +69,32 @@ export const recommendUserProfileImage = style({
backgroundColor: vars.color.lightblue,
});
-export const recommendUserNickname = style([
- titleSmall,
- {
- marginBottom: '10px',
-
- color: vars.color.black,
- },
-]);
+export const recommendUserNickname = style({
+ color: '#121417',
+ marginBottom: '6px',
+ textAlign: 'center',
+ fontSize: '14px',
+ fontWeight: 400,
+ letterSpacing: '-0.28px',
+});
-export const followButtonDefault = style([
- titleSmall,
- {
- width: '100%',
- padding: '4px 0',
+export const followButtonDefault = style({
+ width: 'auto',
+ height: 'auto',
+ padding: '4px 6px',
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'center',
+ display: 'flex',
+ alignItems: 'center',
+ justifyContent: 'center',
- backgroundColor: vars.color.blue,
- borderRadius: '9px',
- color: vars.color.white,
- },
-]);
+ backgroundColor: '#3D95FF',
+ borderRadius: '20px',
+ color: vars.color.white,
+ fontSize: '1.2rem',
+ fontWeight: '400',
+});
export const followButtonFollowing = style({
- background: vars.color.white,
- border: `1px solid ${vars.color.black}`,
- color: vars.color.black,
+ backgroundColor: vars.color.white,
+ color: '#8599AD',
});
diff --git a/src/components/exploreComponents/UsersRecommendation.tsx b/src/components/exploreComponents/RecommendedUsers.tsx
similarity index 92%
rename from src/components/exploreComponents/UsersRecommendation.tsx
rename to src/components/exploreComponents/RecommendedUsers.tsx
index 1ee9f220..547a324b 100644
--- a/src/components/exploreComponents/UsersRecommendation.tsx
+++ b/src/components/exploreComponents/RecommendedUsers.tsx
@@ -5,14 +5,13 @@ import Link from 'next/link';
import { useQuery } from '@tanstack/react-query';
import { QUERY_KEYS } from '@/lib/constants/queryKeys';
-import getRecommendedUsers from '@/app/_api/explore/getRecommendedUsers';
+import getRecommendedUsers from '@/app/_api/home/getRecommendedUsers';
import { useUser } from '@/store/useUser';
import FollowButton from './FollowButton';
import { UserProfileType } from '@/lib/types/userProfileType';
import fallbackProfile from '/public/images/fallback_profileImage.webp';
-import * as styles from './UsersRecommendation.css';
-import waveEmoji from '/public/images/wave.png';
+import * as styles from './RecommendedUsers.css';
import { UserListsSkeleton } from './Skeleton';
import { commonLocale } from '@/components/locale';
import { useLanguage } from '@/store/useLanguage';
@@ -53,8 +52,7 @@ function UsersRecommendation() {
{myId && usersList?.length !== 0 && (
-
HI, LISTER
-
+ 추천 리스터
{usersList?.map((item: UserProfileType) => {
diff --git a/src/components/exploreComponents/TrendingLists.tsx b/src/components/exploreComponents/TrendingLists.tsx
deleted file mode 100644
index f947bb93..00000000
--- a/src/components/exploreComponents/TrendingLists.tsx
+++ /dev/null
@@ -1,207 +0,0 @@
-'use client';
-import Image from 'next/image';
-import Link from 'next/link';
-import { useQuery } from '@tanstack/react-query';
-import { assignInlineVars } from '@vanilla-extract/dynamic';
-import { Swiper, SwiperSlide } from 'swiper/react';
-import 'swiper/css';
-import { Autoplay, EffectCoverflow } from 'swiper/modules';
-
-import getTrendingLists from '@/app/_api/explore/getTrendingLists';
-import { QUERY_KEYS } from '@/lib/constants/queryKeys';
-import { TrendingListType } from '@/lib/types/exploreType';
-
-import * as styles from './TrendingLists.css';
-import { vars } from '@/styles/__theme.css';
-import { TrendingListsSkeleton } from './Skeleton';
-import oceanEmoji from '/public/images/ocean.png';
-import fallbackProfile from '/public/images/fallback_profileImage.webp';
-import { commonLocale } from '@/components/locale';
-import { useLanguage } from '@/store/useLanguage';
-import { BACKGROUND_COLOR_READ } from '@/styles/Color';
-
-/**@todo 트렌딩 리스트 바뀐 디자인에 맞게 새로 갈아엎을 예정 */
-
-const swiperSliderStyle = [
- {
- width: '258px',
- borderRadius: '40px',
- },
- {
- width: '190px',
- borderRadius: '180px',
- },
- {
- width: '258px',
- borderRadius: '40px',
- },
- {
- width: '172px',
- borderRadius: '20px',
- },
-];
-const STYLE_INDEX = (num: number) => num % 4;
-
-function TrendingList() {
- const { language } = useLanguage();
- const { data: trendingLists, isFetching } = useQuery({
- queryKey: [QUERY_KEYS.getTrendingLists],
- queryFn: () => getTrendingLists(),
- });
-
- const swiperStyle = {
- width: '100vw',
- height: '100%',
- padding: '10px 0',
- };
-
- if (isFetching) {
- return ;
- }
-
- return (
-
-
-
TRENDING
-
-
-
-
- {trendingLists && trendingLists.length > 0 && (
-
- {trendingLists.map((item, index) => (
-
-
-
- ))}
-
- {/* 슬라이드 개수가 10개 미만일 경우 추가 슬라이드를 생성 */}
- {trendingLists.length < 10 &&
- Array.from({ length: 10 - trendingLists.length }).map((_, index) => (
-
-
-
- ))}
-
- )}
-
-
-
- );
-}
-
-interface TrendingListItemProps {
- item?: TrendingListType;
- index: number;
-}
-
-function TrendingListItem({ item, index }: TrendingListItemProps) {
- return (
-
-
- {item?.itemImageUrl ? (
-
-
-
- ) : (
-
-
-
- )}
-
-
- );
-}
-
-export default TrendingList;
-
-interface TrendingListInformationType {
- item?: TrendingListType;
-}
-
-function TrendingListInformation({ item }: TrendingListInformationType) {
- const { language } = useLanguage();
- return (
-
-
-
-
-
- {item?.ownerProfileImageUrl ? (
-
- ) : (
-
- )}
-
-
- {item?.ownerNickname}
-
-
-
- );
-}
diff --git a/src/components/floatingButton/ArrowUpFloatingButton.tsx b/src/components/floatingButton/ArrowUpFloatingButton.tsx
index 03d84214..c4ce238f 100644
--- a/src/components/floatingButton/ArrowUpFloatingButton.tsx
+++ b/src/components/floatingButton/ArrowUpFloatingButton.tsx
@@ -37,7 +37,7 @@ export default function ArrowUpFloatingButton() {
<>
{isVisible && (
)}
>
diff --git a/src/components/floatingButton/FloatingContainer.css.ts b/src/components/floatingButton/FloatingContainer.css.ts
index f9ac96a0..76e82f2b 100644
--- a/src/components/floatingButton/FloatingContainer.css.ts
+++ b/src/components/floatingButton/FloatingContainer.css.ts
@@ -26,9 +26,9 @@ export const basicButton = style({
height: '56px',
padding: '1rem',
- background: vars.color.blue,
+ background: vars.color.white,
borderRadius: '50%',
- boxShadow: '0px 4px 4px rgba(0, 0, 0, 0.25)',
+ boxShadow: '0px 0px 4px 0px rgba(142, 142, 142, 0.04), 0px 8px 16px 0px rgba(116, 116, 116, 0.08)',
cursor: 'pointer',
transition: 'all 0.1s linear',
@@ -54,7 +54,7 @@ export const variant = styleVariants({
basicButton,
{
animation: `${fadeIn} 500ms ease`,
- filter: `opacity(0.5)`,
+ // filter: `opacity(0.5)`,
},
],
});
@@ -69,7 +69,7 @@ const dropdown = keyframes({
});
export const icon = style({
- transform: 'translate(25%, 25%);',
+ transform: 'translate(45%, 45%);',
});
export const menuButtons = style({
diff --git a/src/components/floatingButton/PlusOptionFloatingButton.tsx b/src/components/floatingButton/PlusOptionFloatingButton.tsx
index 57990ddb..3acb62b8 100644
--- a/src/components/floatingButton/PlusOptionFloatingButton.tsx
+++ b/src/components/floatingButton/PlusOptionFloatingButton.tsx
@@ -1,28 +1,19 @@
'use client';
-import { usePathname, useRouter } from 'next/navigation';
+import { usePathname } from 'next/navigation';
import * as styles from './FloatingContainer.css';
-import PlusIcon from '/public/icons/plus.svg';
-import ShareAltIcon from '/public/icons/share_alt.svg';
-import WriteIcon from '/public/icons/write.svg';
+import ShareAltIcon from '/public/icons/ver3/share.svg';
-import useBooleanOutput from '@/hooks/useBooleanOutput';
-import { useUser } from '@/store/useUser';
import { useLanguage } from '@/store/useLanguage';
import copyUrl from '@/lib/utils/copyUrl';
-import LoginModal from '@/components/login/LoginModal';
-import Modal from '@/components/Modal/Modal';
import { commonLocale } from '@/components/locale';
function FloatingMenu() {
- const router = useRouter();
const path = usePathname();
- const { user } = useUser();
- const { isOn, handleSetOn, handleSetOff } = useBooleanOutput();
const { language } = useLanguage();
const handleSharePage = () => {
@@ -30,44 +21,22 @@ function FloatingMenu() {
copyUrl(`https://listywave.com${path}`, language);
};
- const handleMoveToPage = () => {
- // TODO 토큰 유효성 검증 관련 인가 처리 로직 추가
- // 지금은 토큰이 있는 지 확인 후 이동만 간단하게 처리시켜 둠(추후 수정 예정)
- if (!user.id) {
- handleSetOn();
- return;
- }
- router.push('/list/create');
- };
-
return (
<>
- {isOn && (
-
-
-
- )}
>
);
}
export default function PlusOptionFloatingButton() {
- const { language } = useLanguage();
- const { isOn, toggle } = useBooleanOutput();
-
return (
<>
- {isOn && }
- toggle()}>
-
+
+
>
);
diff --git a/src/components/floatingButton/__PlusOptionFloationButton.tsx b/src/components/floatingButton/__PlusOptionFloationButton.tsx
new file mode 100644
index 00000000..57990ddb
--- /dev/null
+++ b/src/components/floatingButton/__PlusOptionFloationButton.tsx
@@ -0,0 +1,74 @@
+'use client';
+
+import { usePathname, useRouter } from 'next/navigation';
+
+import * as styles from './FloatingContainer.css';
+
+import PlusIcon from '/public/icons/plus.svg';
+import ShareAltIcon from '/public/icons/share_alt.svg';
+import WriteIcon from '/public/icons/write.svg';
+
+import useBooleanOutput from '@/hooks/useBooleanOutput';
+import { useUser } from '@/store/useUser';
+import { useLanguage } from '@/store/useLanguage';
+import copyUrl from '@/lib/utils/copyUrl';
+
+import LoginModal from '@/components/login/LoginModal';
+import Modal from '@/components/Modal/Modal';
+import { commonLocale } from '@/components/locale';
+
+function FloatingMenu() {
+ const router = useRouter();
+ const path = usePathname();
+
+ const { user } = useUser();
+ const { isOn, handleSetOn, handleSetOff } = useBooleanOutput();
+ const { language } = useLanguage();
+
+ const handleSharePage = () => {
+ // TODO 카카오 공유하기 기능으로 변경하기
+ copyUrl(`https://listywave.com${path}`, language);
+ };
+
+ const handleMoveToPage = () => {
+ // TODO 토큰 유효성 검증 관련 인가 처리 로직 추가
+ // 지금은 토큰이 있는 지 확인 후 이동만 간단하게 처리시켜 둠(추후 수정 예정)
+ if (!user.id) {
+ handleSetOn();
+ return;
+ }
+ router.push('/list/create');
+ };
+
+ return (
+ <>
+
+ {isOn && (
+
+
+
+ )}
+ >
+ );
+}
+
+export default function PlusOptionFloatingButton() {
+ const { language } = useLanguage();
+ const { isOn, toggle } = useBooleanOutput();
+
+ return (
+ <>
+ {isOn &&
}
+
+ >
+ );
+}
diff --git a/src/lib/constants/queryKeys.ts b/src/lib/constants/queryKeys.ts
index 28403e16..63046abc 100644
--- a/src/lib/constants/queryKeys.ts
+++ b/src/lib/constants/queryKeys.ts
@@ -7,6 +7,8 @@ export const QUERY_KEYS = {
getCategories: 'getCategories',
getComments: 'getComments',
getRecommendedLists: 'getRecommendedLists',
+ getRecentLists: 'getRecentLists',
+ getFollowingLists: 'getFollowingLists',
getRecommendedUsers: 'getRecommendedUsers',
getTrendingLists: 'getTrendingLists',
getNotificationAllChecked: 'getNotificationOnAllChecked',
diff --git a/src/lib/types/exploreType.ts b/src/lib/types/exploreType.ts
index b6fc88db..6c69cfcf 100644
--- a/src/lib/types/exploreType.ts
+++ b/src/lib/types/exploreType.ts
@@ -1,12 +1,20 @@
+interface Top3Type {
+ id: number;
+ rank: number;
+ title: string;
+}
+
export interface TrendingListType {
id: number;
ownerId: number;
ownerNickname: string;
ownerProfileImageUrl: string;
title: string;
+ category: string;
description: string;
backgroundColor: string;
itemImageUrl: string;
+ top3: Top3Type[];
}
export interface UsersRecommendationItemType {
@@ -39,4 +47,5 @@ export interface ListRecommendationType {
title: string;
description: string;
items: ListItemType[];
+ version: number;
}
diff --git a/src/lib/types/noticeType.ts b/src/lib/types/noticeType.ts
new file mode 100644
index 00000000..283d620d
--- /dev/null
+++ b/src/lib/types/noticeType.ts
@@ -0,0 +1,35 @@
+export interface NoticeListItemType {
+ id: number;
+ createdDate: string;
+ title: string;
+ itemImageUrl: string | null;
+ category: string;
+ description: string;
+}
+
+export interface NoticeDetailType {
+ id: number;
+ category: string;
+ title: string;
+ description: string;
+ content: NoticeContentType[];
+ createdDate: string;
+ prevNotice: {
+ id: number;
+ title: string;
+ description: string;
+ };
+ nextNotice: {
+ id: number;
+ title: string;
+ description: string;
+ };
+}
+
+export interface NoticeContentType {
+ type: string;
+ description: string;
+ imageUrl: string;
+ buttonName: string;
+ buttonLink: string;
+}
diff --git a/src/store/useTab.ts b/src/store/useTab.ts
new file mode 100644
index 00000000..49feded5
--- /dev/null
+++ b/src/store/useTab.ts
@@ -0,0 +1,13 @@
+import { create } from 'zustand';
+
+export type TabType = 'recommendation' | 'recent' | 'following';
+
+interface tabStoreType {
+ currentTab: TabType;
+ setCurrentTab: (tabType: TabType) => void;
+}
+
+export const useTab = create
((set) => ({
+ currentTab: 'recommendation',
+ setCurrentTab: (tabType: TabType) => set({ currentTab: tabType }),
+}));
diff --git a/src/styles/GlobalStyles.css.ts b/src/styles/GlobalStyles.css.ts
index d2cc5160..95fbaa1b 100644
--- a/src/styles/GlobalStyles.css.ts
+++ b/src/styles/GlobalStyles.css.ts
@@ -8,6 +8,10 @@ globalStyle('html', {
backgroundColor: vars.color.gray3,
});
+globalStyle('body', {
+ backgroundColor: '#F5F6FA !important',
+});
+
globalStyle('body *', {
boxSizing: 'border-box',
fontFamily: Pretendard,