forked from emre/www_projectmycelium_com
		
	feat: redesign cloud features section with new UI and content
- Replaced mobile phone mockups with full-width desktop screenshots for cloud platform features - Updated feature descriptions to focus on cloud/Kubernetes capabilities instead of network features - Changed section layout to improve desktop view with left-aligned feature tabs - Removed unused phone frame component and related mobile UI elements - Updated image assets from jpg to png format and reorganized image paths - Reordered page
This commit is contained in:
		@@ -11,7 +11,6 @@ import {
 | 
			
		||||
} from 'framer-motion'
 | 
			
		||||
import { useDebouncedCallback } from 'use-debounce'
 | 
			
		||||
 | 
			
		||||
import { AppScreen } from '../network/AppScreen'
 | 
			
		||||
import {
 | 
			
		||||
  Eyebrow,
 | 
			
		||||
  FeatureDescription,
 | 
			
		||||
@@ -23,10 +22,9 @@ import {
 | 
			
		||||
import { CircleBackground } from '@/components/CircleBackground'
 | 
			
		||||
import { Container } from '@/components/Container'
 | 
			
		||||
 | 
			
		||||
import connectorImg from '@/images/connector.png'
 | 
			
		||||
import peersImg from '@/images/peers.png'
 | 
			
		||||
import settingImg from '@/images/setting.png'
 | 
			
		||||
import { PhoneFrame } from '@/components/PhoneFrame'
 | 
			
		||||
import reservenodeimg from '/images/cloud/reserve.png'
 | 
			
		||||
import billingImg from '/images/cloud/billing.png'
 | 
			
		||||
import kubeconfigImg from '/images/cloud/kubeconfig.png'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
interface CustomAnimationProps {
 | 
			
		||||
@@ -36,25 +34,25 @@ interface CustomAnimationProps {
 | 
			
		||||
 | 
			
		||||
const features = [
 | 
			
		||||
  {
 | 
			
		||||
    name: 'Mycelium Connector',
 | 
			
		||||
    name: 'Decentralized Kubernetes',
 | 
			
		||||
    description:
 | 
			
		||||
      "Start (and stop) your Mycelium connector to gain access to sites, apps, and workloads available exclusively on the Mycelium Network. View statistics around peers and traffic.",
 | 
			
		||||
      "Reserve a node and deploy sovereign Kubernetes clusters on decentralized infrastructure.",
 | 
			
		||||
    icon: DeviceUserIcon,
 | 
			
		||||
    screen: InviteScreen,
 | 
			
		||||
    screen: ReserveNodeScreen,
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: 'Mycelium Peers',
 | 
			
		||||
    name: 'Manage Your Cluster',
 | 
			
		||||
    description:
 | 
			
		||||
      'Search and discover active peers on the Mycelium Network, or add your own.',
 | 
			
		||||
      'Manage your cluster with ease, with a simple and intuitive interface.',
 | 
			
		||||
    icon: DeviceNotificationIcon,
 | 
			
		||||
    screen: StocksScreen,
 | 
			
		||||
    screen: ManageClusterScreen,
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: 'Network Setting',
 | 
			
		||||
    name: 'Personalised Billings & Accounts',
 | 
			
		||||
    description:
 | 
			
		||||
      'Find version and network information and trigger light or dark mode.',
 | 
			
		||||
      'Easily manage your cluster billing and accounts with personalised configurations.',
 | 
			
		||||
    icon: DeviceTouchIcon,
 | 
			
		||||
    screen: InvestScreen,
 | 
			
		||||
    screen: PersonalisedBillingsScreen,
 | 
			
		||||
  },
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
@@ -182,28 +180,40 @@ const bodyAnimation: MotionProps = {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function InviteScreen() {
 | 
			
		||||
function ReserveNodeScreen() {
 | 
			
		||||
  return (
 | 
			
		||||
    <AppScreen className="w-full">
 | 
			
		||||
      <img src={connectorImg} alt="Mycelium Connector" width="366" height="732" className="-mt-8" />
 | 
			
		||||
    </AppScreen>
 | 
			
		||||
  )
 | 
			
		||||
    <img
 | 
			
		||||
      src={reservenodeimg}
 | 
			
		||||
      alt="Mycelium Reserve Node"
 | 
			
		||||
      width={2432}
 | 
			
		||||
      height={1442}
 | 
			
		||||
      className="w-4xl max-w-none rounded-xl shadow-xl ring-1 ring-gray-400/10 sm:w-240 md:-ml-4 lg:ml-0"
 | 
			
		||||
    />
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function StocksScreen() {
 | 
			
		||||
function ManageClusterScreen() {
 | 
			
		||||
  return (
 | 
			
		||||
    <AppScreen className="w-full">
 | 
			
		||||
      <img src={peersImg} alt="Mycelium Peers" width="366" height="732" className="-mt-8" />
 | 
			
		||||
    </AppScreen>
 | 
			
		||||
  )
 | 
			
		||||
    <img
 | 
			
		||||
      src={kubeconfigImg}
 | 
			
		||||
      alt="Mycelium Kubeconfig"
 | 
			
		||||
      width={2432}
 | 
			
		||||
      height={1442}
 | 
			
		||||
      className="w-4xl max-w-none rounded-xl shadow-xl ring-1 ring-gray-400/10 sm:w-240 md:-ml-4 lg:ml-0"
 | 
			
		||||
    />
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function InvestScreen() {
 | 
			
		||||
function PersonalisedBillingsScreen() {
 | 
			
		||||
  return (
 | 
			
		||||
    <AppScreen className="w-full">
 | 
			
		||||
      <img src={settingImg} alt="Mycelium Settings" width="366" height="732" className="-mt-8" />
 | 
			
		||||
    </AppScreen>
 | 
			
		||||
  )
 | 
			
		||||
    <img
 | 
			
		||||
      src={billingImg}
 | 
			
		||||
      alt="Mycelium Billing"
 | 
			
		||||
      width={2432}
 | 
			
		||||
      height={1442}
 | 
			
		||||
      className="w-4xl max-w-none rounded-xl shadow-xl ring-1 ring-gray-400/10 sm:w-240 md:-ml-4 lg:ml-0"
 | 
			
		||||
    />
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function usePrevious<T>(value: T) {
 | 
			
		||||
@@ -216,7 +226,7 @@ function usePrevious<T>(value: T) {
 | 
			
		||||
  return ref.current
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function FeaturesDesktop() {
 | 
			
		||||
function CloudFeaturesDesktop() {
 | 
			
		||||
  let [changeCount, setChangeCount] = useState(0)
 | 
			
		||||
  let [selectedIndex, setSelectedIndex] = useState(0)
 | 
			
		||||
  let prevIndex = usePrevious(selectedIndex)
 | 
			
		||||
@@ -238,12 +248,12 @@ function FeaturesDesktop() {
 | 
			
		||||
      onChange={onChange}
 | 
			
		||||
      vertical
 | 
			
		||||
    >
 | 
			
		||||
      <TabList className="z-10 order-last col-span-6 space-y-6">
 | 
			
		||||
      <TabList className="z-10 col-span-6 space-y-6 pl-4 sm:pl-6 lg:pl-8">
 | 
			
		||||
        {features.map((feature, featureIndex) => (
 | 
			
		||||
          <div
 | 
			
		||||
            key={feature.name}
 | 
			
		||||
            className={clsx(
 | 
			
		||||
              'relative rounded-2xl outline-2 transition-all duration-300 ease-in-out hover:scale-105 hover:bg-gray-800/30',
 | 
			
		||||
              'relative rounded-2xl outline-2 transition-all duration-300 ease-in-out hover:scale-105 hover:bg-gray-800/30 ml-16',
 | 
			
		||||
              selectedIndex === featureIndex
 | 
			
		||||
                ? 'outline-cyan-500'
 | 
			
		||||
                : 'outline-transparent hover:outline-cyan-500',
 | 
			
		||||
@@ -252,7 +262,7 @@ function FeaturesDesktop() {
 | 
			
		||||
            {featureIndex === selectedIndex && (
 | 
			
		||||
              <motion.div
 | 
			
		||||
                layoutId="activeBackground"
 | 
			
		||||
                className="absolute inset-0 bg-gray-800"
 | 
			
		||||
                className="absolute inset-0 bg-gray-800 "
 | 
			
		||||
                initial={{ borderRadius: 16 }}
 | 
			
		||||
              />
 | 
			
		||||
            )}
 | 
			
		||||
@@ -271,11 +281,11 @@ function FeaturesDesktop() {
 | 
			
		||||
          </div>
 | 
			
		||||
        ))}
 | 
			
		||||
      </TabList>
 | 
			
		||||
      <div className="relative col-span-6">
 | 
			
		||||
      <div className="relative col-span-6 overflow-hidden">
 | 
			
		||||
        <div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2">
 | 
			
		||||
          <CircleBackground id="primaryfeatures_desktop_circle" color="#13B5C8" className="animate-spin-slower" />
 | 
			
		||||
        </div>
 | 
			
		||||
        <PhoneFrame className="z-10 mx-auto w-full max-w-[366px]">
 | 
			
		||||
        <div className="z-10 mx-auto w-full max-w-[366px]">
 | 
			
		||||
          <TabPanels as={Fragment}>
 | 
			
		||||
            <AnimatePresence
 | 
			
		||||
              initial={false}
 | 
			
		||||
@@ -296,13 +306,13 @@ function FeaturesDesktop() {
 | 
			
		||||
              )}
 | 
			
		||||
            </AnimatePresence>
 | 
			
		||||
          </TabPanels>
 | 
			
		||||
        </PhoneFrame>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </TabGroup>
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function FeaturesMobile() {
 | 
			
		||||
function CloudFeaturesMobile() {
 | 
			
		||||
  let [activeIndex, setActiveIndex] = useState(0)
 | 
			
		||||
  let slideContainerRef = useRef<React.ElementRef<'div'>>(null)
 | 
			
		||||
  let slideRefs = useRef<Array<React.ElementRef<'div'>>>([])
 | 
			
		||||
@@ -361,9 +371,9 @@ function FeaturesMobile() {
 | 
			
		||||
                  className={featureIndex % 2 === 1 ? 'rotate-180' : undefined}
 | 
			
		||||
                />
 | 
			
		||||
              </div>
 | 
			
		||||
              <PhoneFrame className="relative mx-auto w-full max-w-[366px]">
 | 
			
		||||
              <div className="relative mx-auto w-full max-w-[366px]">
 | 
			
		||||
                <feature.screen />
 | 
			
		||||
              </PhoneFrame>
 | 
			
		||||
              </div>
 | 
			
		||||
              <div className="absolute inset-x-0 bottom-0 bg-gray-800/95 p-6 backdrop-blur-sm sm:p-10">
 | 
			
		||||
                <feature.icon className="h-8 w-8" />
 | 
			
		||||
                <MobileFeatureTitle color="white" className="mt-6">
 | 
			
		||||
@@ -405,29 +415,27 @@ function FeaturesMobile() {
 | 
			
		||||
export function CloudFeatures() {
 | 
			
		||||
  return (
 | 
			
		||||
    <section
 | 
			
		||||
      id="howitworks"
 | 
			
		||||
      id="overview"
 | 
			
		||||
      aria-label="Features for investing all your money"
 | 
			
		||||
      className="bg-gray-900 py-20 sm:py-32"
 | 
			
		||||
    >
 | 
			
		||||
      <Container>
 | 
			
		||||
        <div className="mx-auto max-w-2xl lg:mx-0 lg:max-w-3xl">
 | 
			
		||||
          <Eyebrow color="accent">How It Works</Eyebrow>
 | 
			
		||||
        <div className="mx-auto max-w-2xl lg:mx-0 lg:max-w-none">
 | 
			
		||||
          <Eyebrow color="accent">Platform Overview</Eyebrow>
 | 
			
		||||
          <SectionHeader color="white" className="mt-2">
 | 
			
		||||
            How Mycelium Operates
 | 
			
		||||
            A Decentralized Cloud that Operates Itself
 | 
			
		||||
          </SectionHeader>
 | 
			
		||||
          <P color="light" className="mt-6">
 | 
			
		||||
            Mycelium, like its natural namesake, thrives on decentralization,
 | 
			
		||||
            efficiency, and security, making it a truly powerful force in the world
 | 
			
		||||
            of decentralized networks.
 | 
			
		||||
           Mycelium Cloud orchestrates Kubernetes clusters on the ThreeFold Grid with cryptographic certainty. Networking, storage, and orchestration are all built-in so developers can deploy critical workloads without wrestling infrastructure.
 | 
			
		||||
          </P>
 | 
			
		||||
        </div>
 | 
			
		||||
      </Container>
 | 
			
		||||
      <div className="hidden md:mt-20 md:block">
 | 
			
		||||
          <CloudFeaturesDesktop />
 | 
			
		||||
        </div>
 | 
			
		||||
      <div className="mt-16 md:hidden">
 | 
			
		||||
        <FeaturesMobile />
 | 
			
		||||
        <CloudFeaturesMobile />
 | 
			
		||||
      </div>
 | 
			
		||||
      <Container className="hidden md:mt-20 md:block">
 | 
			
		||||
        <FeaturesDesktop />
 | 
			
		||||
      </Container>
 | 
			
		||||
    </section>
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,4 @@
 | 
			
		||||
import { AnimatedSection } from '../../components/AnimatedSection'
 | 
			
		||||
import { CloudHero } from './CloudHero'
 | 
			
		||||
import { CloudOverview } from './CloudOverview'
 | 
			
		||||
import { CloudArchitecture } from './CloudArchitecture'
 | 
			
		||||
import { CloudFeatures } from './CloudFeatures'
 | 
			
		||||
@@ -17,14 +16,13 @@ export default function CloudPage() {
 | 
			
		||||
        <CloudHeroNew />
 | 
			
		||||
      </AnimatedSection>
 | 
			
		||||
      <AnimatedSection>
 | 
			
		||||
        <CloudOverview />
 | 
			
		||||
        <CloudFeatures />
 | 
			
		||||
      </AnimatedSection>
 | 
			
		||||
      
 | 
			
		||||
      <AnimatedSection>
 | 
			
		||||
        <CloudArchitecture />
 | 
			
		||||
      </AnimatedSection>
 | 
			
		||||
      <AnimatedSection>
 | 
			
		||||
        <CloudFeatures />
 | 
			
		||||
      </AnimatedSection>
 | 
			
		||||
 | 
			
		||||
      <AnimatedSection>
 | 
			
		||||
        <CloudGettingStarted />
 | 
			
		||||
      </AnimatedSection>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user