diff --git a/docs/.env.example b/docs/.env.example
index 22f6e715f..56b26dafb 100644
--- a/docs/.env.example
+++ b/docs/.env.example
@@ -3,4 +3,5 @@ UMAMI_PROJECT_API_KEY=xxxx
UMAMI_APP_URL=xxxx
ALGOLIA_API_KEY=xxxx
ALGOLIA_APP_ID=xxxx
-GITHUB_ACCESS_TOKEN=xxxx
\ No newline at end of file
+GITHUB_ACCESS_TOKEN=xxxx
+API_KEY_BREVO=xxxx
\ No newline at end of file
diff --git a/docs/blog/01-january-10-2024-bitdefender-false-positive-flag.mdx b/docs/blog/01-january-10-2024-bitdefender-false-positive-flag.mdx
index 6c208764d..37ed1017d 100644
--- a/docs/blog/01-january-10-2024-bitdefender-false-positive-flag.mdx
+++ b/docs/blog/01-january-10-2024-bitdefender-false-positive-flag.mdx
@@ -16,7 +16,7 @@ tags: [Postmortem]
-
+
diff --git a/docs/docs/developer/01-overview/01-architecture.md b/docs/docs/developer/01-overview/01-architecture.md
index 218964bed..26a813173 100644
--- a/docs/docs/developer/01-overview/01-architecture.md
+++ b/docs/docs/developer/01-overview/01-architecture.md
@@ -26,7 +26,7 @@ keywords:
-
+
:::warning
diff --git a/docs/docs/developer/01-overview/02-file-based.md b/docs/docs/developer/01-overview/02-file-based.md
index 2cd8a554c..df8450389 100644
--- a/docs/docs/developer/01-overview/02-file-based.md
+++ b/docs/docs/developer/01-overview/02-file-based.md
@@ -26,7 +26,7 @@ keywords:
-
+
:::warning
diff --git a/docs/docs/developer/01-overview/03-user-interface.md b/docs/docs/developer/01-overview/03-user-interface.md
index fa5a3de79..968e2e254 100644
--- a/docs/docs/developer/01-overview/03-user-interface.md
+++ b/docs/docs/developer/01-overview/03-user-interface.md
@@ -26,7 +26,7 @@ keywords:
-
+
:::warning
diff --git a/docs/docs/developer/01-overview/04-install-and-prerequisites.md b/docs/docs/developer/01-overview/04-install-and-prerequisites.md
index a3e6ccfc1..27ce60eba 100644
--- a/docs/docs/developer/01-overview/04-install-and-prerequisites.md
+++ b/docs/docs/developer/01-overview/04-install-and-prerequisites.md
@@ -29,7 +29,7 @@ keywords:
-
+
## Requirements
diff --git a/docs/docs/developer/01-overview/README.md b/docs/docs/developer/01-overview/README.md
index 4f094685a..b6f9c0423 100644
--- a/docs/docs/developer/01-overview/README.md
+++ b/docs/docs/developer/01-overview/README.md
@@ -26,7 +26,7 @@ keywords:
-
+
The following docs are aimed at developers who want to build extensions on top of the Jan Framework.
diff --git a/docs/docs/developer/04-build-extension/01-your-first-extension.md b/docs/docs/developer/04-build-extension/01-your-first-extension.md
index 3fa9f5da5..51c20e4bb 100644
--- a/docs/docs/developer/04-build-extension/01-your-first-extension.md
+++ b/docs/docs/developer/04-build-extension/01-your-first-extension.md
@@ -28,7 +28,7 @@ keywords:
-
+
:::caution
diff --git a/docs/docs/guides/error-codes/permission-denied.mdx b/docs/docs/guides/error-codes/permission-denied.mdx
index a1c3577f9..d5cac5784 100644
--- a/docs/docs/guides/error-codes/permission-denied.mdx
+++ b/docs/docs/guides/error-codes/permission-denied.mdx
@@ -28,7 +28,7 @@ keywords:
-
+
When you run Jan, you may encounter the following error:
diff --git a/docs/docs/guides/extensions/setup-ext.mdx b/docs/docs/guides/extensions/setup-ext.mdx
index b8e1f757d..aae762663 100644
--- a/docs/docs/guides/extensions/setup-ext.mdx
+++ b/docs/docs/guides/extensions/setup-ext.mdx
@@ -27,7 +27,7 @@ keywords:
-
+
The current Jan Desktop Client has some default extensions built on top of this framework to enhance the user experience. In this guide, we will show you the list of default extensions and how to configure extension settings.
diff --git a/docs/docs/hardware/concepts/gpu-and-vram.md b/docs/docs/hardware/concepts/gpu-and-vram.md
index 0a9316a90..4543d731c 100644
--- a/docs/docs/hardware/concepts/gpu-and-vram.md
+++ b/docs/docs/hardware/concepts/gpu-and-vram.md
@@ -13,7 +13,7 @@ title: GPUs and VRAM
-
+
## What Is a GPU?
diff --git a/docs/docs/hardware/recommendations/by-budget.md b/docs/docs/hardware/recommendations/by-budget.md
index e556c77d3..1d1e24f71 100644
--- a/docs/docs/hardware/recommendations/by-budget.md
+++ b/docs/docs/hardware/recommendations/by-budget.md
@@ -13,7 +13,7 @@ title: Recommended AI Hardware by Budget
-
+
> :warning: **Warning:** Do your own research before any purchase. Jan is not liable for compatibility, performance or other issues. Products can become outdated quickly.
diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js
index 4e7e91baf..3b1bc3d5e 100644
--- a/docs/docusaurus.config.js
+++ b/docs/docusaurus.config.js
@@ -199,7 +199,7 @@ const config = {
// Docs: https://docusaurus.io/docs/api/themes/configuration
themeConfig: {
- image: 'img/og-image.png',
+ image: 'img/og-image.svg',
// Only for react live
liveCodeBlock: {
playgroundPosition: 'bottom',
@@ -222,8 +222,7 @@ const config = {
metadata: [
{
name: 'description',
- content:
- 'Jan runs 100% offline on your computer, utilizes open-source AI models, prioritizes privacy, and is highly customizable.',
+ content: `Jan turns your computer into an AI machine by running LLMs locally on your computer. It's a privacy-focus, local-first, open-source solution.`,
},
{
name: 'keywords',
@@ -233,32 +232,30 @@ const config = {
{ name: 'robots', content: 'index, follow' },
{
property: 'og:title',
- content: 'Jan | Open-source ChatGPT Alternative',
+ content: 'Jan AI | Rethink the Computer',
},
{
property: 'og:description',
- content:
- 'Jan runs 100% offline on your computer, utilizes open-source AI models, prioritizes privacy, and is highly customizable.',
+ content: `Jan turns your computer into an AI machine by running LLMs locally on your computer. It's a privacy-focus, local-first, open-source solution.`,
},
{
property: 'og:image',
- content: 'https://jan.ai/img/og-image.png',
+ content: 'https://jan.ai/img/og-image.svg',
},
{ property: 'og:type', content: 'website' },
{ property: 'twitter:card', content: 'summary_large_image' },
{ property: 'twitter:site', content: '@janframework' },
{
property: 'twitter:title',
- content: 'Jan | Open-source ChatGPT Alternative',
+ content: 'Jan AI | Rethink the Computer',
},
{
property: 'twitter:description',
- content:
- 'Jan runs 100% offline on your computer, utilizes open-source AI models, prioritizes privacy, and is highly customizable.',
+ content: `Jan turns your computer into an AI machine by running LLMs locally on your computer. It's a privacy-focus, local-first, open-source solution.`,
},
{
property: 'twitter:image',
- content: 'https://jan.ai/img/og-image.png',
+ content: 'https://jan.ai/img/og-image.svg',
},
],
headTags: [
@@ -280,8 +277,7 @@ const config = {
'@context': 'https://schema.org/',
'@type': 'localAI',
'name': 'Jan',
- 'description':
- 'Jan runs 100% offline on your computer, utilizes open-source AI models, prioritizes privacy, and is highly customizable.',
+ 'description': `Jan turns your computer into an AI machine by running LLMs locally on your computer. It's a privacy-focus, local-first, open-source solution.`,
'keywords':
'Jan AI, Jan, ChatGPT alternative, local AI, private AI, conversational AI, no-subscription fee, large language model ',
'applicationCategory': 'BusinessApplication',
@@ -338,10 +334,15 @@ const config = {
position: 'left',
label: 'Ecosystem',
},
+ {
+ to: 'download',
+ position: 'left',
+ label: 'Download',
+ },
// {
// type: "docSidebar",
// sidebarId: "pricingSidebar",
- // positionL: "left",
+ // positionl: "left",
// label: "Pricing",
// },
// Navbar right
@@ -403,6 +404,11 @@ const config = {
},
},
+ // Put your custom environment here
+ customFields: {
+ apiKeyBrevo: process.env.API_KEY_BREVO,
+ },
+
themes: ['@docusaurus/theme-live-codeblock', '@docusaurus/theme-mermaid'],
}
diff --git a/docs/package.json b/docs/package.json
index eb386d783..b4418453e 100644
--- a/docs/package.json
+++ b/docs/package.json
@@ -37,9 +37,12 @@
"postcss": "^8.4.30",
"posthog-docusaurus": "^2.0.0",
"prism-react-renderer": "^1.3.5",
+ "lucide-react": "^0.291.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
+ "react-hook-form": "^7.47.0",
"react-icons": "^4.11.0",
+ "react-tweet": "^3.2.0",
"redocusaurus": "^2.0.0",
"sass": "^1.69.3",
"tailwind-merge": "^2.1.0",
@@ -47,7 +50,7 @@
},
"devDependencies": {
"@docusaurus/module-type-aliases": "^3.0.0",
- "dotenv": "^16.3.1",
+ "dotenv": "^16.4.5",
"tailwindcss-animate": "^1.0.7"
},
"browserslist": {
diff --git a/docs/sidebars.js b/docs/sidebars.js
index ad09d670a..efe475283 100644
--- a/docs/sidebars.js
+++ b/docs/sidebars.js
@@ -15,77 +15,76 @@
const sidebars = {
aboutSidebar: [
{
- type: "category",
- label: "What is Jan?",
- link: { type: "doc", id: "about/about" },
+ type: 'category',
+ label: 'What is Jan?',
+ link: { type: 'doc', id: 'about/about' },
items: [
//"about/roadmap",
- "community/community",
+ 'community/community',
],
},
{
- type: "category",
- label: "Who we are",
- link: { type: "doc", id: "team/team" },
- items: ["team/join-us", "team/contributor-program"],
+ type: 'category',
+ label: 'Who we are',
+ link: { type: 'doc', id: 'team/team' },
+ items: ['team/join-us', 'team/contributor-program'],
},
- "wall-of-love",
+ 'wall-of-love',
{
- type: "category",
- label: "How We Work",
- link: { type: "doc", id: "how-we-work" },
+ type: 'category',
+ label: 'How We Work',
+ link: { type: 'doc', id: 'how-we-work' },
items: [
- "how-we-work/strategy/strategy",
- "how-we-work/project-management/project-management",
+ 'how-we-work/strategy/strategy',
+ 'how-we-work/project-management/project-management',
{
- type: "category",
- label: "Engineering",
- link: { type: "doc", id: "how-we-work/engineering/engineering" },
+ type: 'category',
+ label: 'Engineering',
+ link: { type: 'doc', id: 'how-we-work/engineering/engineering' },
items: [
- "how-we-work/engineering/ci-cd",
- "how-we-work/engineering/qa",
+ 'how-we-work/engineering/ci-cd',
+ 'how-we-work/engineering/qa',
],
},
- "how-we-work/product-design/product-design",
- "how-we-work/analytics/analytics",
- "how-we-work/website-docs/website-docs",
+ 'how-we-work/product-design/product-design',
+ 'how-we-work/analytics/analytics',
+ 'how-we-work/website-docs/website-docs',
],
},
- "acknowledgements",
+ 'acknowledgements',
{
- type: "category",
- label: "FAQ",
- link: { type: "doc", id: "about/faq" },
- items:
- [],
+ type: 'category',
+ label: 'FAQ',
+ link: { type: 'doc', id: 'about/faq' },
+ items: [],
},
],
productSidebar: [
{
- type: "category",
- label: "Platforms",
+ type: 'category',
+ label: 'Platforms',
collapsible: false,
items: [
- "platforms/desktop",
- "server-suite/home-server",
+ 'platforms/desktop',
+ 'server-suite/home-server',
// "server-suite/enterprise",
// "platforms/mobile",
// "platforms/hub",
],
},
{
- type: "category",
+ type: 'category',
collapsible: true,
collapsed: false,
- label: "Features",
- link: { type: "doc", id: "features/features" },
+ label: 'Features',
+ link: { type: 'doc', id: 'features/features' },
items: [
- "features/local",
- "features/remote",
- "features/api-server",
- "features/extensions-framework",
- "features/agents-framework",
- "features/data-security",
+ 'features/local',
+ 'features/remote',
+ 'features/api-server',
+ 'features/extensions-framework',
+ 'features/agents-framework',
+ 'features/data-security',
],
},
// NOTE: Jan Server Suite will be torn out into it's own section in the future
@@ -103,56 +102,56 @@ const sidebars = {
],
solutionSidebar: [
{
- type: "category",
- label: "Use Cases",
+ type: 'category',
+ label: 'Use Cases',
collapsed: true,
collapsible: true,
- items: ["solutions/ai-pc", "solutions/chatgpt-alternative"],
+ items: ['solutions/ai-pc', 'solutions/chatgpt-alternative'],
},
{
- type: "category",
- label: "Sectors",
+ type: 'category',
+ label: 'Sectors',
collapsed: true,
collapsible: true,
items: [
- "solutions/finance",
- "solutions/healthcare",
- "solutions/legal",
- "solutions/government",
+ 'solutions/finance',
+ 'solutions/healthcare',
+ 'solutions/legal',
+ 'solutions/government',
],
},
{
- type: "category",
- label: "Organization Type",
+ type: 'category',
+ label: 'Organization Type',
collapsed: true,
collapsible: true,
items: [
- "solutions/developers",
- "solutions/consultants",
- "solutions/startups",
- "solutions/enterprises",
+ 'solutions/developers',
+ 'solutions/consultants',
+ 'solutions/startups',
+ 'solutions/enterprises',
],
},
],
- pricingSidebar: ["pricing/pricing"],
+ pricingSidebar: ['pricing/pricing'],
ecosystemSidebar: [
- "ecosystem/ecosystem",
+ 'ecosystem/ecosystem',
{
- type: "category",
- label: "Partners",
- link: { type: "doc", id: "partners/partners" },
+ type: 'category',
+ label: 'Partners',
+ link: { type: 'doc', id: 'partners/partners' },
collapsible: true,
- items: ["partners/become-a-partner"],
+ items: ['partners/become-a-partner'],
},
{
- type: "category",
- label: "Integrations",
- link: { type: "doc", id: "integrations" },
+ type: 'category',
+ label: 'Integrations',
+ link: { type: 'doc', id: 'integrations' },
items: [
{
- type: "autogenerated",
- dirName: "integrations",
+ type: 'autogenerated',
+ dirName: 'integrations',
},
],
},
@@ -165,159 +164,154 @@ const sidebars = {
// ],
guidesSidebar: [
{
- type: "category",
- label: "Get Started",
+ type: 'category',
+ label: 'Get Started',
collapsible: false,
- className: "head_Menu",
+ className: 'head_Menu',
items: [
- "guides/quickstart",
- "guides/install",
- "guides/start-server",
- "guides/models-list"
- ]
+ 'guides/quickstart',
+ 'guides/install',
+ 'guides/start-server',
+ 'guides/models-list',
+ ],
},
{
- type: "category",
- label: "Guides",
+ type: 'category',
+ label: 'Guides',
collapsible: false,
- className: "head_Menu",
- items: [
- "guides/best-practices",
- "guides/thread",
- ]
+ className: 'head_Menu',
+ items: ['guides/best-practices', 'guides/thread'],
},
{
- type: "category",
- label: "Advanced Features",
+ type: 'category',
+ label: 'Advanced Features',
collapsible: false,
- className: "head_Menu",
+ className: 'head_Menu',
items: [
{
- type: "category",
- label: "Advanced Settings",
- className: "head_SubMenu",
+ type: 'category',
+ label: 'Advanced Settings',
+ className: 'head_SubMenu',
link: {
type: 'doc',
- id: "guides/advanced-settings/advanced-settings",
+ id: 'guides/advanced-settings/advanced-settings',
},
- items: [
- "guides/advanced-settings/http-proxy",
- ]
+ items: ['guides/advanced-settings/http-proxy'],
},
{
- type: "category",
- label: "Advanced Model Setup",
- className: "head_SubMenu",
+ type: 'category',
+ label: 'Advanced Model Setup',
+ className: 'head_SubMenu',
link: {
type: 'doc',
- id: "guides/models/README",
+ id: 'guides/models/README',
},
items: [
- "guides/models/customize-engine",
- "guides/models/import-models",
- "guides/models/integrate-remote",
- ]
+ 'guides/models/customize-engine',
+ 'guides/models/import-models',
+ 'guides/models/integrate-remote',
+ ],
},
{
- type: "category",
- label: "Inference Providers",
- className: "head_SubMenu",
+ type: 'category',
+ label: 'Inference Providers',
+ className: 'head_SubMenu',
link: {
type: 'doc',
- id: "guides/providers/README",
+ id: 'guides/providers/README',
},
items: [
- "guides/providers/llama-cpp",
- "guides/providers/tensorrt-llm",
- ]
+ 'guides/providers/llama-cpp',
+ 'guides/providers/tensorrt-llm',
+ ],
},
{
- type: "category",
- label: "Extensions",
- className: "head_SubMenu",
+ type: 'category',
+ label: 'Extensions',
+ className: 'head_SubMenu',
link: {
type: 'doc',
- id: "guides/extensions/README",
+ id: 'guides/extensions/README',
},
items: [
- "guides/extensions/import-ext",
- "guides/extensions/setup-ext",
- ]
+ 'guides/extensions/import-ext',
+ 'guides/extensions/setup-ext',
+ ],
},
{
- type: "category",
- label: "Integrations",
- className: "head_SubMenu",
+ type: 'category',
+ label: 'Integrations',
+ className: 'head_SubMenu',
link: {
type: 'doc',
- id: "guides/integration/README",
+ id: 'guides/integration/README',
},
items: [
- "guides/integration/azure",
- "guides/integration/discord",
- "guides/integration/groq",
- "guides/integration/lmstudio",
- "guides/integration/mistral",
- "guides/integration/ollama",
- "guides/integration/openinterpreter",
- "guides/integration/openrouter",
- "guides/integration/raycast",
- "guides/integration/vscode",
- ]
+ 'guides/integration/azure',
+ 'guides/integration/discord',
+ 'guides/integration/groq',
+ 'guides/integration/lmstudio',
+ 'guides/integration/mistral',
+ 'guides/integration/ollama',
+ 'guides/integration/openinterpreter',
+ 'guides/integration/openrouter',
+ 'guides/integration/raycast',
+ 'guides/integration/vscode',
+ ],
},
- ]
+ ],
},
{
- type: "category",
- label: "Troubleshooting",
+ type: 'category',
+ label: 'Troubleshooting',
collapsible: false,
- className: "head_Menu",
+ className: 'head_Menu',
items: [
{
- type: "category",
- label: "Error Codes",
- className: "head_SubMenu",
+ type: 'category',
+ label: 'Error Codes',
+ className: 'head_SubMenu',
link: {
type: 'doc',
- id: "guides/error-codes/README",
+ id: 'guides/error-codes/README',
},
items: [
- "guides/error-codes/how-to-get-error-logs",
- "guides/error-codes/permission-denied",
- "guides/error-codes/something-amiss",
- "guides/error-codes/undefined-issue",
- "guides/error-codes/unexpected-token",
- ]
+ 'guides/error-codes/how-to-get-error-logs',
+ 'guides/error-codes/permission-denied',
+ 'guides/error-codes/something-amiss',
+ 'guides/error-codes/undefined-issue',
+ 'guides/error-codes/unexpected-token',
+ ],
},
{
- type: "category",
- label: "Common Error",
- className: "head_SubMenu",
+ type: 'category',
+ label: 'Common Error',
+ className: 'head_SubMenu',
link: {
type: 'doc',
- id: "guides/common-error/README",
+ id: 'guides/common-error/README',
},
items: [
- "guides/common-error/broken-build",
- "guides/common-error/not-using-gpu",
- ]
+ 'guides/common-error/broken-build',
+ 'guides/common-error/not-using-gpu',
+ ],
},
- "guides/faq"
- ]
+ 'guides/faq',
+ ],
},
],
developerSidebar: [
{
- type: "autogenerated",
- dirName: "developer",
+ type: 'autogenerated',
+ dirName: 'developer',
},
],
releasesSidebar: [
{
- type: "autogenerated",
- dirName: "releases",
+ type: 'autogenerated',
+ dirName: 'releases',
},
- ]
-};
+ ],
+}
-module.exports = sidebars;
+module.exports = sidebars
diff --git a/docs/src/containers/Banner/index.js b/docs/src/containers/Banner/index.js
index 07622c63d..3538ab7a9 100644
--- a/docs/src/containers/Banner/index.js
+++ b/docs/src/containers/Banner/index.js
@@ -1,32 +1,43 @@
-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'
+import { FaLinkedin } from 'react-icons/fa'
const socials = [
{
icon: ,
- href: "https://twitter.com/janframework",
+ href: 'https://twitter.com/janframework',
},
{
icon: ,
- href: "https://discord.com/invite/FTk2MvZwJH",
+ href: 'https://discord.com/invite/FTk2MvZwJH',
},
{
icon: ,
- href: "https://github.com/janhq/jan",
+ href: 'https://github.com/janhq/jan',
},
-];
+ {
+ icon: ,
+ href: 'https://www.linkedin.com/company/janframework/',
+ },
+]
export default function AnnoncementBanner() {
- const { stargazers } = useAppStars();
- const { release } = useAppRelease();
+ const { stargazers } = useAppStars()
+ const { release } = useAppRelease()
return (
-
+
- );
+ )
}
diff --git a/docs/src/containers/DownloadApp/index.js b/docs/src/containers/DownloadApp/index.js
index d1b586698..9d1cd6a48 100644
--- a/docs/src/containers/DownloadApp/index.js
+++ b/docs/src/containers/DownloadApp/index.js
@@ -1,135 +1,161 @@
-import React, { useState, useEffect } from "react";
-import axios from "axios";
-import { FaWindows, FaApple, FaLinux } from "react-icons/fa";
-import { twMerge } from "tailwind-merge";
+import React, { useState, useEffect } from 'react'
+import axios from 'axios'
+import { FaWindows, FaApple, FaLinux } from 'react-icons/fa'
+import { twMerge } from 'tailwind-merge'
+import { DownloadIcon } from 'lucide-react'
const systemsTemplate = [
{
- name: "Mac M1, M2, M3",
+ name: 'Mac M1, M2, M3',
+ label: 'Apple Silicon',
logo: FaApple,
- fileFormat: "{appname}-mac-arm64-{tag}.dmg",
- comingSoon: false,
+ fileFormat: '{appname}-mac-arm64-{tag}.dmg',
},
{
- name: "Mac (Intel)",
+ name: 'Mac (Intel)',
+ label: 'Apple Intel',
logo: FaApple,
- fileFormat: "{appname}-mac-x64-{tag}.dmg",
- comingSoon: false,
+ fileFormat: '{appname}-mac-x64-{tag}.dmg',
},
{
- name: "Windows",
+ name: 'Windows',
+ label: 'Standard (64-bit)',
logo: FaWindows,
- fileFormat: "{appname}-win-x64-{tag}.exe",
+ fileFormat: '{appname}-win-x64-{tag}.exe',
},
{
- name: "Linux (AppImage)",
+ name: 'Linux (AppImage)',
+ label: 'AppImage',
logo: FaLinux,
- fileFormat: "{appname}-linux-x86_64-{tag}.AppImage",
+ fileFormat: '{appname}-linux-x86_64-{tag}.AppImage',
},
{
- name: "Linux (deb)",
+ name: 'Linux (deb)',
+ label: 'Deb',
logo: FaLinux,
- fileFormat: "{appname}-linux-amd64-{tag}.deb",
+ fileFormat: '{appname}-linux-amd64-{tag}.deb',
},
-];
+]
+
+const groupTemnplate = [
+ { label: 'MacOS', name: 'mac', logo: FaApple },
+ { label: 'Windows', name: 'windows', logo: FaWindows },
+ { label: 'Linux', name: 'linux', logo: FaLinux },
+]
export default function DownloadApp() {
- const [systems, setSystems] = useState(systemsTemplate);
+ const [systems, setSystems] = useState(systemsTemplate)
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|amd64|x86_64)-.*$/;
- const match = fileName.match(regex);
- return match ? match[1] : null;
- };
+ const regex = /^(.*?)-(?:mac|win|linux)-(?:arm64|x64|amd64|x86_64)-.*$/
+ const match = fileName.match(regex)
+ return match ? match[1] : null
+ }
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
- );
+ )
- return;
+ 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);
+ setSystems(updatedSystems)
} catch (error) {
- console.error("Failed to update download links:", error);
+ console.error('Failed to update download links:', error)
}
- };
+ }
- updateDownloadLinks();
- }, []);
+ updateDownloadLinks()
+ }, [])
+
+ const renderDownloadLink = (group) => {
+ return (
+ <>
+ {systems
+ .filter((x) => x.name.toLowerCase().includes(group))
+ .map((system, i) => (
+
+ ))}
+ >
+ )
+ }
return (
-
-
-
- Download for PC
-
-
- 🚧
- Warning:
-
- Jan is in the process of being built. Expect bugs!
-
-
-
-
- {systems.map((system, i) => (
-
-
- {system.name}
- {system.comingSoon && (
-
- Coming Soon
-
- )}
-
- ))}
+
+
+ {groupTemnplate.map((item, i) => {
+ return (
+
+
+
+
+ {renderDownloadLink(item.name)}
+
+
+
+ )
+ })}
- );
+ )
}
diff --git a/docs/src/containers/Elements/dropdown.js b/docs/src/containers/Elements/dropdown.js
index 91115c811..00176fdf2 100644
--- a/docs/src/containers/Elements/dropdown.js
+++ b/docs/src/containers/Elements/dropdown.js
@@ -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 (
{defaultSystem.name}