<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Interactive Corrective Action Plan</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<!-- Chosen Palette: Neutral Harmony (Warm neutrals: bg-stone-100, bg-white. Comps: text-stone-800, text-stone-600. Accent: blue-600 for buttons/nav) -->
<!-- Application Structure Plan: A "stepper" or "wizard" UI. This structure is best for a complex, multi-part form like the CAP. It breaks the 9 sections into manageable, sequential steps, reducing cognitive load. Users are guided from one section to the next with "Previous" and "Next" buttons. The stepper navigation bar at the top visualizes progress and allows for non-linear navigation. This is far more usable than a single, long scrolling form. Key interactions include dynamic table row adding/deleting and live-updating charts based on user input in the form fields. -->
<!-- Visualization & Content Choices:
- Sec 1, 4, 5, 8, 9: Info: Tables of items. Goal: Organize. Viz: Dynamic HTML Tables. Interaction: "Add Row" button appends new row with inputs/contenteditable fields, "Remove" button per row. Justification: Makes the template a usable, dynamic form. Method: Vanilla JS (DOM Manipulation).
- Sec 2: Financials: Info: KPI table (Current vs. Target). Goal: Compare. Viz: Grouped Bar Chart. Interaction: 'input' events on the table's number fields trigger a JS function to update the chart data live. Justification: Instantly visualizes the gap between current state and target goals. Method: Chart.js.
- Sec 3: Eviction Plan: Info: Process steps. Goal: Organize. Viz: HTML Table. Interaction: Inputs for editing target days. Justification: Simple data entry for a defined process. Method: HTML/JS.
- Sec 6: Budget: Info: Cost items by category. Goal: Compare (Proportions). Viz: Donut Chart. Interaction: 'input' events on cost fields trigger JS function to aggregate costs by category and update the donut chart live. A "Total" div is also updated. Justification: Provides immediate visual feedback on budget allocation. Method: Chart.js.
- Sec 7: Timeline: Info: Milestones. Goal: Organize. Viz: Dynamic HTML Table. Interaction: "Add Milestone" button. Justification: Simple, effective way to build a timeline. Method: Vanilla JS (DOM Manipulation).
-->
<!-- CONFIRMATION: NO SVG graphics used. NO Mermaid JS used. -->
<style>
.chart-container {
position: relative;
width: 100%;
max-width: 600px;
margin-left: auto;
margin-right: auto;
height: 300px;
max-height: 400px;
}
@media (min-width: 768px) {
.chart-container {
height: 350px;
}
}
[contenteditable="true"]:focus {
outline: 2px solid #2563eb;
background-color: #eff6ff;
}
.step {
transition: all 0.3s ease-in-out;
}
.step-active {
background-color: #2563eb !important;
color: white !important;
border-color: #2563eb !important;
}
.step-completed {
background-color: #dbeafe;
border-color: #93c5fd;
color: #1e40af;
}
.tab-content {
display: none;
animation: fadeIn 0.5s;
}
.tab-content-active {
display: block;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.remove-row-btn {
cursor: pointer;
color: #ef4444;
font-weight: bold;
padding: 0 8px;
}
.remove-row-btn:hover {
color: #b91c1c;
}
</style>
</head>
<body class="bg-stone-100 text-stone-800 font-sans leading-relaxed">
<div id="toast-notification" class="fixed top-5 right-5 bg-green-600 text-white py-3 px-6 rounded-lg shadow-lg z-50 transition-all duration-300 translate-x-[120%]" role="alert">
Progress Saved (Simulated)!
</div>
<div class="container mx-auto p-4 md:p-8 max-w-7xl">
<header class="mb-6">
<h1 class="text-3xl md:text-4xl font-bold text-stone-900">Interactive Corrective Action Plan</h1>
<p class="text-lg text-stone-600">Multifamily Asset Turnaround</p>
</header>
<div class="bg-white rounded-lg shadow-xl overflow-hidden">
<nav id="stepper-nav" class="flex flex-wrap border-b border-stone-200 bg-stone-50">
<button id="step-btn-1" data-step="1" class="step flex-1 min-w-[150px] p-4 text-sm md:text-base font-medium border-b-4 border-transparent text-stone-600 hover:bg-stone-100 flex items-center justify-center gap-2 text-center">
<span class="flex items-center justify-center w-6 h-6 rounded-full border-2 border-stone-400 text-sm font-bold">1</span>
<span class="hidden md:inline">Deficiencies</span>
</button>
<button id="step-btn-2" data-step="2" class="step flex-1 min-w-[150px] p-4 text-sm md:text-base font-medium border-b-4 border-transparent text-stone-600 hover:bg-stone-100 flex items-center justify-center gap-2 text-center">
<span class="flex items-center justify-center w-6 h-6 rounded-full border-2 border-stone-400 text-sm font-bold">2</span>
<span class="hidden md:inline">Financials</span>
</button>
<button id="step-btn-3" data-step="3" class="step flex-1 min-w-[150px] p-4 text-sm md:text-base font-medium border-b-4 border-transparent text-stone-600 hover:bg-stone-100 flex items-center justify-center gap-2 text-center">
<span class="flex items-center justify-center w-6 h-6 rounded-full border-2 border-stone-400 text-sm font-bold">3</span>
<span class="hidden md:inline">Eviction Plan</span>
</button>
<button id="step-btn-4" data-step="4" class="step flex-1 min-w-[150px] p-4 text-sm md:text-base font-medium border-b-4 border-transparent text-stone-600 hover:bg-stone-100 flex items-center justify-center gap-2 text-center">
<span class="flex items-center justify-center w-6 h-6 rounded-full border-2 border-stone-400 text-sm font-bold">4</span>
<span class="hidden md:inline">Rent Potential</span>
</button>
<button id="step-btn-5" data-step="5" class="step flex-1 min-w-[150px] p-4 text-sm md:text-base font-medium border-b-4 border-transparent text-stone-600 hover:bg-stone-100 flex items-center justify-center gap-2 text-center">
<span class="flex items-center justify-center w-6 h-6 rounded-full border-2 border-stone-400 text-sm font-bold">5</span>
<span class="hidden md:inline">Physical Needs</span>
</button>
<button id="step-btn-6" data-step="6" class="step flex-1 min-w-[150px] p-4 text-sm md:text-base font-medium border-b-4 border-transparent text-stone-600 hover:bg-stone-100 flex items-center justify-center gap-2 text-center">
<span class="flex items-center justify-center w-6 h-6 rounded-full border-2 border-stone-400 text-sm font-bold">6</span>
<span class="hidden md:inline">Budget</span>
</button>
<button id="step-btn-7" data-step="7" class="step flex-1 min-w-[150px] p-4 text-sm md:text-base font-medium border-b-4 border-transparent text-stone-600 hover:bg-stone-100 flex items-center justify-center gap-2 text-center">
<span class="flex items-center justify-center w-6 h-6 rounded-full border-2 border-stone-400 text-sm font-bold">7</span>
<span class="hidden md:inline">Timeline</span>
</button>
<button id="step-btn-8" data-step="8" class="step flex-1 min-w-[150px] p-4 text-sm md:text-base font-medium border-b-4 border-transparent text-stone-600 hover:bg-stone-100 flex items-center justify-center gap-2 text-center">
<span class="flex items-center justify-center w-6 h-6 rounded-full border-2 border-stone-400 text-sm font-bold">8</span>
<span class="hidden md:inline">Accountability</span>
</button>
<button id="step-btn-9" data-step="9" class="step flex-1 min-w-[150px] p-4 text-sm md:text-base font-medium border-b-4 border-transparent text-stone-600 hover:bg-stone-100 flex items-center justify-center gap-2 text-center">
<span class="flex items-center justify-center w-6 h-6 rounded-full border-2 border-stone-400 text-sm font-bold">9</span>
<span class="hidden md:inline">Follow-Up</span>
</button>
</nav>
<div class="p-6 md:p-10">
<section id="step-content-1" class="tab-content" data-step-content="1">
<h2 class="text-2xl font-bold text-blue-700 mb-4">1. Description of Deficiencies</h2>
<p class="text-stone-600 mb-6">Summarize the critical issues, categorized by impact (Financial, Physical, Operational, Legal). Add as many rows as needed.</p>
<div class="overflow-x-auto">
<table class="w-full min-w-[600px] border-collapse">
<thead class="bg-stone-100">
<tr>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300">Deficiency Category</th>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300">Key Issues Identified</th>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300">Impact (High, Medium, Low)</th>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300 w-12"></th>
</tr>
</thead>
<tbody id="deficiency-table-body">
<tr>
<td class="p-3 border-b border-stone-200" contenteditable="true">Financial</td>
<td class="p-3 border-b border-stone-200" contenteditable="true">Collections are 65%; NOI is negative.</td>
<td class="p-3 border-b border-stone-200" contenteditable="true">High</td>
<td class="p-3 border-b border-stone-200 text-center"><span class="remove-row-btn">×</span></td>
</tr>
<tr>
<td class="p-3 border-b border-stone-200" contenteditable="true">Operational</td>
<td class="p-3 border-b border-stone-200" contenteditable="true">High staff turnover; Maintenance requests backlog > 90 days.</td>
<td class="p-3 border-b border-stone-200" contenteditable="true">High</td>
<td class="p-3 border-b border-stone-200 text-center"><span class="remove-row-btn">×</span></td>
</tr>
</tbody>
</table>
</div>
<button id="add-deficiency-btn" class="mt-4 px-4 py-2 bg-blue-600 text-white text-sm font-medium rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2">
+ Add Deficiency
</button>
</section>
<section id="step-content-2" class="tab-content" data-step-content="2">
<h2 class="text-2xl font-bold text-blue-700 mb-4">2. Financial KPI Analysis</h2>
<p class="text-stone-600 mb-6">Enter the current and target values for key performance indicators. The chart will update automatically to visualize the gap.</p>
<div class="grid md:grid-cols-2 gap-8 items-start">
<div class="overflow-x-auto">
<table class="w-full min-w-[400px] border-collapse">
<thead class="bg-stone-100">
<tr>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300">Financial Metric</th>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300">Current Value</th>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300">Target Value</th>
</tr>
</thead>
<tbody id="kpi-table-body">
<tr>
<td class="p-3 border-b border-stone-200 font-medium">Physical Occupancy (%)</td>
<td class="p-3 border-b border-stone-200"><input type="number" class="w-full p-1 border border-stone-300 rounded" value="78" data-metric="Physical Occupancy" data-type="current"></td>
<td class="p-3 border-b border-stone-200"><input type="number" class="w-full p-1 border border-stone-300 rounded" value="94" data-metric="Physical Occupancy" data-type="target"></td>
</tr>
<tr>
<td class="p-3 border-b border-stone-200 font-medium">Economic Occupancy (%)</td>
<td class="p-3 border-b border-stone-200"><input type="number" class="w-full p-1 border border-stone-300 rounded" value="65" data-metric="Economic Occupancy" data-type="current"></td>
<td class="p-3 border-b border-stone-200"><input type="number" class="w-full p-1 border border-stone-300 rounded" value="90" data-metric="Economic Occupancy" data-type="target"></td>
</tr>
<tr>
<td class="p-3 border-b border-stone-200 font-medium">Avg. Collections (%)</td>
<td class="p-3 border-b border-stone-200"><input type="number" class="w-full p-1 border border-stone-300 rounded" value="75" data-metric="Avg. Collections" data-type="current"></td>
<td class="p-3 border-b border-stone-200"><input type="number" class="w-full p-1 border border-stone-300 rounded" value="98" data-metric="Avg. Collections" data-type="target"></td>
</tr>
<tr>
<td class="p-3 border-b border-stone-200 font-medium">Delinquency (90+ days, $)</td>
<td class="p-3 border-b border-stone-200"><input type="number" class="w-full p-1 border border-stone-300 rounded" value="45000" data-metric="Delinquency" data-type="current"></td>
<td class="p-3 border-b border-stone-200"><input type="number" class="w-full p-1 border border-stone-300 rounded" value="5000" data-metric="Delinquency" data-type="target"></td>
</tr>
<tr>
<td class="p-3 border-b border-stone-200 font-medium">Monthly NOI ($)</td>
<td class="p-3 border-b border-stone-200"><input type="number" class="w-full p-1 border border-stone-300 rounded" value="-5000" data-metric="Monthly NOI" data-type="current"></td>
<td class="p-3 border-b border-stone-200"><input type="number" class="w-full p-1 border border-stone-300 rounded" value="25000" data-metric="Monthly NOI" data-type="target"></td>
</tr>
</tbody>
</table>
</div>
<div class="chart-container">
<canvas id="kpi-chart"></canvas>
</div>
</div>
</section>
<section id="step-content-3" class="tab-content" data-step-content="3">
<h2 class="text-2xl font-bold text-blue-700 mb-4">3. Eviction and Unit Turn Plan</h2>
<p class="text-stone-600 mb-6">Define the optimized timeline for reclaiming units and preparing them for re-lease. Adjust target durations as needed.</p>
<div class="overflow-x-auto">
<table class="w-full min-w-[600px] border-collapse">
<thead class="bg-stone-100">
<tr>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300">Phase</th>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300">Description</th>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300">Key Metric / Benchmark</th>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300">Target Duration (Days)</th>
</tr>
</thead>
<tbody>
<tr>
<td class="p-3 border-b border-stone-200 font-medium">Legal Initiation</td>
<td class="p-3 border-b border-stone-200">Serve 10-Day Notice to Pay or Quit</td>
<td class="p-3 border-b border-stone-200" contenteditable="true">Number of Notices Issued: [Target #]</td>
<td class="p-3 border-b border-stone-200"><input type="number" class="w-20 p-1 border border-stone-300 rounded" value="1"></td>
</tr>
<tr>
<td class="p-3 border-b border-stone-200 font-medium">Court Filing</td>
<td class="p-3 border-b border-stone-200">File with local court, securing hearing date</td>
<td class="p-3 border-b border-stone-200" contenteditable="true">Hearing Date Secured: [Date]</td>
<td class="p-3 border-b border-stone-200"><input type="text" class="w-20 p-1 border border-stone-300 rounded" value="5 - 10"></td>
</tr>
<tr>
<td class="p-3 border-b border-stone-200 font-medium">Judgment/Writ</td>
<td class="p-3 border-b border-stone-200">Secure Judgment and Writ of Possession</td>
<td class="p-3 border-b border-stone-200" contenteditable="true">Writ Secured: [Date]</td>
<td class="p-3 border-b border-stone-200"><input type="text" class="w-20 p-1 border border-stone-300 rounded" value="15 - 30"></td>
</tr>
<tr>
<td class="p-3 border-b border-stone-200 font-medium">Lockout/Possession</td>
<td class="p-3 border-b border-stone-200">Scheduled physical lockout</td>
<td class="p-3 border-b border-stone-200" contenteditable="true">Units Reclaimed: [Target #]</td>
<td class="p-3 border-b border-stone-200"><input type="number" class="w-20 p-1 border border-stone-300 rounded" value="1"></td>
</tr>
<tr>
<td class="p-3 border-b border-stone-200 font-medium">Unit Assessment</td>
<td class="p-3 border-b border-stone-200">Immediate assessment by Maintenance Lead</td>
<td class="p-3 border-b border-stone-200" contenteditable="true">Scope Documented: [Target #]</td>
<td class="p-3 border-b border-stone-200"><input type="number" class="w-20 p-1 border border-stone-300 rounded" value="1"></td>
</tr>
<tr>
<td class="p-3 border-b border-stone-200 font-medium">Turn Execution</td>
<td class="p-3 border-b border-stone-200">Completion of repairs, cleaning, CapEx</td>
<td class="p-3 border-b border-stone-200" contenteditable="true">Unit Ready for Move-In: [Target #]</td>
<td class="p-3 border-b border-stone-200"><input type="text" class="w-20 p-1 border border-stone-300 rounded" value="7 - 14"></td>
</tr>
</tbody>
</table>
</div>
</section>
<section id="step-content-4" class="tab-content" data-step-content="4">
<h2 class="text-2xl font-bold text-blue-700 mb-4">4. Rent Increase Potential Analysis</h2>
<p class="text-stone-600 mb-6">Assess current rents relative to market comparables (Comps) and potential revenue lift after unit improvements.</p>
<div class="overflow-x-auto">
<table class="w-full min-w-[600px] border-collapse">
<thead class="bg-stone-100">
<tr>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300">Unit Type</th>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300">Current Avg. Rent ($)</th>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300">Market Rent (As-Is) ($)</th>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300">Target Rent (Post-Reno) ($)</th>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300"></th>
</tr>
</thead>
<tbody id="rent-table-body">
<tr>
<td class="p-3 border-b border-stone-200" contenteditable="true">1 Bed / 1 Bath</td>
<td class="p-3 border-b border-stone-200"><input type="number" class="w-full p-1 border border-stone-300 rounded" value="950"></td>
<td class="p-3 border-b border-stone-200"><input type="number" class="w-full p-1 border border-stone-300 rounded" value="1100"></td>
<td class="p-3 border-b border-stone-200"><input type="number" class="w-full p-1 border border-stone-300 rounded" value="1350"></td>
<td class="p-3 border-b border-stone-200 text-center"><span class="remove-row-btn">×</span></td>
</tr>
<tr>
<td class="p-3 border-b border-stone-200" contenteditable="true">2 Bed / 1 Bath</td>
<td class="p-3 border-b border-stone-200"><input type="number" class="w-full p-1 border border-stone-300 rounded" value="1150"></td>
<td class="p-3 border-b border-stone-200"><input type="number" class="w-full p-1 border border-stone-300 rounded" value="1300"></td>
<td class="p-3 border-b border-stone-200"><input type="number" class="w-full p-1 border border-stone-300 rounded" value="1550"></td>
<td class="p-3 border-b border-stone-200 text-center"><span class="remove-row-btn">×</span></td>
</tr>
</tbody>
</table>
</div>
<button id="add-rent-btn" class="mt-4 px-4 py-2 bg-blue-600 text-white text-sm font-medium rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2">
+ Add Unit Type
</button>
<div class="mt-6">
<label for="rent-strategy" class="block text-sm font-medium text-stone-700">Rent Increase Strategy</label>
<textarea id="rent-strategy" rows="3" class="mt-1 block w-full rounded-md border-stone-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 sm:text-sm" placeholder="Describe whether increases will be gradual, immediately upon turn, or market-driven."></textarea>
</div>
</section>
<section id="step-content-5" class="tab-content" data-step-content="5">
<h2 class="text-2xl font-bold text-blue-700 mb-4">5. Property Physical Needs (Scope of Work)</h2>
<p class="text-stone-600 mb-6">List necessary capital expenditures and deferred maintenance beyond standard unit turns.</p>
<div class="overflow-x-auto">
<table class="w-full min-w-[600px] border-collapse">
<thead class="bg-stone-100">
<tr>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300">Area / System</th>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300">Specific Physical Need</th>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300">Priority</th>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300">Est. Useful Life Ext.</th>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300 w-12"></th>
</tr>
</thead>
<tbody id="needs-table-body">
<tr>
<td class="p-3 border-b border-stone-200" contenteditable="true">Exterior / Shell</td>
<td class="p-3 border-b border-stone-200" contenteditable="true">Full roof replacement on Building C.</td>
<td class="p-3 border-b border-stone-200" contenteditable="true">Critical</td>
<td class="p-3 border-b border-stone-200" contenteditable="true">20 Years</td>
<td class="p-3 border-b border-stone-200 text-center"><span class="remove-row-btn">×</span></td>
</tr>
<tr>
<td class="p-3 border-b border-stone-200" contenteditable="true">Mechanical Systems</td>
<td class="p-3 border-b border-stone-200" contenteditable="true">HVAC units replacement on 8 priority units.</td>
<td class="p-3 border-b border-stone-200" contenteditable="true">High</td>
<td class="p-3 border-b border-stone-200" contenteditable="true">15 Years</td>
<td class="p-3 border-b border-stone-200 text-center"><span class="remove-row-btn">×</span></td>
</tr>
</tbody>
</table>
</div>
<button id="add-need-btn" class="mt-4 px-4 py-2 bg-blue-600 text-white text-sm font-medium rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2">
+ Add Physical Need
</button>
</section>
<section id="step-content-6" class="tab-content" data-step-content="6">
<h2 class="text-2xl font-bold text-blue-700 mb-4">6. Cost Projection and Budget</h2>
<p class="text-stone-600 mb-6">Define the comprehensive budget for CAP execution. The chart and total will update as you enter costs.</p>
<div class="grid md:grid-cols-2 gap-8 items-start">
<div class="overflow-x-auto">
<table class="w-full min-w-[400px] border-collapse">
<thead class="bg-stone-100">
<tr>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300">Category</th>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300">Item Description</th>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300">Est. Cost ($)</th>
</tr>
</thead>
<tbody id="budget-table-body">
<tr>
<td class="p-3 border-b border-stone-200 font-medium">A. Unit Turns</td>
<td class="p-3 border-b border-stone-200" contenteditable="true">Avg. $3,500 x 20 Units</td>
<td class="p-3 border-b border-stone-200"><input type="number" class="w-full p-1 border border-stone-300 rounded" value="70000" data-category="A"></td>
</tr>
<tr>
<td class="p-3 border-b border-stone-200 font-medium">A. Unit Turns</td>
<td class="p-3 border-b border-stone-200" contenteditable="true">Rehab/CapEx per Unit</td>
<td class="p-3 border-b border-stone-200"><input type="number" class="w-full p-1 border border-stone-300 rounded" value="50000" data-category="A"></td>
</tr>
<tr>
<td class="p-3 border-b border-stone-200 font-medium">B. Legal Fees</td>
<td class="p-3 border-b border-stone-200" contenteditable="true">Attorney Fees (15 cases)</td>
<td class="p-3 border-b border-stone-200"><input type="number" class="w-full p-1 border border-stone-300 rounded" value="15000" data-category="B"></td>
</tr>
<tr>
<td class="p-3 border-b border-stone-200 font-medium">C. Property CapEx</td>
<td class="p-3 border-b border-stone-200" contenteditable="true">Roof Repairs (Sec 5)</td>
<td class="p-3 border-b border-stone-200"><input type="number" class="w-full p-1 border border-stone-300 rounded" value="85000" data-category="C"></td>
</tr>
<tr>
<td class="p-3 border-b border-stone-200 font-medium">D. Contingency</td>
<td class="p-3 border-b border-stone-200" contenteditable="true">General Contingency (10%)</td>
<td class="p-3 border-b border-stone-200"><input type="number" class="w-full p-1 border border-stone-300 rounded" value="22000" data-category="D"></td>
</tr>
</tbody>
</table>
<button id="add-budget-btn" class="mt-4 px-4 py-2 bg-blue-600 text-white text-sm font-medium rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2">
+ Add Budget Item
</button>
</div>
<div>
<div class="chart-container">
<canvas id="budget-chart"></canvas>
</div>
<div class="mt-6 text-center">
<span class="text-lg text-stone-600">Total Estimated Cost:</span>
<h3 id="total-budget-display" class="text-3xl font-bold text-stone-900">$242,000</h3>
</div>
</div>
</div>
</section>
<section id="step-content-7" class="tab-content" data-step-content="7">
<h2 class="text-2xl font-bold text-blue-700 mb-4">7. Time Frame for Delivery (Master Schedule)</h2>
<p class="text-stone-600 mb-6">List the high-level milestones for the full CAP execution.</p>
<div class="overflow-x-auto">
<table class="w-full min-w-[600px] border-collapse">
<thead class="bg-stone-100">
<tr>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300">Milestone</th>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300">Start Date</th>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300">End Date</th>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300">Status</th>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300 w-12"></th>
</tr>
</thead>
<tbody id="timeline-table-body">
<tr>
<td class="p-3 border-b border-stone-200" contenteditable="true">Phase 1: Legal & Funding</td>
<td class="p-3 border-b border-stone-200"><input type="date" class="w-full p-1 border border-stone-300 rounded"></td>
<td class="p-3 border-b border-stone-200"><input type="date" class="w-full p-1 border border-stone-300 rounded"></td>
<td class="p-3 border-b border-stone-200" contenteditable="true">Pending</td>
<td class="p-3 border-b border-stone-200 text-center"><span class="remove-row-btn">×</span></td>
</tr>
<tr>
<td class="p-3 border-b border-stone-200" contenteditable="true">Phase 2: Priority Unit Turns (Batch 1)</td>
<td class="p-3 border-b border-stone-200"><input type="date" class="w-full p-1 border border-stone-300 rounded"></td>
<td class="p-3 border-b border-stone-200"><input type="date" class="w-full p-1 border border-stone-300 rounded"></td>
<td class="p-3 border-b border-stone-200" contenteditable="true">Pending</td>
<td class="p-3 border-b border-stone-200 text-center"><span class="remove-row-btn">×</span></td>
</tr>
</tbody>
</table>
</div>
<button id="add-milestone-btn" class="mt-4 px-4 py-2 bg-blue-600 text-white text-sm font-medium rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2">
+ Add Milestone
</button>
</section>
<section id="step-content-8" class="tab-content" data-step-content="8">
<h2 class="text-2xl font-bold text-blue-700 mb-4">8. Person in Charge of Duty (Accountability Matrix)</h2>
<p class="text-stone-600 mb-6">Assign clear ownership for each critical component of the plan.</p>
<div class="overflow-x-auto">
<table class="w-full min-w-[600px] border-collapse">
<thead class="bg-stone-100">
<tr>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300">Area of Responsibility</th>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300">Accountable Person/Title</th>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300">Required Deliverable</th>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300">Final Deadline</th>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300 w-12"></th>
</tr>
</thead>
<tbody id="accountability-table-body">
<tr>
<td class="p-3 border-b border-stone-200" contenteditable="true">Legal/Evictions</td>
<td class="p-3 border-b border-stone-200" contenteditable="true">Property Attorney</td>
<td class="p-3 border-b border-stone-200" contenteditable="true">Final Lockout of 15 Units</td>
<td class="p-3 border-b border-stone-200"><input type="date" class="w-full p-1 border border-stone-300 rounded"></td>
<td class="p-3 border-b border-stone-200 text-center"><span class="remove-row-btn">×</span></td>
</tr>
<tr>
<td class="p-3 border-b border-stone-200" contenteditable="true">Unit Turn Execution</td>
<td class="p-3 border-b border-stone-200" contenteditable="true">Lead Maintenance Supervisor</td>
<td class="p-3 border-b border-stone-200" contenteditable="true">10 Units Certified Move-In Ready</td>
<td class="p-3 border-b border-stone-200"><input type="date" class="w-full p-1 border border-stone-300 rounded"></td>
<td class="p-3 border-b border-stone-200 text-center"><span class="remove-row-btn">×</span></td>
</tr>
</tbody>
</table>
</div>
<button id="add-accountability-btn" class="mt-4 px-4 py-2 bg-blue-600 text-white text-sm font-medium rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2">
+ Add Responsibility
</button>
</section>
<section id="step-content-9" class="tab-content" data-step-content="9">
<h2 class="text-2xl font-bold text-blue-700 mb-4">9. Follow-Up and Monitoring Form</h2>
<p class="text-stone-600 mb-6">Use this section to create a new follow-up report to track progress against the master schedule and budget.</p>
<div class="grid md:grid-cols-3 gap-4 mb-6">
<div>
<label for="fu-period" class="block text-sm font-medium text-stone-700">Reporting Period</label>
<input type="text" id="fu-period" class="mt-1 block w-full rounded-md border-stone-300 shadow-sm" placeholder="e.g., Week 1: 11/18 - 11/25">
</div>
<div>
<label for="fu-date" class="block text-sm font-medium text-stone-700">Date of Review</label>
<input type="date" id="fu-date" class="mt-1 block w-full rounded-md border-stone-300 shadow-sm">
</div>
<div>
<label for="fu-reviewer" class="block text-sm font-medium text-stone-700">Reviewer</label>
<input type="text" id="fu-reviewer" class="mt-1 block w-full rounded-md border-stone-300 shadow-sm" placeholder="Name">
</div>
</div>
<h3 class="text-lg font-semibold text-stone-800 mb-3">Progress Items</h3>
<div class="overflow-x-auto">
<table class="w-full min-w-[600px] border-collapse">
<thead class="bg-stone-100">
<tr>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300">Section (Ref.)</th>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300">Target for Period</th>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300">Actual Performance</th>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300">Variance</th>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300">Action Required</th>
<th class="p-3 text-left text-sm font-semibold text-stone-700 border-b-2 border-stone-300 w-12"></th>
</tr>
</thead>
<tbody id="followup-table-body">
<tr>
<td class="p-3 border-b border-stone-200" contenteditable="true">3. Eviction</td>
<td class="p-3 border-b border-stone-200" contenteditable="true">5 Writs Secured</td>
<td class="p-3 border-b border-stone-200" contenteditable="true">3 Writs Secured</td>
<td class="p-3 border-b border-stone-200" contenteditable="true">-2</td>
<td class="p-3 border-b border-stone-200" contenteditable="true">Follow up with attorney</td>
<td class="p-3 border-b border-stone-200 text-center"><span class="remove-row-btn">×</span></td>
</tr>
</tbody>
</table>
</div>
<button id="add-followup-btn" class="mt-4 px-4 py-2 bg-blue-600 text-white text-sm font-medium rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2">
+ Add Follow-Up Item
</button>
<div class="mt-6">
<label for="fu-summary" class="block text-sm font-medium text-stone-700">Summary Narrative</label>
<textarea id="fu-summary" rows="4" class="mt-1 block w-full rounded-md border-stone-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 sm:text-sm" placeholder="Describe overall status, roadblocks, and next two weeks' focus."></textarea>
</div>
</section>
</div>
<footer class="flex justify-between items-center p-6 bg-stone-50 border-t border-stone-200">
<button id="prev-btn" class="px-5 py-2 bg-stone-200 text-stone-700 text-sm font-medium rounded-md hover:bg-stone-300 focus:outline-none focus:ring-2 focus:ring-stone-400 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed">
Previous
</button>
<button id="save-btn" class="px-5 py-2 bg-green-600 text-white text-sm font-medium rounded-md hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-green-500 focus:ring-offset-2">
Save Progress (Simulated)
</button>
<button id="next-btn" class="px-5 py-2 bg-blue-600 text-white text-sm font-medium rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed">
Next
</button>
</footer>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
let currentStep = 1;
const totalSteps = 9;
let kpiChart, budgetChart;
const stepperButtons = document.querySelectorAll('#stepper-nav button');
const contentSections = document.querySelectorAll('.tab-content');
const prevBtn = document.getElementById('prev-btn');
const nextBtn = document.getElementById('next-btn');
const saveBtn = document.getElementById('save-btn');
const toast = document.getElementById('toast-notification');
const kpiTableBody = document.getElementById('kpi-table-body');
const budgetTableBody = document.getElementById('budget-table-body');
const totalBudgetDisplay = document.getElementById('total-budget-display');
const addDeficiencyBtn = document.getElementById('add-deficiency-btn');
const addRentBtn = document.getElementById('add-rent-btn');
const addNeedBtn = document.getElementById('add-need-btn');
const addBudgetBtn = document.getElementById('add-budget-btn');
const addMilestoneBtn = document.getElementById('add-milestone-btn');
const addAccountabilityBtn = document.getElementById('add-accountability-btn');
const addFollowupBtn = document.getElementById('add-followup-btn');
function showStep(stepNumber) {
currentStep = stepNumber;
stepperButtons.forEach((btn, index) => {
const step = index + 1;
btn.classList.remove('step-active');
btn.classList.remove('step-completed');
const span = btn.querySelector('span:first-child');
span.classList.remove('bg-blue-600', 'text-white', 'border-blue-600');
if (step < currentStep) {
btn.classList.add('step-completed');
} else if (step === currentStep) {
btn.classList.add('step-active');
span.classList.add('bg-blue-600', 'text-white', 'border-blue-600');
}
});
contentSections.forEach(section => {
if (parseInt(section.dataset.stepContent) === currentStep) {
section.classList.add('tab-content-active');
} else {
section.classList.remove('tab-content-active');
}
});
prevBtn.disabled = currentStep === 1;
nextBtn.disabled = currentStep === totalSteps;
nextBtn.textContent = currentStep === totalSteps ? 'Finish' : 'Next';
}
stepperButtons.forEach(btn => {
btn.addEventListener('click', () => {
const step = parseInt(btn.dataset.step);
showStep(step);
});
});
prevBtn.addEventListener('click', () => {
if (currentStep > 1) {
showStep(currentStep - 1);
}
});
nextBtn.addEventListener('click', () => {
if (currentStep < totalSteps) {
showStep(currentStep + 1);
} else {
showToast('Plan Completed (Simulated)!');
}
});
saveBtn.addEventListener('click', () => {
showToast('Progress Saved (Simulated)!');
});
function showToast(message) {
toast.textContent = message;
toast.classList.remove('translate-x-[120%]');
toast.classList.add('translate-x-0');
setTimeout(() => {
toast.classList.remove('translate-x-0');
toast.classList.add('translate-x-[120%]');
}, 3000);
}
function addDynamicRow(tableBody, cells) {
const tr = document.createElement('tr');
cells.forEach(cell => {
tr.appendChild(cell);
});
const removeCell = document.createElement('td');
removeCell.className = 'p-3 border-b border-stone-200 text-center';
const removeBtn = document.createElement('span');
removeBtn.className = 'remove-row-btn';
removeBtn.innerHTML = '×';
removeBtn.addEventListener('click', () => {
tr.remove();
if (tableBody.id === 'budget-table-body') updateBudgetChart();
});
removeCell.appendChild(removeBtn);
tr.appendChild(removeCell);
tableBody.appendChild(tr);
}
function createCell(content, type = 'text', editable = true) {
const td = document.createElement('td');
td.className = 'p-3 border-b border-stone-200';
if (editable) {
td.setAttribute('contenteditable', 'true');
td.textContent = content;
} else {
if (type === 'date') {
td.innerHTML = `<input type="date" class="w-full p-1 border border-stone-300 rounded">`;
} else if (type === 'number') {
td.innerHTML = `<input type="number" class="w-full p-1 border border-stone-300 rounded" value="0">`;
} else {
td.innerHTML = `<input type="text" class="w-full p-1 border border-stone-300 rounded" value="${content}">`;
}
}
return td;
}
function createInputCell(value, type = 'number', dataCategory = null) {
const td = document.createElement('td');
td.className = 'p-3 border-b border-stone-200';
const input = document.createElement('input');
input.type = type;
input.className = 'w-full p-1 border border-stone-300 rounded';
input.value = value;
if (dataCategory) {
input.dataset.category = dataCategory;
}
td.appendChild(input);
return td;
}
addDeficiencyBtn.addEventListener('click', () => {
addDynamicRow(document.getElementById('deficiency-table-body'), [
createCell('New Category'),
createCell('New Issue'),
createCell('Medium')
]);
});
addRentBtn.addEventListener('click', () => {
addDynamicRow(document.getElementById('rent-table-body'), [
createCell('New Unit Type'),
createInputCell('0', 'number'),
createInputCell('0', 'number'),
createInputCell('0', 'number')
]);
});
addNeedBtn.addEventListener('click', () => {
addDynamicRow(document.getElementById('needs-table-body'), [
createCell('New Area/System'),
createCell('New Need'),
createCell('Medium'),
createCell('10 Years')
]);
});
addBudgetBtn.addEventListener('click', () => {
const categoryCell = document.createElement('td');
categoryCell.className = 'p-3 border-b border-stone-200';
categoryCell.innerHTML = `<select class="w-full p-1 border border-stone-300 rounded">
<option value="A">A. Unit Turns</option>
<option value="B">B. Legal Fees</option>
<option value="C">C. Property CapEx</option>
<option value="D">D. Contingency</option>
</select>`;
const itemCell = createCell('New Budget Item');
const costCell = document.createElement('td');
costCell.className = 'p-3 border-b border-stone-200';
costCell.innerHTML = `<input type="number" class="w-full p-1 border border-stone-300 rounded" value="0">`;
const tr = document.createElement('tr');
tr.appendChild(categoryCell);
tr.appendChild(itemCell);
tr.appendChild(costCell);
const removeCell = document.createElement('td');
removeCell.className = 'p-3 border-b border-stone-200 text-center';
const removeBtn = document.createElement('span');
removeBtn.className = 'remove-row-btn';
removeBtn.innerHTML = '×';
removeBtn.addEventListener('click', () => {
tr.remove();
updateBudgetChart();
});
removeCell.appendChild(removeBtn);
tr.appendChild(removeCell);
budgetTableBody.appendChild(tr);
const newSelect = categoryCell.querySelector('select');
const newCostInput = costCell.querySelector('input');
newSelect.addEventListener('change', () => {
newCostInput.dataset.category = newSelect.value;
updateBudgetChart();
});
newCostInput.addEventListener('input', updateBudgetChart);
newCostInput.dataset.category = newSelect.value;
});
addMilestoneBtn.addEventListener('click', () => {
addDynamicRow(document.getElementById('timeline-table-body'), [
createCell('New Milestone'),
createCell('', 'date', false),
createCell('', 'date', false),
createCell('Pending')
]);
});
addAccountabilityBtn.addEventListener('click', () => {
addDynamicRow(document.getElementById('accountability-table-body'), [
createCell('New Area'),
createCell('New Person'),
createCell('New Deliverable'),
createCell('', 'date', false)
]);
});
addFollowupBtn.addEventListener('click', () => {
addDynamicRow(document.getElementById('followup-table-body'), [
createCell('New Section'),
createCell('New Target'),
createCell('New Actual'),
createCell(''),
createCell('New Action')
]);
});
document.querySelectorAll('.remove-row-btn').forEach(btn => {
btn.addEventListener('click', (e) => {
e.target.closest('tr').remove();
});
});
function getKpiData() {
const inputs = kpiTableBody.querySelectorAll('input');
const data = {};
inputs.forEach(input => {
const metric = input.dataset.metric;
if (!data[metric]) data[metric] = {};
data[metric][input.dataset.type] = parseFloat(input.value) || 0;
});
const labels = Object.keys(data);
const currentData = labels.map(label => data[label].current);
const targetData = labels.map(label => data[label].target);
return { labels, currentData, targetData };
}
function initKpiChart() {
const ctx = document.getElementById('kpi-chart').getContext('2d');
const initialData = getKpiData();
kpiChart = new Chart(ctx, {
type: 'bar',
data: {
labels: initialData.labels,
datasets: [
{
label: 'Current Value',
data: initialData.currentData,
backgroundColor: 'rgba(255, 99, 132, 0.6)',
borderColor: 'rgba(255, 99, 132, 1)',
borderWidth: 1
},
{
label: 'Target Value',
data: initialData.targetData,
backgroundColor: 'rgba(54, 162, 235, 0.6)',
borderColor: 'rgba(54, 162, 235, 1)',
borderWidth: 1
}
]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true
}
},
plugins: {
tooltip: {
callbacks: {
label: function(context) {
let label = context.dataset.label || '';
if (label) {
label += ': ';
}
if (context.parsed.y !== null) {
if (context.label.includes('$') || context.label.includes('NOI')) {
label += new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0 }).format(context.parsed.y);
} else {
label += context.parsed.y + '%';
}
}
return label;
}
}
}
}
}
});
}
function updateKpiChart() {
const data = getKpiData();
kpiChart.data.labels = data.labels;
kpiChart.data.datasets[0].data = data.currentData;
kpiChart.data.datasets[1].data = data.targetData;
kpiChart.update();
}
function getBudgetData() {
const inputs = budgetTableBody.querySelectorAll('input[type="number"]');
const data = { 'A': 0, 'B': 0, 'C': 0, 'D': 0 };
let total = 0;
inputs.forEach(input => {
const category = input.dataset.category || input.closest('tr').querySelector('select')?.value;
const value = parseFloat(input.value) || 0;
if (data.hasOwnProperty(category)) {
data[category] += value;
}
total += value;
});
return {
values: [data['A'], data['B'], data['C'], data['D']],
total: total
};
}
function initBudgetChart() {
const ctx = document.getElementById('budget-chart').getContext('2d');
const initialData = getBudgetData();
totalBudgetDisplay.textContent = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0 }).format(initialData.total);
budgetChart = new Chart(ctx, {
type: 'doughnut',
data: {
labels: ['A. Unit Turns', 'B. Legal Fees', 'C. Property CapEx', 'D. Contingency'],
datasets: [{
label: 'Budget Allocation',
data: initialData.values,
backgroundColor: [
'rgba(255, 99, 132, 0.7)',
'rgba(54, 162, 235, 0.7)',
'rgba(255, 206, 86, 0.7)',
'rgba(75, 192, 192, 0.7)'
],
borderColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)'
],
borderWidth: 1
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'top',
},
tooltip: {
callbacks: {
label: function(context) {
let label = context.label || '';
if (label) {
label += ': ';
}
if (context.parsed !== null) {
label += new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0 }).format(context.parsed);
}
return label;
}
}
}
}
}
});
}
function updateBudgetChart() {
const data = getBudgetData();
budgetChart.data.datasets[0].data = data.values;
budgetChart.update();
totalBudgetDisplay.textContent = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0 }).format(data.total);
}
kpiTableBody.addEventListener('input', updateKpiChart);
budgetTableBody.addEventListener('input', (e) => {
if(e.target.tagName === 'INPUT') {
updateBudgetChart();
}
});
showStep(1);
initKpiChart();
initBudgetChart();
});
</script>
</body>
</html>