Reviews and ratings
Average score, breakdown and written reviews.
Onboarding programme reviews
What Northwind new starters said 30 days after joining.
Overall score
186 responses
- 5 stars54%
- 4 stars30%
- 3 stars11%
- 2 stars4%
- 1 star1%
Up from 4.1 last quarter.
Written reviews
- Luis OrtegaFrontend engineer · 2 Oct 2026Engineering
Laptop and accounts ready on day one
IT had my laptop set up before I arrived, and my buddy walked me through the codebase on day two. Best start I’ve had anywhere.
- Yuki TanakaRecruiter · 28 Sep 2026People Ops
Clear plan, slightly too many sessions
The first-week checklist kept me on track. A few welcome sessions overlapped, so I’d merge the culture and values talks.
- Mia JensenProduct manager · 21 Sep 2026Product
Felt part of the team quickly
Shipped a small change in week one. The Copenhagen team lunch on Friday was a great touch.
- Chloe MartinData analyst · 14 Sep 2026Finance
Payroll set-up was confusing
Bank details had to be entered twice and the pension opt-out deadline wasn’t explained. Everything else was smooth.
- Omar HaddadSupport lead · 3 Sep 2026Customer
Great buddy programme
Having a named buddy outside my team made it easy to ask the questions I didn’t want to ask my manager.
reviews-and-ratings.tsx
"use client";
import { useState } from "react";
import { Avatar, Badge, Rating, RatingSummary, Segment, SegmentedControl } from "@nexera-ui/react";
// Sample data
interface Person {
id: string;
name: string;
initials: string;
role: string;
team: string;
email: string;
location: string;
status: "Active" | "On leave" | "Remote" | "Invited";
}
const PEOPLE: Person[] = [
{
id: "p1",
name: "Ayesha Khan",
initials: "AK",
role: "Senior product designer",
team: "Design",
email: "ayesha.khan@northwind.io",
location: "London",
status: "Active",
},
{
id: "p2",
name: "Sara Malik",
initials: "SM",
role: "Payroll specialist",
team: "People Ops",
email: "sara.malik@northwind.io",
location: "Lisbon",
status: "On leave",
},
{
id: "p3",
name: "Ahmed Raza",
initials: "AR",
role: "Engineering manager",
team: "Engineering",
email: "ahmed.raza@northwind.io",
location: "Lahore",
status: "Remote",
},
{
id: "p4",
name: "Mia Jensen",
initials: "MJ",
role: "Product manager",
team: "Product",
email: "mia.jensen@northwind.io",
location: "Copenhagen",
status: "Active",
},
{
id: "p5",
name: "Luis Ortega",
initials: "LO",
role: "Frontend engineer",
team: "Engineering",
email: "luis.ortega@northwind.io",
location: "Madrid",
status: "Active",
},
{
id: "p6",
name: "Yuki Tanaka",
initials: "YT",
role: "Recruiter",
team: "People Ops",
email: "yuki.tanaka@northwind.io",
location: "Tokyo",
status: "Active",
},
{
id: "p7",
name: "Chloe Martin",
initials: "CM",
role: "Data analyst",
team: "Finance",
email: "chloe.martin@northwind.io",
location: "Paris",
status: "Remote",
},
{
id: "p8",
name: "Omar Haddad",
initials: "OH",
role: "Support lead",
team: "Customer",
email: "omar.haddad@northwind.io",
location: "Dubai",
status: "Invited",
},
];
type Sort = "recent" | "highest" | "lowest";
const REVIEWS = [
{
id: "r1",
person: PEOPLE[4],
rating: 5,
date: "2 Oct 2026",
order: 6,
title: "Laptop and accounts ready on day one",
text: "IT had my laptop set up before I arrived, and my buddy walked me through the codebase on day two. Best start I’ve had anywhere.",
},
{
id: "r2",
person: PEOPLE[5],
rating: 4,
date: "28 Sep 2026",
order: 5,
title: "Clear plan, slightly too many sessions",
text: "The first-week checklist kept me on track. A few welcome sessions overlapped, so I’d merge the culture and values talks.",
},
{
id: "r3",
person: PEOPLE[3],
rating: 5,
date: "21 Sep 2026",
order: 4,
title: "Felt part of the team quickly",
text: "Shipped a small change in week one. The Copenhagen team lunch on Friday was a great touch.",
},
{
id: "r4",
person: PEOPLE[6],
rating: 3,
date: "14 Sep 2026",
order: 3,
title: "Payroll set-up was confusing",
text: "Bank details had to be entered twice and the pension opt-out deadline wasn’t explained. Everything else was smooth.",
},
{
id: "r5",
person: PEOPLE[7],
rating: 4,
date: "3 Sep 2026",
order: 2,
title: "Great buddy programme",
text: "Having a named buddy outside my team made it easy to ask the questions I didn’t want to ask my manager.",
},
].flatMap(({ person, ...rest }) => (person ? [{ person, ...rest }] : []));
const DISTRIBUTION = [
{ stars: 5, percent: 54 },
{ stars: 4, percent: 30 },
{ stars: 3, percent: 11 },
{ stars: 2, percent: 4 },
{ stars: 1, percent: 1 },
];
/** Reviews and ratings: the average score, the share of each star level and written reviews. */
export default function ReviewsAndRatings() {
const [sort, setSort] = useState<Sort>("recent");
const sorted = [...REVIEWS].sort((a, b) =>
sort === "recent"
? b.order - a.order
: sort === "highest"
? b.rating - a.rating
: a.rating - b.rating,
);
return (
<div className="@container bg-page px-4 py-8 @3xl:px-8">
<div className="mx-auto grid w-full max-w-4xl gap-6">
<header className="grid gap-1">
<h2 className="text-heading-h2 text-primary">Onboarding programme reviews</h2>
<p className="text-body-default text-secondary">
What Northwind new starters said 30 days after joining.
</p>
</header>
<div className="grid gap-6 @3xl:grid-cols-[18rem_minmax(0,1fr)] @3xl:items-start">
<section
aria-labelledby="summary-title"
className="grid gap-3 rounded-xl border border-default bg-surface p-5 shadow-xs"
>
<h3 id="summary-title" className="text-heading-h4 text-primary">
Overall score
</h3>
<RatingSummary
value={4.4}
average="4.4"
total="186 responses"
distribution={DISTRIBUTION}
/>
<p className="text-body-small text-secondary">Up from 4.1 last quarter.</p>
</section>
<section aria-labelledby="reviews-title" className="grid gap-4">
<div className="flex flex-wrap items-center justify-between gap-3">
<h3 id="reviews-title" className="text-heading-h4 text-primary">
Written reviews
</h3>
<SegmentedControl
aria-label="Sort reviews"
selectedKeys={[sort]}
onSelectionChange={(keys) => {
const [next] = [...keys];
if (next === "recent" || next === "highest" || next === "lowest") setSort(next);
}}
>
<Segment id="recent" label="Recent" />
<Segment id="highest" label="Highest" />
<Segment id="lowest" label="Lowest" />
</SegmentedControl>
</div>
<ul className="m-0 grid list-none gap-3 p-0">
{sorted.map((review) => (
<li key={review.id}>
<article
aria-labelledby={`${review.id}-title`}
className="grid gap-3 rounded-xl border border-default bg-surface p-4"
>
<div className="flex flex-wrap items-center gap-3">
<Avatar size="md" initials={review.person.initials} isDecorative />
<div className="grid min-w-0 flex-1">
<span className="text-body-strong text-primary">{review.person.name}</span>
<span className="text-body-caption text-muted">
{review.person.role} · {review.date}
</span>
</div>
<Badge tone="neutral" label={review.person.team} dot={false} />
</div>
<Rating value={review.rating} />
<h4 id={`${review.id}-title`} className="text-body-strong text-primary">
{review.title}
</h4>
<p className="text-body-default text-secondary">{review.text}</p>
</article>
</li>
))}
</ul>
</section>
</div>
</div>
</div>
);
}
More commerce and payments blocks
- Pricing plansMonthly or yearly plans with a recommended one.
- CheckoutCard details, billing address and order total.
- Saved payment methodsChoose, add or remove a card.
- Order summaryItems, discounts and totals.
- PayslipEarnings and deductions with totals.
- Product galleryPhotos with thumbnails and zoom.
- Order trackingWhere an order is, step by step.