feat: revamp homepage

This commit is contained in:
Faisal Amir 2024-03-12 19:40:00 +07:00
parent 6c81d83d30
commit 4470d3ac85
8 changed files with 256 additions and 270 deletions

View File

@ -1,32 +1,38 @@
import React from "react"; import React from 'react'
import { useAppStars } from "@site/src/hooks/useAppStars"; import { useAppStars } from '@site/src/hooks/useAppStars'
import { useAppRelease } from "@site/src/hooks/useAppRelease"; import { useAppRelease } from '@site/src/hooks/useAppRelease'
import { AiOutlineGithub, AiOutlineTwitter } from "react-icons/ai"; import { AiOutlineGithub, AiOutlineTwitter } from 'react-icons/ai'
import { BiLogoDiscordAlt } from "react-icons/bi"; import { BiLogoDiscordAlt } from 'react-icons/bi'
const socials = [ const socials = [
{ {
icon: <AiOutlineTwitter className="text-xl text-white" />, icon: <AiOutlineTwitter className="text-xl text-white" />,
href: "https://twitter.com/janframework", href: 'https://twitter.com/janframework',
}, },
{ {
icon: <BiLogoDiscordAlt className="text-xl text-white" />, icon: <BiLogoDiscordAlt className="text-xl text-white" />,
href: "https://discord.com/invite/FTk2MvZwJH", href: 'https://discord.com/invite/FTk2MvZwJH',
}, },
{ {
icon: <AiOutlineGithub className="text-lg text-white" />, icon: <AiOutlineGithub className="text-lg text-white" />,
href: "https://github.com/janhq/jan", href: 'https://github.com/janhq/jan',
}, },
]; ]
export default function AnnoncementBanner() { export default function AnnoncementBanner() {
const { stargazers } = useAppStars(); const { stargazers } = useAppStars()
const { release } = useAppRelease(); const { release } = useAppRelease()
return ( return (
<div className="h-10 w-full flex-shrink-0 bg-blue-600"> <div
className="h-10 w-full flex-shrink-0"
style={{
background:
'radial-gradient(58.83% 95.12% at 62.37% 97.91%, rgba(238, 203, 255, 0.59) 0%, rgba(255, 255, 255, 0.00) 100%), linear-gradient(249deg, rgba(67, 119, 233, 0.80) 79.81%, rgba(67, 119, 233, 0.80) 93.59%, rgba(194, 226, 255, 0.80) 110.85%)',
}}
>
<div className="px-4 lg:px-10 flex h-full items-center justify-between py-0.5"> <div className="px-4 lg:px-10 flex h-full items-center justify-between py-0.5">
<div className="flex h-6 items-center shadow-sm"> <div className="flex h-6 items-center shadow-sm">
<a <a
@ -75,10 +81,10 @@ export default function AnnoncementBanner() {
> >
{social.icon} {social.icon}
</a> </a>
); )
})} })}
</div> </div>
</div> </div>
</div> </div>
); )
} }

View File

