Skip to content

Commit

Permalink
layout added
Browse files Browse the repository at this point in the history
  • Loading branch information
onair-lena committed Jul 16, 2023
1 parent 5777441 commit bae1b9d
Show file tree
Hide file tree
Showing 12 changed files with 833 additions and 544 deletions.
6 changes: 6 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"trailingComma": "es5",
"tabWidth": 2,
"semi": true,
"singleQuote": true
}
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,27 @@
"dependencies": {
"@emotion/react": "^11.5.0",
"@emotion/styled": "^11.3.0",
"@mui/icons-material": "^5.14.0",
"@mui/material": "^5.0.6",
"@mui/styles": "^5.0.2",
"@mui/system": "^5.0.6",
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
"@types/node": "^16.11.6",
"@types/react": "^17.0.33",
"@types/react-dom": "^17.0.10",
"@types/react": "^18.2.15",
"@types/react-dom": "^18.2.7",
"add": "^2.0.6",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-router-dom": "^6.14.1",
"react-scripts": "4.0.3",
"typescript": "^4.4.4",
"web-vitals": "^1.0.1",
"yarn": "^1.22.17"
},
"scripts": {
"start": "react-scripts start",
"start": "export SET NODE_OPTIONS=--openssl-legacy-provider && react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
Expand Down
25 changes: 25 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Route, Routes } from 'react-router-dom';
import { Header } from './components/Header';
import Layout from './pages/Layout';

import { Categories } from './pages/Categories';
import { Home } from './pages/Home';

const navItems = [
{ name: 'Home', path: '/', component: <Home /> },
{ name: 'Categories', path: '/categories', component: <Categories /> },
];

export const App = () => {
return (
<Layout header={<Header navItems={navItems} />}>
<Routes>
{navItems.map(({ path, component }) => (
<>
<Route path={path} element={component} />
</>
))}
</Routes>
</Layout>
);
};
43 changes: 14 additions & 29 deletions src/components/CategoriesList.tsx
Original file line number Diff line number Diff line change
@@ -1,51 +1,36 @@
import { Box, MenuItem, TextField, Typography } from "@mui/material";
import * as React from "react";
import { useState, useEffect } from "react";
import { URL_CATEGORIES, URL_CATEGORY_SEARCH } from "../utils/api";
import { ChuckNorrisResponse } from "../utils/response_type";
import { Box, MenuItem, TextField, Typography } from '@mui/material';
import * as React from 'react';
import { useEffect } from 'react';
import { URL_CATEGORIES, URL_CATEGORY_SEARCH } from '../utils/api';
import { ChuckNorrisResponse } from '../utils/response_type';
import { useFetchData } from '../utils/requests';

const CategoriesList = () => {
const [categories, setCategories] = useState<string[]>([]);
const [jokeByCategory, setJokeByCategory] = useState<ChuckNorrisResponse>({
categories: "",
value: "",
id: "",
});
const { data: categories, getData: getCategories } = useFetchData<string[]>();

const getCategories = () => {
fetch(URL_CATEGORIES).then(async (response) => {
const data: string[] = await response.json();
setCategories(data);
});
};

const getJokeByCategory = (category: string) => {
fetch(`${URL_CATEGORY_SEARCH}${category}`).then(async (response) => {
const data: ChuckNorrisResponse = await response.json();
setJokeByCategory(data);
});
};
const { data: jokeByCategory, getData: getJokeByCategory } =
useFetchData<ChuckNorrisResponse>();

useEffect(() => {
getCategories();
getCategories(URL_CATEGORIES);
}, []);

const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
getJokeByCategory(event.target.value);
getJokeByCategory(`${URL_CATEGORY_SEARCH}${event.target.value}`);
};

return (
<>
<Box display="flex" justifyContent="center" my={2}>
<TextField
sx={{ width: "300px" }}
sx={{ width: '300px' }}
id="categories"
select
label="Select category"
value={jokeByCategory?.categories[0] || ""}
value={jokeByCategory?.categories[0] || ''}
onChange={handleChange}
>
{categories.map((option) => (
{categories?.map((option) => (
<MenuItem key={option} value={option}>
{option}
</MenuItem>
Expand Down
34 changes: 34 additions & 0 deletions src/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Toolbar, Button, AppBar } from '@mui/material';
import { Box } from '@mui/system';
import React from 'react';
import { useNavigate } from 'react-router-dom';

type TProps = {
navItems: {
name: string;
path: string;
component: JSX.Element;
}[];
};

export const Header = ({ navItems }: TProps) => {
const navigate = useNavigate();

return (
<AppBar component="nav">
<Toolbar>
<Box sx={{ display: { xs: 'none', sm: 'block' } }}>
{navItems.map(({ name, path }) => (
<Button
key={name}
sx={{ color: '#fff' }}
onClick={() => navigate(path)}
>
{name}
</Button>
))}
</Box>
</Toolbar>
</AppBar>
);
};
18 changes: 11 additions & 7 deletions src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import FrontPage from "./pages/FrontPage";
import reportWebVitals from "./reportWebVitals";
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';

import reportWebVitals from './reportWebVitals';
import { App } from './App';
import { BrowserRouter } from 'react-router-dom';

ReactDOM.render(
<React.StrictMode>
<FrontPage />
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>,
document.getElementById("root")
document.getElementById('root')
);

reportWebVitals();
10 changes: 10 additions & 0 deletions src/pages/Categories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Grid } from '@mui/material';
import CategoriesList from '../components/CategoriesList';

export const Categories = () => {
return (
<Grid item xs={12} width={'100%'} justifyContent={'center'} my={4}>
<CategoriesList />
</Grid>
);
};
72 changes: 0 additions & 72 deletions src/pages/FrontPage.tsx

This file was deleted.

70 changes: 70 additions & 0 deletions src/pages/Home.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import React from 'react';
import { makeStyles } from '@mui/styles';
import { Box, Grid, Typography, useTheme } from '@mui/material';
import CategoriesList from '../components/CategoriesList';
import RandomJoke from '../components/RandomJoke';
import SearchJoke from '../components/SearchJokes';
import { Header } from '../components/Header';

const useStyles = makeStyles(() => ({
image: {
height: '30vh',
width: 'auto',
'&:hover': {
animation: '$shake 0.5s',
animatedItemExiting: 'infinite',
},
'60%': { transform: 'translate(-3px, 1px) rotate(0deg)' },
'70%': { transform: 'translate(3px, 1px) rotate(-1deg)' },
'80%': { transform: 'translate(-1px, -1px) rotate(1deg)' },
'90% ': { transform: 'translate(1px, 2px) rotate(0deg)' },
'100%': { transform: 'translate(1px, -2px) rotate(-1deg)' },
},
'@keyframes shake': {
'0%': { transform: 'translate(1px, 1px) rotate(0deg)' },
' 10%': { transform: 'translate(-1px, -2px) rotate(-1deg)' },
' 20%': { transform: 'translate(-3px, 0px) rotate(1deg)' },
'30%': { transform: 'translate(3px, 2px) rotate(0deg)' },
'40%': { transform: 'translate(1px, -1px) rotate(1deg)' },
'50%': { transform: 'translate(-1px, 2px) rotate(-1deg)' },
},
}));

export const Home = () => {
const classes = useStyles();
const theme = useTheme();

return (
<Box width={'100%'}>
<Grid container width="100%" my={6}>
<Grid item xs={12} display="flex" justifyContent="center">
<img
className={classes.image}
src="https://api.chucknorris.io/img/chucknorris_logo_coloured_small@2x.png"
alt="Chuck Noris is watching you"
/>
</Grid>
<Grid item xs={12} display="flex" justifyContent="center">
<Typography
component="a"
target="_blank"
variant="h4"
href="http://chucknorris.io"
>
Chuck Norris Quotes
</Typography>
</Grid>
</Grid>

<Grid container width="100%" my={2}>
<Grid item xs={12} my={theme.spacing(2)}>
<RandomJoke />
</Grid>

<Grid item xs={12}>
<SearchJoke />
</Grid>
</Grid>
</Box>
);
};
20 changes: 20 additions & 0 deletions src/pages/Layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Box } from '@mui/system';
import React from 'react';

type TProps = {
header: React.ReactNode;
children: React.ReactNode;
};

const Layout = ({ header, children }: TProps) => {
return (
<>
{header}
<Box mt={8} sx={{ display: 'flex' }}>
{children}
</Box>
</>
);
};

export default Layout;
13 changes: 13 additions & 0 deletions src/utils/requests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { useState } from "react";

export function useFetchData<T>(){

const [data, setData] = useState<T | undefined>()

const getData = (url:string)=> fetch(url).then(async (response) => {
const result = await response.json();
setData(result);
});

return {data, getData}
}
Loading

0 comments on commit bae1b9d

Please sign in to comment.