Skip to content

Commit 2b26611

Browse files
committed
intital commit
0 parents  commit 2b26611

13 files changed

+16590
-0
lines changed

.gitignore

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/.idea
2+
/.history
3+
/.vscode
4+
/.cache
5+
/.yarn
6+
.tmp
7+
node_modules
8+
build
9+
.gqlconfig
10+
.expo
11+
*.log
12+
*.sqlite3
13+
.DS_Store
14+
jsconfig.json
15+
public
16+
*.iml
17+
.npmrc
18+
swagger.yml
19+
deploy.sh

package-lock.json

Lines changed: 16279 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"name": "dynamic_points_react",
3+
"version": "1.0.0",
4+
"description": "",
5+
"keywords": [],
6+
"main": "src/index.tsx",
7+
"dependencies": {
8+
"react": "17.0.2",
9+
"react-dom": "17.0.2",
10+
"react-scripts": "4.0.3",
11+
"styled-components": "5.3.1"
12+
},
13+
"devDependencies": {
14+
"@types/react": "17.0.20",
15+
"@types/react-dom": "17.0.9",
16+
"@types/styled-components": "^5.1.14",
17+
"typescript": "4.4.2"
18+
},
19+
"scripts": {
20+
"start": "react-scripts start",
21+
"build": "react-scripts build",
22+
"test": "react-scripts test --env=jsdom",
23+
"eject": "react-scripts eject"
24+
},
25+
"browserslist": [
26+
">0.2%",
27+
"not dead",
28+
"not ie <= 11",
29+
"not op_mini all"
30+
]
31+
}

src/App.tsx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import React, { useState, useEffect } from "react";
2+
3+
import streamData from "./data.json";
4+
import { formatData } from "./helpers";
5+
import StreamersList from "./components/ItemList";
6+
import { UPDATE_DATA_FREQUENCY } from "./constants";
7+
import './styles.css'
8+
9+
function App() {
10+
const [data, setData] = useState(formatData(streamData));
11+
useEffect(() => {
12+
const interval = setInterval(() => {
13+
setData(formatData);
14+
}, UPDATE_DATA_FREQUENCY);
15+
return function cleanup() {
16+
clearInterval(interval);
17+
};
18+
}, []);
19+
20+
return <StreamersList data={data} />;
21+
}
22+
23+
export default App;

src/components/ItemList.tsx

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import React, { memo } from "react";
2+
import styled from "styled-components";
3+
import ScoreRecords from "./ScoreRecords";
4+
import { RANKING_COLOR } from "../constants";
5+
6+
const Container = styled.div`
7+
background-color: #111;
8+
position: absolute;
9+
width: 90%;
10+
height: 800px;
11+
left: 50%;
12+
top: 30px;
13+
transform: translateX(-50%);
14+
`;
15+
16+
17+
const ItemRank = styled.div`
18+
width: 25px;
19+
display: flex;
20+
justify-content: center;
21+
align-items: center;
22+
height: 25px;
23+
color: white;
24+
`;
25+
26+
const ItemContainer = styled.div`
27+
width: 96%;
28+
height: 80px;
29+
position: absolute;
30+
left: 50%;
31+
transform: translateX(-50%);
32+
display: flex;
33+
-webkit-box-align: center;
34+
align-items: center;
35+
transition: all 0.3s ease 0s;
36+
border-bottom: 1px solid #424242;`
37+
38+
const ItemList = ({data}: any) => (
39+
<div>
40+
<Container>
41+
{data.map((item: any) => {
42+
return (
43+
<ItemContainer key={item.userID} style={{
44+
top: `${80 * ((item.ranking) - 1)}px`
45+
}}>
46+
<ItemRank style={{
47+
backgroundColor: RANKING_COLOR[item.ranking - 1] || "#8eb9f5"
48+
}}>{item.ranking}</ItemRank>
49+
<span style={{
50+
color: 'rgba(255,255,255,0.5)',
51+
paddingLeft: '20px'
52+
}}>{item.displayName}</span>
53+
<ScoreRecords score={item.score}/>
54+
</ItemContainer>
55+
)
56+
})}
57+
</Container>
58+
</div>
59+
);
60+
61+
export default ItemList;

src/components/ScoreRecords.tsx

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import React, { useState, useEffect } from "react";
2+
import styled from "styled-components";
3+
4+
import {
5+
SCORE_INTERVAL,
6+
SCORE_INTERVAL_NUMBER,
7+
SCORE_DIVISOR,
8+
POINT_COLOR
9+
} from "../constants";
10+
11+
const StyledPoint = styled.div`
12+
margin-left: auto;
13+
color: ${POINT_COLOR};
14+
`;
15+
16+
const ScoreRecords = ({ score }: any) => {
17+
const [pt, setPt] = useState(score);
18+
useEffect(() => {
19+
let i = SCORE_INTERVAL_NUMBER;
20+
const interval = setInterval(() => {
21+
i -= 1;
22+
setPt((n: number) => Math.floor(n + (score - n) / SCORE_DIVISOR));
23+
if (i <= 0) {
24+
setPt(score);
25+
clearInterval(interval);
26+
}
27+
}, SCORE_INTERVAL);
28+
return function cleanup() {
29+
clearInterval(interval);
30+
};
31+
}, [score]);
32+
return <StyledPoint>{pt}pt</StyledPoint>;
33+
};
34+
35+
export default ScoreRecords;

