feat: standalone download page
This commit is contained in:
parent
1b6568f665
commit
7d3bf0111b
@ -334,6 +334,11 @@ const config = {
|
||||
position: 'left',
|
||||
label: 'Ecosystem',
|
||||
},
|
||||
{
|
||||
to: 'download',
|
||||
position: 'left',
|
||||
label: 'Download',
|
||||
},
|
||||
// {
|
||||
// type: "docSidebar",
|
||||
// sidebarId: "pricingSidebar",
|
||||
|
||||
@ -37,6 +37,7 @@
|
||||
"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",
|
||||
|
||||
312
docs/sidebars.js
312
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
|
||||
|
||||
@ -1,135 +1,169 @@
|
||||
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) => (
|
||||
<div
|
||||
key={i}
|
||||
className="border-b border-[#F0F0F0] dark:border-gray-800 last:border-none pb-2 pt-2"
|
||||
>
|
||||
<a
|
||||
href={system.href || ''}
|
||||
className={twMerge(
|
||||
'btn-shadow inline-flex text-lg my-2 font-semibold cursor-pointer justify-center items-center space-x-2] text-blue-500 hover:text-blue-500 gap-2',
|
||||
system.comingSoon && 'pointer-events-none'
|
||||
)}
|
||||
>
|
||||
<span className="text-sm">{system.label}</span>
|
||||
<DownloadIcon size={16} />
|
||||
</a>
|
||||
</div>
|
||||
))}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="flex flex-col lg:flex-row items-center justify-center gap-4 mb-4">
|
||||
<span className="text-zinc-500 text-lg font-medium inline-block">
|
||||
Download for PC
|
||||
</span>
|
||||
<div className="bg-yellow-50 text-yellow-700 space-x-2 px-4 py-2 border border-yellow-400 rounded-lg text-base">
|
||||
<span>🚧</span>
|
||||
<span className="font-semibold">Warning:</span>
|
||||
<span className="font-medium">
|
||||
Jan is in the process of being built. Expect bugs!
|
||||
</span>
|
||||
<div className="flex flex-col items-center justify-center gap-4 mb-4">
|
||||
<h6 className="text-2xl font-medium">Detailed platforms</h6>
|
||||
<p className="leading-relaxed text-black/60 dark:text-white/60">
|
||||
Jan is in the process of being built. Expect bugs!
|
||||
</p>
|
||||
</div>
|
||||
<div className="w-full lg:w-3/5 mx-auto px-4">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 py-10 gap-8">
|
||||
{groupTemnplate.map((item, i) => {
|
||||
return (
|
||||
<div
|
||||
className="border border-[#F0F0F0] dark:border-gray-800 rounded-xl text-center"
|
||||
key={i}
|
||||
>
|
||||
<div className="text-center">
|
||||
<div className="flex gap-2 p-4 border-b border-[#F0F0F0] dark:border-gray-800 items-center justify-center">
|
||||
<div className="text-2xl">
|
||||
<item.logo />
|
||||
</div>
|
||||
<h6>{item.label}</h6>
|
||||
</div>
|
||||
<div className="mx-auto text-center py-2">
|
||||
{renderDownloadLink(item.name)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
<div className="mx-auto text-center">
|
||||
{systems.map((system, i) => (
|
||||
<a
|
||||
key={i}
|
||||
href={system.href || ""}
|
||||
className={twMerge(
|
||||
"btn-shadow inline-flex m-2 px-4 rounded-lg text-lg font-semibold cursor-pointer justify-center items-center space-x-2 border border-zinc-200 dark:border-gray-700 text-black dark:text-white bg-zinc-50 min-w-[150px] dark:bg-[#18181B] h-[36px]",
|
||||
system.comingSoon && "pointer-events-none"
|
||||
)}
|
||||
>
|
||||
<system.logo />
|
||||
<span className="text-sm">{system.name}</span>
|
||||
{system.comingSoon && (
|
||||
<span className="bg-zinc-200 py-0.5 px-2 inline-block ml-2 rounded-md text-xs h-[20px] dark:text-black">
|
||||
Coming Soon
|
||||
</span>
|
||||
)}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
@ -36,6 +36,10 @@ const menus = [
|
||||
{
|
||||
name: 'Product',
|
||||
child: [
|
||||
{
|
||||
menu: 'Download',
|
||||
path: '/download',
|
||||
},
|
||||
{
|
||||
menu: 'Documentation',
|
||||
path: '/developer',
|
||||
|
||||
45
docs/src/pages/download.js
Normal file
45
docs/src/pages/download.js
Normal file
@ -0,0 +1,45 @@
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import DownloadApp from '@site/src/containers/DownloadApp'
|
||||
|
||||
import ThemedImage from '@theme/ThemedImage'
|
||||
|
||||
import Layout from '@theme/Layout'
|
||||
import Banner from '@site/src/containers/Banner'
|
||||
|
||||
import useBaseUrl from '@docusaurus/useBaseUrl'
|
||||
|
||||
export default function Download() {
|
||||
return (
|
||||
<>
|
||||
<Banner />
|
||||
<Layout
|
||||
title="Download"
|
||||
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."
|
||||
>
|
||||
<main>
|
||||
{/* Hero */}
|
||||
<div className="text-center px-4 py-20">
|
||||
<h1 className="text-6xl lg:text-7xl !font-normal leading-tight lg:leading-tight mt-2 font-serif">
|
||||
Download Jan for your desktop
|
||||
</h1>
|
||||
<p className="text-2xl -mt-1 leading-relaxed text-black/60 dark:text-white/60">
|
||||
Turn your computer into an AI machine
|
||||
</p>
|
||||
|
||||
<div className="my-16">
|
||||
<ThemedImage
|
||||
className="w-28 mx-auto h-auto"
|
||||
alt="App screenshots"
|
||||
sources={{
|
||||
light: useBaseUrl('/img/homepage/mac-system-black.svg'),
|
||||
dark: useBaseUrl('/img/homepage/mac-system-white.svg'),
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<DownloadApp />
|
||||
</div>
|
||||
</main>
|
||||
</Layout>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@ -87,12 +87,6 @@ export default function Home() {
|
||||
const { stargazers } = useAppStars()
|
||||
const { data } = useDiscordWidget()
|
||||
|
||||
const handleAnchorLink = () => {
|
||||
document
|
||||
.getElementById('download-section')
|
||||
.scrollIntoView({ behavior: 'smooth' })
|
||||
}
|
||||
|
||||
const userAgent = isBrowser && navigator.userAgent
|
||||
const isBrowserChrome = isBrowser && userAgent.includes('Chrome')
|
||||
|
||||
@ -167,12 +161,12 @@ export default function Home() {
|
||||
</p>
|
||||
<div className="mt-10">
|
||||
{!isBrowserChrome ? (
|
||||
<div
|
||||
onClick={() => handleAnchorLink()}
|
||||
<a
|
||||
href="/download"
|
||||
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>
|
||||
</a>
|
||||
) : (
|
||||
<Dropdown />
|
||||
)}
|
||||
@ -811,12 +805,12 @@ export default function Home() {
|
||||
</div>
|
||||
<div className="mt-10 w-full lg:w-1/2 mx-auto lg:mr-auto lg:text-right">
|
||||
{!isBrowserChrome ? (
|
||||
<div
|
||||
onClick={() => handleAnchorLink()}
|
||||
<a
|
||||
href="/download"
|
||||
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>
|
||||
</a>
|
||||
) : (
|
||||
<Dropdown />
|
||||
)}
|
||||
@ -826,12 +820,6 @@ export default function Home() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{!isBrowserChrome && (
|
||||
<div className="my-10" id="download-section">
|
||||
<DownloadApp />
|
||||
</div>
|
||||
)}
|
||||
</main>
|
||||
</Layout>
|
||||
</>
|
||||
|
||||
@ -7097,6 +7097,11 @@ lru-cache@^6.0.0:
|
||||
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.1.0.tgz#2098d41c2dc56500e6c88584aa656c84de7d0484"
|
||||
integrity sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==
|
||||
|
||||
lucide-react@^0.291.0:
|
||||
version "0.291.0"
|
||||
resolved "https://registry.yarnpkg.com/lucide-react/-/lucide-react-0.291.0.tgz#d6db8f5117a68c8bbc6ed51d800879fa6a471978"
|
||||
integrity sha512-79jHlT9Je2PXSvXIBGDkItCK7In2O9iKnnSJ/bJxvIBOFaX2Ex0xEcC4fRS/g0F2uQGFejjmn2qWhwdc5wicMQ==
|
||||
|
||||
lunr@^2.3.9:
|
||||
version "2.3.9"
|
||||
resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user