diff --git a/src/app/dashboard/page.tsx b/src/app/dashboard/page.tsx index 947e1f6..bfddc4e 100644 --- a/src/app/dashboard/page.tsx +++ b/src/app/dashboard/page.tsx @@ -1,6 +1,7 @@ 'use client' import { useEffect, useState, useCallback, useRef } from 'react' +import Link from 'next/link' import { useRouter } from 'next/navigation' import useAuthStore from '../store/authStore' import PageLayout from '../components/PageLayout' @@ -21,6 +22,9 @@ export default function DashboardPage() { const isAuthReady = useAuthStore(state => state.isAuthReady) const isShopEnabled = process.env.NEXT_PUBLIC_SHOW_SHOP !== 'false' const [isMobile, setIsMobile] = useState(false) + const [latestNews, setLatestNews] = useState>([]) + const [newsLoading, setNewsLoading] = useState(false) + const [newsError, setNewsError] = useState(null) const { userStatus, loading: statusLoading } = useUserStatus() @@ -46,6 +50,27 @@ export default function DashboardPage() { } }, []) + useEffect(() => { + let active = true + ;(async () => { + setNewsLoading(true) + setNewsError(null) + try { + const BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL || 'http://localhost:3001' + const res = await fetch(`${BASE_URL}/api/news/active`) + if (!res.ok) throw new Error('Failed to fetch news') + const json = await res.json() + const data = Array.isArray(json.data) ? json.data : [] + if (active) setLatestNews(data.slice(0, 3)) + } catch (e: any) { + if (active) setNewsError(e?.message || 'Failed to load news') + } finally { + if (active) setNewsLoading(false) + } + })() + return () => { active = false } + }, []) + // Redirect if not logged in (only after auth is ready) useEffect(() => { if (isAuthReady && !user) { @@ -231,6 +256,57 @@ export default function DashboardPage() { + + {/* Latest News */} +
+
+

Latest News

+ + View all + +
+ + {newsLoading && ( +
+ {Array.from({ length: 3 }).map((_, i) => ( +
+
+
+
+ ))} +
+ )} + + {newsError && !newsLoading && ( +
{newsError}
+ )} + + {!newsLoading && !newsError && latestNews.length === 0 && ( +
No news yet.
+ )} + + {!newsLoading && !newsError && latestNews.length > 0 && ( +
    + {latestNews.map(item => ( +
  • + +
    + {item.published_at ? new Date(item.published_at).toLocaleDateString('de-DE') : 'Recent'} +
    +
    + {item.title} +
    + {item.summary && ( +
    + {item.summary} +
    + )} + +
  • + ))} +
+ )} +
diff --git a/src/app/quickaction-dashboard/page.tsx b/src/app/quickaction-dashboard/page.tsx index af7394c..dc5729f 100644 --- a/src/app/quickaction-dashboard/page.tsx +++ b/src/app/quickaction-dashboard/page.tsx @@ -1,6 +1,7 @@ 'use client' import { useState, useCallback, useEffect, useRef } from 'react' +import Link from 'next/link' import { useRouter } from 'next/navigation' import PageLayout from '../components/PageLayout' import TutorialModal, { createTutorialSteps } from '../components/TutorialModal' @@ -28,6 +29,16 @@ interface StatusItem { icon: React.ComponentType> } +type LatestNewsItem = { + id: number + title: string + summary?: string + slug: string + category?: string + imageUrl?: string + published_at?: string | null +} + export default function QuickActionDashboardPage() { const router = useRouter() const user = useAuthStore(s => s.user) @@ -35,6 +46,9 @@ export default function QuickActionDashboardPage() { const accessToken = useAuthStore(s => s.accessToken) // NEW const { userStatus, loading, error, refreshStatus } = useUserStatus() const [isClient, setIsClient] = useState(false) + const [latestNews, setLatestNews] = useState([]) + const [newsLoading, setNewsLoading] = useState(false) + const [newsError, setNewsError] = useState(null) // Tutorial state const [isTutorialOpen, setIsTutorialOpen] = useState(false) @@ -49,6 +63,27 @@ export default function QuickActionDashboardPage() { setHasSeenTutorial(!!tutorialSeen) }, []) + useEffect(() => { + let active = true + ;(async () => { + setNewsLoading(true) + setNewsError(null) + try { + const BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL || 'http://localhost:3001' + const res = await fetch(`${BASE_URL}/api/news/active`) + if (!res.ok) throw new Error('Failed to fetch news') + const json = await res.json() + const data = Array.isArray(json.data) ? json.data : [] + if (active) setLatestNews(data.slice(0, 3)) + } catch (e: any) { + if (active) setNewsError(e?.message || 'Failed to load news') + } finally { + if (active) setNewsLoading(false) + } + })() + return () => { active = false } + }, []) + // Derive status from real backend data const emailVerified = userStatus?.email_verified || false const idUploaded = userStatus?.documents_uploaded || false @@ -458,18 +493,55 @@ export default function QuickActionDashboardPage() { {/* Latest News */}
-

- Latest News -

-
    -
  • - New: Referral system - launch – invite friends and earn rewards. -
  • -
  • - Profile completion unlocks more features. Keep progressing! -
  • -
+
+

+ Latest News +

+ + View all + +
+ + {newsLoading && ( +
+ {Array.from({ length: 3 }).map((_, i) => ( +
+
+
+
+ ))} +
+ )} + + {newsError && !newsLoading && ( +
{newsError}
+ )} + + {!newsLoading && !newsError && latestNews.length === 0 && ( +
No news yet.
+ )} + + {!newsLoading && !newsError && latestNews.length > 0 && ( +
    + {latestNews.map(item => ( +
  • + +
    + {item.published_at ? new Date(item.published_at).toLocaleDateString('de-DE') : 'Recent'} +
    +
    + {item.title} +
    + {item.summary && ( +
    + {item.summary} +
    + )} + +
  • + ))} +
+ )}