{# Review Components ================= Product review display and submission components. Usage: {% from 'shared/macros/shop/reviews.html' import review_list, review_card, review_form, review_summary %} #} {% from 'shared/macros/shop/star-rating.html' import star_rating, rating_input, rating_summary %} {# Review Card =========== Individual product review display. Parameters: - review: Static review object - review_var: Alpine.js expression for review (dynamic) - show_avatar: Show reviewer avatar (default: true) - show_verified: Show verified purchase badge (default: true) - show_helpful: Show helpful buttons (default: true) - show_images: Show review images (default: true) - on_helpful: Callback for helpful button click Review structure: { id: 1, author_name: 'John D.', author_avatar: null, rating: 5, title: 'Great product!', content: 'Really happy with this purchase...', verified: true, created_at: '2025-01-15', helpful_count: 42, images: [] } Usage: {{ review_card(review_var='review') }} #} {% macro review_card( review=none, review_var=none, show_avatar=true, show_verified=true, show_helpful=true, show_images=true, on_helpful=none ) %} {% if review_var %}
{# Header #}
{% if show_avatar %}
{% endif %}
{% if show_verified %} Verified Purchase {% endif %}
{# Title #}

{# Content #}

{% if show_images %} {# Review Images #}
{% endif %} {% if show_helpful %} {# Helpful Actions #}
Was this review helpful?
{% endif %}
{% endif %} {% endmacro %} {# Review List =========== List of reviews with optional sorting and pagination. Parameters: - reviews_var: Alpine.js expression for reviews array - loading_var: Alpine.js expression for loading state - empty_message: Message when no reviews (default: 'No reviews yet') - show_sort: Show sort dropdown (default: true) - sort_var: Alpine.js var for sort value (default: 'reviewSort') - on_sort: Callback when sort changes Usage: {{ review_list(reviews_var='reviews', loading_var='loadingReviews') }} #} {% macro review_list( reviews_var='reviews', loading_var='loading', empty_message='No reviews yet. Be the first to review this product!', show_sort=true, sort_var='reviewSort', on_sort=none ) %}
{% if show_sort %} {# Sort Controls #}
reviews
{% for opt in [ {'value': 'newest', 'label': 'Newest'}, {'value': 'oldest', 'label': 'Oldest'}, {'value': 'highest', 'label': 'Highest Rated'}, {'value': 'lowest', 'label': 'Lowest Rated'}, {'value': 'helpful', 'label': 'Most Helpful'} ] %} {% endfor %}
{% endif %} {# Loading State #} {# Empty State #} {# Reviews #}
{% endmacro %} {# Review Form =========== Form for submitting a product review. Parameters: - rating_model: Alpine.js model for rating (default: 'newReview.rating') - title_model: Alpine.js model for title (default: 'newReview.title') - content_model: Alpine.js model for content (default: 'newReview.content') - images_model: Alpine.js model for images (default: 'newReview.images') - submitting_var: Alpine.js var for submitting state (default: 'submittingReview') - on_submit: Submit handler - show_images: Allow image upload (default: true) - require_purchase: Show purchase requirement message (default: false) Usage: {{ review_form(on_submit='submitReview()') }} #} {% macro review_form( rating_model='newReview.rating', title_model='newReview.title', content_model='newReview.content', images_model='newReview.images', submitting_var='submittingReview', on_submit='submitReview()', show_images=true, require_purchase=false ) %}

Write a Review

{% if require_purchase %}

You must have purchased this product to leave a review.

{% endif %} {# Rating #}
{{ rating_input(model=rating_model, size='lg') }}
{# Title #}
{# Content #}

Minimum 50 characters

{% if show_images %} {# Image Upload #}

Up to 5 photos

{% endif %} {# Submit Button #}

By submitting, you agree to our review guidelines.

{% endmacro %} {# Review Summary Section ====================== Complete review summary with rating distribution and write review button. Parameters: - rating_var: Alpine.js expression for average rating - count_var: Alpine.js expression for total reviews - distribution_var: Alpine.js expression for distribution - show_write_button: Show write review button (default: true) - on_write: Callback for write review button Usage: {{ review_summary_section(rating_var='product.rating', count_var='product.review_count', distribution_var='product.rating_distribution') }} #} {% macro review_summary_section( rating_var='rating', count_var='reviewCount', distribution_var='ratingDistribution', show_write_button=true, on_write='showReviewForm = true' ) %}
{# Rating Summary #}
{{ rating_summary(rating_var=rating_var, count_var=count_var, distribution_var=distribution_var) }}
{% if show_write_button %} {# Write Review CTA #}

Share your thoughts

Help others by sharing your experience with this product.

{% endif %}
{% endmacro %}