Skip to content

Commit 5289d09

Browse files
committed
feat: 잔디그래프 api 연동
1 parent 083e7d9 commit 5289d09

5 files changed

Lines changed: 74 additions & 34 deletions

File tree

app/(with-sidebar)/(home)/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ const Page = () => {
9999
/>
100100

101101
{/* 2-2. GraphSection */}
102-
<GraphSection></GraphSection>
102+
<GraphSection uid={currentUser.uid}></GraphSection>
103103

104104
{/* 2-3. BottomSection */}
105105
<BottomSection

components/heatmap/GrassHeatmap.tsx

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,28 @@
11
'use client';
22

3-
import { useMemo } from 'react';
3+
import { useEffect, useMemo, useState } from 'react';
44
import CalendarHeatmap from 'react-calendar-heatmap';
55
import 'react-calendar-heatmap/dist/styles.css';
6+
import { fetchDailyStats } from '@/services/heatmap/dailyStat.service';
67

78
type HeatmapValue = {
89
date: string;
910
count: number;
1011
};
1112

12-
/** 이번 주 토요일 기준으로 endDate 맞추기 (GitHub 느낌) */
13+
/** 토요일 기준으로 endDate 설정 */
1314
function endOfWeek(date = new Date()) {
1415
const d = new Date(date);
1516
const diff = 6 - d.getDay(); // 0=Sun, 6=Sat
1617
d.setDate(d.getDate() + diff);
1718
return d;
1819
}
1920

20-
/** mock data: 최근 1년 */
21-
function buildMockValues(days = 366): HeatmapValue[] {
22-
const out: HeatmapValue[] = [];
23-
const today = new Date();
24-
25-
for (let i = days - 1; i >= 0; i--) {
26-
const d = new Date(today);
27-
d.setDate(today.getDate() - i);
28-
29-
const iso = d.toISOString().slice(0, 10);
30-
31-
const r = Math.random();
32-
const count =
33-
r < 0.65 ? 0 : r < 0.85 ? 1 : r < 0.95 ? 2 : r < 0.985 ? 3 : 4;
34-
35-
if (count > 0) out.push({ date: iso, count });
36-
}
37-
38-
return out;
39-
}
21+
type Props = {
22+
uid?: string;
23+
};
4024

41-
export default function GrassHeatmap() {
25+
export const GrassHeatmap = ({ uid }: Props) => {
4226
const endDate = useMemo(() => endOfWeek(new Date()), []);
4327
const startDate = useMemo(() => {
4428
const d = new Date(endDate);
@@ -47,8 +31,19 @@ export default function GrassHeatmap() {
4731
return d;
4832
}, [endDate]);
4933

50-
const values = useMemo(() => buildMockValues(366), []);
34+
const [values, setValues] = useState<HeatmapValue[]>([]);
35+
useEffect(() => {
36+
if (!uid) return;
5137

38+
(async () => {
39+
const stats = await fetchDailyStats(uid);
40+
const heatmapValues: HeatmapValue[] = stats.map((s) => ({
41+
date: s.date,
42+
count: s.total,
43+
}));
44+
setValues(heatmapValues);
45+
})();
46+
}, [uid]);
5247
return (
5348
<>
5449
{/* 가로 길어질 때 대비 */}
@@ -87,4 +82,5 @@ export default function GrassHeatmap() {
8782
</div>
8883
</>
8984
);
90-
}
85+
};
86+
export default GrassHeatmap;

components/home/GraphSection.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@ import GrassHeatmap from '../heatmap/GrassHeatmap';
33

44
interface GraphSectionProps {
55
className?: string;
6+
uid?: string;
67
}
78

8-
const GraphSection = ({ className }: GraphSectionProps) => {
9+
const GraphSection = ({ className, uid }: GraphSectionProps) => {
910
return (
1011
<div className={className}>
1112
<Card title="학습 기록">
12-
<GrassHeatmap />
13+
<GrassHeatmap uid={uid} />
1314
</Card>
1415
</div>
1516
);

services/heatmap/dailyStat.service.ts

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,30 @@
1-
import { doc, runTransaction, serverTimestamp } from 'firebase/firestore';
1+
import {
2+
doc,
3+
runTransaction,
4+
serverTimestamp,
5+
collection,
6+
getDocs,
7+
query,
8+
where,
9+
orderBy,
10+
} from 'firebase/firestore';
211
import { db } from '@/lib/firebase';
312

13+
export interface DailyStat {
14+
date: string; // YYYY-MM-DD
15+
total: number;
16+
}
17+
418
function dateKeyKST(date = new Date()) {
519
const kst = new Date(date.getTime() + 9 * 60 * 60 * 1000);
620
return kst.toISOString().slice(0, 10);
721
}
822

9-
export async function bumpDailyStat(
23+
export const bumpDailyStat = async (
1024
uid: string,
1125
deltaTil: number,
1226
deltaTodoDone: number
13-
) {
27+
) => {
1428
const key = dateKeyKST();
1529
const ref = doc(db, `users/${uid}/dailyStats/${key}`);
1630

@@ -41,4 +55,33 @@ export async function bumpDailyStat(
4155
{ merge: true }
4256
);
4357
});
44-
}
58+
};
59+
60+
export const fetchDailyStats = async (uid: string) => {
61+
const colRef = collection(db, 'users', uid, 'dailyStats');
62+
63+
const endDate = dateKeyKST(new Date());
64+
const startDate = (() => {
65+
const d = new Date();
66+
d.setFullYear(d.getFullYear() - 1);
67+
d.setDate(d.getDate() + 1);
68+
return dateKeyKST(d);
69+
})();
70+
71+
const q = query(
72+
colRef,
73+
where('date', '>=', startDate),
74+
where('date', '<=', endDate),
75+
orderBy('date', 'asc')
76+
);
77+
78+
const snap = await getDocs(q);
79+
80+
return snap.docs.map((doc) => {
81+
const data = doc.data();
82+
return {
83+
date: data.date,
84+
total: data.total ?? 0,
85+
};
86+
});
87+
};

services/write/til.service.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ export async function fetchMyTil(
5757
uid: string | null | undefined,
5858
tilId: string | null | undefined
5959
): Promise<Til | null> {
60-
// 여기서 uid/tilId 실물 확인
61-
console.log('[fetchMyPost] path =', { uid, tilId });
60+
// // 여기서 uid/tilId 실물 확인
61+
// console.log('[fetchMyPost] path =', { uid, tilId });
6262

6363
if (!uid || !tilId) return null;
6464

0 commit comments

Comments
 (0)