diff --git a/frontend/src/components/Footer.tsx b/frontend/src/components/Footer.tsx index 11577ced..be55e0e9 100644 --- a/frontend/src/components/Footer.tsx +++ b/frontend/src/components/Footer.tsx @@ -58,6 +58,12 @@ export function Footer() { > Pricing + + Downloads + + +
+ + + Download + +
{/* Features Section */} diff --git a/frontend/src/components/SimplifiedFooter.tsx b/frontend/src/components/SimplifiedFooter.tsx index 0bd208ea..6b4e0df7 100644 --- a/frontend/src/components/SimplifiedFooter.tsx +++ b/frontend/src/components/SimplifiedFooter.tsx @@ -14,6 +14,12 @@ export function SimplifiedFooter() {

+ + Downloads + rootRoute, } as any) +const DownloadsRoute = DownloadsImport.update({ + id: '/downloads', + path: '/downloads', + getParentRoute: () => rootRoute, +} as any) + const DesktopAuthRoute = DesktopAuthImport.update({ id: '/desktop-auth', path: '/desktop-auth', @@ -122,6 +129,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof DesktopAuthImport parentRoute: typeof rootRoute } + '/downloads': { + id: '/downloads' + path: '/downloads' + fullPath: '/downloads' + preLoaderRoute: typeof DownloadsImport + parentRoute: typeof rootRoute + } '/login': { id: '/login' path: '/login' @@ -216,6 +230,7 @@ export interface FileRoutesByFullPath { '/': typeof IndexRoute '': typeof AuthRouteWithChildren '/desktop-auth': typeof DesktopAuthRoute + '/downloads': typeof DownloadsRoute '/login': typeof LoginRoute '/password-reset': typeof PasswordResetRouteWithChildren '/pricing': typeof PricingRoute @@ -231,6 +246,7 @@ export interface FileRoutesByTo { '/': typeof IndexRoute '': typeof AuthRouteWithChildren '/desktop-auth': typeof DesktopAuthRoute + '/downloads': typeof DownloadsRoute '/login': typeof LoginRoute '/password-reset': typeof PasswordResetRouteWithChildren '/pricing': typeof PricingRoute @@ -247,6 +263,7 @@ export interface FileRoutesById { '/': typeof IndexRoute '/_auth': typeof AuthRouteWithChildren '/desktop-auth': typeof DesktopAuthRoute + '/downloads': typeof DownloadsRoute '/login': typeof LoginRoute '/password-reset': typeof PasswordResetRouteWithChildren '/pricing': typeof PricingRoute @@ -264,6 +281,7 @@ export interface FileRouteTypes { | '/' | '' | '/desktop-auth' + | '/downloads' | '/login' | '/password-reset' | '/pricing' @@ -278,6 +296,7 @@ export interface FileRouteTypes { | '/' | '' | '/desktop-auth' + | '/downloads' | '/login' | '/password-reset' | '/pricing' @@ -292,6 +311,7 @@ export interface FileRouteTypes { | '/' | '/_auth' | '/desktop-auth' + | '/downloads' | '/login' | '/password-reset' | '/pricing' @@ -308,6 +328,7 @@ export interface RootRouteChildren { IndexRoute: typeof IndexRoute AuthRoute: typeof AuthRouteWithChildren DesktopAuthRoute: typeof DesktopAuthRoute + DownloadsRoute: typeof DownloadsRoute LoginRoute: typeof LoginRoute PasswordResetRoute: typeof PasswordResetRouteWithChildren PricingRoute: typeof PricingRoute @@ -321,6 +342,7 @@ const rootRouteChildren: RootRouteChildren = { IndexRoute: IndexRoute, AuthRoute: AuthRouteWithChildren, DesktopAuthRoute: DesktopAuthRoute, + DownloadsRoute: DownloadsRoute, LoginRoute: LoginRoute, PasswordResetRoute: PasswordResetRouteWithChildren, PricingRoute: PricingRoute, @@ -343,6 +365,7 @@ export const routeTree = rootRoute "/", "/_auth", "/desktop-auth", + "/downloads", "/login", "/password-reset", "/pricing", @@ -364,6 +387,9 @@ export const routeTree = rootRoute "/desktop-auth": { "filePath": "desktop-auth.tsx" }, + "/downloads": { + "filePath": "downloads.tsx" + }, "/login": { "filePath": "login.tsx" }, diff --git a/frontend/src/routes/downloads.tsx b/frontend/src/routes/downloads.tsx new file mode 100644 index 00000000..85d6fac9 --- /dev/null +++ b/frontend/src/routes/downloads.tsx @@ -0,0 +1,202 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { TopNav } from "@/components/TopNav"; +import { FullPageMain } from "@/components/FullPageMain"; +import { MarketingHeader } from "@/components/MarketingHeader"; +import { Monitor, Apple, Terminal, Globe, Smartphone } from "lucide-react"; +import packageJson from "../../package.json"; + +// Get version from package.json +const APP_VERSION = packageJson.version; +const CURRENT_VERSION = `v${APP_VERSION}`; +const BASE_DOWNLOAD_URL = `https://github.com/OpenSecretCloud/Maple/releases/download/${CURRENT_VERSION}`; + +function DownloadPage() { + return ( + <> + + + + Download Maple + + } + subtitle={ +
+

Available for macOS and Ubuntu Linux

+

Access your private AI chat with end-to-end encryption

+
+ } + /> + + {/* Desktop Downloads Section */} +
+

+ Desktop Apps + + A faster, more focused experience for your private AI chat + +

+ +
+
+
+ +
+

macOS

+

+ For Apple Silicon and Intel-based Macs running macOS 11.0 or later. +

+
+ + Download for macOS + +
+ Universal for both Apple Silicon and Intel +
+
+
+ +
+
+ +
+

Linux

+

+ For Ubuntu 24.04+ only. Other Linux distributions are not officially supported. +

+
+ + Download AppImage + + +
+
+
+ +
+

+ Windows version coming soon. In the meantime, you can use the{" "} + + web app + {" "} + for full functionality. +

+

+ Current version: {APP_VERSION} •{" "} + + Release notes + +

+
+
+ + {/* Web Access Section */} +
+
+
+
+

Web Version

+

+ Don't want to download anything? Use Maple directly in your browser with the same + end-to-end encryption. +

+ + + Open Web App + +
+
+
+
+
+
+
+
+
+
+ trymaple.ai +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + {/* Mobile Coming Soon Section */} +
+
+ + Mobile Apps + Coming soon! +
+
+ + + ); +} + +export const Route = createFileRoute("/downloads")({ + component: DownloadPage +}); diff --git a/justfile b/justfile index ccaf716b..814c97b9 100644 --- a/justfile +++ b/justfile @@ -10,6 +10,9 @@ install: dev: cd frontend && bun run dev +build: + cd frontend && bun run build + # Test the frontend (needs local backend running) test: cd tests && bun test