Update hero and download section

This commit is contained in:
Faisal Amir 2023-11-28 21:29:22 +07:00
parent 8586b3ec9e
commit bb9970c21a
10 changed files with 257 additions and 25 deletions

View File

@ -5,15 +5,15 @@ const menus = [
name: "For Developers", name: "For Developers",
child: [ child: [
{ {
menu: "Documentation (WIP)", menu: "Documentation",
path: "/intro", path: "/intro",
}, },
{ {
menu: "Hardware (WIP)", menu: "Hardware",
path: "/hardware", path: "/hardware",
}, },
{ {
menu: "API Reference (WIP)", menu: "API Reference",
path: "/api-reference", path: "/api-reference",
}, },
{ {
@ -67,7 +67,7 @@ const getCurrentYear = new Date().getFullYear();
export default function Footer() { export default function Footer() {
return ( return (
<footer className="flex-shrink-0 border-t dark:border-gray-800 border-gray-200 py-10"> <footer className="flex-shrink-0 dark:bg-[#09090B]/10 bg-[#D4D4D8]/10 relative overflow-hidden py-10">
<div className="container"> <div className="container">
<div className="grid grid-cols-2 gap-8 md:grid-cols-2 lg:grid-cols-6"> <div className="grid grid-cols-2 gap-8 md:grid-cols-2 lg:grid-cols-6">
<div className="lg:col-span-3 col-span-2"> <div className="lg:col-span-3 col-span-2">

View File

@ -0,0 +1,155 @@
import React, { useState, useEffect } from "react";
import axios from "axios";
import { FaWindows, FaApple, FaLinux } from "react-icons/fa";
const systemsTemplate = [
{
name: "Download for Mac (M1/M2)",
logo: FaApple,
fileFormat: "{appname}-mac-arm64-{tag}.dmg",
},
{
name: "Download for Mac (Intel)",
logo: FaApple,
fileFormat: "{appname}-mac-x64-{tag}.dmg",
},
{
name: "Download for Windows",
logo: FaWindows,
fileFormat: "{appname}-win-x64-{tag}.exe",
},
{
name: "Download for Linux",
logo: FaLinux,
fileFormat: "{appname}-linux-amd64-{tag}.deb",
},
];
export default function DownloadApp() {
const [systems, setSystems] = useState(systemsTemplate);
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;
};
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 (
<div>
<div className="flex flex-col gap-y-4">
<div className="flex items-center space-x-4">
<h6 className="w-[100px]">Windows</h6>
{systems
.filter((x) => x.name.includes("Windows"))
.map((system) => (
<a
href={system.href}
className="inline-flex px-4 py-3 rounded-lg text-lg font-semibold cursor-pointer justify-center items-center space-x-2 border border-gray-400 dark:border-gray-700 text-gray-600 dark:text-white"
>
<system.logo />
<span>{system.name}</span>
</a>
))}
</div>
<div className="flex items-start lg:items-center space-x-4">
<h6 className="w-[100px]">Mac</h6>
<div className="flex flex-col lg:flex-row gap-4">
{systems
.filter((x) => x.name.includes("Mac"))
.map((system) => (
<a
href={system.href}
className="inline-flex px-4 py-3 rounded-lg text-lg font-semibold cursor-pointer justify-center items-center space-x-2 border border-gray-400 dark:border-gray-700 text-gray-600 dark:text-white"
>
<system.logo />
<span>{system.name}</span>
</a>
))}
</div>
</div>
<div className="flex items-center space-x-4">
<h6 className="w-[100px]">Linux</h6>
{systems
.filter((x) => x.name.includes("Linux"))
.map((system) => (
<a
href={system.href}
className="inline-flex px-4 py-3 rounded-lg text-lg font-semibold cursor-pointer justify-center items-center space-x-2 border border-gray-400 dark:border-gray-700 text-gray-600 dark:text-white"
>
<system.logo />
<span>{system.name}</span>
</a>
))}
</div>
</div>
{/* {systems.map((system) => (
<a
href={system.href}
className="inline-flex px-4 py-3 rounded-lg text-lg font-semibold cursor-pointer justify-center items-center space-x-2 border border-gray-400 dark:border-gray-700 text-gray-600 dark:text-white"
>
<img
src={system.logo}
alt="Logo"
className="w-3 mr-3 -mt-1 flex-shrink-0"
/>
<span>{system.name}</span>
</a>
))} */}
</div>
);
}

View File

@ -0,0 +1,27 @@
import React from "react";
import { FaGithub, FaDiscord } from "react-icons/fa";
export default function SocialButton() {
return (
<div className="flex items-center space-x-2 justify-center lg:justify-start">
<a
href="https://github.com/janhq/nitro/releases"
className="inline-flex px-4 py-3 rounded-lg text-lg font-semibold cursor-pointer justify-center items-center space-x-2 border border-gray-400 dark:border-gray-700 text-gray-600 dark:text-white"
>
<span>
<FaDiscord className="text-xl" />
</span>
<span>Join our Discord</span>
</a>
<a
href="https://github.com/janhq/jan"
className="text-white bg-blue-600 hover:bg-blue-700 hover:text-white inline-flex px-4 py-3 rounded-lg text-lg font-semibold cursor-pointer justify-center items-center space-x-2"
>
<span>
<FaGithub className="text-lg" />
</span>
<span>View on Github</span>
</a>
</div>
);
}

View File

@ -1,48 +1,98 @@
import React from "react"; import React from "react";
import Dropdown from "@site/src/components/Elements/dropdown"; import DownloadApp from "@site/src/containers/DownloadApp";
import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
import useBaseUrl from "@docusaurus/useBaseUrl"; import useBaseUrl from "@docusaurus/useBaseUrl";
import Layout from "@theme/Layout"; import Layout from "@theme/Layout";
import AnnoncementBanner from "@site/src/components/Announcement"; import Banner from "@site/src/containers/Banner";
import { AiOutlineGithub } from "react-icons/ai";
import ThemedImage from "@theme/ThemedImage"; import ThemedImage from "@theme/ThemedImage";
import DownloadLink from "@site/src/components/Elements/downloadLink"; import SocialButton from "@site/src/containers/SocialButton";
export default function Home() { export default function Home() {
const { siteConfig } = useDocusaurusContext(); const { siteConfig } = useDocusaurusContext();
return ( return (
<> <>
{/* <AnnoncementBanner /> */} <Banner />
<Layout <Layout
title={`${siteConfig.tagline}`} title={`${siteConfig.tagline}`}
description="Jan is a ChatGPT-alternative that runs on your own computer, with a local API server." description="Jan is a ChatGPT-alternative that runs on your own computer, with a local API server."
> >
<main> <main>
<div className="container"> <div className="container">
<div className="grid grid-cols-1 lg:grid-cols-12 mt-10 gap-8 items-center"> <div className="grid grid-cols-1 lg:grid-cols-12 mt-8 gap-8 items-center relative">
<div className="col-span-7"> <div className="col-span-full lg:col-span-5 lg:text-left text-center relative z-10">
<h1 className="bg-gradient-to-b dark:from-white from-black to-gray-700 dark:to-gray-400 bg-clip-text text-7xl font-semibold leading-tight text-transparent dark:text-transparent lg:leading-tight"> <h1 className="bg-gradient-to-b dark:from-white from-black to-gray-700 dark:to-gray-400 bg-clip-text text-6xl font-black leading-tight text-transparent dark:text-transparent lg:leading-tight">
Own your AI Own your AI
</h1> </h1>
<p className="text-2xl mt-1"> <p className="text-2xl mt-1">
Jan is an open-source alternative to ChatGPT that runs on your Jan is an open-source alternative to ChatGPT that runs on your
own computer own computer.
</p> </p>
<div className="mt-8">
<SocialButton />
</div>
</div> </div>
<div className="col-span-5"> <div className="col-span-full lg:col-span-7">
<p> <div className="relative text-center">
Lorem ipsum, dolor sit amet consectetur adipisicing elit. <ThemedImage
Error explicabo aperiam molestias neque quod ad id dolorum className="rounded-md shadow-2xl dark:shadow-none w-full lg:w-4/5"
adipisci dicta magni possimus, tempore temporibus magnam nisi alt="App screenshots"
harum veritatis eaque molestiae suscipit. sources={{
</p> light: useBaseUrl(
"/img/homepage/app-base-screen-light.png"
),
dark: useBaseUrl(
"/img/homepage/app-base-screen-dark.png"
),
}}
/>
</div>
</div> </div>
</div> </div>
</div> </div>
<div className="bg-gray-100 dark:bg-[#09090B]/20 border-y border-gray-300 dark:border-gray-800 mt-10 py-10">
<div className="container">
<div className="w-full lg:w-3/4 mx-auto">
<DownloadApp />
</div>
</div>
</div>
<div className="container text-center mt-20">
<h5>Take Control</h5>
<p>
Jan runs 100% on your own machine, privately, predictably and even
in offline, with no surprise bills
</p>
</div>
<div className="container text-center mt-20">
<h5>100% Open Source</h5>
<p>
Say goodbye to black boxes. Jan has well-documented code and
stores data in open-format files that you can inspect, verify and
tinker with.
</p>
</div>
<div className="container text-center mt-20">
<h5>Extensions</h5>
<p>
Jan has a powerful Extensions API inspired by VSCode. In fact,
most of Jan's core services are built as extensions.
</p>
</div>
<div className="container text-center my-20">
<h5>No-fuss Compatibility</h5>
<p>
Jan's API aims to be a drop-in replacement for OpenAI's REST API,
with a local server that runs at port 1337
</p>
</div>
</main> </main>
</Layout> </Layout>
</> </>

View File

@ -2,7 +2,7 @@
html[data-theme="light"] { html[data-theme="light"] {
--custom-radial-blur: #e1e7fd; --custom-radial-blur: #e1e7fd;
--ifm-background-color: #fafafa; --ifm-background-color: #fff;
--ifm-color-primary: #2563eb; /* New Primary Blue */ --ifm-color-primary: #2563eb; /* New Primary Blue */
--ifm-color-primary-dark: #204fcf; /* Darker Blue */ --ifm-color-primary-dark: #204fcf; /* Darker Blue */
--ifm-color-primary-darker: #1b45b7; /* Even Darker Blue */ --ifm-color-primary-darker: #1b45b7; /* Even Darker Blue */
@ -36,7 +36,7 @@
body { body {
@apply text-base; @apply text-base;
@apply antialiased; @apply antialiased;
@apply bg-[#FAFAFA] dark:bg-[#18181B]; @apply bg-white dark:bg-[#18181B];
} }
img { img {

View File

@ -11,7 +11,7 @@
} }
&__inner { &__inner {
@apply border border-gray-300 dark:border-gray-800 rounded-lg bg-[#E4E4E7]/50 dark:bg-[#09090B]/50 backdrop-blur-md flex items-center h-14 px-8 relative; @apply border border-gray-300 dark:border-gray-800 rounded-lg bg-[#E4E4E7]/20 dark:bg-[#09090B]/50 backdrop-blur-md flex items-center h-14 px-8 relative;
} }
&__logo { &__logo {

View File

@ -47,7 +47,7 @@ export default function Layout(props) {
</ErrorBoundary> </ErrorBoundary>
</div> </div>
{/* {!noFooter && <Footer />} */} {!noFooter && <Footer />}
</LayoutProvider> </LayoutProvider>
); );
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB