'use client'; import React, { useState, useEffect } from 'react'; import Link from 'next/link'; import { formatCurrency, formatCompactCurrency } from '@/lib/utils'; import { ArrowLeft, GitMerge, Loader2, RefreshCcw, ArrowRight, Building2, FileText, Search, AlertCircle, } from 'lucide-react'; interface Entity { id: string; name: string; code: string; type: string; defaultCurrency: string; status: string; } interface ICTransaction { id: string; entryNumber: string; entryDate: string; description: string; status: string; totalAmount: number; entities: Array<{ id: string; name: string; code: string }>; lineCount: number; lines: Array<{ id: string; entityId: string | null; entityName: string | null; entityCode: string | null; accountCode: string; accountName: string; debit: number; credit: number; description: string | null; }>; } interface ICPosition { fromEntity: { id: string; name: string; code: string }; toEntity: { id: string; name: string; code: string }; amount: number; } interface Summary { totalEntities: number; totalIntercompanyTransactions: number; totalIntercompanyValue: number; outstandingPositions: number; totalOutstandingAmount: number; } export default function IntercompanyPage() { const [entities, setEntities] = useState([]); const [transactions, setTransactions] = useState([]); const [positions, setPositions] = useState([]); const [summary, setSummary] = useState(null); const [loading, setLoading] = useState(true); const [activeTab, setActiveTab] = useState<'positions' | 'transactions'>('positions'); const [search, setSearch] = useState(''); const [expandedTxn, setExpandedTxn] = useState(null); useEffect(() => { fetchData(); }, []); const fetchData = async () => { setLoading(true); try { const res = await fetch('/api/intercompany'); const data = await res.json(); setEntities(data.entities || []); setTransactions(data.transactions || []); setPositions(data.positions || []); setSummary(data.summary || null); } catch (err) { console.error('Failed to fetch intercompany data:', err); } finally { setLoading(false); } }; const statusColors: Record = { DRAFT: 'bg-[#1A1A1F] text-[#8B8B9E]', PENDING: 'bg-amber-900/25 text-amber-700', POSTED: 'bg-emerald-900/25 text-emerald-700', APPROVED: 'bg-blue-900/25 text-blue-700', REVERSED: 'bg-red-900/25 text-red-600', }; const filteredTransactions = transactions.filter((txn) => { if (!search.trim()) return true; const q = search.toLowerCase(); return ( txn.entryNumber.toLowerCase().includes(q) || txn.description?.toLowerCase().includes(q) || txn.entities.some((e) => e.name.toLowerCase().includes(q) || e.code.toLowerCase().includes(q)) ); }); if (loading) { return (
); } return (
{/* Header */}

Intercompany Transactions

Track and manage transactions between entities for elimination

{/* Summary Cards */} {summary && (

Entities

{summary.totalEntities}

IC Transactions

{summary.totalIntercompanyTransactions}

Total IC Value

{formatCompactCurrency(summary.totalIntercompanyValue)}

Open Positions

{summary.outstandingPositions}

Outstanding Amount

{formatCompactCurrency(summary.totalOutstandingAmount)}

)} {/* Tabs */}
{[ { id: 'positions' as const, label: 'IC Positions', icon: }, { id: 'transactions' as const, label: 'IC Journal Entries', icon: }, ].map((tab) => ( ))}
{activeTab === 'transactions' && (
setSearch(e.target.value)} className="bg-transparent text-sm outline-none w-48" />
)}
{/* Positions Tab */} {activeTab === 'positions' && (
{positions.length === 0 ? (

No intercompany positions found

Positions appear when journal entries span multiple entities

) : (
{positions.map((pos, idx) => (
{/* From Entity */}

{pos.fromEntity.name}

{pos.fromEntity.code}

{/* Arrow + Amount */}

{formatCurrency(pos.amount)}

Owes

{/* To Entity */}

{pos.toEntity.name}

{pos.toEntity.code}

))}
)}
)} {/* Transactions Tab */} {activeTab === 'transactions' && (
{filteredTransactions.length === 0 ? (

No intercompany journal entries found

) : (
{filteredTransactions.map((txn) => (
{/* Expanded Lines */} {expandedTxn === txn.id && (
{txn.lines.map((line) => ( ))}
Entity Account Description Debit Credit
{line.entityCode || '—'} {line.accountCode} {line.accountName} {line.description || '—'} {line.debit > 0 ? formatCurrency(line.debit) : ''} {line.credit > 0 ? formatCurrency(line.credit) : ''}
)}
))}
)}
)}
{/* Entity Overview */}

Entity Structure

{entities.length} entities in organization

{entities.map((entity) => (

{entity.name}

{entity.code} {entity.type} {entity.defaultCurrency}
))} {entities.length === 0 && (

No entities configured

)}
); }