diff --git a/ui/.env.example b/ui/.env.example
index 57a3ed9..4032dc3 100644
--- a/ui/.env.example
+++ b/ui/.env.example
@@ -1,2 +1,2 @@
-NEXT_PUBLIC_WS_URL=ws://localhost:3001
-NEXT_PUBLIC_API_URL=http://localhost:3001/api
\ No newline at end of file
+NEXT_PUBLIC_WS_URL=ws://localhost:3000
+NEXT_PUBLIC_API_URL=http://localhost:3000/api
\ No newline at end of file
diff --git a/ui/app/api/news/[id]/route.ts b/ui/app/api/news/[id]/route.ts
new file mode 100644
index 0000000..e6295e2
--- /dev/null
+++ b/ui/app/api/news/[id]/route.ts
@@ -0,0 +1,22 @@
+import { NextResponse } from "next/server";
+import fs from "node:fs/promises";
+import path from "node:path";
+import { VALIDATED_ENV } from "../../../../lib/constants";
+
+export async function GET(request: Request, { params }: { params: { id: string } }) {
+ try {
+ console.log(`Fetching news data for id: ${params.id}`);
+ console.log(`API URL: ${VALIDATED_ENV.API_URL}`); // Log the API URL
+
+ const dataDirectory = path.join(process.cwd(), "public", "data");
+ const filePath = path.join(dataDirectory, `${params.id}.json`);
+ const fileContents = await fs.readFile(filePath, "utf8");
+ const newsData = JSON.parse(fileContents);
+
+ return NextResponse.json(newsData);
+ } catch (error) {
+ console.error("Error reading news data:", error);
+ console.log(`WS URL: ${VALIDATED_ENV.WS_URL}`); // Log the WebSocket URL, just as an example
+ return NextResponse.json({ error: "News not found" }, { status: 404 });
+ }
+}
diff --git a/ui/app/api/news/route.ts b/ui/app/api/news/route.ts
new file mode 100644
index 0000000..40cedbc
--- /dev/null
+++ b/ui/app/api/news/route.ts
@@ -0,0 +1,16 @@
+import { NextResponse } from "next/server";
+import fs from "node:fs/promises";
+import path from "node:path";
+
+export async function GET() {
+ try {
+ const dataDirectory = path.join(process.cwd(), "public", "data");
+ const filePath = path.join(dataDirectory, "index.json");
+ const fileContents = await fs.readFile(filePath, "utf8");
+ const data = JSON.parse(fileContents);
+ return NextResponse.json(data);
+ } catch (error) {
+ console.error("Error reading news data:", error);
+ return NextResponse.json({ error: "Failed to load news data" }, { status: 500 });
+ }
+}
diff --git a/ui/app/news/[id]/layout.tsx b/ui/app/news/[id]/layout.tsx
index 4131370..5eecd46 100644
--- a/ui/app/news/[id]/layout.tsx
+++ b/ui/app/news/[id]/layout.tsx
@@ -1,17 +1,15 @@
-import Link from "next/link";
-import { ArrowLeft } from "lucide-react";
+import { Metadata } from "next";
+import React from "react";
+import { ENV, assertEnvVariables } from "../../../lib/constants";
-export default function NewsDetailLayout({ children }: { children: React.ReactNode }) {
- return (
-
-
-
- Back
-
- {children}
-
- );
-}
+export const metadata: Metadata = {
+ title: "News - Perplexica",
+};
+
+assertEnvVariables(ENV);
+
+const Layout = ({ children }: { children: React.ReactNode }) => {
+ return {children}
;
+};
+
+export default Layout;
diff --git a/ui/app/news/[id]/page.tsx b/ui/app/news/[id]/page.tsx
index b9b0a3c..a2fbfcc 100644
--- a/ui/app/news/[id]/page.tsx
+++ b/ui/app/news/[id]/page.tsx
@@ -1,11 +1,19 @@
-import { fetchNewsData } from "../../../lib/fetchNewsData";
import NewsDetail from "../../../components/NewsDetail";
+import { VALIDATED_ENV } from "../../../lib/constants";
+
+async function getNewsData(id: string) {
+ const res = await fetch(`${VALIDATED_ENV.API_URL}/news/${id}`, { next: { revalidate: 60 } });
+ if (!res.ok) {
+ throw new Error("Failed to fetch news");
+ }
+ return res.json();
+}
export default async function NewsPage({ params }: { params: { id: string } }) {
- const newsData = await fetchNewsData(params.id);
+ const newsData = await getNewsData(params.id);
if (!newsData) {
- return News not found
;
+ return News not found or failed to load
;
}
return ;
diff --git a/ui/components/ContextItem.tsx b/ui/components/ContextItem.tsx
index 87dfed4..03f25b1 100644
--- a/ui/components/ContextItem.tsx
+++ b/ui/components/ContextItem.tsx
@@ -7,7 +7,14 @@ interface ContextItemProperties {
name: string;
url: string;
description: string;
- provider: { name: string; image?: { thumbnail: { contentUrl: string } } }[];
+ provider: {
+ name: string;
+ image?: {
+ thumbnail: {
+ contentUrl: string;
+ };
+ };
+ }[];
datePublished: string;
image?: {
contentUrl: string;
@@ -32,11 +39,30 @@ const ContextItem: React.FC = ({ item }) => {
-
+
Read more
-
- {item.provider[0].name} | {new Date(item.datePublished).toLocaleDateString()}
+
+
+ {item.provider[0].image && (
+
+ )}
+ {item.provider[0].name}
+
+
+ {new Date(item.datePublished).toLocaleDateString()}
+
);
diff --git a/ui/components/NewsPage.tsx b/ui/components/NewsPage.tsx
index 62072c2..b39551b 100644
--- a/ui/components/NewsPage.tsx
+++ b/ui/components/NewsPage.tsx
@@ -19,9 +19,7 @@ const NewsPage = () => {
const fetchNews = async () => {
try {
console.log("Fetching news...");
- const response = await fetch(
- "https://raw.githubusercontent.com/newspedia-crew/newspedia-web/intern-change/public/data/index.json",
- );
+ const response = await fetch("/api/news");
console.log("Response status:", response.status);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
diff --git a/ui/lib/constants.ts b/ui/lib/constants.ts
new file mode 100644
index 0000000..d038f2a
--- /dev/null
+++ b/ui/lib/constants.ts
@@ -0,0 +1,19 @@
+export const ENV = {
+ WS_URL: process.env.NEXT_PUBLIC_WS_URL || "ws://localhost:3000",
+ API_URL: process.env.NEXT_PUBLIC_API_URL || "http://localhost:3000/api",
+} as const;
+
+export type ENV = typeof ENV;
+
+// Type guard function
+export function assertEnvVariables(ENV: ENV): asserts ENV is Required {
+ const missingVariables = Object.entries(ENV).filter(([_, value]) => value === undefined);
+ if (missingVariables.length > 0) {
+ console.warn(`Warning: Missing environment variables: ${missingVariables.map(([key]) => key).join(", ")}`);
+ console.warn("Using default values for missing variables.");
+ }
+}
+
+assertEnvVariables(ENV);
+
+export const VALIDATED_ENV: Required = ENV as Required;
diff --git a/ui/lib/fetchNewsData.ts b/ui/lib/fetchNewsData.ts
deleted file mode 100644
index b5568f8..0000000
--- a/ui/lib/fetchNewsData.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-export async function fetchNewsData(id: string) {
- const response = await fetch(
- `https://raw.githubusercontent.com/newspedia-crew/newspedia-web/intern-change/public/data/${id}.json`,
- );
- if (!response.ok) {
- return null;
- }
- return response.json();
-}
diff --git a/public/data/1fa9b398-080f-54de-9a4f-3ba386acce11.json b/ui/public/data/1fa9b398-080f-54de-9a4f-3ba386acce11.json
similarity index 100%
rename from public/data/1fa9b398-080f-54de-9a4f-3ba386acce11.json
rename to ui/public/data/1fa9b398-080f-54de-9a4f-3ba386acce11.json
diff --git a/public/data/73090b7b-a04e-5c50-ae84-c77f1d7d03a8.json b/ui/public/data/73090b7b-a04e-5c50-ae84-c77f1d7d03a8.json
similarity index 100%
rename from public/data/73090b7b-a04e-5c50-ae84-c77f1d7d03a8.json
rename to ui/public/data/73090b7b-a04e-5c50-ae84-c77f1d7d03a8.json
diff --git a/public/data/869d933c-e186-51b0-a225-edc2d338b6fa.json b/ui/public/data/869d933c-e186-51b0-a225-edc2d338b6fa.json
similarity index 100%
rename from public/data/869d933c-e186-51b0-a225-edc2d338b6fa.json
rename to ui/public/data/869d933c-e186-51b0-a225-edc2d338b6fa.json
diff --git a/public/data/b84c7962-2971-53de-a99b-3c9e45492c79.json b/ui/public/data/b84c7962-2971-53de-a99b-3c9e45492c79.json
similarity index 100%
rename from public/data/b84c7962-2971-53de-a99b-3c9e45492c79.json
rename to ui/public/data/b84c7962-2971-53de-a99b-3c9e45492c79.json
diff --git a/public/data/ed701716-e443-5804-aaa9-99e7e04c33e2.json b/ui/public/data/ed701716-e443-5804-aaa9-99e7e04c33e2.json
similarity index 100%
rename from public/data/ed701716-e443-5804-aaa9-99e7e04c33e2.json
rename to ui/public/data/ed701716-e443-5804-aaa9-99e7e04c33e2.json
diff --git a/public/data/fd20973f-54b2-5b15-bf7b-79b5e5515b5c.json b/ui/public/data/fd20973f-54b2-5b15-bf7b-79b5e5515b5c.json
similarity index 100%
rename from public/data/fd20973f-54b2-5b15-bf7b-79b5e5515b5c.json
rename to ui/public/data/fd20973f-54b2-5b15-bf7b-79b5e5515b5c.json
diff --git a/public/data/index.json b/ui/public/data/index.json
similarity index 100%
rename from public/data/index.json
rename to ui/public/data/index.json