feat: Add new landing page

This commit is contained in:
Jesse Wierzbinski 2024-07-23 02:25:45 +02:00
parent 0234304198
commit 4f685d1ec6
No known key found for this signature in database
4 changed files with 137 additions and 24 deletions

104
app/page.tsx Normal file
View file

@ -0,0 +1,104 @@
import { Resource, type ResourceType } from "@/components/Resources";
import { wrapper } from "@/components/mdx";
import type { Metadata } from "next";
import type { FC } from "react";
export const metadata: Metadata = {
title: "Lysand Documentation",
description:
"Introduction to the Lysand Protocol, a communication medium for federated applications, leveraging the HTTP stack.",
};
const Page: FC = () => {
const resources: ResourceType[] = [
{
name: "JSON-based APIs",
description: "Simple JSON objects are used to represent all data.",
icon: "tabler:code-dots",
},
{
name: "MIT licensed",
description:
"Lysand is licensed under the MIT License, which allows you to use it for any purpose.",
icon: "tabler:license",
},
{
name: "Built-in namespaced extensions",
description:
"Extensions for common use cases are built-in, such as custom emojis and reactions",
icon: "tabler:puzzle",
},
{
name: "Easy to implement",
description:
"Lysand is designed to be easy to implement in any language.",
icon: "tabler:code",
},
{
name: "Signed by default",
description:
"All requests are signed using advanced cryptographic algorithms.",
icon: "tabler:shield-check",
},
{
name: "No vendor lock-in",
description:
"Standardization is heavy and designed to break vendor lock-in.",
icon: "tabler:database",
},
{
name: "In-depth security docs",
description:
"Docs provide lots of information on how to program a secure server.",
icon: "tabler:shield",
},
{
name: "Official SDKs",
description: "Official SDKs are available for TypeScript",
icon: "tabler:plug",
},
];
return wrapper({
children: (
<>
<div className="relative z-10 max-w-2xl lg:pt-6">
<h1 className="text-5xl font-semibold tracking-tight text-brand-600 dark:text-brand-400">
Lysand
</h1>
<h1 className="text-4xl sm:text-5xl font-semibold tracking-tight">
Federation, simpler
</h1>
<p className="mt-6 text-lg">
A simple, extensible federated protocol for building
useful applications.
</p>
</div>
<h2>Made by developers</h2>
<p className="lead">
Lysand is designed and maintained by the developers of the
Lysand Server, which uses Lysand for federation. This
community could include you! Check out our{" "}
<a
href="https://github.com/lysand-org/lysand"
target="_blank"
rel="noopener noreferrer"
>
Git repository
</a>{" "}
to see how you can contribute.
</p>
<div className="not-prose mt-4 grid grid-cols-1 max-w-full gap-8 border-t border-zinc-900/5 pt-10 sm:grid-cols-2 xl:grid-cols-4 dark:border-white/5">
{resources.map((resource) => (
<Resource key={resource.name} resource={resource} />
))}
</div>
</>
),
});
};
export default Page;

View file

