33import { Button } from "@/components/ui/button"
44import { Card , CardContent } from "@/components/ui/card"
55import { Download , Package } from "lucide-react"
6+ import { useEffect , useState } from "react"
67import { useTranslation } from "react-i18next"
8+ import { findAsset , formatBytes , getLatestRelease } from "@/lib/github"
79
8- const downloads = [
10+ const SOURCEFORGE_URL = "https://sourceforge.net/projects/dashai/files/latest/download"
11+
12+ type DownloadEntry = {
13+ id : "mac_intel" | "mac_arm" | "windows"
14+ icon : typeof Package
15+ key : string
16+ defaultPlatform : string
17+ version : string
18+ size : string
19+ defaultFormat : string
20+ link : string
21+ }
22+
23+ const FALLBACK_DOWNLOADS : DownloadEntry [ ] = [
924 {
1025 id : "mac_intel" ,
1126 icon : Package ,
1227 key : "macIntel" ,
1328 defaultPlatform : "macOS Intel processors" ,
14- version : "v0.1.15 " ,
15- size : "487 MB " ,
16- defaultFormat : "binary " ,
17- link : "https://dashai.nyc3.cdn.digitaloceanspaces.com/executables/DashAI-launcher-cpu-x86_64" ,
29+ version : "" ,
30+ size : "" ,
31+ defaultFormat : ".dmg " ,
32+ link : SOURCEFORGE_URL ,
1833 } ,
1934 {
2035 id : "mac_arm" ,
2136 icon : Package ,
2237 key : "macArm" ,
2338 defaultPlatform : "macOS ARM processors" ,
24- version : "v0.1.15 " ,
25- size : "381 MB " ,
26- defaultFormat : "binary " ,
27- link : "https://dashai.nyc3.cdn.digitaloceanspaces.com/executables/DashAI-launcher-cpu-arm64" ,
39+ version : "" ,
40+ size : "" ,
41+ defaultFormat : ".dmg " ,
42+ link : SOURCEFORGE_URL ,
2843 } ,
2944 {
3045 id : "windows" ,
3146 icon : Package ,
3247 key : "windows" ,
3348 defaultPlatform : "Windows" ,
34- version : "v0.1.15 " ,
35- size : "434 MB " ,
49+ version : "" ,
50+ size : "" ,
3651 defaultFormat : ".exe" ,
37- link : "https://dashai.nyc3.cdn.digitaloceanspaces.com/executables/DashAI-launcher-cpu.exe" ,
52+ link : SOURCEFORGE_URL ,
3853 } ,
3954]
4055
@@ -53,6 +68,26 @@ async function trackClick(buttonId: string) {
5368
5469export function DownloadSection ( ) {
5570 const { t } = useTranslation ( )
71+ const [ downloads , setDownloads ] = useState < DownloadEntry [ ] > ( FALLBACK_DOWNLOADS )
72+
73+ useEffect ( ( ) => {
74+ getLatestRelease ( ) . then ( ( release ) => {
75+ if ( ! release ) return
76+ setDownloads (
77+ FALLBACK_DOWNLOADS . map ( ( entry ) => {
78+ const asset = findAsset ( release . assets , entry . id )
79+ if ( ! asset ) return entry
80+ return {
81+ ...entry ,
82+ version : release . tag_name ,
83+ size : formatBytes ( asset . size ) ,
84+ link : asset . browser_download_url ,
85+ }
86+ } )
87+ )
88+ } )
89+ } , [ ] )
90+
5691 return (
5792 < section id = "download" className = "py-24 px-4 bg-secondary/30" >
5893 < div className = "container mx-auto" >
@@ -66,7 +101,7 @@ export function DownloadSection() {
66101 < p className = "text-lg text-muted-foreground max-w-2xl mx-auto leading-relaxed" >
67102 { t ( "download:description" , {
68103 defaultValue :
69- "This early version lets you explore DashAI’ s main features. We appreciate your feedback to help us improve before the official release." ,
104+ "This early version lets you explore DashAI' s main features. We appreciate your feedback to help us improve before the official release." ,
70105 } ) }
71106 </ p >
72107 </ div >
@@ -92,17 +127,19 @@ export function DownloadSection() {
92127 </ div >
93128 < h3 className = "text-xl font-semibold mb-2" > { platform } </ h3 >
94129 < div className = "space-y-1 mb-4" >
95- < p className = "text-sm text-muted-foreground" >
96- { download . version } • { download . size }
97- </ p >
130+ { download . version && (
131+ < p className = "text-sm text-muted-foreground" >
132+ { download . version } • { download . size }
133+ </ p >
134+ ) }
98135 < p className = "text-xs text-muted-foreground font-mono" > { format } </ p >
99136 </ div >
100137 < Button
101138 className = "w-full bg-primary hover:bg-primary/90 text-primary-foreground cursor-pointer"
102139 size = "sm"
103140 asChild
104141 >
105- < a href = { download . link } download onClick = { ( ) => trackClick ( download . id ) } >
142+ < a href = { download . link } onClick = { ( ) => trackClick ( download . id ) } >
106143 < Download className = "mr-2 h-4 w-4" />
107144 { t ( "download:button" , { defaultValue : "Download" } ) }
108145 </ a >
@@ -140,4 +177,4 @@ export function DownloadSection() {
140177 </ div >
141178 </ section >
142179 )
143- }
180+ }
0 commit comments