├── src
├── index.css
├── main.jsx
├── App.jsx
└── components
│ ├── Navbar.jsx
│ ├── Pagination.jsx
│ ├── News.jsx
│ ├── NewsList.jsx
│ └── Footer.jsx
├── postcss.config.cjs
├── vite.config.js
├── tailwind.config.cjs
├── .gitignore
├── index.html
├── package.json
└── public
└── vite.svg
/src/index.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
--------------------------------------------------------------------------------
/postcss.config.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react'
3 |
4 | // https://vitejs.dev/config/
5 | export default defineConfig({
6 | plugins: [react()],
7 | })
8 |
--------------------------------------------------------------------------------
/src/main.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import ReactDOM from 'react-dom/client'
3 | import App from './App'
4 | import './index.css'
5 |
6 | ReactDOM.createRoot(document.getElementById('root')).render(
7 |
8 |
9 | ,
10 | )
11 |
--------------------------------------------------------------------------------
/tailwind.config.cjs:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | module.exports = {
3 | content: [
4 | "./index.html",
5 | "./src/**/*.{js,ts,jsx,tsx}",
6 | ],
7 | theme: {
8 | extend: {},
9 | },
10 | plugins: [require("daisyui")],
11 | daisyui: {
12 | darkTheme: "night",
13 | },
14 | }
--------------------------------------------------------------------------------
/src/App.jsx:
--------------------------------------------------------------------------------
1 | import Footer from './components/Footer'
2 | import Navbar from './components/Navbar'
3 | import NewsList from './components/NewsList'
4 |
5 | const App = () => {
6 | return (
7 | <>
8 |
9 |
10 |
11 | >
12 | )
13 | }
14 |
15 | export default App
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/src/components/Navbar.jsx:
--------------------------------------------------------------------------------
1 | const Navbar = () => {
2 | return (
3 |
9 | )
10 | }
11 |
12 | export default Navbar
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | News Information
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/components/Pagination.jsx:
--------------------------------------------------------------------------------
1 | const Pagination = ({ newsPerPage, totalNews, paginate }) => {
2 | const pageNumber = []
3 |
4 | for (let i = 1; i <= Math.ceil(totalNews / newsPerPage); i++) pageNumber.push(i)
5 |
6 | return (
7 |
8 |
9 | {pageNumber.map((number) => (
10 |
13 | ))}
14 |
15 |
16 | )
17 | }
18 |
19 | export default Pagination
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "news",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "vite build",
9 | "preview": "vite preview"
10 | },
11 | "dependencies": {
12 | "axios": "^1.2.2",
13 | "daisyui": "^2.46.1",
14 | "react": "^18.2.0",
15 | "react-dom": "^18.2.0"
16 | },
17 | "devDependencies": {
18 | "@types/react": "^18.0.26",
19 | "@types/react-dom": "^18.0.9",
20 | "@vitejs/plugin-react": "^3.0.0",
21 | "autoprefixer": "^10.4.13",
22 | "postcss": "^8.4.20",
23 | "tailwindcss": "^3.2.4",
24 | "vite": "^4.0.0"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/components/News.jsx:
--------------------------------------------------------------------------------
1 | const News = ({ news, loading }) => {
2 | if (loading) {
3 | return Loading...
4 | }
5 |
6 | return (
7 |
8 | {news.map((data, index) => (
9 |
10 |

11 |
12 |
13 | {data.title}
14 |
NEW
15 |
16 |
{data.description}
17 |
18 |
{data.author == null ? "Author" : data.author}
19 |
24 |
25 |
26 |
27 | ))}
28 |
29 | )
30 | }
31 |
32 | export default News
--------------------------------------------------------------------------------
/src/components/NewsList.jsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from "react"
2 | import axios from "axios"
3 | import News from "./News"
4 | import Pagination from "./Pagination"
5 |
6 | const NewsList = () => {
7 | const [datas, setDatas] = useState([])
8 | const [loading, setLoading] = useState(false)
9 | const [currentPage, setCurrentPage] = useState(1)
10 | const [newsPerPage, setNewsPerPage] = useState(9)
11 |
12 | useEffect(() => {
13 | const getNews = async () => {
14 | setLoading(true)
15 | try {
16 | const response = await axios.get('https://newsapi.org/v2/top-headlines?country=id&apiKey=affb50f0bd6648a49c80b2bd454845e1')
17 |
18 | setDatas(response.data.articles)
19 | } catch (e) {
20 | console.log(e);
21 | }
22 | setLoading(false)
23 | }
24 |
25 | getNews()
26 | }, [])
27 |
28 | const indexOfLastNews = currentPage * newsPerPage
29 | const indexOfFirstNews = indexOfLastNews - newsPerPage
30 | const currentNews = datas.slice(indexOfFirstNews, indexOfLastNews)
31 |
32 | const paginate = (pageNumber) => setCurrentPage(pageNumber)
33 |
34 | return (
35 |
36 |
News Information
37 |
38 |
39 |
40 | )
41 | }
42 |
43 | export default NewsList
--------------------------------------------------------------------------------
/public/vite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/Footer.jsx:
--------------------------------------------------------------------------------
1 | const Footer = () => {
2 | return (
3 |
14 | )
15 | }
16 |
17 | export default Footer
--------------------------------------------------------------------------------