ok
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
import CountUp from "react-countup";
|
||||
import React from "react";
|
||||
import { Button } from "./Button";
|
||||
import { Button } from "@/components/Button";
|
||||
|
||||
export function GridStats() {
|
||||
return (
|
||||
|
263
src/components/Archives/UseCases copy.tsx
Normal file
263
src/components/Archives/UseCases copy.tsx
Normal file
@@ -0,0 +1,263 @@
|
||||
'use client'
|
||||
|
||||
import React, { useEffect, useMemo, useRef, useState } from 'react'
|
||||
import clsx from 'clsx'
|
||||
import {
|
||||
ArchiveBoxIcon,
|
||||
CodeBracketIcon,
|
||||
CpuChipIcon,
|
||||
GlobeAltIcon,
|
||||
MagnifyingGlassIcon,
|
||||
ShareIcon,
|
||||
UserGroupIcon,
|
||||
CheckBadgeIcon,
|
||||
} from '@heroicons/react/24/solid'
|
||||
|
||||
import { Container } from '@/components/Container'
|
||||
import { H2, P, CT, CP } from '@/components/Texts'
|
||||
import { motion, useInView } from 'framer-motion'
|
||||
|
||||
interface Review {
|
||||
title: string
|
||||
body: string
|
||||
}
|
||||
|
||||
const reviews: Array<Review> = [
|
||||
{
|
||||
title: 'FungiStor: Long-Term AI Memory',
|
||||
body: 'Quantum-safe permanent storage preserving AI knowledge forever. Zero-knowledge architecture with mathematical dispersal ensures immortality.',
|
||||
},
|
||||
{
|
||||
title: 'HeroDB: Active AI Memory',
|
||||
body: 'High-performance datastore for AI working memory. Multi-modal indexing enables vector search with global accessibility.',
|
||||
},
|
||||
{
|
||||
title: 'MOS Sandboxes: Secure Agent Workspaces',
|
||||
body: 'Lightweight isolated environments deploying globally in five seconds. Hardware-level isolation ensures maximum security for agents.',
|
||||
},
|
||||
{
|
||||
title: 'Mycelium Mesh: Secure Communication Network',
|
||||
body: 'Peer-to-peer overlay network with end-to-end encryption. Self-healing shortest-path routing creates resilient agentic communication.',
|
||||
},
|
||||
{
|
||||
title: 'Deterministic Deployment: Verifiable Code Execution',
|
||||
body: 'Cryptographic guarantee system ensuring deployed code matches specifications. Prevents supply-chain attacks with immutable trails.',
|
||||
},
|
||||
{
|
||||
title: 'Agent Coordination: Sovereign Workflow Management',
|
||||
body: 'User-centric orchestration where HERO agents coordinate worker fleets. Planetary-scale coordination with instant spawning.',
|
||||
},
|
||||
{
|
||||
title: 'Universal Interface Layer: AI Service Gateway',
|
||||
body: 'Unified broker connecting agents to LLMs, APIs, and services. Integrated micropayments simplify development.',
|
||||
},
|
||||
{
|
||||
title: 'Semantic Index & Search: Navigable Knowledge Fabric',
|
||||
body: 'Transforms data chaos into unified knowledge graphs. Goes beyond keywords to understand meaning and context.',
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
function getReviewIcon(title: string) {
|
||||
if (title.startsWith('FungiStor')) return ArchiveBoxIcon;
|
||||
if (title.startsWith('HeroDB')) return CpuChipIcon;
|
||||
if (title.startsWith('MOS Sandboxes')) return CodeBracketIcon;
|
||||
if (title.startsWith('Mycelium Mesh')) return ShareIcon;
|
||||
if (title.startsWith('Deterministic Deployment')) return CheckBadgeIcon;
|
||||
if (title.startsWith('Agent Coordination')) return UserGroupIcon;
|
||||
if (title.startsWith('Universal Interface Layer')) return GlobeAltIcon;
|
||||
if (title.startsWith('Semantic Index & Search')) return MagnifyingGlassIcon;
|
||||
return GlobeAltIcon; // default
|
||||
}
|
||||
|
||||
function Review({
|
||||
title,
|
||||
body,
|
||||
className,
|
||||
...props
|
||||
}: Omit<React.ComponentPropsWithoutRef<'figure'>, keyof Review> & Review) {
|
||||
let animationDelay = useMemo(() => {
|
||||
let possibleAnimationDelays = ['0s', '0.1s', '0.2s', '0.3s', '0.4s', '0.5s']
|
||||
return possibleAnimationDelays[
|
||||
Math.floor(Math.random() * possibleAnimationDelays.length)
|
||||
]
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<figure
|
||||
className={clsx(
|
||||
'animate-fade-in rounded-3xl bg-white p-6 opacity-0 shadow-md shadow-gray-900/5',
|
||||
className,
|
||||
)}
|
||||
style={{ animationDelay }}
|
||||
{...props}
|
||||
>
|
||||
<blockquote className="text-gray-900">
|
||||
{React.createElement(getReviewIcon(title), { className: "h-6 w-6 text-[#2F3178] mb-2" })}
|
||||
<CT color="primary" className="mt-4 text-lg/6 font-semibold">
|
||||
{title}
|
||||
</CT>
|
||||
<CP color="custom" className="mt-3 text-sm">{body}</CP>
|
||||
</blockquote>
|
||||
|
||||
</figure>
|
||||
)
|
||||
}
|
||||
|
||||
function splitArray<T>(array: Array<T>, numParts: number) {
|
||||
let result: Array<Array<T>> = []
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
let index = i % numParts
|
||||
if (!result[index]) {
|
||||
result[index] = []
|
||||
}
|
||||
result[index].push(array[i])
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
function ReviewColumn({
|
||||
reviews,
|
||||
className,
|
||||
reviewClassName,
|
||||
msPerPixel = 0,
|
||||
}: {
|
||||
reviews: Array<Review>
|
||||
className?: string
|
||||
reviewClassName?: (reviewIndex: number) => string
|
||||
msPerPixel?: number
|
||||
}) {
|
||||
let columnRef = useRef<React.ElementRef<'div'>>(null)
|
||||
let [columnHeight, setColumnHeight] = useState(0)
|
||||
let duration = `${columnHeight * msPerPixel}ms`
|
||||
|
||||
useEffect(() => {
|
||||
if (!columnRef.current) {
|
||||
return
|
||||
}
|
||||
|
||||
let resizeObserver = new window.ResizeObserver(() => {
|
||||
setColumnHeight(columnRef.current?.offsetHeight ?? 0)
|
||||
})
|
||||
|
||||
resizeObserver.observe(columnRef.current)
|
||||
|
||||
return () => {
|
||||
resizeObserver.disconnect()
|
||||
}
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={columnRef}
|
||||
className={clsx('animate-marquee space-y-8 py-4', className)}
|
||||
style={{ '--marquee-duration': duration } as React.CSSProperties}
|
||||
>
|
||||
{reviews.concat(reviews).map((review, reviewIndex) => (
|
||||
<Review
|
||||
key={reviewIndex}
|
||||
aria-hidden={reviewIndex >= reviews.length}
|
||||
className={reviewClassName?.(reviewIndex % reviews.length)}
|
||||
{...review}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function ReviewGrid() {
|
||||
let containerRef = useRef<React.ElementRef<'div'>>(null)
|
||||
let isInView = useInView(containerRef, { once: true, amount: 0.4 })
|
||||
let columns = splitArray(reviews, 3)
|
||||
let column1 = columns[0]
|
||||
let column2 = columns[1]
|
||||
let column3 = splitArray(columns[2], 2)
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={containerRef}
|
||||
className="relative -mx-4 mt-0 grid h-196 max-h-[150vh] grid-cols-1 items-start gap-8 overflow-hidden px-4 sm:mt-20 md:grid-cols-2 lg:grid-cols-3"
|
||||
>
|
||||
{isInView && (
|
||||
<>
|
||||
<ReviewColumn
|
||||
reviews={[...column1, ...column3.flat(), ...column2]}
|
||||
reviewClassName={(reviewIndex) =>
|
||||
clsx(
|
||||
reviewIndex >= column1.length + column3[0].length &&
|
||||
'md:hidden',
|
||||
reviewIndex >= column1.length && 'lg:hidden',
|
||||
)
|
||||
}
|
||||
msPerPixel={10}
|
||||
/>
|
||||
<ReviewColumn
|
||||
reviews={[...column2, ...column3[1]]}
|
||||
className="hidden md:block"
|
||||
reviewClassName={(reviewIndex) =>
|
||||
reviewIndex >= column2.length ? 'lg:hidden' : ''
|
||||
}
|
||||
msPerPixel={15}
|
||||
/>
|
||||
<ReviewColumn
|
||||
reviews={column3.flat()}
|
||||
className="hidden lg:block"
|
||||
msPerPixel={10}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
<div className="pointer-events-none absolute inset-x-0 top-0 h-32 bg-linear-to-b from-white" />
|
||||
<div className="pointer-events-none absolute inset-x-0 bottom-0 h-32 bg-linear-to-t from-white" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export function UseCases() {
|
||||
const ref = useRef(null);
|
||||
const isInView = useInView(ref, { once: true });
|
||||
|
||||
return (
|
||||
<section
|
||||
id="usecases"
|
||||
ref={ref}
|
||||
aria-labelledby="usecases-title"
|
||||
className="py-12"
|
||||
>
|
||||
<Container className=''>
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={isInView ? { opacity: 1, y: 0 } : { opacity: 0, y: 20 }}
|
||||
transition={{ duration: 0.8, delay: 0.1 }}
|
||||
className="mx-auto max-w-2xl lg:max-w-5xl"
|
||||
>
|
||||
<H2
|
||||
id="usecases-title"
|
||||
color="primary"
|
||||
className="text-center"
|
||||
>
|
||||
Coming Soon: The Future of Mycelium
|
||||
</H2>
|
||||
<P className="mt-6 text-center" color="custom">
|
||||
Mycelium Cloud is evolving to bring even more powerful decentralized features, designed to enhance your experience and expand possibilities. Be the first to explore what's coming next by staying connected with our latest updates.
|
||||
</P>
|
||||
</motion.div>
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={isInView ? { opacity: 1 } : { opacity: 0 }}
|
||||
transition={{ duration: 1, delay: 0.2 }}
|
||||
aria-hidden="true"
|
||||
className="absolute inset-x-0 -top-40 -z-10 transform-gpu overflow-hidden blur-3xl sm:-top-80"
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
clipPath:
|
||||
'polygon(74.1% 44.1%, 100% 61.6%, 97.5% 26.9%, 85.5% 0.1%, 80.7% 2%, 72.5% 32.5%, 60.2% 62.4%, 52.4% 68.1%, 47.5% 58.3%, 45.2% 34.5%, 27.5% 76.7%, 0.1% 64.9%, 17.9% 100%, 27.6% 76.8%, 76.1% 97.7%, 74.1% 44.1%)',
|
||||
}}
|
||||
className="relative left-[calc(50%-30rem)] aspect-[1155/678] w-[36.125rem] -translate-x-1/2 bg-gradient-to-tr from-[#93c5fd] to-[#9089fc] opacity-30 sm:left-[calc(50%-36rem)] sm:w-[72.1875rem]"
|
||||
/>
|
||||
</motion.div>
|
||||
<ReviewGrid />
|
||||
</Container>
|
||||
</section>
|
||||
)
|
||||
}
|
@@ -1,14 +1,21 @@
|
||||
import { useId } from 'react'
|
||||
import clsx from 'clsx'
|
||||
|
||||
const formClasses =
|
||||
'block w-full appearance-none rounded-lg border border-gray-200 bg-white py-[calc(--spacing(2)-1px)] px-[calc(--spacing(3)-1px)] text-gray-900 placeholder:text-gray-400 focus:border-cyan-500 focus:outline-hidden focus:ring-cyan-500 sm:text-sm'
|
||||
const formClasses = {
|
||||
light:
|
||||
'block w-full appearance-none rounded-lg border border-gray-200 bg-white py-[calc(--spacing(2)-1px)] px-[calc(--spacing(3)-1px)] text-gray-900 placeholder:text-gray-400 focus:border-cyan-500 focus:outline-none focus:ring-cyan-500 sm:text-sm',
|
||||
dark:
|
||||
'block w-full appearance-none rounded-lg border border-gray-600 bg-transparent py-[calc(--spacing(2)-1px)] px-[calc(--spacing(3)-1px)] text-white placeholder:text-gray-400 focus:border-cyan-500 focus:outline-none focus:ring-cyan-500 sm:text-sm',
|
||||
}
|
||||
|
||||
function Label({ id, children }: { id: string; children: React.ReactNode }) {
|
||||
function Label({ id, children, variant = 'light' }: { id: string; children: React.ReactNode, variant?: 'light' | 'dark' }) {
|
||||
return (
|
||||
<label
|
||||
htmlFor={id}
|
||||
className="mb-2 block text-sm font-semibold text-gray-900"
|
||||
className={clsx(
|
||||
'mb-2 block text-sm font-semibold',
|
||||
variant === 'light' ? 'text-gray-900' : 'text-white',
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</label>
|
||||
@@ -19,14 +26,15 @@ export function TextField({
|
||||
label,
|
||||
type = 'text',
|
||||
className,
|
||||
variant = 'light',
|
||||
...props
|
||||
}: Omit<React.ComponentPropsWithoutRef<'input'>, 'id'> & { label?: string }) {
|
||||
}: Omit<React.ComponentPropsWithoutRef<'input'>, 'id'> & { label?: string; variant?: 'light' | 'dark' }) {
|
||||
let id = useId()
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
{label && <Label id={id}>{label}</Label>}
|
||||
<input id={id} type={type} {...props} className={formClasses} />
|
||||
{label && <Label id={id} variant={variant}>{label}</Label>}
|
||||
<input id={id} type={type} {...props} className={formClasses[variant]} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@@ -22,11 +22,11 @@ function QrCodeBorder(props: React.ComponentPropsWithoutRef<'svg'>) {
|
||||
|
||||
export function Footer() {
|
||||
return (
|
||||
<footer id="footer" className="border-t border-gray-200">
|
||||
<footer id="footer" className="border-t border-gray-800">
|
||||
<Container>
|
||||
<div className="flex flex-col items-start justify-between gap-y-12 pt-16 pb-6 lg:flex-row lg:items-center lg:py-16">
|
||||
<div>
|
||||
<div className="flex items-center text-gray-900">
|
||||
<div className="flex items-center text-white">
|
||||
<Logomark className="h-10 w-10 flex-none fill-cyan-500" />
|
||||
<div className="ml-4">
|
||||
<p className="text-base font-semibold">Project Mycelium</p>
|
||||
@@ -37,25 +37,25 @@ export function Footer() {
|
||||
<NavLinks />
|
||||
</nav>
|
||||
</div>
|
||||
<div className="group relative -mx-4 flex items-center self-stretch p-4 transition-colors hover:bg-gray-100 sm:self-auto sm:rounded-2xl lg:mx-0 lg:self-auto lg:p-6">
|
||||
<div className="group relative -mx-4 flex items-center self-stretch p-4 transition-colors hover:bg-gray-800/50 sm:self-auto sm:rounded-2xl lg:mx-0 lg:self-auto lg:p-6">
|
||||
<div className="relative flex h-24 w-24 flex-none items-center justify-center">
|
||||
<QrCodeBorder className="absolute inset-0 h-full w-full stroke-gray-300 transition-colors group-hover:stroke-cyan-500" />
|
||||
<QrCodeBorder className="absolute inset-0 h-full w-full stroke-gray-700 transition-colors group-hover:stroke-cyan-500" />
|
||||
<Image src={qrCode} alt="" unoptimized />
|
||||
</div>
|
||||
<div className="ml-8 lg:w-64">
|
||||
<p className="text-base font-semibold text-gray-900">
|
||||
<p className="text-base font-semibold text-white">
|
||||
<Link href="#">
|
||||
<span className="absolute inset-0 sm:rounded-2xl" />
|
||||
Download the app
|
||||
</Link>
|
||||
</p>
|
||||
<p className="mt-1 text-sm text-gray-700">
|
||||
<p className="mt-1 text-sm text-gray-400">
|
||||
Scan the QR code to download the app from the App Store.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col items-center border-t border-gray-200 pt-8 pb-12 md:flex-row-reverse md:justify-between md:pt-6">
|
||||
<div className="flex flex-col items-center border-t border-gray-800 pt-8 pb-12 md:flex-row-reverse md:justify-between md:pt-6">
|
||||
<form className="flex w-full justify-center md:w-auto">
|
||||
<TextField
|
||||
type="email"
|
||||
@@ -63,6 +63,7 @@ export function Footer() {
|
||||
placeholder="Email address"
|
||||
autoComplete="email"
|
||||
required
|
||||
variant="dark"
|
||||
className="w-60 min-w-0 shrink"
|
||||
/>
|
||||
<Button type="submit" color="cyan" className="ml-4 flex-none">
|
||||
@@ -70,7 +71,7 @@ export function Footer() {
|
||||
<span className="lg:hidden">Join newsletter</span>
|
||||
</Button>
|
||||
</form>
|
||||
<p className="mt-6 text-sm text-gray-500 md:mt-0">
|
||||
<p className="mt-6 text-sm text-gray-400 md:mt-0">
|
||||
© Copyright ThreeFold {new Date().getFullYear()}. All rights reserved.
|
||||
</p>
|
||||
</div>
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
import CountUp from "react-countup";
|
||||
import React from "react";
|
||||
import { Button } from "./Button";
|
||||
import { Button } from "@/components/Button";
|
||||
|
||||
export function GridStats() {
|
||||
return (
|
||||
@@ -63,16 +63,10 @@ export function GridStats() {
|
||||
function StatCard({
|
||||
label,
|
||||
description,
|
||||
value,
|
||||
unit,
|
||||
note,
|
||||
className = "",
|
||||
}: {
|
||||
label: string;
|
||||
description: string;
|
||||
value: React.ReactNode;
|
||||
unit?: string;
|
||||
note: string;
|
||||
className?: string;
|
||||
}) {
|
||||
return (
|
||||
|
@@ -86,18 +86,18 @@ function Review({
|
||||
return (
|
||||
<figure
|
||||
className={clsx(
|
||||
'animate-fade-in rounded-3xl bg-white p-6 opacity-0 shadow-md shadow-gray-900/5',
|
||||
'animate-fade-in rounded-3xl bg-gray-900/50 p-6 opacity-0 shadow-md shadow-gray-900/5',
|
||||
className,
|
||||
)}
|
||||
style={{ animationDelay }}
|
||||
{...props}
|
||||
>
|
||||
<blockquote className="text-gray-900">
|
||||
<blockquote className="text-white">
|
||||
{React.createElement(getReviewIcon(title), { className: "h-6 w-6 text-[#2F3178] mb-2" })}
|
||||
<CT color="primary" className="mt-4 text-lg/6 font-semibold">
|
||||
<CT color="light" className="mt-4 text-lg/6 font-semibold">
|
||||
{title}
|
||||
</CT>
|
||||
<CP color="custom" className="mt-3 text-sm">{body}</CP>
|
||||
<CP color="light" className="mt-3 text-sm">{body}</CP>
|
||||
</blockquote>
|
||||
|
||||
</figure>
|
||||
@@ -176,7 +176,7 @@ function ReviewGrid() {
|
||||
return (
|
||||
<div
|
||||
ref={containerRef}
|
||||
className="relative -mx-4 mt-0 grid h-196 max-h-[150vh] grid-cols-1 items-start gap-8 overflow-hidden px-4 sm:mt-20 md:grid-cols-2 lg:grid-cols-3"
|
||||
className="relative -mx-4 mt-0 grid h-196 max-h-[150vh] grid-cols-1 items-start gap-8 overflow-hidden px-4 md:grid-cols-2 lg:grid-cols-3"
|
||||
>
|
||||
{isInView && (
|
||||
<>
|
||||
@@ -206,8 +206,8 @@ function ReviewGrid() {
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
<div className="pointer-events-none absolute inset-x-0 top-0 h-32 bg-linear-to-b from-white" />
|
||||
<div className="pointer-events-none absolute inset-x-0 bottom-0 h-32 bg-linear-to-t from-white" />
|
||||
<div className="pointer-events-none absolute inset-x-0 top-0 h-32 bg-linear-to-b from-black" />
|
||||
<div className="pointer-events-none absolute inset-x-0 bottom-0 h-32 bg-linear-to-t from-black" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -221,7 +221,7 @@ export function UseCases() {
|
||||
id="usecases"
|
||||
ref={ref}
|
||||
aria-labelledby="usecases-title"
|
||||
className="py-12"
|
||||
className="bg-black py-12"
|
||||
>
|
||||
<Container className=''>
|
||||
<motion.div
|
||||
@@ -232,12 +232,12 @@ export function UseCases() {
|
||||
>
|
||||
<H2
|
||||
id="usecases-title"
|
||||
color="primary"
|
||||
color="light"
|
||||
className="text-center"
|
||||
>
|
||||
Coming Soon: The Future of Mycelium
|
||||
</H2>
|
||||
<P className="mt-6 text-center" color="custom">
|
||||
<P className="mt-6 text-center" color="light">
|
||||
Mycelium Cloud is evolving to bring even more powerful decentralized features, designed to enhance your experience and expand possibilities. Be the first to explore what's coming next by staying connected with our latest updates.
|
||||
</P>
|
||||
</motion.div>
|
||||
|
Reference in New Issue
Block a user