Files
www_projectmycelium_com/src/pages/home/HomeBenefits.tsx
sasha-astiadi 8fac6f8edd refactor: clean up unused imports and fix component naming
- Removed unused component imports across multiple page files
- Fixed component name casing inconsistencies (CalltoAction → CallToAction, NetworkUseCases → NetworkUsecases)
- Changed AgentComponents from default to named export
- Removed stray character in NetworkPage.tsx
2025-11-05 13:10:45 +01:00

306 lines
12 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import createGlobe from "cobe";
import { useEffect, useRef } from "react";
import { motion } from "motion/react";
import { IconBrandYoutubeFilled } from "@tabler/icons-react";
import { H2, CP, Eyebrow } from '@/components/Texts'
export function HomeBenefits() {
const features = [
{
title: "Unbreakable by Design",
description:
"No central cloud to censor or fail. The network heals itself.",
image: "/images/benefits/energy.webp",
},
{
title: "Sovereign by Default",
description:
"Identity, compute, and data belong to you cryptographically.",
image: "/images/benefits/sovereign.webp",
},
{
title: "Hackable & Open",
description:
"Learn, build, and experiment without permission.",
image: "/images/benefits/autonomous.webp",
},
{
title: "Cost & Energy Efficient",
description:
"Distributed hardware eliminates hyperscale overhead.",
image: "/images/benefits/cost.webp",
},
];
return (
<div className="relative z-20 py-10 lg:py-24 max-w-7xl mx-auto">
<div className="px-12">
<Eyebrow className="text-center text-cyan-500">
Benefits
</Eyebrow>
<H2 className="text-3xl lg:text-5xl lg:leading-tight max-w-5xl mx-auto text-center tracking-tight font-medium text-black dark:text-white">
Why It Matters
</H2>
</div>
<div className="mt-10 grid grid-cols-1 gap-4 sm:mt-16 lg:grid-cols-7 lg:grid-rows-2 lg:px-12 px-6">
<div className="flex p-px lg:col-span-4">
<div className="w-full overflow-hidden rounded-lg bg-white/40 dark:bg-black/40 shadow-sm border border-transparent transition-all duration-300 hover:scale-105 hover:shadow-lg hover:shadow-cyan-500/50 hover:border-cyan-500 max-lg:rounded-t-4xl lg:rounded-tl-4xl">
<div className="flex items-center">
<div className="w-1/3 p-2">
<img
alt={features[0].title}
src={features[0].image}
className="w-40 h-40 object-contain"
/>
</div>
<div className="w-2/3 p-2 pr-12">
<h3 className="text-lg font-semibold text-black dark:text-white">{features[0].title}</h3>
<CP className="mt-2 text-gray-600 dark:text-gray-300">
{features[0].description}
</CP>
</div>
</div>
</div>
</div>
<div className="flex p-px lg:col-span-3">
<div className="w-full overflow-hidden rounded-lg bg-white/40 dark:bg-black/40 shadow-sm border border-transparent transition-all duration-300 hover:scale-105 hover:shadow-lg hover:shadow-cyan-500/50 hover:border-cyan-500 lg:rounded-tr-4xl">
<div className="flex items-center">
<div className="w-1/3 p-4">
<img
alt={features[1].title}
src={features[1].image}
className="w-40 h-40 object-contain"
/>
</div>
<div className="w-2/3 p-4">
<h3 className="text-lg font-semibold text-black dark:text-white">{features[1].title}</h3>
<CP className="mt-2 text-gray-600 dark:text-gray-300">
{features[1].description}
</CP>
</div>
</div>
</div>
</div>
<div className="flex p-px lg:col-span-3">
<div className="w-full overflow-hidden rounded-lg bg-white/40 dark:bg-black/40 shadow-sm border border-transparent transition-all duration-300 hover:scale-105 hover:shadow-lg hover:shadow-cyan-500/50 hover:border-cyan-500 lg:rounded-bl-4xl">
<div className="flex items-center">
<div className="w-1/3 p-4">
<img
alt={features[2].title}
src={features[2].image}
className="w-40 h-40 object-contain"
/>
</div>
<div className="w-2/3 p-4">
<h3 className="text-lg font-semibold text-black dark:text-white">{features[2].title}</h3>
<CP className="mt-2 text-gray-600 dark:text-gray-300">
{features[2].description}
</CP>
</div>
</div>
</div>
</div>
<div className="flex p-px lg:col-span-4">
<div className="w-full overflow-hidden rounded-lg bg-white/40 dark:bg-black/40 shadow-sm border border-transparent transition-all duration-300 hover:scale-105 hover:shadow-lg hover:shadow-cyan-500/50 hover:border-cyan-500 max-lg:rounded-b-4xl lg:rounded-br-4xl">
<div className="flex items-center">
<div className="w-1/3 p-2">
<img
alt={features[3].title}
src={features[3].image}
className="w-40 h-40 object-contain"
/>
</div>
<div className="w-2/3 p-2 pr-12">
<h3 className="text-lg font-semibold text-black dark:text-white">{features[3].title}</h3>
<CP className="mt-2 text-gray-600 dark:text-gray-300">
{features[3].description}
</CP>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
export const SkeletonOne = () => {
return (
<div className="relative flex py-8 px-2 gap-10 h-full">
<div className="w-full p-5 mx-auto bg-white dark:bg-neutral-900 shadow-2xl group h-full">
<div className="flex flex-1 w-full h-full flex-col space-y-2 ">
{/* TODO */}
<img
src="/linear.webp"
alt="header"
width={800}
height={800}
className="h-full w-full aspect-square object-cover object-left-top rounded-sm"
/>
</div>
</div>
<div className="absolute bottom-0 z-40 inset-x-0 h-60 bg-gradient-to-t from-white dark:from-black via-white dark:via-black to-transparent w-full pointer-events-none" />
<div className="absolute top-0 z-40 inset-x-0 h-60 bg-gradient-to-b from-white dark:from-black via-transparent to-transparent w-full pointer-events-none" />
</div>
);
};
export const SkeletonThree = () => {
return (
<a
href="https://www.youtube.com/watch?v=RPa3_AD1_Vs"
target="__blank"
className="relative flex gap-10 h-full group/image"
>
<div className="w-full mx-auto bg-transparent dark:bg-transparent group h-full">
<div className="flex flex-1 w-full h-full flex-col space-y-2 relative">
{/* TODO */}
<IconBrandYoutubeFilled className="h-20 w-20 absolute z-10 inset-0 text-red-500 m-auto " />
<img
src="https://assets.aceternity.com/fireship.jpg"
alt="header"
width={800}
height={800}
className="h-full w-full aspect-square object-cover object-center rounded-sm blur-none group-hover/image:blur-md transition-all duration-200"
/>
</div>
</div>
</a>
);
};
export const SkeletonTwo = () => {
const images = [
"https://images.unsplash.com/photo-1517322048670-4fba75cbbb62?q=80&w=3000&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
"https://images.unsplash.com/photo-1573790387438-4da905039392?q=80&w=3425&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
"https://images.unsplash.com/photo-1555400038-63f5ba517a47?q=80&w=3540&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
"https://images.unsplash.com/photo-1554931670-4ebfabf6e7a9?q=80&w=3387&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
"https://images.unsplash.com/photo-1546484475-7f7bd55792da?q=80&w=2581&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
];
const imageVariants = {
whileHover: {
scale: 1.1,
rotate: 0,
zIndex: 100,
},
whileTap: {
scale: 1.1,
rotate: 0,
zIndex: 100,
},
};
return (
<div className="relative flex flex-col items-start p-8 gap-10 h-full overflow-hidden">
{/* TODO */}
<div className="flex flex-row -ml-20">
{images.map((image, idx) => (
<motion.div
variants={imageVariants}
key={"images-first" + idx}
style={{
rotate: Math.random() * 20 - 10,
}}
whileHover="whileHover"
whileTap="whileTap"
className="rounded-xl -mr-4 mt-4 p-1 bg-white dark:bg-neutral-800 dark:border-neutral-700 border border-neutral-100 shrink-0 overflow-hidden"
>
<img
src={image}
alt="bali images"
width="500"
height="500"
className="rounded-lg h-20 w-20 md:h-40 md:w-40 object-cover shrink-0"
/>
</motion.div>
))}
</div>
<div className="flex flex-row">
{images.map((image, idx) => (
<motion.div
key={"images-second" + idx}
style={{
rotate: Math.random() * 20 - 10,
}}
variants={imageVariants}
whileHover="whileHover"
whileTap="whileTap"
className="rounded-xl -mr-4 mt-4 p-1 bg-white dark:bg-neutral-800 dark:border-neutral-700 border border-neutral-100 shrink-0 overflow-hidden"
>
<img
src={image}
alt="bali images"
width="500"
height="500"
className="rounded-lg h-20 w-20 md:h-40 md:w-40 object-cover shrink-0"
/>
</motion.div>
))}
</div>
<div className="absolute left-0 z-[100] inset-y-0 w-20 bg-gradient-to-r from-white dark:from-black to-transparent h-full pointer-events-none" />
<div className="absolute right-0 z-[100] inset-y-0 w-20 bg-gradient-to-l from-white dark:from-black to-transparent h-full pointer-events-none" />
</div>
);
};
export const SkeletonFour = () => {
return (
<div className="h-60 md:h-60 flex flex-col items-center relative bg-transparent dark:bg-transparent mt-10">
<Globe className="absolute -right-10 md:-right-10 -bottom-80 md:-bottom-72" />
</div>
);
};
export const Globe = ({ className }: { className?: string }) => {
const canvasRef = useRef<HTMLCanvasElement>(null);
useEffect(() => {
let phi = 0;
if (!canvasRef.current) return;
const globe = createGlobe(canvasRef.current, {
devicePixelRatio: 2,
width: 600 * 2,
height: 600 * 2,
phi: 0,
theta: 0,
dark: 1,
diffuse: 1.2,
mapSamples: 16000,
mapBrightness: 6,
baseColor: [0.3, 0.3, 0.3],
markerColor: [0.1, 0.8, 1],
glowColor: [1, 1, 1],
markers: [
// longitude latitude
{ location: [37.7595, -122.4367], size: 0.03 },
{ location: [40.7128, -74.006], size: 0.1 },
],
onRender: (state) => {
// Called on every animation frame.
// `state` will be an empty object, return updated params.
state.phi = phi;
phi += 0.01;
},
});
return () => {
globe.destroy();
};
}, []);
return (
<canvas
ref={canvasRef}
style={{ width: 600, height: 600, maxWidth: "100%", aspectRatio: 1 }}
className={className}
/>
);
};