import React, { useState, useEffect } from 'react'; import Toast from '../Components/Toast'; import { ChevronLeft, Edit2, TrendingUp, Calendar, MapPin, Building, Wallet, FileText, Users, Eye, Percent, Clock, Shield, CheckCircle2, AlertCircle, X, ArrowRight, Download } from 'lucide-react'; export default function InvestorView({ id }) { const isReceptionist = window.__APP_DATA__?.role === 'receptionist'; const basePath = isReceptionist ? '/receptionist/investors' : '/owner/investors'; const [investor, setInvestor] = useState(null); const [payouts, setPayouts] = useState([]); const [roiStatus, setRoiStatus] = useState([]); const [loading, setLoading] = useState(true); const [toast, setToast] = useState(null); const [activeTab, setActiveTab] = useState('Overview'); const [isPreviewOpen, setIsPreviewOpen] = useState(false); const [settleModal, setSettleModal] = useState({ isOpen: false, month: '', amount: '', originalAmount: '', baseAmount: 0, carryOver: 0, date: new Date().toISOString().split('T')[0], method: 'Bank Transfer', remarks: '' }); useEffect(() => { fetchInvestor(); fetchPayouts(); fetchROIStatus(); }, [id]); const fetchPayouts = async () => { try { const response = await fetch(`/api/investors/${id}/payouts`); const data = await response.json(); setPayouts(data); } catch (error) { console.error('Error fetching payouts:', error); } }; const fetchROIStatus = async () => { try { const response = await fetch(`/api/investors/${id}/roi-status`); const data = await response.json(); setRoiStatus(data); } catch (error) { console.error('Error fetching ROI status:', error); } }; const fetchInvestor = async () => { try { const response = await fetch(`/api/investors/${id}`); const data = await response.json(); setInvestor(data); } catch (error) { console.error('Error fetching investor:', error); setToast({ message: 'Failed to load investor details.', type: 'error' }); } finally { setLoading(false); } }; const handleSettleROI = async (e) => { e.preventDefault(); // Validation: Remarks mandatory if amount is adjusted if (parseFloat(settleModal.amount) !== parseFloat(settleModal.originalAmount) && !settleModal.remarks?.trim()) { setToast({ message: 'Remarks field is mandatory when adjusting the payment amount.', type: 'error' }); return; } const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content'); try { const response = await fetch(`/api/investors/${id}/settle-roi`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrfToken }, body: JSON.stringify({ payout_month: settleModal.month, amount: settleModal.amount, payout_date: settleModal.date, payment_method: settleModal.method, remarks: settleModal.remarks }) }); if (response.ok) { setToast({ message: 'ROI settled successfully!', type: 'success' }); setSettleModal({ isOpen: false, month: '', amount: '', originalAmount: '', date: new Date().toISOString().split('T')[0], method: 'Bank Transfer', remarks: '' }); fetchPayouts(); fetchROIStatus(); } else { setToast({ message: 'Settlement failed.', type: 'error' }); } } catch (error) { setToast({ message: 'Error during settlement.', type: 'error' }); } }; if (loading) return (
); if (!investor) return (

Investor Not Found

); const initials = investor.name?.split(' ').map(n => n[0]).join('').toUpperCase() || 'INV'; const totalPayouts = payouts.reduce((acc, p) => acc + parseFloat(p.amount || 0), 0); return ( <> {toast && setToast(null)} />}
{/* Navigation & Actions */}
{/* Profile Identity Card */}
{initials}

{investor.name}

Active Investor
{investor.applicable_to_all_branches ? "Global Portfolio" : `${investor.branches?.length || 0} Branches`}
Since {new Date(investor.investment_date).toLocaleDateString()}

Total Capital

{parseFloat(investor.investment_amount).toLocaleString()} AED

ROI Yielded

{totalPayouts.toLocaleString()} AED

{/* Tabs & Content */}
{['Overview', 'ROI Payouts', 'Monthly Status'].map(tab => ( ))}
{activeTab === 'Overview' && (

Investment Terms

{investor.roi_type === 'Percentage' ? 'ROI Interest' : 'Fixed ROI'}

{investor.roi_value} {investor.roi_type === 'Percentage' ? '%' : ' AED'}

PER {investor.roi_period || 'MONTH'}

Strategic Allocation

{investor.applicable_to_all_branches ? (
Organization Wide Equity
) : ( investor.branches?.map(branch => (
{branch.name}
)) )}

Security & Docs

{investor.security_proof_document ? (
setIsPreviewOpen(true)}>

Security Proof

Click to View

) : (

No Document provided

)}
)} {activeTab === 'ROI Payouts' && (

Distribution History

Total ROI Settled: {totalPayouts.toLocaleString()} AED

{payouts.length > 0 ? ( payouts.map(p => ( )) ) : ( )}
Period Amount (AED) Payment Date Method Status
{p.payout_month} {(parseFloat(p.amount) || 0).toLocaleString()} AED {new Date(p.payout_date).toLocaleDateString(undefined, { day: '2-digit', month: 'short', year: 'numeric' })} {p.payment_method} {p.status || 'Paid'}

No ROI distributions recorded

)} {activeTab === 'Monthly Status' && (

Settlement Tracking

Unpaid ROI Periods since Investment

{roiStatus.filter(s => s.status === 'Pending' || s.status === 'Partial').length > 0 ? ( roiStatus.filter(s => s.status === 'Pending' || s.status === 'Partial').map((s, idx) => ( )) ) : ( )}
ROI Period Breakdown Net Due Status Action
{s.month}

Base ROI: {(parseFloat(s.base_amount) || 0).toLocaleString()} AED

{parseFloat(s.carry_from_previous) !== 0 && (

0 ? 'text-amber-500' : 'text-emerald-500'}`}> Carry Over: {parseFloat(s.carry_from_previous) > 0 ? '+' : ''}{parseFloat(s.carry_from_previous).toLocaleString()} AED

)} {s.paid > 0 && (

Allocated: -{(parseFloat(s.paid) || 0).toLocaleString()} AED

)}
{(parseFloat(s.amount) || 0).toLocaleString()} AED {s.status === 'Pending' ? ( Pending ) : ( Partially Paid )} {s.can_settle ? ( ) : ( )}

All ROI Distributions Up to Date

)}
{/* Document Preview Modal */} {isPreviewOpen && (
{investor.security_proof_document.toLowerCase().endsWith('.pdf') ? (