145 lines
4.7 KiB
TypeScript
145 lines
4.7 KiB
TypeScript
import Breadcrumbs from "@/components/ui/breadcrumbs";
|
|
import { Button } from "@/components/ui/button";
|
|
import Avatar from "@/feature/Avatar";
|
|
import { useUsers } from "@/store/admin/users";
|
|
import { useEffect, type FC } from "react";
|
|
import { Link, useParams } from "react-router";
|
|
|
|
const InfoCard = ({
|
|
title,
|
|
children,
|
|
}: {
|
|
title: string;
|
|
children: React.ReactNode;
|
|
}) => (
|
|
<div className="border dark:border-gray-800 border-gray-300 rounded mb-4">
|
|
<div className="p-4 border-b dark:border-gray-800 border-gray-300">
|
|
<h2 className="text-gray-800 dark:text-gray-200 font-semibold text-lg">
|
|
{title}
|
|
</h2>
|
|
</div>
|
|
<div className="p-4">{children}</div>
|
|
</div>
|
|
);
|
|
|
|
const AdminViewUserPage: FC = () => {
|
|
const { userId } = useParams();
|
|
const user = useUsers((state) => state.current);
|
|
const userPermissions = useUsers((s) => s.userPermissions);
|
|
// const loading = useApiServices((state) => state.fetchingApiService);
|
|
|
|
const loadUser = useUsers((state) => state.fetchUser);
|
|
|
|
useEffect(() => {
|
|
if (typeof userId === "string") loadUser(userId);
|
|
}, [loadUser, userId]);
|
|
|
|
if (!user) {
|
|
return (
|
|
<div className="p-4 flex items-center justify-center h-[60vh]">
|
|
<div className="text-center">
|
|
<div className="animate-spin rounded-full h-8 w-8 border-2 border-blue-500 border-t-transparent mx-auto mb-3" />
|
|
<p className="text-gray-600 dark:text-gray-400">Loading User...</p>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="dark:text-gray-200 text-gray-800 p-4">
|
|
<Breadcrumbs
|
|
items={[
|
|
{ href: "/admin", label: "Admin" },
|
|
{ href: "/admin/users", label: "Users" },
|
|
{ label: "View User" },
|
|
]}
|
|
/>
|
|
|
|
<div className="sm:p-4 pt-4">
|
|
{/* 📋 Main Details */}
|
|
<InfoCard title="Personal Info">
|
|
<div className="flex flex-col gap-4 text-sm">
|
|
<div className="flex flex-col gap-4">
|
|
<span className="font-medium text-gray-900 dark:text-white">
|
|
Avatar:
|
|
</span>
|
|
<Avatar
|
|
avatarId={user.profile_picture ?? undefined}
|
|
className="w-16 h-16"
|
|
iconSize={28}
|
|
/>
|
|
</div>
|
|
<div>
|
|
<span className="font-medium text-gray-900 dark:text-white">
|
|
Full Name:
|
|
</span>{" "}
|
|
{user.full_name}
|
|
</div>
|
|
<div>
|
|
<span className="font-medium text-gray-900 dark:text-white">
|
|
Email:
|
|
</span>{" "}
|
|
{user.email}
|
|
</div>
|
|
<div>
|
|
<span className="font-medium text-gray-900 dark:text-white">
|
|
Phone Number:
|
|
</span>{" "}
|
|
{user.phone_number || "-"}{" "}
|
|
</div>
|
|
<div>
|
|
<span className="font-medium text-gray-900 dark:text-white">
|
|
Is Admin:
|
|
</span>{" "}
|
|
<span
|
|
className={`font-semibold px-2 py-1 rounded ${
|
|
user.is_admin
|
|
? "bg-green-200 text-green-800 dark:bg-green-700/20 dark:text-green-300"
|
|
: "bg-red-200 text-red-800 dark:bg-red-700/20 dark:text-red-300"
|
|
}`}
|
|
>
|
|
{user.is_admin ? "Yes" : "No"}
|
|
</span>
|
|
</div>
|
|
<div>
|
|
<span className="font-medium text-gray-900 dark:text-white">
|
|
Created At:
|
|
</span>{" "}
|
|
{new Date(user.created_at).toLocaleString()}
|
|
</div>
|
|
<div>
|
|
<span className="font-medium text-gray-900 dark:text-white">
|
|
Last Login At:
|
|
</span>{" "}
|
|
{user.last_login
|
|
? new Date(user.last_login).toLocaleString()
|
|
: "never"}
|
|
</div>
|
|
</div>
|
|
</InfoCard>
|
|
|
|
<InfoCard title="Roles & Permissions">
|
|
<pre>{JSON.stringify(userPermissions, null, 2)}</pre>
|
|
</InfoCard>
|
|
|
|
{/* 🚀 Actions */}
|
|
<div className="flex flex-wrap gap-4 mt-6 justify-between items-center">
|
|
<Link to="/admin/users">
|
|
<Button variant="outlined">Back</Button>
|
|
</Link>
|
|
<div className="flex flex-row items-center gap-4">
|
|
<Link
|
|
to={`/admin/users/edit/${userId}`}
|
|
className="hover:underline hover:text-gray-600 dark:hover:text-gray-300 transition-colors"
|
|
>
|
|
<Button variant="contained">Edit</Button>
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default AdminViewUserPage;
|