Initial commit
This commit is contained in:
@@ -0,0 +1,188 @@
|
||||
<!-- Quick Create Appointment Modal -->
|
||||
<div class="modal fade" id="quickCreateModal" tabindex="-1" aria-labelledby="quickCreateModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-primary text-white">
|
||||
<h5 class="modal-title" id="quickCreateModalLabel">
|
||||
<i class="bi bi-calendar-plus me-2"></i>Quick Create Appointment
|
||||
</h5>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<form id="quickCreateForm">
|
||||
<div class="modal-body">
|
||||
<div class="alert alert-danger d-none" id="quickCreateError"></div>
|
||||
|
||||
<!-- Title -->
|
||||
<div class="mb-3">
|
||||
<label for="quickTitle" class="form-label">Title <span class="text-danger">*</span></label>
|
||||
<input type="text" class="form-control" id="quickTitle" name="Title" required placeholder="e.g., Customer Drop-Off">
|
||||
</div>
|
||||
|
||||
<!-- Customer -->
|
||||
<div class="mb-3">
|
||||
<label for="quickCustomer" class="form-label">Customer</label>
|
||||
<select class="form-select" id="quickCustomer" name="CustomerId">
|
||||
<option value="">-- Select Customer (Optional) --</option>
|
||||
@foreach (var customer in (SelectList)ViewBag.Customers)
|
||||
{
|
||||
<option value="@customer.Value">@customer.Text</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Appointment Type -->
|
||||
<div class="mb-3">
|
||||
<label for="quickType" class="form-label">Type <span class="text-danger">*</span></label>
|
||||
<select class="form-select" id="quickType" name="AppointmentTypeId" required>
|
||||
<option value="">-- Select Type --</option>
|
||||
@foreach (var type in (SelectList)ViewBag.AppointmentTypes)
|
||||
{
|
||||
<option value="@type.Value">@type.Text</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- All Day -->
|
||||
<div class="mb-3 form-check">
|
||||
<input type="checkbox" class="form-check-input" id="quickAllDay" name="IsAllDay">
|
||||
<label class="form-check-label" for="quickAllDay">
|
||||
All Day Event
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<!-- Start Date/Time -->
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="quickStart" class="form-label">Start <span class="text-danger">*</span></label>
|
||||
<input type="datetime-local" class="form-control" id="quickStart" name="ScheduledStartTime" required>
|
||||
</div>
|
||||
|
||||
<!-- End Date/Time -->
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="quickEnd" class="form-label">End <span class="text-danger">*</span></label>
|
||||
<input type="datetime-local" class="form-control" id="quickEnd" name="ScheduledEndTime" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="text-muted small mb-0">
|
||||
<i class="bi bi-info-circle"></i> For more options, use the <a asp-action="Create">full create form</a>.
|
||||
</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
||||
<button type="submit" class="btn btn-primary" id="quickCreateSubmit">
|
||||
<i class="bi bi-check-circle"></i> Create Appointment
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Quick Create Modal Logic
|
||||
document.getElementById('quickCreateForm').addEventListener('submit', async function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const submitBtn = document.getElementById('quickCreateSubmit');
|
||||
const errorDiv = document.getElementById('quickCreateError');
|
||||
errorDiv.classList.add('d-none');
|
||||
|
||||
// Disable submit button
|
||||
submitBtn.disabled = true;
|
||||
submitBtn.innerHTML = '<span class="spinner-border spinner-border-sm me-2"></span>Creating...';
|
||||
|
||||
try {
|
||||
const formData = new FormData(this);
|
||||
const data = Object.fromEntries(formData.entries());
|
||||
|
||||
// Convert checkbox to boolean
|
||||
data.IsAllDay = formData.get('IsAllDay') === 'on';
|
||||
|
||||
const response = await fetch('@Url.Action("QuickCreate")', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'RequestVerificationToken': document.querySelector('input[name="__RequestVerificationToken"]').value
|
||||
},
|
||||
body: JSON.stringify(data)
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (result.success) {
|
||||
// Close modal
|
||||
const modal = bootstrap.Modal.getInstance(document.getElementById('quickCreateModal'));
|
||||
modal.hide();
|
||||
|
||||
// Show success toast
|
||||
showToast('success', result.message || 'Appointment created successfully');
|
||||
|
||||
// Reload calendar events
|
||||
if (typeof loadCalendarEvents === 'function') {
|
||||
loadCalendarEvents();
|
||||
}
|
||||
|
||||
// Reset form
|
||||
this.reset();
|
||||
} else {
|
||||
errorDiv.textContent = result.message || 'An error occurred';
|
||||
errorDiv.classList.remove('d-none');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error:', error);
|
||||
errorDiv.textContent = 'An unexpected error occurred';
|
||||
errorDiv.classList.remove('d-none');
|
||||
} finally {
|
||||
// Re-enable submit button
|
||||
submitBtn.disabled = false;
|
||||
submitBtn.innerHTML = '<i class="bi bi-check-circle"></i> Create Appointment';
|
||||
}
|
||||
});
|
||||
|
||||
// Toggle datetime/date input based on All Day checkbox
|
||||
document.getElementById('quickAllDay').addEventListener('change', function() {
|
||||
const startInput = document.getElementById('quickStart');
|
||||
const endInput = document.getElementById('quickEnd');
|
||||
|
||||
if (this.checked) {
|
||||
startInput.type = 'date';
|
||||
endInput.type = 'date';
|
||||
} else {
|
||||
startInput.type = 'datetime-local';
|
||||
endInput.type = 'datetime-local';
|
||||
}
|
||||
});
|
||||
|
||||
// Auto-update end time when start time changes
|
||||
document.getElementById('quickStart').addEventListener('change', function() {
|
||||
const endInput = document.getElementById('quickEnd');
|
||||
const isAllDay = document.getElementById('quickAllDay').checked;
|
||||
|
||||
// Always update end time based on start time
|
||||
if (isAllDay) {
|
||||
endInput.value = this.value;
|
||||
} else {
|
||||
const newEndTime = new Date(this.value);
|
||||
newEndTime.setHours(newEndTime.getHours() + 1);
|
||||
endInput.value = newEndTime.toISOString().slice(0, 16);
|
||||
}
|
||||
});
|
||||
|
||||
// Helper function to show toast notifications
|
||||
function showToast(type, message) {
|
||||
// Simple toast implementation - can be enhanced with Bootstrap Toast component
|
||||
const alertDiv = document.createElement('div');
|
||||
alertDiv.className = `alert alert-${type} alert-dismissible fade show position-fixed top-0 start-50 translate-middle-x mt-3`;
|
||||
alertDiv.style.zIndex = '9999';
|
||||
alertDiv.innerHTML = `
|
||||
<i class="bi bi-${type === 'success' ? 'check-circle' : 'exclamation-triangle'} me-2"></i>${message}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||
`;
|
||||
document.body.appendChild(alertDiv);
|
||||
|
||||
setTimeout(() => {
|
||||
alertDiv.remove();
|
||||
}, 5000);
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user