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 { useAppRelease } from "@site/src/hooks/useAppRelease";
import { useAppStars } from '@site/src/hooks/useAppStars'
import { useAppRelease } from '@site/src/hooks/useAppRelease'
import { AiOutlineGithub, AiOutlineTwitter } from "react-icons/ai";
import { BiLogoDiscordAlt } from "react-icons/bi";
import { AiOutlineGithub, AiOutlineTwitter } from 'react-icons/ai'
import { BiLogoDiscordAlt } from 'react-icons/bi'
const socials = [
{
icon: <AiOutlineTwitter className="text-xl text-white" />,
href: "https://twitter.com/janframework",
href: 'https://twitter.com/janframework',
},
{
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" />,
href: "https://github.com/janhq/jan",
href: 'https://github.com/janhq/jan',
},
];
]
export default function AnnoncementBanner() {
const { stargazers } = useAppStars();
const { release } = useAppRelease();
const { stargazers } = useAppStars()
const { release } = useAppRelease()
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="flex h-6 items-center shadow-sm">
<a
@ -75,10 +81,10 @@ export default function AnnoncementBanner() {
>
{social.icon}
</a>
);
)
})}
</div>
</div>
</div>
);
)
}

View File

@ -1,134 +1,134 @@
import React, { useState, useEffect } from "react";
import { Fragment } from "react";
import { Menu, Transition } from "@headlessui/react";
import { ChevronDownIcon } from "@heroicons/react/20/solid";
import axios from "axios";
import { FaWindows, FaApple, FaLinux } from "react-icons/fa";
import React, { useState, useEffect } from 'react'
import { Fragment } from 'react'
import { Menu, Transition } from '@headlessui/react'
import { ChevronDownIcon } from '@heroicons/react/20/solid'
import axios from 'axios'
import { FaWindows, FaApple, FaLinux } from 'react-icons/fa'
const systemsTemplate = [
{
name: "Download for Mac (M1/M2/M3)",
name: 'Download for Mac (M1/M2/M3)',
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,
fileFormat: "{appname}-mac-x64-{tag}.dmg",
fileFormat: '{appname}-mac-x64-{tag}.dmg',
},
{
name: "Download for Windows",
name: 'Download for Windows',
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,
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,
fileFormat: "{appname}-linux-amd64-{tag}.deb",
}
];
fileFormat: '{appname}-linux-amd64-{tag}.deb',
},
]
function classNames(...classes) {
return classes.filter(Boolean).join(" ");
return classes.filter(Boolean).join(' ')
}
export default function Dropdown() {
const [systems, setSystems] = useState(systemsTemplate);
const [defaultSystem, setDefaultSystem] = useState(systems[0]);
const [systems, setSystems] = useState(systemsTemplate)
const [defaultSystem, setDefaultSystem] = useState(systems[0])
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 {
const response = await axios.get(url);
return response.data;
const response = await axios.get(url)
return response.data
} catch (error) {
console.error(error);
return null;
console.error(error)
return null
}
};
}
const extractAppName = (fileName) => {
// Extract appname using a regex that matches the provided file formats
const regex = /^(.*?)-(?:mac|win|linux)-(?:arm64|x64|x86_64|amd64)-.*$/;
const match = fileName.match(regex);
return match ? match[1] : null;
};
const regex = /^(.*?)-(?:mac|win|linux)-(?:arm64|x64|x86_64|amd64)-.*$/
const match = fileName.match(regex)
return match ? match[1] : null
}
const changeDefaultSystem = async (systems) => {
const userAgent = navigator.userAgent;
const userAgent = navigator.userAgent
if (userAgent.includes("Windows")) {
if (userAgent.includes('Windows')) {
// windows user
setDefaultSystem(systems[2]);
} else if (userAgent.includes("Linux")) {
setDefaultSystem(systems[2])
} else if (userAgent.includes('Linux')) {
// linux user
setDefaultSystem(systems[3]);
} else if (userAgent.includes("Mac OS")) {
setDefaultSystem(systems[0]);
setDefaultSystem(systems[3])
} else if (userAgent.includes('Mac OS')) {
setDefaultSystem(systems[0])
} else {
setDefaultSystem(systems[1]);
setDefaultSystem(systems[1])
}
};
}
useEffect(() => {
const updateDownloadLinks = async () => {
try {
const releaseInfo = await getLatestReleaseInfo("janhq", "jan");
const releaseInfo = await getLatestReleaseInfo('janhq', 'jan')
// Extract appname from the first asset name
const firstAssetName = releaseInfo.assets[0].name;
const appname = extractAppName(firstAssetName);
const firstAssetName = releaseInfo.assets[0].name
const appname = extractAppName(firstAssetName)
if (!appname) {
console.error(
"Failed to extract appname from file name:",
'Failed to extract appname from file name:',
firstAssetName
);
changeDefaultSystem(systems);
return;
)
changeDefaultSystem(systems)
return
}
// 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;
: releaseInfo.tag_name
const updatedSystems = systems.map((system) => {
const downloadUrl = system.fileFormat
.replace("{appname}", appname)
.replace("{tag}", tag);
.replace('{appname}', appname)
.replace('{tag}', tag)
return {
...system,
href: `https://github.com/janhq/jan/releases/download/${releaseInfo.tag_name}/${downloadUrl}`,
};
});
}
})
setSystems(updatedSystems);
changeDefaultSystem(updatedSystems);
setSystems(updatedSystems)
changeDefaultSystem(updatedSystems)
} catch (error) {
console.error("Failed to update download links:", error);
console.error('Failed to update download links:', error)
}
};
}
updateDownloadLinks();
}, []);
updateDownloadLinks()
}, [])
return (
<div className="inline-flex align-items-stretch">
<a
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"
href={defaultSystem.href || ''}
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.name}
</a>
<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>
<ChevronDownIcon className="h-6 w-6" aria-hidden="true" />
</Menu.Button>
@ -141,7 +141,7 @@ export default function Dropdown() {
leaveFrom="transform opacity-100 scale-100"
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">
{systems.map((system) => (
<Menu.Item
@ -150,16 +150,16 @@ export default function Dropdown() {
>
{({ active }) => (
<a
href={system.href || ""}
href={system.href || ''}
className={classNames(
active
? "dark:bg-blue-100 bg-gray-900 hover:text-white dark:text-black"
: "text-white dark:text-black",
"flex px-4 py-3 items-center text-white hover:text-white dark:text-black"
? 'dark:bg-black/20 bg-gray-900 hover:text-white'
: 'text-white ',
'flex px-4 py-3 items-center text-white hover:text-white'
)}
>
<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}
</span>
</a>
@ -171,5 +171,5 @@ export default function Dropdown() {
</Transition>
</Menu>
</div>
);
)
}

View File

@ -1,31 +1,31 @@
import React from "react";
import DownloadApp from "@site/src/containers/DownloadApp";
import React from 'react'
import DownloadApp from '@site/src/containers/DownloadApp'
import useBaseUrl from "@docusaurus/useBaseUrl";
import Layout from "@theme/Layout";
import Banner from "@site/src/containers/Banner";
import useBaseUrl from '@docusaurus/useBaseUrl'
import Layout from '@theme/Layout'
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() {
const isBrowser = useIsBrowser();
const isBrowser = useIsBrowser()
const handleAnchorLink = () => {
document
.getElementById("download-section")
.scrollIntoView({ behavior: "smooth" });
};
.getElementById('download-section')
.scrollIntoView({ behavior: 'smooth' })
}
const userAgent = isBrowser && navigator.userAgent;
const isBrowserChrome = isBrowser && userAgent.includes("Chrome");
const userAgent = isBrowser && navigator.userAgent
const isBrowserChrome = isBrowser && userAgent.includes('Chrome')
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."
>
<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="col-span-full lg:col-start-2 lg:col-span-5 text-left relative z-10 px-4 py-6">
<img
src="/img/homepage/element-hero-blur.webp"
alt="Element blur"
className="hidden lg:block absolute blur-3xl opacity-30 right-32 -bottom-32"
/>
<div className="flex items-center space-x-2 mb-3">
<img alt="Jan Logo" src="img/logo.svg" width={36} height={36} />
<span className="text-zinc-500 text-4xl font-medium">
Meet Jan
</span>
</div>
<h1 className="text-5xl lg:text-7xl font-semibold leading-tight lg:leading-tight mt-2">
Bringing AI to <br /> your Desktop{" "}
<span className="relative w-16 h-16 inline-block">
<img
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 className="text-center py-24">
<h1 className="text-5xl lg:text-8xl !font-normal leading-tight lg:leading-tight mt-2 font-serif">
Rethink the Computer
</h1>
<p className="text-2xl -mt-1 leading-relaxed text-zinc-500">
Turn your computer into a{' '}
<span className="text-black dark:text-white font-semibold">
AI machine
</span>
</p>
<div className="mt-10">
{!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>
</div>
</div>
<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>
) : (
<Dropdown />
)}
</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
className="dark:bg-[#09090B]/20 border-t border-zinc-200 dark:border-gray-800 py-10 lg:py-16"
id="download-section"
>
@ -115,9 +74,9 @@ export default function Home() {
<DownloadApp />
</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="w-full lg:w-3/4 mx-auto relative rounded-xl py-10">
<img
@ -157,9 +116,9 @@ export default function Home() {
</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="w-full lg:w-3/4 mx-auto relative">
<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">
<b className="text-bold text-black dark:text-white">
10x productivity
</b>{" "}
with customizable AI <br className="hidden lg:block" />{" "}
</b>{' '}
with customizable AI <br className="hidden lg:block" />{' '}
assistants, global hotkeys, and in-line AI.
</p>
</div>
@ -182,10 +141,10 @@ export default function Home() {
alt="App screenshots"
sources={{
light: useBaseUrl(
"/img/homepage/desktop-app-light.webp"
'/img/homepage/desktop-app-light.webp'
),
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 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="w-full lg:w-3/4 mx-auto relative ">
<div className="grid grid-cols-1 lg:grid-cols-12 gap-8 items-center">
@ -210,7 +169,7 @@ export default function Home() {
</span>
</div>
<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
into your&nbsp;
<b className="text-bold text-black dark:text-white">
@ -226,10 +185,10 @@ export default function Home() {
alt="App screenshots"
sources={{
light: useBaseUrl(
"/img/homepage/mobile-app-light.webp"
'/img/homepage/mobile-app-light.webp'
),
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 className="dark:bg-[#09090B]/20">
{/* <div className="dark:bg-[#09090B]/20">
<div className="container py-12 lg:py-32">
<div className="w-full xl:w-10/12 mx-auto relative">
<div className="text-center">
@ -266,7 +225,7 @@ export default function Home() {
Offline and Local First
</h2>
<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,
exportable, and can be deleted at any time.
</p>
@ -278,12 +237,12 @@ export default function Home() {
OpenAI Compatible
</h2>
<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;
<b>localhost:</b>&nbsp;
<span className="bg-blue-600 text-white font-bold py-0.5 px-2 rounded-lg">
1337
</span>{" "}
</span>{' '}
that can be used as a drop-in replacement with
compatible apps.
</p>
@ -332,9 +291,16 @@ export default function Home() {
</div>
</div>
</div>
</div>
</div> */}
</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>
</>
);
)
}

View File

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

View File

@ -1,15 +1,17 @@
@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";
@import url('https://fonts.googleapis.com/css2?family=Arapey&family=Inter:wght@100..900&display=swap');
@import "./components/base.scss";
@import "./components/typography.scss";
@import "./components/card.scss";
@import 'tailwindcss/base';
@import 'tailwindcss/components';
@import 'tailwindcss/utilities';
@import "./tweaks/navbar.scss";
@import "./tweaks/breadcrumb.scss";
@import "./tweaks/markdown.scss";
@import "./tweaks/redocusaurus.scss";
@import "./tweaks/sidebar.scss";
@import './components/base.scss';
@import './components/typography.scss';
@import './components/card.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;
&__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 {
@ -19,7 +19,7 @@
font-size: 18px;
}
[class*="searchBox_"] {
[class*='searchBox_'] {
display: none;
}
}

View File

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

View File

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