Files
Krow-workspace/frontend-web/src/components/business/ERPSettingsTab.jsx
2025-11-26 13:05:42 -05:00

256 lines
10 KiB
JavaScript

import React, { useState, useEffect } from "react";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Badge } from "@/components/ui/badge";
import { Switch } from "@/components/ui/switch";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Save, Loader2, Link2, Building2, FileText, Mail, CheckCircle, AlertCircle } from "lucide-react";
const ERP_SYSTEMS = [
{ value: "None", label: "No ERP Integration" },
{ value: "SAP Ariba", label: "SAP Ariba" },
{ value: "Fieldglass", label: "SAP Fieldglass" },
{ value: "CrunchTime", label: "CrunchTime" },
{ value: "Coupa", label: "Coupa" },
{ value: "Oracle NetSuite", label: "Oracle NetSuite" },
{ value: "Workday", label: "Workday" },
{ value: "Other", label: "Other" },
];
const EDI_FORMATS = [
{ value: "CSV", label: "CSV (Excel Compatible)" },
{ value: "EDI 810", label: "EDI 810 (Standard Invoice)" },
{ value: "cXML", label: "cXML (Ariba/Coupa)" },
{ value: "JSON", label: "JSON (API Format)" },
{ value: "Custom", label: "Custom Template" },
];
export default function ERPSettingsTab({ business, onSave, isSaving }) {
const [settings, setSettings] = useState({
erp_system: business?.erp_system || "None",
erp_vendor_id: business?.erp_vendor_id || "",
erp_cost_center: business?.erp_cost_center || "",
edi_enabled: business?.edi_enabled || false,
edi_format: business?.edi_format || "CSV",
invoice_email: business?.invoice_email || "",
po_required: business?.po_required || false,
});
useEffect(() => {
if (business) {
setSettings({
erp_system: business.erp_system || "None",
erp_vendor_id: business.erp_vendor_id || "",
erp_cost_center: business.erp_cost_center || "",
edi_enabled: business.edi_enabled || false,
edi_format: business.edi_format || "CSV",
invoice_email: business.invoice_email || "",
po_required: business.po_required || false,
});
}
}, [business]);
const handleChange = (field, value) => {
setSettings(prev => ({ ...prev, [field]: value }));
};
const handleSubmit = () => {
onSave(settings);
};
const isConfigured = settings.erp_system !== "None" && settings.erp_vendor_id;
return (
<div className="space-y-6">
{/* Status Card */}
<Card className={`border-2 ${isConfigured ? 'border-green-200 bg-green-50' : 'border-amber-200 bg-amber-50'}`}>
<CardContent className="p-4">
<div className="flex items-center gap-3">
{isConfigured ? (
<CheckCircle className="w-6 h-6 text-green-600" />
) : (
<AlertCircle className="w-6 h-6 text-amber-600" />
)}
<div>
<p className={`font-semibold ${isConfigured ? 'text-green-900' : 'text-amber-900'}`}>
{isConfigured ? 'ERP Integration Active' : 'ERP Integration Not Configured'}
</p>
<p className={`text-sm ${isConfigured ? 'text-green-700' : 'text-amber-700'}`}>
{isConfigured
? `Connected to ${settings.erp_system} • Vendor ID: ${settings.erp_vendor_id}`
: 'Configure ERP settings to enable automated invoice delivery'}
</p>
</div>
</div>
</CardContent>
</Card>
{/* ERP System Settings */}
<Card className="border-slate-200 shadow-lg">
<CardHeader className="bg-slate-50 border-b border-slate-200">
<CardTitle className="flex items-center gap-2 text-slate-900">
<Building2 className="w-5 h-5 text-blue-600" />
ERP System Configuration
</CardTitle>
</CardHeader>
<CardContent className="p-6 space-y-6">
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div className="space-y-2">
<Label className="text-slate-700 font-medium">ERP System</Label>
<Select
value={settings.erp_system}
onValueChange={(value) => handleChange('erp_system', value)}
>
<SelectTrigger className="border-slate-200">
<SelectValue placeholder="Select ERP system" />
</SelectTrigger>
<SelectContent>
{ERP_SYSTEMS.map(erp => (
<SelectItem key={erp.value} value={erp.value}>{erp.label}</SelectItem>
))}
</SelectContent>
</Select>
<p className="text-xs text-slate-500">Client's procurement or ERP system</p>
</div>
<div className="space-y-2">
<Label className="text-slate-700 font-medium">Vendor ID in ERP</Label>
<Input
value={settings.erp_vendor_id}
onChange={(e) => handleChange('erp_vendor_id', e.target.value)}
placeholder="e.g., VND-12345"
className="border-slate-200"
/>
<p className="text-xs text-slate-500">Your vendor identifier in client's system</p>
</div>
<div className="space-y-2">
<Label className="text-slate-700 font-medium">Default Cost Center</Label>
<Input
value={settings.erp_cost_center}
onChange={(e) => handleChange('erp_cost_center', e.target.value)}
placeholder="e.g., CC-1001"
className="border-slate-200"
/>
<p className="text-xs text-slate-500">Default cost center for invoice allocation</p>
</div>
<div className="space-y-2">
<Label className="text-slate-700 font-medium">Invoice Delivery Email</Label>
<Input
type="email"
value={settings.invoice_email}
onChange={(e) => handleChange('invoice_email', e.target.value)}
placeholder="ap@client.com"
className="border-slate-200"
/>
<p className="text-xs text-slate-500">Accounts payable email for invoice delivery</p>
</div>
</div>
</CardContent>
</Card>
{/* EDI Settings */}
<Card className="border-slate-200 shadow-lg">
<CardHeader className="bg-slate-50 border-b border-slate-200">
<CardTitle className="flex items-center gap-2 text-slate-900">
<Link2 className="w-5 h-5 text-purple-600" />
EDI / Export Settings
</CardTitle>
</CardHeader>
<CardContent className="p-6 space-y-6">
<div className="flex items-center justify-between p-4 bg-slate-50 rounded-lg">
<div>
<p className="font-medium text-slate-900">Enable EDI Integration</p>
<p className="text-sm text-slate-500">Automatically format invoices for EDI transmission</p>
</div>
<Switch
checked={settings.edi_enabled}
onCheckedChange={(checked) => handleChange('edi_enabled', checked)}
/>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div className="space-y-2">
<Label className="text-slate-700 font-medium">Preferred Export Format</Label>
<Select
value={settings.edi_format}
onValueChange={(value) => handleChange('edi_format', value)}
>
<SelectTrigger className="border-slate-200">
<SelectValue placeholder="Select format" />
</SelectTrigger>
<SelectContent>
{EDI_FORMATS.map(format => (
<SelectItem key={format.value} value={format.value}>{format.label}</SelectItem>
))}
</SelectContent>
</Select>
<p className="text-xs text-slate-500">Default format for invoice exports</p>
</div>
<div className="flex items-center justify-between p-4 bg-slate-50 rounded-lg h-fit">
<div>
<p className="font-medium text-slate-900">PO Required</p>
<p className="text-sm text-slate-500">Require PO number on invoices</p>
</div>
<Switch
checked={settings.po_required}
onCheckedChange={(checked) => handleChange('po_required', checked)}
/>
</div>
</div>
{/* Format Info */}
<div className="p-4 bg-blue-50 rounded-lg border border-blue-200">
<h4 className="font-semibold text-blue-900 mb-2 flex items-center gap-2">
<FileText className="w-4 h-4" />
Supported Formats
</h4>
<div className="grid grid-cols-2 md:grid-cols-4 gap-3 text-sm">
<div className="flex items-center gap-2">
<Badge className="bg-green-100 text-green-700">EDI 810</Badge>
<span className="text-blue-700">Standard</span>
</div>
<div className="flex items-center gap-2">
<Badge className="bg-purple-100 text-purple-700">cXML</Badge>
<span className="text-blue-700">Ariba/Coupa</span>
</div>
<div className="flex items-center gap-2">
<Badge className="bg-orange-100 text-orange-700">CSV</Badge>
<span className="text-blue-700">Excel</span>
</div>
<div className="flex items-center gap-2">
<Badge className="bg-slate-100 text-slate-700">JSON</Badge>
<span className="text-blue-700">API</span>
</div>
</div>
</div>
</CardContent>
</Card>
{/* Save Button */}
<div className="flex justify-end">
<Button
onClick={handleSubmit}
disabled={isSaving}
className="bg-blue-600 hover:bg-blue-700 text-white px-8"
>
{isSaving ? (
<>
<Loader2 className="w-4 h-4 mr-2 animate-spin" />
Saving...
</>
) : (
<>
<Save className="w-4 h-4 mr-2" />
Save ERP Settings
</>
)}
</Button>
</div>
</div>
);
}