diff --git a/docs/src/components/Elements/downloadLink.js b/docs/src/components/Elements/downloadLink.js new file mode 100644 index 000000000..744961380 --- /dev/null +++ b/docs/src/components/Elements/downloadLink.js @@ -0,0 +1,127 @@ +import React, { useState, useEffect } from "react"; +import axios from "axios"; + +const systemsTemplate = [ + { + name: "Download for Mac (M1/M2)", + logo: require("@site/static/img/apple-logo-white.png").default, + fileFormat: "{appname}-mac-arm64-{tag}.dmg", + }, + { + name: "Download for Mac (Intel)", + logo: require("@site/static/img/apple-logo-white.png").default, + fileFormat: "{appname}-mac-x64-{tag}.dmg", + }, + { + name: "Download for Windows", + logo: require("@site/static/img/windows-logo-white.png").default, + fileFormat: "{appname}-win-x64-{tag}.exe", + }, + { + name: "Download for Linux", + logo: require("@site/static/img/linux-logo-white.png").default, + fileFormat: "{appname}-linux-amd64-{tag}.deb", + }, +]; + +function classNames(...classes) { + return classes.filter(Boolean).join(" "); +} + +export default function DownloadLink() { + 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`; + try { + const response = await axios.get(url); + return response.data; + } catch (error) { + 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|amd64)-.*$/; + const match = fileName.match(regex); + return match ? match[1] : null; + }; + + const changeDefaultSystem = async (systems) => { + const userAgent = navigator.userAgent; + + const arc = await navigator?.userAgentData?.getHighEntropyValues([ + "architecture", + ]); + + if (userAgent.includes("Windows")) { + // windows user + setDefaultSystem(systems[2]); + } else if (userAgent.includes("Linux")) { + // linux user + setDefaultSystem(systems[3]); + } else if ( + userAgent.includes("Mac OS") && + arc && + arc.architecture === "arm" + ) { + setDefaultSystem(systems[0]); + } else { + setDefaultSystem(systems[1]); + } + }; + + useEffect(() => { + const updateDownloadLinks = async () => { + try { + const releaseInfo = await getLatestReleaseInfo("janhq", "jan"); + + // Extract appname from the first asset name + const firstAssetName = releaseInfo.assets[0].name; + const appname = extractAppName(firstAssetName); + + if (!appname) { + console.error( + "Failed to extract appname from file name:", + firstAssetName + ); + changeDefaultSystem(systems); + return; + } + + // Remove 'v' at the start of the tag_name + const tag = releaseInfo.tag_name.startsWith("v") + ? releaseInfo.tag_name.substring(1) + : releaseInfo.tag_name; + + const updatedSystems = systems.map((system) => { + const downloadUrl = system.fileFormat + .replace("{appname}", appname) + .replace("{tag}", tag); + return { + ...system, + href: `https://github.com/janhq/jan/releases/download/${releaseInfo.tag_name}/${downloadUrl}`, + }; + }); + + setSystems(updatedSystems); + changeDefaultSystem(updatedSystems); + } catch (error) { + console.error("Failed to update download links:", error); + } + }; + + updateDownloadLinks(); + }, []); + + return ( +
+ + Download Jan + +
+ ); +} diff --git a/docs/src/components/Elements/dropdown.js b/docs/src/components/Elements/dropdown.js index 31c2bf05a..5709a89ac 100644 --- a/docs/src/components/Elements/dropdown.js +++ b/docs/src/components/Elements/dropdown.js @@ -76,6 +76,7 @@ export default function Dropdown() { setDefaultSystem(systems[1]); } }; + useEffect(() => { const updateDownloadLinks = async () => { try { diff --git a/docs/src/pages/index.js b/docs/src/pages/index.js index d07e7d279..32176f9d8 100644 --- a/docs/src/pages/index.js +++ b/docs/src/pages/index.js @@ -5,38 +5,12 @@ import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; import useBaseUrl from "@docusaurus/useBaseUrl"; import Layout from "@theme/Layout"; import AnnoncementBanner from "@site/src/components/Announcement"; -import { - CloudArrowUpIcon, - CursorArrowRaysIcon, - ShieldCheckIcon, - CpuChipIcon, - ClipboardDocumentIcon, - CubeTransparentIcon, - ComputerDesktopIcon, - FolderPlusIcon, -} from "@heroicons/react/24/outline"; -import { AiOutlineGithub, AiOutlineTwitter } from "react-icons/ai"; + +import { AiOutlineGithub } from "react-icons/ai"; import ThemedImage from "@theme/ThemedImage"; -const features = [ - { - name: "Personal AI that runs on your computer", - desc: "Jan runs directly on your local machine, offering privacy, convenience and customizability.", - }, - { - name: "Extendable via App and Plugin framework", - desc: "Jan has a versatile app and plugin framework, allowing you to customize it to your needs.", - }, - { - name: "Private and offline, your data never leaves your machine", - desc: "Your conversations and data are with an AI that runs on your computer, where only you have access.", - }, - { - name: "No subscription fees, the AI runs on your computer", - desc: "Say goodbye to monthly subscriptions or usage-based APIs. Jan runs 100% free on your own hardware.", - }, -]; +import DownloadLink from "@site/src/components/Elements/downloadLink"; export default function Home() { const { siteConfig } = useDocusaurusContext(); @@ -45,19 +19,18 @@ export default function Home() {
- {/* */} + />
@@ -72,7 +45,6 @@ export default function Home() {

*/} -

Own your AI

@@ -108,7 +80,6 @@ export default function Home() {
- {/*
*/}
- {/*
+

AI that you control

Private. Local. Infinitely Customizable.

-
- {features.map((feat, i) => { - return ( -
-
-
{feat.name}
-

{feat.desc}

-
-
- ); - })} -
-
*/} -
-
-
-

Your AI, forever.

-

Apps come and go, but your AI and data should last.

+
+
+ Element +
+
Personal AI that runs on your computer
+

+ Jan runs directly on your local machine, offering privacy, + convenience and customizability. +

+ +
+
+
+
+
Extendable via App and Plugin framework
+

+ Jan has a versatile app and plugin framework, allowing you + to customize it to your needs. +

+
+ +
+
+
+
+ Private and offline, your data never leaves your machine +
+

+ Your conversations and data are with an AI that runs on your + computer, where only you have access. +

+
+ +
+
+
+
No subscription fees, the AI runs on your computer
+

+ Say goodbye to monthly subscriptions or usage-based APIs. + Jan runs 100% free on your own hardware. +

+
+
-
+ +
+
+
+

Your AI, forever.

+

+ Apps come and go, but your AI and data should last.{" "} +

+
+
+
+ Icon - Lock +

+ Jan uses open, standard and non-proprietary files stored + locally on your device. +

+
+
+ Icon - Camera +

+ You have total control over your AI, which means you can + use Jan offline and switch to another app easily if you + want. +

+
+
+
+
+ +
+ +

100% free on your own hardware

+ +
+
+
+ +

We are open-source.
Join Jan community.

diff --git a/docs/src/styles/card.scss b/docs/src/styles/card.scss index 592de481f..9149c3d0d 100644 --- a/docs/src/styles/card.scss +++ b/docs/src/styles/card.scss @@ -14,7 +14,7 @@ 0px 1px 2px 0px #525154 inset; } .card { - @apply p-8 rounded-3xl border bg-gray-100 border-gray-100 dark:border-[#202231] dark:bg-[#111217]; + @apply rounded-3xl border bg-gray-100 border-gray-100 dark:border-[#202231] dark:bg-[#111217]; &-link { display: inline-flex; diff --git a/docs/static/img/card-element.png b/docs/static/img/card-element.png new file mode 100644 index 000000000..94fab7029 Binary files /dev/null and b/docs/static/img/card-element.png differ diff --git a/docs/static/img/card-framework-dark.png b/docs/static/img/card-framework-dark.png new file mode 100644 index 000000000..ca59ecd76 Binary files /dev/null and b/docs/static/img/card-framework-dark.png differ diff --git a/docs/static/img/card-framework-light.png b/docs/static/img/card-framework-light.png new file mode 100644 index 000000000..01bdb999a Binary files /dev/null and b/docs/static/img/card-framework-light.png differ diff --git a/docs/static/img/card-free-dark.png b/docs/static/img/card-free-dark.png new file mode 100644 index 000000000..875c01fd7 Binary files /dev/null and b/docs/static/img/card-free-dark.png differ diff --git a/docs/static/img/card-free-light.png b/docs/static/img/card-free-light.png new file mode 100644 index 000000000..a57439df5 Binary files /dev/null and b/docs/static/img/card-free-light.png differ diff --git a/docs/static/img/card-nitro-dark.png b/docs/static/img/card-nitro-dark.png new file mode 100644 index 000000000..749fd8f91 Binary files /dev/null and b/docs/static/img/card-nitro-dark.png differ diff --git a/docs/static/img/card-nitro-light.png b/docs/static/img/card-nitro-light.png new file mode 100644 index 000000000..13a2f2179 Binary files /dev/null and b/docs/static/img/card-nitro-light.png differ diff --git a/docs/static/img/group-chat-dark.png b/docs/static/img/group-chat-dark.png new file mode 100644 index 000000000..5b8be82a7 Binary files /dev/null and b/docs/static/img/group-chat-dark.png differ diff --git a/docs/static/img/group-chat-light.png b/docs/static/img/group-chat-light.png new file mode 100644 index 000000000..2f716f4a2 Binary files /dev/null and b/docs/static/img/group-chat-light.png differ diff --git a/docs/static/img/ic-baseline-control-camera.svg b/docs/static/img/ic-baseline-control-camera.svg new file mode 100644 index 000000000..46daf8f0e --- /dev/null +++ b/docs/static/img/ic-baseline-control-camera.svg @@ -0,0 +1,4 @@ + + + + diff --git a/docs/static/img/ic-park-solid-unlock.svg b/docs/static/img/ic-park-solid-unlock.svg new file mode 100644 index 000000000..3c8729f91 --- /dev/null +++ b/docs/static/img/ic-park-solid-unlock.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/docs/static/img/jan-icon-dark.png b/docs/static/img/jan-icon-dark.png new file mode 100644 index 000000000..d18b13fdd Binary files /dev/null and b/docs/static/img/jan-icon-dark.png differ diff --git a/docs/static/img/jan-icon-light.png b/docs/static/img/jan-icon-light.png new file mode 100644 index 000000000..182f8569c Binary files /dev/null and b/docs/static/img/jan-icon-light.png differ