├── .vscode └── settings.json ├── next.config.js ├── .eslintrc ├── pages ├── _app.js ├── coin │ ├── DetailCoin.module.css │ └── [id].js └── index.js ├── components ├── SearchBar │ ├── SearchBar.jsx │ └── SearchBar.module.css ├── Coins │ └── Coins.jsx ├── Coin │ ├── Coin.module.css │ └── Coin.jsx └── Layout.jsx ├── package.json ├── .gitignore ├── styles └── globals.css └── README.md /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.fontFamily": "Apl2741" 3 | } -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | reactStrictMode: false, 3 | } 4 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "next", 4 | "next/core-web-vitals" 5 | ], 6 | "rules": { 7 | "@next/next/no-img-element": "off" 8 | } 9 | } -------------------------------------------------------------------------------- /pages/_app.js: -------------------------------------------------------------------------------- 1 | import '../styles/globals.css' 2 | 3 | function MyApp({ Component, pageProps }) { 4 | return ( 5 | <> 6 | 7 | 8 | ) 9 | } 10 | 11 | export default MyApp 12 | -------------------------------------------------------------------------------- /components/SearchBar/SearchBar.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import styles from './SearchBar.module.css' 3 | 4 | 5 | function SearchBar({ ...props }) { 6 | return ( 7 |
8 | 9 |
10 | ) 11 | } 12 | 13 | export default SearchBar 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "next-crypto-currency", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "next": "11.0.1", 13 | "react": "17.0.2", 14 | "react-dom": "17.0.2" 15 | }, 16 | "devDependencies": { 17 | "eslint": "7.30.0", 18 | "eslint-config-next": "11.0.1" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # local env files 28 | .env.local 29 | .env.development.local 30 | .env.test.local 31 | .env.production.local 32 | 33 | # vercel 34 | .vercel 35 | -------------------------------------------------------------------------------- /components/SearchBar/SearchBar.module.css: -------------------------------------------------------------------------------- 1 | .search_container { 2 | display: flex; 3 | justify-content: center; 4 | margin-bottom: 5rem; 5 | } 6 | 7 | .search_container input { 8 | width: 300px; 9 | } 10 | 11 | .coin_input { 12 | background: #222531; 13 | border: none; 14 | padding: 16px; 15 | border-radius: 4px; 16 | outline: none; 17 | height: 100%; 18 | width: 100%; 19 | color: #e2e2e2; 20 | font-size: 16px; 21 | } 22 | 23 | .coin_input::placeholder { 24 | color: #b8b5b5; 25 | font-size: 13px; 26 | } 27 | 28 | /* Media Query */ 29 | @media only screen and (max-width: 480px) { 30 | .search_container { 31 | margin-left: 8rem; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /pages/coin/DetailCoin.module.css: -------------------------------------------------------------------------------- 1 | .coin_page { 2 | display: flex; 3 | justify-content: center; 4 | height: 75vh; 5 | align-items: center; 6 | } 7 | 8 | .coin_container { 9 | display: flex; 10 | flex-direction: column; 11 | justify-content: center; 12 | align-items: center; 13 | border: 1px solid #2fffe5; 14 | border-radius: 10px; 15 | padding: 4rem; 16 | width: 400px; 17 | } 18 | 19 | .coin_image { 20 | margin-bottom: 1rem; 21 | } 22 | 23 | .coin_name { 24 | margin-bottom: 1rem; 25 | } 26 | 27 | .coin_ticker { 28 | margin-bottom: 1rem; 29 | } 30 | 31 | .coin_current { 32 | margin-bottom: 1rem; 33 | font-size: 2rem; 34 | } 35 | -------------------------------------------------------------------------------- /components/Coins/Coins.jsx: -------------------------------------------------------------------------------- 1 | import Coin from '../Coin/Coin' 2 | 3 | function Coins({ data }) { 4 | return ( 5 |
6 | {data.map(coin => ( 7 | 18 | ))} 19 |
20 | ) 21 | } 22 | 23 | export default Coins 24 | -------------------------------------------------------------------------------- /styles/globals.css: -------------------------------------------------------------------------------- 1 | a { 2 | color: inherit; 3 | text-decoration: none !important; 4 | } 5 | 6 | @import url("https://fonts.googleapis.com/css2?family=Mate+SC&display=swap"); 7 | 8 | * { 9 | box-sizing: border-box; 10 | margin: 0; 11 | padding: 0; 12 | font-family: "Mate SC", serif; 13 | } 14 | 15 | body { 16 | background-color: #101012 !important; 17 | } 18 | 19 | .coin_app { 20 | display: flex; 21 | flex-direction: column; 22 | align-items: center; 23 | margin-top: 10px; 24 | color: #fff; 25 | } 26 | 27 | /* Layout CSS */ 28 | .layout { 29 | height: 100%; 30 | width: 100%; 31 | } 32 | 33 | .header { 34 | display: flex; 35 | justify-content: center; 36 | } 37 | .coin_logo { 38 | height: 200px; 39 | width: 200px; 40 | } 41 | 42 | 43 | /* Media Query */ 44 | @media only screen and (max-width: 480px) { 45 | .header { 46 | margin-left: 7rem; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /pages/coin/[id].js: -------------------------------------------------------------------------------- 1 | import styles from './DetailCoin.module.css' 2 | import Layout from './../../components/Layout'; 3 | 4 | 5 | function CoinDetail({ data }) { 6 | return ( 7 | 8 |
9 |
10 | {data.name} 14 |

{data.name}

15 |

{data.symbol}

16 |

17 | {data.market_data.current_price.usd} 18 |

19 |
20 |
21 |
22 | ) 23 | } 24 | 25 | export default CoinDetail 26 | 27 | 28 | 29 | export async function getServerSideProps(context) { 30 | const id = context.params.id 31 | 32 | const res = await fetch(`https://api.coingecko.com/api/v3/coins/${id}`); 33 | const data = await res.json(); 34 | 35 | return { 36 | props: { 37 | data 38 | } 39 | }; 40 | } 41 | -------------------------------------------------------------------------------- /pages/index.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react' 2 | import Head from 'next/head' 3 | import Layout from '../components/Layout' 4 | import SearchBar from '../components/SearchBar/SearchBar' 5 | import Coins from '../components/Coins/Coins' 6 | 7 | 8 | export default function Home({ data }) { 9 | const [search, setSearch] = useState(''); 10 | 11 | const filteredAllCoins = data.filter(coin => 12 | coin.name.toLowerCase().includes(search.toLowerCase()) 13 | ); 14 | 15 | const handleChange = (e) => { 16 | setSearch(e.target.value.toLowerCase()) 17 | } 18 | 19 | return ( 20 | 21 |
22 | 23 | Next | Crypto Currency 24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 | 32 |
33 | ) 34 | } 35 | 36 | export const getServerSideProps = async () => { 37 | const res = await fetch("https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&order=market_cap_desc&per_page=20&page=1&sparkline=false&price_change_percentage=24h") 38 | const data = await res.json() 39 | 40 | return { 41 | props: { data } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /components/Coin/Coin.module.css: -------------------------------------------------------------------------------- 1 | .coin_container { 2 | display: flex; 3 | justify-content: center; 4 | color: #03f6ff; 5 | } 6 | 7 | .coin_row { 8 | display: flex; 9 | flex-direction: row; 10 | justify-content: flex-start; 11 | align-items: center; 12 | height: 80px; 13 | border-bottom: 1px solid #2e2e2e; 14 | width: 1000px; 15 | padding: 0rem 2rem; 16 | } 17 | 18 | .coin_row:hover { 19 | background: #171718; 20 | } 21 | 22 | .coin { 23 | display: flex; 24 | align-items: center; 25 | padding-right: 24px; 26 | } 27 | 28 | .coin_img { 29 | height: 30px; 30 | width: 30px; 31 | margin-right: 10px; 32 | } 33 | 34 | .coin_h1 { 35 | font-size: 16px; 36 | width: 150px; 37 | } 38 | 39 | .coin_symbol { 40 | text-transform: uppercase; 41 | } 42 | 43 | .coin_data { 44 | display: flex; 45 | text-align: right; 46 | justify-content: space-between; 47 | width: 100%; 48 | } 49 | 50 | .coin_price { 51 | width: 170px; 52 | margin-left: 4.5rem; 53 | text-align: center; 54 | } 55 | 56 | .coin_volume { 57 | width: 100px; 58 | } 59 | 60 | .coin_marketcap { 61 | width: 230px; 62 | } 63 | 64 | .coin_percent { 65 | width: 100px; 66 | } 67 | 68 | .red { 69 | color: #f00606; 70 | } 71 | 72 | .green { 73 | color: #13c783; 74 | } 75 | 76 | 77 | /* Media Query */ 78 | @media only screen and (max-width: 480px) { 79 | .coin_row { 80 | width: 500px; 81 | } 82 | .coin_volume { 83 | display: none; 84 | } 85 | } 86 | 87 | @media only screen and (max-width: 576px) { 88 | .coin_row { 89 | width: 600px; 90 | } 91 | .coin_volume { 92 | display: none; 93 | } 94 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 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). 2 | 3 | ## Getting Started 4 | 5 | First, run the development server: 6 | 7 | ```bash 8 | npm run dev 9 | # or 10 | yarn dev 11 | ``` 12 | 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! 29 | 30 | ## Deploy on Vercel 31 | 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. 33 | 34 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. 35 | -------------------------------------------------------------------------------- /components/Coin/Coin.jsx: -------------------------------------------------------------------------------- 1 | import Link from 'next/link' 2 | import styles from './Coin.module.css' 3 | 4 | 5 | function Coin(props) { 6 | 7 | const { id, name, price, symbol, image, volume, priceChange } = props 8 | 9 | return ( 10 | 11 | 12 |
13 |
14 |
15 | {name} 16 |

{name}

17 |

{symbol}

18 |
19 |
20 |

${price}

21 |

${volume.toLocaleString()} 22 |

23 | 24 | {priceChange < 0 ? ( 25 |

26 | {priceChange.toFixed(2)}% 27 |

28 | ) : ( 29 |

30 | {priceChange.toFixed(2)}% 31 |

32 | )} 33 |
34 |
35 |
36 |
37 | 38 | ) 39 | } 40 | 41 | export default Coin 42 | 43 | -------------------------------------------------------------------------------- /components/Layout.jsx: -------------------------------------------------------------------------------- 1 | import Head from 'next/head' 2 | import Link from 'next/link' 3 | 4 | 5 | function Layout({ children }) { 6 | return ( 7 |
8 | 9 | Nexy Crypto 10 | 11 | 12 |
13 | 14 | 15 | 23 | 28 | 33 | 41 | 45 | 49 | 53 | 54 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 |
70 | 71 |
{children}
72 | 73 |
74 | ) 75 | } 76 | 77 | export default Layout 78 | --------------------------------------------------------------------------------