Multi-tenant factory inspection system (SpiFox, Enkid, Alpet): - FastAPI backend with JWT auth, PostgreSQL (asyncpg) - Next.js 16 frontend with App Router, SWR data fetching - Machines CRUD with equipment parts management - Part lifecycle tracking (hours/count/date) with counters - Partial unique index for soft-delete support - 24 pytest tests passing, E2E verified Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
61 lines
2.0 KiB
TypeScript
61 lines
2.0 KiB
TypeScript
'use client';
|
|
|
|
import { useRouter } from 'next/navigation';
|
|
import { useAuth } from '@/lib/auth-context';
|
|
import { useTenants } from '@/lib/hooks';
|
|
import { Card } from '@/components/Card';
|
|
|
|
export default function HomePage() {
|
|
const { user, logout } = useAuth();
|
|
const { tenants, isLoading } = useTenants();
|
|
const router = useRouter();
|
|
|
|
const handleTenantSelect = (tenantId: string) => {
|
|
router.push(`/${tenantId}`);
|
|
};
|
|
|
|
return (
|
|
<div className="home-container">
|
|
<div className="home-header">
|
|
<div className="home-title">
|
|
<span className="material-symbols-outlined">precision_manufacturing</span>
|
|
<h1>FactoryOps v2</h1>
|
|
</div>
|
|
<div className="home-user">
|
|
<span>{user?.name} ({user?.role})</span>
|
|
<button onClick={logout} className="btn-outline">
|
|
<span className="material-symbols-outlined">logout</span>
|
|
로그아웃
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="home-content">
|
|
<Card icon="business" title="고객사 선택">
|
|
{isLoading ? (
|
|
<div className="loading">
|
|
<span className="material-symbols-outlined spinning">progress_activity</span>
|
|
</div>
|
|
) : tenants.length === 0 ? (
|
|
<p className="empty-message">접근 가능한 고객사가 없습니다.</p>
|
|
) : (
|
|
<div className="tenant-grid">
|
|
{tenants.map((tenant) => (
|
|
<button
|
|
key={tenant.id}
|
|
className="tenant-card"
|
|
onClick={() => handleTenantSelect(tenant.id)}
|
|
>
|
|
<span className="material-symbols-outlined tenant-icon">factory</span>
|
|
<span className="tenant-name">{tenant.name}</span>
|
|
<span className="tenant-id">{tenant.id}</span>
|
|
</button>
|
|
))}
|
|
</div>
|
|
)}
|
|
</Card>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|