RatingBreakdown Social Proof
Gedetailleerde beoordelingsuitslitsing per categorie met balken.
src/components/social-proof/RatingBreakdown.astro
---
/**
* RatingBreakdown
* Gedetailleerde beoordelingsuitslitsing per categorie.
*/
interface Props {
headline?: string;
overallScore: number;
reviewCount: number;
breakdown: { label: string; score: number; max?: number }[];
platform?: string;
bg?: 'white' | 'light';
}
const { headline, overallScore, reviewCount, breakdown, platform = 'Google', bg = 'white' } = Astro.props;
---
<section class={`rb rb--${bg}`}>
<div class="rb-inner">
{headline && <h2 class="rb-headline">{headline}</h2>}
<div class="rb-content">
<div class="rb-summary">
<div class="rb-big-score">{overallScore.toFixed(1)}</div>
<div class="rb-stars">
{Array.from({length: Math.round(overallScore)}).map(() => <span class="rb-star">★</span>)}
</div>
<p class="rb-count">{reviewCount} reviews op {platform}</p>
</div>
<div class="rb-bars">
{breakdown.map(b => (
<div class="rb-bar-row">
<span class="rb-bar-label">{b.label}</span>
<div class="rb-bar-track">
<div class="rb-bar-fill" style={`width: ${((b.score / (b.max || 5)) * 100).toFixed(0)}%`}></div>
</div>
<span class="rb-bar-score">{b.score.toFixed(1)}</span>
</div>
))}
</div>
</div>
</div>
</section>
<style>
.rb { padding: 5rem 2rem; }
.rb--white { background: #fff; border-top: 1px solid #e5e7eb; }
.rb--light { background: #f8fafc; border-top: 1px solid #e5e7eb; }
.rb-inner { max-width: 800px; margin: 0 auto; }
.rb-headline { font-size: clamp(1.5rem, 3vw, 2.25rem); font-weight: 900; color: #0a0a0a; letter-spacing: -0.03em; line-height: 1.2; margin: 0 0 2.5rem; text-align: center; }
.rb-content { display: grid; grid-template-columns: auto 1fr; gap: 3rem; align-items: center; }
.rb-summary { text-align: center; }
.rb-big-score { font-size: 5rem; font-weight: 900; color: #0a0a0a; letter-spacing: -0.05em; line-height: 1; }
.rb-stars { display: flex; justify-content: center; gap: 0.25rem; margin: 0.5rem 0; }
.rb-star { color: #f59e0b; font-size: 1.25rem; }
.rb-count { font-size: 0.8125rem; color: #9ca3af; margin: 0; white-space: nowrap; }
.rb-bars { display: flex; flex-direction: column; gap: 1rem; }
.rb-bar-row { display: grid; grid-template-columns: 1fr auto auto; gap: 1rem; align-items: center; }
.rb-bar-label { font-size: 0.9375rem; color: #374151; font-weight: 500; }
.rb-bar-track { height: 8px; background: #e5e7eb; border-radius: 4px; overflow: hidden; min-width: 180px; }
.rb-bar-fill { height: 100%; background: var(--color-accent,#6366f1); border-radius: 4px; }
.rb-bar-score { font-size: 0.875rem; font-weight: 700; color: #0a0a0a; min-width: 2.5rem; text-align: right; }
@media (max-width: 600px) { .rb-content { grid-template-columns: 1fr; } .rb-summary { display: flex; align-items: center; gap: 1.5rem; } }
</style>
Props
| Prop | Type | Default | Beschrijving |
|---|---|---|---|
overallScore * | number | — | Totaalscore |
reviewCount * | number | — | Aantal reviews |
breakdown * | { label: string; score: number; max?: number }[] | — | Categoriebeoordelingen |
headline | string | — | Sectie headline |
platform | string | — | Platform naam |
bg | 'white' | 'light' | — | Achtergrond variant |
* = verplicht