Skip to content
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: 4 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"presets": ["next/babel"],
"plugins": [["styled-components", { "ssr": true }]]
}
Empty file added =16.8.0
Empty file.
44 changes: 44 additions & 0 deletions =2.8.0
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
yarn add v1.22.5
[1/4] Resolving packages...
[2/4] Fetching packages...
info @next/swc-android-arm-eabi@13.0.6: The platform "win32" is incompatible with this module.
info "@next/swc-android-arm-eabi@13.0.6" is an optional dependency and failed compatibility check. Excluding it from installation.
info @next/swc-android-arm-eabi@13.0.6: The CPU architecture "x64" is incompatible with this module.
info @next/swc-android-arm64@13.0.6: The platform "win32" is incompatible with this module.
info "@next/swc-android-arm64@13.0.6" is an optional dependency and failed compatibility check. Excluding it from installation.
info @next/swc-android-arm64@13.0.6: The CPU architecture "x64" is incompatible with this module.
info @next/swc-darwin-arm64@13.0.6: The platform "win32" is incompatible with this module.
info "@next/swc-darwin-arm64@13.0.6" is an optional dependency and failed compatibility check. Excluding it from installation.
info @next/swc-darwin-arm64@13.0.6: The CPU architecture "x64" is incompatible with this module.
info @next/swc-darwin-x64@13.0.6: The platform "win32" is incompatible with this module.
info "@next/swc-darwin-x64@13.0.6" is an optional dependency and failed compatibility check. Excluding it from installation.
info @next/swc-freebsd-x64@13.0.6: The platform "win32" is incompatible with this module.
info "@next/swc-freebsd-x64@13.0.6" is an optional dependency and failed compatibility check. Excluding it from installation.
info @next/swc-linux-arm-gnueabihf@13.0.6: The platform "win32" is incompatible with this module.
info "@next/swc-linux-arm-gnueabihf@13.0.6" is an optional dependency and failed compatibility check. Excluding it from installation.
info @next/swc-linux-arm-gnueabihf@13.0.6: The CPU architecture "x64" is incompatible with this module.
info @next/swc-linux-arm64-gnu@13.0.6: The platform "win32" is incompatible with this module.
info "@next/swc-linux-arm64-gnu@13.0.6" is an optional dependency and failed compatibility check. Excluding it from installation.
info @next/swc-linux-arm64-gnu@13.0.6: The CPU architecture "x64" is incompatible with this module.
info @next/swc-linux-arm64-musl@13.0.6: The platform "win32" is incompatible with this module.
info "@next/swc-linux-arm64-musl@13.0.6" is an optional dependency and failed compatibility check. Excluding it from installation.
info @next/swc-linux-arm64-musl@13.0.6: The CPU architecture "x64" is incompatible with this module.
info @next/swc-linux-x64-gnu@13.0.6: The platform "win32" is incompatible with this module.
info "@next/swc-linux-x64-gnu@13.0.6" is an optional dependency and failed compatibility check. Excluding it from installation.
info @next/swc-linux-x64-musl@13.0.6: The platform "win32" is incompatible with this module.
info "@next/swc-linux-x64-musl@13.0.6" is an optional dependency and failed compatibility check. Excluding it from installation.
info @next/swc-win32-arm64-msvc@13.0.6: The CPU architecture "x64" is incompatible with this module.
info "@next/swc-win32-arm64-msvc@13.0.6" is an optional dependency and failed compatibility check. Excluding it from installation.
info @next/swc-win32-ia32-msvc@13.0.6: The CPU architecture "x64" is incompatible with this module.
info "@next/swc-win32-ia32-msvc@13.0.6" is an optional dependency and failed compatibility check. Excluding it from installation.
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved lockfile.
success Saved 2 new dependencies.
info Direct dependencies
├─ react-is@18.2.0
└─ typescript@4.9.4
info All dependencies
├─ react-is@18.2.0
└─ typescript@4.9.4
Done in 26.57s.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,19 @@ https://github.com/public-apis/public-apis
- Utilizar inglês no projeto todo.
- Utilizar Injeção de Dependências.
- Fazer deploy do mesmo (heroku, netlify, aws, vercel, github pages ou outro da preferência).

------------------------------------------------------

## APPLICATION TO FETCH CHESS.COM API

- Application made with Next.js
- Styled with styled components
- Responsive even on smaller screens
- Use of useEffects, useState, useContext
- Deployed on vercel

------------------------------------------------------

## VERCEL DEPLOYED APPLICATION

- https://frontend-test-two-jade.vercel.app/
99 changes: 99 additions & 0 deletions components/Cards/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import Link from "next/link";
import React, { useContext, useState } from "react";
import dataContext from "../../context/dataContext";
import {
Buttons,
Card,
CardsView,
Img,
Input,
InputButtons,
Space,
} from "./styles";

const Cards = () => {
const { board, setBoard, setSelectedItem } = useContext(dataContext);
const [originalBoard, setOriginalBoard] = useState([]);
const [currentPage, setCurrentPage] = useState(1);
const [itemsPerPage] = useState(15);

const indexOfLastItem = currentPage * itemsPerPage;
const indexOfFirstItem = indexOfLastItem - itemsPerPage;
const currentItems = board.slice(indexOfFirstItem, indexOfLastItem);

const handleClick = (item) => {
setSelectedItem(item);
};

const [filterValue, setFilterValue] = useState("");

const handleFilter = () => {
// lógica para filtrar jogadores com base no valor digitado no campo de entrada
setOriginalBoard(board);
const filteredPlayers = board.filter(
(player) => player.username.includes(filterValue)
// player.rank === Number(filterValue)
);
setBoard(filteredPlayers);
};

const handleClearFilter = () => {
setFilterValue("");
setBoard(originalBoard);
};

return (
<>
<Input
value={filterValue}
onChange={(e) => setFilterValue(e.target.value)}
placeholder={"Filter by name"}
/>
<InputButtons onClick={handleFilter}>Filter</InputButtons>
<InputButtons onClick={handleClearFilter}>Clear</InputButtons>
<CardsView>
{currentItems.length > 0 &&
currentItems.map((item) => (
<Card key={item.player_id} onClick={() => handleClick(item)}>
<div>
<Img src={item.avatar} alt="" />
</div>
<div>{item.username}</div>
<Space>
<div>
<strong>Rank: </strong>
{item.rank}
</div>
<div>
<strong> Score: </strong>
{item.score}
</div>
<Link
href={"/player/[username]"}
as={`/player/${item.username}`}
>
<button onClick={() => handleClick(item)}>
View Details
</button>
</Link>
</Space>
</Card>
))}
</CardsView>
<div>
{indexOfFirstItem > 0 && (
<Buttons onClick={() => setCurrentPage(currentPage - 1)}>
Previous
</Buttons>
)}
{indexOfLastItem < board.length && (
<Buttons onClick={() => setCurrentPage(currentPage + 1)}>
Next
</Buttons>
)}
</div>
</>
);
};

export default Cards;
76 changes: 76 additions & 0 deletions components/Cards/styles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import styled from "styled-components";

export const CardsView = styled.div`
width: 80%;
margin: auto;
margin-top: 16px;
display: flex;
flex-wrap: wrap;
justify-content: center;
`;

export const Card = styled.div`
background-color: #f1faee;
width: 200px;
margin: 0.5rem;
border: 1px solid;
`;

export const Img = styled.img`
width: 200px;
height: 200px;
`;

export const Space = styled.div`
display: flex;
justify-content: space-between;
padding: 0 0.8rem;
`;

export const Buttons = styled.button`
background-color: #52796f; /* Green */
border: none;
color: white;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 0.5rem;
margin-bottom: 16px;
width: 127px;
&:hover {
opacity: 80%;
}
cursor: pointer;
`;

export const DetailsButton = styled.button``;

export const Input = styled.input`
padding: 10px 10px;
display: inline-block;
font-size: 16px;
margin: 0 1rem;
width: 240px;
&:hover {
opacity: 80%;
}
`;

export const InputButtons = styled.button`
background-color: #52796f; /* Green */
border-color: gray;
color: white;
padding: 10px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 0 0.2rem;
width: 127px;
&:hover {
opacity: 80%;
}
cursor: pointer;
`;
135 changes: 135 additions & 0 deletions components/Layout/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import { useRouter } from "next/router";
import { useState } from "react";
import { ThemeProvider } from "styled-components";
import Title from "../Title";
import {
DarkTheme,
GlobalStyle,
HeaderStyle,
Hr,
LayoutButtoms,
LightTheme,
RightButtoms,
} from "./styles";
import { setCookie, parseCookies } from "nookies";

export default function Layout(props) {
const [theme, setTheme] = useState(
parseCookies("theme").theme || "LightTheme"
);
const isDarkTheme = theme === "DarkTheme";
const router = useRouter();

return (
<ThemeProvider theme={isDarkTheme ? DarkTheme : LightTheme}>
<div>
<HeaderStyle
className={`
flex flex-col w-2/3
bg-white text-gray-800 rounded-md
`}
>
<GlobalStyle />
<LayoutButtoms>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth={1.5}
stroke="currentColor"
className="w-2 h-2"
width={"36px"}
onClick={() => router.push("/")}
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M2.25 12l8.954-8.955c.44-.439 1.152-.439 1.591 0L21.75 12M4.5 9.75v10.125c0 .621.504 1.125 1.125 1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75M8.25 21h8.25"
/>
</svg>
</LayoutButtoms>
<div>
<Title>{props.title ? props.title : "Leaderboards"}</Title>
</div>

<RightButtoms>
<LayoutButtoms>
<div
onClick={() => {
if (theme === "LightTheme") {
setTheme("DarkTheme");
setCookie(null, "theme", "DarkTheme", {
maxAge: 86400 * 7,
path: "/",
});
}
if (theme === "DarkTheme") {
setTheme("LightTheme");
setCookie(null, "theme", "LightTheme", {
maxAge: 86400 * 7,
path: "/",
});
}
}}
>
{theme === "LightTheme" ? (
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth={1.5}
stroke="currentColor"
className="w-6 h-6"
width={"38px"}
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M21.752 15.002A9.718 9.718 0 0118 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 003 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 009.002-5.998z"
/>
</svg>
) : (
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth={1.5}
stroke="currentColor"
className="w-6 h-6"
width={"38px"}
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M12 3v2.25m6.364.386l-1.591 1.591M21 12h-2.25m-.386 6.364l-1.591-1.591M12 18.75V21m-4.773-4.227l-1.591 1.591M5.25 12H3m4.227-4.773L5.636 5.636M15.75 12a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0z"
/>
</svg>
)}
</div>
</LayoutButtoms>
<LayoutButtoms>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth={1.5}
stroke="currentColor"
className="w-6 h-6"
width={"38px"}
onClick={() => router.back()}
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M9 15L3 9m0 0l6-6M3 9h12a6 6 0 010 12h-3"
/>
</svg>
</LayoutButtoms>
</RightButtoms>
</HeaderStyle>
<Hr />
<div className="p-6">{props.children}</div>
</div>
</ThemeProvider>
);
}
Loading