From 78c4f6bb32657127d73ab1990285856a738e98d0 Mon Sep 17 00:00:00 2001 From: halil Date: Sat, 19 Oct 2024 23:21:30 +0300 Subject: [PATCH 1/4] fix: remove unused import resolve warning in startup --- frontend/src/App.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/App.js b/frontend/src/App.js index cecbfb60..cb38beee 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -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'; From bc888a8089975338cd0481f64aa18b3b6278285c Mon Sep 17 00:00:00 2001 From: halil Date: Sat, 19 Oct 2024 23:50:48 +0300 Subject: [PATCH 2/4] feat: add news page component alongside news page, we also add news card and filter button components that used in news page. --- frontend/src/components/news/FilterButtons.js | 27 +++ frontend/src/components/news/NewsCard.js | 27 +++ frontend/src/components/news/NewsPage.js | 155 +++++++++++++++- frontend/src/styles/News.css | 171 ++++++++++++++++++ 4 files changed, 374 insertions(+), 6 deletions(-) create mode 100644 frontend/src/components/news/FilterButtons.js create mode 100644 frontend/src/components/news/NewsCard.js create mode 100644 frontend/src/styles/News.css diff --git a/frontend/src/components/news/FilterButtons.js b/frontend/src/components/news/FilterButtons.js new file mode 100644 index 00000000..31620b81 --- /dev/null +++ b/frontend/src/components/news/FilterButtons.js @@ -0,0 +1,27 @@ +// FilterButtons.js +import React from 'react'; +import PropTypes from 'prop-types'; + +const FilterButtons = ({ categories, setSelectedCategory, selectedCategory }) => { + return ( +
+ {categories.map((category) => ( + + ))} +
+ ); +}; + +FilterButtons.propTypes = { + categories: PropTypes.array.isRequired, + setSelectedCategory: PropTypes.func.isRequired, + selectedCategory: PropTypes.string.isRequired, // Pass selectedCategory as a prop +}; + +export default FilterButtons; diff --git a/frontend/src/components/news/NewsCard.js b/frontend/src/components/news/NewsCard.js new file mode 100644 index 00000000..d010fc1a --- /dev/null +++ b/frontend/src/components/news/NewsCard.js @@ -0,0 +1,27 @@ +import React from 'react'; +import '../../styles/News.css'; + +const NewsCard = ({ news }) => { + return ( +
window.open(news.rssUrl, '_blank')}> +
+ {news.source} + {news.publishedAt} +
+
+
+

{news.title}

+

{news.description}

+
+ {news.coverImageUrl && ( +
+ {news.source} +
+ )} +
+
+ + ); +}; + +export default NewsCard; diff --git a/frontend/src/components/news/NewsPage.js b/frontend/src/components/news/NewsPage.js index 978a359d..57055ebe 100644 --- a/frontend/src/components/news/NewsPage.js +++ b/frontend/src/components/news/NewsPage.js @@ -1,13 +1,156 @@ -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", // Time ago + coverImageUrl: "https://www.thisiscolossal.com/wp-content/uploads/2024/10/jonk-1.jpg", + source: "Economic Times", // Publishing source name + }, + { + 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'; + // Separate category states for both sections + const [selectedCategory, setSelectedCategory] = useState(all); + const [selectedRssCategory, setSelectedRssCategory] = useState(all); + + useEffect(() => { + // Set mock news data + setNewsData(mockNewsData); + setRssNewsData(mockRssFeedData); + }, []); + + // Extract unique categories for mock news and RSS feed news + const newsCategories = [all, ...new Set(mockNewsData.map(news => news.category))]; + const rssCategories = [all, ...new Set(mockRssFeedData.map(news => news.category))]; + + // Filter logic for the first news section + const filteredNews = newsData.filter((news) => + selectedCategory === all ? true : news.category === selectedCategory + ); + + // Filter logic for the RSS feed news section + const filteredRssNews = rssNewsData.filter((news) => + selectedRssCategory === all ? true : news.category === selectedRssCategory + ); + return ( -
-

News Page

-

News goes here

+
+
+

Economic News

+

Your daily updates on economic trends

+
+ +
+ {/* Filter Buttons for Mock News Section */} +

Mock Economic News Section

+
+ +
+
+ {filteredNews.map((news) => ( + + ))} +
+ + {/* Filter Buttons for Mock RSS Feed News Section */} +

Mock RSS Feed Economic News Section

+
+ +
+
+ {filteredRssNews.map((news) => ( + + ))} +
+
); -} +}; export default NewsPage; - diff --git a/frontend/src/styles/News.css b/frontend/src/styles/News.css new file mode 100644 index 00000000..b9dad861 --- /dev/null +++ b/frontend/src/styles/News.css @@ -0,0 +1,171 @@ +.news-page { + display: flex; + flex-direction: column; + flex: 1; + background-color: var(--color-neutral-white); + overflow-y: auto; +} + +.news-header { + flex: 0 0 auto; + width: 100%; + background-color: var(--color-primary-100); + padding: 120px 0; + border-bottom: 1px solid var(--color-neutral-300); + text-align: center; +} + +.news-title { + font-size: 4rem; + margin: 0; + color: var(--color-primary-900); +} + +.news-subtitle { + font-size: 1.8rem; + margin: 10px 0; + color: var(--color-neutral-700); +} + +.news-content { + flex: 1; + width: 100%; + padding: 20px 32px; + text-align: left; + background-color: var(--color-neutral-white); +} + +.section-title { + font-size: 2rem; + margin: 20px 0; + text-align: left; + color: var(--color-primary-800); +} + +.scrollable-section { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 32px; + margin-bottom: 20px; +} + + +@media (max-width: 768px) { + .scrollable-section { + grid-template-columns: repeat(2, 1fr); + } + + .card { + flex: 1 1 auto; + } +} + +@media (max-width: 480px) { + .scrollable-section { + grid-template-columns: 1fr; + } +} + +.filter-buttons { + display: flex; + gap: 10px; + margin-bottom: 20px; + justify-content: flex-start; +} + +.filter-buttons button, +.filter-buttons .filter-button { + padding: 8px 12px; + border: none; + border-radius: 5px; + cursor: pointer; + background-color: var(--color-secondary-500); + color: var(--color-neutral-white); + transition: background-color 0.3s ease; +} + +.filter-buttons button:hover, +.filter-buttons .filter-button:hover { + background-color: var(--color-secondary-700); +} + +.filter-buttons .filter-button.selected { + font-weight: bold; + +} + +.filter-buttons .filter-button:hover { + background-color: var(--color-secondary-600); +} + + +.card, +.news-card { + border: 1px solid var(--color-neutral-300); + border-radius: 8px; + padding: 20px; + box-shadow: var(--shadow-md); + text-align: left; + background-color: var(--color-neutral-white); + transition: background-color 0.3s ease; + cursor: pointer; +} + +.card:hover, +.news-card:hover { + background-color: var(--color-neutral-100); +} + +.card-header { + display: flex; + justify-content: space-between; + font-size: 0.9rem; + color: var(--color-neutral-600); + margin-bottom: 10px; +} + +.card-source { + font-weight: bold; +} + +.card-time { + color: var(--color-neutral-500); +} + +.card-body { + display: flex; + justify-content: space-between; + align-items: center; +} + +.card-text { + flex-grow: 1; + margin-right: 10px; +} + +.card-title { + font-size: 1.2rem; + margin-bottom: 8px; +} + +.card-description { + font-size: 1rem; + color: var(--color-neutral-700); +} + +.card-icon { + width: auto; + width: 25%; /* Allow the icon to take up at most 20% of the card width */ + height: auto; + aspect-ratio: 1 / 1; /* Keep it square */ + border-radius: 12px; /* Rounded corners */ + overflow: hidden; /* Crop image if it's too large */ + margin-left: 10px; /* Space between text and icon */ + flex-shrink: 0; /* Prevent shrinking smaller than its natural size */ +} + +.card-icon img { + width: 100%; + height: 100%; + object-fit: cover; /* Ensure the image fits without stretching */ +} \ No newline at end of file From a49cb80e04d6177550cb1a8800a436e8a81f4a89 Mon Sep 17 00:00:00 2001 From: halil Date: Sat, 19 Oct 2024 23:51:31 +0300 Subject: [PATCH 3/4] refactor: update dashboard colors using palette adds a palette under index.css and uses it --- frontend/src/index.css | 110 ++++++++++++++++++++++++++++++ frontend/src/styles/Dashboard.css | 32 +++------ 2 files changed, 121 insertions(+), 21 deletions(-) diff --git a/frontend/src/index.css b/frontend/src/index.css index 5d92d119..464bd1e9 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -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); +} diff --git a/frontend/src/styles/Dashboard.css b/frontend/src/styles/Dashboard.css index 828f0a71..a567aed0 100644 --- a/frontend/src/styles/Dashboard.css +++ b/frontend/src/styles/Dashboard.css @@ -1,6 +1,7 @@ * { box-sizing: border-box; } + .dashboard-container { display: flex; flex-direction: column; @@ -10,7 +11,7 @@ } .navbar { - background-color: #333; + background-color: var(--color-primary-900); padding: 1rem; display: flex; justify-content: space-between; @@ -28,7 +29,7 @@ } .nav-links a { - color: white; + color: var(--color-neutral-white); text-decoration: none; font-weight: bold; padding: 10px 15px; @@ -37,7 +38,7 @@ } .nav-links a:hover { - background-color: #555; + background-color: var(--color-primary-700); } .auth-buttons { @@ -45,8 +46,8 @@ } .auth-button { - color: white; - background-color: #007bff; + color: var(--color-neutral-white); + background-color: var(--color-secondary-500); border: none; border-radius: 5px; padding: 10px 15px; @@ -56,25 +57,14 @@ } .auth-button:hover { - background-color: #0056b3; + background-color: var(--color-secondary-700); } .content { + overflow-y: auto; flex: 1; - display: flex; - justify-content: center; + display: flex; + flex-direction: column; align-items: center; - position: relative; - overflow: hidden; + justify-content: center; } - -.hello-text { - font-size: 5rem; - color: #333; - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - margin: 0; - text-align: center; -} \ No newline at end of file From 130a8cefaee44244f0a0bc8313fd79a214b7fb0f Mon Sep 17 00:00:00 2001 From: halil Date: Sun, 20 Oct 2024 00:06:29 +0300 Subject: [PATCH 4/4] refactor: remove extra comments --- frontend/src/components/news/NewsPage.js | 11 ++--------- frontend/src/styles/News.css | 14 +++++++------- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/frontend/src/components/news/NewsPage.js b/frontend/src/components/news/NewsPage.js index 57055ebe..5369d5d7 100644 --- a/frontend/src/components/news/NewsPage.js +++ b/frontend/src/components/news/NewsPage.js @@ -10,9 +10,9 @@ const mockNewsData = [ 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", // Time ago + publishedAt: "2 hours ago", coverImageUrl: "https://www.thisiscolossal.com/wp-content/uploads/2024/10/jonk-1.jpg", - source: "Economic Times", // Publishing source name + source: "Economic Times", }, { id: 2, @@ -95,26 +95,21 @@ const NewsPage = () => { const [newsData, setNewsData] = useState([]); const [rssNewsData, setRssNewsData] = useState([]); const all = 'All'; - // Separate category states for both sections const [selectedCategory, setSelectedCategory] = useState(all); const [selectedRssCategory, setSelectedRssCategory] = useState(all); useEffect(() => { - // Set mock news data setNewsData(mockNewsData); setRssNewsData(mockRssFeedData); }, []); - // Extract unique categories for mock news and RSS feed news const newsCategories = [all, ...new Set(mockNewsData.map(news => news.category))]; const rssCategories = [all, ...new Set(mockRssFeedData.map(news => news.category))]; - // Filter logic for the first news section const filteredNews = newsData.filter((news) => selectedCategory === all ? true : news.category === selectedCategory ); - // Filter logic for the RSS feed news section const filteredRssNews = rssNewsData.filter((news) => selectedRssCategory === all ? true : news.category === selectedRssCategory ); @@ -127,7 +122,6 @@ const NewsPage = () => {
- {/* Filter Buttons for Mock News Section */}

Mock Economic News Section

@@ -138,7 +132,6 @@ const NewsPage = () => { ))}
- {/* Filter Buttons for Mock RSS Feed News Section */}

Mock RSS Feed Economic News Section

diff --git a/frontend/src/styles/News.css b/frontend/src/styles/News.css index b9dad861..ba9c9766 100644 --- a/frontend/src/styles/News.css +++ b/frontend/src/styles/News.css @@ -155,17 +155,17 @@ .card-icon { width: auto; - width: 25%; /* Allow the icon to take up at most 20% of the card width */ + width: 25%; height: auto; - aspect-ratio: 1 / 1; /* Keep it square */ - border-radius: 12px; /* Rounded corners */ - overflow: hidden; /* Crop image if it's too large */ - margin-left: 10px; /* Space between text and icon */ - flex-shrink: 0; /* Prevent shrinking smaller than its natural size */ + aspect-ratio: 1 / 1; + border-radius: 12px; + overflow: hidden; + margin-left: 10px; + flex-shrink: 0; } .card-icon img { width: 100%; height: 100%; - object-fit: cover; /* Ensure the image fits without stretching */ + object-fit: cover; } \ No newline at end of file