@@ -170,7 +69,7 @@ const ScreenMainPage = () => {
/>
)}
{/* */}
-
+ {!isLoading && }
diff --git a/app/main/page.tsx b/app/main/page.tsx
index 8e7aa80..fdf9b3d 100644
--- a/app/main/page.tsx
+++ b/app/main/page.tsx
@@ -1,6 +1,41 @@
+import { serverApi } from "@/lib/server-api";
+import {
+ dehydrate,
+ HydrationBoundary,
+ QueryClient,
+} from "@tanstack/react-query";
import React from "react";
import ScreenMainPage from "./_components/ScreenMainPage";
-export default function MainPage() {
- return ;
+import { ItemsResponse } from "@/hooks/useItems";
+import { MatchingHistoryResponse } from "@/hooks/useMatchingHistory";
+
+export default async function MainPage() {
+ const queryClient = new QueryClient();
+
+ // 서버사이드에서 데이터를 미리 가져와서 캐시에 채워줍니다.
+ await Promise.all([
+ queryClient.prefetchQuery({
+ queryKey: ["items"],
+ queryFn: async () => {
+ const res = await serverApi.get({ path: "/api/items" });
+ return res.data;
+ },
+ }),
+ queryClient.prefetchQuery({
+ queryKey: ["matchingHistory"],
+ queryFn: async () => {
+ const res = await serverApi.get({
+ path: "/api/matching/history",
+ });
+ return res.data;
+ },
+ }),
+ ]);
+
+ return (
+
+
+
+ );
}
diff --git a/hooks/useItems.ts b/hooks/useItems.ts
new file mode 100644
index 0000000..760efbb
--- /dev/null
+++ b/hooks/useItems.ts
@@ -0,0 +1,42 @@
+import { api } from "@/lib/axios";
+import { useQuery } from "@tanstack/react-query";
+
+interface Item {
+ itemId: number;
+ itemType: string;
+ quantity: number;
+ expiredAt: string;
+}
+
+export interface ItemsResponse {
+ code: string;
+ status: number;
+ message: string;
+ data: {
+ items: {
+ content: Item[];
+ currentPage: number;
+ size: number;
+ totalElements: number;
+ totalPages: number;
+ hasNext: boolean;
+ hasPrevious: boolean;
+ };
+ matchingTicketCount: number;
+ optionTicketCount: number;
+ };
+}
+
+export const fetchItems = async (): Promise => {
+ const { data } = await api.get("/api/items");
+ return data;
+};
+
+export const useItems = () => {
+ return useQuery({
+ queryKey: ["items"],
+ queryFn: fetchItems,
+ staleTime: Infinity, // 충전/소모 전까지는 데이터가 변하지 않으므로 무한정 캐싱
+ gcTime: 1000 * 60 * 60, // 메모리에서 1시간 동안 유지
+ });
+};
diff --git a/hooks/useMatchingHistory.ts b/hooks/useMatchingHistory.ts
new file mode 100644
index 0000000..6184838
--- /dev/null
+++ b/hooks/useMatchingHistory.ts
@@ -0,0 +1,69 @@
+import { api } from "@/lib/axios";
+import {
+ Gender,
+ MBTI,
+ SocialType,
+ Hobby,
+ IntroItem,
+ ContactFrequency,
+} from "@/lib/types/profile";
+import { useQuery } from "@tanstack/react-query";
+
+export interface MatchingPartner {
+ memberId: number;
+ email: string;
+ nickname: string;
+ gender: Gender;
+ birthDate: string;
+ mbti: MBTI;
+ intro: string | null;
+ profileImageUrl: string;
+ socialType: SocialType | null;
+ socialAccountId: string | null;
+ university: string;
+ major: string;
+ contactFrequency: ContactFrequency;
+ hobbies: Hobby[];
+ intros: IntroItem[];
+ advantages: string[] | null;
+ favoriteSong: string | null;
+}
+
+export interface MatchingHistoryItem {
+ historyId: number;
+ partner: MatchingPartner;
+ favorite: boolean;
+ matchedAt: string;
+}
+
+export interface MatchingHistoryResponse {
+ code: string;
+ status: number;
+ message: string;
+ data: {
+ content: MatchingHistoryItem[];
+ currentPage: number;
+ size: number;
+ totalElements: number;
+ totalPages: number;
+ hasNext: boolean;
+ hasPrevious: boolean;
+ };
+}
+
+export const fetchMatchingHistory =
+ async (): Promise => {
+ const { data } = await api.get(
+ "/api/matching/history",
+ );
+ return data;
+ };
+
+export const useMatchingHistory = () => {
+ return useQuery({
+ queryKey: ["matchingHistory"],
+ queryFn: fetchMatchingHistory,
+ staleTime: Infinity, // 새로운 매칭이나 즐겨찾기 변경 전까지는 캐시 유지
+ gcTime: 1000 * 60 * 60, // 메모리에서 1시간 동안 유지
+ });
+};