From e640008f545c68b0d3efaa3c2478b8f618f41367 Mon Sep 17 00:00:00 2001 From: Aftab Alam <532906+one-aalam@users.noreply.github.com> Date: Mon, 13 Apr 2020 11:10:48 +0530 Subject: [PATCH] Add NewsItem component --- components/NewsItem.module.css | 15 ++++ components/NewsItem.tsx | 124 +++++++++++++++++++++++++++++++++ components/utility.module.css | 49 +++++++++++++ package.json | 1 + yarn.lock | 12 ++++ 5 files changed, 201 insertions(+) create mode 100644 components/NewsItem.module.css create mode 100644 components/NewsItem.tsx create mode 100644 components/utility.module.css diff --git a/components/NewsItem.module.css b/components/NewsItem.module.css new file mode 100644 index 0000000..34d66f7 --- /dev/null +++ b/components/NewsItem.module.css @@ -0,0 +1,15 @@ +.NewsItem { + padding: 2px 8px; +} +.NewsItem__NumCol { + width: 80px; + text-align: right; +} +@media screen and (min-width: 768px) { + .NewsItem { + padding: 4px 12px; + } + .NewsItem__NumCol { + width: 100px; + } +} \ No newline at end of file diff --git a/components/NewsItem.tsx b/components/NewsItem.tsx new file mode 100644 index 0000000..1b8a63d --- /dev/null +++ b/components/NewsItem.tsx @@ -0,0 +1,124 @@ +import React from 'react'; +import cx from 'classnames'; +import TimeAgo from 'javascript-time-ago'; +import en from 'javascript-time-ago/locale/en'; + +import styles from './utility.module.css'; +import mstyle from './NewsItem.module.css'; + +TimeAgo.addLocale(en); +const timeAgo = new TimeAgo('en-US'); + +type Props = { + // + id: number; + title: string; + points: number; + commentCount: number; + source: string; + author: string; // username of the poster + createdAt: string; // timestamp + + onUpvote: (id: number, points: number) => void; + onHide: (id: number) => void; + + visible?: boolean; + alt?: boolean; +}; + +const NewsItem: React.FC = ({ + commentCount, + points: pointsProp, + title = '', + source = '', + author = '', + createdAt, + id, + onHide = () => {}, + onUpvote = () => {}, + visible: visibleProp = true, + alt = false, +}) => { + const [visible, setVisibility] = React.useState(true); + const [points, setPoints] = React.useState(0); + + React.useEffect(() => { + setPoints(pointsProp); + setVisibility(visibleProp); + return () => {}; + }, [visibleProp, pointsProp]); + + const handleVisibility = () => { + setVisibility(!visible); + onHide(id); + }; + + const handleUpvote = () => { + setPoints((prevPoints) => prevPoints + 1); + onUpvote(id, points); + }; + + return ( + visible && ( +
+
+ {/* NewsItem: Comments Count */} +
{commentCount > 0 ? commentCount : '-'}
+ {/* NewsItem: Points & Upvote button */} +
+ + +
+ {/* NewsItem: Title */} +
{title}
  +
+ +
+ {/* NewsItem: Source */} +
+ ( + + {source.indexOf('://') !== -1 ? source.split('://')[1].split('/')[0] : source} + + ) +
+ + {/* NewsItem: Author */} +
+  by {author}  +
+ + {/* NewsItem: CreatedAt */} +
{timeAgo.format(new Date(createdAt))}
+ + {/* NewsItem: Hide Button */} + +
+
+ ) + ); +}; + +const NewsItemPoint = ({ points }) => ( + = 100 && styles.tcBlazeOrange, + points < 100 && points >= 80 && styles.tcFire, + points < 80 && styles.white + )} + > + {points} + +); + +export default NewsItem; diff --git a/components/utility.module.css b/components/utility.module.css new file mode 100644 index 0000000..a40ebdb --- /dev/null +++ b/components/utility.module.css @@ -0,0 +1,49 @@ +/** Utility classes **/ +.flex { display: flex;} +.flexR { display: flex; flex-direction: column;} +@media screen and (min-width: 768px) { + .flexR { + flex-direction: row; + } +} + +.unstyled { outline: 0; border: 0; background: none;} + +.fs12 { font-size: 12px;} +.fs14 { font-size: 14px;} + +.px4 { padding-left: 4px; padding-right: 4px;} + +.fw500 { font-weight: 500 } +.fw600 { font-weight: 600 } + +.bgCararra { background-color: #e6e6df;} +.bgSpringWood { background-color: #f6f6ef;} +.bgBlazeOrange { background-color: #ff6602;} + +.tcBlazeOrange { color: #ff6602; } +.tcFire { color: #aa4400; } +.tcBlack { color: #000000; } +.tcGray { color: #828282; } +.tcDustyGray { color: #999999; } +.tcStack { color: #8d8f8c } +.tcSilverLight { color: #c9c9c9; } +.tcSilverDark { color: #b8b8b8; } + +/** +- Primary: #ff6602 // blaze-orange +- White: #ffffff +- Black: #000000 + +- Bg, row-normal: #f6f6ef // spring-wood +- news row-alt: #e6e6df // cararra +- news upvote: #999999 // dusty-gray + +- news source: #828282 // gray +- news source bracket: #c9c9c9 // silver-light + +- news source by: #b8b8b8 // silver-dark +- news source time ago: #828282 // gray +- news hide bracket: #8d8f8c // stack + +- #aa4400 (above 80) **/ \ No newline at end of file diff --git a/package.json b/package.json index 922e228..9b5e671 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "classnames": "^2.2.6", "dotenv": "^8.2.0", "isomorphic-unfetch": "^3.0.0", + "javascript-time-ago": "^2.0.7", "next": "9.3.4", "react": "16.13.1", "react-dom": "16.13.1" diff --git a/yarn.lock b/yarn.lock index d40dca1..69a0fc1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4108,6 +4108,13 @@ istanbul-reports@^3.0.0: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" +javascript-time-ago@^2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/javascript-time-ago/-/javascript-time-ago-2.0.7.tgz#ed3e4cfae7059d1c3ecc0e7fc253427f0e120636" + integrity sha512-NjM8FNqY91lciAE4bIm6KBW1efDt+0T6+08erwaQRu6SzLov8fJ6623LcyxnBN/Xtf4q9O4s5AMxPtStaNz0rA== + dependencies: + relative-time-format "^0.1.3" + jest-changed-files@^25.2.6: version "25.2.6" resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-25.2.6.tgz#7d569cd6b265b1a84db3914db345d9c452f26b71" @@ -6060,6 +6067,11 @@ regjsparser@^0.6.4: dependencies: jsesc "~0.5.0" +relative-time-format@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/relative-time-format/-/relative-time-format-0.1.3.tgz#d50f49d13f97c7f801afba600b1a4a0890755df2" + integrity sha512-0O6i4fKjsx8qhz57zorG+LrIDnF9pSvP5s7H9R1Nb5nSqih5dvRyKzNKs6MxhL3bv4iwsz4DuDwAyw+c47QFIA== + remove-trailing-separator@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef"