375 lines
16 KiB
XML
375 lines
16 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<odoo>
|
|
<!-- Web Rating Form Template -->
|
|
<template id="rating_form_page" name="Rating Form Page">
|
|
<t t-call="web.layout">
|
|
<t t-set="head">
|
|
<style>
|
|
.rating_form_container {
|
|
max-width: 600px;
|
|
margin: 80px auto;
|
|
padding: 40px;
|
|
text-align: center;
|
|
background: #ffffff;
|
|
border-radius: 8px;
|
|
box-shadow: 0 2px 12px rgba(0,0,0,0.15);
|
|
}
|
|
.rating_form_title {
|
|
font-size: 28px;
|
|
font-weight: 600;
|
|
color: #212529;
|
|
margin-bottom: 16px;
|
|
}
|
|
.rating_form_description {
|
|
font-size: 16px;
|
|
color: #6c757d;
|
|
margin-bottom: 32px;
|
|
line-height: 1.6;
|
|
}
|
|
.rating_form_ticket_info {
|
|
background: #f8f9fa;
|
|
padding: 16px;
|
|
border-radius: 6px;
|
|
margin-bottom: 32px;
|
|
font-size: 14px;
|
|
color: #495057;
|
|
}
|
|
.rating_form_ticket_info strong {
|
|
color: #212529;
|
|
}
|
|
.rating_form_widget_container {
|
|
margin: 32px 0;
|
|
display: flex;
|
|
justify-content: center;
|
|
}
|
|
.rating_form_submit_container {
|
|
margin-top: 32px;
|
|
}
|
|
.rating_form_submit_btn {
|
|
background: #007bff;
|
|
color: white;
|
|
border: none;
|
|
padding: 12px 32px;
|
|
font-size: 16px;
|
|
font-weight: 500;
|
|
border-radius: 6px;
|
|
cursor: pointer;
|
|
transition: background 0.2s;
|
|
}
|
|
.rating_form_submit_btn:hover {
|
|
background: #0056b3;
|
|
}
|
|
.rating_form_submit_btn:disabled {
|
|
background: #6c757d;
|
|
cursor: not-allowed;
|
|
}
|
|
.rating_form_feedback {
|
|
margin-top: 24px;
|
|
}
|
|
.rating_form_feedback textarea {
|
|
width: 100%;
|
|
min-height: 100px;
|
|
padding: 12px;
|
|
border: 1px solid #ced4da;
|
|
border-radius: 6px;
|
|
font-size: 14px;
|
|
font-family: inherit;
|
|
resize: vertical;
|
|
}
|
|
.rating_form_feedback textarea:focus {
|
|
outline: none;
|
|
border-color: #007bff;
|
|
box-shadow: 0 0 0 3px rgba(0,123,255,0.1);
|
|
}
|
|
.rating_form_feedback_label {
|
|
display: block;
|
|
text-align: left;
|
|
font-size: 14px;
|
|
font-weight: 500;
|
|
color: #495057;
|
|
margin-bottom: 8px;
|
|
}
|
|
@media (max-width: 768px) {
|
|
.rating_form_container {
|
|
margin: 40px 20px;
|
|
padding: 24px;
|
|
}
|
|
.rating_form_title {
|
|
font-size: 24px;
|
|
}
|
|
}
|
|
</style>
|
|
</t>
|
|
<div class="rating_form_container">
|
|
<h1 class="rating_form_title">Rate Your Experience</h1>
|
|
<p class="rating_form_description">
|
|
We value your feedback! Please rate your experience with our support team.
|
|
</p>
|
|
|
|
<t t-if="ticket_name">
|
|
<div class="rating_form_ticket_info">
|
|
<strong>Ticket:</strong> <t t-esc="ticket_name"/>
|
|
</div>
|
|
</t>
|
|
|
|
<form id="rating_form" method="POST" t-att-action="'/rating/' + token + '/submit'">
|
|
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
|
|
<input type="hidden" id="rating_value_input" name="rating_value" value="0"/>
|
|
|
|
<div class="rating_form_widget_container">
|
|
<div id="rating_stars_widget" class="rating-stars-container rating-stars-large">
|
|
<span class="rating-star rating-star-empty rating-star-interactive" data-star="1" role="button" aria-label="Rate 1 star out of 5">☆</span>
|
|
<span class="rating-star rating-star-empty rating-star-interactive" data-star="2" role="button" aria-label="Rate 2 stars out of 5">☆</span>
|
|
<span class="rating-star rating-star-empty rating-star-interactive" data-star="3" role="button" aria-label="Rate 3 stars out of 5">☆</span>
|
|
<span class="rating-star rating-star-empty rating-star-interactive" data-star="4" role="button" aria-label="Rate 4 stars out of 5">☆</span>
|
|
<span class="rating-star rating-star-empty rating-star-interactive" data-star="5" role="button" aria-label="Rate 5 stars out of 5">☆</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="rating_form_feedback">
|
|
<label class="rating_form_feedback_label" for="feedback_text">
|
|
Additional Comments (Optional)
|
|
</label>
|
|
<textarea
|
|
id="feedback_text"
|
|
name="feedback"
|
|
placeholder="Tell us more about your experience..."
|
|
maxlength="1000">
|
|
</textarea>
|
|
</div>
|
|
|
|
<div class="rating_form_submit_container">
|
|
<button type="submit"
|
|
class="rating_form_submit_btn"
|
|
id="submit_rating_btn"
|
|
disabled="disabled">
|
|
Submit Rating
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<script type="text/javascript">
|
|
// Initialize the rating widget when DOM is ready
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const widgetContainer = document.getElementById('rating_stars_widget');
|
|
const ratingInput = document.getElementById('rating_value_input');
|
|
const submitBtn = document.getElementById('submit_rating_btn');
|
|
const stars = widgetContainer.querySelectorAll('.rating-star');
|
|
|
|
let selectedRating = 0;
|
|
let hoverRating = 0;
|
|
|
|
// Update star display
|
|
function updateStars(rating) {
|
|
stars.forEach(function(star, index) {
|
|
const starValue = index + 1;
|
|
if (starValue <= rating) {
|
|
star.textContent = '★';
|
|
star.classList.remove('rating-star-empty');
|
|
star.classList.add('rating-star-filled');
|
|
} else {
|
|
star.textContent = '☆';
|
|
star.classList.remove('rating-star-filled');
|
|
star.classList.add('rating-star-empty');
|
|
}
|
|
});
|
|
}
|
|
|
|
// Handle star click
|
|
stars.forEach(function(star) {
|
|
star.addEventListener('click', function() {
|
|
selectedRating = parseInt(this.getAttribute('data-star'));
|
|
ratingInput.value = selectedRating;
|
|
submitBtn.disabled = false;
|
|
updateStars(selectedRating);
|
|
});
|
|
|
|
// Handle hover
|
|
star.addEventListener('mouseenter', function() {
|
|
hoverRating = parseInt(this.getAttribute('data-star'));
|
|
updateStars(hoverRating);
|
|
});
|
|
});
|
|
|
|
// Handle mouse leave from container
|
|
widgetContainer.addEventListener('mouseleave', function() {
|
|
hoverRating = 0;
|
|
updateStars(selectedRating);
|
|
});
|
|
|
|
// Keyboard navigation
|
|
widgetContainer.setAttribute('tabindex', '0');
|
|
widgetContainer.addEventListener('keydown', function(e) {
|
|
let handled = false;
|
|
|
|
switch(e.key) {
|
|
case 'ArrowRight':
|
|
case 'ArrowUp':
|
|
if (selectedRating < 5) {
|
|
selectedRating++;
|
|
ratingInput.value = selectedRating;
|
|
submitBtn.disabled = false;
|
|
updateStars(selectedRating);
|
|
}
|
|
handled = true;
|
|
break;
|
|
|
|
case 'ArrowLeft':
|
|
case 'ArrowDown':
|
|
if (selectedRating > 1) {
|
|
selectedRating--;
|
|
ratingInput.value = selectedRating;
|
|
submitBtn.disabled = false;
|
|
updateStars(selectedRating);
|
|
}
|
|
handled = true;
|
|
break;
|
|
|
|
case 'Home':
|
|
selectedRating = 1;
|
|
ratingInput.value = selectedRating;
|
|
submitBtn.disabled = false;
|
|
updateStars(selectedRating);
|
|
handled = true;
|
|
break;
|
|
|
|
case 'End':
|
|
selectedRating = 5;
|
|
ratingInput.value = selectedRating;
|
|
submitBtn.disabled = false;
|
|
updateStars(selectedRating);
|
|
handled = true;
|
|
break;
|
|
}
|
|
|
|
if (handled) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
}
|
|
});
|
|
});
|
|
</script>
|
|
</t>
|
|
</template>
|
|
|
|
<!-- Rating Confirmation Page -->
|
|
<template id="rating_confirmation_page" name="Rating Confirmation Page">
|
|
<t t-call="web.layout">
|
|
<t t-set="head">
|
|
<style>
|
|
.rating_confirmation_container {
|
|
max-width: 600px;
|
|
margin: 80px auto;
|
|
padding: 40px;
|
|
text-align: center;
|
|
background: #f8f9fa;
|
|
border-radius: 8px;
|
|
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
|
}
|
|
.rating_stars_display {
|
|
font-size: 48px;
|
|
color: #ffc107;
|
|
margin: 20px 0;
|
|
letter-spacing: 4px;
|
|
}
|
|
.rating_confirmation_title {
|
|
font-size: 28px;
|
|
font-weight: 600;
|
|
color: #28a745;
|
|
margin-bottom: 16px;
|
|
}
|
|
.rating_confirmation_message {
|
|
font-size: 16px;
|
|
color: #6c757d;
|
|
line-height: 1.6;
|
|
}
|
|
.rating_checkmark {
|
|
font-size: 64px;
|
|
color: #28a745;
|
|
margin-bottom: 20px;
|
|
}
|
|
.rating_update_notice {
|
|
background: #fff3cd;
|
|
border: 1px solid #ffc107;
|
|
border-radius: 6px;
|
|
padding: 12px;
|
|
margin-top: 20px;
|
|
font-size: 14px;
|
|
color: #856404;
|
|
}
|
|
</style>
|
|
</t>
|
|
<div class="rating_confirmation_container">
|
|
<div class="rating_checkmark">✓</div>
|
|
<h1 class="rating_confirmation_title">
|
|
<t t-if="is_update">Rating Updated!</t>
|
|
<t t-else="">Thank You for Your Feedback!</t>
|
|
</h1>
|
|
<div class="rating_stars_display">
|
|
<t t-esc="stars_html"/>
|
|
</div>
|
|
<p class="rating_confirmation_message">
|
|
<t t-if="is_update">
|
|
Your rating has been updated to <strong><t t-esc="rating_value"/> stars</strong>.
|
|
<br/>
|
|
Thank you for updating your feedback.
|
|
</t>
|
|
<t t-else="">
|
|
Your rating of <strong><t t-esc="rating_value"/> stars</strong> has been recorded successfully.
|
|
<br/>
|
|
We appreciate you taking the time to share your experience with us.
|
|
</t>
|
|
</p>
|
|
<t t-if="is_update">
|
|
<div class="rating_update_notice">
|
|
<strong>Note:</strong> Your previous rating has been replaced with this new rating.
|
|
</div>
|
|
</t>
|
|
</div>
|
|
</t>
|
|
</template>
|
|
|
|
<!-- Rating Error Page -->
|
|
<template id="rating_error_page" name="Rating Error Page">
|
|
<t t-call="web.layout">
|
|
<t t-set="head">
|
|
<style>
|
|
.rating_error_container {
|
|
max-width: 600px;
|
|
margin: 80px auto;
|
|
padding: 40px;
|
|
text-align: center;
|
|
background: #f8f9fa;
|
|
border-radius: 8px;
|
|
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
|
}
|
|
.rating_error_icon {
|
|
font-size: 64px;
|
|
color: #dc3545;
|
|
margin-bottom: 20px;
|
|
}
|
|
.rating_error_title {
|
|
font-size: 28px;
|
|
font-weight: 600;
|
|
color: #dc3545;
|
|
margin-bottom: 16px;
|
|
}
|
|
.rating_error_message {
|
|
font-size: 16px;
|
|
color: #6c757d;
|
|
line-height: 1.6;
|
|
}
|
|
</style>
|
|
</t>
|
|
<div class="rating_error_container">
|
|
<div class="rating_error_icon">⚠</div>
|
|
<h1 class="rating_error_title"><t t-esc="error_title"/></h1>
|
|
<p class="rating_error_message">
|
|
<t t-esc="error_message"/>
|
|
</p>
|
|
</div>
|
|
</t>
|
|
</template>
|
|
</odoo>
|