├── .prettierignore ├── .eslintignore ├── public ├── bg-tile.png ├── bg-types.png ├── pokemon-egg.png ├── colored-logo.png ├── pokenex-screen.gif ├── typeIcons │ ├── bug.png │ ├── dark.png │ ├── fire.png │ ├── ice.png │ ├── rock.png │ ├── dragon.png │ ├── fairy.png │ ├── flying.png │ ├── ghost.png │ ├── grass.png │ ├── ground.png │ ├── normal.png │ ├── poison.png │ ├── steel.png │ ├── water.png │ ├── electric.png │ ├── fighting.png │ └── psychic.png ├── vercel.svg └── favicon.svg ├── next-env.d.ts ├── .prettierrc.json ├── next.config.js ├── pages ├── index.tsx ├── _document.tsx ├── 404.tsx ├── user │ └── [uid].tsx ├── leaderboard.tsx ├── profile.tsx ├── pokemon │ └── [pid].tsx ├── api │ ├── users.ts │ ├── user │ │ └── [userID].ts │ ├── signin.ts │ ├── delete │ │ └── [deleteID].ts │ ├── auth │ │ └── [...nextauth].ts │ └── update │ │ └── [updateID].ts ├── explore.tsx ├── play.tsx ├── _error.tsx └── _app.tsx ├── components ├── Profile │ ├── ProfilePage.tsx │ ├── UserPage.tsx │ ├── Favorites.tsx │ ├── _profile-page.scss │ └── ProfileComponent.tsx ├── PokemonPage │ ├── FlexBetween.tsx │ ├── PokemonPage.tsx │ ├── EvoStatCard.tsx │ ├── _pokemon-page.scss │ ├── Evolution.tsx │ └── BioTrainCard.tsx ├── AccessDenied │ └── AccessDenied.tsx ├── Leaderboard │ ├── _leaderboard.scss │ └── LeaderboardPage.tsx ├── Cards │ ├── EndCard.tsx │ ├── HiddenCard.tsx │ ├── FramerCard.tsx │ ├── Card.tsx │ ├── _card.scss │ └── Deck.tsx ├── InputComponents │ ├── Search.tsx │ ├── Sort.tsx │ └── FilterByType.tsx ├── Explore │ ├── UndoButton.tsx │ ├── _explore.scss │ └── ExplorePage.tsx ├── Nav │ ├── ActiveLink.tsx │ ├── _navbar.scss │ └── Nav.tsx ├── LandingPage │ ├── _landing-page.scss │ └── LandingPage.tsx ├── HeadTitle │ └── HeadTitle.tsx └── Game │ ├── GameOver.tsx │ ├── Options.tsx │ ├── _game.scss │ └── GamePage.tsx ├── lib ├── reduxHooks.ts ├── pokemonSlice.ts ├── useRefineItems.ts └── userSlice.ts ├── interfaces ├── next-auth.d.ts └── Interfaces.ts ├── utils ├── store.ts └── dataBaseConnection.ts ├── styles ├── styles.scss ├── _pages.scss └── _config.scss ├── .gitignore ├── models └── User.ts ├── tsconfig.json ├── helpers ├── getUsers.ts ├── getTypeIconsAndColor.ts ├── getPokemon.ts └── GlobalFunctions.ts ├── package.json ├── .eslintrc.js └── README.md /.prettierignore: -------------------------------------------------------------------------------- 1 | 2 | build 3 | coverage 4 | .vercel 5 | .next 6 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | 2 | build/* 3 | public/* 4 | docs/* 5 | templates/* 6 | -------------------------------------------------------------------------------- /public/bg-tile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kitharvey/pokenex/HEAD/public/bg-tile.png -------------------------------------------------------------------------------- /public/bg-types.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kitharvey/pokenex/HEAD/public/bg-types.png -------------------------------------------------------------------------------- /next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /public/pokemon-egg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kitharvey/pokenex/HEAD/public/pokemon-egg.png -------------------------------------------------------------------------------- /public/colored-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kitharvey/pokenex/HEAD/public/colored-logo.png -------------------------------------------------------------------------------- /public/pokenex-screen.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kitharvey/pokenex/HEAD/public/pokenex-screen.gif -------------------------------------------------------------------------------- /public/typeIcons/bug.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kitharvey/pokenex/HEAD/public/typeIcons/bug.png -------------------------------------------------------------------------------- /public/typeIcons/dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kitharvey/pokenex/HEAD/public/typeIcons/dark.png -------------------------------------------------------------------------------- /public/typeIcons/fire.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kitharvey/pokenex/HEAD/public/typeIcons/fire.png -------------------------------------------------------------------------------- /public/typeIcons/ice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kitharvey/pokenex/HEAD/public/typeIcons/ice.png -------------------------------------------------------------------------------- /public/typeIcons/rock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kitharvey/pokenex/HEAD/public/typeIcons/rock.png -------------------------------------------------------------------------------- /public/typeIcons/dragon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kitharvey/pokenex/HEAD/public/typeIcons/dragon.png -------------------------------------------------------------------------------- /public/typeIcons/fairy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kitharvey/pokenex/HEAD/public/typeIcons/fairy.png -------------------------------------------------------------------------------- /public/typeIcons/flying.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kitharvey/pokenex/HEAD/public/typeIcons/flying.png -------------------------------------------------------------------------------- /public/typeIcons/ghost.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kitharvey/pokenex/HEAD/public/typeIcons/ghost.png -------------------------------------------------------------------------------- /public/typeIcons/grass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kitharvey/pokenex/HEAD/public/typeIcons/grass.png -------------------------------------------------------------------------------- /public/typeIcons/ground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kitharvey/pokenex/HEAD/public/typeIcons/ground.png -------------------------------------------------------------------------------- /public/typeIcons/normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kitharvey/pokenex/HEAD/public/typeIcons/normal.png -------------------------------------------------------------------------------- /public/typeIcons/poison.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kitharvey/pokenex/HEAD/public/typeIcons/poison.png -------------------------------------------------------------------------------- /public/typeIcons/steel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kitharvey/pokenex/HEAD/public/typeIcons/steel.png -------------------------------------------------------------------------------- /public/typeIcons/water.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kitharvey/pokenex/HEAD/public/typeIcons/water.png -------------------------------------------------------------------------------- /public/typeIcons/electric.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kitharvey/pokenex/HEAD/public/typeIcons/electric.png -------------------------------------------------------------------------------- /public/typeIcons/fighting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kitharvey/pokenex/HEAD/public/typeIcons/fighting.png -------------------------------------------------------------------------------- /public/typeIcons/psychic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kitharvey/pokenex/HEAD/public/typeIcons/psychic.png -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "es5", 3 | "printWidth": 100, 4 | "semi": false, 5 | "tabWidth": 2 6 | } 7 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | images: { 3 | domains: ['raw.githubusercontent.com', 'avatars.githubusercontent.com'], 4 | }, 5 | } -------------------------------------------------------------------------------- /pages/index.tsx: -------------------------------------------------------------------------------- 1 | import HeadTitle from "@components/HeadTitle/HeadTitle" 2 | import LandingPage from "@components/LandingPage/LandingPage" 3 | 4 | const Home = () => { 5 | return ( 6 | <> 7 | 8 | 9 | 10 | ) 11 | } 12 | 13 | export default Home 14 | -------------------------------------------------------------------------------- /components/Profile/ProfilePage.tsx: -------------------------------------------------------------------------------- 1 | import { useAppSelector } from "@lib/reduxHooks" 2 | import ProfileComponent from "./ProfileComponent" 3 | 4 | const ProfilePage = () => { 5 | const { userData } = useAppSelector((state) => state.user) 6 | 7 | return <>{userData && } 8 | } 9 | 10 | export default ProfilePage 11 | -------------------------------------------------------------------------------- /lib/reduxHooks.ts: -------------------------------------------------------------------------------- 1 | import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux" 2 | import type { RootState, AppDispatch } from "@utils/store" 3 | 4 | // Use throughout your app instead of plain `useDispatch` and `useSelector` 5 | export const useAppDispatch = () => useDispatch() 6 | export const useAppSelector: TypedUseSelectorHook = useSelector 7 | -------------------------------------------------------------------------------- /interfaces/next-auth.d.ts: -------------------------------------------------------------------------------- 1 | import NextAuth from "next-auth" 2 | 3 | declare module "next-auth" { 4 | /** 5 | * Returned by `useSession`, `getSession` and received as a prop on the `Provider` React Context 6 | */ 7 | export interface Session { 8 | user: { 9 | name?: string | null 10 | picture?: string | null 11 | uid?: string | null 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /pages/_document.tsx: -------------------------------------------------------------------------------- 1 | import NextDocument, { Html, Head, Main, NextScript } from "next/document" 2 | 3 | class Document extends NextDocument { 4 | render() { 5 | return ( 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | ) 14 | } 15 | } 16 | 17 | export default Document 18 | -------------------------------------------------------------------------------- /pages/404.tsx: -------------------------------------------------------------------------------- 1 | import HeadTitle from "@components/HeadTitle/HeadTitle" 2 | import React from "react" 3 | 4 | const Error404 = () => { 5 | return ( 6 |
7 | 8 |

404

9 |

This page could not be found.

10 |
11 | ) 12 | } 13 | 14 | export default Error404 15 | -------------------------------------------------------------------------------- /utils/store.ts: -------------------------------------------------------------------------------- 1 | import { configureStore } from "@reduxjs/toolkit" 2 | import userReducer from "@lib/userSlice" 3 | import pokemonReducer from "@lib/pokemonSlice" 4 | 5 | export const store = configureStore({ 6 | reducer: { 7 | user: userReducer, 8 | pokemon: pokemonReducer, 9 | }, 10 | }) 11 | 12 | export type RootState = ReturnType 13 | export type AppDispatch = typeof store.dispatch 14 | -------------------------------------------------------------------------------- /utils/dataBaseConnection.ts: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose" 2 | 3 | async function dbConnect() { 4 | if (mongoose.connection.readyState >= 1) { 5 | return false 6 | } 7 | 8 | return mongoose.connect(`${process.env.MONGODB_URI}`, { 9 | useNewUrlParser: true, 10 | useUnifiedTopology: true, 11 | useFindAndModify: false, 12 | useCreateIndex: true, 13 | }) 14 | } 15 | 16 | export default dbConnect 17 | -------------------------------------------------------------------------------- /components/PokemonPage/FlexBetween.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | 3 | type FlexBetweenProps = { 4 | category: string 5 | details: React.ReactNode 6 | } 7 | 8 | const FlexBetween: React.FC = ({ category, details }) => ( 9 |
10 |

{category}

11 |
{details}
12 |
13 | ) 14 | 15 | export default FlexBetween 16 | -------------------------------------------------------------------------------- /pages/user/[uid].tsx: -------------------------------------------------------------------------------- 1 | import AccessDenied from "@components/AccessDenied/AccessDenied" 2 | import UserPage from "@components/Profile/UserPage" 3 | import { useSession } from "next-auth/client" 4 | import { useRouter } from "next/router" 5 | import React from "react" 6 | 7 | const User = () => { 8 | const [session] = useSession() 9 | const router = useRouter() 10 | 11 | if (!session) return 12 | 13 | return <>{router.query.uid && } 14 | } 15 | 16 | export default User 17 | -------------------------------------------------------------------------------- /styles/styles.scss: -------------------------------------------------------------------------------- 1 | @import "config"; 2 | @import "@components/Nav/navbar"; 3 | @import "@components/Leaderboard/leaderboard"; 4 | @import "@components/Cards/card"; 5 | @import "@components/Explore/explore"; 6 | @import "@components/Game/game"; 7 | @import "@components/Profile/profile-page"; 8 | @import "@components/PokemonPage/pokemon-page"; 9 | @import "@components/LandingPage/landing-page"; 10 | @import "pages"; 11 | 12 | a { 13 | color: inherit; 14 | text-decoration: none; 15 | } 16 | 17 | * { 18 | box-sizing: border-box; 19 | } 20 | -------------------------------------------------------------------------------- /pages/leaderboard.tsx: -------------------------------------------------------------------------------- 1 | import LeaderboardPage from "@components/Leaderboard/LeaderboardPage" 2 | import HeadTitle from "@components/HeadTitle/HeadTitle" 3 | import { useSession } from "next-auth/client" 4 | import AccessDenied from "@components/AccessDenied/AccessDenied" 5 | 6 | const Leaderboard = () => { 7 | const [session] = useSession() 8 | if (!session) return 9 | return ( 10 | <> 11 | 12 | 13 | 14 | ) 15 | } 16 | 17 | export default Leaderboard 18 | -------------------------------------------------------------------------------- /.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 | 36 | .vercel 37 | -------------------------------------------------------------------------------- /pages/profile.tsx: -------------------------------------------------------------------------------- 1 | import AccessDenied from "@components/AccessDenied/AccessDenied" 2 | import HeadTitle from "@components/HeadTitle/HeadTitle" 3 | import ProfilePage from "@components/Profile/ProfilePage" 4 | import { useSession } from "next-auth/client" 5 | 6 | const Profile = () => { 7 | const [session] = useSession() 8 | if (!session) return 9 | return ( 10 | <> 11 | 12 | 13 | 14 | ) 15 | } 16 | 17 | export default Profile 18 | -------------------------------------------------------------------------------- /components/Profile/UserPage.tsx: -------------------------------------------------------------------------------- 1 | import HeadTitle from "@components/HeadTitle/HeadTitle" 2 | import { getUsers } from "@helpers/getUsers" 3 | import useSWR from "swr" 4 | import ProfileComponent from "./ProfileComponent" 5 | 6 | const UserPage: React.FC<{ id: string | string[] }> = ({ id }) => { 7 | const { data } = useSWR(`/api/user/${id}`, getUsers) 8 | return ( 9 | <> 10 | 11 | {data && } 12 | 13 | ) 14 | } 15 | 16 | export default UserPage 17 | -------------------------------------------------------------------------------- /models/User.ts: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose" 2 | 3 | const userSchema = new mongoose.Schema({ 4 | uid: { 5 | type: String, 6 | required: true, 7 | }, 8 | name: { 9 | type: String, 10 | required: true, 11 | }, 12 | picture: { 13 | type: String, 14 | required: true, 15 | }, 16 | favorites: [ 17 | { 18 | id: Number, 19 | name: String, 20 | types: [String], 21 | sprite: String, 22 | }, 23 | ], 24 | score: { 25 | type: Number, 26 | default: 0, 27 | }, 28 | }) 29 | 30 | export default mongoose.models.User || mongoose.model("User", userSchema) 31 | -------------------------------------------------------------------------------- /pages/pokemon/[pid].tsx: -------------------------------------------------------------------------------- 1 | import HeadTitle from "@components/HeadTitle/HeadTitle" 2 | import PokemonPage from "@components/PokemonPage/PokemonPage" 3 | import { useAppSelector } from "@lib/reduxHooks" 4 | import Case from "case" 5 | 6 | const Pokemon = () => { 7 | const { pokemonData } = useAppSelector((state) => state.pokemon) 8 | 9 | return ( 10 | <> 11 | 16 | 17 | 18 | ) 19 | } 20 | 21 | export default Pokemon 22 | -------------------------------------------------------------------------------- /pages/api/users.ts: -------------------------------------------------------------------------------- 1 | import type { NextApiRequest, NextApiResponse } from "next" 2 | import User from "@models/User" 3 | import dbConnect from "@utils/dataBaseConnection" 4 | 5 | export default async (req: NextApiRequest, res: NextApiResponse) => { 6 | await dbConnect() 7 | const { method } = req 8 | if (method === "GET") { 9 | try { 10 | const users = await User.find() 11 | return res.status(200).json(users) 12 | } catch (error) { 13 | return res.status(500).json({ message: error.message }) 14 | } 15 | } else { 16 | return res.status(400).json({ message: "invalid method" }) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /components/AccessDenied/AccessDenied.tsx: -------------------------------------------------------------------------------- 1 | import HeadTitle from "@components/HeadTitle/HeadTitle" 2 | import { signIn } from "next-auth/client" 3 | import { FaGithub } from "react-icons/fa" 4 | 5 | const AccessDenied = () => { 6 | return ( 7 |
8 | 9 |

Access Denied

10 |

You must be signed in to view this page

11 | 14 |
15 | ) 16 | } 17 | 18 | export default AccessDenied 19 | -------------------------------------------------------------------------------- /components/Leaderboard/_leaderboard.scss: -------------------------------------------------------------------------------- 1 | .leaderboard-page { 2 | margin-top: 40px; 3 | 4 | .table-wrapper { 5 | .table-head, 6 | .table-row { 7 | display: grid; 8 | grid-template-columns: repeat(3, 1fr); 9 | align-items: center; 10 | justify-items: center; 11 | height: 40px; 12 | } 13 | .table-row { 14 | font-weight: 300; 15 | cursor: pointer; 16 | border-radius: 5px; 17 | transition: all 0.1s ease-in-out; 18 | &:hover { 19 | background: #00000025; 20 | } 21 | } 22 | } 23 | } 24 | 25 | .spinner-wrapper { 26 | position: fixed; 27 | bottom: 50px; 28 | right: 50px; 29 | } 30 | -------------------------------------------------------------------------------- /components/Cards/EndCard.tsx: -------------------------------------------------------------------------------- 1 | import Image from "next/image" 2 | import React from "react" 3 | 4 | const EndCard: React.FC = () => { 5 | return ( 6 |
7 |
13 | pokemon egg 21 |

End of Deck

22 |
23 |
24 | ) 25 | } 26 | 27 | export default EndCard 28 | -------------------------------------------------------------------------------- /components/InputComponents/Search.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import { FaSearch } from "react-icons/fa" 3 | 4 | interface SearchProps { 5 | handleSearch: (event: React.ChangeEvent) => void 6 | searchValue: string 7 | } 8 | 9 | const Search: React.FC = ({ handleSearch, searchValue }) => { 10 | return ( 11 |
12 | 13 | 22 |
23 | ) 24 | } 25 | 26 | export default Search 27 | -------------------------------------------------------------------------------- /pages/explore.tsx: -------------------------------------------------------------------------------- 1 | import ExplorePage from "@components/Explore/ExplorePage" 2 | import HeadTitle from "@components/HeadTitle/HeadTitle" 3 | import { fetchExploreList } from "@helpers/getPokemon" 4 | import { PokemonDataInterface } from "@interfaces/Interfaces" 5 | import { InferGetStaticPropsType } from "next" 6 | 7 | export const getStaticProps = async () => { 8 | const list = await fetchExploreList() 9 | return { 10 | props: { 11 | pokemons: list, 12 | }, 13 | } 14 | } 15 | 16 | const Explore = ({ pokemons }: InferGetStaticPropsType) => { 17 | return ( 18 | <> 19 | 20 | {pokemons && } 21 | 22 | ) 23 | } 24 | 25 | export default Explore 26 | -------------------------------------------------------------------------------- /components/Explore/UndoButton.tsx: -------------------------------------------------------------------------------- 1 | import { motion } from "framer-motion" 2 | import React from "react" 3 | import { FaUndoAlt } from "react-icons/fa" 4 | 5 | interface UndoProps { 6 | handleUndo: () => void 7 | } 8 | 9 | const UndoButton: React.FC = ({ handleUndo }) => { 10 | return ( 11 | handleUndo()} 14 | style={{ 15 | boxShadow: "rgba(0, 0, 0, 0.314) 0 0px 10px 1px", 16 | }} 17 | whileTap={{ 18 | rotate: -180, 19 | }} 20 | whileHover={{ 21 | cursor: "pointer", 22 | boxShadow: "rgba(0, 0, 0, 0.314) 0px 0px 15px 1px", 23 | }} 24 | > 25 | 26 | 27 | ) 28 | } 29 | 30 | export default UndoButton 31 | -------------------------------------------------------------------------------- /components/Nav/ActiveLink.tsx: -------------------------------------------------------------------------------- 1 | import { useRouter } from "next/router" 2 | import Link from "next/link" 3 | import React, { Children } from "react" 4 | 5 | interface ActiveLinkProps { 6 | children: JSX.Element 7 | activeClassName: string 8 | href: string 9 | } 10 | 11 | const ActiveLink: React.FC = ({ children, activeClassName, ...props }) => { 12 | const { asPath } = useRouter() 13 | const child = Children.only(children) 14 | const childClassName = child.props.className || "" 15 | 16 | const className = 17 | asPath === props.href ? `${childClassName} ${activeClassName}`.trim() : childClassName 18 | 19 | return ( 20 | 21 | {React.cloneElement(child, { 22 | className: className || null, 23 | })} 24 | 25 | ) 26 | } 27 | 28 | export default ActiveLink 29 | -------------------------------------------------------------------------------- /pages/play.tsx: -------------------------------------------------------------------------------- 1 | import GamePage from "@components/Game/GamePage" 2 | import { InferGetServerSidePropsType } from "next" 3 | import { fetchPlayList } from "@helpers/getPokemon" 4 | import HeadTitle from "@components/HeadTitle/HeadTitle" 5 | 6 | export const getStaticProps = async () => { 7 | const pokemons = await fetchPlayList() 8 | if (!pokemons) { 9 | return { 10 | redirect: { 11 | destination: "/", 12 | permanent: false, 13 | }, 14 | } 15 | } 16 | 17 | return { 18 | props: { 19 | pokemons, 20 | }, 21 | } 22 | } 23 | 24 | const Play = ({ pokemons }: InferGetServerSidePropsType) => { 25 | return ( 26 | <> 27 | 28 | {pokemons && } 29 | 30 | ) 31 | } 32 | 33 | export default Play 34 | -------------------------------------------------------------------------------- /components/InputComponents/Sort.tsx: -------------------------------------------------------------------------------- 1 | import { SortKey } from "@lib/useRefineItems" 2 | import React from "react" 3 | import { FaSort } from "react-icons/fa" 4 | 5 | interface FilterByTypeProps { 6 | handleSort: (event: React.ChangeEvent) => void 7 | sortValue: SortKey | null 8 | } 9 | 10 | const Sort: React.FC = ({ handleSort, sortValue }) => { 11 | return ( 12 |
13 | 14 | 24 |
25 | ) 26 | } 27 | 28 | export default Sort 29 | -------------------------------------------------------------------------------- /pages/api/user/[userID].ts: -------------------------------------------------------------------------------- 1 | import type { NextApiRequest, NextApiResponse } from "next" 2 | import User from "@models/User" 3 | import dbConnect from "@utils/dataBaseConnection" 4 | import { getSession } from "next-auth/client" 5 | 6 | export default async (req: NextApiRequest, res: NextApiResponse) => { 7 | await dbConnect() 8 | const session = getSession({ req }) 9 | const { userID } = req.query 10 | const { method } = req 11 | if (method === "GET" && session) { 12 | try { 13 | const user = await User.findById(userID) 14 | if (user) { 15 | return res.json({ user }) 16 | } 17 | return res.status(404).json({ message: "Cannot find user" }) 18 | } catch (err) { 19 | return res.status(400).json({ err }) 20 | } 21 | } else { 22 | return res.status(400).json({ message: "invalid method or not authorized" }) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /components/LandingPage/_landing-page.scss: -------------------------------------------------------------------------------- 1 | .landing-page { 2 | width: 100%; 3 | min-height: 80vh; 4 | display: flex; 5 | justify-content: space-between; 6 | align-items: center; 7 | 8 | .right { 9 | display: none; 10 | @media screen and (min-width: 640px) { 11 | display: block; 12 | } 13 | .card-wrapper { 14 | height: 315px; 15 | width: 240px; 16 | 17 | button { 18 | display: none; 19 | } 20 | .name { 21 | font-size: medium; 22 | } 23 | } 24 | } 25 | 26 | .left { 27 | h1 { 28 | line-height: 1.2; 29 | } 30 | .button-wrapper { 31 | margin-top: 20px; 32 | button { 33 | margin-right: 10px; 34 | } 35 | } 36 | .signin { 37 | font-size: smaller; 38 | button:hover { 39 | color: $color-accent-dark; 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /pages/_error.tsx: -------------------------------------------------------------------------------- 1 | import HeadTitle from "@components/HeadTitle/HeadTitle" 2 | import type { NextPageContext } from "next" 3 | 4 | interface ErrorProps { 5 | statusCode: number 6 | message: string 7 | } 8 | 9 | function Error({ statusCode, message }: ErrorProps) { 10 | return ( 11 |
12 | 13 | {statusCode &&

{statusCode}

} 14 | {message &&

{message}

} 15 |
16 | ) 17 | } 18 | 19 | Error.getInitialProps = ({ res, err }: NextPageContext) => { 20 | let statusCode 21 | let message 22 | if (res) { 23 | statusCode = res.statusCode 24 | message = res.statusMessage 25 | } 26 | if (err) { 27 | statusCode = err.statusCode 28 | message = err.message 29 | } 30 | 31 | return { statusCode, message } 32 | } 33 | 34 | export default Error 35 | -------------------------------------------------------------------------------- /pages/api/signin.ts: -------------------------------------------------------------------------------- 1 | import type { NextApiRequest, NextApiResponse } from "next" 2 | import User from "@models/User" 3 | import dbConnect from "@utils/dataBaseConnection" 4 | 5 | export default async (req: NextApiRequest, res: NextApiResponse) => { 6 | await dbConnect() 7 | 8 | let user 9 | const { uid, name, picture } = req.body 10 | const { method } = req 11 | if (method === "POST") { 12 | try { 13 | const isUserAlready = await User.findOne({ uid }) 14 | if (isUserAlready) { 15 | user = isUserAlready 16 | return res.status(200).json({ user }) 17 | } 18 | const newuser = new User({ uid, name, picture }) 19 | user = await newuser.save() 20 | return res.status(201).json({ user }) 21 | } catch (err) { 22 | return res.status(400).json({ err }) 23 | } 24 | } else { 25 | return res.status(400).json({ message: "invalid method" }) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /components/Cards/HiddenCard.tsx: -------------------------------------------------------------------------------- 1 | import { getPokemonImage } from "@helpers/GlobalFunctions" 2 | import { NameIDInterface } from "@interfaces/Interfaces" 3 | import Image from "next/image" 4 | import React from "react" 5 | 6 | interface ExploreCardProps { 7 | pokemon: NameIDInterface 8 | reveal: boolean 9 | } 10 | 11 | const HiddenCard: React.FC = ({ pokemon, reveal }) => { 12 | const imgsrc = getPokemonImage(+pokemon.id) 13 | return ( 14 |
15 |
21 |
22 | hidden pokemon 23 |
24 |
25 |
26 | ) 27 | } 28 | 29 | export default HiddenCard 30 | -------------------------------------------------------------------------------- /pages/api/delete/[deleteID].ts: -------------------------------------------------------------------------------- 1 | import type { NextApiRequest, NextApiResponse } from "next" 2 | import User from "@models/User" 3 | import dbConnect from "@utils/dataBaseConnection" 4 | import { getSession } from "next-auth/client" 5 | 6 | export default async (req: NextApiRequest, res: NextApiResponse) => { 7 | await dbConnect() 8 | const session = getSession({ req }) 9 | const { deleteID } = req.query 10 | const { method } = req 11 | if (method === "DELETE" && session) { 12 | try { 13 | const isUserAlready = await User.findById(deleteID) 14 | if (isUserAlready) { 15 | isUserAlready.remove() 16 | return res.json({ message: `Account was deleted` }) 17 | } 18 | return res.status(404).json({ message: "Cannot find user" }) 19 | } catch (err) { 20 | return res.status(400).json({ err }) 21 | } 22 | } else { 23 | return res.status(400).json({ message: "invalid method or not authorized" }) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /pages/api/auth/[...nextauth].ts: -------------------------------------------------------------------------------- 1 | import NextAuth from "next-auth" 2 | import Providers from "next-auth/providers" 3 | import { NextApiRequest, NextApiResponse } from "next" 4 | 5 | export default (req: NextApiRequest, res: NextApiResponse) => 6 | NextAuth(req, res, { 7 | providers: [ 8 | Providers.GitHub({ 9 | clientId: process.env.GITHUB_CLIENT_ID, 10 | clientSecret: process.env.GITHUB_CLIENT_SECRET, 11 | scope: "read:user", 12 | }), 13 | ], 14 | session: { 15 | maxAge: 60 * 60 * 24, 16 | }, 17 | secret: process.env.AUTH_SECRET, 18 | jwt: { 19 | secret: process.env.JWT_SECRET, 20 | }, 21 | callbacks: { 22 | session: async (session, user) => { 23 | session.user = user 24 | session.user = { 25 | name: user.name, 26 | picture: user.picture as string, 27 | uid: user.sub as string, 28 | } 29 | return Promise.resolve(session) 30 | }, 31 | }, 32 | }) 33 | -------------------------------------------------------------------------------- /styles/_pages.scss: -------------------------------------------------------------------------------- 1 | .page { 2 | width: 100%; 3 | min-height: 80vh; 4 | height: max-content; 5 | display: flex; 6 | flex-direction: column; 7 | align-items: center; 8 | justify-content: center; 9 | user-select: none; 10 | 11 | .black-button { 12 | border-radius: 5px; 13 | margin-top: 10px; 14 | font-size: 1rem; 15 | padding: 5px 10px; 16 | } 17 | } 18 | 19 | .error-page { 20 | width: 100%; 21 | min-height: 80vh; 22 | height: max-content; 23 | display: flex; 24 | align-items: center; 25 | justify-content: center; 26 | 27 | .status-code { 28 | display: inline-block; 29 | border-right: 1px solid rgba(0, 0, 0, 0.3); 30 | margin: 0; 31 | margin-right: 20px; 32 | padding: 10px 23px 10px 0; 33 | font-size: 24px; 34 | font-weight: 500; 35 | vertical-align: top; 36 | } 37 | .message { 38 | font-size: 14px; 39 | font-weight: normal; 40 | line-height: inherit; 41 | margin: 0; 42 | padding: 0; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowJs": true, 4 | "alwaysStrict": true, 5 | "esModuleInterop": true, 6 | "forceConsistentCasingInFileNames": true, 7 | "isolatedModules": true, 8 | "jsx": "preserve", 9 | "lib": ["dom", "es2019"], 10 | "module": "esnext", 11 | "moduleResolution": "node", 12 | "noEmit": true, 13 | "noFallthroughCasesInSwitch": true, 14 | "noUnusedLocals": true, 15 | "noUnusedParameters": true, 16 | "resolveJsonModule": true, 17 | "skipLibCheck": true, 18 | "strict": true, 19 | "target": "esnext", 20 | "baseUrl": "./", 21 | "paths": { 22 | "@models/*": ["models/*"], 23 | "@utils/*": ["utils/*"], 24 | "@components/*": ["components/*"], 25 | "@lib/*": ["lib/*"], 26 | "@helpers/*": ["helpers/*"], 27 | "@interfaces/*": ["interfaces/*"], 28 | "@styles/*": ["styles/*"] 29 | } 30 | }, 31 | 32 | "exclude": ["node_modules"], 33 | "include": ["**/*.ts", "**/*.tsx"] 34 | } 35 | -------------------------------------------------------------------------------- /pages/api/update/[updateID].ts: -------------------------------------------------------------------------------- 1 | import type { NextApiRequest, NextApiResponse } from "next" 2 | import User from "@models/User" 3 | import dbConnect from "@utils/dataBaseConnection" 4 | import { getSession } from "next-auth/client" 5 | 6 | export default async (req: NextApiRequest, res: NextApiResponse) => { 7 | await dbConnect() 8 | const session = getSession({ req }) 9 | const { 10 | method, 11 | query: { updateID }, 12 | body, 13 | } = req 14 | if (method === "PATCH" && session) { 15 | try { 16 | const isUserAlready = await User.findById(updateID) 17 | if (isUserAlready) { 18 | isUserAlready[body.key] = body[body.key] 19 | const user = await isUserAlready.save() 20 | return res.status(202).json({ user }) 21 | } 22 | return res.status(404).json({ message: "Cannot find user" }) 23 | } catch (err) { 24 | return res.status(400).json({ err }) 25 | } 26 | } else { 27 | return res.status(400).json({ message: "invalid method or not authorized" }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /public/vercel.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import Router from "next/router" 2 | import type { AppProps } from "next/app" 3 | import { Provider as ReduxProvider } from "react-redux" 4 | import { Provider as NextAuthProvider } from "next-auth/client" 5 | import ProgressBar from "@badrap/bar-of-progress" 6 | import Nav from "@components/Nav/Nav" 7 | import "@styles/styles.scss" 8 | import { store } from "@utils/store" 9 | 10 | const progress = new ProgressBar({ 11 | size: 2, 12 | color: "#ff5a5f", 13 | className: "bar-of-progress", 14 | delay: 100, 15 | }) 16 | 17 | Router.events.on("routeChangeStart", progress.start) 18 | Router.events.on("routeChangeComplete", progress.finish) 19 | Router.events.on("routeChangeError", progress.finish) 20 | 21 | const MyApp = ({ Component, pageProps }: AppProps) => { 22 | return ( 23 | 24 | 25 |