Year in Review Page
v1.0.0Added in 1.8.0
A Wrapped-style year in review of a team's workspace: giant numbers, a chapter and chart per stat, a story player and a share poster.
The hero sets "2026, wrapped." in giant type beside a stack of drawn stat cards, and the tasks total rolls up once on load. A chapter strip under the hero (and, from 1280px, a sticky dot rail that follows the chapter in view) jumps to eight chapters: tasks per month, a year of daily activity, words written, hours saved by automations, top projects, favorite reactions, the hour-of-day clock that names the team early birds or night owls, and the MVPs. Each chapter's big number rolls up and its chart grows the first time it scrolls into view (everything is final in the server markup). Hover, tap or Tab to a month, a day, an hour or a point for its value. The personality card flips to show the scores behind it. Play your story (hero, strip or rail) opens a full-screen story player: one card per chapter with a progress bar on top that moves on by itself (paused with Space or the pause button, never under reduced motion); tap the left third or press Left to go back, tap the rest or press Right to move on, swipe sideways on touch, swipe down or press Escape to return to the page. The share section shows a drawn poster with Share (the system sheet where there is one), Copy link and Download image, each confirming inline.
Built with
The sections this page is made of. In the full-screen preview, hold Alt to outline each one on the page.
Add to a project
npx wingo-ui@latest add year-in-review-pagePro item: the CLI needs a Pro account. See plans
Usage
// app/(app)/wrapped/page.tsx
"use client"
import Link from "next/link"
import { YearInReviewPage } from "@/components/templates/year-in-review-page"
export default function WrappedRoute() {
return (
<YearInReviewPage
linkComponent={Link}
teamName="Northwind"
year={2026}
ctaTone="brand"
shareUrl="https://acme.com/wrapped/northwind-2026"
onShare={async (method, url) => {
if (method === "copy") await navigator.clipboard.writeText(url)
if (method === "download") window.open(`/api/wrapped/poster?team=northwind`, "_blank")
}}
/>
)
}Props
designdefault"classic""classic" | "vivid" | "mono"The whole page's look. classic: a soft glow hero beside drawn cards, chapters washed in their color, raised chart cards; vivid: a dark mesh hero, every chapter a saturated color band with light charts, a pill header, a band CTA and a wordmark footer; mono: no color at all, ink charts, rules between chapters, giant type, a transparent header and a simple footer. ctaProps, headerProps and footerProps still win.
modedefault"scroll""scroll" | "stories"scroll: the long page. stories: the full-screen story player opens over it; closing it (Escape, the X, a swipe down) returns to the page and calls onModeChange.
onModeChange(mode: YearInReviewPageMode) => voidRuns when the story player opens or closes.
storyDurationdefault6000numberMilliseconds each story card stays before the next one (1500 or more).
autoAdvancedefaulttruebooleanStory cards move on by themselves with a filling progress bar. Reduced motion always turns it off.
yeardefault2026numberThe year in the title, the poster and the story.
teamNamedefault"Northwind"stringThe team or workspace the year belongs to.
statsdefault"WRAPPED_STATS"WrappedStats{ tasks, docs, words, automationRuns, hoursSaved, comments, reactions, members, projects }: the year's totals.
monthsdefault"WRAPPED_MONTHS"WrappedMonth[]{ month (yyyy-mm), tasks, words, partial? } per month; partial hatches the month still in progress.
activitydefault"WRAPPED_ACTIVITY"WrappedDay[]{ date (yyyy-mm-dd), value } tasks shipped per day, for the heatmap, the busiest day and the streak.
endDatedefault"2026-10-11"stringThe last day the year covers (yyyy-mm-dd): the heatmap's last column and its today ring.
hoursdefault"WRAPPED_HOURS"number[]Tasks shipped per hour of the day, 12 AM first (24 values): the clock, the peak hour and the persona.
projectsdefault"WRAPPED_PROJECTS"WrappedProject[]{ id, name, tasks, lead }; the top five are ranked.
reactionsdefault"WRAPPED_REACTIONS"WrappedReaction[]{ emoji, label, count } most used reactions.
automationsdefault"WRAPPED_AUTOMATIONS"WrappedAutomation[]{ id, name, runs } top automations.
peopledefault"WRAPPED_PEOPLE"WrappedPerson[]{ id, name, role, title, value, unit, note, src? }: the MVPs and their superlatives.
personalitydefault"WRAPPED_PERSONALITY"WrappedPersonality{ name, tagline, description, rarity, traits: { label, score }[] } for the personality card.
longestDocdefault"WRAPPED_LONGEST_DOC"WrappedDoc{ title, author, words } named in the words chapter.
accentColorsdefault"WRAPPED_ACCENTS"string[]One CSS color per chapter (shipped, rhythm, words, autopilot, projects, reactions, persona, MVPs); also lights the hero, the personality card and the poster. Defaults to the chart palette. mono ignores it.
shareUrldefault"https://acme.com/wrapped/northwind-2026"stringThe link the share buttons hand out.
onShare(method: "copy" | "download" | "native", url: string) => (void | Promise<unknown>)Copy link, Download image and Share; a returned promise keeps the button loading, a rejection shows an error. Without it the page copies the link, pretends the download (900 ms) and opens the system share sheet where there is one (else copies).
labelsdefault"DEFAULT_YEAR_IN_REVIEW_PAGE_LABELS"Partial<YearInReviewPageLabels>Every visible string; {placeholders} are filled from the data.
showAnnouncementdefaulttruebooleanThe strip above the header bar.
showNavdefaulttruebooleanThe chapter strip under the hero and the sticky dot rail (from 1280px).
showShippeddefaulttruebooleanThe tasks per month chapter.
showRhythmdefaulttruebooleanThe daily activity heatmap chapter.
showWordsdefaulttruebooleanThe words written chapter.
showAutomationsdefaulttruebooleanThe hours saved chapter.
showProjectsdefaulttruebooleanThe top projects chapter.
showReactionsdefaulttruebooleanThe reactions chapter.
showPersonadefaulttruebooleanThe hour of day clock with the early bird or night owl persona.
showPeopledefaulttruebooleanThe MVPs chapter.
showPersonalitydefaulttruebooleanThe personality card (and its story card).
showSharedefaulttruebooleanThe share section with the poster.
showCtadefaulttruebooleanThe closing call to action.
ctaVariantdefault"inverted""inverted" | "soft" | "split"The closing band: a solid band, a gray band, or copy beside the buttons on a raised panel. Applies to the classic design.
tonedefault"neutral""neutral" | "brand" | "success" | "warning" | "danger" | "info"The active dot of the chapter rail and the personality score bars.
ctaTonedefault"neutral""neutral" | "brand" | "success" | "warning" | "danger" | "info"Play your story, Share, the header's Get started and the closing band; brand is the marketing orange.
headerdefaulttruebooleanThe marketing header; off inside a site or app layout.
footerdefaulttruebooleanThe marketing footer with its newsletter form.
headerPropsPartial<MarketingHeaderProps>Passed to MarketingHeader.
footerPropsPartial<MarketingFooterProps>Passed to MarketingFooter.
ctaPropsPartial<CtaSectionProps>Overrides for the closing CtaSection (hrefs, labels, variant...).
onSubscribe(email: string) => (void | Promise<unknown>)The footer newsletter; a rejected promise shows an error.
animateIndefaulttruebooleanBig numbers roll up and charts grow the first time they scroll into view; false keeps the page still (thumbnails). Reduced motion always does.
localedefault"en-US"stringIntl locale for the numbers, months, days and hours.
linkComponentdefault"<a>"(props: LinkComponentProps) => ReactNodeThe router link for every link on the page (next/link in an app).
classNamestringClasses for the root.
classNamesPartial<Record<YearInReviewPageSlot, string>>Classes for header, hero, title, counter, art, chapters, nav, chapter, panel, people, personality, share, poster, story, cta and footer.
Parts
YEAR_IN_REVIEW_SAMPLE
constantAll the sample content in one object: stats, months, activity, hours, projects, reactions, automations, people, personality and longestDoc.
WRAPPED_STATS
constantNorthwind's totals: 12,480 tasks, 1,284 docs, 612,400 words, 48,920 automation runs, 1,860 hours saved.
WRAPPED_MONTHS
constantJanuary to October 2026, October still in progress.
WRAPPED_ACTIVITY
constant284 days of seeded activity that add up to each month's total.
WRAPPED_END_DATE
constant"2026-10-11", the last day of the sample.
WRAPPED_HOURS
constantTasks per hour of the day, peaking at 10 AM.
WRAPPED_PROJECTS
constantThe five busiest projects with their leads.
WRAPPED_REACTIONS
constantSix reactions, 🚀 first.
WRAPPED_AUTOMATIONS
constantThe four automations that ran the most.
WRAPPED_PEOPLE
constantSix MVPs with a superlative each.
WRAPPED_PERSONALITY
constantThe Steady Shippers, with four trait scores.
WRAPPED_LONGEST_DOC
constantThe longest doc of the year.
WRAPPED_ACCENTS
constantThe default chapter colors: the chart palette's series vars, ordered so neighbours differ.
DEFAULT_YEAR_IN_REVIEW_PAGE_LABELS
constantThe English strings.
YEAR_IN_REVIEW_PAGE_DESIGNS
constantThe design names, classic first: ["classic", "vivid", "mono"].
YearInReviewPageProps
typeProps of YearInReviewPage.
YearInReviewPageDesign
type"classic" | "vivid" | "mono".
YearInReviewPageMode
type"scroll" | "stories".
YearInReviewChapter
typeThe chapter keys, in page order.
YearInReviewPageLabels
typeThe strings labels can override.
YearInReviewPageSlot
typeThe classNames keys.
WrappedStats
typeThe year's totals.
WrappedMonth
typeOne month: tasks, words, partial.
WrappedDay
typeOne day of activity.
WrappedProject
typeOne ranked project.
WrappedReaction
typeOne reaction and its count.
WrappedAutomation
typeOne automation and its runs.
WrappedPerson
typeOne MVP and the superlative.
WrappedPersonality
typeThe personality card's content.
WrappedTrait
typeOne personality score.
WrappedDoc
typeA doc named in the words chapter.
Examples
Vivid design
design="vivid": a dark mesh hero, every chapter a saturated color band with light charts, a pill header and a wordmark footer.
Mono design
design="mono": no color at all. Ink charts, hairline rules between chapters, giant type and a transparent header.
Story mode
mode="stories": the full-screen player opens on load. Tap the sides, swipe or use the arrow keys; Escape returns to the page.
Brand orange, custom colors
ctaTone and tone brand, with accentColors swapped for a warm palette and the closing band split.
Embedded, short
Without the marketing header and footer, the people and reactions chapters hidden: a Wrapped inside your app.
Dependencies
Files
- components/templates/year-in-review-page.tsx
- components/templates/year-in-review-page-data.ts