Skip to content

Commit

Permalink
Merge pull request #303 from bounswe/feature/FE-news-page
Browse files Browse the repository at this point in the history
Add news page skeleton
  • Loading branch information
hikasap authored Oct 20, 2024
2 parents 12d5bc6 + 042bd7e commit c338f67
Show file tree
Hide file tree
Showing 7 changed files with 489 additions and 28 deletions.
2 changes: 1 addition & 1 deletion frontend/src/App.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import './App.css';
import { BrowserRouter as Router, Route, Routes, Link } from 'react-router-dom';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import Login from "./components/Login.js";
import Dashboard from "./components/Dashboard.js";
import NewsPage from './components/news/NewsPage.js';
Expand Down
27 changes: 27 additions & 0 deletions frontend/src/components/news/FilterButtons.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// FilterButtons.js
import React from 'react';
import PropTypes from 'prop-types';

const FilterButtons = ({ categories, setSelectedCategory, selectedCategory }) => {
return (
<div className="filter-buttons">
{categories.map((category) => (
<button
key={category}
onClick={() => setSelectedCategory(category)}
className={`filter-button ${selectedCategory === category ? 'selected' : ''}`}
>
{category}
</button>
))}
</div>
);
};

FilterButtons.propTypes = {
categories: PropTypes.array.isRequired,
setSelectedCategory: PropTypes.func.isRequired,
selectedCategory: PropTypes.string.isRequired, // Pass selectedCategory as a prop
};

export default FilterButtons;
27 changes: 27 additions & 0 deletions frontend/src/components/news/NewsCard.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from 'react';
import '../../styles/News.css';

const NewsCard = ({ news }) => {
return (
<div className="card" onClick={() => window.open(news.rssUrl, '_blank')}>
<div className="card-header">
<span className="card-source">{news.source}</span>
<span className="card-time">{news.publishedAt}</span>
</div>
<div className="card-body">
<div className="card-text">
<h3 className="card-title">{news.title}</h3>
<p className="card-description">{news.description}</p>
</div>
{news.coverImageUrl && (
<div className="card-icon">
<img src={news.coverImageUrl} alt={news.source} />
</div>
)}
</div>
</div>

);
};

export default NewsCard;
148 changes: 142 additions & 6 deletions frontend/src/components/news/NewsPage.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,149 @@
import React from 'react';
import React, { useEffect, useState } from 'react';
import NewsCard from './NewsCard';
import FilterButtons from './FilterButtons';
import '../../styles/News.css';

const mockNewsData = [
{
id: 1,
title: "GDP Growth Forecasts Revised",
description: "Recent reports indicate that GDP growth forecasts for major economies have been revised upwards.",
rssUrl: "https://example.com/news1",
category: "Global Economy",
publishedAt: "2 hours ago",
coverImageUrl: "https://www.thisiscolossal.com/wp-content/uploads/2024/10/jonk-1.jpg",
source: "Economic Times",
},
{
id: 2,
title: "Major Indices Reach All-Time Highs",
description: "The stock market sees a significant uptick as major indices reach all-time highs.",
rssUrl: "https://example.com/news2",
category: "Stock Market",
publishedAt: "3 hours ago",
// coverImageUrl: "https://example.com/images/news2.jpg",
source: "Market Watch",
},
{
id: 3,
title: "Bitcoin Surges Past $60,000",
description: "Bitcoin's value has surged past $60,000 amid increased institutional adoption.",
rssUrl: "https://example.com/news3",
category: "Cryptocurrency",
publishedAt: "1 hour ago",
// coverImageUrl: "https://example.com/images/news3.jpg",
source: "CoinDesk",
},
{
id: 4,
title: "Rising Costs Impact Consumers",
description: "Inflation rates are rising, leading to increased costs for consumers on everyday goods.",
rssUrl: "https://example.com/news4",
category: "Inflation",
publishedAt: "4 hours ago",
// coverImageUrl: "https://example.com/images/news4.jpg",
source: "Bloomberg",
},
{
id: 5,
title: "Unemployment Rates Hit Record Low",
description: "The job market strengthens as unemployment rates hit a record low across the nation.",
rssUrl: "https://example.com/news5",
category: "Job Market",
publishedAt: "5 hours ago",
coverImageUrl: "https://1finance.co.in/magazine/wp-content/uploads/2024/01/Blog-5-b-scaled.jpg",
source: "The Wall Street Journal",
},
];

// Mock data for RSS feeds
const mockRssFeedData = [
{
id: 6,
title: "New Agreements Boost International Trade",
description: "New trade agreements are set to boost international trade among participating countries.",
rssUrl: "https://example.com/news6",
category: "Trade",
publishedAt: "3 days ago",
// coverImageUrl: "https://example.com/images/news6.jpg",
source: "Reuters",
},
{
id: 7,
title: "Emerging Markets on the Rise",
description: "Emerging markets are gaining traction as investors look for new opportunities.",
rssUrl: "https://example.com/news7",
category: "Market Trends",
publishedAt: "2 days ago",
// coverImageUrl: "https://example.com/images/news7.jpg",
source: "Forbes",
},
{
id: 8,
title: "Interest Rates Held Steady",
description: "The Federal Reserve has announced that interest rates will remain steady for the foreseeable future.",
rssUrl: "https://example.com/news8",
category: "Federal Reserve",
publishedAt: "1 day ago",
// coverImageUrl: "https://example.com/images/news8.jpg",
source: "CNBC",
},
];


const NewsPage = () => {
const [newsData, setNewsData] = useState([]);
const [rssNewsData, setRssNewsData] = useState([]);
const all = 'All';
const [selectedCategory, setSelectedCategory] = useState(all);
const [selectedRssCategory, setSelectedRssCategory] = useState(all);

useEffect(() => {
setNewsData(mockNewsData);
setRssNewsData(mockRssFeedData);
}, []);

const newsCategories = [all, ...new Set(mockNewsData.map(news => news.category))];
const rssCategories = [all, ...new Set(mockRssFeedData.map(news => news.category))];

const filteredNews = newsData.filter((news) =>
selectedCategory === all ? true : news.category === selectedCategory
);

const filteredRssNews = rssNewsData.filter((news) =>
selectedRssCategory === all ? true : news.category === selectedRssCategory
);

return (
<div>
<h1>News Page</h1>
<p>News goes here</p>
<div className="news-page">
<div className="news-header">
<h1 className="news-title">Economic News</h1>
<h2 className="news-subtitle">Your daily updates on economic trends</h2>
</div>

<div className="news-content">
<h3 className="section-title">Mock Economic News Section</h3>
<div className="filter-buttons">
<FilterButtons categories={newsCategories} setSelectedCategory={setSelectedCategory} selectedCategory={selectedCategory} />
</div>
<div className="scrollable-section">
{filteredNews.map((news) => (
<NewsCard key={news.id} news={news} />
))}
</div>

<h3 className="section-title">Mock RSS Feed Economic News Section</h3>
<div className="filter-buttons">
<FilterButtons categories={rssCategories} setSelectedCategory={setSelectedRssCategory} selectedCategory={selectedRssCategory} />
</div>
<div className="scrollable-section">
{filteredRssNews.map((news) => (
<NewsCard key={news.id} news={news} />
))}
</div>
</div>
</div>
);
}
};

export default NewsPage;

110 changes: 110 additions & 0 deletions frontend/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,113 @@ html, body, #root {
padding: 0;
}


:root {
/* Primary colors */
--color-primary-100: #e3f2fd;
--color-primary-200: #bbdefb;
--color-primary-300: #90caf9;
--color-primary-400: #64b5f6;
--color-primary-500: #42a5f5;
--color-primary-600: #1e88e5;
--color-primary-700: #1976d2;
--color-primary-800: #1565c0;
--color-primary-900: #0d47a1;

/* Secondary colors */
--color-secondary-100: #e1f5fe;
--color-secondary-200: #b3e5fc;
--color-secondary-300: #81d4fa;
--color-secondary-400: #4fc3f7;
--color-secondary-500: #29b6f6;
--color-secondary-600: #039be5;
--color-secondary-700: #0288d1;
--color-secondary-800: #0277bd;
--color-secondary-900: #01579b;

/* Accent colors */
--color-accent-100: #f1f8e9;
--color-accent-200: #dcedc8;
--color-accent-300: #c5e1a5;
--color-accent-400: #aed581;
--color-accent-500: #8bc34a;
--color-accent-600: #7cb342;
--color-accent-700: #689f38;
--color-accent-800: #558b2f;
--color-accent-900: #33691e;

/* Neutral colors */
--color-neutral-100: #fafafa;
--color-neutral-200: #f5f5f5;
--color-neutral-300: #eeeeee;
--color-neutral-400: #e0e0e0;
--color-neutral-500: #bdbdbd;
--color-neutral-600: #9e9e9e;
--color-neutral-700: #757575;
--color-neutral-800: #616161;
--color-neutral-900: #424242;
--color-neutral-black: #212121;
--color-neutral-white: #ffffff;

/* Error colors */
--color-error-100: #ffebee;
--color-error-200: #ffcdd2;
--color-error-300: #ef9a9a;
--color-error-400: #e57373;
--color-error-500: #f44336;
--color-error-600: #e53935;
--color-error-700: #d32f2f;
--color-error-800: #c62828;
--color-error-900: #b71c1c;

/* Success colors */
--color-success-100: #e8f5e9;
--color-success-200: #c8e6c9;
--color-success-300: #a5d6a7;
--color-success-400: #81c784;
--color-success-500: #4caf50;
--color-success-600: #43a047;
--color-success-700: #388e3c;
--color-success-800: #2e7d32;
--color-success-900: #1b5e20;

/* Info colors */
--color-info-100: #e3f2fd;
--color-info-200: #bbdefb;
--color-info-300: #90caf9;
--color-info-400: #64b5f6;
--color-info-500: #42a5f5;
--color-info-600: #1e88e5;
--color-info-700: #1976d2;
--color-info-800: #1565c0;
--color-info-900: #0d47a1;

/* Warm colors */
--color-warm-100: #fffde7;
--color-warm-200: #fff9c4;
--color-warm-300: #fff59d;
--color-warm-400: #fff176;
--color-warm-500: #ffeb3b;
--color-warm-600: #fdd835;
--color-warm-700: #fbc02d;
--color-warm-800: #f9a825;
--color-warm-900: #f57f17;

/* Shadows */
--shadow-light: rgba(0, 0, 0, 0.1);
--shadow-medium: rgba(0, 0, 0, 0.3);
--shadow-dark: rgba(0, 0, 0, 0.6);

/* Borders */
--border-light: #e0e0e0;
--border-medium: #9e9e9e;
--border-dark: #424242;

/* Gradients */
--primary-gradient: linear-gradient(45deg, #42a5f5, #1e88e5);
--secondary-gradient: linear-gradient(45deg, #29b6f6, #0288d1);
--accent-gradient: linear-gradient(45deg, #8bc34a, #558b2f);
--info-gradient: linear-gradient(45deg, #64b5f6, #42a5f5);
--error-gradient: linear-gradient(45deg, #f44336, #d32f2f);
--success-gradient: linear-gradient(45deg, #4caf50, #388e3c);
}
Loading

0 comments on commit c338f67

Please sign in to comment.