mirror of
https://github.com/versia-pub/docs.git
synced 2025-12-06 06:18:19 +01:00
feat: ✨ Add new landing page
This commit is contained in:
parent
0234304198
commit
4f685d1ec6
104
app/page.tsx
Normal file
104
app/page.tsx
Normal 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;
|
||||||
|
|
@ -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" },
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -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}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue