Skip to content

Commit

Permalink
Simple chuck norris joke fetcher
Browse files Browse the repository at this point in the history
  • Loading branch information
Mark Chigrin authored Feb 6, 2022
1 parent 35a5d62 commit e51d8c5
Show file tree
Hide file tree
Showing 19 changed files with 9,090 additions and 1 deletion.
23 changes: 23 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*
22 changes: 21 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,21 @@
# chuck-norris
# Чак Норис челендж

## Это челендж который тебе предстоит пройти если ты хочешь вступить в наши ряды.

Идея простая, но реализация отнюдь.

- Есть Апи которое умеет получать шутки Чака Нориса - https://api.chucknorris.io/
- Нужно сделать интерфейс который бы по нажатию кнопки получал одну шутку и отображал ее на экране
- Нужно создать кнопку которая каждые 3 секунды показывает новую шутку и если нажать на нее еще раз показ шуток должен остановиться.
- Также нужно создать кнопку которая добавляет шутку в лист любимых шуток и если нажать еще раз она ее удалит из листа и при перезагрузке страницы они должны сохраняться. (используй localStorage)
- Нужно создать кнопку которая будет переходить в лист любимых шуток и оттуда можно удалить любую шутку
- Любимых шуток может отображаться максимум 10, после при добавление новой шутки самая первая удаляется, а новая добавляется в конец листа.
- Так же нужно создать кнопку которая очищает лист любимых шуток.

- Удели вниманию блокам в листе любимых шуток
https://www.figma.com/file/nYKrkNVMT4EdMIRV1idWGR/Chuck-Norris-WareFrame?node-id=0%3A1

- Обязательные технические требования:
- TypeScript
- Styled Components
- Библиотека для управления состоянием (redux, effector, mobx и т.п)
45 changes: 45 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"name": "chuck-norris",
"version": "0.1.0",
"private": true,
"dependencies": {
"@16bits/nes.css": "^2.3.2",
"@emotion/react": "^11.7.1",
"@emotion/styled": "^11.6.0",
"@fontsource/press-start-2p": "^4.5.1",
"@reduxjs/toolkit": "^1.7.2",
"@types/node": "^16.7.13",
"@types/react": "^17.0.20",
"@types/react-dom": "^17.0.9",
"clsx": "^1.1.1",
"modern-normalize": "^1.1.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-redux": "^7.2.6",
"react-router": "^6.2.1",
"react-router-dom": "^6.2.1",
"react-scripts": "5.0.0",
"typescript": "^4.4.2"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build"
},
"eslintConfig": {
"extends": [
"react-app"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
Binary file added public/favicon.ico
Binary file not shown.
15 changes: 15 additions & 0 deletions public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<title>Chuck Norris</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
15 changes: 15 additions & 0 deletions public/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"short_name": "Chuck Norris",
"name": "Chuck Norris jokes app",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}
3 changes: 3 additions & 0 deletions public/robots.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:
14 changes: 14 additions & 0 deletions src/app/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Provider } from "react-redux";
import { BrowserRouter } from "react-router-dom";

import { Pages } from "pages";

import { store } from "./store";

export const App: React.VFC = () => (
<Provider store={store}>
<BrowserRouter>
<Pages />
</BrowserRouter>
</Provider>
);
13 changes: 13 additions & 0 deletions src/app/store.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { configureStore } from "@reduxjs/toolkit";

import { api } from "services/api";

export const store = configureStore({
reducer: {
[api.reducerPath]: api.reducer,
},
middleware: (getDefaultMiddleware) => [
...getDefaultMiddleware(),
api.middleware,
],
});
5 changes: 5 additions & 0 deletions src/components/Button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import clsx from "clsx";

export const Button: React.FC<React.ComponentPropsWithRef<"button">> = (
props
) => <button {...props} className={clsx(props.className, "nes-btn")} />;
5 changes: 5 additions & 0 deletions src/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#root {
font-family: "Press Start 2P", cursive;
font-size: 16px;
height: 100vh;
}
16 changes: 16 additions & 0 deletions src/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from "react";
import ReactDOM from "react-dom";
import "modern-normalize/modern-normalize.css";
import "@fontsource/press-start-2p";
import "@16bits/nes.css/css/nes.min.css";

import { App } from "app";

import "./index.css";

ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById("root")
);
32 changes: 32 additions & 0 deletions src/pages/Main.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import styled from "@emotion/styled";
import { Button } from "components/Button";
import { useGetRandomJokeQuery } from "services/api";

const Container = styled.div`
display: grid;
place-items: center;
height: 100%;
margin: 0 auto;
max-width: 30rem;
`;

const Column = styled.div`
display: flex;
flex-direction: column;
justify-content: center;
gap: 2rem;
text-align: center;
`;

export const Main: React.VFC = () => {
const { data: joke, isLoading, refetch } = useGetRandomJokeQuery();
return (
<Container>
<Column>
{isLoading && "Loading..."}
{joke?.value}
<Button onClick={refetch}>Next cite</Button>
</Column>
</Container>
);
};
9 changes: 9 additions & 0 deletions src/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Route, Routes } from "react-router";

import { Main } from "./Main";

export const Pages = () => (
<Routes>
<Route path="/" element={<Main />} />
</Routes>
);
1 change: 1 addition & 0 deletions src/react-app-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/// <reference types="react-scripts" />
20 changes: 20 additions & 0 deletions src/services/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";

import { Joke } from "types";

export const api = createApi({
reducerPath: "chuckNorrisApi",
baseQuery: fetchBaseQuery({
baseUrl: "https://api.chucknorris.io/jokes/",
}),
endpoints: (build) => ({
getRandomJoke: build.query<Joke, void>({
query: () => "random",
}),
getJokeById: build.query<Joke, string>({
query: (id) => id,
}),
}),
});

export const { useGetRandomJokeQuery, useGetJokeByIdQuery } = api;
10 changes: 10 additions & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export interface Joke {
id: string;
url: string;
value: string;

// created_at: string;
// updated_at: string;
// icon_url: string;
// categories: string[];
}
20 changes: 20 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"baseUrl": "src"
},
"include": ["src"]
}
Loading

0 comments on commit e51d8c5

Please sign in to comment.