refactor: add basic table display

This commit is contained in:
sirlolcat 2022-06-06 15:54:55 +04:30
parent 0efaac4748
commit bc7f5deea8
20 changed files with 518 additions and 68 deletions

View File

@ -15,14 +15,17 @@
"@types/node": "^16.11.38",
"@types/react": "^18.0.10",
"@types/react-dom": "^18.0.5",
"framer-motion": "^6.3.10",
"react": "^18.1.0",
"react-dom": "^18.1.0",
"react-scripts": "5.0.1",
"react-table": "^7.8.0",
"styled-components": "^5.3.5",
"typescript": "^4.7.2",
"web-vitals": "^2.1.4"
},
"devDependencies": {
"@types/react-table": "^7.7.12",
"@types/styled-components": "^5.1.25"
}
},
@ -3808,6 +3811,15 @@
"@types/react": "*"
}
},
"node_modules/@types/react-table": {
"version": "7.7.12",
"resolved": "https://registry.npmjs.org/@types/react-table/-/react-table-7.7.12.tgz",
"integrity": "sha512-bRUent+NR/WwtDGwI/BqhZ8XnHghwHw0HUKeohzB5xN3K2qKWYE5w19e7GCuOkL1CXD9Gi1HFy7TIm2AvgWUHg==",
"dev": true,
"dependencies": {
"@types/react": "*"
}
},
"node_modules/@types/resolve": {
"version": "1.17.1",
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz",
@ -7926,6 +7938,48 @@
"url": "https://www.patreon.com/infusion"
}
},
"node_modules/framer-motion": {
"version": "6.3.10",
"resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-6.3.10.tgz",
"integrity": "sha512-modFplFb1Fznsm0MrmRAJUC32UDA5jbGU9rDvkGzhAHksru2tnoKbU/Pa3orzdsJI0CJviG4NGBrmwGveU98Cg==",
"dependencies": {
"framesync": "6.0.1",
"hey-listen": "^1.0.8",
"popmotion": "11.0.3",
"style-value-types": "5.0.0",
"tslib": "^2.1.0"
},
"optionalDependencies": {
"@emotion/is-prop-valid": "^0.8.2"
},
"peerDependencies": {
"react": ">=16.8 || ^17.0.0 || ^18.0.0",
"react-dom": ">=16.8 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/framer-motion/node_modules/@emotion/is-prop-valid": {
"version": "0.8.8",
"resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz",
"integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==",
"optional": true,
"dependencies": {
"@emotion/memoize": "0.7.4"
}
},
"node_modules/framer-motion/node_modules/@emotion/memoize": {
"version": "0.7.4",
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz",
"integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==",
"optional": true
},
"node_modules/framesync": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/framesync/-/framesync-6.0.1.tgz",
"integrity": "sha512-fUY88kXvGiIItgNC7wcTOl0SNRCVXMKSWW2Yzfmn7EKNc+MpCzcz9DhdHcdjbrtN3c6R4H5dTY2jiCpPdysEjA==",
"dependencies": {
"tslib": "^2.1.0"
}
},
"node_modules/fresh": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
@ -8270,6 +8324,11 @@
"he": "bin/he"
}
},
"node_modules/hey-listen": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/hey-listen/-/hey-listen-1.0.8.tgz",
"integrity": "sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q=="
},
"node_modules/hoist-non-react-statics": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
@ -12197,6 +12256,17 @@
"node": ">=4"
}
},
"node_modules/popmotion": {
"version": "11.0.3",
"resolved": "https://registry.npmjs.org/popmotion/-/popmotion-11.0.3.tgz",
"integrity": "sha512-Y55FLdj3UxkR7Vl3s7Qr4e9m0onSnP8W7d/xQLsoJM40vs6UKHFdygs6SWryasTZYqugMjm3BepCF4CWXDiHgA==",
"dependencies": {
"framesync": "6.0.1",
"hey-listen": "^1.0.8",
"style-value-types": "5.0.0",
"tslib": "^2.1.0"
}
},
"node_modules/postcss": {
"version": "8.4.14",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz",
@ -13764,6 +13834,18 @@
}
}
},
"node_modules/react-table": {
"version": "7.8.0",
"resolved": "https://registry.npmjs.org/react-table/-/react-table-7.8.0.tgz",
"integrity": "sha512-hNaz4ygkZO4bESeFfnfOft73iBUj8K5oKi1EcSHPAibEydfsX2MyU6Z8KCr3mv3C9Kqqh71U+DhZkFvibbnPbA==",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/tannerlinsley"
},
"peerDependencies": {
"react": "^16.8.3 || ^17.0.0-0 || ^18.0.0"
}
},
"node_modules/readable-stream": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
@ -14849,6 +14931,15 @@
"webpack": "^5.0.0"
}
},
"node_modules/style-value-types": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/style-value-types/-/style-value-types-5.0.0.tgz",
"integrity": "sha512-08yq36Ikn4kx4YU6RD7jWEv27v4V+PUsOGa4n/as8Et3CuODMJQ00ENeAVXAeydX4Z2j1XHZF1K2sX4mGl18fA==",
"dependencies": {
"hey-listen": "^1.0.8",
"tslib": "^2.1.0"
}
},
"node_modules/styled-components": {
"version": "5.3.5",
"resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.5.tgz",
@ -19109,6 +19200,15 @@
"@types/react": "*"
}
},
"@types/react-table": {
"version": "7.7.12",
"resolved": "https://registry.npmjs.org/@types/react-table/-/react-table-7.7.12.tgz",
"integrity": "sha512-bRUent+NR/WwtDGwI/BqhZ8XnHghwHw0HUKeohzB5xN3K2qKWYE5w19e7GCuOkL1CXD9Gi1HFy7TIm2AvgWUHg==",
"dev": true,
"requires": {
"@types/react": "*"
}
},
"@types/resolve": {
"version": "1.17.1",
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz",
@ -22125,6 +22225,44 @@
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz",
"integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA=="
},
"framer-motion": {
"version": "6.3.10",
"resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-6.3.10.tgz",
"integrity": "sha512-modFplFb1Fznsm0MrmRAJUC32UDA5jbGU9rDvkGzhAHksru2tnoKbU/Pa3orzdsJI0CJviG4NGBrmwGveU98Cg==",
"requires": {
"@emotion/is-prop-valid": "^0.8.2",
"framesync": "6.0.1",
"hey-listen": "^1.0.8",
"popmotion": "11.0.3",
"style-value-types": "5.0.0",
"tslib": "^2.1.0"
},
"dependencies": {
"@emotion/is-prop-valid": {
"version": "0.8.8",
"resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz",
"integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==",
"optional": true,
"requires": {
"@emotion/memoize": "0.7.4"
}
},
"@emotion/memoize": {
"version": "0.7.4",
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz",
"integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==",
"optional": true
}
}
},
"framesync": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/framesync/-/framesync-6.0.1.tgz",
"integrity": "sha512-fUY88kXvGiIItgNC7wcTOl0SNRCVXMKSWW2Yzfmn7EKNc+MpCzcz9DhdHcdjbrtN3c6R4H5dTY2jiCpPdysEjA==",
"requires": {
"tslib": "^2.1.0"
}
},
"fresh": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
@ -22365,6 +22503,11 @@
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw=="
},
"hey-listen": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/hey-listen/-/hey-listen-1.0.8.tgz",
"integrity": "sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q=="
},
"hoist-non-react-statics": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
@ -25209,6 +25352,17 @@
}
}
},
"popmotion": {
"version": "11.0.3",
"resolved": "https://registry.npmjs.org/popmotion/-/popmotion-11.0.3.tgz",
"integrity": "sha512-Y55FLdj3UxkR7Vl3s7Qr4e9m0onSnP8W7d/xQLsoJM40vs6UKHFdygs6SWryasTZYqugMjm3BepCF4CWXDiHgA==",
"requires": {
"framesync": "6.0.1",
"hey-listen": "^1.0.8",
"style-value-types": "5.0.0",
"tslib": "^2.1.0"
}
},
"postcss": {
"version": "8.4.14",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz",
@ -26203,6 +26357,12 @@
"workbox-webpack-plugin": "^6.4.1"
}
},
"react-table": {
"version": "7.8.0",
"resolved": "https://registry.npmjs.org/react-table/-/react-table-7.8.0.tgz",
"integrity": "sha512-hNaz4ygkZO4bESeFfnfOft73iBUj8K5oKi1EcSHPAibEydfsX2MyU6Z8KCr3mv3C9Kqqh71U+DhZkFvibbnPbA==",
"requires": {}
},
"readable-stream": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
@ -27006,6 +27166,15 @@
"integrity": "sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==",
"requires": {}
},
"style-value-types": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/style-value-types/-/style-value-types-5.0.0.tgz",
"integrity": "sha512-08yq36Ikn4kx4YU6RD7jWEv27v4V+PUsOGa4n/as8Et3CuODMJQ00ENeAVXAeydX4Z2j1XHZF1K2sX4mGl18fA==",
"requires": {
"hey-listen": "^1.0.8",
"tslib": "^2.1.0"
}
},
"styled-components": {
"version": "5.3.5",
"resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.5.tgz",

View File

@ -10,9 +10,11 @@
"@types/node": "^16.11.38",
"@types/react": "^18.0.10",
"@types/react-dom": "^18.0.5",
"framer-motion": "^6.3.10",
"react": "^18.1.0",
"react-dom": "^18.1.0",
"react-scripts": "5.0.1",
"react-table": "^7.8.0",
"styled-components": "^5.3.5",
"typescript": "^4.7.2",
"web-vitals": "^2.1.4"
@ -42,6 +44,7 @@
]
},
"devDependencies": {
"@types/react-table": "^7.7.12",
"@types/styled-components": "^5.1.25"
}
}

