diff --git a/apps/landing/src/app/Background.tsx b/apps/landing/src/app/Background.tsx deleted file mode 100644 index 5a679a278..000000000 --- a/apps/landing/src/app/Background.tsx +++ /dev/null @@ -1,70 +0,0 @@ -'use client'; - -import dynamic from 'next/dynamic'; -import { ReactNode, Suspense, useEffect, useState } from 'react'; -import { hasWebGLContext } from '~/utils/util'; - -const FADE = { - start: 300, // start fading out at 100px - end: 1300 // end fading out at 300px -}; - -const Space = dynamic(() => import('~/components/Space'), { ssr: false }); -const Bubbles = dynamic(() => import('~/components/Bubbles').then((m) => m.Bubbles), { - ssr: false -}); - -export function Background() { - const [opacity, setOpacity] = useState(0.6); - const [isWindowResizing, setIsWindowResizing] = useState(false); - const [canUseWebGL, setCanUseWebGL] = useState(hasWebGLContext()); - const [inner, setInner] = useState(null); - - useEffect(() => { - const handleScroll = () => { - const currentScrollY = window.scrollY; - - if (currentScrollY <= FADE.start) { - setOpacity(0.6); - } else if (currentScrollY <= FADE.end) { - const range = FADE.end - FADE.start; - const diff = currentScrollY - FADE.start; - const ratio = diff / range; - setOpacity(0.6 - ratio); - } else { - setOpacity(0); - } - }; - window.addEventListener('scroll', handleScroll); - - return () => { - window.removeEventListener('scroll', handleScroll); - }; - }, []); - - useEffect(() => { - let resizeTimer: ReturnType; - const handleResize = () => { - setIsWindowResizing(true); - clearTimeout(resizeTimer); - resizeTimer = setTimeout(() => { - setIsWindowResizing(false); - }, 100); - }; - window.addEventListener('resize', handleResize); - return () => { - window.removeEventListener('resize', handleResize); - clearTimeout(resizeTimer); - }; - }, []); - - useEffect(() => { - setInner(canUseWebGL ? setCanUseWebGL(false)} /> : ); - }, [canUseWebGL]); - - return ( -
- {!isWindowResizing && inner} -
- ); -} diff --git a/apps/landing/src/app/Footer.tsx b/apps/landing/src/app/Footer.tsx deleted file mode 100644 index b9d01d6e1..000000000 --- a/apps/landing/src/app/Footer.tsx +++ /dev/null @@ -1,171 +0,0 @@ -'use client'; - -import { - Discord, - Github, - Instagram, - Opencollective, - Twitch, - Twitter -} from '@sd/assets/svgs/brands'; -import Image from 'next/image'; -import Link from 'next/link'; -import { PropsWithChildren } from 'react'; -import companyLogoFull from '~/assets/company_full_logo.svg?url'; - -import { getLatestRelease } from './docs/changelog/data'; -import { DownloadButton } from './Downloads/Button'; -import { useCurrentPlatform } from './Downloads/Platform'; - -export function Footer() { - const currentPlatform = useCurrentPlatform(); - - return ( - <> - {/* Download Button */} -
-
- -
-
- - - ); -} - -function FooterLink({ - blank, - link, - ...props -}: PropsWithChildren<{ link: string; blank?: boolean }>) { - return ( - - {props.children} - - ); -} diff --git a/apps/landing/src/app/blog/[slug]/page.tsx b/apps/landing/src/app/blog/[slug]/page.tsx index d7fa954b4..a1683b416 100644 --- a/apps/landing/src/app/blog/[slug]/page.tsx +++ b/apps/landing/src/app/blog/[slug]/page.tsx @@ -4,7 +4,7 @@ import { Metadata } from 'next'; import { useMDXComponent } from 'next-contentlayer/hooks'; import Image from 'next/image'; import { notFound } from 'next/navigation'; -import { BlogTag } from '~/components/BlogTag'; +import { BlogTag } from '~/components/blog-tag'; import { BlogMDXComponents } from '~/components/mdx'; export function generateStaticParams(): Array { diff --git a/apps/landing/src/app/blog/page.tsx b/apps/landing/src/app/blog/page.tsx index cb4c89eea..38c9c1458 100644 --- a/apps/landing/src/app/blog/page.tsx +++ b/apps/landing/src/app/blog/page.tsx @@ -2,7 +2,7 @@ import { allPosts } from '@contentlayer/generated'; import dayjs from 'dayjs'; import Image from 'next/image'; import Link from 'next/link'; -import { BlogTag } from '~/components/BlogTag'; +import { BlogTag } from '~/components/blog-tag'; export const metadata = { title: 'Spacedrive Blog', diff --git a/apps/landing/src/app/Providers.tsx b/apps/landing/src/app/client-providers.tsx similarity index 70% rename from apps/landing/src/app/Providers.tsx rename to apps/landing/src/app/client-providers.tsx index 93555f316..2bbe16249 100644 --- a/apps/landing/src/app/Providers.tsx +++ b/apps/landing/src/app/client-providers.tsx @@ -3,6 +3,6 @@ import { PropsWithChildren } from 'react'; import { TooltipProvider } from '@sd/ui'; -export function Providers({ children }: PropsWithChildren) { +export function ClientProviders({ children }: PropsWithChildren) { return {children}; } diff --git a/apps/landing/src/app/docs/Breadcrumbs.tsx b/apps/landing/src/app/docs/Breadcrumbs.tsx index e08a6998b..00e9e60f6 100644 --- a/apps/landing/src/app/docs/Breadcrumbs.tsx +++ b/apps/landing/src/app/docs/Breadcrumbs.tsx @@ -3,7 +3,7 @@ import { CaretRight } from '@phosphor-icons/react'; import { useParams } from 'next/navigation'; import { Fragment } from 'react'; -import { toTitleCase } from '~/utils/util'; +import { toTitleCase } from '~/utils/misc'; export function Breadcrumbs() { const { slug } = useParams<{ slug?: string[] }>(); diff --git a/apps/landing/src/app/docs/Sidebar/index.tsx b/apps/landing/src/app/docs/Sidebar/index.tsx index 9aea5d5fb..5869c1e7f 100644 --- a/apps/landing/src/app/docs/Sidebar/index.tsx +++ b/apps/landing/src/app/docs/Sidebar/index.tsx @@ -1,5 +1,5 @@ import { iconConfig } from '~/utils/contentlayer'; -import { toTitleCase } from '~/utils/util'; +import { toTitleCase } from '~/utils/misc'; import { getReleasesCategories } from '../changelog/data'; import { navigationMeta } from '../data'; diff --git a/apps/landing/src/app/docs/[...slug]/page.tsx b/apps/landing/src/app/docs/[...slug]/page.tsx index acc448e07..210ea4bfd 100644 --- a/apps/landing/src/app/docs/[...slug]/page.tsx +++ b/apps/landing/src/app/docs/[...slug]/page.tsx @@ -6,7 +6,7 @@ import { getMDXComponent } from 'next-contentlayer/hooks'; import Link from 'next/link'; import { notFound } from 'next/navigation'; import { DocMDXComponents } from '~/components/mdx'; -import { toTitleCase } from '~/utils/util'; +import { toTitleCase } from '~/utils/misc'; import { getDoc } from '../data'; import { Markdown } from '../Markdown'; diff --git a/apps/landing/src/app/docs/changelog/[category]/[tag]/page.tsx b/apps/landing/src/app/docs/changelog/[category]/[tag]/page.tsx index eecdcc15c..e0bd2ecd9 100644 --- a/apps/landing/src/app/docs/changelog/[category]/[tag]/page.tsx +++ b/apps/landing/src/app/docs/changelog/[category]/[tag]/page.tsx @@ -3,7 +3,7 @@ import { getMDXComponent } from 'next-contentlayer/hooks'; import { notFound } from 'next/navigation'; import { getRelease, githubFetch } from '~/app/api/github'; import { DocMDXComponents } from '~/components/mdx'; -import { toTitleCase } from '~/utils/util'; +import { toTitleCase } from '~/utils/misc'; import { Markdown } from '../../../Markdown'; import { getReleasesCategories } from '../../data'; diff --git a/apps/landing/src/app/docs/changelog/data.ts b/apps/landing/src/app/docs/changelog/data.ts index b36b808c3..a7de94665 100644 --- a/apps/landing/src/app/docs/changelog/data.ts +++ b/apps/landing/src/app/docs/changelog/data.ts @@ -1,5 +1,5 @@ import { getRecentReleases, getReleaseFrontmatter, githubFetch } from '~/app/api/github'; -import { toTitleCase } from '~/utils/util'; +import { toTitleCase } from '~/utils/misc'; import { SectionMeta } from '../data'; diff --git a/apps/landing/src/app/fonts.ts b/apps/landing/src/app/fonts.ts index a899f6a93..638369520 100644 --- a/apps/landing/src/app/fonts.ts +++ b/apps/landing/src/app/fonts.ts @@ -1,7 +1,7 @@ import { IBM_Plex_Sans, Inter } from 'next/font/google'; export const plexSansFont = IBM_Plex_Sans({ - weight: ['400', '600', '700'], + weight: ['300', '400', '600', '700'], subsets: ['latin'], display: 'swap', variable: '--font-plex-sans' diff --git a/apps/landing/src/app/layout.tsx b/apps/landing/src/app/layout.tsx index 54ebc1fc6..d568d7d74 100644 --- a/apps/landing/src/app/layout.tsx +++ b/apps/landing/src/app/layout.tsx @@ -1,8 +1,7 @@ import type { Metadata, Viewport } from 'next'; -import { PropsWithChildren } from 'react'; - -import { Footer } from './Footer'; -import { NavBar } from './NavBar'; +import { PropsWithChildren, useRef } from 'react'; +import { GlobalFooter } from '~/components/global-footer'; +import { NavBar } from '~/components/global-nav-bar'; import '@sd/ui/style/style.scss'; import '~/styles/prism.css'; @@ -10,9 +9,10 @@ import '~/styles/style.scss'; import clsx from 'clsx'; import PlausibleProvider from 'next-plausible'; +import { DisclaimerBanner } from '~/components/disclaimer-banner'; +import { ClientProviders } from './client-providers'; import { interFont, plexSansFont } from './fonts'; -import { Providers } from './Providers'; export const metadata: Metadata = { metadataBase: new URL('https://spacedrive.com'), @@ -29,10 +29,11 @@ export const metadata: Metadata = { export const viewport: Viewport = { themeColor: [ - // embed color on discord, for instance - { color: '#E751ED', media: 'not screen' }, // background color in Safari - { color: '#0E0E12', media: 'screen' } + { color: '#0E0E12', media: 'screen' }, + // MUST BE LAST to actually work on embeds + // embed color on discord, for instance + { color: '#E751ED', media: 'not screen' } ] }; @@ -51,17 +52,14 @@ export default function Layout({ children }: PropsWithChildren) { /> -
- The content of this site is not final and should not be considered official - marketing or advertising from Spacedrive Technology Inc. -
- + +
{children}
-
+
-
+ ); diff --git a/apps/landing/src/app/logo.png b/apps/landing/src/app/logo.png deleted file mode 100644 index a10fffd52..000000000 Binary files a/apps/landing/src/app/logo.png and /dev/null differ diff --git a/apps/landing/src/app/not-found.tsx b/apps/landing/src/app/not-found.tsx index 8558a7f5d..9e26e4341 100644 --- a/apps/landing/src/app/not-found.tsx +++ b/apps/landing/src/app/not-found.tsx @@ -3,7 +3,7 @@ import { SmileyXEyes } from '@phosphor-icons/react'; import { useRouter } from 'next/navigation'; import { Button } from '@sd/ui'; -import Markdown from '~/components/Markdown'; +import { MarkdownPage } from '~/components/markdown-page'; export const metadata = { title: 'Not Found - Spacedrive' @@ -13,7 +13,7 @@ export default function NotFound() { const router = useRouter(); return ( - +
@@ -35,6 +35,6 @@ export default function NotFound() {
- + ); } diff --git a/apps/landing/src/app/page.tsx b/apps/landing/src/app/page.tsx index f5d86a63f..477f30360 100644 --- a/apps/landing/src/app/page.tsx +++ b/apps/landing/src/app/page.tsx @@ -1,14 +1,12 @@ -import { ArrowUp } from '@phosphor-icons/react/dist/ssr'; import { Github } from '@sd/assets/svgs/brands'; import Image from 'next/image'; -import { BentoBox } from '~/components/BentoBox'; -import CyclingImage from '~/components/CyclingImage'; -import { toTitleCase } from '~/utils/util'; +import { BentoBox } from '~/components/bento-box'; +import { CTAButtons } from '~/components/cta-buttons'; +import CyclingImage from '~/components/cycling-image'; +import { GoldenBadge } from '~/components/golden-badge'; +import { toTitleCase } from '~/utils/misc'; import { getLatestRelease, getReleaseFrontmatter, githubFetch } from './api/github'; -import { Background } from './Background'; -import { Banner } from './Banner'; -import { Downloads } from './Downloads'; export const metadata = { title: 'Spacedrive — A file manager from the future.', @@ -46,7 +44,7 @@ export default async function Page() { className="mt-[50px] lg:mt-0" href={`/docs/changelog/alpha/${release.tag_name}`} /> */} - - {/* */} {/* */} - {/* */} {/* */} {/*
*/}
diff --git a/apps/landing/src/app/team/page.tsx b/apps/landing/src/app/team/page.tsx index 676ccc2e1..eb6ddafbb 100644 --- a/apps/landing/src/app/team/page.tsx +++ b/apps/landing/src/app/team/page.tsx @@ -1,6 +1,6 @@ import { ArrowRight } from '@phosphor-icons/react/dist/ssr'; import Link from 'next/link'; -import Markdown from '~/components/Markdown'; +import { MarkdownPage } from '~/components/markdown-page'; import { investors, teamMembers } from './people'; import { TeamMember } from './TeamMember'; @@ -12,7 +12,7 @@ export const metadata = { export default function Page() { return ( - +

@@ -71,6 +71,6 @@ export default function Page() {

-
+ ); } diff --git a/apps/landing/src/components/AccessData.tsx b/apps/landing/src/components/AccessData.tsx deleted file mode 100644 index d271dcf48..000000000 --- a/apps/landing/src/components/AccessData.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import Image from 'next/image'; -import React from 'react'; - -const AccessData = () => { - return ( -
- data globe -
-

- Access data from anywhere -

-

- users can enjoy the freedom of accessing their important files, documents, and - media assets from any device with an internet connection, ensuring productivity - and convenience on the go. -

-
-
- ); -}; - -export default AccessData; diff --git a/apps/landing/src/components/BentoBoxes.tsx b/apps/landing/src/components/BentoBoxes.tsx deleted file mode 100644 index 6c4feb987..000000000 --- a/apps/landing/src/components/BentoBoxes.tsx +++ /dev/null @@ -1,212 +0,0 @@ -import dynamic from 'next/dynamic'; -import Image from 'next/image'; -import Link from 'next/link'; -import { useMemo } from 'react'; -import { Button, tw } from '@sd/ui'; -import { useWindowSize } from '~/hooks/useWindowSize'; - -import { MagicCard, MagicContainer } from './MagicCard'; -import PlatformsArt from './PlatformsArt'; -import SpacedropArt from './SpacedropArt'; - -const Heading = tw.h1`z-30 text-center font-semibold leading-tight text-white text-lg`; -const Text = tw.p`leading-2 text-zinc-500 z-30 mb-8 mt-1 max-w-4xl text-center text-[14px] lg:leading-8"`; - -interface Props { - rowSpan?: number; - colSpan?: number; - className?: string; - bgUrl?: string; - children?: React.ReactNode; -} - -const BentoBox = ({ rowSpan = 1, colSpan = 1, className = '', children, bgUrl = '' }: Props) => ( -
- {children} -
-); - -// const AppFrameOuter = tw.div`relative m-auto flex w-full max-w-7xl rounded-lg border border-black transition-opacity`; -// const AppFrameInner = tw.div`z-30 flex w-full rounded-lg border-t border-app-line/50 bg-app/30 backdrop-blur`; - -const GitHubButton = dynamic(() => import('react-github-btn'), { ssr: false }); - -const BentoBoxes = () => { - const { width } = useWindowSize(); - const particleCount = useMemo(() => { - if (width) { - return width > 768 ? 50 : 25; - } - return 50; - }, [width]); - return ( - - -
-
- Encryption - - Your files and folders are fully encrypted through our algorithm, preventing - unauthorized access and guaranteed protection. - -
-
- Encryption -
- - -
- Powerful tags -
-
- -
- Powerful tags - - Create and apply tags to your files and folders, and instantly locate - desired content through filterable tags. - -
- - -
- Search everything - - Easily find your files and folders through our search - -
-
-
- Search -
- - -
-
- Library -
-
- Full Ownership & Control - Make Spacedrive yours -
- - -
- Spacedrop - - Send files to other devices quickly and easily - -
-
-
-
- -
-
- - -
- Free & Opensource - - Developers and users can contribute with new ideas and features - -
-
-
- - - - - Star - -
- - -
- -
-
-
- Cross platform - - Windows, macOS, Linux, iOS, Android, and the web. Spacedrive is everywhere. - -
-
- - - ); -}; - -export default BentoBoxes; diff --git a/apps/landing/src/components/CloudStorage.tsx b/apps/landing/src/components/CloudStorage.tsx deleted file mode 100644 index 95e0f74b8..000000000 --- a/apps/landing/src/components/CloudStorage.tsx +++ /dev/null @@ -1,96 +0,0 @@ -import clsx from 'clsx'; -import { useInView } from 'framer-motion'; -import Image from 'next/image'; -import React, { useRef } from 'react'; - -import CloudStorageArt from './CloudStorageArt'; - -const CloudStorage = () => { - const ref = useRef(null); - const isInView = useInView(ref, { - amount: 0.5, - once: true - }); - - return ( -
-
-
- -
- cloud gradient -
-
- - - -
- - -
-
-

- Coming soon -

-

- Combine all storage locations & clouds -

-
- ); -}; - -interface Props { - logoUrl: string; - title: string; - imageWidth?: number; - children?: React.ReactNode; -} - -const CloudCard = ({ logoUrl, title, imageWidth = 70, children }: Props) => { - return ( -
- {children} -
- cloud storage -

{title}

-
-
- ); -}; - -export default CloudStorage; diff --git a/apps/landing/src/components/CloudStorageArt.tsx b/apps/landing/src/components/CloudStorageArt.tsx deleted file mode 100644 index 870c53c30..000000000 --- a/apps/landing/src/components/CloudStorageArt.tsx +++ /dev/null @@ -1,126 +0,0 @@ -const CloudStorageArt = () => { - return ( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ); -}; - -export default CloudStorageArt; diff --git a/apps/landing/src/components/DotPattern.tsx b/apps/landing/src/components/DotPattern.tsx deleted file mode 100644 index 2a32471d4..000000000 --- a/apps/landing/src/components/DotPattern.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import { useId } from 'react'; - -import { cn } from './MagicCard'; - -interface DotPatternProps { - width?: any; - height?: any; - x?: any; - y?: any; - cx?: any; - cy?: any; - cr?: any; - className?: string; - [key: string]: any; -} -export function DotPattern({ - width = 16, - height = 16, - x = 0, - y = 0, - cx = 1, - cy = 1, - cr = 1, - className, - ...props -}: DotPatternProps) { - const id = useId(); - - return ( - - ); -} - -export default DotPattern; diff --git a/apps/landing/src/components/DownloadToday.tsx b/apps/landing/src/components/DownloadToday.tsx deleted file mode 100644 index f165da894..000000000 --- a/apps/landing/src/components/DownloadToday.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import { Download } from '@phosphor-icons/react/dist/ssr'; -import clsx from 'clsx'; -import { useInView } from 'framer-motion'; -import React, { useRef } from 'react'; -import { Button } from '@sd/ui'; - -interface Props { - isWindows?: boolean; -} - -const DownloadToday = ({ isWindows }: Props) => { - const ref = useRef(null); - const isInView = useInView(ref, { - amount: 0.5, - once: true - }); - return ( -
-
-

- Ready to get organized? -

- -
-
- ); -}; - -export default DownloadToday; diff --git a/apps/landing/src/components/HomeCTA.tsx b/apps/landing/src/components/HomeCTA.tsx deleted file mode 100644 index a9164daa7..000000000 --- a/apps/landing/src/components/HomeCTA.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { type IconProps } from '@phosphor-icons/react'; -import clsx from 'clsx'; -import { Button, LinkButtonProps } from '@sd/ui'; - -interface Props extends LinkButtonProps { - className?: string; - text: string; - icon?: IconProps; - onClick?: () => void; -} - -export function HomeCTA({ className, text, icon, ...props }: Props) { - return ( - - ); -} - -export default HomeCTA; diff --git a/apps/landing/src/components/MagicCard.tsx b/apps/landing/src/components/MagicCard.tsx deleted file mode 100644 index 7212a1504..000000000 --- a/apps/landing/src/components/MagicCard.tsx +++ /dev/null @@ -1,246 +0,0 @@ -'use client'; - -import clsx, { ClassValue } from 'clsx'; -import { CSSProperties, ReactNode, useCallback, useEffect, useRef, useState } from 'react'; -import { twMerge } from 'tailwind-merge'; - -export function cn(...inputs: ClassValue[]) { - return twMerge(clsx(inputs)); -} - -interface MousePosition { - x: number; - y: number; -} - -function useMousePosition(): MousePosition { - const [mousePosition, setMousePosition] = useState({ - x: 0, - y: 0 - }); - - useEffect(() => { - const handleMouseMove = (event: globalThis.MouseEvent) => { - setMousePosition({ x: event.clientX, y: event.clientY }); - }; - - window.addEventListener('mousemove', handleMouseMove); - - return () => { - window.removeEventListener('mousemove', handleMouseMove); - }; - }, []); - - return mousePosition; -} - -interface MagicContainerProps { - children?: ReactNode; - className?: any; - style?: CSSProperties; -} - -const MagicContainer = ({ children, className, style }: MagicContainerProps) => { - const containerRef = useRef(null); - const mousePosition = useMousePosition(); - const mouse = useRef<{ x: number; y: number }>({ x: 0, y: 0 }); - const containerSize = useRef<{ w: number; h: number }>({ w: 0, h: 0 }); - const [boxes, setBoxes] = useState>([]); - - const init = useCallback(() => { - if (containerRef.current) { - containerSize.current.w = containerRef.current.offsetWidth; - containerSize.current.h = containerRef.current.offsetHeight; - } - }, []); - - const onMouseMove = useCallback(() => { - if (containerRef.current) { - const rect = containerRef.current.getBoundingClientRect(); - const { w, h } = containerSize.current; - const x = mousePosition.x - rect.left; - const y = mousePosition.y - rect.top; - const inside = x < w && x > 0 && y < h && y > 0; - - mouse.current.x = x; - mouse.current.y = y; - boxes.forEach((box) => { - const boxX = -(box.getBoundingClientRect().left - rect.left) + mouse.current.x; - const boxY = -(box.getBoundingClientRect().top - rect.top) + mouse.current.y; - box.style.setProperty('--mouse-x', `${boxX}px`); - box.style.setProperty('--mouse-y', `${boxY}px`); - - if (inside) { - box.style.setProperty('--opacity', `1`); - } else { - box.style.setProperty('--opacity', `0`); - } - }); - } - }, [boxes, mousePosition]); - - useEffect(() => { - init(); - containerRef.current && - setBoxes(Array.from(containerRef.current.children).map((el) => el as HTMLElement)); - }, [init]); - - useEffect(() => { - init(); - window.addEventListener('resize', init); - - return () => { - window.removeEventListener('resize', init); - }; - }, [setBoxes, init]); - - useEffect(() => { - onMouseMove(); - }, [mousePosition, onMouseMove]); - - return ( -
- {children} -
- ); -}; - -interface MagicCardProps { - /** - * @default div - * @type React.ElementType - * @description - * The component to render the card as - * */ - as?: React.ElementType; - /** - * @default "" - * @type string - * @description - * The className of the card - */ - className?: string; - - /** - * @default "" - * @type ReactNode - * @description - * The children of the card - * */ - children?: ReactNode; - - /** - * @default 600 - * @type number - * @description - * The size of the spotlight effect in pixels - * */ - size?: number; - - /** - * ]@default "#475569" - * @type string - * @description - * The border color of the card - */ - borderColor?: string; - - /** - * @default 1 - * @type number - * @description - * The border width of the card - * */ - borderWidth?: number; - - /** - * @default 16 - * @type number - * @description - * The border radius of the card - * */ - borderRadius?: number; - - /** - * @default true - * @type boolean - * @description - * Whether to show the spotlight - * */ - spotlight?: boolean; - - /** - * @default "rgba(255,255,255,0.03)" - * @type string - * @description - * The color of the spotlight - * */ - spotlightColor?: string; - - /** - * @default true - * @type boolean - * @description - * Whether to isolate the card which is being hovered - * */ - isolated?: boolean; - - /** - * @default "transparent" - * @type string - * @description - * The background of the card - * */ - background?: string; -} - -const MagicCard = ({ - as: Component = 'div', - className, - children, - size = 600, - borderColor = 'rgba(86,114,157, 0.2)', - borderWidth = 1, - borderRadius = 10, - spotlight = true, - spotlightColor = 'rgba(86,114,157, 0.01)', - isolated = false, - background = 'rgba(255,255,255,0.03)' -}: MagicCardProps) => { - const spotlightStyles = - 'before:pointer-events-none before:absolute before:w-full before:h-full before:rounded-[var(--border-radius)] before:top-0 before:left-0 before:duration-500 before:transition-opacity before:bg-[radial-gradient(var(--mask-size)_circle_at_var(--mouse-x)_var(--mouse-y),var(--spotlight-color),transparent_40%)] before:z-[3] before:blur-xs'; - - const borderStyles = - 'after:pointer-events-none after:absolute after:w-full after:h-full after:rounded-[var(--border-radius)] after:top-0 after:left-0 after:duration-500 after:transition-opacity after:bg-[radial-gradient(var(--mask-size)_circle_at_var(--mouse-x)_var(--mouse-y),var(--border-color),transparent_40%)] after:z-[1]'; - return ( - -
- {children} -
-
- ); -}; - -export { MagicCard, MagicContainer }; diff --git a/apps/landing/src/components/NavBar.tsx b/apps/landing/src/components/NavBar.tsx deleted file mode 100644 index d220b7d48..000000000 --- a/apps/landing/src/components/NavBar.tsx +++ /dev/null @@ -1,166 +0,0 @@ -import { Book, Chat, DotsThreeVertical, MapPin, User } from '@phosphor-icons/react/dist/ssr'; -import { Academia, Discord, Github } from '@sd/assets/svgs/brands'; -import clsx from 'clsx'; -import Image from 'next/image'; -import Link from 'next/link'; -import { NextRouter, useRouter } from 'next/router'; -import { PropsWithChildren, useEffect, useState } from 'react'; -import { Button, Dropdown } from '@sd/ui'; -import { positions } from '~/app/careers/data'; -import { getWindow } from '~/utils/util'; - -import Logo from '../../public/logo.png'; - -function NavLink(props: PropsWithChildren<{ link?: string }>) { - return ( - - {props.children} - - ); -} - -function link(path: string, router: NextRouter) { - const selected = getWindow()?.location.href.includes(path); - - return { - selected, - onClick: () => router.push(path), - className: clsx(selected && 'bg-accent/20') - }; -} - -function redirect(href: string) { - return () => (window.location.href = href); -} - -export default function NavBar() { - const [isAtTop, setIsAtTop] = useState(true); - const window = getWindow(); - - function onScroll() { - if ((getWindow()?.pageYOffset || 0) < 20) setIsAtTop(true); - else if (isAtTop) setIsAtTop(false); - } - - const router = useRouter(); - - useEffect(() => { - if (!window) return; - setTimeout(onScroll, 0); - getWindow()?.addEventListener('scroll', onScroll); - return () => getWindow()?.removeEventListener('scroll', onScroll); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - return ( -
-
- - Spacedrive logo -

Spacedrive

- - -
- Roadmap - Team - {/* Pricing */} - Blog - Docs -
- Careers - {positions.length > 0 ? ( - - {` ${positions.length} `} - - ) : null} -
-
-
- - - - } - className="right-4 top-2 block h-6 w-44 text-white lg:hidden" - itemsClassName="!rounded-2xl shadow-2xl shadow-black p-2 !bg-gray-850 mt-2 !border-gray-500 text-[15px]" - > - - - Join Discord - - - Repository - - - - - Roadmap - - - Team - - {/* - Pricing - */} - - Blog - - - Docs - - - Careers - {positions.length > 0 ? ( - - {positions.length} - - ) : null} - - - - -
- - - - - - -
-
-
-
-
-
-
- ); -} diff --git a/apps/landing/src/components/NewBanner.tsx b/apps/landing/src/components/NewBanner.tsx deleted file mode 100644 index e7aa06f62..000000000 --- a/apps/landing/src/components/NewBanner.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import { Newspaper } from '@phosphor-icons/react/dist/ssr'; -import clsx from 'clsx'; -import Link from 'next/link'; - -export interface NewBannerProps { - headline: string; - href: string; - link: string; - className?: string; -} - -const NewBanner: React.FC = (props) => { - const { headline, href, link } = props; - - return ( - - ); -}; - -export default NewBanner; diff --git a/apps/landing/src/components/PlatformsArt.tsx b/apps/landing/src/components/PlatformsArt.tsx deleted file mode 100644 index 62b1099dd..000000000 --- a/apps/landing/src/components/PlatformsArt.tsx +++ /dev/null @@ -1,1624 +0,0 @@ -import React from 'react'; - -const PlatformsArt = () => { - return ( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ); -}; - -export default PlatformsArt; diff --git a/apps/landing/src/components/Space.tsx b/apps/landing/src/components/Space.tsx deleted file mode 100644 index 66af31578..000000000 --- a/apps/landing/src/components/Space.tsx +++ /dev/null @@ -1,96 +0,0 @@ -'use client'; - -import { PointMaterial, Points, Trail } from '@react-three/drei'; -import { Canvas, useFrame } from '@react-three/fiber'; -import { inSphere as randomInSphere } from 'maath/random'; -import { useRef, useState } from 'react'; -import { Color, WebGL1Renderer, WebGLRenderer, type Mesh } from 'three'; - -const Stars = (props: any) => { - const ref = useRef(); - const [sphere] = useState(() => randomInSphere(new Float32Array(35000), { radius: 1 })); - - useFrame((_, delta) => { - if (ref.current) { - ref.current.rotation.x -= delta / 300; - ref.current.rotation.y -= delta / 300; - } - }); - - return ( - - - - - - ); -}; - -function ShootingStar() { - const ref = useRef(); - - useFrame((state) => { - const t = state.clock.getElapsedTime() * 0.5; - if (ref.current) { - ref.current.position.set( - Math.sin(t) * 4, - Math.atan(t) * Math.cos(t / 2) * 2, - Math.cos(t) * 4 - ); - } - }); - - return ( - t * t}> - - - - - - ); -} - -export default function Space({ onRenderFail }: { onRenderFail?: (error: unknown) => void }) { - return ( -
- { - try { - // https://github.com/pmndrs/react-three-fiber/blob/f2b430c/packages/fiber/src/core/index.tsx#L113-L119 - return new WebGLRenderer({ - alpha: true, - canvas: canvas, - antialias: true, - powerPreference: 'high-performance' - }); - } catch (error) { - try { - // Let's try WebGL1, maybe the user's browser doesn't support WebGL2 - return new WebGL1Renderer({ - alpha: true, - canvas: canvas, - antialias: true, - powerPreference: 'high-performance' - }); - } catch (error) { - onRenderFail?.(error); - // Return an empty renderer, just so the app doesn't crash - return { render() {}, setSize() {}, setPixelRatio() {} }; - } - } - }} - camera={{ position: [0, 0, 0] }} - > - - - - -
- ); -} diff --git a/apps/landing/src/components/WormHole.tsx b/apps/landing/src/components/WormHole.tsx deleted file mode 100644 index b4f78dc4a..000000000 --- a/apps/landing/src/components/WormHole.tsx +++ /dev/null @@ -1,152 +0,0 @@ -'use client'; - -import clsx from 'clsx'; -import Image from 'next/image'; -import React from 'react'; - -const WormHole = () => { - return ( -
-
-
- heart -
-
- game -
-
- image -
-
- lock -
-
- video -
-
- application -
-
- collection -
-
- node -
-
- texturedmesh -
-
- database -
-
- package -
- wormhole -
-
-

- Heading -

-

- Lorem ipsum dolor sit amet consectetur adipisicing elit. Nam, iure ea dolores - atque unde fugit ad libero debitis nemo quis culpa sequi illum aliquam iusto - harum quo laborum ducimus voluptas Lorem, ipsum dolor sit amet consectetur - adipisicing elit. Similique eos, voluptatum, ipsam facilis placeat tempore - consequuntur officia distinctio voluptate blanditiis tenetur, animi ut ea - laboriosam laborum culpa autem accusantium reprehenderit! -

-
-
- ); -}; - -export default WormHole; diff --git a/apps/landing/src/components/BentoBox.tsx b/apps/landing/src/components/bento-box.tsx similarity index 100% rename from apps/landing/src/components/BentoBox.tsx rename to apps/landing/src/components/bento-box.tsx diff --git a/apps/landing/src/components/BlogTag.tsx b/apps/landing/src/components/blog-tag.tsx similarity index 100% rename from apps/landing/src/components/BlogTag.tsx rename to apps/landing/src/components/blog-tag.tsx diff --git a/apps/landing/src/app/Downloads/Button.tsx b/apps/landing/src/components/cta-buttons/Button.tsx similarity index 100% rename from apps/landing/src/app/Downloads/Button.tsx rename to apps/landing/src/components/cta-buttons/Button.tsx diff --git a/apps/landing/src/app/Downloads/DockerDialog.tsx b/apps/landing/src/components/cta-buttons/DockerDialog.tsx similarity index 100% rename from apps/landing/src/app/Downloads/DockerDialog.tsx rename to apps/landing/src/components/cta-buttons/DockerDialog.tsx diff --git a/apps/landing/src/app/Downloads/Platform.tsx b/apps/landing/src/components/cta-buttons/Platform.tsx similarity index 100% rename from apps/landing/src/app/Downloads/Platform.tsx rename to apps/landing/src/components/cta-buttons/Platform.tsx diff --git a/apps/landing/src/app/Downloads/index.tsx b/apps/landing/src/components/cta-buttons/index.tsx similarity index 97% rename from apps/landing/src/app/Downloads/index.tsx rename to apps/landing/src/components/cta-buttons/index.tsx index 695d9e73e..435b00021 100644 --- a/apps/landing/src/app/Downloads/index.tsx +++ b/apps/landing/src/components/cta-buttons/index.tsx @@ -6,8 +6,8 @@ import clsx from 'clsx'; import { motion } from 'framer-motion'; import { usePlausible } from 'next-plausible'; import { useState } from 'react'; +import DiscordButton from '~/components/discord-button'; -import DiscordButton from '../DiscordButton'; import { DownloadButton } from './Button'; import { DockerDialog } from './DockerDialog'; import { BASE_DL_LINK, Platform, platforms, useCurrentPlatform } from './Platform'; @@ -16,7 +16,7 @@ interface Props { latestVersion: string; } -export function Downloads({ latestVersion }: Props) { +export function CTAButtons({ latestVersion }: Props) { const [selectedPlatform, setSelectedPlatform] = useState(null); const currentPlatform = useCurrentPlatform(); diff --git a/apps/landing/src/components/CyclingImage.tsx b/apps/landing/src/components/cycling-image.tsx similarity index 100% rename from apps/landing/src/components/CyclingImage.tsx rename to apps/landing/src/components/cycling-image.tsx diff --git a/apps/landing/src/components/disclaimer-banner.tsx b/apps/landing/src/components/disclaimer-banner.tsx new file mode 100644 index 000000000..7c3bfa35d --- /dev/null +++ b/apps/landing/src/components/disclaimer-banner.tsx @@ -0,0 +1,22 @@ +'use client'; + +import { useEffect, useRef } from 'react'; + +export const DisclaimerBanner = () => { + const disclaimerBannerRef = useRef(null); + + return ( +
{ + disclaimerBannerRef.current && + (disclaimerBannerRef.current.style.visibility = 'hidden'); + }} + > + The content of this site is not final and should not be considered official marketing or + advertising from Spacedrive Technology Inc. +
+ ); +}; diff --git a/apps/landing/src/app/DiscordButton.tsx b/apps/landing/src/components/discord-button.tsx similarity index 100% rename from apps/landing/src/app/DiscordButton.tsx rename to apps/landing/src/components/discord-button.tsx diff --git a/apps/landing/src/components/global-footer.tsx b/apps/landing/src/components/global-footer.tsx new file mode 100644 index 000000000..02ee4ff72 --- /dev/null +++ b/apps/landing/src/components/global-footer.tsx @@ -0,0 +1,212 @@ +'use client'; + +import Image from 'next/image'; +import Link from 'next/link'; +import { PropsWithChildren } from 'react'; +import companyLogoFull from '~/assets/company_full_logo.svg?url'; +import { DownloadButton } from '~/components/cta-buttons/Button'; +import { useCurrentPlatform } from '~/components/cta-buttons/Platform'; + +export function GlobalFooter() { + const currentPlatform = useCurrentPlatform(); + + return ( + <> + {/* Download Button */} +
+
+ +
+
+ + + ); +} + +function FooterLink({ + blank, + link, + ...props +}: PropsWithChildren<{ link: string; blank?: boolean }>) { + return ( + + {props.children} + + ); +} diff --git a/apps/landing/src/app/NavBar/index.tsx b/apps/landing/src/components/global-nav-bar/index.tsx similarity index 97% rename from apps/landing/src/app/NavBar/index.tsx rename to apps/landing/src/components/global-nav-bar/index.tsx index 1b5d0bb3c..49cf45460 100644 --- a/apps/landing/src/app/NavBar/index.tsx +++ b/apps/landing/src/components/global-nav-bar/index.tsx @@ -6,9 +6,8 @@ import Image from 'next/image'; import Link from 'next/link'; import { PropsWithChildren, useState } from 'react'; import appFullLogo from '~/assets/app_full_logo.svg?url'; - -import { DownloadButton } from '../Downloads/Button'; -import { useCurrentPlatform } from '../Downloads/Platform'; +import { DownloadButton } from '~/components/cta-buttons/Button'; +import { useCurrentPlatform } from '~/components/cta-buttons/Platform'; import '~/styles/navbar.css'; diff --git a/apps/landing/src/app/NavBar/MobileDropdown.tsx b/apps/landing/src/components/global-nav-bar/mobile-dropdown.tsx similarity index 96% rename from apps/landing/src/app/NavBar/MobileDropdown.tsx rename to apps/landing/src/components/global-nav-bar/mobile-dropdown.tsx index 850ffdaa3..06883f914 100644 --- a/apps/landing/src/app/NavBar/MobileDropdown.tsx +++ b/apps/landing/src/components/global-nav-bar/mobile-dropdown.tsx @@ -6,9 +6,8 @@ import clsx from 'clsx'; import { AppRouterInstance } from 'next/dist/shared/lib/app-router-context.shared-runtime'; import { usePathname, useRouter } from 'next/navigation'; import { Button, Dropdown } from '@sd/ui'; -import { getWindow } from '~/utils/util'; -import { positions } from '../careers/data'; +import { positions } from '../../app/careers/data'; export function MobileDropdown() { const router = useRouter(); diff --git a/apps/landing/src/app/Banner.tsx b/apps/landing/src/components/golden-badge.tsx similarity index 94% rename from apps/landing/src/app/Banner.tsx rename to apps/landing/src/components/golden-badge.tsx index e14cbcc45..acef9aab3 100644 --- a/apps/landing/src/app/Banner.tsx +++ b/apps/landing/src/components/golden-badge.tsx @@ -2,14 +2,14 @@ import { Star } from '@phosphor-icons/react/dist/ssr'; import clsx from 'clsx'; import Link from 'next/link'; -export interface BannerProps { +export interface GoldenBadgeProps { headline: string; href?: string; link?: string; className?: string; } -export function Banner(props: BannerProps) { +export function GoldenBadge(props: GoldenBadgeProps) { const { headline, href, link } = props; return ( diff --git a/apps/landing/src/components/Markdown.tsx b/apps/landing/src/components/markdown-page.tsx similarity index 89% rename from apps/landing/src/components/Markdown.tsx rename to apps/landing/src/components/markdown-page.tsx index 1f461a386..7e4014f4b 100644 --- a/apps/landing/src/components/Markdown.tsx +++ b/apps/landing/src/components/markdown-page.tsx @@ -6,7 +6,7 @@ interface MarkdownPageProps { articleClassNames?: string; } -function MarkdownPage(props: PropsWithChildren) { +export function MarkdownPage(props: PropsWithChildren) { return (
) {
); } - -export default MarkdownPage; diff --git a/apps/landing/src/components/mdx/index.tsx b/apps/landing/src/components/mdx/index.tsx index 1aae55998..75bb04e04 100644 --- a/apps/landing/src/components/mdx/index.tsx +++ b/apps/landing/src/components/mdx/index.tsx @@ -2,9 +2,9 @@ import { MDXComponents } from 'mdx/types'; import NextImage, { ImageProps } from 'next/image'; import { env } from '~/env'; -import Notice from './Notice'; -import Pre from './Pre'; -import Video from './Video'; +import Notice from './notice'; +import Pre from './pre'; +import Video from './video'; const Image = (props: ImageProps) => (