phase 1-6 implemented
This commit is contained in:
1 parent
22c274bb83
commit
2c4927478a
73 files changed
+9702
-2354
No files matched your search
@@ -1,104 +1,135 @@
|
||||
|
||||
import { getDatabase } from "@/lib/database";
|
||||
import { Recommendations } from "@/components/users/Recommendations";
|
||||
import { notFound } from "next/navigation";
|
||||
|
||||
interface PageProps {
|
||||
params: Promise<{
|
||||
id: string;
|
||||
}>;
|
||||
params: Promise<{
|
||||
id: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
export default async function UserProfilePage({ params }: PageProps) {
|
||||
const { id } = await params;
|
||||
const db = await getDatabase();
|
||||
const user = await db.getUserById(id);
|
||||
const { id } = await params;
|
||||
const db = await getDatabase();
|
||||
const user = await db.getUserById(id);
|
||||
|
||||
if (!user) {
|
||||
notFound();
|
||||
}
|
||||
if (!user) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
const client = await db.getClientByUserId(user.id);
|
||||
const fitnessProfile = await db.getFitnessProfileByUserId(user.id);
|
||||
const client = await db.getClientByUserId(user.id);
|
||||
const fitnessProfile = await db.getFitnessProfileByUserId(user.id);
|
||||
|
||||
return (
|
||||
<div className="space-y-8">
|
||||
<div className="flex justify-between items-center">
|
||||
<h1 className="text-3xl font-bold">
|
||||
{user.firstName} {user.lastName}
|
||||
</h1>
|
||||
<span className="px-3 py-1 bg-gray-100 rounded-full text-sm font-medium capitalize">
|
||||
{user.role}
|
||||
</span>
|
||||
</div>
|
||||
return (
|
||||
<div className="space-y-8">
|
||||
<div className="flex justify-between items-center">
|
||||
<h1 className="text-3xl font-bold">
|
||||
{user.firstName} {user.lastName}
|
||||
</h1>
|
||||
<span className="px-3 py-1 bg-gray-100 rounded-full text-sm font-medium capitalize">
|
||||
{user.role}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
{/* Basic Info */}
|
||||
<div className="bg-white p-6 rounded-lg shadow">
|
||||
<h2 className="text-xl font-semibold mb-4">Contact Information</h2>
|
||||
<div className="space-y-2">
|
||||
<p><span className="font-medium">Email:</span> {user.email}</p>
|
||||
<p><span className="font-medium">Phone:</span> {user.phone || "N/A"}</p>
|
||||
<p><span className="font-medium">Joined:</span> {user.createdAt.toLocaleDateString()}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Client Info */}
|
||||
{client && (
|
||||
<div className="bg-white p-6 rounded-lg shadow">
|
||||
<h2 className="text-xl font-semibold mb-4">Membership Details</h2>
|
||||
<div className="space-y-2">
|
||||
<p><span className="font-medium">Type:</span> {client.membershipType}</p>
|
||||
<p><span className="font-medium">Status:</span> {client.membershipStatus}</p>
|
||||
<p><span className="font-medium">Member Since:</span> {client.joinDate.toLocaleDateString()}</p>
|
||||
<p><span className="font-medium">Last Visit:</span> {client.lastVisit?.toLocaleDateString() || "Never"}</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Fitness Profile */}
|
||||
<div className="bg-white p-6 rounded-lg shadow">
|
||||
<h2 className="text-xl font-semibold mb-4">Fitness Profile</h2>
|
||||
{fitnessProfile ? (
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
<div>
|
||||
<h3 className="font-medium mb-2 text-gray-700">Physical Stats</h3>
|
||||
<p>Height: {fitnessProfile.height} cm</p>
|
||||
<p>Weight: {fitnessProfile.weight} kg</p>
|
||||
<p>Age: {fitnessProfile.age}</p>
|
||||
<p>Gender: {fitnessProfile.gender}</p>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-medium mb-2 text-gray-700">Health & Habits</h3>
|
||||
<p>Activity Level: {fitnessProfile.activityLevel.replace('_', ' ')}</p>
|
||||
<p>Diet: {fitnessProfile.dietHabits || "N/A"}</p>
|
||||
<p>Exercise: {fitnessProfile.exerciseHabits || "N/A"}</p>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-medium mb-2 text-gray-700">Medical</h3>
|
||||
<p>Conditions: {fitnessProfile.medicalConditions || "None"}</p>
|
||||
<p>Allergies: {fitnessProfile.allergies || "None"}</p>
|
||||
<p>Injuries: {fitnessProfile.injuries || "None"}</p>
|
||||
</div>
|
||||
<div className="col-span-full mt-4">
|
||||
<h3 className="font-medium mb-2 text-gray-700">Goals</h3>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{fitnessProfile.fitnessGoals.map((goal, i) => (
|
||||
<span key={i} className="px-2 py-1 bg-blue-50 text-blue-700 rounded text-sm">
|
||||
{goal.replace('_', ' ')}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<p className="text-gray-500 italic">No fitness profile created yet.</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Recommendations Component */}
|
||||
<Recommendations userId={user.id} />
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
{/* Basic Info */}
|
||||
<div className="bg-white p-6 rounded-lg shadow">
|
||||
<h2 className="text-xl font-semibold mb-4">Contact Information</h2>
|
||||
<div className="space-y-2">
|
||||
<p>
|
||||
<span className="font-medium">Email:</span> {user.email}
|
||||
</p>
|
||||
<p>
|
||||
<span className="font-medium">Phone:</span> {user.phone || "N/A"}
|
||||
</p>
|
||||
<p>
|
||||
<span className="font-medium">Joined:</span>{" "}
|
||||
{user.createdAt.toLocaleDateString()}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
{/* Client Info */}
|
||||
{client && (
|
||||
<div className="bg-white p-6 rounded-lg shadow">
|
||||
<h2 className="text-xl font-semibold mb-4">Membership Details</h2>
|
||||
<div className="space-y-2">
|
||||
<p>
|
||||
<span className="font-medium">Type:</span>{" "}
|
||||
{client.membershipType}
|
||||
</p>
|
||||
<p>
|
||||
<span className="font-medium">Status:</span>{" "}
|
||||
{client.membershipStatus}
|
||||
</p>
|
||||
<p>
|
||||
<span className="font-medium">Member Since:</span>{" "}
|
||||
{client.joinDate.toLocaleDateString()}
|
||||
</p>
|
||||
<p>
|
||||
<span className="font-medium">Last Visit:</span>{" "}
|
||||
{client.lastVisit?.toLocaleDateString() || "Never"}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Fitness Profile */}
|
||||
<div className="bg-white p-6 rounded-lg shadow">
|
||||
<h2 className="text-xl font-semibold mb-4">Fitness Profile</h2>
|
||||
{fitnessProfile ? (
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
<div>
|
||||
<h3 className="font-medium mb-2 text-gray-700">Physical Stats</h3>
|
||||
<p>Height: {fitnessProfile.height} cm</p>
|
||||
<p>Weight: {fitnessProfile.weight} kg</p>
|
||||
<p>Age: {fitnessProfile.age}</p>
|
||||
<p>Gender: {fitnessProfile.gender}</p>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-medium mb-2 text-gray-700">
|
||||
Health & Habits
|
||||
</h3>
|
||||
<p>
|
||||
Activity Level:{" "}
|
||||
{fitnessProfile.activityLevel?.replace("_", " ") || "N/A"}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-medium mb-2 text-gray-700">Medical</h3>
|
||||
<p>Conditions: {fitnessProfile.medicalConditions || "None"}</p>
|
||||
<p>Allergies: {fitnessProfile.allergies || "None"}</p>
|
||||
<p>Injuries: {fitnessProfile.injuries || "None"}</p>
|
||||
</div>
|
||||
<div className="col-span-full mt-4">
|
||||
<h3 className="font-medium mb-2 text-gray-700">Goals</h3>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{fitnessProfile.fitnessGoals &&
|
||||
fitnessProfile.fitnessGoals.length > 0 ? (
|
||||
fitnessProfile.fitnessGoals.map((goal, i) => (
|
||||
<span
|
||||
key={i}
|
||||
className="px-2 py-1 bg-blue-50 text-blue-700 rounded text-sm"
|
||||
>
|
||||
{goal.replace("_", " ")}
|
||||
</span>
|
||||
))
|
||||
) : (
|
||||
<span className="text-gray-500 italic">No goals set</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<p className="text-gray-500 italic">
|
||||
No fitness profile created yet.
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Recommendations Component */}
|
||||
<Recommendations userId={user.id} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user