Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
NEXT_PUBLIC_GOOGLE_ADSENSE_CLIENT_ID=
NEXT_PUBLIC_GA_MEASUREMENT_ID=
NEXT_PUBLIC_GITHUB_REPO_NAME=
NEXT_PUBLIC_GITHUB_REPO_NAME=
NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_ANON_KEY=
34 changes: 34 additions & 0 deletions app/games/poop-dodge/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import type { Metadata } from 'next';
import { openGraph } from '@/app/shared-metadata';

const ogTitle = '똥피하기';
const description = '똥을 피해 살아남으세요! 기록을 세우고 리더보드에 도전하세요.';

export const metadata: Metadata = {
title: ogTitle,
description,
openGraph: {
...openGraph,
title: ogTitle,
description,
url: '/games/poop-dodge',
images: [
{
url: '/images/games/poop/poop-dodge-thumbnail.png',
width: 1200,
height: 630,
alt: '똥피하기 게임 썸네일',
},
],
},
twitter: {
title: ogTitle,
description,
card: 'summary_large_image',
images: ['/images/games/poop/poop-dodge-thumbnail.png'],
},
};

export default function Layout({ children }: { children: React.ReactNode }) {
return children;
}
62 changes: 62 additions & 0 deletions app/games/poop-dodge/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,40 @@
'use client';

import { useEffect, useState } from 'react';
import { supabase } from '@/lib/supabaseClient';

interface LeaderboardEntry {
id: number;
nickname: string;
record: string;
}

const PoopDodgePage = () => {
const [leaderboard, setLeaderboard] = useState<LeaderboardEntry[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);

useEffect(() => {
const fetchLeaderboard = async () => {
setLoading(true);
setError(null);
const { data, error } = await supabase
.from('leaderboard')
.select('id, nickname, record')
.eq('game_id', 'game1')
.order('record', { ascending: false })
.limit(5);
if (error) {
setError('리더보드 정보를 불러오지 못했습니다.');
setLeaderboard([]);
} else {
setLeaderboard(data || []);
}
setLoading(false);
};
fetchLeaderboard();
}, []);

return (
<main className="container-lg py-10">
<h1 className="mb-2 text-3xl font-bold">똥피하기</h1>
Expand All @@ -16,6 +50,34 @@ const PoopDodgePage = () => {
allowFullScreen
></iframe>
</div>
{/* 리더보드 */}
<div className="mt-10 flex flex-col items-center">
<h2 className="text-2xl font-bold mb-4">리더보드</h2>
{loading ? (
<div className="text-slate-500">로딩 중...</div>
) : error ? (
<div className="text-red-500">{error}</div>
) : (
<table className="min-w-[320px] max-w-lg w-full text-center border-separate border-spacing-y-2">
<thead>
<tr className="bg-gray-100">
<th className="py-2 rounded-l-lg">순위</th>
<th className="py-2">닉네임</th>
<th className="py-2 rounded-r-lg">기록</th>
</tr>
</thead>
<tbody>
{leaderboard.map((entry, idx) => (
<tr key={entry.id} className="bg-white shadow rounded-lg">
<td className="py-2 font-bold text-indigo-600">{idx + 1}</td>
<td className="py-2">{entry.nickname}</td>
<td className="py-2">{entry.record}</td>
</tr>
))}
</tbody>
</table>
)}
</div>
</main>
);
};
Expand Down
6 changes: 6 additions & 0 deletions lib/supabaseClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { createClient } from '@supabase/supabase-js';

const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL || process.env.SUPABASE_URL;
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY || process.env.SUPABASE_ANON_KEY;

export const supabase = createClient(supabaseUrl!, supabaseAnonKey!);
133 changes: 133 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"lint": "next lint"
},
"dependencies": {
"@supabase/supabase-js": "^2.49.8",
"cheerio": "^1.0.0-rc.12",
"clsx": "^2.0.0",
"contentlayer": "^0.3.4",
Expand Down