new temporal folder to test

This commit is contained in:
José Salazar
2025-12-04 18:02:28 -05:00
parent cf18fdb16b
commit 48d86436e3
252 changed files with 120330 additions and 0 deletions

View File

@@ -0,0 +1,407 @@
import React, { useState, useEffect } from "react";
import { base44 } from "@/api/base44Client";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Building2, Save, Loader2, X } from "lucide-react";
import { useToast } from "@/components/ui/use-toast";
export default function EditVendorModal({ vendor, open, onClose }) {
const queryClient = useQueryClient();
const { toast } = useToast();
const [vendorData, setVendorData] = useState({
vendor_number: "",
legal_name: "",
doing_business_as: "",
tax_id: "",
business_type: "LLC",
primary_contact_name: "",
primary_contact_email: "",
primary_contact_phone: "",
billing_address: "",
service_address: "",
coverage_regions: [],
eligible_roles: [],
insurance_expiry: "",
approval_status: "approved",
is_active: true,
notes: ""
});
const [regionInput, setRegionInput] = useState("");
const [roleInput, setRoleInput] = useState("");
useEffect(() => {
if (vendor) {
setVendorData({
vendor_number: vendor.vendorNumber || vendor.vendor_number || "",
legal_name: vendor.name || vendor.legal_name || "",
doing_business_as: vendor.doing_business_as || "",
tax_id: vendor.tax_id || "",
business_type: vendor.business_type || "LLC",
primary_contact_name: vendor.primary_contact_name || "",
primary_contact_email: vendor.primary_contact_email || `contact@${vendor.name?.toLowerCase().replace(/\s+/g, '').replace(/[()&]/g, '')}.com`,
primary_contact_phone: vendor.primary_contact_phone || "(555) 123-4567",
billing_address: vendor.billing_address || "",
service_address: vendor.service_address || "",
coverage_regions: vendor.coverage_regions || [vendor.region] || [],
eligible_roles: vendor.eligible_roles || [vendor.specialty] || [],
insurance_expiry: vendor.insurance_expiry || "",
approval_status: vendor.approval_status || "approved",
is_active: vendor.is_active !== undefined ? vendor.is_active : true,
notes: vendor.notes || ""
});
}
}, [vendor]);
const updateVendorMutation = useMutation({
mutationFn: (data) => {
// For now, just show success toast since we're using mock data
return Promise.resolve(data);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['vendors'] });
toast({
title: "Vendor Updated",
description: "Vendor information has been successfully updated",
});
onClose();
},
});
const handleAddRegion = () => {
if (regionInput.trim() && !vendorData.coverage_regions.includes(regionInput.trim())) {
setVendorData({
...vendorData,
coverage_regions: [...vendorData.coverage_regions, regionInput.trim()]
});
setRegionInput("");
}
};
const handleRemoveRegion = (index) => {
setVendorData({
...vendorData,
coverage_regions: vendorData.coverage_regions.filter((_, i) => i !== index)
});
};
const handleAddRole = () => {
if (roleInput.trim() && !vendorData.eligible_roles.includes(roleInput.trim())) {
setVendorData({
...vendorData,
eligible_roles: [...vendorData.eligible_roles, roleInput.trim()]
});
setRoleInput("");
}
};
const handleRemoveRole = (index) => {
setVendorData({
...vendorData,
eligible_roles: vendorData.eligible_roles.filter((_, i) => i !== index)
});
};
const handleSubmit = (e) => {
e.preventDefault();
updateVendorMutation.mutate(vendorData);
};
if (!vendor) return null;
return (
<Dialog open={open} onOpenChange={onClose}>
<DialogContent className="max-w-4xl max-h-[90vh] overflow-hidden p-0">
<DialogHeader className="px-6 pt-6 pb-4 border-b border-slate-200">
<DialogTitle className="flex items-center gap-2 text-2xl">
<Building2 className="w-6 h-6 text-[#0A39DF]" />
Edit Vendor: {vendor.name}
</DialogTitle>
</DialogHeader>
<div className="overflow-y-auto max-h-[calc(90vh-180px)] px-6 pb-6">
<form onSubmit={handleSubmit} className="space-y-6">
{/* Basic Information */}
<Card className="border-slate-200 shadow-sm">
<CardHeader className="bg-gradient-to-br from-slate-50 to-white border-b">
<CardTitle className="text-base">Basic Information</CardTitle>
</CardHeader>
<CardContent className="p-4 space-y-4">
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<Label htmlFor="vendor_number" className="text-sm">Vendor Number</Label>
<Input
id="vendor_number"
value={vendorData.vendor_number}
disabled
className="bg-slate-100 text-sm"
/>
</div>
<div>
<Label htmlFor="approval_status" className="text-sm">Status</Label>
<Select
value={vendorData.approval_status}
onValueChange={(value) => setVendorData({...vendorData, approval_status: value})}
>
<SelectTrigger className="text-sm">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="pending">Pending</SelectItem>
<SelectItem value="approved">Approved</SelectItem>
<SelectItem value="suspended">Suspended</SelectItem>
<SelectItem value="terminated">Terminated</SelectItem>
</SelectContent>
</Select>
</div>
<div className="md:col-span-2">
<Label htmlFor="legal_name" className="text-sm">Legal Business Name *</Label>
<Input
id="legal_name"
placeholder="e.g., ABC Staffing LLC"
value={vendorData.legal_name}
onChange={(e) => setVendorData({...vendorData, legal_name: e.target.value})}
required
className="text-sm"
/>
</div>
<div className="md:col-span-2">
<Label htmlFor="doing_business_as" className="text-sm">Doing Business As (DBA)</Label>
<Input
id="doing_business_as"
placeholder="e.g., ABC Staff"
value={vendorData.doing_business_as}
onChange={(e) => setVendorData({...vendorData, doing_business_as: e.target.value})}
className="text-sm"
/>
</div>
<div>
<Label htmlFor="tax_id" className="text-sm">Federal Tax ID / EIN</Label>
<Input
id="tax_id"
placeholder="12-3456789"
value={vendorData.tax_id}
onChange={(e) => setVendorData({...vendorData, tax_id: e.target.value})}
className="text-sm"
/>
</div>
<div>
<Label htmlFor="business_type" className="text-sm">Business Type</Label>
<Select
value={vendorData.business_type}
onValueChange={(value) => setVendorData({...vendorData, business_type: value})}
>
<SelectTrigger className="text-sm">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="Corporation">Corporation</SelectItem>
<SelectItem value="LLC">LLC</SelectItem>
<SelectItem value="Partnership">Partnership</SelectItem>
<SelectItem value="Sole Proprietorship">Sole Proprietorship</SelectItem>
</SelectContent>
</Select>
</div>
</div>
</CardContent>
</Card>
{/* Contact Information */}
<Card className="border-slate-200 shadow-sm">
<CardHeader className="bg-gradient-to-br from-slate-50 to-white border-b">
<CardTitle className="text-base">Primary Contact</CardTitle>
</CardHeader>
<CardContent className="p-4 space-y-4">
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div className="md:col-span-2">
<Label htmlFor="primary_contact_name" className="text-sm">Contact Name</Label>
<Input
id="primary_contact_name"
placeholder="John Doe"
value={vendorData.primary_contact_name}
onChange={(e) => setVendorData({...vendorData, primary_contact_name: e.target.value})}
className="text-sm"
/>
</div>
<div>
<Label htmlFor="primary_contact_email" className="text-sm">Email *</Label>
<Input
id="primary_contact_email"
type="email"
placeholder="john@vendor.com"
value={vendorData.primary_contact_email}
onChange={(e) => setVendorData({...vendorData, primary_contact_email: e.target.value})}
required
className="text-sm"
/>
</div>
<div>
<Label htmlFor="primary_contact_phone" className="text-sm">Phone</Label>
<Input
id="primary_contact_phone"
type="tel"
placeholder="(555) 123-4567"
value={vendorData.primary_contact_phone}
onChange={(e) => setVendorData({...vendorData, primary_contact_phone: e.target.value})}
className="text-sm"
/>
</div>
</div>
</CardContent>
</Card>
{/* Coverage & Services */}
<Card className="border-slate-200 shadow-sm">
<CardHeader className="bg-gradient-to-br from-slate-50 to-white border-b">
<CardTitle className="text-base">Coverage & Services</CardTitle>
</CardHeader>
<CardContent className="p-4 space-y-4">
<div>
<Label className="text-sm">Coverage Regions</Label>
<div className="flex gap-2 mb-2">
<Input
placeholder="Add region (e.g., San Francisco Bay Area)"
value={regionInput}
onChange={(e) => setRegionInput(e.target.value)}
onKeyPress={(e) => e.key === 'Enter' && (e.preventDefault(), handleAddRegion())}
className="text-sm"
/>
<Button type="button" onClick={handleAddRegion} variant="outline" size="sm">
Add
</Button>
</div>
<div className="flex flex-wrap gap-2">
{vendorData.coverage_regions.map((region, i) => (
<span key={i} className="bg-blue-100 text-blue-700 px-2 py-1 rounded-full text-xs flex items-center gap-1">
{region}
<button type="button" onClick={() => handleRemoveRegion(i)} className="text-blue-900 hover:text-blue-700">×</button>
</span>
))}
</div>
</div>
<div>
<Label className="text-sm">Eligible Roles</Label>
<div className="flex gap-2 mb-2">
<Input
placeholder="Add role (e.g., Server, Bartender)"
value={roleInput}
onChange={(e) => setRoleInput(e.target.value)}
onKeyPress={(e) => e.key === 'Enter' && (e.preventDefault(), handleAddRole())}
className="text-sm"
/>
<Button type="button" onClick={handleAddRole} variant="outline" size="sm">
Add
</Button>
</div>
<div className="flex flex-wrap gap-2">
{vendorData.eligible_roles.map((role, i) => (
<span key={i} className="bg-purple-100 text-purple-700 px-2 py-1 rounded-full text-xs flex items-center gap-1">
{role}
<button type="button" onClick={() => handleRemoveRole(i)} className="text-purple-900 hover:text-purple-700">×</button>
</span>
))}
</div>
</div>
<div className="grid grid-cols-1 gap-4">
<div>
<Label htmlFor="billing_address" className="text-sm">Billing Address</Label>
<Textarea
id="billing_address"
rows={2}
placeholder="123 Main St, San Francisco, CA 94102"
value={vendorData.billing_address}
onChange={(e) => setVendorData({...vendorData, billing_address: e.target.value})}
className="text-sm"
/>
</div>
<div>
<Label htmlFor="service_address" className="text-sm">Service Address</Label>
<Textarea
id="service_address"
rows={2}
placeholder="456 Service St, San Francisco, CA 94103"
value={vendorData.service_address}
onChange={(e) => setVendorData({...vendorData, service_address: e.target.value})}
className="text-sm"
/>
</div>
</div>
</CardContent>
</Card>
{/* Notes */}
<Card className="border-slate-200 shadow-sm">
<CardHeader className="bg-gradient-to-br from-slate-50 to-white border-b">
<CardTitle className="text-base">Additional Information</CardTitle>
</CardHeader>
<CardContent className="p-4">
<div>
<Label htmlFor="notes" className="text-sm">Internal Notes</Label>
<Textarea
id="notes"
rows={3}
placeholder="Add any internal notes about this vendor..."
value={vendorData.notes}
onChange={(e) => setVendorData({...vendorData, notes: e.target.value})}
className="text-sm"
/>
</div>
</CardContent>
</Card>
</form>
</div>
{/* Action Buttons */}
<div className="flex justify-end gap-3 px-6 py-4 border-t border-slate-200 bg-slate-50">
<Button
type="button"
variant="outline"
onClick={onClose}
>
Cancel
</Button>
<Button
type="submit"
onClick={handleSubmit}
disabled={updateVendorMutation.isPending}
className="bg-[#0A39DF] hover:bg-[#0A39DF]/90"
>
{updateVendorMutation.isPending ? (
<>
<Loader2 className="w-4 h-4 mr-2 animate-spin" />
Updating...
</>
) : (
<>
<Save className="w-4 h-4 mr-2" />
Update Vendor
</>
)}
</Button>
</div>
</DialogContent>
</Dialog>
);
}