Files
PowderCoatingLogix/src/PowderCoating.Web/Views/Appointments/Edit.cshtml
T
2026-04-23 21:38:24 -04:00

274 lines
15 KiB
Plaintext

@model PowderCoating.Application.DTOs.Appointment.UpdateAppointmentDto
@{
ViewData["Title"] = "Edit Appointment";
ViewData["PageIcon"] = "bi-pencil";
ViewData["PageHelpTitle"] = "Edit Appointment";
ViewData["PageHelpContent"] = "Update appointment details, change status, record actual arrival/completion times, or adjust the reminder. Use Actual Times to track punctuality vs scheduled time.";
}
<div class="d-flex justify-content-end align-items-center mb-4">
<a asp-action="Details" asp-route-id="@Model.Id" class="btn btn-outline-secondary">
<i class="bi bi-arrow-left"></i> Back to Details
</a>
</div>
<div class="row">
<div class="col-lg-8">
<div class="card">
<div class="card-body">
<form asp-action="Edit" method="post">
<input type="hidden" asp-for="Id" />
<partial name="_ValidationSummary" />
<!-- Title -->
<div class="mb-3">
<label asp-for="Title" class="form-label">Title <span class="text-danger">*</span></label>
<input asp-for="Title" class="form-control" />
<span asp-validation-for="Title" class="text-danger"></span>
</div>
<!-- Description -->
<div class="mb-3">
<label asp-for="Description" class="form-label">Description</label>
<textarea asp-for="Description" class="form-control" rows="3"></textarea>
<span asp-validation-for="Description" class="text-danger"></span>
</div>
<div class="row">
<!-- Customer -->
<div class="col-md-6 mb-3">
<label asp-for="CustomerId" class="form-label">Customer</label>
<select asp-for="CustomerId" class="form-select" asp-items="ViewBag.Customers">
<option value="">-- Select Customer (Optional) --</option>
</select>
<span asp-validation-for="CustomerId" class="text-danger"></span>
</div>
<!-- Appointment Type -->
<div class="col-md-6 mb-3">
<label asp-for="AppointmentTypeId" class="form-label">Type <span class="text-danger">*</span></label>
<select asp-for="AppointmentTypeId" class="form-select" asp-items="ViewBag.AppointmentTypes" id="appointmentType">
<option value="">-- Select Type --</option>
</select>
<span asp-validation-for="AppointmentTypeId" class="text-danger"></span>
</div>
</div>
<div class="row">
<!-- Status -->
<div class="col-md-6 mb-3">
<div class="d-flex align-items-center gap-1 mb-1">
<label asp-for="AppointmentStatusId" class="form-label mb-0">Status <span class="text-danger">*</span></label>
<a tabindex="0" class="help-icon" role="button"
data-bs-toggle="popover" data-bs-placement="right" data-bs-trigger="focus"
data-bs-title="Appointment Status"
data-bs-content="Scheduled → Confirmed (customer acknowledged) → In Progress (currently happening) → Completed. Use Cancelled for cancellations, No Show if the customer didn't arrive, and Rescheduled when moved to a new time.">
<i class="bi bi-question-circle"></i>
</a>
</div>
<select asp-for="AppointmentStatusId" class="form-select" asp-items="ViewBag.AppointmentStatuses">
<option value="">-- Select Status --</option>
</select>
<span asp-validation-for="AppointmentStatusId" class="text-danger"></span>
</div>
<!-- Job (conditional) -->
<div class="col-md-6 mb-3">
<label asp-for="JobId" class="form-label">Linked Job</label>
<select asp-for="JobId" class="form-select" asp-items="ViewBag.Jobs">
<option value="">-- Select Job (Optional) --</option>
</select>
<span asp-validation-for="JobId" class="text-danger"></span>
</div>
</div>
<!-- All Day Checkbox -->
<div class="mb-3 form-check">
<input asp-for="IsAllDay" class="form-check-input" id="isAllDay" />
<label asp-for="IsAllDay" class="form-check-label">
All Day Event
</label>
</div>
<div class="row">
<!-- Start Date/Time -->
<div class="col-md-6 mb-3">
<label asp-for="ScheduledStartTime" class="form-label">Start <span class="text-danger">*</span></label>
<input asp-for="ScheduledStartTime" type="datetime-local" class="form-control" id="startTime" />
<span asp-validation-for="ScheduledStartTime" class="text-danger"></span>
</div>
<!-- End Date/Time -->
<div class="col-md-6 mb-3">
<label asp-for="ScheduledEndTime" class="form-label">End <span class="text-danger">*</span></label>
<input asp-for="ScheduledEndTime" type="datetime-local" class="form-control" id="endTime" />
<span asp-validation-for="ScheduledEndTime" class="text-danger"></span>
</div>
</div>
<!-- Actual Times -->
<div class="card mb-3 bg-light">
<div class="card-header">
<div class="d-flex align-items-center gap-2">
<h6 class="mb-0"><i class="bi bi-clock-history me-2"></i>Actual Times</h6>
<a tabindex="0" class="help-icon" role="button"
data-bs-toggle="popover" data-bs-placement="right" data-bs-trigger="focus"
data-bs-title="Actual Times"
data-bs-content="Record when the customer actually arrived and when the appointment finished. These are optional and separate from the scheduled times — useful for tracking punctuality and measuring how accurately appointments are estimated.">
<i class="bi bi-question-circle"></i>
</a>
</div>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6 mb-3 mb-md-0">
<label asp-for="ActualStartTime" class="form-label">Actual Start</label>
<input asp-for="ActualStartTime" type="datetime-local" class="form-control" />
<span asp-validation-for="ActualStartTime" class="text-danger"></span>
</div>
<div class="col-md-6">
<label asp-for="ActualEndTime" class="form-label">Actual End</label>
<input asp-for="ActualEndTime" type="datetime-local" class="form-control" />
<span asp-validation-for="ActualEndTime" class="text-danger"></span>
</div>
</div>
</div>
</div>
<div class="row">
<!-- Assigned Worker -->
<div class="col-md-6 mb-3">
<label asp-for="AssignedUserId" class="form-label">Assign To Worker</label>
<select asp-for="AssignedUserId" class="form-select" asp-items="ViewBag.Workers">
<option value="">-- No Assignment --</option>
</select>
<span asp-validation-for="AssignedUserId" class="text-danger"></span>
</div>
<!-- Location -->
<div class="col-md-6 mb-3">
<label asp-for="Location" class="form-label">Location</label>
<input asp-for="Location" class="form-control" />
<span asp-validation-for="Location" class="text-danger"></span>
</div>
</div>
<!-- Internal Notes -->
<div class="mb-3">
<label asp-for="Notes" class="form-label">Internal Notes</label>
<textarea asp-for="Notes" class="form-control" rows="2"></textarea>
<span asp-validation-for="Notes" class="text-danger"></span>
</div>
<!-- Reminder Settings -->
<div class="card mb-3">
<div class="card-header">
<div class="d-flex align-items-center gap-2">
<h6 class="mb-0"><i class="bi bi-bell me-2"></i>Reminder Settings</h6>
<a tabindex="0" class="help-icon" role="button"
data-bs-toggle="popover" data-bs-placement="right" data-bs-trigger="focus"
data-bs-title="Reminder Settings"
data-bs-content="Enable a reminder to receive an in-app notification before the appointment. Set how many minutes in advance — e.g., 30 for a brief heads-up, 1440 for a full day before. Reminders are per-appointment and do not send external emails or SMS.">
<i class="bi bi-question-circle"></i>
</a>
</div>
</div>
<div class="card-body">
<div class="mb-3 form-check">
<input asp-for="IsReminderEnabled" class="form-check-input" id="reminderEnabled" />
<label asp-for="IsReminderEnabled" class="form-check-label">
Send reminder notification
</label>
</div>
<div class="mb-0" id="reminderTime" style="display: @(Model.IsReminderEnabled ? "block" : "none")">
<label asp-for="ReminderMinutesBefore" class="form-label">Remind me</label>
<div class="input-group">
<input asp-for="ReminderMinutesBefore" type="number" class="form-control" min="5" max="1440" />
<span class="input-group-text">minutes before</span>
</div>
<span asp-validation-for="ReminderMinutesBefore" class="text-danger"></span>
</div>
</div>
</div>
<!-- Actions -->
<div class="d-flex justify-content-between">
<button type="submit" class="btn btn-primary">
<i class="bi bi-check-circle"></i> Save Changes
</button>
<a asp-action="Details" asp-route-id="@Model.Id" class="btn btn-outline-secondary">Cancel</a>
</div>
</form>
</div>
</div>
</div>
<!-- Sidebar - Status Guide -->
<div class="col-lg-4">
<div class="card">
<div class="card-header bg-info text-white">
<h6 class="mb-0"><i class="bi bi-info-circle me-2"></i>Status Guide</h6>
</div>
<div class="card-body">
<h6>Status Meanings:</h6>
<ul class="small mb-3">
<li><strong>Scheduled:</strong> Initial appointment booking</li>
<li><strong>Confirmed:</strong> Customer has confirmed attendance</li>
<li><strong>In Progress:</strong> Appointment is currently happening</li>
<li><strong>Completed:</strong> Appointment finished successfully</li>
<li><strong>Cancelled:</strong> Appointment was cancelled</li>
<li><strong>No Show:</strong> Customer didn't arrive</li>
<li><strong>Rescheduled:</strong> Moved to a different time</li>
</ul>
<h6>Actual Times:</h6>
<p class="small mb-0">Record when the customer actually arrived and when the appointment was completed. Useful for tracking punctuality and duration accuracy.</p>
</div>
</div>
</div>
</div>
@section Scripts {
<partial name="_ValidationScriptsPartial" />
<script>
// Toggle reminder time visibility
document.getElementById('reminderEnabled').addEventListener('change', function() {
const reminderTime = document.getElementById('reminderTime');
reminderTime.style.display = this.checked ? 'block' : 'none';
});
// Hide time inputs when "All Day" is checked
const isAllDayCheckbox = document.getElementById('isAllDay');
const startTimeInput = document.getElementById('startTime');
const endTimeInput = document.getElementById('endTime');
function toggleTimeInputs() {
if (isAllDayCheckbox.checked) {
startTimeInput.type = 'date';
endTimeInput.type = 'date';
} else {
startTimeInput.type = 'datetime-local';
endTimeInput.type = 'datetime-local';
}
}
// Initialize on load
toggleTimeInputs();
isAllDayCheckbox.addEventListener('change', toggleTimeInputs);
// Auto-update end time when start time changes
startTimeInput.addEventListener('change', function() {
if (isAllDayCheckbox.checked) {
// For all-day events, set end date to same as start date
endTimeInput.value = this.value;
} else {
// For timed events, set end time to 1 hour after start time
const newEndTime = new Date(this.value);
newEndTime.setHours(newEndTime.getHours() + 1);
endTimeInput.value = newEndTime.toISOString().slice(0, 16);
}
});
</script>
}