diff --git a/components/FolderTag.tsx b/components/FolderTag.tsx
index 9745c83..94b97b8 100644
--- a/components/FolderTag.tsx
+++ b/components/FolderTag.tsx
@@ -5,7 +5,11 @@ interface FolderData {
linkCount: number;
}
-const FolderTag = (list: FolderData[]) => {
+interface FolderTagProps {
+ list: FolderData[];
+}
+
+const FolderTag = ({ list }: FolderTagProps) => {
const folderStyle = "py-[8px] px-[12px] border border-purple-100 rounded-md";
return (
diff --git a/components/Link/ActionButtons.tsx b/components/Link/ActionButtons.tsx
new file mode 100644
index 0000000..b498677
--- /dev/null
+++ b/components/Link/ActionButtons.tsx
@@ -0,0 +1,18 @@
+import Image from "next/image";
+
+const ActionButtons = () => (
+
+ {[
+ { src: "/icons/share.svg", alt: "공유", text: "공유" },
+ { src: "/icons/pen.svg", alt: "이름 변경", text: "이름 변경" },
+ { src: "/icons/delete.svg", alt: "삭제", text: "삭제" },
+ ].map(({ src, alt, text }) => (
+
+ ))}
+
+);
+
+export default ActionButtons;
diff --git a/pages/api/folders.ts b/pages/api/folders.ts
new file mode 100644
index 0000000..d8301eb
--- /dev/null
+++ b/pages/api/folders.ts
@@ -0,0 +1,44 @@
+import { NextApiRequest, NextApiResponse } from "next";
+import { parse } from "cookie";
+import axiosInstance from "@/lib/api/axiosInstanceApi";
+
+const handler = async (req: NextApiRequest, res: NextApiResponse) => {
+ const cookies = parse(req.headers.cookie || "");
+ const accessToken = cookies.accessToken;
+
+ console.log("getFolder 요청 : ", accessToken);
+
+ switch (req.method) {
+ case "GET":
+ // 유저의 모든 폴더 조회
+ try {
+ const response = await axiosInstance.get("/folders", {
+ headers: { Authorization: `Bearer ${accessToken}` },
+ });
+ return res.status(201).json(response.data);
+ } catch (err) {
+ console.error(err);
+ return res
+ .status(500)
+ .json({ message: "모든 폴저 조회에 실패했습니다." });
+ }
+
+ case "POST":
+ // 유저의 폴더 생성
+ try {
+ const response = await axiosInstance.post("/folders", req.body, {
+ headers: { Authorization: `Bearer ${accessToken}` },
+ });
+ return res.status(201).json(response.data);
+ } catch (err) {
+ console.error(err);
+ return res.status(500).json({ message: "폴더 생성에 실패했습니다." });
+ }
+
+ default:
+ res.setHeader("Allow", ["GET", "POST"]);
+ return res.status(405).end(`메서드 ${req.method}는 허용되지 않습니다.`);
+ }
+};
+
+export default handler;
diff --git a/pages/api/links.ts b/pages/api/links.ts
new file mode 100644
index 0000000..53f0128
--- /dev/null
+++ b/pages/api/links.ts
@@ -0,0 +1,46 @@
+import { NextApiRequest, NextApiResponse } from "next";
+import { parse } from "cookie";
+import axiosInstance from "@/lib/api/axiosInstanceApi";
+
+const handler = async (req: NextApiRequest, res: NextApiResponse) => {
+ const cookies = parse(req.headers.cookie || "");
+ const accessToken = cookies.accessToken;
+
+ console.log("서버에서 전달받은 쿠키의 값: ", cookies);
+ console.log("서버에서 전달받은 토큰의 값: ", accessToken);
+
+ switch (req.method) {
+ case "GET":
+ // 유저의 전체 링크 조회
+ try {
+
+ const response = await axiosInstance.get("/links", {
+ headers: { Authorization: `Bearer ${accessToken}` },
+ });
+ return res.status(201).json(response.data);
+ } catch (err) {
+ console.error(err);
+ return res
+ .status(500)
+ .json({ message: "전체 링크 조회에 실패했습니다." });
+ }
+
+ case "POST":
+ // 링크 생성 로직
+ try {
+ const response = await axiosInstance.post("/links", req.body, {
+ headers: { Authorization: `Bearer ${accessToken}` },
+ });
+ return res.status(201).json(response.data);
+ } catch (err) {
+ console.error(err);
+ return res.status(500).json({ message: "링크 생성에 실패했습니다." });
+ }
+
+ default:
+ res.setHeader("Allow", ["GET", "POST"]);
+ return res.status(405).end(`메서드 ${req.method}는 허용되지 않습니다.`);
+ }
+};
+
+export default handler;
diff --git a/pages/link/index.tsx b/pages/link/index.tsx
new file mode 100644
index 0000000..51a84f9
--- /dev/null
+++ b/pages/link/index.tsx
@@ -0,0 +1,74 @@
+import { GetServerSidePropsContext } from "next";
+import { proxy } from "@/lib/api/axiosInstanceApi";
+import { SearchInput } from "../../components/Search/SearchInput";
+import { LinkData } from "@/types/linkTypes";
+import { FolderData } from "@/types/folderTypes";
+import Container from "@/components/Layout/Container";
+import CardsLayout from "@/components/Layout/CardsLayout";
+import FolderTag from "../../components/FolderTag";
+import LinkCard from "../../components/LinkCard";
+import AddLinkInput from "@/components/link/AddLinkInput";
+import ActionButtons from "@/components/link/ActionButtons";
+
+interface LinkPageProps {
+ links: LinkData[];
+ folders: FolderData[];
+}
+export const getServerSideProps = async (
+ context: GetServerSidePropsContext
+) => {
+ const { req } = context;
+
+ const fetchData = async (endpoint: string) => {
+ const response = await proxy.get(endpoint, {
+ headers: {
+ Cookie: req.headers.cookie,
+ },
+ });
+ return response.data;
+ };
+
+ const [links, folders] = await Promise.all([
+ fetchData("/api/links"),
+ fetchData("/api/folders"),
+ ]);
+
+ return {
+ props: {
+ links: links.list || [], // 기본값 처리
+ folders: folders || [], // 기본값 처리
+ },
+ };
+};
+
+const LinkPage = ({ links, folders }: LinkPageProps) => {
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+ {links.map((link) => (
+
+ ))}
+
+
+
+ >
+ );
+};
+
+export default LinkPage;
diff --git a/public/icons/delete.svg b/public/icons/delete.svg
new file mode 100644
index 0000000..1923de9
--- /dev/null
+++ b/public/icons/delete.svg
@@ -0,0 +1,8 @@
+
diff --git a/public/icons/pen.svg b/public/icons/pen.svg
new file mode 100644
index 0000000..fb75fc3
--- /dev/null
+++ b/public/icons/pen.svg
@@ -0,0 +1,5 @@
+
diff --git a/public/icons/share.svg b/public/icons/share.svg
new file mode 100644
index 0000000..da9d0c1
--- /dev/null
+++ b/public/icons/share.svg
@@ -0,0 +1,11 @@
+
diff --git a/types/folderTypes.ts b/types/folderTypes.ts
new file mode 100644
index 0000000..8db6c6d
--- /dev/null
+++ b/types/folderTypes.ts
@@ -0,0 +1,6 @@
+export interface FolderData {
+ id: number;
+ createdAt: string;
+ name: string;
+ linkCount: number;
+}
diff --git a/types/linkTypes.ts b/types/linkTypes.ts
new file mode 100644
index 0000000..96088c6
--- /dev/null
+++ b/types/linkTypes.ts
@@ -0,0 +1,9 @@
+export interface LinkData {
+ id: number;
+ favorite: boolean;
+ url: string;
+ title: string;
+ imageSource: string;
+ description: string;
+ createdAt: string;
+}