Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Contributing to Trophy UI
# Contributing to Gamification UI Kit by Trophy

Thank you for helping improve [Trophy UI](https://ui.trophy.so). This document explains how to set up the repo locally, run the site and tooling, and what we look for in contributions.
Thank you for helping improve [Gamification UI Kit by Trophy](https://ui.trophy.so). This document explains how to set up the repo locally, run the site and tooling, and what we look for in contributions.

## Prerequisites

Expand Down
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
![Trophy UI](./assets/readme-hero.png)
![Gamification UI Kit by Trophy](./assets/readme-hero.png)

# Trophy UI
# Gamification UI Kit by Trophy

[Trophy UI](https://ui.trophy.so) is a component library built on top of [shadcn/ui](https://ui.shadcn.com/) to help you build gamification experiences faster.
[Gamification UI Kit by Trophy](https://ui.trophy.so) is a component library built on top of [shadcn/ui](https://ui.shadcn.com/) to help you build gamification experiences faster.

## Overview

Trophy UI provides pre-built, customizable React components for gamification—streaks, achievements, leaderboards, points, XP charts, event banners, and more. The [shadcn/ui](https://ui.shadcn.com/) CLI pulls components straight from the registry so you can own the code and tailor it to your product.
Trophy's Gamification UI Kit provides pre-built, customizable React components for gamification—streaks, achievements, leaderboards, points, XP charts, event banners, and more. The [shadcn/ui](https://ui.shadcn.com/) CLI pulls components straight from the registry so you can own the code and tailor it to your product.

## Installation

Expand All @@ -18,7 +18,7 @@ npx shadcn@latest add https://ui.trophy.so/streak-badge

## Prerequisites

Before using Trophy UI, ensure your project meets these requirements:
Before using Trophy's Gamification UI Kit, ensure your project meets these requirements:

- **Node.js 18** or later
- **React 18+** — components are client-side React
Expand All @@ -35,7 +35,7 @@ Install every registry component at once:
npx shadcn@latest add https://ui.trophy.so/all
```

This adds Trophy UI components (and any shared primitives they depend on) into your configured components directory.
This adds components (and any shared primitives they depend on) into your configured components directory.

### Install specific components

Expand Down Expand Up @@ -65,7 +65,7 @@ Browse the full set on the docs site: [Components](https://ui.trophy.so/docs/com

## Contributing

If you would like to contribute to Trophy UI:
If you would like to contribute to Gamification UI Kit by Trophy:

1. Fork the repository
2. Create a branch for your change
Expand Down
12 changes: 10 additions & 2 deletions apps/www/.source/source.config.mjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
// source.config.ts
import { defineConfig, defineDocs } from "fumadocs-mdx/config";
import { defineConfig, defineDocs, frontmatterSchema } from "fumadocs-mdx/config";
import { z } from "zod";
var docsPageSchema = frontmatterSchema.extend({
seoTitle: z.string().optional(),
keywords: z.array(z.string()).optional()
});
var docs = defineDocs({
dir: "content/docs"
dir: "content/docs",
docs: {
schema: docsPageSchema
}
});
var source_config_default = defineConfig({
mdxOptions: {
Expand Down
194 changes: 186 additions & 8 deletions apps/www/app/(app)/(root)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,120 @@ import {
PageHeaderHeading,
} from "@/components/page-header"
import { Button } from "@/registry/trophy/ui/button"
import { TextAnimate } from "@/components/ui/text-animate"

export const dynamic = "force-static"
export const revalidate = false

export const metadata: Metadata = {
title: {
template: `%s | ${siteConfig.title}`,
default: `${siteConfig.tagline} | ${siteConfig.title}`,
default: siteConfig.title,
},
description: siteConfig.description,
keywords: siteConfig.keywords,
openGraph: {
title: `${siteConfig.tagline} | ${siteConfig.title}`,
title: siteConfig.title,
description: siteConfig.description,
url: siteConfig.url,
siteName: siteConfig.title,
images: [{ url: siteConfig.ogImage }],
locale: "en_US",
type: "website",
},
twitter: {
card: "summary_large_image",
title: siteConfig.title,
description: siteConfig.description,
images: [siteConfig.ogImage],
},
alternates: {
canonical: siteConfig.url,
},
metadataBase: new URL(siteConfig.url),
}

const jsonLd = {
"@context": "https://schema.org",
"@type": "SoftwareApplication",
name: "Gamification UI Kit by Trophy",
applicationCategory: "DeveloperApplication",
operatingSystem: "Any",
description: siteConfig.description,
url: siteConfig.url,
keywords:
"gamification UI kit, gamification component library, open source gamification UI, free gamification components, React gamification, Next.js gamification, shadcn gamification, shadcn registry, Tailwind gamification, streak component, achievement component, leaderboard component, points component",
featureList: [
"Streak tracking components",
"Achievement badges and cards",
"Leaderboard rankings and podiums",
"Points displays and level systems",
"Built on shadcn/ui and Tailwind CSS for React and Next.js",
"Install with the shadcn CLI from this open registry",
"Fully customizable and open source",
],
softwareHelp: {
"@type": "CreativeWork",
url: `${siteConfig.url}/docs`,
},
author: {
"@type": "Organization",
name: "Trophy",
url: "https://trophy.so",
},
}

const categories = [
{
title: "Streak Components",
description:
"Keep users coming back with streak tracking UI. Display daily streaks, streak calendars, and streak badges that motivate consistent engagement.",
href: "/docs/components/streak-card",
components: ["Streak Card", "Streak Calendar", "Streak Badge"],
},
{
title: "Achievement Components",
description:
"Celebrate milestones with achievement badges, unlock animations, and achievement grids. Give users a sense of progress and accomplishment.",
href: "/docs/components/achievement-badge",
components: [
"Achievement Badge",
"Achievement Card",
"Achievement Grid",
"Achievement List",
"Achievement Unlocked",
],
},
{
title: "Leaderboard Components",
description:
"Drive competition with leaderboard rankings, podium displays, and leaderboard cards. Show users where they stand among peers.",
href: "/docs/components/leaderboard-rankings",
components: ["Leaderboard Rankings", "Leaderboard Podium", "Leaderboard Card"],
},
{
title: "Points & Levels Components",
description:
"Reward actions with points badges, level timelines, points charts, and boost indicators. Build complete progression systems.",
href: "/docs/components/points-badge",
components: [
"Points Badge",
"Points Awards",
"Points Boost",
"Points Chart",
"Points Levels List",
"Points Levels Timeline",
],
},
]

export default function IndexPage() {
return (
<div className="flex flex-1 flex-col">
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
<div className="relative overflow-hidden">
<div
className="pointer-events-none absolute inset-0"
Expand All @@ -46,12 +135,15 @@ export default function IndexPage() {
<PageHeader className="relative z-10">
<PageHeaderHeading className="max-w-4xl">
<span className="font-montserrat flex items-baseline gap-2 sm:gap-3">
<span className="leading-[0.95] font-bold tracking-[-0.03em]">
Trophy
</span>
<span className="font-normal tracking-[-0.02em] opacity-90">
UI
</span>
{/* <span className="leading-[0.95] font-bold tracking-[-0.03em]">
Gamification UI Kit
</span> */}
<TextAnimate animation="slideLeft" by="character">
Gamification UI Kit by Trophy
</TextAnimate>
{/* <span className="animate-expand-in overflow-hidden whitespace-nowrap font-normal tracking-[-0.02em]">
by Trophy
</span> */}
</span>
</PageHeaderHeading>
<PageHeaderDescription>
Expand All @@ -68,6 +160,92 @@ export default function IndexPage() {
</PageHeader>
<HomeComponentMosaic />
</div>
<section className="container-wrapper">
<div className="container mx-auto max-w-3xl px-4 py-12 text-center">
<h2 className="text-2xl font-semibold tracking-tight sm:text-3xl">
Gamification UI Components for React
</h2>
<p className="text-muted-foreground mx-auto mt-4 max-w-2xl text-base sm:text-lg">
Trophy&apos;s Gamification UI Kit gives you production-ready
gamification components — streak trackers, achievement badges,
leaderboards, points displays, and more. Built on{" "}
<Link href="https://ui.shadcn.com" className="underline">
shadcn/ui
</Link>{" "}
and Tailwind CSS, every component is open source, fully
customizable, and installs with a single CLI command into any React
or Next.js project.
</p>
</div>
</section>
<section className="container-wrapper border-grid border-t">
<div className="container mx-auto max-w-5xl px-4 py-16">
<h2 className="text-center text-2xl font-semibold tracking-tight sm:text-3xl">
Everything You Need to Ship Gamification
</h2>
<p className="text-muted-foreground mx-auto mt-3 max-w-2xl text-center text-base sm:text-lg">
Four categories of components covering the most impactful
gamification patterns — all composable, accessible, and
theme-aware.
</p>
<div className="mt-12 grid gap-8 sm:grid-cols-2">
{categories.map((category) => (
<Link
key={category.title}
href={category.href}
className="border-border hover:border-foreground/20 group rounded-xl border p-6 transition-colors"
>
<h3 className="text-lg font-semibold tracking-tight">
{category.title}
</h3>
<p className="text-muted-foreground mt-2 text-sm leading-relaxed">
{category.description}
</p>
<div className="mt-4 flex flex-wrap gap-1.5">
{category.components.map((component) => (
<span
key={component}
className="bg-secondary text-secondary-foreground rounded-md px-2 py-0.5 text-xs"
>
{component}
</span>
))}
</div>
</Link>
))}
</div>
</div>
</section>
<section className="container-wrapper border-grid border-t">
<div className="container mx-auto max-w-3xl px-4 py-16 text-center">
<h2 className="text-2xl font-semibold tracking-tight sm:text-3xl">
Built for Developers
</h2>
<div className="mt-8 grid gap-6 text-left sm:grid-cols-3">
<div>
<h3 className="font-semibold">One-Command Install</h3>
<p className="text-muted-foreground mt-1 text-sm">
Add any component to your project with a single CLI command.
No extra dependencies to manage.
</p>
</div>
<div>
<h3 className="font-semibold">Fully Customizable</h3>
<p className="text-muted-foreground mt-1 text-sm">
Every component lives in your codebase. Tweak styles, layout,
and behavior to match your brand.
</p>
</div>
<div>
<h3 className="font-semibold">Open Source</h3>
<p className="text-muted-foreground mt-1 text-sm">
MIT licensed and community-driven. Use in personal projects or
production apps without restrictions.
</p>
</div>
</div>
</div>
</section>
</div>
)
}
25 changes: 21 additions & 4 deletions apps/www/app/(app)/docs/[[...slug]]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ import { findNeighbour } from "fumadocs-core/server"
import { ChevronLeft, ChevronRight, CircleAlert, GitFork } from "lucide-react"

import { siteConfig } from "@/lib/config"
import {
resolveDocsMetaKeywords,
resolveDocsSeoTitle,
type TrophyDocsFrontmatter,
} from "@/lib/docs-metadata"
import { source } from "@/lib/source"
import { absoluteUrl } from "@/lib/utils"
import { DocsCopyPage } from "@/components/docs-copy-page"
Expand All @@ -30,26 +35,38 @@ export async function generateMetadata(props: {
notFound()
}

const doc = page.data
const doc = page.data as typeof page.data & TrophyDocsFrontmatter

if (!doc.title || !doc.description) {
notFound()
}

const metaTitle = resolveDocsSeoTitle(doc)
const metaKeywords = resolveDocsMetaKeywords(doc)

return {
title: doc.title,
title: metaTitle,
description: doc.description,
keywords: metaKeywords,
alternates: {
canonical: `${siteConfig.url}${page.url}`,
},
openGraph: {
title: doc.title,
title: metaTitle,
description: doc.description,
type: "article",
url: `${siteConfig.url}${page.url}`,
images: [
{
url: `/og?title=${encodeURIComponent(doc.title)}&description=${encodeURIComponent(doc.description)}`,
url: `/og?title=${encodeURIComponent(metaTitle)}&description=${encodeURIComponent(doc.description)}`,
},
],
},
twitter: {
card: "summary_large_image",
title: metaTitle,
description: doc.description,
},
}
}

Expand Down
7 changes: 7 additions & 0 deletions apps/www/app/(app)/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import type { Metadata } from "next"

import { siteConfig } from "@/lib/config"
import { SiteFooter } from "@/components/site-footer"
import { SiteHeader } from "@/components/site-header"

export const metadata: Metadata = {
metadataBase: new URL(siteConfig.url),
}

export default function AppLayout({ children }: { children: React.ReactNode }) {
return (
<div className="bg-background relative z-10 flex min-h-svh flex-col">
Expand Down
2 changes: 1 addition & 1 deletion apps/www/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export default function RootLayout({
}}
/>
<meta name="theme-color" content={META_THEME_COLORS.light} />
<meta name="apple-mobile-web-app-title" content="Trophy UI" />
<meta name="apple-mobile-web-app-title" content="Gamification UI Kit by Trophy" />
</head>
<body
className={cn(
Expand Down
Loading
Loading