From fcd0b78f3cfe49c4c12f67e0647fbb4c65871bf6 Mon Sep 17 00:00:00 2001 From: Johngreen Date: Thu, 12 Feb 2026 14:41:58 +0900 Subject: [PATCH] feat: visually distinguish digital-twin linked tenants - Add has_digital_twin flag to tenant API response - Show cloud badge on tenant card for linked tenants - Hide sync/import buttons for tenants without mapping - Add .tenant-badge-dt CSS for the badge --- dashboard/app/[tenant]/page.tsx | 25 ++++++++++++++++--------- dashboard/app/globals.css | 17 +++++++++++++++++ dashboard/app/page.tsx | 6 ++++++ dashboard/lib/types.ts | 1 + src/tenant/manager.py | 2 ++ 5 files changed, 42 insertions(+), 9 deletions(-) diff --git a/dashboard/app/[tenant]/page.tsx b/dashboard/app/[tenant]/page.tsx index cab3d96..d13a5e9 100644 --- a/dashboard/app/[tenant]/page.tsx +++ b/dashboard/app/[tenant]/page.tsx @@ -2,7 +2,7 @@ import { useState, useCallback, useMemo } from 'react'; import { useParams, useRouter } from 'next/navigation'; -import { useMachines } from '@/lib/hooks'; +import { useMachines, useTenants } from '@/lib/hooks'; import { useToast } from '@/lib/toast-context'; import { api } from '@/lib/api'; import { MachineList } from '@/components/MachineList'; @@ -36,7 +36,10 @@ export default function TenantDashboard() { const router = useRouter(); const tenantId = params?.tenant as string; const { machines, isLoading, error, mutate } = useMachines(tenantId); + const { tenants } = useTenants(); const { addToast } = useToast(); + const currentTenant = tenants.find(t => t.id === tenantId); + const hasDigitalTwin = currentTenant?.has_digital_twin ?? false; const [showModal, setShowModal] = useState(false); const [form, setForm] = useState(INITIAL_FORM); @@ -270,14 +273,18 @@ export default function TenantDashboard() { 설비 관리
- - + {hasDigitalTwin && ( + <> + + + + )} ))}
diff --git a/dashboard/lib/types.ts b/dashboard/lib/types.ts index 832b5be..1b88b5b 100644 --- a/dashboard/lib/types.ts +++ b/dashboard/lib/types.ts @@ -12,6 +12,7 @@ export interface Tenant { name: string; industry_type: string; is_active: boolean; + has_digital_twin: boolean; created_at: string | null; } diff --git a/src/tenant/manager.py b/src/tenant/manager.py index 0cb3ef5..bd0ef77 100644 --- a/src/tenant/manager.py +++ b/src/tenant/manager.py @@ -44,6 +44,7 @@ async def get_tenant(db: AsyncSession, tenant_id: str) -> Dict: "name": str(tenant.name), "industry_type": str(tenant.industry_type), "is_active": bool(tenant.is_active), + "has_digital_twin": bool(tenant.digital_twin_company_id), "created_at": _format_timestamp(tenant.created_at), } @@ -99,6 +100,7 @@ async def list_tenants(db: AsyncSession) -> List[Dict]: "name": str(t.name), "industry_type": str(t.industry_type), "is_active": bool(t.is_active), + "has_digital_twin": bool(t.digital_twin_company_id), "created_at": _format_timestamp(t.created_at), } for t in tenants