feat: Add @radix-ui/react-tabs npm dependency and update header.tsx to include a download link

This commit is contained in:
Mauro Balades 2024-07-03 19:58:38 +02:00
parent acebd412e7
commit 80fa3d1842
7 changed files with 230 additions and 3 deletions

60
package-lock.json generated
View file

@ -10,6 +10,7 @@
"dependencies": {
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-navigation-menu": "^1.2.0",
"@radix-ui/react-tabs": "^1.1.0",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"cobe": "^0.6.3",
@ -2966,6 +2967,36 @@
}
}
},
"node_modules/@radix-ui/react-roving-focus": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.0.tgz",
"integrity": "sha512-EA6AMGeq9AEeQDeSH0aZgG198qkfHSbvWTf1HvoDmOB5bBG/qTxjYMWUKMnYiV6J/iP/J8MEFSuB2zRU2n7ODA==",
"dependencies": {
"@radix-ui/primitive": "1.1.0",
"@radix-ui/react-collection": "1.1.0",
"@radix-ui/react-compose-refs": "1.1.0",
"@radix-ui/react-context": "1.1.0",
"@radix-ui/react-direction": "1.1.0",
"@radix-ui/react-id": "1.1.0",
"@radix-ui/react-primitive": "2.0.0",
"@radix-ui/react-use-callback-ref": "1.1.0",
"@radix-ui/react-use-controllable-state": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-slot": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz",
@ -2983,6 +3014,35 @@
}
}
},
"node_modules/@radix-ui/react-tabs": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.0.tgz",
"integrity": "sha512-bZgOKB/LtZIij75FSuPzyEti/XBhJH52ExgtdVqjCIh+Nx/FW+LhnbXtbCzIi34ccyMsyOja8T0thCzoHFXNKA==",
"dependencies": {
"@radix-ui/primitive": "1.1.0",
"@radix-ui/react-context": "1.1.0",
"@radix-ui/react-direction": "1.1.0",
"@radix-ui/react-id": "1.1.0",
"@radix-ui/react-presence": "1.1.0",
"@radix-ui/react-primitive": "2.0.0",
"@radix-ui/react-roving-focus": "1.1.0",
"@radix-ui/react-use-controllable-state": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-use-callback-ref": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz",

View file

@ -11,6 +11,7 @@
"dependencies": {
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-navigation-menu": "^1.2.0",
"@radix-ui/react-tabs": "^1.1.0",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"cobe": "^0.6.3",

14
src/app/download/page.tsx Normal file
View file

@ -0,0 +1,14 @@
import DownloadPage from "@/components/download";
import Footer from "@/components/footer";
import { Navigation } from "@/components/navigation";
export default function Download() {
return (
<main className="flex min-h-screen flex-col items-center justify-start">
<DownloadPage />
<Footer />
<Navigation /> {/* At the bottom of the page */}
</main>
);
}

View file

@ -0,0 +1,95 @@
"use client";
import { ny } from "@/lib/utils";
import GridPattern from "./ui/grid-pattern";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "./ui/tabs";
import { DownloadCloudIcon, DownloadIcon } from "lucide-react";
const BASE_URL = "https://github.com/zen-browser/desktop/releases/download/latest";
const releases: any = {
Windows: [
"zen.win64.zip",
],
//MacOS: [],
Linux: [
"zen.linux.tar.bz2",
],
};
function getDefaultPlatformBasedOnUserAgent() {
const userAgent = navigator.userAgent;
if (userAgent.includes("Win")) {
return "Windows";
}
if (userAgent.includes("Mac")) {
return "MacOS";
}
if (userAgent.includes("Linux")) {
return "Linux";
}
return "Windows";
}
export default function DownloadPage() {
return (
<div className="w-full relative h-screen flex items-center justify-center">
<div className="w-1/2 relative h-full px-64 flex items-cetner justify-center flex-col">
<GridPattern
numSquares={30}
maxOpacity={0.5}
height={50}
width={50}
duration={3}
repeatDelay={1}
x={-1}
y={-1}
strokeDasharray="4 2"
className={ny(
'[mask-image:radial-gradient(350px_circle_at_center,white,transparent)]',
'w-full z-0',
)}
/>
<h1 className="!text-4xl font-bold tracking-[-0.02em] text-black dark:text-white md:text-7xl md:leading-[5rem]">
Download Zen Browser
</h1>
<p className="!text-md text-muted-foreground !font-medium">
Get started with Zen Browser today. Get back to browsing the web with peace of mind.
</p>
</div>
<div className="w-1/2 relative flex items-cetner justify-start">
<Tabs defaultValue={getDefaultPlatformBasedOnUserAgent()} className="mx-auto w-fit flex flex-col items-start justify-center">
<TabsList>
{Object.keys(releases).map((platform) => (
<TabsTrigger key={platform} value={platform}>{platform}</TabsTrigger>
))}
</TabsList>
{Object.keys(releases).map((platform) => (
<TabsContent key={platform} value={platform} className="border rounded-md p-5 border-gray">
<table>
<thead className="">
<tr>
<th className="text-start pb-4 min-w-64">File</th>
<th className="text-start pb-4">Download</th>
</tr>
</thead>
<tbody>
{releases[platform].map((release: string) => (
<tr key={release} className="relative w-full">
<td className="min-w-64">{release}</td>
<td className="flex items-center w-full justify-center">
<a href={`${BASE_URL}/${release}`} className="text-blue-500">
<DownloadIcon size={24} />
</a>
</td>
</tr>
))}
</tbody>
</table>
</TabsContent>
))}
</Tabs>
</div>
</div>
);
}

View file

@ -26,7 +26,8 @@ export default function Header() {
'w-full z-0',
)}
/>
<div className="z-10 flex mb-10 items-center justify-center">
<div className="z-10 flex mb-10 items-center justify-center">
<a href="/download">
<AnimatedGradientText>
🎉
{' '}
@ -41,6 +42,7 @@ export default function Header() {
</span>
<ChevronRight className="ml-1 size-3 transition-transform duration-300 ease-in-out group-hover:translate-x-0.5" />
</AnimatedGradientText>
</a>
</div>
<WordPullUp
className="text-3xl font-bold tracking-[-0.02em] text-black dark:text-white md:text-7xl md:leading-[5rem]"
@ -58,7 +60,7 @@ export default function Header() {
framerProps={{
show: { transition: { delay: 0.2 } },
}}
text="Fade Up"
text="Documentation"
/>
</a>
<ShinyButton text="Download now" />

View file

@ -30,7 +30,7 @@ const components: { title: string; href: string; description: string }[] = [
export function Navigation() {
return (
<div className="absolute z-10 top-0 left-0 w-full flex fixed border-b border-grey p-2 items-center justify-center">
<div className="backdrop-blur fixed z-10 top-0 left-0 w-full flex fixed border-b border-grey p-2 items-center justify-center">
<NavigationMenu>
<NavigationMenuList>
<NavigationMenuItem>

View file

@ -0,0 +1,55 @@
'use client'
import * as React from 'react'
import * as TabsPrimitive from '@radix-ui/react-tabs'
import { ny } from '@/lib/utils'
const Tabs = TabsPrimitive.Root
const TabsList = React.forwardRef<
React.ElementRef<typeof TabsPrimitive.List>,
React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>
>(({ className, ...props }, ref) => (
<TabsPrimitive.List
ref={ref}
className={ny(
'inline-flex h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground',
className,
)}
{...props}
/>
))
TabsList.displayName = TabsPrimitive.List.displayName
const TabsTrigger = React.forwardRef<
React.ElementRef<typeof TabsPrimitive.Trigger>,
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>
>(({ className, ...props }, ref) => (
<TabsPrimitive.Trigger
ref={ref}
className={ny(
'inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow',
className,
)}
{...props}
/>
))
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName
const TabsContent = React.forwardRef<
React.ElementRef<typeof TabsPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>
>(({ className, ...props }, ref) => (
<TabsPrimitive.Content
ref={ref}
className={ny(
'mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',
className,
)}
{...props}
/>
))
TabsContent.displayName = TabsPrimitive.Content.displayName
export { Tabs, TabsList, TabsTrigger, TabsContent }