diff --git a/CHANGELOG.md b/CHANGELOG.md index c055fe2..4736d49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # CHANGELOG.md +## 1.1.0 (2022-10-26) - Lunchtime Updates + +Features: + + - Navigation Updates & Improvements (Logo, Active Class, etc) - `next/navigation` + - Post/Item Listing Output Cleanup (better UI/UX for listings) + - Post/Item Listing Pagination Support + - Post/Item Components / Shared Code (`SinglePost.js` and `NewsList.js`) + ## 1.0.0 (2022-10-25) Features: diff --git a/README.md b/README.md index a43b6eb..d90718a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Rehacker -Note: This is an early *NextJS 13* test build/learning expirement with all of the changes; feel free to fork, make changes, point out bugs/idiotic configurations, etc. :) +Note: This is an early *NextJS 13* test build/learning expirement with all of the recent changes/additions; feel free to fork, make changes, point out bugs/idiotic configurations, etc. :) ## Demo URL @@ -20,13 +20,13 @@ Note: This is an early *NextJS 13* test build/learning expirement with all of t `npm run build` -### Todo's +### Current Todo's -* Threaded Comments & Comment Children -* Pagination (Ask, Show, Top, Best, etc) +* Threaded Comments (and ability to `Load More`) +* Comments Styling & Readability +* Comments JSON Undefined Issue * Better Organization of getData* Functions * SEO / New `HEAD` Setup (`head.js`) - -### Known Issues - -* Comments Loading (when large number of requests, oddity with undefined JSON) \ No newline at end of file +* Single News Item Styling & Updates +* Mobile/Responsive Fixes +* Performance Updates & Caching \ No newline at end of file diff --git a/app/ask/page.js b/app/ask/page.js index 8561837..ce00352 100644 --- a/app/ask/page.js +++ b/app/ask/page.js @@ -1,6 +1,6 @@ import { use } from 'react'; -import SinglePost from "../../components/posts/SinglePost" +import NewsList from "../../components/posts/NewsList" async function getNewsItems() { @@ -10,25 +10,13 @@ async function getNewsItems() { } export default function Page() { + var newsItems = use(getNewsItems()); - newsItems = newsItems.slice(0, 30); return ( <> -
-
- {newsItems && - <> - {newsItems.map(item => { - return ( - - ) - })} - - } -
-
+ ) diff --git a/app/item/[slug]/page.js b/app/item/[slug]/page.js index 11bd363..be6b719 100644 --- a/app/item/[slug]/page.js +++ b/app/item/[slug]/page.js @@ -15,6 +15,11 @@ async function getNewsItem(id) { export default function SingleNewsItemPage({ params, searchParams }) { var newsItem = use(getNewsItem( params.slug )); + var comments = newsItem.kids; + if(comments && comments.length > 0) { + comments = comments.slice(0, 30); + } + return ( <>
@@ -59,10 +64,10 @@ export default function SingleNewsItemPage({ params, searchParams }) { - { newsItem.kids && newsItem.kids.length > 0 && + { comments && comments.length > 0 && <>
- { newsItem.kids.map((commentId, index) => ( + { comments.map((commentId, index) => ( <> diff --git a/app/jobs/page.js b/app/jobs/page.js index 45373aa..a21e6d3 100644 --- a/app/jobs/page.js +++ b/app/jobs/page.js @@ -1,6 +1,6 @@ import { use } from 'react'; -import SinglePost from "../../components/posts/SinglePost" +import NewsList from "../../components/posts/NewsList" async function getNewsItems() { @@ -10,25 +10,13 @@ async function getNewsItems() { } export default function Page() { + var newsItems = use(getNewsItems()); - newsItems = newsItems.slice(0, 30); return ( <> -
-
- {newsItems && - <> - {newsItems.map(item => { - return ( - - ) - })} - - } -
-
+ ) diff --git a/app/layout.js b/app/layout.js index 55066c0..ee8d65e 100644 --- a/app/layout.js +++ b/app/layout.js @@ -1,8 +1,9 @@ import '../styles/globals.css' -import Link from 'next/link'; -export default function RootLayout({ children }) { +import NavLinks from '../components/navigation/NavLinks'; +import PaginateNews from '../components/navigation/PaginateNews'; +export default function RootLayout({ children }) { return ( @@ -13,47 +14,22 @@ export default function RootLayout({ children }) {
+ + {children} diff --git a/app/new/page.js b/app/new/page.js index 2ed34a3..656e9f1 100644 --- a/app/new/page.js +++ b/app/new/page.js @@ -1,6 +1,6 @@ import { use } from 'react'; -import SinglePost from "../../components/posts/SinglePost" +import NewsList from "../../components/posts/NewsList" async function getNewsItems() { @@ -10,25 +10,13 @@ async function getNewsItems() { } export default function Page() { + var newsItems = use(getNewsItems()); - newsItems = newsItems.slice(0, 30); return ( <> -
-
- {newsItems && - <> - {newsItems.map(item => { - return ( - - ) - })} - - } -
-
+ ) diff --git a/app/page.js b/app/page.js index c286154..22f4dcc 100644 --- a/app/page.js +++ b/app/page.js @@ -1,6 +1,7 @@ import { use } from 'react'; import SinglePost from "../components/posts/SinglePost" +import NewsList from "../components/posts/NewsList" async function getNewsItems() { @@ -10,25 +11,13 @@ async function getNewsItems() { } export default function Page() { + var newsItems = use(getNewsItems()); - newsItems = newsItems.slice(0, 30); return ( <> -
-
- {newsItems && - <> - {newsItems.map(item => { - return ( - - ) - })} - - } -
-
+ ) diff --git a/app/show/page.js b/app/show/page.js index 3a90735..80bcd80 100644 --- a/app/show/page.js +++ b/app/show/page.js @@ -1,6 +1,6 @@ import { use } from 'react'; -import SinglePost from "../../components/posts/SinglePost" +import NewsList from "../../components/posts/NewsList" async function getNewsItems() { @@ -10,25 +10,13 @@ async function getNewsItems() { } export default function Page() { + var newsItems = use(getNewsItems()); - newsItems = newsItems.slice(0, 30); return ( <> -
-
- {newsItems && - <> - {newsItems.map(item => { - return ( - - ) - })} - - } -
-
+ ) diff --git a/components/navigation/NavLinks.js b/components/navigation/NavLinks.js new file mode 100644 index 0000000..3dc0f09 --- /dev/null +++ b/components/navigation/NavLinks.js @@ -0,0 +1,52 @@ +'use client'; + +import Link from 'next/link'; +import Image from 'next/image'; + +import { usePathname } from 'next/navigation'; + +export default function NavLinks( props ) { + + const pathname = usePathname(); + + return ( + <> +
  • + + Rehacker + +
  • + +
  • + + Top + +
  • + +
  • + + New + +
  • + +
  • + + Show + +
  • + +
  • + + Ask + +
  • + +
  • + + Jobs + +
  • + + ) + +} \ No newline at end of file diff --git a/components/navigation/PaginateNews.js b/components/navigation/PaginateNews.js new file mode 100644 index 0000000..14aeb4b --- /dev/null +++ b/components/navigation/PaginateNews.js @@ -0,0 +1,61 @@ +'use client'; + +import Link from 'next/link'; + +import { usePathname } from 'next/navigation'; +import { useSearchParams } from 'next/navigation'; + +export default function PaginateNews( props ) { + + const pathname = usePathname(); + const searchParams = useSearchParams(); + + var p = searchParams.get('p'); + if( p == null ) { + p = 0; + } + + var next_page = parseInt(p) + 1; + var prev_page = parseInt(p) - 1; + + return ( + <> +
    +
    +
    + { prev_page >= 0 ? ( + <> + + + + + ) : ( + <> + < previous + + )} +
    + +
    + { p } / 3 +
    + +
    + { next_page <= 3 ? ( + <> + + + + + ) : ( + <> + next > + + )} +
    +
    +
    + + ) + +} \ No newline at end of file diff --git a/components/posts/NewsList.js b/components/posts/NewsList.js new file mode 100644 index 0000000..1a22b46 --- /dev/null +++ b/components/posts/NewsList.js @@ -0,0 +1,46 @@ +'use client'; + +import { useSearchParams } from 'next/navigation'; + +import SinglePost from './SinglePost'; + +export default function NewsList( props ) { + + const searchParams = useSearchParams(); + + var items_per_page = 30; + var start = 0; + var end = 30; + var p = searchParams.get('p'); + if( p == null || p == 0) { + p = 0; + }else{ + start = p * items_per_page; + end = start + items_per_page; + } + + var next_page = parseInt(p) + 1; + var prev_page = parseInt(p) - 1; + + var newsItems = props.data; + newsItems = newsItems.slice(start, end); + + return ( + <> + +
    +
    + {newsItems && + <> + {newsItems.map((item, index) => ( + + ))} + + } +
    +
    + + + ) + +} \ No newline at end of file diff --git a/components/posts/SinglePost.js b/components/posts/SinglePost.js index 6d69291..2627caa 100644 --- a/components/posts/SinglePost.js +++ b/components/posts/SinglePost.js @@ -1,65 +1,91 @@ +'use client'; + import Link from 'next/link'; import DateOutput from '../global/DateOutput'; import DomainOutput from '../global/DomainOutput'; -async function getSingleNewsItem(id) { +import useSWR from 'swr' +import React, { useState, useEffect } from "react"; - const res = await fetch('https://hacker-news.firebaseio.com/v0/item/' + id + '.json?print=pretty', { next: { revalidate: 60 } }); - return res.json(); +export default function SinglePost( props ) { -} + const [isLoading, setIsLoading] = React.useState(1); + const [newsItem, setNewsItem] = React.useState(0); + + const fetcher = (...args) => fetch(...args).then(res => res.json()) + const { data, error } = useSWR('https://hacker-news.firebaseio.com/v0/item/' + props.id + '.json', fetcher) + + useEffect(() => { + setNewsItem(data); + setIsLoading(0); + }, [isLoading, data, newsItem]); -export default async function SinglePost( props ) { - const newsItem = await getSingleNewsItem( props.id ); return ( <> - { newsItem && + { isLoading == 1 ? ( <> -
    -

    - { newsItem.url ? ( - <> - { newsItem.title } - - ) : ( - <> - - { newsItem.title } - - - ) } - -

    - -
    - Score: { newsItem.score } - - - - - - - - - - - { newsItem.descendants } comments - - - - - - - by { newsItem.by } - +
    +
    + Loading...
    - - } + ) : ( + <> + { newsItem && + <> +
    +
    +
    +
    + { newsItem.score } +
    +
    + +
    +

    + { newsItem.url ? ( + <> + { newsItem.title } + + ) : ( + <> + + { newsItem.title } + + + ) } + +

    + +
    + + + + + + + + + + { newsItem.descendants } comments + + + | by { newsItem.by } + +
    +
    +
    +
    + + + } + + )} ) -} \ No newline at end of file +} + diff --git a/package-lock.json b/package-lock.json index 3fe1079..d725a9d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "rehacker", - "version": "0.1.0", + "version": "1.1.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "rehacker", - "version": "0.1.0", + "version": "1.1.0", "dependencies": { "next": "^13.0.0", "react": "^18.2.0", diff --git a/package.json b/package.json index a1bd0cc..f756779 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rehacker", - "version": "0.1.0", + "version": "1.1.0", "private": true, "scripts": { "dev": "next dev", diff --git a/public/hn-logo.svg b/public/hn-logo.svg new file mode 100755 index 0000000..40eaae0 --- /dev/null +++ b/public/hn-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/styles/globals.css b/styles/globals.css index bd6213e..688df16 100644 --- a/styles/globals.css +++ b/styles/globals.css @@ -1,3 +1,7 @@ @tailwind base; @tailwind components; -@tailwind utilities; \ No newline at end of file +@tailwind utilities; + +.logo-color { + filter: brightness(0) invert(1); +} \ No newline at end of file