From f6dd484614391a3addf0d54eb1a85c6e798f4778 Mon Sep 17 00:00:00 2001 From: namsh1125 Date: Sat, 1 Feb 2025 23:56:42 +0900 Subject: [PATCH 1/3] =?UTF-8?q?=E2=9C=A8=20=ED=86=B5=EA=B3=84=20API=20?= =?UTF-8?q?=EC=9A=94=EC=B2=AD=ED=95=98=EB=8A=94=20route.js=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/statistics/category/route.js | 10 ++++++++++ app/api/statistics/summary/route.js | 10 ++++++++++ app/api/statistics/weekly/route.js | 10 ++++++++++ 3 files changed, 30 insertions(+) create mode 100644 app/api/statistics/category/route.js create mode 100644 app/api/statistics/summary/route.js create mode 100644 app/api/statistics/weekly/route.js diff --git a/app/api/statistics/category/route.js b/app/api/statistics/category/route.js new file mode 100644 index 0000000..00765cc --- /dev/null +++ b/app/api/statistics/category/route.js @@ -0,0 +1,10 @@ +import { NextResponse } from "next/server"; + +export async function GET() { + const response = await fetch( + "http://34.64.250.183:8080/api/statistics/category" + ); + const data = await response.json(); + + return NextResponse.json(data); +} diff --git a/app/api/statistics/summary/route.js b/app/api/statistics/summary/route.js new file mode 100644 index 0000000..2ccc4e6 --- /dev/null +++ b/app/api/statistics/summary/route.js @@ -0,0 +1,10 @@ +import { NextResponse } from "next/server"; + +export async function GET() { + const response = await fetch( + "http://34.64.250.183:8080/api/statistics/summary" + ); + const data = await response.json(); + + return NextResponse.json(data); +} diff --git a/app/api/statistics/weekly/route.js b/app/api/statistics/weekly/route.js new file mode 100644 index 0000000..c5d0c23 --- /dev/null +++ b/app/api/statistics/weekly/route.js @@ -0,0 +1,10 @@ +import { NextResponse } from "next/server"; + +export async function GET() { + const response = await fetch( + "http://34.64.250.183:8080/api/statistics/weekly" + ); + const data = await response.json(); + + return NextResponse.json(data); +} From 341db92b1357421e82118fe0507743b3e51d2de8 Mon Sep 17 00:00:00 2001 From: namsh1125 Date: Sun, 2 Feb 2025 00:08:32 +0900 Subject: [PATCH 2/3] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20=EA=B8=B0=EC=A1=B4=20M?= =?UTF-8?q?ock=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EB=B0=A9=EC=8B=9D=EC=9D=84?= =?UTF-8?q?=20API=20=EC=9A=94=EC=B2=AD=20=EB=B0=A9=EC=8B=9D=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=BD=94=EB=93=9C=EB=A5=BC=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/statistics/page.js | 212 ++++++++++++++++++++++++----------------- 1 file changed, 124 insertions(+), 88 deletions(-) diff --git a/app/statistics/page.js b/app/statistics/page.js index 652a6bb..51e8e09 100644 --- a/app/statistics/page.js +++ b/app/statistics/page.js @@ -1,6 +1,6 @@ "use client"; -import React, { useState } from "react"; +import React, { useState, useEffect } from "react"; import { Container, Typography } from "@mui/material"; import { Responsive, WidthProvider } from "react-grid-layout"; import "@/styles/react-grid.css"; @@ -18,11 +18,6 @@ import { RadialLinearScale, } from "chart.js"; import ChartDataLabels from "chartjs-plugin-datalabels"; -import { - mockSummaryStatisticsData, - mockWeeklyStatisticsData, - mockCategoryStatisticsData, -} from "@/constants/mockStatisticsResponseData"; import TotalSolvedChart from "@/components/statistics/summary/total-solved"; import CorrectRateChart from "@/components/statistics/summary/correct-rate"; @@ -31,7 +26,7 @@ import CategorySolvedChart from "@/components/statistics/category/category-solve import CategoryAccuracyChart from "@/components/statistics/category/category-accuracy"; import WeeklyTrendChart from "@/components/statistics/weekly/weekly-trend"; import { statisticUtils } from "@/utils/statisticUtils"; -import {Bell, Settings} from "lucide-react"; +import { Bell, Settings } from "lucide-react"; const ResponsiveGridLayout = WidthProvider(Responsive); @@ -69,6 +64,48 @@ export default function StatisticsPage() { ], }); + const [summaryData, setSummaryData] = useState(null); + const [weeklyData, setWeeklyData] = useState(null); + const [categoryData, setCategoryData] = useState(null); + const [isLoading, setIsLoading] = useState(true); + + useEffect(() => { + const fetchData = async () => { + try { + // API 호출 + const [summaryRes, weeklyRes, categoryRes] = await Promise.all([ + fetch("/api/statistics/summary"), + fetch("/api/statistics/weekly"), + fetch("/api/statistics/category"), + ]); + + // JSON 파싱 + const summary = await summaryRes.json(); + const weekly = await weeklyRes.json(); + const category = await categoryRes.json(); + + // 상태 업데이트 + setSummaryData(summary); + setWeeklyData(weekly); + setCategoryData(category); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + setIsLoading(false); + } + }; + + fetchData(); + }, []); + + if (isLoading) { + return ( +
+
Loading...
+
+ ); + } + const gridItemStyle = { backgroundColor: "#fff", borderRadius: "8px", @@ -78,92 +115,91 @@ export default function StatisticsPage() { }; return ( -
- {/* Header */} -
-
-
-

나의 학습통계

-
- - -
+
+ {/* Header */} +
+
+
+

나의 학습통계

+
+ +
-
- - - {/**/} - {/* 나의 학습 통계*/} - {/**/} - - { - setLayouts(allLayouts); - }} - > -
- -
+
+
-
- -
+ {/* 나의 학습 통계 */} + + { + setLayouts(allLayouts); + }} + > +
+ +
-
- - 총 해결한 문제 - - - {mockSummaryStatisticsData.data.user.totalSolved}문제 - -
-
- - 나의 정답률 - - - {mockSummaryStatisticsData.data.user.correctRate}% - -
-
- - 평균 풀이 시간 - - - {statisticUtils.formatters.timeInSeconds( - mockSummaryStatisticsData.data.user.timeStats.averageTime - )} - -
+
+ +
-
- -
+
+ + 총 해결한 문제 + + + {summaryData.data.user.totalSolved}문제 + +
-
- -
+
+ + 나의 정답률 + + + {summaryData.data.user.correctRate}% + +
-
- -
+
+ + 평균 풀이 시간 + + + {statisticUtils.formatters.timeInSeconds( + summaryData.data.user.timeStats.averageTime + )} + +
-
- -
-
-
-
- ); - } +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ + + + ); +} From 4f2d86cd1052bab24c7688c8325cb72cd0ae38a1 Mon Sep 17 00:00:00 2001 From: namsh1125 Date: Sun, 2 Feb 2025 00:12:43 +0900 Subject: [PATCH 3/3] =?UTF-8?q?=F0=9F=97=91=EF=B8=8F=20API=20=EC=9A=94?= =?UTF-8?q?=EC=B2=AD=EC=9C=BC=EB=A1=9C=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20mock=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- constants/mockStatisticsResponseData.js | 252 ------------------------ 1 file changed, 252 deletions(-) delete mode 100644 constants/mockStatisticsResponseData.js diff --git a/constants/mockStatisticsResponseData.js b/constants/mockStatisticsResponseData.js deleted file mode 100644 index 7bf607b..0000000 --- a/constants/mockStatisticsResponseData.js +++ /dev/null @@ -1,252 +0,0 @@ -/** - * GET /api/statistics/summary - * 사용자 통계 요약 정보 - */ -export const mockSummaryStatisticsData = { - isSuccess: true, - statusCode: 200, - message: "사용자 통계 요약 정보 조회 성공", - data: { - user: { - totalSolved: 45, - correctRate: 78, - incorrectRate: 22, - timeStats: { - averageTime: 240, // 문제당 평균 소요 시간(초) - totalTime: 10800, // 총 학습 시간(초) - fastestTime: 60, // 최단 소요 시간(초) - longestTime: 600, // 최장 소요 시간(초) - averageTimeByCategory: { - // 카테고리별 평균 소요 시간(초) - 운영체제: 240, - 네트워크: 200, - 자료구조: 250, - 알고리즘: 300, - DB: 150, - 보안: 150, - }, - }, - }, - average: { - totalSolved: 32, - correctRate: 65, - incorrectRate: 35, - timeStats: { - averageTime: 300, // 전체 사용자 평균 소요 시간(초) - totalTime: 9600, // 전체 사용자 평균 총 학습 시간(초) - }, - }, - }, -}; - -/** - * GET /api/statistics/weekly - * 주간 문제 해결 현황 - */ -export const mockWeeklyStatisticsData = { - isSuccess: true, - statusCode: 200, - message: "주간 문제 해결 현황 조회 성공", - data: { - weeklyProgress: [ - { - day: "월", - date: "2024-01-22", - solved: 4, - categoryDetails: [ - { category: "운영체제", solved: 1 }, - { category: "네트워크", solved: 0 }, - { category: "자료구조", solved: 1 }, - { category: "알고리즘", solved: 2 }, - { category: "DB", solved: 0 }, - { category: "보안", solved: 0 }, - ], - }, - { - day: "화", - date: "2024-01-23", - solved: 6, - categoryDetails: [ - { category: "운영체제", solved: 2 }, - { category: "네트워크", solved: 1 }, - { category: "자료구조", solved: 1 }, - { category: "알고리즘", solved: 1 }, - { category: "DB", solved: 1 }, - { category: "보안", solved: 0 }, - ], - }, - { - day: "수", - date: "2024-01-24", - solved: 3, - categoryDetails: [ - { category: "운영체제", solved: 1 }, - { category: "네트워크", solved: 0 }, - { category: "자료구조", solved: 0 }, - { category: "알고리즘", solved: 1 }, - { category: "DB", solved: 1 }, - { category: "보안", solved: 0 }, - ], - }, - { - day: "목", - date: "2024-01-25", - solved: 7, - categoryDetails: [ - { category: "운영체제", solved: 2 }, - { category: "네트워크", solved: 1 }, - { category: "자료구조", solved: 1 }, - { category: "알고리즘", solved: 2 }, - { category: "DB", solved: 1 }, - { category: "보안", solved: 0 }, - ], - }, - { - day: "금", - date: "2024-01-26", - solved: 5, - categoryDetails: [ - { category: "운영체제", solved: 1 }, - { category: "네트워크", solved: 1 }, - { category: "자료구조", solved: 1 }, - { category: "알고리즘", solved: 1 }, - { category: "DB", solved: 0 }, - { category: "보안", solved: 1 }, - ], - }, - { - day: "토", - date: "2024-01-27", - solved: 8, - categoryDetails: [ - { category: "운영체제", solved: 2 }, - { category: "네트워크", solved: 2 }, - { category: "자료구조", solved: 1 }, - { category: "알고리즘", solved: 2 }, - { category: "DB", solved: 1 }, - { category: "보안", solved: 0 }, - ], - }, - { - day: "일", - date: "2024-01-28", - solved: 4, - categoryDetails: [ - { category: "운영체제", solved: 1 }, - { category: "네트워크", solved: 0 }, - { category: "자료구조", solved: 1 }, - { category: "알고리즘", solved: 1 }, - { category: "DB", solved: 1 }, - { category: "보안", solved: 0 }, - ], - }, - ], - }, -}; - -/** - * GET /api/statistics/category - * 카테고리별 통계 - */ -export const mockCategoryStatisticsData = { - isSuccess: true, - statusCode: 200, - message: "카테고리별 통계 조회 성공", - data: { - categories: [ - { - name: "운영체제", - solvedCount: 12, // 푼 문제 수 - totalSolvedPercentage: 17.1, // 전체 문제 중 차지하는 비율 - correctCount: 14, // 맞은 문제 수 - incorrectCount: 4, // 틀린 문제 수 - totalCount: 18, // 시도한 문제 수 - accuracyRate: 78, // 정답률 - incorrectRate: 22, // 오답률 - currentStreak: 3, // 현재 연속 정답 수 - bestStreak: 5, // 최대 연속 정답 수 - }, - { - name: "네트워크", - solvedCount: 15, - totalSolvedPercentage: 21.4, - correctCount: 17, - incorrectCount: 3, - totalCount: 20, - accuracyRate: 85, - incorrectRate: 15, - currentStreak: 4, - bestStreak: 7, - }, - { - name: "자료구조", - solvedCount: 8, - totalSolvedPercentage: 11.4, - correctCount: 22, - incorrectCount: 3, - totalCount: 25, - accuracyRate: 88, - incorrectRate: 12, - currentStreak: 2, - bestStreak: 6, - }, - { - name: "알고리즘", - solvedCount: 20, - totalSolvedPercentage: 28.6, - correctCount: 15, - incorrectCount: 5, - totalCount: 20, - accuracyRate: 75, - incorrectRate: 25, - currentStreak: 5, - bestStreak: 8, - }, - { - name: "DB", - solvedCount: 10, - totalSolvedPercentage: 14.3, - correctCount: 23, - incorrectCount: 2, - totalCount: 25, - accuracyRate: 92, - incorrectRate: 8, - currentStreak: 6, - bestStreak: 9, - }, - { - name: "보안", - solvedCount: 5, - totalSolvedPercentage: 7.2, - correctCount: 9, - incorrectCount: 2, - totalCount: 11, - accuracyRate: 82, - incorrectRate: 18, - currentStreak: 1, - bestStreak: 3, - }, - ], - }, -}; - -/** - * API 에러 응답 예시 - */ -export const errorResponse = { - isSuccess: false, - statusCode: 404, - message: "데이터를 찾을 수 없습니다.", - data: null, -}; - -/** - * API 응답 상태 코드 - */ -export const API_STATUS = { - SUCCESS: 200, - BAD_REQUEST: 400, - UNAUTHORIZED: 401, - NOT_FOUND: 404, - SERVER_ERROR: 500, -};