Share Mark Complete modal as partial view; hide install button after PWA install

- Extract _CompleteJobModal.cshtml partial; Details.cshtml uses PartialAsync
- Job board COMPLETED drop fetches partial via AJAX and shows modal in-place
- Add GET Jobs/CompleteJobModal action to load job data for the board modal
- install-app.js: persist installed state in localStorage; clears automatically when browser re-fires beforeinstallprompt after uninstall

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-06 19:55:37 -04:00
parent bbedaedeaa
commit 2cfe093780
5 changed files with 207 additions and 159 deletions
@@ -2643,6 +2643,22 @@ public class JobsController : Controller
#region Job Completion
/// <summary>
/// Returns the Mark Complete modal partial view populated with full job data.
/// Called via AJAX from the Job Board when a card is dragged to the Completed column.
/// </summary>
[HttpGet]
public async Task<IActionResult> CompleteJobModal(int id)
{
var job = await _unitOfWork.Jobs.LoadForDetailsAsync(id);
if (job == null) return NotFound();
var currentUser = await _userManager.GetUserAsync(User);
if (currentUser != null)
await PopulateEmailNotificationDefaultsAsync(currentUser.CompanyId);
var dto = _mapper.Map<JobDto>(job);
return PartialView("_CompleteJobModal", dto);
}
/// <summary>
/// Marks a job as completed, recording actual time spent and final price adjustments.
/// Updates the CompletedDate, ActualTimeSpentHours, and FinalPrice fields, transitions to