public: add reviews

This commit is contained in:
Carl-Gerhard Lindesvärd
2026-02-05 13:04:40 +00:00
parent f1c85c53cf
commit 05ccbc372c
3 changed files with 79 additions and 6 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -82,6 +82,20 @@ const testimonials = [
retweets: 68,
likes: 648,
},
{
verified: true,
avatarUrl: '/twitter-thomas.jpg',
name: 'Thomas Sanlis',
handle: 'T_Zahil',
content: [
`We're now sponsoring @OpenPanelDev with Uneed 🥳`,
`If you're looking for open source analytics, OpenPanel is BY FAR the best I've ever seen`,
'Bonus: 1-click install on Coolify 🥰',
],
replies: 8,
retweets: 3,
likes: 23,
},
];
export function Testimonials() {

View File

@@ -1,9 +1,13 @@
'use client';
import { FeatureCardBackground } from '@/components/feature-card';
import { Section, SectionHeader, SectionLabel } from '@/components/section';
import { Tag } from '@/components/tag';
import { Button } from '@/components/ui/button';
import { cn } from '@/lib/utils';
import { ArrowDownIcon } from 'lucide-react';
import { QuoteIcon } from 'lucide-react';
import Image from 'next/image';
import { useState } from 'react';
import Markdown from 'react-markdown';
const images = [
{
@@ -38,13 +42,33 @@ const images = [
},
];
const quotes: {
quote: string;
author: string;
site?: string;
}[] = [
{
quote:
'After testing several product analytics tools for Strackr, **we chose OpenPanel and we are very satisfied with the product**. We have been using it since the beta, and there are constant updates. Profiles and Conversion Events are our favorite features.',
author: 'Julien Hany',
site: 'https://strackr.com',
},
{
quote: `Before OpenPanel, I was using Plausible, and it was ok. **But OpenPanel is like 10 leagues ahead!!** Better UX/UI, many more features, and incredible support from the founder. Bonus point: it's 1 click install on Coolify!! I won't switch to anything else 😎`,
author: 'Thomas Sanlis',
site: 'https://uneed.best',
},
{
quote: `We've been using OpenPanel for almost three months and we're extremely happy with it. After paying a lot to PostHog for years, OpenPanel gives us the same, in many ways better, analytics while keeping full ownership of our data. It's truly self-hosted but surprisingly low maintenance: setup and ongoing upkeep are straightforward, so we spend less time managing tooling and more time acting on insights.\n\nOpenPanel delivers the metrics we need to understand our website and app performance and how users actually interact with them. The dashboards are clear, the data is reliable, and the feature set covers everything we relied on before. The support is absolutely fantastic: responsive, helpful, and knowledgeable, and that made the switch effortless. We honestly dont want to run any business without OpenPanel anymore.`,
author: 'Self-hosting users',
},
];
export function WhyOpenPanel() {
const [showMore, setShowMore] = useState(false);
return (
<Section className="container gap-16">
<SectionHeader
label="Trusted by builders"
title="Join thousands of companies using OpenPanel to understand their users"
/>
<SectionHeader label="Trusted by founders" title="Who uses OpenPanel?" />
<div className="col overflow-hidden">
<SectionLabel className="text-muted-foreground bg-background -mb-2 z-5 self-start pr-4">
USED BY
@@ -72,6 +96,41 @@ export function WhyOpenPanel() {
</div>
))}
</div>
<div className="grid grid-cols-1 md:grid-cols-2 -mx-4 border-y py-4">
{quotes.slice(0, showMore ? quotes.length : 2).map((quote) => (
<figure
key={quote.author}
className="px-4 py-4 md:odd:border-r group"
>
<QuoteIcon className="size-10 text-muted-foreground/50 stroke-1 mb-2 group-hover:text-foreground group-hover:rotate-6 transition-all" />
<blockquote className="text-xl prose">
<Markdown>{quote.quote}</Markdown>
</blockquote>
<figcaption className="row justify-between text-muted-foreground text-sm mt-4">
<span>{quote.author}</span>
{quote.site && (
<cite className="not-italic">
<a
href={quote.site}
target="_blank"
rel="noopener noreferrer"
>
{quote.site.replace('https://', '')}
</a>
</cite>
)}
</figcaption>
</figure>
))}
</div>
<Button
onClick={() => setShowMore((p) => !p)}
type="button"
variant="outline"
className="self-end mt-4"
>
{showMore ? 'Show less' : 'View more reviews'}
</Button>
</div>
</Section>
);