diff --git a/package.json b/package.json
index b90a5765..605f0417 100644
--- a/package.json
+++ b/package.json
@@ -23,8 +23,10 @@
}
},
"dependencies": {
+ "@egjs/react-grid": "^1.16.0",
"@tanstack/react-query": "^5.17.12",
"@tanstack/react-query-devtools": "^5.17.12",
+ "@vanilla-extract/dynamic": "^2.1.0",
"@vanilla-extract/integration": "^6.2.4",
"@vanilla-extract/next-plugin": "^2.3.2",
"@yaireo/tagify": "^4.19.0",
diff --git a/public/icons/arrow_left.svg b/public/icons/arrow_left.svg
new file mode 100644
index 00000000..8f212969
--- /dev/null
+++ b/public/icons/arrow_left.svg
@@ -0,0 +1,3 @@
+
diff --git a/public/icons/arrow_up.svg b/public/icons/arrow_up.svg
new file mode 100644
index 00000000..a2f043aa
--- /dev/null
+++ b/public/icons/arrow_up.svg
@@ -0,0 +1,3 @@
+
diff --git a/public/icons/lock_alt.svg b/public/icons/lock_alt.svg
new file mode 100644
index 00000000..231ca711
--- /dev/null
+++ b/public/icons/lock_alt.svg
@@ -0,0 +1,3 @@
+
diff --git a/public/icons/plus.svg b/public/icons/plus.svg
new file mode 100644
index 00000000..fa859916
--- /dev/null
+++ b/public/icons/plus.svg
@@ -0,0 +1,3 @@
+
diff --git a/public/icons/setting.svg b/public/icons/setting.svg
new file mode 100644
index 00000000..b517b015
--- /dev/null
+++ b/public/icons/setting.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/app/[userNickname]/_components/Action.css.ts b/src/app/[userNickname]/_components/Action.css.ts
new file mode 100644
index 00000000..fad5fe4f
--- /dev/null
+++ b/src/app/[userNickname]/_components/Action.css.ts
@@ -0,0 +1,12 @@
+import { style } from '@vanilla-extract/css';
+
+export const button = style({
+ padding: '0.8rem 1.2rem',
+
+ backgroundColor: 'var(--Blue, #0047FF)',
+ borderRadius: '5rem',
+
+ fontSize: '1rem',
+ fontWeight: '600',
+ color: '#fff',
+});
diff --git a/src/app/[userNickname]/_components/Action.tsx b/src/app/[userNickname]/_components/Action.tsx
new file mode 100644
index 00000000..5680f586
--- /dev/null
+++ b/src/app/[userNickname]/_components/Action.tsx
@@ -0,0 +1,27 @@
+'use client';
+
+/**
+ TODO
+ - [ ] 상태(팔로우, 언팔로우)에 따른 팔로우 버튼 UI
+ - [ ] 조건(비회원, 회원)에 따른 팔로우 버튼 동작(api 연동)
+ */
+
+import * as styles from './Action.css';
+
+interface ActionProps {
+ isFollowed: boolean;
+}
+
+export default function Action({ isFollowed }: ActionProps) {
+ const label = isFollowed ? '팔로우' : '팔로우 취소';
+
+ const handleFollowUser = () => {
+ // 1. follow 하는 api 요청 + update
+ };
+
+ return (
+
+ );
+}
diff --git a/src/app/[userNickname]/_components/Card.css.ts b/src/app/[userNickname]/_components/Card.css.ts
new file mode 100644
index 00000000..0c685b9f
--- /dev/null
+++ b/src/app/[userNickname]/_components/Card.css.ts
@@ -0,0 +1,51 @@
+import { style, createVar } from '@vanilla-extract/css';
+
+export const listColor = createVar();
+
+export const container = style({
+ width: '185px',
+ padding: '3rem 1.2rem',
+
+ borderRadius: '1.5rem',
+ backgroundColor: listColor,
+});
+
+export const title = style({
+ padding: '1.1rem',
+
+ fontSize: '1.7rem',
+ fontWeight: '600',
+ color: 'var(--text-text-grey-dark, #202020)',
+ textAlign: 'right',
+ letterSpacing: '-0.51px',
+ wordBreak: 'keep-all',
+});
+
+export const list = style({
+ padding: '1rem 0',
+
+ display: 'flex',
+ flexDirection: 'column',
+
+ fontSize: '1.2rem',
+ fontWeight: '400',
+ color: 'var(--text-text-grey-dark, #202020)',
+ lineHeight: '2.5rem',
+ letterSpacing: '-0.36px',
+});
+
+export const lockIcon = style({
+ padding: '0 1rem',
+
+ display: 'flex',
+ justifyContent: 'flex-end',
+ alignItems: 'center',
+ gap: '2px',
+});
+
+export const lockText = style({
+ fontSize: '1.1rem',
+ fontWeight: '400',
+ letterSpacing: '-0.33px',
+ color: '#AFB1B6',
+});
diff --git a/src/app/[userNickname]/_components/Card.tsx b/src/app/[userNickname]/_components/Card.tsx
new file mode 100644
index 00000000..8869df5d
--- /dev/null
+++ b/src/app/[userNickname]/_components/Card.tsx
@@ -0,0 +1,43 @@
+/**
+ TODO
+ - [ ] 다른 사람 피드볼때, 비공개 리스트는 보여지지 않음
+ - [ ] svg 아이콘 컴포넌트화
+ */
+
+import { ListType } from '../mockData/mockDataTypes'; // 삭제 예정
+import { assignInlineVars } from '@vanilla-extract/dynamic';
+import * as styles from './Card.css';
+
+import CardItem from './CardItem';
+import LockIcon from '/public/icons/lock_alt.svg';
+
+interface CardProps {
+ list: ListType;
+ isOwner: boolean;
+}
+
+export default function Card({ list, isOwner }: CardProps) {
+ const isVisibleLockIcon = isOwner && !list.isPublic;
+
+ return (
+
+ {isVisibleLockIcon && (
+
+ 비공개
+
+
+ )}
+ {list.title}
+
+ {list.items.map((item) => (
+
+ ))}
+
+
+ );
+}
diff --git a/src/app/[userNickname]/_components/CardItem.css.ts b/src/app/[userNickname]/_components/CardItem.css.ts
new file mode 100644
index 00000000..a2d4862e
--- /dev/null
+++ b/src/app/[userNickname]/_components/CardItem.css.ts
@@ -0,0 +1,6 @@
+import { style } from '@vanilla-extract/css';
+
+export const container = style({
+ display: 'flex',
+ gap: '5px',
+});
diff --git a/src/app/[userNickname]/_components/CardItem.tsx b/src/app/[userNickname]/_components/CardItem.tsx
new file mode 100644
index 00000000..a544f108
--- /dev/null
+++ b/src/app/[userNickname]/_components/CardItem.tsx
@@ -0,0 +1,16 @@
+import { ItemType } from '../mockData/mockDataTypes'; // 삭제 예정
+
+import * as styles from './CardItem.css';
+
+interface CardItemProps {
+ item: ItemType;
+}
+
+export default function CardItem({ item }: CardItemProps) {
+ return (
+
+ {item.rank}.
+ {item.title}
+
+ );
+}
diff --git a/src/app/[userNickname]/_components/Categories.css.ts b/src/app/[userNickname]/_components/Categories.css.ts
new file mode 100644
index 00000000..8d07fdd1
--- /dev/null
+++ b/src/app/[userNickname]/_components/Categories.css.ts
@@ -0,0 +1,35 @@
+import { style } from '@vanilla-extract/css';
+
+export const container = style({
+ padding: '2.1rem 0 1.5rem 1.5rem',
+
+ display: 'flex',
+ alignItems: 'flex-start',
+ gap: '1.2rem',
+
+ overflow: 'scroll',
+ msOverflowStyle: 'none',
+ '::-webkit-scrollbar': {
+ display: 'none',
+ },
+});
+
+export const button = style({
+ padding: '0.8rem 1.2rem',
+
+ backgroundColor: '#FFF',
+ borderRadius: '5rem',
+ border: '1px solid #DEDEDE',
+
+ fontSize: '1.6rem',
+ fontWeight: '500',
+ color: '#828282',
+ letterSpacing: '-0.48px',
+ whiteSpace: 'nowrap',
+});
+
+export const variant = style({
+ backgroundColor: '#0047FF',
+ color: '#FFF',
+ border: 'none',
+});
diff --git a/src/app/[userNickname]/_components/Categories.tsx b/src/app/[userNickname]/_components/Categories.tsx
new file mode 100644
index 00000000..ba97cb20
--- /dev/null
+++ b/src/app/[userNickname]/_components/Categories.tsx
@@ -0,0 +1,52 @@
+'use client';
+
+/**
+ TODO
+ - [ ] api 연동
+ - [ ] 클릭했을때 로직 (상위요소에 핸들러 고민) (리팩토링)
+ */
+import { KINDS } from '../mockData/categories'; // 삭제 예정
+
+import { useState } from 'react';
+// import { useQuery } from '@tanstack/react-query'; // 주석 import 나중에 사용 예정
+
+import * as styles from './Categories.css';
+
+// import { getCategories } from '@/app/_api/getCategories';
+// import { CategoriesType } from '@/lib/types/categoriesType';
+// import { queryKeys } from '@/lib/constants/queryKeys';
+
+interface CategoriesProps {
+ onClick: (kind: string) => void;
+}
+
+const DEFAULT_CATEGORY = '전체'; // 나중에 constants 파일로 분리
+
+export default function Categories({ onClick }: CategoriesProps) {
+ const [selected, setSelected] = useState(DEFAULT_CATEGORY);
+
+ // 1. 카테고리 api 요청
+ // const { data } = useQuery({
+ // queryKey: [queryKeys.getCategories],
+ // queryFn: getCategories,
+ // });
+
+ const handleChangeCategory = (kind: string) => () => {
+ onClick(kind);
+ setSelected(kind);
+ };
+
+ return (
+
+ {KINDS.map((kind) => (
+
+ ))}
+
+ );
+}
diff --git a/src/app/[userNickname]/_components/Content.css.ts b/src/app/[userNickname]/_components/Content.css.ts
new file mode 100644
index 00000000..debc53eb
--- /dev/null
+++ b/src/app/[userNickname]/_components/Content.css.ts
@@ -0,0 +1,59 @@
+import { style } from '@vanilla-extract/css';
+
+export const container = style({
+ width: '100%',
+ marginTop: '40rem',
+
+ position: 'absolute',
+ top: 0,
+
+ backgroundColor: '#FFF',
+ borderTopLeftRadius: '2.5rem',
+ borderTopRightRadius: '2.5rem',
+});
+
+export const options = style({
+ height: '6.4rem',
+ display: 'flex',
+ borderBottom: '1px solid rgba(0, 0, 0, 0.10)',
+});
+
+export const link = style({
+ flexGrow: '1',
+});
+
+export const button = style({
+ width: '100%',
+ height: '100%',
+
+ backgroundColor: 'white',
+ borderTop: '1px solid rgba(0, 0, 0, 0.25)',
+ borderBottom: '1px solid rgba(0, 0, 0, 0.10)',
+
+ fontSize: '1.6rem',
+ fontWeight: '500',
+});
+
+export const leftButton = style([
+ button,
+ {
+ paddingLeft: '5.75rem',
+ borderTopLeftRadius: '2.5rem',
+ },
+]);
+
+export const rightButton = style([
+ button,
+ {
+ paddingRight: '5.75rem',
+ borderTopRightRadius: '2.5rem',
+ },
+]);
+
+export const variant = style({
+ borderBottom: '1px solid #0047FF',
+});
+
+export const cards = style({
+ padding: '2.1rem',
+});
diff --git a/src/app/[userNickname]/_components/Content.tsx b/src/app/[userNickname]/_components/Content.tsx
new file mode 100644
index 00000000..342df24b
--- /dev/null
+++ b/src/app/[userNickname]/_components/Content.tsx
@@ -0,0 +1,54 @@
+'use client';
+
+/**
+ TODO
+ - [ ] api 연동
+ - [ ] 무한스크롤 적용
+ - [ ] 피드페이지 스켈레톤 ui 적용
+ */
+
+import Link from 'next/link';
+import { MasonryGrid } from '@egjs/react-grid';
+
+import * as styles from './Content.css';
+
+import { ListType, UserType } from '../mockData/mockDataTypes'; // 삭제 예정
+import { LISTS_ME } from '../mockData/lists'; // 삭제 예정
+
+import Card from './Card';
+import Categories from './Categories';
+
+interface ContentProps {
+ user: UserType;
+ type: string;
+}
+
+export default function Content({ user, type }: ContentProps) {
+ // 1. props로 받아온 userId, type으로 피드 정보 가져오는 api 요청
+
+ const handleFetchListsOnCategory = (kind: string) => {
+ // console.log(type, kind); // 삭제 예정
+ // 2. userId, type, category로 피드 정보 가져오는 api 요청
+ };
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+ {LISTS_ME.map((list: ListType) => (
+
+ ))}
+
+
+
+ );
+}
diff --git a/src/app/[userNickname]/_components/Profile.css.ts b/src/app/[userNickname]/_components/Profile.css.ts
new file mode 100644
index 00000000..f08e6cc0
--- /dev/null
+++ b/src/app/[userNickname]/_components/Profile.css.ts
@@ -0,0 +1,104 @@
+import { style, createVar } from '@vanilla-extract/css';
+
+export const imageUrl = createVar();
+
+export const container = style({
+ padding: '1.9rem 1.9rem 6.4rem 1.5rem',
+ height: '464px',
+
+ position: 'fixed',
+ top: 0,
+
+ display: 'flex',
+ flexDirection: 'column',
+ justifyContent: 'space-between',
+ gap: '2.1rem',
+
+ backgroundImage: imageUrl,
+ backgroundSize: 'cover',
+ backgroundPosition: 'center',
+ backgroundRepeat: 'no-repeat',
+});
+
+export const header = style({
+ paddingTop: '2.5rem',
+ display: 'flex',
+ justifyContent: 'space-between',
+});
+
+export const profileContainer = style({
+ padding: '0 2.9rem 0 3.3rem',
+
+ display: 'flex',
+ flexDirection: 'column',
+ gap: '1.2rem',
+});
+
+export const icon = style({
+ cursor: 'pointer',
+});
+
+export const profile = style({
+ display: 'flex',
+ alignItems: 'center',
+ gap: '1.6rem',
+});
+
+export const avatar = style({
+ borderRadius: '50%',
+ border: '2px solid #FFF',
+});
+
+export const info = style({
+ display: 'flex',
+ flexDirection: 'column',
+ gap: '0.8rem',
+});
+
+export const user = style({
+ display: 'flex',
+ alignItems: 'center',
+ gap: '1.2rem',
+});
+
+export const nickName = style({
+ fontSize: '2rem',
+ fontWeight: ' 700',
+ color: '#202020',
+ letterSpacing: '-0.6px',
+});
+
+export const follow = style({
+ display: 'flex',
+ gap: '1.6rem',
+ lineHeight: '2.5rem',
+});
+
+export const text = style({
+ display: 'flex',
+ alignItems: 'center',
+ gap: '0.5rem',
+
+ fontSize: '1rem',
+ fontWeight: '500',
+ letterSpacing: '-0.3px',
+});
+
+export const count = style({
+ fontSize: '1.3rem',
+ fontWeight: '600',
+ letterSpacing: '-0.39px',
+});
+
+export const description = style({
+ paddingBottom: '1.9rem',
+
+ width: '100%',
+ maxHeight: '80px',
+
+ fontSize: '1.2rem',
+ fontWeight: '500',
+ color: '#333',
+ lineHeight: '1.6rem',
+ letterSpacing: '-0.36px',
+});
diff --git a/src/app/[userNickname]/_components/Profile.tsx b/src/app/[userNickname]/_components/Profile.tsx
new file mode 100644
index 00000000..5f9513ac
--- /dev/null
+++ b/src/app/[userNickname]/_components/Profile.tsx
@@ -0,0 +1,64 @@
+/**
+ TODO
+ - [ ] 디자인 최종본으로 수정
+ - [ ] 프로필 이미지, 배경 이미지 적용
+ - [ ] api 연동
+ */
+import { UserType } from '../mockData/mockDataTypes'; // 삭제 예정
+
+import Image from 'next/image';
+import { assignInlineVars } from '@vanilla-extract/dynamic';
+import * as styles from './Profile.css';
+
+import Action from './Action';
+import ArrowLeftIcon from '/public/icons/arrow_left.svg';
+import SettingIcon from '/public/icons/setting.svg';
+
+interface ProfileProps {
+ user: UserType;
+}
+
+export default function Profile({ user }: ProfileProps) {
+ return (
+
+
+
+
+
+
+
+
+
+ {user.followingCount}
+ 팔로잉
+
+
+ {user.followerCount}
+ 팔로워
+
+
+
+
+
{user.description}
+
+
+ );
+}
diff --git a/src/app/[userNickname]/collabolist/page.tsx b/src/app/[userNickname]/collabolist/page.tsx
new file mode 100644
index 00000000..02058891
--- /dev/null
+++ b/src/app/[userNickname]/collabolist/page.tsx
@@ -0,0 +1,39 @@
+/**
+ TODO
+ - [ ] user api 연동
+ - [ ] 페이지 하위 컴포넌트 global css 변수로 변경
+ - [ ] 반응형 UI 구현
+ */
+
+import '@/styles/globalStyles.css';
+
+import { USER_DATA_ME } from '../mockData/user'; // 삭제 예정
+
+import Profile from '../_components/Profile';
+import Content from '../_components/Content';
+import FloatingContainer from '@/components/floatingButton/FloatingContainer';
+import PlusOptionFloatingButton from '@/components/floatingButton/PlusOptionFloatingButton';
+import ArrowUpFloatingButton from '@/components/floatingButton/ArrowUpFloatingButton';
+
+// 타입 사용할 때 재정의
+// interface CollaboListPageProps {
+// params: {
+// userNickname: number;
+// };
+// userId: number;
+// }
+
+export default function CollaboListPage() {
+ // 1. userId로 유저 정보 가져오는 api 요청
+
+ return (
+
+ );
+}
diff --git a/src/app/[userNickname]/mockData/categories.ts b/src/app/[userNickname]/mockData/categories.ts
new file mode 100644
index 00000000..60b48add
--- /dev/null
+++ b/src/app/[userNickname]/mockData/categories.ts
@@ -0,0 +1,49 @@
+// 카테고리 데이터
+
+export const KINDS = [
+ {
+ codeValue: '1',
+ nameValue: 'ENTIRE',
+ korNameValue: '전체',
+ },
+ {
+ codeValue: '2',
+ nameValue: 'CULTURE',
+ korNameValue: '문화',
+ },
+ {
+ codeValue: '3',
+ nameValue: 'LIFE',
+ korNameValue: '일상생활',
+ },
+ {
+ codeValue: '4',
+ nameValue: 'PLACE',
+ korNameValue: '장소',
+ },
+ {
+ codeValue: '5',
+ nameValue: 'MUSIC',
+ korNameValue: '음악',
+ },
+ {
+ codeValue: '6',
+ nameValue: 'MOVIE_DRAMA',
+ korNameValue: '영화/드라마',
+ },
+ {
+ codeValue: '7',
+ nameValue: 'BOOK',
+ korNameValue: '도서',
+ },
+ {
+ codeValue: '8',
+ nameValue: 'ANIMAL_PLANT',
+ korNameValue: '동식물',
+ },
+ {
+ codeValue: '9',
+ nameValue: 'ETC',
+ korNameValue: '기타',
+ },
+];
diff --git a/src/app/[userNickname]/mockData/items.ts b/src/app/[userNickname]/mockData/items.ts
new file mode 100644
index 00000000..e6e44a45
--- /dev/null
+++ b/src/app/[userNickname]/mockData/items.ts
@@ -0,0 +1,283 @@
+export const ITEMS_01 = {
+ id: 1,
+ listId: 1000,
+ data: [
+ {
+ id: 1,
+ rank: 1,
+ title: '프랭크버거',
+ comment: '', // Nullable
+ link: '', // Nullable
+ imageUrl: '', // Nullable
+ // items 다른 속성 추가 될 수도 있음
+ },
+ {
+ id: 2,
+ rank: 2,
+ title: '캔모아',
+ comment: '',
+ link: '',
+ imageUrl: '',
+ },
+ {
+ id: 3,
+ rank: 3,
+ title: '젤라띠젤라띠',
+ comment: '',
+ link: '',
+ imageUrl: '',
+ },
+ ],
+};
+
+export const ITEMS_02 = {
+ id: 2,
+ listId: 1001,
+ data: [
+ {
+ id: 1,
+ rank: 1,
+ title: '스타벅스',
+ comment: '',
+ link: '',
+ imageUrl: '',
+ },
+ {
+ id: 2,
+ rank: 2,
+ title: '투썸플레이스',
+ comment: '',
+ link: '',
+ imageUrl: '',
+ },
+ {
+ id: 3,
+ rank: 3,
+ title: '원두볶는 사람들',
+ comment: '',
+ link: '',
+ imageUrl: '',
+ },
+ {
+ id: 4,
+ rank: 4,
+ title: '할리스커피',
+ comment: '',
+ link: '',
+ imageUrl: '',
+ },
+ {
+ id: 5,
+ rank: 5,
+ title: '탐앤탐스',
+ comment: '',
+ link: '',
+ imageUrl: '',
+ },
+ {
+ id: 6,
+ rank: 6,
+ title: '커스텀커피',
+ comment: '',
+ link: '',
+ imageUrl: '',
+ },
+ ],
+};
+
+export const ITEMS_03 = {
+ id: 3,
+ listId: 1002,
+ data: [
+ {
+ id: 1,
+ rank: 1,
+ title: '달러구트 꿈 백화점 1',
+ comment: '',
+ link: '',
+ imageUrl: '',
+ },
+ {
+ id: 2,
+ rank: 2,
+ title: '달러구트 꿈 백화점 2',
+ comment: '',
+ link: '',
+ imageUrl: '',
+ },
+ {
+ id: 3,
+ rank: 3,
+ title: '모순',
+ comment: '',
+ link: '',
+ imageUrl: '',
+ },
+ {
+ id: 4,
+ rank: 4,
+ title: '지구끝의 온실',
+ comment: '',
+ link: '',
+ imageUrl: '',
+ },
+ {
+ id: 5,
+ rank: 5,
+ title: '메리골드 마음 세탁소',
+ comment: '',
+ link: '',
+ imageUrl: '',
+ },
+ {
+ id: 6,
+ rank: 6,
+ title: '작별인사',
+ comment: '',
+ link: '',
+ imageUrl: '',
+ },
+ {
+ id: 7,
+ rank: 7,
+ title: '튜브',
+ comment: '',
+ link: '',
+ imageUrl: '',
+ },
+ {
+ id: 8,
+ rank: 8,
+ title: '아몬드',
+ comment: '',
+ link: '',
+ imageUrl: '',
+ },
+ {
+ id: 9,
+ rank: 9,
+ title: '백의 그림자',
+ comment: '',
+ link: '',
+ imageUrl: '',
+ },
+ {
+ id: 10,
+ rank: 10,
+ title: '내게 무해한 사람',
+ comment: '',
+ link: '',
+ imageUrl: '',
+ },
+ ],
+};
+
+export const ITEMS_04 = {
+ id: 4,
+ listId: 1003,
+ data: [
+ {
+ id: 1,
+ rank: 1,
+ title: '스타벅스',
+ comment: '',
+ link: '',
+ imageUrl: '',
+ },
+ {
+ id: 2,
+ rank: 2,
+ title: '투썸플레이스',
+ comment: '',
+ link: '',
+ imageUrl: '',
+ },
+ {
+ id: 3,
+ rank: 3,
+ title: '원두볶는 사람들',
+ comment: '',
+ link: '',
+ imageUrl: '',
+ },
+ {
+ id: 4,
+ rank: 4,
+ title: '할리스커피',
+ comment: '',
+ link: '',
+ imageUrl: '',
+ },
+ {
+ id: 5,
+ rank: 5,
+ title: '탐앤탐스',
+ comment: '',
+ link: '',
+ imageUrl: '',
+ },
+ {
+ id: 6,
+ rank: 6,
+ title: '커스텀커피',
+ comment: '',
+ link: '',
+ imageUrl: '',
+ },
+ {
+ id: 7,
+ rank: 7,
+ title: '빽다방',
+ comment: '',
+ link: '',
+ imageUrl: '',
+ },
+ ],
+};
+
+export const ITEMS_05 = {
+ id: 5,
+ listId: 1004,
+ data: [
+ {
+ id: 1,
+ rank: 1,
+ title: '도라지꽃',
+ comment: '',
+ link: '',
+ imageUrl: '',
+ },
+ {
+ id: 2,
+ rank: 2,
+ title: '라넌큘러스',
+ comment: '',
+ link: '',
+ imageUrl: '',
+ },
+ {
+ id: 3,
+ rank: 3,
+ title: '해바라기',
+ comment: '',
+ link: '',
+ imageUrl: '',
+ },
+ {
+ id: 4,
+ rank: 4,
+ title: '튤립',
+ comment: '',
+ link: '',
+ imageUrl: '',
+ },
+ {
+ id: 5,
+ rank: 5,
+ title: '카라',
+ comment: '',
+ link: '',
+ imageUrl: '',
+ },
+ ],
+};
diff --git a/src/app/[userNickname]/mockData/lists.ts b/src/app/[userNickname]/mockData/lists.ts
new file mode 100644
index 00000000..78c02f3c
--- /dev/null
+++ b/src/app/[userNickname]/mockData/lists.ts
@@ -0,0 +1,66 @@
+// 리스트 데이터
+
+import { ITEMS_01, ITEMS_02, ITEMS_03, ITEMS_04, ITEMS_05 } from './items';
+
+export const LISTS_ME = [
+ {
+ listId: 1000,
+ category: '장소', // 코드
+ title: '내 동네 미사2동 맛집은 글자수가 30자일까요 top3',
+ ownerId: 100, // userId
+ ownerNickname: '파도타기',
+ ownerProfileImageUrl: '',
+ createdDate: '',
+ backgroundColor: '#B7EEFF',
+ items: ITEMS_01.data,
+ isPublic: true,
+ },
+ {
+ listId: 1001,
+ category: '장소', // 코드
+ title: 'What is essential is invisible to the eye.',
+ ownerId: 100, // userId
+ ownerNickname: '파도타기',
+ ownerProfileImageUrl: '',
+ createdDate: '',
+ backgroundColor: '#FFF6A5',
+ items: ITEMS_02.data,
+ isPublic: false,
+ },
+ {
+ listId: 1002,
+ category: '도서', // 코드
+ title: '내 기준 지루하지 않은 소설 TOP10',
+ ownerId: 100, // userId
+ ownerNickname: '파도타기',
+ ownerProfileImageUrl: '',
+ createdDate: '',
+ backgroundColor: '#D0FF89B2',
+ items: ITEMS_03.data,
+ isPublic: true,
+ },
+ {
+ listId: 1003,
+ category: '장소', // 코드
+ title: '자주 가는 카페(순위가 변경 될 수도 있음!!)',
+ ownerId: 100, // userId
+ ownerNickname: '파도타기',
+ ownerProfileImageUrl: '',
+ createdDate: '',
+ backgroundColor: '#FFDCB2',
+ items: ITEMS_04.data,
+ isPublic: true,
+ },
+ {
+ listId: 1004,
+ category: '동식물', // 코드
+ title: '좋아하는 꽃',
+ ownerId: 100, // userId
+ ownerNickname: '파도타기',
+ ownerProfileImageUrl: '',
+ createdDate: '',
+ backgroundColor: '#E6C6FF',
+ items: ITEMS_05.data,
+ isPublic: false,
+ },
+];
diff --git a/src/app/[userNickname]/mockData/mockDataTypes.ts b/src/app/[userNickname]/mockData/mockDataTypes.ts
new file mode 100644
index 00000000..753fedda
--- /dev/null
+++ b/src/app/[userNickname]/mockData/mockDataTypes.ts
@@ -0,0 +1,42 @@
+/**
+ TODO
+ - [ ] 타입 공통파일로 분리
+ - [ ] 이에 따른 타입 재점검
+ */
+
+// 공통 타입
+
+export interface UserType {
+ id: number;
+ backgroundImageUrl?: string; // mock 데이터 기준 optional
+ profileImageUrl?: string; // mock 데이터 기준 optional
+ nickname: string;
+ description: string;
+ followerCount: number;
+ followingCount: number;
+ isFollowed: boolean;
+ isOwner: boolean;
+}
+
+export interface ListType {
+ listId: number;
+ category: string;
+ title: string;
+ ownerId: number;
+ ownerNickname: string;
+ ownerProfileImageUrl?: string; // mock 데이터 기준 optional
+ createdDate?: string; // mock 데이터 기준 optional
+ backgroundColor: string;
+ items: ItemType[];
+ isPublic: boolean;
+}
+
+export interface ItemType {
+ id: number;
+ rank: number;
+ title: string;
+ comment?: string;
+ link?: string;
+ imageUrl?: string;
+ // items 다른 속성 추가 될 수도 있음
+}
diff --git a/src/app/[userNickname]/mockData/user.ts b/src/app/[userNickname]/mockData/user.ts
new file mode 100644
index 00000000..431665ba
--- /dev/null
+++ b/src/app/[userNickname]/mockData/user.ts
@@ -0,0 +1,26 @@
+// 사용자 데이터
+
+export const USER_DATA_ME = {
+ id: 100,
+ nickname: '파도타기',
+ description:
+ '리스트는 데이터를 순서대로 저장하는 자료 구조입니다. 파이썬에서는 대괄호([])로 표현하며, 다양한 연산을 지원합니다. 인덱스를 사용하여 요소에 접근할 수 있고, 데이터 처리에 효율적입니다. 리스트는 프로그래밍에서 중요한 개념이며, 다양한 알고리즘과 과제에 활용됩니다.',
+ profileImageUrl: 'https://image.utoimage.com/preview/cp872722/2022/12/202212008462_500.jpg',
+ backgroundImageUrl: 'https://image.utoimage.com/preview/cp872722/2022/12/202212008462_500.jpg',
+ followingCount: 1000, // 최대 1,000
+ followerCount: 0,
+ isFollowed: false, // default false
+ isOwner: true,
+};
+
+export const USER_DATA_OTHER = {
+ id: 101,
+ nickname: '파도타기1',
+ description: '파도타기 좋아요',
+ profileImageUrl: '',
+ backgroundImageUrl: '',
+ followingCount: 1000, // 최대 1,000
+ followerCount: 999,
+ isFollowed: false, // default false
+ isOwner: false,
+};
diff --git a/src/app/[userNickname]/mylist/page.tsx b/src/app/[userNickname]/mylist/page.tsx
new file mode 100644
index 00000000..d4feb866
--- /dev/null
+++ b/src/app/[userNickname]/mylist/page.tsx
@@ -0,0 +1,41 @@
+/**
+ TODO
+ - [ ] user api 연동
+ - [ ] 페이지 하위 컴포넌트 global css 변수로 변경
+ - [ ] 반응형 UI 구현
+ */
+
+import '@/styles/globalStyles.css';
+
+import { USER_DATA_ME } from '../mockData/user'; // 삭제 예정
+
+import Profile from '../_components/Profile';
+import Content from '../_components/Content';
+import FloatingContainer from '@/components/floatingButton/FloatingContainer';
+import PlusButton from '@/components/floatingButton/PlusOptionFloatingButton';
+import ArrowUpButton from '@/components/floatingButton/ArrowUpFloatingButton';
+
+// 타입 사용할 때 재정의
+// interface MyListPageProps {
+// params: {
+// userNickname: number;
+// };
+// userId: number;
+// }
+
+export default function MyListPage() {
+ // console.log(params.userNickname); // 삭제 예정
+
+ // 1. userId로 유저 정보 가져오는 api 요청
+
+ return (
+
+ );
+}
diff --git a/src/app/_api/category/getCategories.ts b/src/app/_api/category/getCategories.ts
new file mode 100644
index 00000000..637001e9
--- /dev/null
+++ b/src/app/_api/category/getCategories.ts
@@ -0,0 +1,8 @@
+import axiosInstance from '@/lib/axios/axiosInstance';
+import { CategoriesType } from '@/lib/types/categoriesType';
+
+export const getCategories = async () => {
+ const response = await axiosInstance.get('/categories');
+
+ return response.data;
+};
diff --git a/src/app/_api/init.ts b/src/app/_api/init.ts
deleted file mode 100644
index e099ee9f..00000000
--- a/src/app/_api/init.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-// 보일러플레이트용 임시 파일
-// 추후 이 파일은 지워주세요
diff --git a/src/app/_api/list/createList.ts b/src/app/_api/list/createList.ts
new file mode 100644
index 00000000..99d78ac3
--- /dev/null
+++ b/src/app/_api/list/createList.ts
@@ -0,0 +1 @@
+// 리스트 생성 api
diff --git a/src/app/_api/list/deleteList.ts b/src/app/_api/list/deleteList.ts
new file mode 100644
index 00000000..d0064953
--- /dev/null
+++ b/src/app/_api/list/deleteList.ts
@@ -0,0 +1 @@
+// 리스트 삭제 api
diff --git a/src/app/_api/list/getLists.ts b/src/app/_api/list/getLists.ts
new file mode 100644
index 00000000..4b7bcac9
--- /dev/null
+++ b/src/app/_api/list/getLists.ts
@@ -0,0 +1 @@
+// 리스트 조회 api
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index fa45bfa6..2ba93d43 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -1,7 +1,11 @@
'use client';
+
import { ReactNode } from 'react';
+import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import '@/styles/globalStyles.css';
+const queryClient = new QueryClient();
+
export default function TempLayout({ children }: { children: ReactNode }) {
return (
@@ -9,8 +13,10 @@ export default function TempLayout({ children }: { children: ReactNode }) {
ListyWave
-
- {children}
+
+
+ {children}
+