diff --git a/src/app/api/attendance/route.ts b/src/app/api/attendance/route.ts new file mode 100644 index 0000000..8353c25 --- /dev/null +++ b/src/app/api/attendance/route.ts @@ -0,0 +1,28 @@ +import { NextResponse } from "next/server"; +import prisma from "@/lib/prisma"; +import { getUserIdFromRequest } from "@/lib/auth"; + +export async function GET(req: Request) { + const userId = getUserIdFromRequest(req); + if (!userId) return NextResponse.json({ today: null, count: 0 }); + const start = new Date(); start.setHours(0,0,0,0); + const end = new Date(); end.setHours(23,59,59,999); + const today = await prisma.pointTransaction.findFirst({ + where: { userId, reason: "attendance", createdAt: { gte: start, lte: end } }, + }); + const count = await prisma.pointTransaction.count({ where: { userId, reason: "attendance" } }); + return NextResponse.json({ today: !!today, count }); +} + +export async function POST(req: Request) { + const userId = getUserIdFromRequest(req); + if (!userId) return NextResponse.json({ error: "login required" }, { status: 401 }); + const start = new Date(); start.setHours(0,0,0,0); + const end = new Date(); end.setHours(23,59,59,999); + const exists = await prisma.pointTransaction.findFirst({ where: { userId, reason: "attendance", createdAt: { gte: start, lte: end } } }); + if (exists) return NextResponse.json({ ok: true, duplicated: true }); + await prisma.pointTransaction.create({ data: { userId, amount: 10, reason: "attendance" } }); + return NextResponse.json({ ok: true }); +} + + diff --git a/src/app/attendance/page.tsx b/src/app/attendance/page.tsx new file mode 100644 index 0000000..e1ddb63 --- /dev/null +++ b/src/app/attendance/page.tsx @@ -0,0 +1,17 @@ +"use client"; +import useSWR from "swr"; + +const fetcher = (url: string) => fetch(url).then((r) => r.json()); + +export default function AttendancePage() { + const { data, mutate } = useSWR<{ today: boolean; count: number }>("/api/attendance", fetcher); + return ( +
+

출석부

+

오늘 출석: {data?.today ? "✅" : "❌"} / 누적: {data?.count ?? 0}

+ +
+ ); +} + + diff --git a/todolist.txt b/todolist.txt index 05cbaf0..bd4b9cf 100644 --- a/todolist.txt +++ b/todolist.txt @@ -52,7 +52,7 @@ 7.10 제휴업소 일반(사진) 카테고리 전용 이미지 첨부/미리보기 규칙 o [특수 페이지(카테고리)] -8.1 출석부: 데일리 체크인/중복 방지/포인트 지급/누적 통계 +8.1 출석부: 데일리 체크인/중복 방지/포인트 지급/누적 통계 o 8.2 포인트안내: 정책 안내 페이지(에디터 연동/버전 이력) 8.3 회원랭킹: 기간별 랭킹 집계/캐싱/페이지네이션/정렬 옵션 8.4 무료쿠폰: 쿠폰 등록/재고/사용 처리/만료/1인 제한/로그