Skip to content

feat: add nextjs in react app #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
REACT_APP_API_KEY = ""
REACT_APP_API_URL = "https://newsapi.org/v2/"
NEXT_PUBLIC_API_KEY = ""
NEXT_PUBLIC_API_URL = "https://newsapi.org/v2/"
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

.next
# dependencies
/node_modules
/.pnp
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ In this ABlOG Project project we have the following sections done:

## Technologies Used

This project is mainly based on [React.js](https://reactjs.org/) plus others few libraries listed below:
This project is mainly based on [Next.js](https://nextjs.org/) plus others few libraries listed below:

- [Tailwind css](https://tailwindcss.com/)
- [redux](https://www.npmjs.com/package/redux)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { Link } from "react-router-dom";
import Link from "next/link";

export default function Header() {
return (
<div className="flex justify-between items-center py-3 border-b-[3px] border-gray-900">
<Link className="flex cursor-pointer" to="/">
<Link className="flex cursor-pointer" href="/">
<span className="text-2xl font-semibold">A</span>
<span className="text-2xl font-normal">BlOG</span>
</Link>
<div className="">
<Link
to="https://www.hirwaaldo.com/#Contact"
href="https://www.hirwaaldo.com/#Contact"
target="_blank"
rel="noreferrer"
className="bg-transparent border text-gray-900 border-gray-900 rounded-full pt-1.5 pb-2 px-4"
Expand Down
27 changes: 27 additions & 0 deletions components/sections/Blog/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { useSelector } from "react-redux";
import Card from "../../ui/Card";
import CardSkeleton from "../../ui/Card/Skeleton";
import ErrorFound from "../../ui/ErrorFound";
import NotFound from "../../ui/NotFound";

export default function Blog({ headlines }) {
const data = useSelector((state) =>
headlines ? state.headlines : state.articles
);
return (
<>
{data.isError && <ErrorFound />}
<div className="grid grid-cols-1 md:grid-cols-3 lg:grid-cols-5 gap-4 mt-5">
{data.isLoading ? (
<CardSkeleton count={10} />
) : (
data.value?.map((article, index) => {
return <Card key={`card-index-${index}`} article={article} />;
})
)}
</div>

{data.value?.length === 0 && <NotFound />}
</>
);
}
7 changes: 7 additions & 0 deletions components/sections/homepage/NavSkeleton.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import Skeleton from "react-loading-skeleton";

export default function NavSkeleton({ count }) {
return Array(count)
.fill()
.map((_, index) => <Skeleton key={`tab-skeleton-${index}`} width={100} />);
}
Original file line number Diff line number Diff line change
@@ -1,30 +1,25 @@
import { useState } from "react";
import { useGetPublisherQuery } from "../../../services/publishersApi";
import Skeleton from "react-loading-skeleton";
import SearchInput from "../../ui/SearchInput";
import Slider from "react-slick";
import settings from "../../../config/reactSlickSetting";
import { Link } from "react-router-dom";
import { useSelector } from "react-redux";
import Link from "next/link";
import NavSkeleton from "./NavSkeleton";

export default function Navigation() {
const { data: publishers, isLoading } = useGetPublisherQuery();
const navigationTab = useSelector((state) => state.publishers);
const [whichTab, setWhichTab] = useState("");

return (
<div className="border-b-2 border-gray-900 py-3">
<div className="flex flex-wrap text-base justify-center md:justify-start space-x-6">
{isLoading === true ? (
Array(5)
.fill()
.map((value, index) => (
<Skeleton key={`tab-skeleton-${index}`} width={100} />
))
{navigationTab.isLoading ? (
<NavSkeleton count={5} />
) : (
<Slider {...settings} className="w-11/12 md:w-1/2 mx-6">
{publishers?.sources.map((item) => (
{navigationTab.value?.map((item) => (
<Link
to={`/:${item.name}/article`}
state={{ whichTab: item.id }}
href={`/news/${item.id}`}
className={`text-md cursor-pointer mr-4 ${
whichTab === item.id && "underline"
}`}
Expand All @@ -36,6 +31,7 @@ export default function Navigation() {
))}
</Slider>
)}
{navigationTab.isError && <p>Opps.. something went wrong</p>}
<div className="hidden md:block">
<span className="block h-full w-0.5 bg-black" />
</div>
Expand Down
22 changes: 22 additions & 0 deletions components/ui/Card/Skeleton.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import Skeleton from "react-loading-skeleton";

export default function CardSkeleton({ count }) {
return (
<>
{Array(count)
.fill()
.map((_, index) => {
return (
<div key={`tab-skeleton-${index}`}>
<Skeleton height={176} />
<div className="flex gap-4 mt-4 mb-2">
<Skeleton width={50} />
<Skeleton width={50} />
</div>
<Skeleton count={2} />
</div>
);
})}
</>
);
}
9 changes: 4 additions & 5 deletions src/components/ui/Card.jsx → components/ui/Card/index.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { Link } from "react-router-dom";
import getDateTime from "../../utils/getDateTime";

import Link from "next/link";
import getDateTime from "../../../utils/getDateTime";
export default function Card({ article }) {
const { title, urlToImage, publishedAt } = article;
const { title, urlToImage, publishedAt, url } = article;
const date = new Date(publishedAt);
return (
<Link to={`/article/:${title}`} state={article}>
<Link href={url} target="_blank" referrerPolicy="no-referrer">
<div className="cursor-pointer group">
<img
src={urlToImage}
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
import { useState } from "react";
import { Search, X } from "react-feather";
import { useDispatch } from "react-redux";
import { setArticles } from "../../features/articles";
import { useSearchArticlesQuery } from "../../services/articlesApi";
import { searchHeadlines } from "../../features/headlines";

export default function SearchInput() {
const [search, setSearch] = useState("");
const { data: article } = useSearchArticlesQuery(search);
const dispatch = useDispatch();

function searchArticle(event) {
const [search, setSearch] = useState("");
function findArticle(event) {
event.preventDefault();
dispatch(setArticles(article));
dispatch(searchHeadlines({ value: search }));
}

return (
<form className="flex gap-2 items-center w-full" onSubmit={searchArticle}>
<form className="flex gap-2 items-center w-full" onSubmit={findArticle}>
<Search size={17} />
<input
type="text"
Expand All @@ -26,7 +23,10 @@ export default function SearchInput() {
/>
{search.length > 0 && (
<div className="flex items-center gap-1">
<button className="block h-full text-sm bg-gray-800 text-white rounded-sm px-2 cursor-pointer">
<button
type="submit"
className="block h-full text-sm bg-gray-800 text-white rounded-sm px-2 cursor-pointer"
>
find
</button>
<X
Expand Down
File renamed without changes.
6 changes: 5 additions & 1 deletion src/features/articles.js → features/articles.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { createSlice } from "@reduxjs/toolkit";
const articlesSlice = createSlice({
name: "articles",
initialState: [],
initialState: {
value: [],
isError: false,
isLoading: true,
},
reducers: {
setArticles: (state, action) => {
return (state = action.payload);
Expand Down
36 changes: 36 additions & 0 deletions features/headlines.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { createSlice } from "@reduxjs/toolkit";
const headlinesSlice = createSlice({
name: "headlines",
initialState: {
value: [],
backupValues: [],
isError: false,
isLoading: true,
},
reducers: {
setHeadlines: (state, action) => {
return (state = action.payload);
},
searchHeadlines: (state, action) => {
const { value } = action.payload;
const { backupValues } = state;
if (value === "") {
return {
...state,
value: backupValues,
};
}
const filteredHeadlines = backupValues.filter((headline) => {
const { title } = headline;
return title.toLowerCase().includes(value.toLowerCase());
});
return {
...state,
value: filteredHeadlines,
};
},
},
});

export const { setHeadlines, searchHeadlines } = headlinesSlice.actions;
export default headlinesSlice.reducer;
26 changes: 26 additions & 0 deletions features/publishers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { createSlice } from "@reduxjs/toolkit";
import { HYDRATE } from "next-redux-wrapper";
const publishersSlice = createSlice({
name: "publishers",
initialState: {
value: [],
isError: false,
isLoading: true,
},
reducers: {
setPublishers: (state, action) => {
return (state = action.payload);
},
},
extraReducers: {
[HYDRATE]: (state, action) => {
return {
...state,
...action.payload.auth,
};
},
},
});

export const { setPublishers } = publishersSlice.actions;
export default publishersSlice.reducer;
Loading