mirror of
https://github.com/different-ai/openwork
synced 2026-04-25 17:15:34 +02:00
Refine landing trust center into one-screen review flow (#1363)
* Add trust review pages for enterprise follow-up * Simplify trust page into decision-maker summary * Refine landing trust center review flow * Simplify trust center into one-screen flow * Remove unused trust topic page component * trust me, I'm compliant (WIP) * good copy * eliminating dead space * mobile
This commit is contained in:
21
ee/apps/landing/app/trust/page.tsx
Normal file
21
ee/apps/landing/app/trust/page.tsx
Normal file
@@ -0,0 +1,21 @@
|
||||
import { LandingTrustOverview } from "../../components/landing-trust";
|
||||
import { getGithubData } from "../../lib/github";
|
||||
|
||||
export const metadata = {
|
||||
title: "OpenWork — Trust",
|
||||
description:
|
||||
"How OpenWork approaches deployment control, local-first architecture, provider choice, and enterprise trust."
|
||||
};
|
||||
|
||||
export default async function TrustPage() {
|
||||
const github = await getGithubData();
|
||||
const cal = process.env.NEXT_PUBLIC_CAL_URL ?? "";
|
||||
|
||||
return (
|
||||
<LandingTrustOverview
|
||||
stars={github.stars}
|
||||
downloadHref={github.downloads.macos}
|
||||
calUrl={cal}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -99,6 +99,12 @@ export function LandingEnterprise(props: Props) {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-4">
|
||||
<a href="/trust" className="text-[14px] font-medium text-[#011627] transition-colors hover:text-slate-700">
|
||||
Trust details
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="space-y-6">
|
||||
|
||||
257
ee/apps/landing/components/landing-trust.tsx
Normal file
257
ee/apps/landing/components/landing-trust.tsx
Normal file
@@ -0,0 +1,257 @@
|
||||
"use client";
|
||||
|
||||
import Link from "next/link";
|
||||
import { ChevronLeft } from "lucide-react";
|
||||
import { useMemo, useState } from "react";
|
||||
import { type Subprocessor, subprocessors } from "./trust-content";
|
||||
|
||||
import { SiteFooter } from "./site-footer";
|
||||
|
||||
import { LandingBackground } from "./landing-background";
|
||||
import { SiteNav } from "./site-nav";
|
||||
import {
|
||||
defaultTrustTopicSlug,
|
||||
getTrustTopic,
|
||||
statusPageRequestHref,
|
||||
trustTopics,
|
||||
type TrustTopic
|
||||
} from "./trust-content";
|
||||
|
||||
const categoryColors: Record<string, string> = {
|
||||
Analytics: "bg-orange-50 text-orange-700",
|
||||
Payments: "bg-violet-50 text-violet-700",
|
||||
Authentication: "bg-blue-50 text-blue-700",
|
||||
Infrastructure: "bg-cyan-50 text-cyan-700"
|
||||
};
|
||||
|
||||
function SubprocessorRows() {
|
||||
return (
|
||||
<div className="mt-5 flex flex-col divide-y divide-slate-200/70 overflow-hidden rounded-2xl border border-slate-200/70 bg-white/85">
|
||||
{subprocessors.map((sp) => (
|
||||
<a
|
||||
key={sp.name}
|
||||
href={sp.href}
|
||||
rel="noreferrer"
|
||||
target="_blank"
|
||||
className="flex min-w-0 items-center gap-3 px-4 py-2.5 transition-colors hover:bg-slate-50/80"
|
||||
>
|
||||
<div
|
||||
className="flex h-8 w-8 shrink-0 items-center justify-center rounded-lg text-[10px] font-bold tracking-wide"
|
||||
style={{ backgroundColor: sp.brandColor, color: sp.textColor }}
|
||||
>
|
||||
{sp.initial}
|
||||
</div>
|
||||
<div className="min-w-0 flex-1">
|
||||
<p className="truncate text-[13px] leading-relaxed text-slate-500">
|
||||
<span className="font-semibold text-[#011627]">{sp.name}</span>
|
||||
{": "}
|
||||
{sp.purpose}
|
||||
</p>
|
||||
</div>
|
||||
<div className="hidden shrink-0 items-center gap-2 sm:flex">
|
||||
<span
|
||||
className={`rounded-full px-2 py-0.5 text-[11px] font-medium ${categoryColors[sp.category] ?? "bg-slate-100 text-slate-600"}`}
|
||||
>
|
||||
{sp.category}
|
||||
</span>
|
||||
<span className="text-[11px] text-slate-400">{sp.location} Region</span>
|
||||
</div>
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
type SharedProps = {
|
||||
stars: string;
|
||||
downloadHref: string;
|
||||
calUrl: string;
|
||||
};
|
||||
|
||||
function externalLinkProps(href: string) {
|
||||
return /^https?:\/\//.test(href) || href.startsWith("mailto:")
|
||||
? { rel: "noreferrer", target: "_blank" as const }
|
||||
: {};
|
||||
}
|
||||
|
||||
function TopicChip({
|
||||
topic,
|
||||
active,
|
||||
onSelect
|
||||
}: {
|
||||
topic: TrustTopic;
|
||||
active: boolean;
|
||||
onSelect: (slug: string) => void;
|
||||
}) {
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onSelect(topic.slug)}
|
||||
className={`shrink-0 rounded-full border px-3.5 py-1.5 text-[13px] font-medium tracking-tight transition-all ${
|
||||
active
|
||||
? "border-[#011627] bg-[#011627] text-white shadow-[0_8px_20px_-8px_rgba(1,22,39,0.45)]"
|
||||
: "border-slate-200/80 bg-white/80 text-slate-600 hover:border-slate-300 hover:text-[#011627]"
|
||||
}`}
|
||||
aria-pressed={active}
|
||||
>
|
||||
{topic.label}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
function TopicRailItem({
|
||||
topic,
|
||||
active,
|
||||
onSelect
|
||||
}: {
|
||||
topic: TrustTopic;
|
||||
active: boolean;
|
||||
onSelect: (slug: string) => void;
|
||||
}) {
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onSelect(topic.slug)}
|
||||
className={`w-full rounded-[1.2rem] border px-4 py-3 text-left transition-all ${
|
||||
active
|
||||
? "border-[#011627] bg-[#011627] text-white shadow-[0_14px_32px_-18px_rgba(1,22,39,0.55)]"
|
||||
: "border-slate-200/80 bg-white/80 text-slate-600 hover:border-slate-300 hover:text-[#011627]"
|
||||
}`}
|
||||
aria-pressed={active}
|
||||
>
|
||||
<div className="text-[14px] font-medium tracking-tight">{topic.label}</div>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
function TopicPanel({ topic, callHref }: { topic: TrustTopic; callHref: string }) {
|
||||
const Icon = topic.icon;
|
||||
|
||||
return (
|
||||
<div className="landing-shell flex h-full flex-col rounded-[1.75rem] p-5 md:p-6">
|
||||
<div>
|
||||
<div className="flex items-center gap-3">
|
||||
<div
|
||||
className={`flex h-9 w-9 shrink-0 items-center justify-center rounded-xl ${topic.toneClassName}`}
|
||||
>
|
||||
<Icon size={16} />
|
||||
</div>
|
||||
<h2 className="max-w-2xl text-[1.2rem] font-medium tracking-tight text-[#011627] md:text-[1.35rem]">
|
||||
{topic.title}
|
||||
</h2>
|
||||
</div>
|
||||
<p className="mt-2 max-w-2xl text-[13px] leading-relaxed text-slate-600 md:text-[14px]">
|
||||
{topic.panelIntro}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{topic.slug === "subprocessors" ? (
|
||||
<SubprocessorRows />
|
||||
) : (
|
||||
<div className="mt-3 flex flex-1 flex-col gap-2">
|
||||
{topic.bullets.map((bullet) => (
|
||||
<div
|
||||
key={bullet}
|
||||
className="flex flex-1 items-center rounded-2xl border border-slate-200/70 bg-white/85 px-4 py-2 text-[13px] leading-relaxed text-slate-600"
|
||||
>
|
||||
{bullet}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="mt-3 flex flex-col items-start gap-3 sm:flex-row sm:items-center">
|
||||
{topic.slug === "status-page-access" ? (
|
||||
<a
|
||||
href={statusPageRequestHref}
|
||||
className="doc-button text-sm"
|
||||
{...externalLinkProps(statusPageRequestHref)}
|
||||
>
|
||||
Request status page
|
||||
</a>
|
||||
) : topic.slug === "subprocessors" ? null : (
|
||||
<a href={callHref} className="doc-button text-sm" {...externalLinkProps(callHref)}>
|
||||
Book a call
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function LandingTrustOverview(props: SharedProps) {
|
||||
const callHref = props.calUrl || "/enterprise#book";
|
||||
const [activeSlug, setActiveSlug] = useState(defaultTrustTopicSlug);
|
||||
|
||||
const activeTopic = useMemo(
|
||||
() => getTrustTopic(activeSlug) ?? trustTopics[0],
|
||||
[activeSlug]
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="relative min-h-screen overflow-hidden text-[#011627]">
|
||||
<LandingBackground />
|
||||
|
||||
<div className="relative z-10 flex min-h-screen flex-col items-center pb-3 pt-1 md:pb-4 md:pt-2">
|
||||
<div className="w-full">
|
||||
<SiteNav
|
||||
stars={props.stars}
|
||||
callUrl={callHref}
|
||||
downloadHref={props.downloadHref}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<main className="mx-auto flex min-h-[calc(100vh-6rem)] w-full max-w-5xl flex-1 flex-col justify-between gap-4 px-6 pb-6 md:px-8 md:pb-8">
|
||||
<section className="max-w-4xl pt-2 md:pt-3">
|
||||
<h1 className="max-w-4xl text-4xl font-medium leading-[1.05] tracking-tight md:text-[2.7rem] lg:text-[3rem]">
|
||||
Openwork's Trust Center
|
||||
</h1>
|
||||
|
||||
<p className="mt-3 max-w-4xl text-[15px] leading-relaxed text-slate-600 md:text-[16px]">
|
||||
Moving at startup speed without compromising on enterprise protection.
|
||||
We treat security not as an afterthought, but as a foundational pillar of everything we build.
|
||||
This mindset drives our development processes, infrastructure decisions, and organizational policies.
|
||||
We treat the data entrusted to us with the utmost care and responsibility.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section className="flex flex-col gap-4 xl:grid xl:grid-cols-[220px_minmax(0,1fr)]">
|
||||
{/* Mobile: horizontal scrollable chip row */}
|
||||
<div className="flex gap-2 overflow-x-auto pb-1 [&::-webkit-scrollbar]:hidden xl:hidden">
|
||||
{trustTopics.map((topic) => (
|
||||
<TopicChip
|
||||
key={topic.slug}
|
||||
topic={topic}
|
||||
active={topic.slug === activeTopic.slug}
|
||||
onSelect={setActiveSlug}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Desktop: sidebar rail */}
|
||||
<div className="landing-shell hidden rounded-[1.75rem] p-5 xl:block">
|
||||
<div className="mb-3 text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500">
|
||||
Topics
|
||||
</div>
|
||||
<div className="grid gap-2">
|
||||
{trustTopics.map((topic) => (
|
||||
<TopicRailItem
|
||||
key={topic.slug}
|
||||
topic={topic}
|
||||
active={topic.slug === activeTopic.slug}
|
||||
onSelect={setActiveSlug}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<TopicPanel topic={activeTopic} callHref={callHref} />
|
||||
</section>
|
||||
|
||||
<SiteFooter />
|
||||
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -33,13 +33,16 @@ export function SiteFooter() {
|
||||
<Link href="/enterprise" className="transition-colors hover:text-gray-800">
|
||||
Enterprise
|
||||
</Link>
|
||||
<Link href="/trust" className="transition-colors hover:text-gray-800">
|
||||
Trust Center
|
||||
</Link>
|
||||
<Link href="/privacy" className="transition-colors hover:text-gray-800">
|
||||
Privacy
|
||||
</Link>
|
||||
<Link href="/terms" className="transition-colors hover:text-gray-800">
|
||||
Terms
|
||||
</Link>
|
||||
<div>© 2026 OpenWork Project.</div>
|
||||
<div>© 2026 Different AI</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
259
ee/apps/landing/components/trust-content.tsx
Normal file
259
ee/apps/landing/components/trust-content.tsx
Normal file
@@ -0,0 +1,259 @@
|
||||
import {
|
||||
Building2,
|
||||
Database,
|
||||
HardDrive,
|
||||
KeyRound,
|
||||
LifeBuoy,
|
||||
ShieldCheck,
|
||||
type LucideIcon
|
||||
} from "lucide-react";
|
||||
|
||||
export const statusPageRequestHref =
|
||||
"mailto:team@openworklabs.com?subject=Status%20page%20access%20request&body=Hi%20OpenWork%20team%2C%0A%0AWe%27re%20evaluating%20OpenWork%20and%20would%20like%20access%20to%20the%20status%20page%20for%20operational%20review.%0A%0ACompany%3A%20%5Byour%20company%5D%0AUse%20case%3A%20%5Bbrief%20description%5D%0A%0AThanks";
|
||||
|
||||
type TrustLink = {
|
||||
label: string;
|
||||
href: string;
|
||||
external?: boolean;
|
||||
};
|
||||
|
||||
export type TrustTopic = {
|
||||
slug: string;
|
||||
label: string;
|
||||
title: string;
|
||||
panelIntro: string;
|
||||
bullets: string[];
|
||||
icon: LucideIcon;
|
||||
toneClassName: string;
|
||||
links: TrustLink[];
|
||||
};
|
||||
|
||||
export type Subprocessor = {
|
||||
name: string;
|
||||
purpose: string;
|
||||
category: string;
|
||||
location: string;
|
||||
brandColor: string;
|
||||
textColor: string;
|
||||
initial: string;
|
||||
href: string;
|
||||
};
|
||||
|
||||
export const subprocessors: Subprocessor[] = [
|
||||
{
|
||||
name: "PostHog",
|
||||
purpose: "Anonymous website analytics and product telemetry",
|
||||
category: "Analytics",
|
||||
location: "US / EU",
|
||||
brandColor: "#FFF0EB",
|
||||
textColor: "#C93C00",
|
||||
initial: "PH",
|
||||
href: "https://posthog.com"
|
||||
},
|
||||
{
|
||||
name: "Polar",
|
||||
purpose: "Subscription billing and payment processing",
|
||||
category: "Payments",
|
||||
location: "US",
|
||||
brandColor: "#F3EEFF",
|
||||
textColor: "#6D28D9",
|
||||
initial: "PO",
|
||||
href: "https://polar.sh"
|
||||
},
|
||||
{
|
||||
name: "Google",
|
||||
purpose: "OAuth sign-in and authentication services",
|
||||
category: "Authentication",
|
||||
location: "US",
|
||||
brandColor: "#EAF1FB",
|
||||
textColor: "#1A56C4",
|
||||
initial: "G",
|
||||
href: "https://google.com"
|
||||
},
|
||||
{
|
||||
name: "GitHub",
|
||||
purpose: "OAuth sign-in and source code hosting",
|
||||
category: "Authentication",
|
||||
location: "US",
|
||||
brandColor: "#F0F0F0",
|
||||
textColor: "#24292E",
|
||||
initial: "GH",
|
||||
href: "https://github.com"
|
||||
},
|
||||
{
|
||||
name: "Daytona",
|
||||
purpose: "Virtual sandbox infrastructure for the Cloud Service",
|
||||
category: "Infrastructure",
|
||||
location: "EU",
|
||||
brandColor: "#E0F7FA",
|
||||
textColor: "#0277BD",
|
||||
initial: "D",
|
||||
href: "https://daytona.io"
|
||||
}
|
||||
];
|
||||
|
||||
export const trustTopics: TrustTopic[] = [
|
||||
{
|
||||
slug: "self-hosted-deployment",
|
||||
label: "Self-hosting",
|
||||
title: "Your infra, your rules.",
|
||||
panelIntro:
|
||||
"Enterprise governance, regional compliance, and internal security reviews get simpler when you own the stack (and the data!). Self-host with confidence, not as a fallback.",
|
||||
bullets: [
|
||||
"OpenWork supports desktop-hosted, CLI-hosted, and hosted cloud server paths.",
|
||||
"We help enterpises avoid lock-in with a single LLM provider and retain their data ownership.",
|
||||
"Your team keeps infrastructure ownership when you deploy in your own environment.",
|
||||
"Enterprise review does not require adopting a hosted-only control plane."
|
||||
],
|
||||
icon: Building2,
|
||||
toneClassName: "bg-blue-50 text-blue-700",
|
||||
links: [
|
||||
{ label: "Enterprise", href: "/enterprise" },
|
||||
{
|
||||
label: "Infrastructure",
|
||||
href: "https://github.com/different-ai/openwork/blob/dev/INFRASTRUCTURE.md",
|
||||
external: true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
slug: "local-first-workflows",
|
||||
label: "Local-first workflows",
|
||||
title: "Local-first by design.",
|
||||
panelIntro:
|
||||
"Most AI tooling defaults to cloud and asks you to opt out. We are local-first, and cloud connections are explicit choices your team makes, not hidden defaults.",
|
||||
bullets: [
|
||||
"The desktop-hosted app/server path is a first-class way to run OpenWork.",
|
||||
"Hosted and self-hosted modes share the same user-level connect flow instead of separate products.",
|
||||
"OpenWork stays open, local-first, and standards-based in the product vision.",
|
||||
"Runtime boundaries stay legible and transparent for enterprise review."
|
||||
],
|
||||
icon: HardDrive,
|
||||
toneClassName: "bg-emerald-50 text-emerald-700",
|
||||
links: [
|
||||
{
|
||||
label: "Vision",
|
||||
href: "https://github.com/different-ai/openwork/blob/dev/VISION.md",
|
||||
external: true
|
||||
},
|
||||
{
|
||||
label: "Architecture",
|
||||
href: "https://github.com/different-ai/openwork/blob/dev/ARCHITECTURE.md",
|
||||
external: true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
slug: "provider-and-key-control",
|
||||
label: "BYOK",
|
||||
title: "Bring your own keys.",
|
||||
panelIntro:
|
||||
"Keep your existing model provider agreements intact. When you connect directly with your own credentials, your usage stays between you and your provider.",
|
||||
bullets: [
|
||||
"We do not collect or analyze usage or performance analytics. No telemetry without consent.",
|
||||
"Individual Teams can keep provider choice aligned with internal approvals and procurement.",
|
||||
"Third-party model providers connected with your own credentials are governed by their own terms.",
|
||||
"We also support custom proxy gateways such as LiteLLM and Cloudflare AI Gateway. "
|
||||
],
|
||||
icon: KeyRound,
|
||||
toneClassName: "bg-violet-50 text-violet-700",
|
||||
links: [
|
||||
{ label: "Privacy", href: "/privacy" },
|
||||
{ label: "Terms", href: "/terms" }
|
||||
]
|
||||
},
|
||||
{
|
||||
slug: "data-residency-controls",
|
||||
label: "Data residency",
|
||||
title: "The Data stays where your company or customers are.",
|
||||
panelIntro:
|
||||
"Data regulations shouldn't restrict innovation. Self-hosted environments give your team full authority over region, network boundary, and egress policy without negotiating with a control plane.",
|
||||
bullets: [
|
||||
"We let you choose your own data Residency instead of imposing ours.",
|
||||
"Self-hosted environments keep infrastructure location under customer control.",
|
||||
"OpenWork avoids forcing a cloud-only lock-in model for teams that need residency control.",
|
||||
"Provider choice and deployment choice stay separate for cleaner review."
|
||||
],
|
||||
icon: Database,
|
||||
toneClassName: "bg-cyan-50 text-cyan-700",
|
||||
links: [
|
||||
{
|
||||
label: "Infrastructure",
|
||||
href: "https://github.com/different-ai/openwork/blob/dev/INFRASTRUCTURE.md",
|
||||
external: true
|
||||
},
|
||||
{ label: "Privacy", href: "/privacy" }
|
||||
]
|
||||
},
|
||||
{
|
||||
slug: "incident-response",
|
||||
label: "Incident response",
|
||||
title: "We'll notify of any major security incident withtin 72 hours.",
|
||||
panelIntro:
|
||||
"We commit to a 3-day acknowledgment and notification of any major security incident. By default, we also commit to a 7-day triage and resolution for high priority issues.",
|
||||
bullets: [
|
||||
"Security issues can be reported privately or via a github issue if you're a security researcher.",
|
||||
"The public security policy asks reporters to include impact and reproduction details.",
|
||||
"OpenWork commits to acknowledge receipt within 3 business days.",
|
||||
"OpenWork commits to share an initial triage status within 7 business days."
|
||||
],
|
||||
icon: ShieldCheck,
|
||||
toneClassName: "bg-amber-50 text-amber-700",
|
||||
links: [
|
||||
{
|
||||
label: "Security policy",
|
||||
href: "https://github.com/different-ai/openwork/blob/dev/SECURITY.md",
|
||||
external: true
|
||||
},
|
||||
{
|
||||
label: "Support",
|
||||
href: "https://github.com/different-ai/openwork/blob/dev/SUPPORT.md",
|
||||
external: true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
slug: "status-page-access",
|
||||
label: "Status page access",
|
||||
title: "Real operational data, on request.",
|
||||
panelIntro:
|
||||
"We uphold SLAs, uptime and other reliability parameters via measurable metrics, not a marketing copy.",
|
||||
bullets: [
|
||||
"Status information is available by request.",
|
||||
"Operational review can happen without padded uptime claims.",
|
||||
"Request access to live status data during procurement so you can evaluate our reliability.",
|
||||
"Feel free to request access to our status page by clicking at the button below:"
|
||||
],
|
||||
icon: LifeBuoy,
|
||||
toneClassName: "bg-rose-50 text-rose-700",
|
||||
links: [
|
||||
{ label: "Request status page", href: statusPageRequestHref, external: true },
|
||||
{ label: "Enterprise", href: "/enterprise" }
|
||||
]
|
||||
},
|
||||
{
|
||||
slug: "subprocessors",
|
||||
label: "Subprocessors",
|
||||
title: "No hidden third parties.",
|
||||
panelIntro:
|
||||
"Every vendor that touches data in the OpenWork cloud path is named in the privacy policy. Procurement teams can evaluate each subprocessor's data handling before signing, not after.",
|
||||
bullets: [
|
||||
"PostHog handles anonymous website analytics.",
|
||||
"Polar handles subscription billing and payment processing.",
|
||||
"Google and GitHub provide OAuth sign-in services.",
|
||||
"Daytona provides virtual sandbox infrastructure for the Cloud Service."
|
||||
],
|
||||
icon: ShieldCheck,
|
||||
toneClassName: "bg-slate-100 text-slate-700",
|
||||
links: [
|
||||
{ label: "Privacy", href: "/privacy" },
|
||||
{ label: "Terms", href: "/terms" }
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
export const defaultTrustTopicSlug = trustTopics[0].slug;
|
||||
|
||||
export function getTrustTopic(slug: string) {
|
||||
return trustTopics.find((topic) => topic.slug === slug);
|
||||
}
|
||||
2
ee/apps/landing/next-env.d.ts
vendored
2
ee/apps/landing/next-env.d.ts
vendored
@@ -2,4 +2,4 @@
|
||||
/// <reference types="next/image-types/global" />
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
||||
// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
|
||||
|
||||
BIN
ee/apps/landing/pr/trust-page-overview.png
Normal file
BIN
ee/apps/landing/pr/trust-page-overview.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 547 KiB |
Reference in New Issue
Block a user