Skip to content

Commit 669b394

Browse files
Initial Commit
1 parent 48bd16c commit 669b394

File tree

10 files changed

+184
-93
lines changed

10 files changed

+184
-93
lines changed

.vscode/settings.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"cSpell.words": [
3+
"Hashnode"
4+
]
5+
}

README.md

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,33 @@
1-
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
1+
# Hashnode NextJs
2+
Integrate Hashnode to NextJS Project
23

3-
## Getting Started
4-
5-
First, run the development server:
4+
### First, run the development server:
65

76
```bash
87
npm run dev
9-
# or
10-
yarn dev
118
```
129

13-
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
14-
15-
You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.
16-
17-
[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`.
18-
19-
The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
20-
21-
## Learn More
22-
23-
To learn more about Next.js, take a look at the following resources:
24-
25-
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
26-
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
27-
28-
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
10+
### Build for production AND generate static website into "out" folder:
11+
```bash
12+
npm run build
13+
```
2914

30-
## Deploy on Vercel
15+
### Run in production:
16+
```bash
17+
npm start
18+
```
3119

32-
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
20+
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
3321

34-
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
22+
## Folder Structure
23+
.
24+
├── ...
25+
├── components # Components Folder
26+
│ ├── BlogItem.js # Single Blog component
27+
│ ├── BlogList.js # Wrapper component for our BlogItem
28+
│ ├── Header.js
29+
│ └── Layout.js # Blueprint for our page Layout
30+
├── pages # Pages Folder
31+
│ ├── _app.js
32+
│ └── index.js
33+
└── ...

components/BlogItem.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
export default function BlogItem({ post }) {
2+
const redirectToHashnode = () => {
3+
window.open("https://blog.christianpelayo.com/" + post.slug, "_blank");
4+
};
5+
6+
const getDateAdded = () => {
7+
let d = new Date(post.dateAdded);
8+
let ye = new Intl.DateTimeFormat("en", { year: "numeric" }).format(d);
9+
let mo = new Intl.DateTimeFormat("en", { month: "short" }).format(d);
10+
let da = new Intl.DateTimeFormat("en", { day: "2-digit" }).format(d);
11+
return `${mo} ${da}, ${ye}`;
12+
};
13+
14+
const formattedDate = getDateAdded();
15+
16+
return (
17+
<div className="card mb-3 border-light" onClick={redirectToHashnode}>
18+
<style jsx>{`
19+
.card {
20+
cursor: pointer;
21+
}
22+
`}</style>
23+
<img src={post.coverImage} className="img-fluid" />
24+
<div className="card-body">
25+
<h3 className="card-title">{post.title}</h3>
26+
<h6 className="card-subtitle mb-2 text-muted">{formattedDate}</h6>
27+
<p className="card-text">{post.brief}</p>
28+
</div>
29+
</div>
30+
);
31+
}

components/BlogList.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import BlogItem from "./BlogItem";
2+
3+
export default function BlogList({ publications }) {
4+
let posts = publications.data.user.publication.posts;
5+
6+
return (
7+
<div className="mt-5">
8+
<div className="mb-4">
9+
<h2>My Publications</h2>
10+
</div>
11+
<div className="row">
12+
{posts.map((post, index) => {
13+
return (
14+
<div key={index} className="col-xs-12 col-sm-12 col-md-12 col-lg-4">
15+
<BlogItem post={post} />
16+
</div>
17+
);
18+
})}
19+
</div>
20+
</div>
21+
);
22+
}

components/Header.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
export default function Header() {
2+
return (
3+
<nav className="navbar navbar-expand-lg navbar-dark bg-primary">
4+
<div className="container">
5+
<a className="navbar-brand" href="#">
6+
Hanshnode & NextJS
7+
</a>
8+
<button
9+
className="navbar-toggler"
10+
type="button"
11+
data-bs-toggle="collapse"
12+
data-bs-target="#navbarColor01"
13+
aria-controls="navbarColor01"
14+
aria-expanded="false"
15+
aria-label="Toggle navigation">
16+
<span className="navbar-toggler-icon"></span>
17+
</button>
18+
19+
<div className="collapse navbar-collapse" id="navbarColor01">
20+
<ul className="navbar-nav me-auto">
21+
<li className="nav-item">
22+
<a className="nav-link active" href="#">
23+
Home
24+
<span className="visually-hidden">(current)</span>
25+
</a>
26+
</li>
27+
</ul>
28+
</div>
29+
</div>
30+
</nav>
31+
);
32+
}

components/Layout.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import Head from "next/head";
2+
import Header from "../components/Header";
3+
4+
export default function Layout(props) {
5+
return (
6+
<div className="main-container">
7+
<Head>
8+
<title>Hashnode NextJS Integration</title>
9+
</Head>
10+
<Header />
11+
<main className="container mb-5">{props.children}</main>
12+
</div>
13+
);
14+
}

package-lock.json

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"lint": "next lint"
1010
},
1111
"dependencies": {
12+
"bootswatch": "^5.1.0",
1213
"next": "11.1.0",
1314
"react": "17.0.2",
1415
"react-dom": "17.0.2"

pages/_app.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import '../styles/globals.css'
1+
import "../styles/globals.css";
2+
import "bootswatch/dist/pulse/bootstrap.min.css";
23

34
function MyApp({ Component, pageProps }) {
4-
return <Component {...pageProps} />
5+
return <Component {...pageProps} />;
56
}
67

7-
export default MyApp
8+
export default MyApp;

pages/index.js

Lines changed: 40 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,44 @@
1-
import Head from 'next/head'
2-
import Image from 'next/image'
3-
import styles from '../styles/Home.module.css'
1+
import Layout from "../components/Layout";
2+
import BlogList from "../components/BlogList";
43

5-
export default function Home() {
4+
export default function Home({ publications }) {
65
return (
7-
<div className={styles.container}>
8-
<Head>
9-
<title>Create Next App</title>
10-
<meta name="description" content="Generated by create next app" />
11-
<link rel="icon" href="/favicon.ico" />
12-
</Head>
13-
14-
<main className={styles.main}>
15-
<h1 className={styles.title}>
16-
Welcome to <a href="https://nextjs.org">Next.js!</a>
17-
</h1>
18-
19-
<p className={styles.description}>
20-
Get started by editing{' '}
21-
<code className={styles.code}>pages/index.js</code>
22-
</p>
23-
24-
<div className={styles.grid}>
25-
<a href="https://nextjs.org/docs" className={styles.card}>
26-
<h2>Documentation &rarr;</h2>
27-
<p>Find in-depth information about Next.js features and API.</p>
28-
</a>
29-
30-
<a href="https://nextjs.org/learn" className={styles.card}>
31-
<h2>Learn &rarr;</h2>
32-
<p>Learn about Next.js in an interactive course with quizzes!</p>
33-
</a>
34-
35-
<a
36-
href="https://github.com/vercel/next.js/tree/master/examples"
37-
className={styles.card}
38-
>
39-
<h2>Examples &rarr;</h2>
40-
<p>Discover and deploy boilerplate example Next.js projects.</p>
41-
</a>
42-
43-
<a
44-
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
45-
className={styles.card}
46-
>
47-
<h2>Deploy &rarr;</h2>
48-
<p>
49-
Instantly deploy your Next.js site to a public URL with Vercel.
50-
</p>
51-
</a>
52-
</div>
53-
</main>
6+
<Layout>
7+
<BlogList publications={publications} />
8+
</Layout>
9+
);
10+
}
5411

55-
<footer className={styles.footer}>
56-
<a
57-
href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
58-
target="_blank"
59-
rel="noopener noreferrer"
60-
>
61-
Powered by{' '}
62-
<span className={styles.logo}>
63-
<Image src="/vercel.svg" alt="Vercel Logo" width={72} height={16} />
64-
</span>
65-
</a>
66-
</footer>
67-
</div>
68-
)
12+
/**
13+
* Method used to fetch data from Hashnode.
14+
* 1. AUTHORIZATION_TOKEN => Your Hashnode Personal Access Token
15+
* 2. USER_NAME => Your Hashnode username
16+
* @param {Object} context
17+
* @returns props
18+
*/
19+
export async function getServerSideProps(context) {
20+
const res = await fetch("https://api.hashnode.com/", {
21+
method: "POST",
22+
headers: {
23+
"Content-Type": "application/json",
24+
Authorization: "0a5eee0d-d0d1-443e-840c-e57fed1ec879",
25+
},
26+
body: JSON.stringify({
27+
query:
28+
'query {user(username: "testchan") {publication {posts(page: 0) {title brief slug coverImage dateAdded}}}}',
29+
}),
30+
});
31+
const publications = await res.json();
32+
33+
if (!publications) {
34+
return {
35+
notFound: true,
36+
};
37+
}
38+
39+
return {
40+
props: {
41+
publications,
42+
},
43+
};
6944
}

0 commit comments

Comments
 (0)