feat: revamp homepage
This commit is contained in:
parent
6c81d83d30
commit
4470d3ac85
@ -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>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
@ -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>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
@ -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
|
||||
<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 computer—secure,
|
||||
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
|
||||
<b>localhost:</b>
|
||||
<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>
|
||||
</>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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';
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
@ -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')],
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user