Files
usda-vision/management-dashboard-web-app/src/components/DashboardHome.tsx

186 lines
9.5 KiB
TypeScript
Executable File
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { User } from '../lib/supabase'
interface DashboardHomeProps {
user: User
}
export function DashboardHome({ user }: DashboardHomeProps) {
const getRoleBadgeColor = (role: string) => {
switch (role) {
case 'admin':
return 'bg-error-50 text-error-600 dark:bg-error-500/15 dark:text-error-500'
case 'conductor':
return 'bg-brand-50 text-brand-500 dark:bg-brand-500/15 dark:text-brand-400'
case 'analyst':
return 'bg-success-50 text-success-600 dark:bg-success-500/15 dark:text-success-500'
case 'data recorder':
return 'bg-theme-purple-500/10 text-theme-purple-500'
default:
return 'bg-gray-100 text-gray-700 dark:bg-white/5 dark:text-white/80'
}
}
const getPermissionsByRole = (role: string) => {
switch (role) {
case 'admin':
return ['Full system access', 'User management', 'All modules', 'System configuration']
case 'conductor':
return ['Experiment management', 'Data collection', 'Analytics access', 'Data entry']
case 'analyst':
return ['Data analysis', 'Report generation', 'Read-only access', 'Analytics dashboard']
case 'data recorder':
return ['Data entry', 'Record management', 'Basic reporting', 'Data validation']
default:
return []
}
}
return (
<div className="grid grid-cols-12 gap-4 md:gap-6">
{/* Welcome Section */}
<div className="col-span-12 mb-6">
<h1 className="text-title-md font-bold text-gray-800 dark:text-white/90">Dashboard</h1>
<p className="mt-2 text-gray-500 dark:text-gray-400">Welcome to the Pecan Experiments Dashboard</p>
</div>
{/* User Information Card */}
<div className="col-span-12 xl:col-span-8">
<div className="rounded-2xl border border-gray-200 bg-white p-5 dark:border-gray-800 dark:bg-white/[0.03] md:p-6">
<div className="flex items-center justify-center w-12 h-12 bg-gray-100 rounded-xl dark:bg-gray-800 mb-5">
<svg className="text-gray-800 size-6 dark:text-white/90" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" />
</svg>
</div>
<h3 className="text-lg font-bold text-gray-800 dark:text-white/90 mb-2">
User Information
</h3>
<p className="text-sm text-gray-500 dark:text-gray-400 mb-6">
Your account details and role permissions.
</p>
<div className="space-y-4">
<div className="flex items-center justify-between py-3 border-b border-gray-200 dark:border-gray-800">
<span className="text-sm font-medium text-gray-500 dark:text-gray-400">Email</span>
<span className="text-sm text-gray-800 dark:text-white/90">{user.email}</span>
</div>
<div className="flex items-center justify-between py-3 border-b border-gray-200 dark:border-gray-800">
<span className="text-sm font-medium text-gray-500 dark:text-gray-400">Roles</span>
<div className="flex flex-wrap gap-1">
{user.roles.map((role) => (
<span
key={role}
className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${getRoleBadgeColor(role)}`}
>
{role.charAt(0).toUpperCase() + role.slice(1)}
</span>
))}
</div>
</div>
<div className="flex items-center justify-between py-3 border-b border-gray-200 dark:border-gray-800">
<span className="text-sm font-medium text-gray-500 dark:text-gray-400">Status</span>
<span className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${user.status === 'active'
? 'bg-success-50 text-success-600 dark:bg-success-500/15 dark:text-success-500'
: 'bg-error-50 text-error-600 dark:bg-error-500/15 dark:text-error-500'
}`}>
{user.status.charAt(0).toUpperCase() + user.status.slice(1)}
</span>
</div>
<div className="flex items-center justify-between py-3 border-b border-gray-200 dark:border-gray-800">
<span className="text-sm font-medium text-gray-500 dark:text-gray-400">User ID</span>
<span className="text-sm text-gray-800 dark:text-white/90 font-mono">{user.id}</span>
</div>
<div className="flex items-center justify-between py-3">
<span className="text-sm font-medium text-gray-500 dark:text-gray-400">Member since</span>
<span className="text-sm text-gray-800 dark:text-white/90">
{new Date(user.created_at).toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric'
})}
</span>
</div>
</div>
</div>
</div>
{/* Role Permissions */}
<div className="col-span-12 xl:col-span-4">
<div className="rounded-2xl border border-gray-200 bg-white p-5 dark:border-gray-800 dark:bg-white/[0.03] md:p-6">
<div className="flex items-center justify-center w-12 h-12 bg-gray-100 rounded-xl dark:bg-gray-800 mb-5">
<svg className="text-gray-800 size-6 dark:text-white/90" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z" />
</svg>
</div>
<h3 className="text-lg font-bold text-gray-800 dark:text-white/90 mb-2">
Role Permissions
</h3>
<p className="text-sm text-gray-500 dark:text-gray-400 mb-6">
Your access levels and capabilities.
</p>
<div className="space-y-4">
{user.roles.map((role) => (
<div key={role} className="border border-gray-200 dark:border-gray-800 rounded-lg p-4">
<div className="flex items-center mb-3">
<span className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${getRoleBadgeColor(role)}`}>
{role.charAt(0).toUpperCase() + role.slice(1)}
</span>
</div>
<ul className="space-y-2">
{getPermissionsByRole(role).map((permission, index) => (
<li key={index} className="flex items-center text-sm text-gray-600 dark:text-gray-400">
<span className="text-success-500 mr-2"></span>
{permission}
</li>
))}
</ul>
</div>
))}
</div>
</div>
</div>
{/* Quick Actions */}
{user.roles.includes('admin') && (
<div className="col-span-12">
<div className="rounded-2xl border border-gray-200 bg-white p-5 dark:border-gray-800 dark:bg-white/[0.03] md:p-6">
<div className="flex items-center justify-center w-12 h-12 bg-gray-100 rounded-xl dark:bg-gray-800 mb-5">
<svg className="text-gray-800 size-6 dark:text-white/90" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 10V3L4 14h7v7l9-11h-7z" />
</svg>
</div>
<h3 className="text-lg font-bold text-gray-800 dark:text-white/90 mb-2">
Quick Actions
</h3>
<p className="text-sm text-gray-500 dark:text-gray-400 mb-6">
Administrative shortcuts and tools.
</p>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
<button className="inline-flex items-center justify-center px-4 py-2.5 border border-transparent text-sm font-medium rounded-lg text-white bg-brand-500 hover:bg-brand-600 focus:outline-none focus:ring-3 focus:ring-brand-500/10 transition-colors">
👥 Manage Users
</button>
<button className="inline-flex items-center justify-center px-4 py-2.5 border border-gray-200 text-sm font-medium rounded-lg text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-3 focus:ring-brand-500/10 dark:border-gray-800 dark:bg-white/[0.03] dark:text-gray-300 dark:hover:bg-white/5 transition-colors">
🧪 View Experiments
</button>
<button className="inline-flex items-center justify-center px-4 py-2.5 border border-gray-200 text-sm font-medium rounded-lg text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-3 focus:ring-brand-500/10 dark:border-gray-800 dark:bg-white/[0.03] dark:text-gray-300 dark:hover:bg-white/5 transition-colors">
📊 Analytics
</button>
<button className="inline-flex items-center justify-center px-4 py-2.5 border border-gray-200 text-sm font-medium rounded-lg text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-3 focus:ring-brand-500/10 dark:border-gray-800 dark:bg-white/[0.03] dark:text-gray-300 dark:hover:bg-white/5 transition-colors">
Settings
</button>
</div>
</div>
</div>
)}
</div>
)
}