View File

@ -1,9 +0,0 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import App from './components/App';
test('renders learn react link', () => {
render(<App />);
const linkElement = screen.getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
});

View File

@ -1,5 +1,6 @@
.App {
text-align: center;
height: 50vh;
}
.App-logo {

View File

@ -1,14 +1,34 @@
import useDayLoader from '../hooks/useDayLoader';
import './App.css';
import Items from './Items';
import { createGlobalStyle } from 'styled-components';
import ItemsSection from './ItemsSection';
function App() {
const { loadNextDay } = useDayLoader();
function App(): JSX.Element {
const GlobalStyle = createGlobalStyle`
* {
margin: 0;
padding: 0;
}
html, body {
background-color: RGB(132, 151, 149);
color: RGB(227, 226, 215);
width: 100%;
height: 100%;
}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;
text-align: center;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
`
return (
<div className="App">
<Items />
<button onClick={() => loadNextDay()}></button>
</div>
<section>
<GlobalStyle />
{/* <Header /> */}
<ItemsSection />
</section>
);
}

View File

@ -0,0 +1,19 @@
import { motion } from 'framer-motion';
import useDayLoader from '../hooks/useDayLoader';
import styled from 'styled-components';
//TODO: define styled components here
function Button() {
const Button = styled(motion.button)`
border: none;
`
const { loadNextDay } = useDayLoader();
return (
<Button onClick={loadNextDay}>Next Day</Button>
);
}
export default Button;

View File

@ -1,21 +0,0 @@
import useAllItems from "../hooks/useAllItems";
import { TItem } from "../types"
function Items() {
const { items } = useAllItems();
return (
<div className="Item">
<ul>
{items.map((item: TItem) => {
return (
<li key={item.name}>
Name: {item.name} Quality: {item.quality} SellIn: {item.sellIn}
</li>
);
})}
</ul>
</div>
);
};
export default Items;

View File

@ -0,0 +1,69 @@
import { useMemo } from "react";
import styled from "styled-components";
import useAllItems from "../hooks/useAllItems";
import ItemsTable from './ItemsTable';
import Button from './Button';
function ItemsSection(): JSX.Element {
const ItemsSection = styled.section`
height: 85vh;
ul {
display: flex;
flex-direction: row;
flex-wrap: wrap;
width: 100%;
height: 100%;
color: white;
justify-content: center;
align-items: center;
}
li {
list-style: none;
display: inline-block;
height: 10%;
width: 40%;
border: 1px solid white;
margin: 3% 3%;
}
`;
const { items } = useAllItems();
const data = useMemo(() => items, [items]);
const columns = useMemo(() => [
{
Header: "Details",
columns: [
{
Header: 'Name',
accessor: 'name',
},
{
Header: 'Conjured',
accessor: 'isConjured'
}
],
},
{
Header: "Item Info",
columns: [
{
Header: 'Quality',
accessor: 'quality'
},
{
Header: 'Days Left',
accessor: 'sellIn'
}
],
}
], []);
return (
<ItemsSection>
<ItemsTable columns={columns} data={data}/>
<Button />
</ItemsSection>
);
}
export default ItemsSection;

View File

@ -0,0 +1,131 @@
import { useTable } from "react-table";
import styled from "styled-components";
import { TTable } from "../types";
function ItemTable({ columns, data }: TTable): JSX.Element {
const ItemsSection = styled.section`
height: 85vh;
ul {
display: flex;
flex-direction: row;
flex-wrap: wrap;
width: 100%;
height: 100%;
color: white;
justify-content: center;
align-items: center;
}
li {
list-style: none;
display: inline-block;
height: 10%;
width: 40%;
border: 1px solid white;
margin: 3% 3%;
}
`;
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow,
} = useTable({
columns,
data,
});
return (
<table {...getTableProps()} style={{ border: 'solid 1px blue' }}>
<thead>
{headerGroups.map(headerGroup => (
<tr>
{headerGroup.headers.map(column => (
<th
{...column.getHeaderProps()}
style={{
borderBottom: 'solid 3px red',
background: 'aliceblue',
color: 'black',
fontWeight: 'bold',
}}
>
{column.render('Header')}
</th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{rows.map(row => {
prepareRow(row)
return (
<tr {...row.getRowProps()}>
{row.cells.map(cell => {
return (
<td
{...cell.getCellProps()}
style={{
padding: '10px',
border: 'solid 1px gray',
background: 'papayawhip',
}}
>
{cell.render('Cell')}
</td>
)
})}
</tr>
)
})}
</tbody>
</table>
)
}
export default ItemTable;

View File

@ -2,10 +2,7 @@ import { useReducer } from "react";
import initialState from "../model/initialState";
import reducer from "../model/reducer";
import StoreContext from "../model/storeContext";
type TProps = {
children: JSX.Element;
}
import { TProps } from "../types";
function StoreProvider({ children }: TProps): JSX.Element {
const [state, dispatch] = useReducer(reducer, initialState);

View File

@ -0,0 +1,8 @@
import styled from 'styled-components';
const ButtonSectionStyle = styled.section`
width: 100%;
height: 20%;
`
export default ButtonSectionStyle;

View File

@ -0,0 +1,8 @@
import { css } from 'styled-components';
const ButtonStyle = css`
width: 1%;
height: 2%;
`
export default ButtonStyle;

View File

@ -0,0 +1,24 @@
import { createGlobalStyle } from "styled-components";
const GlobalStyle = createGlobalStyle`
* {
margin: 0;
padding: 0;
}
html, body {
background-color: RGB(132, 151, 149);
color: RGB(227, 226, 215);
width: 100%;
height: 100%;
}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;
text-align: center;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
`
export default GlobalStyle;

View File

@ -0,0 +1,26 @@
import styled from "styled-components";
const ItemsStyle = styled.div`
height: 85vh;
ul {
display: flex;
flex-direction: row;
flex-wrap: wrap;
width: 100%;
height: 100%;
color: white;
justify-content: center;
align-items: center;
}
li {
list-style: none;
display: inline-block;
height: 10%;
width: 40%;
border: 1px solid white;
margin: 3% 3%;
}
`;
export default ItemsStyle;

View File

@ -0,0 +1,13 @@
import ButtonSectionStyle from './ButtonSectionStyle';
import ButtonStyle from './ButtonStyle';
import GlobalStyle from './GlobalStyle';
import ItemsStyle from './ItemsStyle';
const styles = {
ButtonSectionStyle,
ButtonStyle,
GlobalStyle,
ItemsStyle
}
export default styles;

View File

@ -1,7 +0,0 @@
import styled from 'styled-components';
const Button = styled.button`
`
export default Button;

View File

@ -1,15 +0,0 @@
body {
margin: 0;
padding: 0;
height: 100vh;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}

View File

@ -1,6 +1,5 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './components/App';
import StoreProvider from './components/StoreProvider';

View File

@ -1,4 +1,6 @@
const initialState = {
import { TState } from "../types";
const initialState: TState = {
items: [
{
name: '+5 Dexterity Vest',

View File

@ -1,3 +1,5 @@
import { Column } from "react-table";
type TItem = {
name: string,
sellIn: number,
@ -5,6 +7,15 @@ type TItem = {
isConjured: boolean
}
type TProps = {
children: JSX.Element;
}
type TTable = {
columns: Column[],
data: TItem[]
}
type TState = {
items: TItem[]
};
@ -27,5 +38,7 @@ export type {
TItem,
TState,
TAction,
TContext
TContext,
TProps,
TTable
};