diff --git a/core/src/types/index.ts b/core/src/types/index.ts index 7a7faad6d..dcbc20ca3 100644 --- a/core/src/types/index.ts +++ b/core/src/types/index.ts @@ -240,6 +240,7 @@ export type ModelMetadata = { author: string; tags: string[]; size: number; + cover?: string; }; /** diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index da62e3399..47a7910a0 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -3,7 +3,6 @@ require("dotenv").config(); -const lightCodeTheme = require("prism-react-renderer/themes/github"); const darkCodeTheme = require("prism-react-renderer/themes/dracula"); /** @type {import('@docusaurus/types').Config} */ @@ -115,11 +114,11 @@ const config = { primaryColor: "#1a73e8", primaryColorDark: "#1a73e8", options: { - requiredPropsFirst: true, - noAutoAuth: true, - hideDownloadButton: true, - disableSearch: true, - }, + requiredPropsFirst: true, + noAutoAuth: true, + hideDownloadButton: true, + disableSearch: true, + }, }, }, ], @@ -135,48 +134,72 @@ const config = { docs: { sidebar: { hideable: true, - autoCollapseCategories: true, + autoCollapseCategories: false, }, }, - // SEO Docusarus + // SEO Docusarus metadata: [ - { name: 'description', content: 'Jan is a ChatGPT-alternative that runs on your own computer, with a local API server.' }, - { name: 'keywords', content: 'Jan, ChatGPT alternative, on-premises AI, local API server, local AI, llm, conversational AI, no-subscription fee' }, - { name: 'robots', content: 'index, follow' }, - { property: 'og:title', content: 'Run your own AI | Jan' }, - { property: 'og:description', content: 'Jan is a ChatGPT-alternative that runs on your own computer, with a local API server.' }, - { property: 'og:image', content: 'https://jan.ai/img/jan-social-card.png' }, - { property: 'og:type', content: 'website' }, - { property: 'twitter:card', content: 'summary_large_image' }, - { property: 'twitter:site', content: '@janhq_' }, - { property: 'twitter:title', content: 'Run your own AI | Jan' }, - { property: 'twitter:description', content: 'Jan is a ChatGPT-alternative that runs on your own computer, with a local API server.' }, - { property: 'twitter:image', content: 'https://jan.ai/img/jan-social-card.png' }, + { + name: "description", + content: + "Jan is a ChatGPT-alternative that runs on your own computer, with a local API server.", + }, + { + name: "keywords", + content: + "Jan, ChatGPT alternative, on-premises AI, local API server, local AI, llm, conversational AI, no-subscription fee", + }, + { name: "robots", content: "index, follow" }, + { property: "og:title", content: "Run your own AI | Jan" }, + { + property: "og:description", + content: + "Jan is a ChatGPT-alternative that runs on your own computer, with a local API server.", + }, + { + property: "og:image", + content: "https://jan.ai/img/jan-social-card.png", + }, + { property: "og:type", content: "website" }, + { property: "twitter:card", content: "summary_large_image" }, + { property: "twitter:site", content: "@janhq_" }, + { property: "twitter:title", content: "Run your own AI | Jan" }, + { + property: "twitter:description", + content: + "Jan is a ChatGPT-alternative that runs on your own computer, with a local API server.", + }, + { + property: "twitter:image", + content: "https://jan.ai/img/jan-social-card.png", + }, ], headTags: [ // Declare a preconnect tag { - tagName: 'link', + tagName: "link", attributes: { - rel: 'preconnect', - href: 'https://jan.ai/', + rel: "preconnect", + href: "https://jan.ai/", }, }, // Declare some json-ld structured data { - tagName: 'script', + tagName: "script", attributes: { - type: 'application/ld+json', + type: "application/ld+json", }, innerHTML: JSON.stringify({ - '@context': 'https://schema.org/', - '@type': 'localAI', - name: 'Jan', - description: "Jan is a ChatGPT-alternative that runs on your own computer, with a local API server.", - keywords: "Jan, ChatGPT alternative, on-premises AI, local API server, local AI, llm, conversational AI, no-subscription fee", + "@context": "https://schema.org/", + "@type": "localAI", + name: "Jan", + description: + "Jan is a ChatGPT-alternative that runs on your own computer, with a local API server.", + keywords: + "Jan, ChatGPT alternative, on-premises AI, local API server, local AI, llm, conversational AI, no-subscription fee", applicationCategory: "BusinessApplication", operatingSystem: "Multiple", - url: 'https://jan.ai/', + url: "https://jan.ai/", }), }, ], @@ -234,10 +257,10 @@ const config = { prism: { theme: darkCodeTheme, darkTheme: darkCodeTheme, - additionalLanguages: ["python"], + additionalLanguages: ["python", "powershell", "bash"], }, colorMode: { - defaultMode: "dark", + defaultMode: "light", disableSwitch: false, respectPrefersColorScheme: false, }, diff --git a/docs/src/components/Announcement/index.js b/docs/src/containers/Banner/index.js similarity index 96% rename from docs/src/components/Announcement/index.js rename to docs/src/containers/Banner/index.js index 922be62f7..33061de0f 100644 --- a/docs/src/components/Announcement/index.js +++ b/docs/src/containers/Banner/index.js @@ -27,7 +27,7 @@ export default function AnnoncementBanner() { return (
-
+
{ + 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; + }; + + 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 + ); + + 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); + } catch (error) { + console.error("Failed to update download links:", error); + } + }; + + updateDownloadLinks(); + }, []); + + return ( +
+
+ + Download for PC + +
+ 🚧 + + Warning: Jan is in the process of being built. Expect bugs! + +
+
+
+
+ ); +} diff --git a/docs/src/components/Elements/downloadLink.js b/docs/src/containers/Elements/downloadLink.js similarity index 100% rename from docs/src/components/Elements/downloadLink.js rename to docs/src/containers/Elements/downloadLink.js diff --git a/docs/src/components/Elements/dropdown.js b/docs/src/containers/Elements/dropdown.js similarity index 100% rename from docs/src/components/Elements/dropdown.js rename to docs/src/containers/Elements/dropdown.js diff --git a/docs/src/components/Footer/index.js b/docs/src/containers/Footer/index.js similarity index 61% rename from docs/src/components/Footer/index.js rename to docs/src/containers/Footer/index.js index e5c09fe8e..d2fde6b8a 100644 --- a/docs/src/components/Footer/index.js +++ b/docs/src/containers/Footer/index.js @@ -1,19 +1,37 @@ import React from "react"; +import { AiOutlineGithub, AiOutlineTwitter } from "react-icons/ai"; +import { BiLogoDiscordAlt } from "react-icons/bi"; + +const socials = [ + { + icon: , + href: "https://twitter.com/janhq_", + }, + { + icon: , + href: "https://discord.com/invite/FTk2MvZwJH", + }, + { + icon: , + href: "https://github.com/janhq/jan", + }, +]; + const menus = [ { name: "For Developers", child: [ { - menu: "Documentation (WIP)", + menu: "Documentation", path: "/intro", }, { - menu: "Hardware (WIP)", + menu: "Hardware", path: "/hardware", }, { - menu: "API Reference (WIP)", + menu: "API Reference", path: "/api-reference", }, { @@ -67,16 +85,32 @@ const getCurrentYear = new Date().getFullYear(); export default function Footer() { return ( -