fix: syntax error in tenant assignment and enabled strict detail levels
This commit is contained in:
+133
-12
@@ -219,10 +219,56 @@ function generateProperties() {
|
|||||||
const baseVal = isCommercial ? 2500000 + (index * 100000) : style.baseValue;
|
const baseVal = isCommercial ? 2500000 + (index * 100000) : style.baseValue;
|
||||||
const value = Math.floor(baseVal * (1 + valueVariance));
|
const value = Math.floor(baseVal * (1 + valueVariance));
|
||||||
|
|
||||||
const isRented = Math.random() > 0.7; // 30% rented
|
// Rental Logic: Target ~10-15 rented (approx 40-50% chance given ~30 props)
|
||||||
const tenantName = isRented ? (isCommercial ? "Multiple Commercial Tenants" : REAL_NAMES[(index + 5) % REAL_NAMES.length]) : null;
|
const isRented = Math.random() > 0.55;
|
||||||
const tenantOcc = isRented ? (isCommercial ? "Retail/Office Mix" : OCCUPATIONS[(index + 3) % OCCUPATIONS.length]) : null;
|
|
||||||
const rentAmount = isRented ? Math.floor(value * 0.008 / 100) * 100 : null;
|
let tenantData = {};
|
||||||
|
if (isRented) {
|
||||||
|
const tName = isCommercial ? "Global Corp Inc." : REAL_NAMES[(index + 5) % REAL_NAMES.length];
|
||||||
|
const tOcc = isCommercial ? "Retail/Office Mix" : OCCUPATIONS[(index + 3) % OCCUPATIONS.length];
|
||||||
|
const tPhone = `469-555-${2000 + index}`;
|
||||||
|
const tEmail = generateEmail(tName.split(' ')[0] || "tenant", isCommercial ? "tenant.com" : null);
|
||||||
|
const tEmployer = isCommercial ? "N/A" : (EMPLOYERS_BY_OCCUPATION[tOcc]?.[0] || "Self");
|
||||||
|
const tIncome = isCommercial ? "$5M+" : ["$60k", "$85k", "$110k", "$140k"][index % 4];
|
||||||
|
const tFamily = isCommercial ? "N/A" : (Math.random() > 0.4 ? "Family" : "Single");
|
||||||
|
const tLeaseType = isCommercial ? "Commercial NNN" : "Residential Standard";
|
||||||
|
|
||||||
|
tenantData = {
|
||||||
|
currentlyRented: true,
|
||||||
|
currentTenantName: tName,
|
||||||
|
tenantPhone: tPhone,
|
||||||
|
tenantEmail: tEmail,
|
||||||
|
tenantOccupation: tOcc,
|
||||||
|
tenantEmployer: tEmployer,
|
||||||
|
tenantAnnualIncome: tIncome,
|
||||||
|
livingStatus: tFamily,
|
||||||
|
leaseType: tLeaseType,
|
||||||
|
currentMonthlyRentAmount: Math.floor(value * 0.008 / 100) * 100,
|
||||||
|
leaseStartDate: "2023-01-01",
|
||||||
|
leaseEndDate: "2025-01-01",
|
||||||
|
leaseSignedDate: "2022-12-15",
|
||||||
|
ownerWillingToRent: false // Already rented
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
tenantData = {
|
||||||
|
currentlyRented: false,
|
||||||
|
currentTenantName: null,
|
||||||
|
tenantPhone: null,
|
||||||
|
tenantEmail: null,
|
||||||
|
tenantOccupation: null,
|
||||||
|
tenantEmployer: null,
|
||||||
|
tenantAnnualIncome: null,
|
||||||
|
livingStatus: null,
|
||||||
|
leaseType: null,
|
||||||
|
currentMonthlyRentAmount: null,
|
||||||
|
leaseStartDate: null,
|
||||||
|
leaseEndDate: null,
|
||||||
|
leaseSignedDate: null,
|
||||||
|
ownerWillingToRent: Math.random() > 0.6
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const rentAmount = tenantData.currentMonthlyRentAmount; // For use below if needed, though mapped in tenantData now
|
||||||
|
|
||||||
// Weighted Roof Condition
|
// Weighted Roof Condition
|
||||||
const roofCondition = getWeightedRandom(
|
const roofCondition = getWeightedRandom(
|
||||||
@@ -257,14 +303,10 @@ function generateProperties() {
|
|||||||
lastMajorRenovationDate: "2020-05-15",
|
lastMajorRenovationDate: "2020-05-15",
|
||||||
lastRoofRepairReplacementDate: "2018-02-10",
|
lastRoofRepairReplacementDate: "2018-02-10",
|
||||||
recentMajorRepairs: "Routine Maintenance",
|
recentMajorRepairs: "Routine Maintenance",
|
||||||
currentlyRented: isRented,
|
|
||||||
currentTenantName: tenantName,
|
// Spread new robust tenant data
|
||||||
tenantOccupation: tenantOcc,
|
...tenantData,
|
||||||
tenantAnnualIncome: isRented ? "$100k - $150k" : null,
|
|
||||||
currentMonthlyRentAmount: rentAmount,
|
|
||||||
leaseStartDate: isRented ? "2023-01-01" : null,
|
|
||||||
leaseEndDate: isRented ? "2025-01-01" : null,
|
|
||||||
ownerWillingToRent: !isRented && Math.random() > 0.6,
|
|
||||||
expectedMonthlyRentAmount: Math.floor(value * 0.008 / 100) * 100,
|
expectedMonthlyRentAmount: Math.floor(value * 0.008 / 100) * 100,
|
||||||
rentalAvailabilityDate: null,
|
rentalAvailabilityDate: null,
|
||||||
rentalTermsPreference: null,
|
rentalTermsPreference: null,
|
||||||
@@ -332,6 +374,85 @@ function generateProperties() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 3. Assign Tenants (Strict Counts & Data Depth)
|
||||||
|
// User Request: 10-15 Total Rented. 5-8 with "Complete" info, rest "Sparse" (Mandatory only).
|
||||||
|
// Current Date Context: Feb 5, 2026.
|
||||||
|
|
||||||
|
const totalRented = Math.floor(Math.random() * (15 - 10 + 1)) + 10; // 10 to 15
|
||||||
|
const fullDetailCount = Math.floor(Math.random() * (8 - 5 + 1)) + 5; // 5 to 8
|
||||||
|
const sparseDetailCount = totalRented - fullDetailCount;
|
||||||
|
|
||||||
|
// Reshuffle for tenant assignment (independent of status)
|
||||||
|
const tenantIndices = allProperties.map((_, i) => i);
|
||||||
|
for (let i = tenantIndices.length - 1; i > 0; i--) {
|
||||||
|
const j = Math.floor(Math.random() * (i + 1));
|
||||||
|
[tenantIndices[i], tenantIndices[j]] = [tenantIndices[j], tenantIndices[i]];
|
||||||
|
}
|
||||||
|
|
||||||
|
tenantIndices.forEach((propIndex, i) => {
|
||||||
|
if (i < totalRented) {
|
||||||
|
const prop = allProperties[propIndex];
|
||||||
|
const isFullDetail = i < fullDetailCount;
|
||||||
|
const isCommercial = prop.propertyData.propertyType === "Commercial" || prop.propertyData.propertyType === "Apartments";
|
||||||
|
const val = prop.propertyData.currentEstimatedMarketValue;
|
||||||
|
|
||||||
|
// Generate Base Data (Mandatory)
|
||||||
|
const tName = isCommercial ? "Global Corp Inc." : REAL_NAMES[(propIndex + 5) % REAL_NAMES.length];
|
||||||
|
const tPhone = `469-555-${3000 + propIndex}`;
|
||||||
|
|
||||||
|
// Optional Data (Full vs Sparse)
|
||||||
|
const tEmail = isFullDetail ? generateEmail(tName.split(' ')[0], isCommercial ? "enterprises.com" : null) : "";
|
||||||
|
const tOcc = isFullDetail ? (isCommercial ? "Retail/Office Mix" : OCCUPATIONS[(propIndex + 3) % OCCUPATIONS.length]) : "";
|
||||||
|
const tEmployer = isFullDetail ? (isCommercial ? "N/A" : (EMPLOYERS_BY_OCCUPATION[tOcc]?.[0] || "Self")) : "";
|
||||||
|
const tIncome = isFullDetail ? (isCommercial ? "$5M+" : ["$60k", "$85k", "$110k", "$140k"][propIndex % 4]) : "";
|
||||||
|
const tFamily = isFullDetail ? (isCommercial ? "N/A" : (Math.random() > 0.4 ? "Family" : "Single")) : "Single";
|
||||||
|
const tLeaseType = isFullDetail ? (isCommercial ? "Commercial NNN" : "Residential Standard") : "Residential Standard";
|
||||||
|
|
||||||
|
// Dates (Relative to Feb 2026)
|
||||||
|
// Start: Jan 2025 - Jan 2026
|
||||||
|
const startYear = Math.random() > 0.5 ? 2025 : 2026;
|
||||||
|
const tStart = `${startYear}-01-15`;
|
||||||
|
|
||||||
|
// Signed: 1 month before start
|
||||||
|
const tSigned = `${startYear - 1}-12-15`;
|
||||||
|
|
||||||
|
// End: 1 year after start (2026 or 2027)
|
||||||
|
const tEnd = `${startYear + 1}-01-14`;
|
||||||
|
|
||||||
|
const tRent = Math.floor(val * 0.008 / 100) * 100;
|
||||||
|
|
||||||
|
// Apply updates
|
||||||
|
allProperties[propIndex].propertyData = {
|
||||||
|
...allProperties[propIndex].propertyData,
|
||||||
|
currentlyRented: true,
|
||||||
|
currentTenantName: tName,
|
||||||
|
tenantPhone: tPhone,
|
||||||
|
|
||||||
|
// Optional / Detail Dependent
|
||||||
|
tenantEmail: tEmail,
|
||||||
|
tenantOccupation: tOcc,
|
||||||
|
tenantEmployer: tEmployer,
|
||||||
|
tenantAnnualIncome: tIncome,
|
||||||
|
livingStatus: tFamily,
|
||||||
|
leaseType: tLeaseType,
|
||||||
|
|
||||||
|
// Dates & Financials (Assign sparse ones too if needed, or leave blank? User said sparse has MANDATORY only. But Rent amount is needed to be "Rented" usually. I'll add Rent/Dates to Full, and maybe just Rent to Sparse?)
|
||||||
|
// Re-reading: "The remaining entries may include only the mandatory fields."
|
||||||
|
// I will add rent/dates to ALL rented properties because otherwise the map might look broken for "Rented" status without a lease end date. But strictly, I could leave them empty.
|
||||||
|
// Let's populate Dates/Rent for ALL, but Personal Info (Email/Job/Income) only for Full.
|
||||||
|
|
||||||
|
currentMonthlyRentAmount: tRent,
|
||||||
|
leaseStartDate: tStart,
|
||||||
|
leaseEndDate: tEnd,
|
||||||
|
leaseSignedDate: tSigned,
|
||||||
|
|
||||||
|
ownerWillingToRent: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return allProperties;
|
return allProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+39
-10
@@ -405,11 +405,29 @@ const Drawer = ({ isOpen, onClose, data, newLocation, onUpdateStatus, onSave, lo
|
|||||||
|
|
||||||
{formData.isRented === 'Yes' ? (
|
{formData.isRented === 'Yes' ? (
|
||||||
<div className="p-4 bg-purple-50 dark:bg-purple-900/10 rounded-xl space-y-4 border border-purple-100 dark:border-purple-500/20">
|
<div className="p-4 bg-purple-50 dark:bg-purple-900/10 rounded-xl space-y-4 border border-purple-100 dark:border-purple-500/20">
|
||||||
<RenderInput label="Tenant Name" field="tenantName" />
|
<h4 className="text-[10px] uppercase font-bold text-purple-600 dark:text-purple-400 border-b border-purple-200 dark:border-purple-500/20 pb-1 mb-2">Tenant Profile</h4>
|
||||||
|
<RenderInput label="Full Name *" field="tenantName" placeholder="Required" />
|
||||||
<div className="grid grid-cols-2 gap-4">
|
<div className="grid grid-cols-2 gap-4">
|
||||||
<RenderInput label="Current Rent" field="currentRent" type="number" />
|
<RenderInput label="Phone *" field="tenantPhone" placeholder="Required" />
|
||||||
<RenderInput label="Lease End" field="leaseEnd" type="date" />
|
<RenderInput label="Email" field="tenantEmail" />
|
||||||
</div>
|
</div>
|
||||||
|
<div className="grid grid-cols-2 gap-4">
|
||||||
|
<RenderInput label="Occupation" field="tenantOccupation" />
|
||||||
|
<RenderInput label="Employer" field="tenantEmployer" />
|
||||||
|
</div>
|
||||||
|
<div className="grid grid-cols-2 gap-4">
|
||||||
|
<RenderInput label="Annual Income" field="tenantIncome" />
|
||||||
|
<RenderInput label="Family Status" field="livingStatus" options={["Single", "Family", "Couple", "Roommates"]} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h4 className="text-[10px] uppercase font-bold text-purple-600 dark:text-purple-400 border-b border-purple-200 dark:border-purple-500/20 pb-1 mb-2 mt-4">Lease Details</h4>
|
||||||
|
<RenderInput label="Lease Type" field="leaseType" options={["Residential Standard", "Commercial NNN", "Short Term", "Month-to-Month"]} />
|
||||||
|
<div className="grid grid-cols-3 gap-2">
|
||||||
|
<RenderInput label="Signed" field="leaseSigned" type="date" />
|
||||||
|
<RenderInput label="Start" field="leaseStart" type="date" />
|
||||||
|
<RenderInput label="End" field="leaseEnd" type="date" />
|
||||||
|
</div>
|
||||||
|
<RenderInput label="Monthly Rent ($)" field="currentRent" type="number" />
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="p-4 bg-zinc-50 dark:bg-white/5 rounded-xl space-y-4">
|
<div className="p-4 bg-zinc-50 dark:bg-white/5 rounded-xl space-y-4">
|
||||||
@@ -603,13 +621,24 @@ function Maps() {
|
|||||||
roofCondition: formData.roofCondition,
|
roofCondition: formData.roofCondition,
|
||||||
lastRenovationDate: formData.lastRenovationDate,
|
lastRenovationDate: formData.lastRenovationDate,
|
||||||
|
|
||||||
// Rental Status
|
// Rental Status (Enhanced)
|
||||||
isRented: formData.isRented,
|
isRented: formData.isRented === 'Yes',
|
||||||
tenantName: formData.tenantName,
|
currentlyRented: formData.isRented === 'Yes', // Sync both just in case
|
||||||
currentRent: formData.currentRent,
|
currentTenantName: formData.tenantName,
|
||||||
leaseEnd: formData.leaseEnd,
|
tenantPhone: formData.tenantPhone,
|
||||||
ownerWillingToRent: formData.ownerWillingToRent,
|
tenantEmail: formData.tenantEmail,
|
||||||
expectedRent: formData.expectedRent,
|
tenantOccupation: formData.tenantOccupation,
|
||||||
|
tenantEmployer: formData.tenantEmployer,
|
||||||
|
tenantAnnualIncome: formData.tenantIncome,
|
||||||
|
livingStatus: formData.livingStatus,
|
||||||
|
leaseType: formData.leaseType,
|
||||||
|
leaseSignedDate: formData.leaseSigned,
|
||||||
|
leaseStartDate: formData.leaseStart,
|
||||||
|
leaseEndDate: formData.leaseEnd,
|
||||||
|
currentMonthlyRentAmount: formData.currentRent,
|
||||||
|
|
||||||
|
ownerWillingToRent: formData.ownerWillingToRent === 'Yes',
|
||||||
|
expectedMonthlyRentAmount: formData.expectedRent,
|
||||||
|
|
||||||
// Location (can be expanded)
|
// Location (can be expanded)
|
||||||
schoolDistrict: formData.schoolDistrict,
|
schoolDistrict: formData.schoolDistrict,
|
||||||
|
|||||||
Reference in New Issue
Block a user