@ -246,7 +246,7 @@ export const navigation: NavGroup[] = [
{ {
title: "Guides", title: "Guides",
links: [ links: [
{ title: "Introduction", href: "/" }, { title: "Introduction", href: "/introduction" },
{ title: "SDKs", href: "/sdks" }, { title: "SDKs", href: "/sdks" },
{ title: "Entities", href: "/entities" }, { title: "Entities", href: "/entities" },
], ],

View file

@ -8,34 +8,29 @@ import {
} from "framer-motion"; } from "framer-motion";
import Link from "next/link"; import Link from "next/link";
import type { import { Icon } from "@iconify-icon/react";
ComponentPropsWithoutRef, import type { ComponentPropsWithoutRef, MouseEvent } from "react";
ComponentType,
MouseEvent,
} from "react";
import { GridPattern } from "./GridPattern"; import { GridPattern } from "./GridPattern";
import { Heading } from "./Heading"; import { Heading } from "./Heading";
import { ChatBubbleIcon } from "./icons/ChatBubbleIcon";
import { UsersIcon } from "./icons/UsersIcon";
interface Resource { export interface ResourceType {
href: string; href?: string;
name: string; name: string;
description: string; description: string;
icon: ComponentType<{ className?: string }>; icon: string;
pattern: Omit< pattern?: Omit<
ComponentPropsWithoutRef<typeof GridPattern>, ComponentPropsWithoutRef<typeof GridPattern>,
"width" | "height" | "x" "width" | "height" | "x"
>; >;
} }
const resources: Resource[] = [ const resources: ResourceType[] = [
{ {
href: "/entities", href: "/entities",
name: "Entities", name: "Entities",
description: description:
"Learn how Entities work and how to use them to transmit federated data.", "Learn how Entities work and how to use them to transmit federated data.",
icon: ChatBubbleIcon, icon: "tabler:code-asterisk",
pattern: { pattern: {
y: 16, y: 16,
squares: [ squares: [
@ -49,7 +44,7 @@ const resources: Resource[] = [
name: "Security", name: "Security",
description: description:
"Learn how to secure your Lysand implementation and protect your users' data.", "Learn how to secure your Lysand implementation and protect your users' data.",
icon: UsersIcon, icon: "tabler:building-bank",
pattern: { pattern: {
y: -6, y: -6,
squares: [ squares: [
@ -60,10 +55,14 @@ const resources: Resource[] = [
}, },
]; ];
function ResourceIcon({ icon: Icon }: { icon: Resource["icon"] }) { function ResourceIcon({ icon }: { icon: string }) {
return ( return (
<div className="flex h-7 w-7 items-center justify-center rounded-md bg-zinc-900/5 ring-1 ring-zinc-900/25 backdrop-blur-[2px] transition duration-300 group-hover:bg-white/50 group-hover:ring-zinc-900/25 dark:bg-white/7.5 dark:ring-white/15 dark:group-hover:bg-brand-300/10 dark:group-hover:ring-brand-400"> <div className="flex h-7 w-7 items-center justify-center rounded-md bg-zinc-900/5 ring-1 ring-zinc-900/25 backdrop-blur-[2px] transition duration-300 group-hover:bg-white/50 group-hover:ring-zinc-900/25 dark:bg-white/7.5 dark:ring-white/15 dark:group-hover:bg-brand-300/10 dark:group-hover:ring-brand-400">
<Icon className="h-5 w-5 fill-zinc-700/10 stroke-zinc-700 transition-colors duration-300 group-hover:stroke-zinc-900 dark:fill-white/10 dark:stroke-zinc-400 dark:group-hover:fill-brand-300/10 dark:group-hover:stroke-brand-400" /> <Icon
icon={icon}
width="unset"
className="h-5 w-5 fill-zinc-700/10 stroke-zinc-700 transition-colors duration-300 group-hover:stroke-zinc-900 dark:fill-white/10 dark:stroke-zinc-400 dark:group-hover:fill-brand-300/10 dark:group-hover:stroke-brand-400"
/>
</div> </div>
); );
} }
@ -72,7 +71,7 @@ function ResourcePattern({
mouseX, mouseX,
mouseY, mouseY,
...gridProps ...gridProps
}: Resource["pattern"] & { }: ResourceType["pattern"] & {
mouseX: MotionValue<number>; mouseX: MotionValue<number>;
mouseY: MotionValue<number>; mouseY: MotionValue<number>;
}) { }) {
@ -110,7 +109,7 @@ function ResourcePattern({
); );
} }
function Resource({ resource }: { resource: Resource }) { export function Resource({ resource }: { resource: ResourceType }) {
const mouseX = useMotionValue(0); const mouseX = useMotionValue(0);
const mouseY = useMotionValue(0); const mouseY = useMotionValue(0);
@ -131,7 +130,13 @@ function Resource({ resource }: { resource: Resource }) {
className="group relative flex rounded-md bg-zinc-50 transition-shadow hover:shadow-md hover:shadow-zinc-900/5 dark:bg-white/2.5 dark:hover:shadow-black/5" className="group relative flex rounded-md bg-zinc-50 transition-shadow hover:shadow-md hover:shadow-zinc-900/5 dark:bg-white/2.5 dark:hover:shadow-black/5"
> >
<ResourcePattern <ResourcePattern
{...resource.pattern} {...(resource.pattern ?? {
y: 0,
squares: [
[0, 1],
[1, 2],
],
})}
mouseX={mouseX} mouseX={mouseX}
mouseY={mouseY} mouseY={mouseY}
/> />
@ -139,10 +144,14 @@ function Resource({ resource }: { resource: Resource }) {
<div className="relative rounded-md px-4 pb-4 pt-16"> <div className="relative rounded-md px-4 pb-4 pt-16">
<ResourceIcon icon={resource.icon} /> <ResourceIcon icon={resource.icon} />
<h3 className="mt-4 text-sm font-semibold leading-7 text-zinc-900 dark:text-white"> <h3 className="mt-4 text-sm font-semibold leading-7 text-zinc-900 dark:text-white">
<Link href={resource.href}> {resource.href ? (
<span className="absolute inset-0 rounded-md" /> <Link href={resource.href}>
{resource.name} <span className="absolute inset-0 rounded-md" />
</Link> {resource.name}
</Link>
) : (
resource.name
)}
</h3> </h3>
<p className="mt-1 text-sm text-zinc-600 dark:text-zinc-400"> <p className="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
{resource.description} {resource.description}