"use client"; import { type MotionValue, motion, useMotionTemplate, useMotionValue, } from "framer-motion"; import Link from "next/link"; import { Icon } from "@iconify-icon/react"; import type { ComponentPropsWithoutRef, MouseEvent } from "react"; import { GridPattern } from "./GridPattern"; import { Heading } from "./Heading"; export interface ResourceType { href?: string; name: string; description: string; icon: string; pattern?: Omit< ComponentPropsWithoutRef, "width" | "height" | "x" >; } const resources: ResourceType[] = [ { href: "/entities", name: "Entities", description: "Learn how Entities work and how to use them to transmit federated data.", icon: "tabler:code-asterisk", pattern: { y: 16, squares: [ [0, 1], [1, 3], ], }, }, { href: "/federation", name: "Federation", description: "Learn how to federate data across the Versia federation network.", icon: "tabler:building-bank", pattern: { y: -6, squares: [ [-1, 2], [1, 3], ], }, }, ]; function ResourceIcon({ icon }: { icon: string }) { return (
); } function ResourcePattern({ mouseX, mouseY, ...gridProps }: ResourceType["pattern"] & { mouseX: MotionValue; mouseY: MotionValue; }) { const maskImage = useMotionTemplate`radial-gradient(180px at ${mouseX}px ${mouseY}px, white, transparent)`; const style = { maskImage, WebkitMaskImage: maskImage }; return (
); } export function Resource({ resource }: { resource: ResourceType }) { const mouseX = useMotionValue(0); const mouseY = useMotionValue(0); function onMouseMove({ currentTarget, clientX, clientY, }: MouseEvent) { const { left, top } = currentTarget.getBoundingClientRect(); mouseX.set(clientX - left); mouseY.set(clientY - top); } return (

{resource.href ? ( {resource.name} ) : ( resource.name )}

{resource.description}

); } export function Resources() { return (
Resources
{resources.map((resource) => ( ))}
); }