@ -1,134 +1,134 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from 'react'
import { Fragment } from "react"; import { Fragment } from 'react'
import { Menu, Transition } from "@headlessui/react"; import { Menu, Transition } from '@headlessui/react'
import { ChevronDownIcon } from "@heroicons/react/20/solid"; import { ChevronDownIcon } from '@heroicons/react/20/solid'
import axios from "axios"; import axios from 'axios'
import { FaWindows, FaApple, FaLinux } from "react-icons/fa"; import { FaWindows, FaApple, FaLinux } from 'react-icons/fa'
const systemsTemplate = [ const systemsTemplate = [
{ {
name: "Download for Mac (M1/M2/M3)", name: 'Download for Mac (M1/M2/M3)',
logo: FaApple, logo: FaApple,
fileFormat: "{appname}-mac-arm64-{tag}.dmg", fileFormat: '{appname}-mac-arm64-{tag}.dmg',
}, },
{ {
name: "Download for Mac (Intel)", name: 'Download for Mac (Intel)',
logo: FaApple, logo: FaApple,
fileFormat: "{appname}-mac-x64-{tag}.dmg", fileFormat: '{appname}-mac-x64-{tag}.dmg',
}, },
{ {
name: "Download for Windows", name: 'Download for Windows',
logo: FaWindows, logo: FaWindows,
fileFormat: "{appname}-win-x64-{tag}.exe", fileFormat: '{appname}-win-x64-{tag}.exe',
}, },
{ {
name: "Download for Linux (AppImage)", name: 'Download for Linux (AppImage)',
logo: FaLinux, logo: FaLinux,
fileFormat: "{appname}-linux-x86_64-{tag}.AppImage", fileFormat: '{appname}-linux-x86_64-{tag}.AppImage',
}, },
{ {
name: "Download for Linux (deb)", name: 'Download for Linux (deb)',
logo: FaLinux, logo: FaLinux,
fileFormat: "{appname}-linux-amd64-{tag}.deb", fileFormat: '{appname}-linux-amd64-{tag}.deb',
} },
]; ]
function classNames(...classes) { function classNames(...classes) {
return classes.filter(Boolean).join(" "); return classes.filter(Boolean).join(' ')
} }
export default function Dropdown() { export default function Dropdown() {
const [systems, setSystems] = useState(systemsTemplate); const [systems, setSystems] = useState(systemsTemplate)
const [defaultSystem, setDefaultSystem] = useState(systems[0]); const [defaultSystem, setDefaultSystem] = useState(systems[0])
const getLatestReleaseInfo = async (repoOwner, repoName) => { const getLatestReleaseInfo = async (repoOwner, repoName) => {
const url = `https://api.github.com/repos/${repoOwner}/${repoName}/releases/latest`; const url = `https://api.github.com/repos/${repoOwner}/${repoName}/releases/latest`
try { try {
const response = await axios.get(url); const response = await axios.get(url)
return response.data; return response.data
} catch (error) { } catch (error) {
console.error(error); console.error(error)
return null; return null
} }
}; }
const extractAppName = (fileName) => { const extractAppName = (fileName) => {
// Extract appname using a regex that matches the provided file formats // Extract appname using a regex that matches the provided file formats
const regex = /^(.*?)-(?:mac|win|linux)-(?:arm64|x64|x86_64|amd64)-.*$/; const regex = /^(.*?)-(?:mac|win|linux)-(?:arm64|x64|x86_64|amd64)-.*$/
const match = fileName.match(regex); const match = fileName.match(regex)
return match ? match[1] : null; return match ? match[1] : null
}; }
const changeDefaultSystem = async (systems) => { const changeDefaultSystem = async (systems) => {
const userAgent = navigator.userAgent; const userAgent = navigator.userAgent
if (userAgent.includes("Windows")) { if (userAgent.includes('Windows')) {
// windows user // windows user
setDefaultSystem(systems[2]); setDefaultSystem(systems[2])
} else if (userAgent.includes("Linux")) { } else if (userAgent.includes('Linux')) {
// linux user // linux user
setDefaultSystem(systems[3]); setDefaultSystem(systems[3])
} else if (userAgent.includes("Mac OS")) { } else if (userAgent.includes('Mac OS')) {
setDefaultSystem(systems[0]); setDefaultSystem(systems[0])
} else { } else {
setDefaultSystem(systems[1]); setDefaultSystem(systems[1])
} }
}; }
useEffect(() => { useEffect(() => {
const updateDownloadLinks = async () => { const updateDownloadLinks = async () => {
try { try {
const releaseInfo = await getLatestReleaseInfo("janhq", "jan"); const releaseInfo = await getLatestReleaseInfo('janhq', 'jan')
// Extract appname from the first asset name // Extract appname from the first asset name
const firstAssetName = releaseInfo.assets[0].name; const firstAssetName = releaseInfo.assets[0].name
const appname = extractAppName(firstAssetName); const appname = extractAppName(firstAssetName)
if (!appname) { if (!appname) {
console.error( console.error(
"Failed to extract appname from file name:", 'Failed to extract appname from file name:',
firstAssetName firstAssetName
); )
changeDefaultSystem(systems); changeDefaultSystem(systems)
return; return
} }
// Remove 'v' at the start of the tag_name // Remove 'v' at the start of the tag_name
const tag = releaseInfo.tag_name.startsWith("v") const tag = releaseInfo.tag_name.startsWith('v')
? releaseInfo.tag_name.substring(1) ? releaseInfo.tag_name.substring(1)
: releaseInfo.tag_name; : releaseInfo.tag_name
const updatedSystems = systems.map((system) => { const updatedSystems = systems.map((system) => {
const downloadUrl = system.fileFormat const downloadUrl = system.fileFormat
.replace("{appname}", appname) .replace('{appname}', appname)
.replace("{tag}", tag); .replace('{tag}', tag)
return { return {
...system, ...system,
href: `https://github.com/janhq/jan/releases/download/${releaseInfo.tag_name}/${downloadUrl}`, href: `https://github.com/janhq/jan/releases/download/${releaseInfo.tag_name}/${downloadUrl}`,
}; }
}); })
setSystems(updatedSystems); setSystems(updatedSystems)
changeDefaultSystem(updatedSystems); changeDefaultSystem(updatedSystems)
} catch (error) { } catch (error) {
console.error("Failed to update download links:", error); console.error('Failed to update download links:', error)
} }
}; }
updateDownloadLinks(); updateDownloadLinks()
}, []); }, [])
return ( return (
<div className="inline-flex align-items-stretch"> <div className="inline-flex align-items-stretch">
<a <a
href={defaultSystem.href || ""} href={defaultSystem.href || ''}
className="cursor-pointer relative inline-flex items-center rounded-l-md border-0 px-4 py-3 text-base font-semibold dark:bg-white dark:text-black bg-black text-white dark:hover:text-black hover:text-white" className="cursor-pointer relative inline-flex items-center rounded-l-xl border-0 px-4 py-4 text-base font-semibold dark:bg-[#343435] dark:text-white bg-black text-white hover:text-white dark:border dark:border-[#B2B2B3]"
> >
<defaultSystem.logo className="h-5 mr-3 -mt-1" /> <defaultSystem.logo className="h-5 mr-3 -mt-1" />
{defaultSystem.name} {defaultSystem.name}
</a> </a>
<Menu as="div" className="relative -ml-px block"> <Menu as="div" className="relative -ml-px block">
<Menu.Button className="cursor-pointer relative inline-flex items-center rounded-r-md border-l border-gray-600 h-full dark:bg-white dark:text-black bg-black text-white dark:hover:text-black hover:text-white w-8 justify-center"> <Menu.Button className="cursor-pointer relative inline-flex items-center rounded-r-xl border-l border-gray-600 h-full dark:bg-[#343435] dark:text-white bg-black text-white hover:text-white w-8 justify-center dark:border dark:border-[#B2B2B3]">
<span className="sr-only">Open OS options</span> <span className="sr-only">Open OS options</span>
<ChevronDownIcon className="h-6 w-6" aria-hidden="true" /> <ChevronDownIcon className="h-6 w-6" aria-hidden="true" />
</Menu.Button> </Menu.Button>
@ -141,7 +141,7 @@ export default function Dropdown() {
leaveFrom="transform opacity-100 scale-100" leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95" leaveTo="transform opacity-0 scale-95"
> >
<Menu.Items className="absolute right-0 z-10 mt-1 w-80 text-left origin-top-right rounded-md dark:bg-white dark:text-black bg-black text-white dark:hover:text-black hover:text-white shadow-2xl ring-1 ring-black ring-opacity-5 focus:outline-none overflow-hidden"> <Menu.Items className="absolute right-0 z-10 mt-1 w-80 text-left origin-top-right rounded-xl dark:bg-[#343435] dark:text-white bg-black text-white hover:text-white shadow-2xl ring-1 ring-black ring-opacity-5 focus:outline-none overflow-hidden">
<div className="overflow-hidden"> <div className="overflow-hidden">
{systems.map((system) => ( {systems.map((system) => (
<Menu.Item <Menu.Item
@ -150,16 +150,16 @@ export default function Dropdown() {
> >
{({ active }) => ( {({ active }) => (
<a <a
href={system.href || ""} href={system.href || ''}
className={classNames( className={classNames(
active active
? "dark:bg-blue-100 bg-gray-900 hover:text-white dark:text-black" ? 'dark:bg-black/20 bg-gray-900 hover:text-white'
: "text-white dark:text-black", : 'text-white ',
"flex px-4 py-3 items-center text-white hover:text-white dark:text-black" 'flex px-4 py-3 items-center text-white hover:text-white'
)} )}
> >
<system.logo className="w-3 mr-3 -mt-1 flex-shrink-0" /> <system.logo className="w-3 mr-3 -mt-1 flex-shrink-0" />
<span className="text-white dark:text-black font-medium"> <span className="text-white font-medium">
{system.name} {system.name}
</span> </span>
</a> </a>
@ -171,5 +171,5 @@ export default function Dropdown() {
</Transition> </Transition>
</Menu> </Menu>
</div> </div>
); )
} }

View File

@ -1,31 +1,31 @@
import React from "react"; import React from 'react'
import DownloadApp from "@site/src/containers/DownloadApp"; import DownloadApp from '@site/src/containers/DownloadApp'
import useBaseUrl from "@docusaurus/useBaseUrl"; import useBaseUrl from '@docusaurus/useBaseUrl'
import Layout from "@theme/Layout"; import Layout from '@theme/Layout'
import Banner from "@site/src/containers/Banner"; import Banner from '@site/src/containers/Banner'
import ThemedImage from "@theme/ThemedImage"; import ThemedImage from '@theme/ThemedImage'
import SocialButton from "@site/src/containers/SocialButton"; import SocialButton from '@site/src/containers/SocialButton'
import { IoArrowDown } from "react-icons/io5"; import { IoArrowDown } from 'react-icons/io5'
import Dropdown from "@site/src/containers/Elements/dropdown"; import Dropdown from '@site/src/containers/Elements/dropdown'
import useIsBrowser from "@docusaurus/useIsBrowser"; import useIsBrowser from '@docusaurus/useIsBrowser'
export default function Home() { export default function Home() {
const isBrowser = useIsBrowser(); const isBrowser = useIsBrowser()
const handleAnchorLink = () => { const handleAnchorLink = () => {
document document
.getElementById("download-section") .getElementById('download-section')
.scrollIntoView({ behavior: "smooth" }); .scrollIntoView({ behavior: 'smooth' })
}; }
const userAgent = isBrowser && navigator.userAgent; const userAgent = isBrowser && navigator.userAgent
const isBrowserChrome = isBrowser && userAgent.includes("Chrome"); const isBrowserChrome = isBrowser && userAgent.includes('Chrome')
return ( return (
<> <>
@ -35,78 +35,37 @@ export default function Home() {
description="Jan runs 100% offline on your computer, utilizes open-source AI models, prioritizes privacy, and is highly customizable." description="Jan runs 100% offline on your computer, utilizes open-source AI models, prioritizes privacy, and is highly customizable."
> >
<main> <main>
<div className="grid grid-cols-1 lg:grid-cols-12 -mt-1 gap-8 items-center relative min-h-[calc(100vh-96px)] "> <div className="text-center py-24">
<div className="col-span-full lg:col-start-2 lg:col-span-5 text-left relative z-10 px-4 py-6"> <h1 className="text-5xl lg:text-8xl !font-normal leading-tight lg:leading-tight mt-2 font-serif">
<img Rethink the Computer
src="/img/homepage/element-hero-blur.webp" </h1>
alt="Element blur" <p className="text-2xl -mt-1 leading-relaxed text-zinc-500">
className="hidden lg:block absolute blur-3xl opacity-30 right-32 -bottom-32" Turn your computer into a{' '}
/> <span className="text-black dark:text-white font-semibold">
<div className="flex items-center space-x-2 mb-3"> AI machine
<img alt="Jan Logo" src="img/logo.svg" width={36} height={36} /> </span>
<span className="text-zinc-500 text-4xl font-medium"> </p>
Meet Jan <div className="mt-10">
</span> {!isBrowserChrome ? (
</div> <div
<h1 className="text-5xl lg:text-7xl font-semibold leading-tight lg:leading-tight mt-2"> onClick={() => handleAnchorLink()}
Bringing AI to <br /> your Desktop{" "} className="inline-flex px-4 py-3 rounded-lg text-lg font-semibold cursor-pointer justify-center items-center space-x-2 dark:bg-white dark:text-black bg-black text-white dark:hover:text-black hover:text-white scroll-smooth"
<span className="relative w-16 h-16 inline-block"> >
<img <span>Download Jan for PC</span>
src="/img/homepage/element-hero-heading.png"
alt="Element hero heading"
className="object-contain inline-block"
width={64}
height={64}
/>
</span>
</h1>
<p className="text-2xl mt-3 leading-relaxed text-zinc-500">
Open-source ChatGPT alternative that runs{" "}
<br className="hidden lg:block" /> 100% offline on your
computer.
</p>
<div className="mt-8"></div>
<div className="mt-8">
{!isBrowserChrome ? (
<div
onClick={() => handleAnchorLink()}
className="inline-flex px-4 py-3 rounded-lg text-lg font-semibold cursor-pointer justify-center items-center space-x-2 dark:bg-white dark:text-black bg-black text-white dark:hover:text-black hover:text-white scroll-smooth"
>
<span>Download Jan for PC</span>
</div>
) : (
<Dropdown />
)}
</div>
<div
onClick={() => handleAnchorLink()}
className="hidden lg:inline-block cursor-pointer"
>
<div className="mt-16 flex items-center space-x-2">
<p>Find out more</p>
<IoArrowDown size={24} className="animate-bounce-down" />
</div> </div>
</div> ) : (
</div> <Dropdown />
)}
<div className="col-span-full lg:col-span-6 h-full">
<div className="relative text-center h-full">
<ThemedImage
className="w-full object-cover mr-auto h-full"
alt="App screenshots"
sources={{
light: useBaseUrl(
"/img/homepage/app-base-screen-light.webp"
),
dark: useBaseUrl("/img/homepage/app-base-screen-dark.webp"),
}}
/>
</div>
</div> </div>
<p className="mt-6 text-zinc-500">
<span className="text-blue-500 font-bold dark:text-blue-500">
400K+
</span>{' '}
downloads | Free & Open Source
</p>
</div> </div>
<div {/* <div
className="dark:bg-[#09090B]/20 border-t border-zinc-200 dark:border-gray-800 py-10 lg:py-16" className="dark:bg-[#09090B]/20 border-t border-zinc-200 dark:border-gray-800 py-10 lg:py-16"
id="download-section" id="download-section"
> >
@ -115,9 +74,9 @@ export default function Home() {
<DownloadApp /> <DownloadApp />
</div> </div>
</div> </div>
</div> </div> */}
<div className="dark:bg-[#09090B]/20 pb-10 lg:pb-36"> {/* <div className="dark:bg-[#09090B]/20 pb-10 lg:pb-36">
<div className="container h-full "> <div className="container h-full ">
<div className="w-full lg:w-3/4 mx-auto relative rounded-xl py-10"> <div className="w-full lg:w-3/4 mx-auto relative rounded-xl py-10">
<img <img
@ -157,9 +116,9 @@ export default function Home() {
</div> </div>
</div> </div>
</div> </div>
</div> </div> */}
<div className="dark:bg-[#27272A] bg-zinc-100 pt-10 lg:pt-20 pb-10"> {/* <div className="dark:bg-[#27272A] bg-zinc-100 pt-10 lg:pt-20 pb-10">
<div className="container"> <div className="container">
<div className="w-full lg:w-3/4 mx-auto relative"> <div className="w-full lg:w-3/4 mx-auto relative">
<div className="grid grid-cols-1 lg:grid-cols-12 gap-8 items-center"> <div className="grid grid-cols-1 lg:grid-cols-12 gap-8 items-center">
@ -170,8 +129,8 @@ export default function Home() {
<p className="text-zinc-600 dark:text-zinc-400 mt-4 text-lg leading-relaxed"> <p className="text-zinc-600 dark:text-zinc-400 mt-4 text-lg leading-relaxed">
<b className="text-bold text-black dark:text-white"> <b className="text-bold text-black dark:text-white">
10x productivity 10x productivity
</b>{" "} </b>{' '}
with customizable AI <br className="hidden lg:block" />{" "} with customizable AI <br className="hidden lg:block" />{' '}
assistants, global hotkeys, and in-line AI. assistants, global hotkeys, and in-line AI.
</p> </p>
</div> </div>
@ -182,10 +141,10 @@ export default function Home() {
alt="App screenshots" alt="App screenshots"
sources={{ sources={{
light: useBaseUrl( light: useBaseUrl(
"/img/homepage/desktop-app-light.webp" '/img/homepage/desktop-app-light.webp'
), ),
dark: useBaseUrl( dark: useBaseUrl(
"/img/homepage/desktop-app-dark.webp" '/img/homepage/desktop-app-dark.webp'
), ),
}} }}
/> />
@ -194,9 +153,9 @@ export default function Home() {
</div> </div>
</div> </div>
</div> </div>
</div> </div> */}
<div className="dark:bg-[#27272A] bg-zinc-100 lg:pb-20 pb-10 pt-10"> {/* <div className="dark:bg-[#27272A] bg-zinc-100 lg:pb-20 pb-10 pt-10">
<div className="container"> <div className="container">
<div className="w-full lg:w-3/4 mx-auto relative "> <div className="w-full lg:w-3/4 mx-auto relative ">
<div className="grid grid-cols-1 lg:grid-cols-12 gap-8 items-center"> <div className="grid grid-cols-1 lg:grid-cols-12 gap-8 items-center">
@ -210,7 +169,7 @@ export default function Home() {
</span> </span>
</div> </div>
<p className="text-zinc-600 dark:text-zinc-400 mt-4 text-lg leading-relaxed"> <p className="text-zinc-600 dark:text-zinc-400 mt-4 text-lg leading-relaxed">
Take your AI assistants on the go.{" "} Take your AI assistants on the go.{' '}
<br className="hidden lg:block" /> Seamless integration <br className="hidden lg:block" /> Seamless integration
into your&nbsp; into your&nbsp;
<b className="text-bold text-black dark:text-white"> <b className="text-bold text-black dark:text-white">
@ -226,10 +185,10 @@ export default function Home() {
alt="App screenshots" alt="App screenshots"
sources={{ sources={{
light: useBaseUrl( light: useBaseUrl(
"/img/homepage/mobile-app-light.webp" '/img/homepage/mobile-app-light.webp'
), ),
dark: useBaseUrl( dark: useBaseUrl(
"/img/homepage/mobile-app-dark.webp" '/img/homepage/mobile-app-dark.webp'
), ),
}} }}
/> />
@ -238,9 +197,9 @@ export default function Home() {
</div> </div>
</div> </div>
</div> </div>
</div> </div> */}
<div className="dark:bg-[#09090B]/20"> {/* <div className="dark:bg-[#09090B]/20">
<div className="container py-12 lg:py-32"> <div className="container py-12 lg:py-32">
<div className="w-full xl:w-10/12 mx-auto relative"> <div className="w-full xl:w-10/12 mx-auto relative">
<div className="text-center"> <div className="text-center">
@ -266,7 +225,7 @@ export default function Home() {
Offline and Local First Offline and Local First
</h2> </h2>
<p className="mt-2 text-zinc-600 dark:text-zinc-400 text-lg leading-relaxed"> <p className="mt-2 text-zinc-600 dark:text-zinc-400 text-lg leading-relaxed">
Conversations, preferences, and model usage stay on{" "} Conversations, preferences, and model usage stay on{' '}
<br className="hidden lg:block" /> your computersecure, <br className="hidden lg:block" /> your computersecure,
exportable, and can be deleted at any time. exportable, and can be deleted at any time.
</p> </p>
@ -278,12 +237,12 @@ export default function Home() {
OpenAI Compatible OpenAI Compatible
</h2> </h2>
<p className="mt-4 leading-relaxed text-zinc-600 dark:text-zinc-400 text-lg"> <p className="mt-4 leading-relaxed text-zinc-600 dark:text-zinc-400 text-lg">
Jan provides an OpenAI-equivalent API{" "} Jan provides an OpenAI-equivalent API{' '}
<br className="hidden lg:block" /> server at&nbsp; <br className="hidden lg:block" /> server at&nbsp;
<b>localhost:</b>&nbsp; <b>localhost:</b>&nbsp;
<span className="bg-blue-600 text-white font-bold py-0.5 px-2 rounded-lg"> <span className="bg-blue-600 text-white font-bold py-0.5 px-2 rounded-lg">
1337 1337
</span>{" "} </span>{' '}
that can be used as a drop-in replacement with that can be used as a drop-in replacement with
compatible apps. compatible apps.
</p> </p>
@ -332,9 +291,16 @@ export default function Home() {
</div> </div>
</div> </div>
</div> </div>
</div> </div> */}
</main> </main>
{/* <main>
<div className="text-center py-24">
<h1 className="font-serif text-8xl">Rethink the Computer</h1>
<p>Turn your computer into a AI machine</p>
</div>
</main> */}
</Layout> </Layout>
</> </>
); )
} }

View File

@ -1,5 +1,5 @@
@layer base { @layer base {
html[data-theme="light"] { html[data-theme='light'] {
--custom-radial-blur: #e1e7fd; --custom-radial-blur: #e1e7fd;
--ifm-background-color: #fff; --ifm-background-color: #fff;
--ifm-color-primary: #2563eb; /* New Primary Blue */ --ifm-color-primary: #2563eb; /* New Primary Blue */
@ -14,7 +14,7 @@
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1);
} }
html[data-theme="dark"] { html[data-theme='dark'] {
--custom-radial-blur: #1d1b48; --custom-radial-blur: #1d1b48;
--ifm-background-color: #18181b; --ifm-background-color: #18181b;
--ifm-color-primary: #ffffff; /* New Primary Blue */ --ifm-color-primary: #ffffff; /* New Primary Blue */
@ -35,7 +35,7 @@
body { body {
@apply text-base; @apply text-base;
@apply antialiased; @apply antialiased;
@apply bg-white dark:bg-[#18181B]; @apply bg-white dark:bg-[#0C0C0C];
} }
img { img {

View File

@ -1,15 +1,17 @@
@import "tailwindcss/base"; @import url('https://fonts.googleapis.com/css2?family=Arapey&family=Inter:wght@100..900&display=swap');
@import "tailwindcss/components";
@import "tailwindcss/utilities";
@import "./components/base.scss"; @import 'tailwindcss/base';
@import "./components/typography.scss"; @import 'tailwindcss/components';
@import "./components/card.scss"; @import 'tailwindcss/utilities';
@import "./tweaks/navbar.scss"; @import './components/base.scss';
@import "./tweaks/breadcrumb.scss"; @import './components/typography.scss';
@import "./tweaks/markdown.scss"; @import './components/card.scss';
@import "./tweaks/redocusaurus.scss";
@import "./tweaks/sidebar.scss";
@import "../css/custom.css"; @import './tweaks/navbar.scss';
@import './tweaks/breadcrumb.scss';
@import './tweaks/markdown.scss';
@import './tweaks/redocusaurus.scss';
@import './tweaks/sidebar.scss';
@import '../css/custom.css';

View File

@ -2,7 +2,7 @@
@apply bg-transparent py-0 shadow-none px-0; @apply bg-transparent py-0 shadow-none px-0;
&__inner { &__inner {
@apply border border-gray-200 dark:border-gray-800 bg-white/80 dark:bg-[#09090B]/50 backdrop-blur-md flex items-center h-14 px-4 lg:px-8 relative; @apply border-b border-gray-200 dark:border-gray-800 bg-white/80 dark:bg-[#09090B]/50 backdrop-blur-md flex items-center h-14 px-4 lg:px-8 relative;
} }
&__logo { &__logo {
@ -19,7 +19,7 @@
font-size: 18px; font-size: 18px;
} }
[class*="searchBox_"] { [class*='searchBox_'] {
display: none; display: none;
} }
} }

View File

@ -1,23 +1,33 @@
import React from "react"; import React from 'react'
import clsx from "clsx"; import clsx from 'clsx'
import ErrorBoundary from "@docusaurus/ErrorBoundary"; import ErrorBoundary from '@docusaurus/ErrorBoundary'
import { import {
PageMetadata, PageMetadata,
SkipToContentFallbackId, SkipToContentFallbackId,
ThemeClassNames, ThemeClassNames,
} from "@docusaurus/theme-common"; } from '@docusaurus/theme-common'
import { useKeyboardNavigation } from "@docusaurus/theme-common/internal"; import { useKeyboardNavigation } from '@docusaurus/theme-common/internal'
import SkipToContent from "@theme/SkipToContent"; import SkipToContent from '@theme/SkipToContent'
import AnnouncementBar from "@theme/AnnouncementBar"; import AnnouncementBar from '@theme/AnnouncementBar'
import Navbar from "@theme/Navbar"; import Navbar from '@theme/Navbar'
import Footer from "@site/src/containers/Footer"; import Footer from '@site/src/containers/Footer'
import LayoutProvider from "@theme/Layout/Provider"; import LayoutProvider from '@theme/Layout/Provider'
import ErrorPageContent from "@theme/ErrorPageContent"; import ErrorPageContent from '@theme/ErrorPageContent'
import styles from "./styles.module.scss"; import styles from './styles.module.scss'
import NavBarExtension from "../NavbarExtension"; import NavBarExtension from '../NavbarExtension'
import { useLocation } from "react-router-dom"; import { useLocation } from 'react-router-dom'
const allowedPaths = ["/docs/", "/developer/", "/api-reference/", "/guides/", "/guides", "/docs", "/developer", "/api-reference", "/changelog"]; const allowedPaths = [
'/docs/',
'/developer/',
'/api-reference/',
'/guides/',
'/guides',
'/docs',
'/developer',
'/api-reference',
'/changelog',
]
export default function Layout(props) { export default function Layout(props) {
const { const {
@ -27,12 +37,14 @@ export default function Layout(props) {
// Not really layout-related, but kept for convenience/retro-compatibility // Not really layout-related, but kept for convenience/retro-compatibility
title, title,
description, description,
} = props; } = props
useKeyboardNavigation(); useKeyboardNavigation()
const location = useLocation(); const location = useLocation()
const isAllowedPath = allowedPaths.some(path => location.pathname.startsWith(path)); const isAllowedPath = allowedPaths.some((path) =>
location.pathname.startsWith(path)
)
return ( return (
<LayoutProvider> <LayoutProvider>
@ -42,20 +54,19 @@ export default function Layout(props) {
<AnnouncementBar /> <AnnouncementBar />
<Navbar/> <Navbar />
{isAllowedPath ? <NavBarExtension /> : ""} {isAllowedPath ? <NavBarExtension /> : ''}
{/* {console.log("Is allowed path?", location.pathname)} */} {/* {console.log("Is allowed path?", location.pathname)} */}
<div <div
id={SkipToContentFallbackId} id={SkipToContentFallbackId}
className={clsx( className={clsx(
ThemeClassNames.wrapper.main, ThemeClassNames.wrapper.main,
styles.mainWrapper, styles.mainWrapper,
wrapperClassName, wrapperClassName,
isAllowedPath && "mt-0 md:mt-11" isAllowedPath && 'mt-0 md:mt-11'
)} )}
> >
<ErrorBoundary fallback={(params) => <ErrorPageContent {...params} />}> <ErrorBoundary fallback={(params) => <ErrorPageContent {...params} />}>
@ -65,5 +76,5 @@ export default function Layout(props) {
{!noFooter && <Footer />} {!noFooter && <Footer />}
</LayoutProvider> </LayoutProvider>
); )
} }

View File

@ -1,67 +1,68 @@
// tailwind.config.js // tailwind.config.js
/** @type {import('tailwindcss').Config} */ /** @type {import('tailwindcss').Config} */
module.exports = { module.exports = {
content: ["./src/**/*.{js,jsx,ts,tsx}"], content: ['./src/**/*.{js,jsx,ts,tsx}'],
darkMode: ["class", '[data-theme="dark"]'], darkMode: ['class', '[data-theme="dark"]'],
theme: { theme: {
animation: { animation: {
wave: "wave 2.5s linear infinite", 'wave': 'wave 2.5s linear infinite',
enter: "enter 200ms ease-out", 'enter': 'enter 200ms ease-out',
"slide-in": "slide-in 1.2s cubic-bezier(.41,.73,.51,1.02)", 'slide-in': 'slide-in 1.2s cubic-bezier(.41,.73,.51,1.02)',
leave: "leave 150ms ease-in forwards", 'leave': 'leave 150ms ease-in forwards',
"bounce-down": "bounce-down 3s infinite", 'bounce-down': 'bounce-down 3s infinite',
}, },
keyframes: { keyframes: {
wave: { 'wave': {
"0%": { transform: "rotate( 0.0deg)" }, '0%': { transform: 'rotate( 0.0deg)' },
"10%": { transform: "rotate(14.0deg)" }, '10%': { transform: 'rotate(14.0deg)' },
"20%": { transform: "rotate(-8.0deg)" }, '20%': { transform: 'rotate(-8.0deg)' },
"30%": { transform: "rotate(14.0deg)" }, '30%': { transform: 'rotate(14.0deg)' },
"40%": { transform: "rotate(-4.0deg)" }, '40%': { transform: 'rotate(-4.0deg)' },
"50%": { transform: "rotate(10.0deg)" }, '50%': { transform: 'rotate(10.0deg)' },
"60%": { transform: "rotate( 0.0deg)" }, '60%': { transform: 'rotate( 0.0deg)' },
"100%": { transform: "rotate( 0.0deg)" }, '100%': { transform: 'rotate( 0.0deg)' },
}, },
enter: { 'enter': {
"0%": { transform: "scale(0.8)", opacity: "0" }, '0%': { transform: 'scale(0.8)', opacity: '0' },
"100%": { transform: "scale(1)", opacity: "1" }, '100%': { transform: 'scale(1)', opacity: '1' },
}, },
leave: { 'leave': {
"0%": { transform: "scale(1)", opacity: "1" }, '0%': { transform: 'scale(1)', opacity: '1' },
"100%": { transform: "scale(0.8)", opacity: "0" }, '100%': { transform: 'scale(0.8)', opacity: '0' },
}, },
"slide-in": { 'slide-in': {
"0%": { transform: "translateY(-100%)" }, '0%': { transform: 'translateY(-100%)' },
"100%": { transform: "translateY(0)" }, '100%': { transform: 'translateY(0)' },
}, },
"bounce-down": { 'bounce-down': {
"0%,20%, 50%,80%,100%": { transform: "translateY(0)" }, '0%,20%, 50%,80%,100%': { transform: 'translateY(0)' },
"40%": { transform: "translateY(-8px)" }, '40%': { transform: 'translateY(-8px)' },
"60%": { transform: "translateY(-4px)" }, '60%': { transform: 'translateY(-4px)' },
}, },
}, },
container: { container: {
center: true, center: true,
padding: "16px", padding: '16px',
}, },
fontFamily: { fontFamily: {
sans: [ sans: [
"Inter", 'Inter',
"-apple-system", '-apple-system',
"BlinkMacSystemFont", 'BlinkMacSystemFont',
"Segoe UI", 'Segoe UI',
"Roboto", 'Roboto',
"Oxygen-Sans", 'Oxygen-Sans',
"Ubuntu,Cantarell", 'Ubuntu,Cantarell',
"Helvetica", 'Helvetica',
"sans-serif", 'sans-serif',
], ],
serif: ['Arapey'],
}, },
extend: { extend: {
backgroundImage: { backgroundImage: {
'custom-img': "url('/img/homepage-new/bg.png')", 'custom-img': "url('/img/homepage-new/bg.png')",
} },
}, },
}, },
plugins: [require("tailwindcss-animate")], plugins: [require('tailwindcss-animate')],
}; }