src/constants.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
export const UPDATE_DATA_FREQUENCY = 1000;
2+
export const SCORE_INTERVAL = 1;
3+
export const SCORE_INTERVAL_NUMBER = 1;
4+
export const SCORE_DIVISOR = 10;
5+
export const RANDOM_MAX = 25000;
6+
export const RANDOM_MIN = 1000;
7+
export const NUMERATOR = 1;
8+
export const DENOMINATOR = 3;
9+
export const RANKING_COLOR = ["red", "orange", "grey"];
10+
11+
export const POINT_COLOR = "orange";

src/data.json

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
[
2+
{
3+
"userID": "u-1",
4+
"displayName": "James N. Martin",
5+
"score": 4210
6+
},
7+
{
8+
"userID": "u-2",
9+
"displayName": "Danny A. Austin",
10+
"score": 45784
11+
},
12+
{
13+
"userID": "u-3",
14+
"displayName": "Paul K. Craig",
15+
"score": 65852
16+
},
17+
{
18+
"userID": "u-4",
19+
"displayName": "Michelle J. Henderson",
20+
"score": 45123
21+
},
22+
{
23+
"userID": "u-5",
24+
"displayName": "Kathleen M. Smith",
25+
"score": 98745
26+
},
27+
{
28+
"userID": "u-6",
29+
"displayName": "Coreen S. Lee",
30+
"score": 85697
31+
},
32+
{
33+
"userID": "u-7",
34+
"displayName": "Brad L. Coleman",
35+
"score": 45789
36+
},
37+
{
38+
"userID": "u-8",
39+
"displayName": "Tracey B. Knight",
40+
"score": 63258
41+
},
42+
{
43+
"userID": "u-9",
44+
"displayName": "Miranda L. Cohn",
45+
"score": 1020
46+
},
47+
{
48+
"userID": "u-10",
49+
"displayName": "Sunny Soni",
50+
"score": 157000
51+
}
52+
]

src/helpers.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { RANDOM_MAX, RANDOM_MIN, NUMERATOR, DENOMINATOR } from "./constants";
2+
3+
4+
const rank = (userID: any, arr: any) => {
5+
let result = null;
6+
arr.forEach((item: any, index: any) => {
7+
if (item.userID === userID) {
8+
result = index + 1;
9+
}
10+
});
11+
return result;
12+
};
13+
14+
15+
const setScore = (key: any) => {
16+
return function (objA: any, objB: any) {
17+
const valueN = objA[key];
18+
const valueM = objB[key];
19+
if (valueN < valueM) return 1;
20+
else if (valueN > valueM) return -1;
21+
else return 0;
22+
};
23+
};
24+
25+
export const formatData = (arr: any) => {
26+
const newArr = [...arr].map((item) => {
27+
return {
28+
...item,
29+
score: item.score +=
30+
Math.floor(Math.random() * DENOMINATOR) < NUMERATOR
31+
? Math.floor(Math.random() * RANDOM_MAX + RANDOM_MIN)
32+
: 0
33+
};
34+
});
35+
newArr.sort(setScore("score"));
36+
return arr.map((item: any) => {
37+
return {
38+
...item,
39+
ranking: rank(item.userID, newArr)
40+
};
41+
});
42+
};

src/index.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { render } from "react-dom";
2+
3+
import App from "./App";
4+
5+
const rootElement = document.getElementById("root");
6+
render(<App />, rootElement);

src/react-app-env.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/// <reference types="react-scripts" />

src/styles.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
body {
2+
font-family: 'Poppins', sans-serif;
3+
font-weight: 600;
4+
text-align: center;
5+
}

tsconfig.json

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"include": [
3+
"./src/**/*"
4+
],
5+
"compilerOptions": {
6+
"strict": true,
7+
"esModuleInterop": true,
8+
"lib": [
9+
"dom",
10+
"es2015"
11+
],
12+
"jsx": "react-jsx",
13+
"target": "es5",
14+
"allowJs": true,
15+
"skipLibCheck": true,
16+
"allowSyntheticDefaultImports": true,
17+
"forceConsistentCasingInFileNames": true,
18+
"noFallthroughCasesInSwitch": true,
19+
"module": "esnext",
20+
"moduleResolution": "node",
21+
"resolveJsonModule": true,
22+
"isolatedModules": true,
23+
"noEmit": true
24+
}
25+
}

0 commit comments

Comments
 (0)