diff --git a/app/api/server/fellowships/route.ts b/app/api/server/fellowships/route.ts new file mode 100644 index 0000000..ddea110 --- /dev/null +++ b/app/api/server/fellowships/route.ts @@ -0,0 +1,8 @@ +//app/api/server/fellowships/route.ts +import { NextResponse } from "next/server"; + +export async function GET() { + const res = await fetch("https://dataforge-qa.onrender.com/Dijkstra/v1/fellowships/"); + const data = await res.json(); + return NextResponse.json(data); +} diff --git a/components/opportunities/featured-fellowship-slider.tsx b/components/opportunities/featured-fellowship-slider.tsx index 4d8da25..0417757 100644 --- a/components/opportunities/featured-fellowship-slider.tsx +++ b/components/opportunities/featured-fellowship-slider.tsx @@ -1,7 +1,6 @@ "use client"; import * as React from "react"; -// import Image from "next/image"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { @@ -33,14 +32,13 @@ import { import { Dialog, DialogContent, - DialogDescription, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; -import { fellowships } from "@/data/fellowship-data"; import { ScrollArea } from "../ui/scroll-area"; import ProjectDetails from "../project-details"; +import { Fellowship } from "@/types"; interface FeaturedFellowshipSliderProps { category?: string; @@ -55,13 +53,16 @@ const fellowshipConfig = { requirements: true, readme: true, }, -} +}; const FeaturedFellowshipSlider = React.forwardRef< CarouselApi, FeaturedFellowshipSliderProps >(({ category = "featured" }, ref) => { const [api, setApi] = React.useState(); + const [fellowships, setFellowships] = React.useState([]); + const [loading, setLoading] = React.useState(true); + const [error, setError] = React.useState(null); React.useEffect(() => { if (api && ref) { @@ -73,13 +74,36 @@ const FeaturedFellowshipSlider = React.forwardRef< } }, [api, ref]); + // Fetch fellowships from Next.js API route + React.useEffect(() => { + const fetchFellowships = async () => { + try { + setLoading(true); + setError(null); + const res = await fetch("/api/server/fellowships"); + + if (!res.ok) throw new Error("Failed to fetch fellowships"); + + const data: Fellowship[] = await res.json(); + setFellowships(data); + } catch (err: any) { + console.error("Error fetching fellowships:", err); + setError(err.message || "Unknown error"); + } finally { + setLoading(false); + } + }; + + fetchFellowships(); + }, []); + // Filter fellowships based on category const filteredFellowships = React.useMemo(() => { if (category === "featured") { - return fellowships.filter((fellowship) => fellowship.featured); + return fellowships.filter((f) => f.featured); } return fellowships.slice(0, 6); - }, [category]); + }, [category, fellowships]); // Calculate days until deadline const getDaysUntilDeadline = (deadlineString: string) => { @@ -94,8 +118,8 @@ const FeaturedFellowshipSlider = React.forwardRef< return `${diffDays} days left`; }; - // Get appropriate highlight icon and color - const getHighlightDetails = (highlight: string | undefined) => { + // Get highlight icon and color + const getHighlightDetails = (highlight?: string) => { switch (highlight) { case "new": return { @@ -130,6 +154,10 @@ const FeaturedFellowshipSlider = React.forwardRef< } }; + if (loading) return

Loading fellowships...

; + if (error) return

Error: {error}

; + if (!filteredFellowships.length) return

No fellowships found.

; + return (
{filteredFellowships.map((fellowship) => { - const highlightDetails = fellowship.highlight - ? getHighlightDetails(fellowship.highlight) - : null; + const highlightDetails = getHighlightDetails(fellowship.highlight); return (
-
- {fellowship.organizationLogo ? ( - // {fellowship.organization} - {fellowship.organization} - ) : ( - - )} -
+ {fellowship.organizationLogo ? ( + {fellowship.organization} + ) : ( + + )}
{highlightDetails && (
+
- - {fellowship.duration} - - - {fellowship.locationType.charAt(0).toUpperCase() + - fellowship.locationType.slice(1)} + {fellowship.duration} + + {fellowship.locationType?.charAt(0).toUpperCase() + fellowship.locationType?.slice(1) || "Unknown"}
- - {fellowship.stipend} - + {fellowship.stipend}
- Deadline:{" "} - {getDaysUntilDeadline( - fellowship.applicationDeadline - )} + Deadline: {getDaysUntilDeadline(fellowship.applicationDeadline)}
- Starts:{" "} - {new Date( - fellowship.startDate - ).toLocaleDateString()} + Starts: {new Date(fellowship.startDate).toLocaleDateString()}
@@ -254,17 +252,11 @@ const FeaturedFellowshipSlider = React.forwardRef< Benefits:

- {fellowship.benefits - .slice(0, 3) - .map((benefit, index) => ( - - {benefit} - - ))} + {fellowship.benefits.slice(0, 3).map((b, i) => ( + + {b} + + ))} {fellowship.benefits.length > 3 && ( +{fellowship.benefits.length - 3} more @@ -273,12 +265,9 @@ const FeaturedFellowshipSlider = React.forwardRef<
+ - @@ -288,7 +277,7 @@ const FeaturedFellowshipSlider = React.forwardRef< - {/* */} + {fellowship.title} @@ -296,7 +285,6 @@ const FeaturedFellowshipSlider = React.forwardRef< - {/* */}