75 lines
2.6 KiB
TypeScript
75 lines
2.6 KiB
TypeScript
import { getMemberToken, getApiBaseUrl } from '../_lib/api';
|
|
import Link from 'next/link';
|
|
|
|
interface MemberProfile {
|
|
id: string;
|
|
tenantId: string;
|
|
jid: string;
|
|
displayName: string | null;
|
|
createdAt: string;
|
|
}
|
|
|
|
async function fetchProfile(token: string): Promise<MemberProfile | null> {
|
|
const res = await fetch(`${getApiBaseUrl()}/my/profile`, {
|
|
headers: { Accept: 'application/json', Authorization: `Bearer ${token}` },
|
|
cache: 'no-store',
|
|
}).catch(() => null);
|
|
if (!res || !res.ok) return null;
|
|
return (await res.json()) as MemberProfile;
|
|
}
|
|
|
|
export default async function MyPage() {
|
|
const token = await getMemberToken();
|
|
if (!token) {
|
|
return (
|
|
<div className="max-w-md mx-auto mt-12 p-6 rounded-lg border border-yellow-200 bg-yellow-50">
|
|
<h1 className="text-lg font-semibold text-yellow-800">Member portal</h1>
|
|
<p className="text-sm text-yellow-700">
|
|
No member session. Complete onboarding via the link a group admin sent you.
|
|
</p>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
const profile = await fetchProfile(token);
|
|
if (!profile) {
|
|
return (
|
|
<div className="max-w-md mx-auto mt-12 p-6 rounded-lg border border-red-200 bg-red-50">
|
|
<h1 className="text-lg font-semibold text-red-800">Couldn't load your account</h1>
|
|
<p className="text-sm text-red-700">
|
|
Your session may have expired. Please complete onboarding again.
|
|
</p>
|
|
<form method="POST" action="/api/my/logout" className="mt-4">
|
|
<button type="submit" className="text-sm text-blue-600 underline">
|
|
Sign out
|
|
</button>
|
|
</form>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="max-w-2xl mx-auto mt-12 p-6 rounded-lg border border-gray-200 bg-white">
|
|
<h1 className="text-xl font-semibold mb-4">Your account</h1>
|
|
<dl className="text-sm space-y-1 mb-6">
|
|
<div>
|
|
<dt className="inline font-medium">Display name: </dt>
|
|
<dd className="inline">{profile.displayName ?? '—'}</dd>
|
|
</div>
|
|
<div>
|
|
<dt className="inline font-medium">JID: </dt>
|
|
<dd className="inline">{profile.jid}</dd>
|
|
</div>
|
|
<div>
|
|
<dt className="inline font-medium">Joined: </dt>
|
|
<dd className="inline">{new Date(profile.createdAt).toLocaleDateString()}</dd>
|
|
</div>
|
|
</dl>
|
|
<div className="flex flex-col gap-2 text-sm">
|
|
<Link href="/my/groups" className="text-blue-600 underline">Manage your groups →</Link>
|
|
<Link href="/my/settings" className="text-blue-600 underline">Privacy & account settings →</Link>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|