first commit
This commit is contained in:
210
app/dashboard/page.tsx
Normal file
210
app/dashboard/page.tsx
Normal file
@@ -0,0 +1,210 @@
|
||||
"use client";
|
||||
|
||||
import { useSession, signOut } from "next-auth/react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useEffect } from "react";
|
||||
|
||||
// JWT token'dan expiry bilgisini çıkar
|
||||
function getTokenExpiry(token: string | undefined): string {
|
||||
if (!token) return 'N/A';
|
||||
|
||||
try {
|
||||
const payload = JSON.parse(atob(token.split('.')[1]));
|
||||
if (payload.exp) {
|
||||
const expiryDate = new Date(payload.exp * 1000);
|
||||
const now = Date.now();
|
||||
const remainingMs = expiryDate.getTime() - now;
|
||||
const remainingMinutes = Math.floor(remainingMs / 60000);
|
||||
|
||||
if (remainingMs < 0) {
|
||||
return '⚠️ Token süresi dolmuş';
|
||||
} else if (remainingMinutes > 60) {
|
||||
const hours = Math.floor(remainingMinutes / 60);
|
||||
const mins = remainingMinutes % 60;
|
||||
return `${hours} saat ${mins} dakika`;
|
||||
} else {
|
||||
return `${remainingMinutes} dakika`;
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
return 'N/A';
|
||||
}
|
||||
return 'N/A';
|
||||
}
|
||||
|
||||
export default function DashboardPage() {
|
||||
const { data: session, status } = useSession();
|
||||
const router = useRouter();
|
||||
|
||||
useEffect(() => {
|
||||
if (status === "unauthenticated") {
|
||||
router.push("/auth/login");
|
||||
}
|
||||
}, [status, router]);
|
||||
|
||||
if (status === "loading") {
|
||||
return (
|
||||
<div className="min-h-screen flex items-center justify-center bg-gray-50">
|
||||
<div className="text-gray-600">Yükleniyor...</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (!session) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-50 py-8">
|
||||
<div className="max-w-4xl mx-auto px-4">
|
||||
<div className="bg-white rounded-lg shadow p-8">
|
||||
<div className="flex justify-between items-center mb-8">
|
||||
<h1 className="text-3xl font-bold text-gray-900">Dashboard</h1>
|
||||
<div className="flex gap-3">
|
||||
<button
|
||||
onClick={() => router.push("/profile")}
|
||||
className="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
|
||||
>
|
||||
Profil
|
||||
</button>
|
||||
<button
|
||||
onClick={() => signOut({ callbackUrl: "/auth/login" })}
|
||||
className="px-4 py-2 bg-red-600 text-white rounded-md hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2"
|
||||
>
|
||||
Çıkış Yap
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-6">
|
||||
{session.error && (
|
||||
<div className="bg-red-50 border border-red-200 rounded-md p-4">
|
||||
<div className="flex items-center">
|
||||
<svg className="h-5 w-5 text-red-400 mr-2" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clipRule="evenodd" />
|
||||
</svg>
|
||||
<div>
|
||||
<p className="font-medium text-red-800">Session Hatası</p>
|
||||
<p className="text-sm text-red-700 mt-1">
|
||||
{session.error === 'RefreshAccessTokenError'
|
||||
? 'Token yenileme başarısız. Lütfen tekrar giriş yapın.'
|
||||
: session.error}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
onClick={() => signOut({ callbackUrl: "/auth/login" })}
|
||||
className="mt-3 text-sm text-red-600 hover:text-red-500 underline"
|
||||
>
|
||||
Tekrar giriş yap →
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div>
|
||||
<h2 className="text-xl font-semibold text-gray-900 mb-4">
|
||||
Session Bilgileri
|
||||
</h2>
|
||||
<div className="bg-gray-50 rounded-md p-4 space-y-3">
|
||||
<div>
|
||||
<span className="font-medium text-gray-700">Email:</span>
|
||||
<p className="text-gray-900 mt-1">{session.user?.email || 'N/A'}</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<span className="font-medium text-gray-700">İsim:</span>
|
||||
<p className="text-gray-900 mt-1">{session.user?.name || 'Belirtilmemiş'}</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<span className="font-medium text-gray-700">
|
||||
Access Token:
|
||||
</span>
|
||||
<div className="mt-1 space-y-2">
|
||||
<div className="p-3 bg-white rounded border border-gray-200 break-all">
|
||||
<code className="text-xs text-gray-800">
|
||||
{session.accessToken || '❌ Token bulunamadı'}
|
||||
</code>
|
||||
</div>
|
||||
{session.accessToken && (
|
||||
<p className="text-xs text-gray-600">
|
||||
⏱️ Kalan süre: {getTokenExpiry(session.accessToken)}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<span className="font-medium text-gray-700">
|
||||
Refresh Token:
|
||||
</span>
|
||||
<div className="mt-1 space-y-2">
|
||||
<div className="p-3 bg-white rounded border border-gray-200 break-all">
|
||||
<code className="text-xs text-gray-800">
|
||||
{session.refreshToken || '❌ Token bulunamadı'}
|
||||
</code>
|
||||
</div>
|
||||
{session.refreshToken && (
|
||||
<p className="text-xs text-gray-600">
|
||||
⏱️ Kalan süre: {getTokenExpiry(session.refreshToken)}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<span className="font-medium text-gray-700">
|
||||
Session Bitiş Tarihi:
|
||||
</span>
|
||||
<p className="text-gray-900 mt-1">
|
||||
{session.expires ? new Date(session.expires).toLocaleString('tr-TR', {
|
||||
dateStyle: 'medium',
|
||||
timeStyle: 'medium'
|
||||
}) : 'N/A'}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<span className="font-medium text-gray-700">
|
||||
Kalan Süre:
|
||||
</span>
|
||||
<p className="text-gray-900 mt-1">
|
||||
{session.expires ? (() => {
|
||||
const expiryTime = new Date(session.expires).getTime();
|
||||
const now = Date.now();
|
||||
const remainingMs = expiryTime - now;
|
||||
const remainingMinutes = Math.floor(remainingMs / 60000);
|
||||
const remainingHours = Math.floor(remainingMinutes / 60);
|
||||
const remainingDays = Math.floor(remainingHours / 24);
|
||||
|
||||
if (remainingMs < 0) {
|
||||
return '⚠️ Session süresi dolmuş (yeniden giriş yapın)';
|
||||
} else if (remainingDays > 0) {
|
||||
return `${remainingDays} gün ${remainingHours % 24} saat`;
|
||||
} else if (remainingHours > 0) {
|
||||
return `${remainingHours} saat ${remainingMinutes % 60} dakika`;
|
||||
} else {
|
||||
return `${remainingMinutes} dakika`;
|
||||
}
|
||||
})() : 'N/A'}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h2 className="text-xl font-semibold text-gray-900 mb-4">
|
||||
Tüm Session Verisi
|
||||
</h2>
|
||||
<div className="bg-gray-900 rounded-md p-4 overflow-auto">
|
||||
<pre className="text-xs text-green-400">
|
||||
{JSON.stringify(session, null, 2)}
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user