Diversen
This commit is contained in:
@@ -283,6 +283,19 @@
|
||||
💾
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="setting-group">
|
||||
<label for="pickup_confirmation_email_text">Ophaalbevestiging E-mail Tekst</label>
|
||||
<textarea
|
||||
id="pickup_confirmation_email_text"
|
||||
v-model="settings.pickup_confirmation_email_text"
|
||||
rows="8"
|
||||
placeholder="Standaard tekst voor ophaalbevestiging e-mail"
|
||||
></textarea>
|
||||
<button @click="updateSetting('pickup_confirmation_email_text', settings.pickup_confirmation_email_text)" class="save-btn" title="Opslaan">
|
||||
💾
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -321,25 +334,34 @@
|
||||
<strong>Gewenste Datum/Tijd:</strong> {{ formatDateTime(selectedRequest.requested_date, selectedRequest.requested_time) }}
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<strong>Status:</strong>
|
||||
<strong>Status:</strong>
|
||||
<select v-model="selectedRequest.status" @change="updateRequestStatus">
|
||||
<option value="pending">In afwachting</option>
|
||||
<option value="confirmed">Bevestigd</option>
|
||||
<option value="mail_sent">Bevestigd mail verstuurd</option>
|
||||
<option value="completed">Voltooid</option>
|
||||
<option value="cancelled">Geannuleerd</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<strong>Werkelijke Reparatie Datum:</strong>
|
||||
<strong>Werkelijke ophaalDatum:</strong>
|
||||
<input type="date" v-model="selectedRequest.actual_repair_date" @change="updateRequestDate" />
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<strong>Werkelijke Reparatie Tijd:</strong>
|
||||
<strong>Werkelijke ophaaltijd:</strong>
|
||||
<input type="time" v-model="selectedRequest.actual_repair_time" @change="updateRequestTime" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button
|
||||
@click="sendPickupConfirmation"
|
||||
class="btn-pickup-confirmation"
|
||||
:disabled="!selectedRequest?.email || !selectedRequest?.actual_repair_date || !selectedRequest?.actual_repair_time || pickupConfirmationLoading"
|
||||
title="Verstuur ophaalbevestiging e-mail naar klant"
|
||||
>
|
||||
{{ pickupConfirmationLoading ? '📧 Versturen...' : '📧 Ophaalbevestiging Versturen' }}
|
||||
</button>
|
||||
<button @click="closeRequestModal" class="btn-primary">Sluiten</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -522,6 +544,7 @@ export default {
|
||||
// Loading states
|
||||
const emailLoading = ref(false)
|
||||
const smsLoading = ref(false)
|
||||
const pickupConfirmationLoading = ref(false)
|
||||
|
||||
const tabs = [
|
||||
{ id: 'requests', label: 'Service Aanvragen' },
|
||||
@@ -542,6 +565,7 @@ export default {
|
||||
const statusMap = {
|
||||
'pending': 'In afwachting',
|
||||
'confirmed': 'Bevestigd',
|
||||
'mail_sent': 'Bevestigd mail verstuurd',
|
||||
'completed': 'Voltooid',
|
||||
'cancelled': 'Geannuleerd'
|
||||
}
|
||||
@@ -658,7 +682,7 @@ export default {
|
||||
const viewRequest = async (request) => {
|
||||
requestModalLoading.value = true
|
||||
showRequestModal.value = true
|
||||
|
||||
|
||||
// Get the latest data from the database to ensure we have the most current information
|
||||
try {
|
||||
const response = await fetch(`/api/service-requests/${request.id}`, {
|
||||
@@ -666,16 +690,29 @@ export default {
|
||||
})
|
||||
if (response.ok) {
|
||||
const latestRequest = await response.json()
|
||||
|
||||
// Format dates for HTML date inputs (YYYY-MM-DD)
|
||||
if (latestRequest.actual_repair_date) {
|
||||
// Extract just the date part if it's a datetime string
|
||||
latestRequest.actual_repair_date = latestRequest.actual_repair_date.split('T')[0]
|
||||
}
|
||||
|
||||
selectedRequest.value = { ...latestRequest }
|
||||
} else {
|
||||
// Fallback to local data if API call fails
|
||||
const latestRequest = requests.value.find(r => r.id === request.id)
|
||||
if (latestRequest && latestRequest.actual_repair_date) {
|
||||
latestRequest.actual_repair_date = latestRequest.actual_repair_date.split('T')[0]
|
||||
}
|
||||
selectedRequest.value = latestRequest ? { ...latestRequest } : { ...request }
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch latest request data:', error)
|
||||
// Fallback to local data if API call fails
|
||||
const latestRequest = requests.value.find(r => r.id === request.id)
|
||||
if (latestRequest && latestRequest.actual_repair_date) {
|
||||
latestRequest.actual_repair_date = latestRequest.actual_repair_date.split('T')[0]
|
||||
}
|
||||
selectedRequest.value = latestRequest ? { ...latestRequest } : { ...request }
|
||||
} finally {
|
||||
requestModalLoading.value = false
|
||||
@@ -764,7 +801,7 @@ export default {
|
||||
|
||||
const submitSms = async () => {
|
||||
if (!smsForm.value.message.trim()) return
|
||||
|
||||
|
||||
smsLoading.value = true
|
||||
try {
|
||||
const response = await fetch(`/api/service-requests/${selectedRequest.value.id}/send-sms`, {
|
||||
@@ -772,7 +809,7 @@ export default {
|
||||
headers: authStore.getAuthHeaders(),
|
||||
body: JSON.stringify({ message: smsForm.value.message })
|
||||
})
|
||||
|
||||
|
||||
if (response.ok) {
|
||||
closeSmsModal()
|
||||
await fetchRequests() // Refresh to show new communication
|
||||
@@ -783,6 +820,51 @@ export default {
|
||||
smsLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const sendPickupConfirmation = async () => {
|
||||
if (!selectedRequest.value?.email) {
|
||||
alert('Geen e-mailadres beschikbaar voor deze klant')
|
||||
return
|
||||
}
|
||||
|
||||
if (!selectedRequest.value?.actual_repair_date || !selectedRequest.value?.actual_repair_time) {
|
||||
alert('Vul eerst de werkelijke ophaaldatum en tijd in')
|
||||
return
|
||||
}
|
||||
|
||||
if (!confirm('Weet u zeker dat u de ophaalbevestiging wilt versturen naar ' + selectedRequest.value.email + '?')) {
|
||||
return
|
||||
}
|
||||
|
||||
pickupConfirmationLoading.value = true
|
||||
try {
|
||||
const response = await fetch(`/api/service-requests/${selectedRequest.value.id}/send-pickup-confirmation`, {
|
||||
method: 'POST',
|
||||
headers: authStore.getAuthHeaders()
|
||||
})
|
||||
|
||||
if (response.ok) {
|
||||
const data = await response.json()
|
||||
alert('Ophaalbevestiging succesvol verzonden!')
|
||||
|
||||
// Update the selected request with the new status
|
||||
if (data.service_request) {
|
||||
selectedRequest.value = data.service_request
|
||||
}
|
||||
|
||||
// Refresh the requests list
|
||||
await fetchRequests()
|
||||
} else {
|
||||
const error = await response.json()
|
||||
alert('Fout bij versturen: ' + (error.message || 'Onbekende fout'))
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to send pickup confirmation:', error)
|
||||
alert('Fout bij versturen van ophaalbevestiging')
|
||||
} finally {
|
||||
pickupConfirmationLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const editBlockedDate = (date) => {
|
||||
editingBlockedDate.value = date
|
||||
@@ -1045,6 +1127,7 @@ export default {
|
||||
communications,
|
||||
emailLoading,
|
||||
smsLoading,
|
||||
pickupConfirmationLoading,
|
||||
minDate,
|
||||
getStatusText,
|
||||
getCommTypeText,
|
||||
@@ -1063,6 +1146,7 @@ export default {
|
||||
viewCommunications,
|
||||
submitEmail,
|
||||
submitSms,
|
||||
sendPickupConfirmation,
|
||||
editBlockedDate,
|
||||
saveBlockedDate,
|
||||
deleteBlockedDate,
|
||||
@@ -1311,6 +1395,12 @@ export default {
|
||||
color: #0c5460;
|
||||
}
|
||||
|
||||
.status-badge.mail_sent {
|
||||
background: #e7d4c5;
|
||||
color: #6d5637;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.status-badge.completed {
|
||||
background: #d4edda;
|
||||
color: #155724;
|
||||
@@ -1604,16 +1694,24 @@ export default {
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
.setting-group input {
|
||||
.setting-group input,
|
||||
.setting-group textarea {
|
||||
padding: 0.75rem;
|
||||
border: 2px solid #e1e8ed;
|
||||
border-radius: 8px;
|
||||
font-size: 1rem;
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
.setting-group input:focus {
|
||||
.setting-group input:focus,
|
||||
.setting-group textarea:focus {
|
||||
outline: none;
|
||||
border-color: #3498db;
|
||||
border-color: var(--primary-color);
|
||||
}
|
||||
|
||||
.setting-group textarea {
|
||||
resize: vertical;
|
||||
min-height: 120px;
|
||||
}
|
||||
|
||||
.save-btn {
|
||||
@@ -1801,6 +1899,30 @@ export default {
|
||||
background: #5a6268;
|
||||
}
|
||||
|
||||
.btn-pickup-confirmation {
|
||||
padding: 0.75rem 1.5rem;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
font-size: 1rem;
|
||||
transition: all 0.3s ease;
|
||||
background: var(--secondary-color);
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.btn-pickup-confirmation:hover:not(:disabled) {
|
||||
background: var(--secondary-dark);
|
||||
box-shadow: 0 4px 10px rgba(139, 111, 71, 0.3);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.btn-pickup-confirmation:disabled {
|
||||
background: #bdc3c7;
|
||||
cursor: not-allowed;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
/* Form Styles */
|
||||
.form-group {
|
||||
display: flex;
|
||||
|
||||
@@ -93,7 +93,7 @@ export default {
|
||||
|
||||
.back-btn {
|
||||
display: inline-block;
|
||||
background: #6c757d;
|
||||
background: var(--secondary-color);
|
||||
color: white;
|
||||
padding: 0.75rem 1.5rem;
|
||||
text-decoration: none;
|
||||
@@ -103,7 +103,7 @@ export default {
|
||||
}
|
||||
|
||||
.back-btn:hover {
|
||||
background: #5a6268;
|
||||
background: var(--secondary-dark);
|
||||
}
|
||||
|
||||
.loading-state, .empty-state {
|
||||
@@ -114,7 +114,7 @@ export default {
|
||||
|
||||
.loading-spinner {
|
||||
border: 4px solid #f3f3f3;
|
||||
border-top: 4px solid #3498db;
|
||||
border-top: 4px solid var(--primary-color);
|
||||
border-radius: 50%;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
@@ -146,7 +146,7 @@ export default {
|
||||
.price-card:hover {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0 8px 25px rgba(0,0,0,0.15);
|
||||
border-color: #3498db;
|
||||
border-color: var(--primary-color);
|
||||
}
|
||||
|
||||
.price-header {
|
||||
@@ -165,7 +165,7 @@ export default {
|
||||
}
|
||||
|
||||
.price {
|
||||
background: #3498db;
|
||||
background: var(--primary-color);
|
||||
color: white;
|
||||
padding: 0.5rem 1rem;
|
||||
border-radius: 25px;
|
||||
@@ -184,7 +184,7 @@ export default {
|
||||
background: #f8f9fa;
|
||||
padding: 3rem 2rem;
|
||||
border-radius: 15px;
|
||||
border: 2px dashed #3498db;
|
||||
border: 2px dashed var(--primary-color);
|
||||
}
|
||||
|
||||
.cta-section h2 {
|
||||
@@ -200,7 +200,7 @@ export default {
|
||||
|
||||
.cta-button {
|
||||
display: inline-block;
|
||||
background: #3498db;
|
||||
background: var(--primary-color);
|
||||
color: white;
|
||||
padding: 1rem 2rem;
|
||||
text-decoration: none;
|
||||
@@ -211,7 +211,7 @@ export default {
|
||||
}
|
||||
|
||||
.cta-button:hover {
|
||||
background: #2980b9;
|
||||
background: var(--primary-dark);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
|
||||
Reference in New Issue
Block a user