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>
52 lines
1.4 KiB
TypeScript
52 lines
1.4 KiB
TypeScript
'use client';
|
|
|
|
import { createContext, useContext, useState, useEffect, ReactNode } from 'react';
|
|
import { useParams } from 'next/navigation';
|
|
|
|
interface TenantContextType {
|
|
tenantId: string | null;
|
|
tenantName: string | null;
|
|
setTenant: (id: string, name: string) => void;
|
|
}
|
|
|
|
const TenantContext = createContext<TenantContextType | undefined>(undefined);
|
|
|
|
export function TenantProvider({ children }: { children: ReactNode }) {
|
|
const params = useParams();
|
|
const [tenantId, setTenantId] = useState<string | null>(null);
|
|
const [tenantName, setTenantName] = useState<string | null>(null);
|
|
|
|
useEffect(() => {
|
|
const tenant = params?.tenant as string | undefined;
|
|
if (tenant) {
|
|
setTenantId(tenant);
|
|
}
|
|
}, [params]);
|
|
|
|
const setTenant = (id: string, name: string) => {
|
|
setTenantId(id);
|
|
setTenantName(name);
|
|
};
|
|
|
|
return (
|
|
<TenantContext.Provider value={{ tenantId, tenantName, setTenant }}>
|
|
{children}
|
|
</TenantContext.Provider>
|
|
);
|
|
}
|
|
|
|
export function useTenant() {
|
|
const context = useContext(TenantContext);
|
|
if (context === undefined) {
|
|
throw new Error('useTenant must be used within a TenantProvider');
|
|
}
|
|
return context;
|
|
}
|
|
|
|
export function getTenantFromPath(): string | null {
|
|
if (typeof window === 'undefined') return null;
|
|
const path = window.location.pathname;
|
|
const match = path.match(/^\/([a-z0-9][a-z0-9-]{1,30}[a-z0-9])(?:\/|$)/);
|
|
return match ? match[1] : null;
|
|
}
|