feat: Add complete reviews system with star ratings
✨ New Features: - Reviews system with 1-5 star ratings - User can add, edit, and delete their own reviews - One review per product per user (DB constraint) - Automatic average rating calculation - Review count tracking - Interactive star selection UI - AJAX-powered review submission - Responsive design for all devices 🗄️ Database: - New 'reviews' table with full structure - Added 'rating' and 'review_count' fields to products - PostgreSQL triggers for automatic rating updates - Database functions for rating calculations - Indexes for performance optimization 📦 Backend (PHP): - Review model with 15+ methods - ReviewController with 5 actions - Updated Product model to include ratings - Updated ProductController to load reviews - 5 new API endpoints 🎨 Frontend: - Reviews list component (_reviews_list.php) - Review form component (_review_form.php) - Reviews sechow page - Star ratings in catalog view - Interactive JavaScript (200+ lines) - Adaptive styles (400+ lines) 🔒 Security: - Server-side authorization checks - XSS protection (htmlspecialchars) - SQL injection protection (PDO prepared) - Input validation (client + server) - Access control for review editing 📝 Modified Files: - app/Models/Product.php - added rating fields to queries - app/Controllers/ProductController.php - loads reviews - app/Views/products/show.php - reviews section - app/Views/products/catalog.php - star ratings - config/routes.php - review endpoints - public/style_for_cite.less - rating styles 🆕 New Files: - app/Models/Review.php - app/Controllers/ReviewController.php - app/Views/products/_reviews_list.php - app/Views/products/_review_form.php
This commit is contained in:
@@ -148,19 +148,65 @@ p, li, span {
|
||||
.flex-center(10px);
|
||||
width: 200px;
|
||||
flex-shrink: 0;
|
||||
user-select: none;
|
||||
z-index: 1000;
|
||||
|
||||
&__menu {
|
||||
.menu-base();
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
width: 250px;
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
|
||||
padding: 15px;
|
||||
z-index: 10000;
|
||||
margin-top: 5px;
|
||||
display: none;
|
||||
pointer-events: auto;
|
||||
max-height: 400px;
|
||||
overflow-y: auto;
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
li {
|
||||
padding: 8px 0;
|
||||
cursor: pointer;
|
||||
transition: color 0.3s;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
list-style: none;
|
||||
&:last-child { border-bottom: none; }
|
||||
&:hover { color: @color-accent; }
|
||||
a {
|
||||
display: block;
|
||||
color: #333;
|
||||
text-decoration: none;
|
||||
padding: 5px 0;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
&:hover {
|
||||
color: @color-accent;
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
a {
|
||||
color: @color-accent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
&:hover &__menu { display: block; }
|
||||
|
||||
&:hover &__menu,
|
||||
&.active &__menu {
|
||||
display: block;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: #e8e8e8;
|
||||
}
|
||||
}
|
||||
|
||||
.search-box {
|
||||
@@ -943,6 +989,67 @@ p, li, span {
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
margin-bottom: 30px;
|
||||
|
||||
.stars {
|
||||
display: flex;
|
||||
gap: 2px;
|
||||
|
||||
.star {
|
||||
font-size: 18px;
|
||||
color: #ddd;
|
||||
|
||||
&.filled {
|
||||
color: #ffc107;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
// Global rating styles
|
||||
.rating-stars {
|
||||
display: flex;
|
||||
gap: 2px;
|
||||
|
||||
.star {
|
||||
font-size: 16px;
|
||||
color: #ddd;
|
||||
|
||||
&.filled {
|
||||
color: #ffc107;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Review rating styles for product cards
|
||||
.product-rating {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-top: 5px;
|
||||
|
||||
.stars {
|
||||
display: flex;
|
||||
gap: 1px;
|
||||
|
||||
.star {
|
||||
font-size: 14px;
|
||||
color: #ddd;
|
||||
|
||||
&.filled {
|
||||
color: #ffc107;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.rating-text {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
|
||||
.product__color-selector {
|
||||
|
||||
Reference in New Issue
Block a user