Skip to content

Commit

Permalink
Demo (#19)
Browse files Browse the repository at this point in the history
* Well let's try this ! (#16)

* typo into release pipeline

* Feat/add username in header (#14)

* feat: add user in redux

* feat: update app and topbar components

* feat: avoid user to autolike his comment (#15)

* feat: add user in redux

* feat: update app and topbar components

* feat: avoid user to autolike his comment

* Feat/leaderboard (#18)

* feat: add user in redux

* feat: update app and topbar components

* chore: recover leaderboard

* chore: cleanup App.tsx from leaderboard

* feat: finish leaderboard

* feat: update scoring algo

Co-authored-by: Yann RENAUDIN <4748419+emyann@users.noreply.github.com>
  • Loading branch information
julienstroheker and emyann authored Jan 31, 2020
1 parent 2fd5f2c commit f742766
Show file tree
Hide file tree
Showing 6 changed files with 187 additions and 31 deletions.
2 changes: 2 additions & 0 deletions cmd/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"d3-scale": "^3.2.1",
"date-fns": "^2.9.0",
"js-cookie": "^2.2.1",
"mdi-react": "^6.6.0",
"morphism": "^1.12.3",
"react": "^16.12.0",
"react-dom": "^16.12.0",
Expand Down Expand Up @@ -47,6 +48,7 @@
]
},
"devDependencies": {
"@types/d3-scale": "^2.1.1",
"@types/react-redux": "^7.1.5",
"@types/redux-logger": "^3.0.7",
"@types/webpack-env": "^1.14.1"
Expand Down
3 changes: 1 addition & 2 deletions cmd/web/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,10 @@ export default function App() {
dispatch(saveUser({ userId }));
}
};
}, []);
}, [dispatch]);
return (
<Container>
<TopBar />
{/* <Leaderboard /> */}
<Questions />
<QuestionBar />
<ProTip />
Expand Down
110 changes: 97 additions & 13 deletions cmd/web/src/Leaderboard.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,112 @@
import React, { FC } from 'react';
import React, { FC, useEffect, useMemo } from 'react';
import { useSelector } from 'react-redux';
import { getAuthors, getAuthorsWithScore } from './store/authors';
import { TableContainer, Table, TableHead, TableRow, TableCell, TableBody } from '@material-ui/core';
import { getAuthorsWithScore } from './store/authors';
import {
TableContainer,
Table,
TableHead,
TableRow,
TableCell,
TableBody,
Typography,
withStyles,
Theme,
createStyles,
Paper,
makeStyles,
Avatar,
Badge
} from '@material-ui/core';
import MedalIcon from 'mdi-react/MedalIcon';
import { deepOrange, deepPurple, lightGreen, yellow } from '@material-ui/core/colors';

const StyledTableCell = withStyles((theme: Theme) =>
createStyles({
head: {
backgroundColor: theme.palette.common.black,
color: theme.palette.common.white
},
body: {
fontSize: 14
}
})
)(TableCell);

const useStyles = makeStyles((theme: Theme) =>
createStyles({
table: {
minWidth: 500
},
rankCell: {
alignItems: 'center',
justifyContent: 'center'
},
green: {
color: theme.palette.getContrastText('#000000'),
backgroundColor: '#000000'
}
})
);

export const Leaderboard: FC = () => {
const classes = useStyles();
const authorsWithScore = useSelector(getAuthorsWithScore);
const sortedAuthorsWithScore = useMemo(
() =>
authorsWithScore.sort((a, b) => {
return b.score - a.score;
}),
[authorsWithScore]
);

function getMedalColor(index: number) {
switch (index) {
case 1: {
return '#ffdf00';
}
case 2: {
return '#aaa9ad';
}
case 3: {
return '#cd7f32';
}
default:
break;
}
}
return (
<TableContainer>
<Table stickyHeader aria-label="simple table">
<TableContainer component={Paper}>
<Table className={classes.table} stickyHeader aria-label="simple table">
<TableHead>
<TableRow>
<TableCell>Rank</TableCell>
<TableCell>ID</TableCell>
<TableCell>Score</TableCell>
<StyledTableCell>Rank</StyledTableCell>
<StyledTableCell>ID</StyledTableCell>
<StyledTableCell>Score</StyledTableCell>
</TableRow>
</TableHead>
<TableBody>
{authorsWithScore.map(({ author, score }, index) => (
{sortedAuthorsWithScore.map(({ author, score }, index) => (
<TableRow hover key={author.id}>
<TableCell component="th" scope="row">
{index + 1}
<TableCell component="th" className={classes.rankCell}>
<Badge
overlap="circle"
anchorOrigin={{
vertical: 'bottom',
horizontal: 'right'
}}
badgeContent={index <= 2 ? <MedalIcon color={getMedalColor(index + 1)} /> : null}
>
<Avatar className={classes.green}>{index + 1}</Avatar>
</Badge>
</TableCell>
<TableCell>
<Typography>{author.id}</Typography>
</TableCell>
<TableCell>
<Typography variant="body1" color="secondary">
<strong>{score}</strong>
</Typography>
</TableCell>
<TableCell>{author.id}</TableCell>
<TableCell>{score}</TableCell>
</TableRow>
))}
</TableBody>
Expand Down
47 changes: 45 additions & 2 deletions cmd/web/src/TopBar.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useState } from 'react';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import Typography from '@material-ui/core/Typography';
Expand All @@ -10,6 +10,9 @@ import KeyboardArrowUpIcon from '@material-ui/icons/KeyboardArrowUp';
import Zoom from '@material-ui/core/Zoom';
import { useSelector } from 'react-redux';
import { getUser } from './store/user';
import { Button, Popover } from '@material-ui/core';
import { Leaderboard } from './Leaderboard';
import { TableChart } from '@material-ui/icons';

interface Props {
/**
Expand Down Expand Up @@ -63,13 +66,26 @@ const useStyles2 = makeStyles((theme: Theme) =>
createStyles({
title: {
flexGrow: 1
},
username: {
padding: theme.spacing(2)
}
})
);

export default function BackToTop(props: Props) {
const classes = useStyles2();
const user = useSelector(getUser);
const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null);

function handleOpenLeaderboard(event: React.MouseEvent<HTMLButtonElement>) {
setAnchorEl(event.currentTarget);
}

function handleClose() {
setAnchorEl(null);
}
const open = Boolean(anchorEl);
return (
<React.Fragment>
<CssBaseline />
Expand All @@ -78,7 +94,34 @@ export default function BackToTop(props: Props) {
<Typography variant="h5" className={classes.title}>
I Have A Question ?!
</Typography>
<Typography variant="h6">{user.id}</Typography>
<Button
aria-describedby="leaderboard"
variant="contained"
color="secondary"
onClick={handleOpenLeaderboard}
startIcon={<TableChart />}
>
Open Leaderboard
</Button>
<Popover
id="leaderboard"
open={open}
anchorEl={anchorEl}
onClose={handleClose}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'center'
}}
transformOrigin={{
vertical: 'top',
horizontal: 'center'
}}
>
<Leaderboard />
</Popover>
<Typography variant="h6" className={classes.username}>
{user.id}
</Typography>
</Toolbar>
</AppBar>
<Toolbar id="back-to-top-anchor" />
Expand Down
39 changes: 25 additions & 14 deletions cmd/web/src/store/authors/authors.selectors.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { AppState } from '../rootReducer';
import { createSelector } from '@reduxjs/toolkit';
import { getAuthorMessagesById } from '../authorMessages/authorMessages.selectors';
import { getMessage, messagesSelector } from '../messages/messages.selectors';
import { getMessage, messagesSelector, getMessages } from '../messages/messages.selectors';
import { scalePow } from 'd3-scale';

export const authorsSelector = (state: AppState) => state.authors;
export const makeGetAuthor = createSelector(authorsSelector, state => (authorId: string) => state.byId[authorId]);
Expand All @@ -16,19 +17,29 @@ export const getAuthorMessages = createSelector([getAuthorMessagesById, getMessa
}
});

export const getAuthorsWithScore = createSelector([authorsSelector, getAuthorMessages], (state, getAuthorMessages) =>
Object.values(state.byId).map(author => {
const messages = getAuthorMessages(author.id);
const countOfMessages = messages.length;
const countOfLikes = messages.reduce((acc, message) => {
acc += message.likes;
return acc;
}, 0);
return {
author,
score: (countOfLikes + 1) * countOfMessages
};
})
export const getAuthorsWithScore = createSelector(
[authorsSelector, getAuthorMessages, getMessages],
(state, getAuthorMessages, messages) => {
const allLikes = messages.map(message => message.likes);
const min = Math.min(...allLikes);
const max = Math.max(...allLikes);
const scale = scalePow()
.exponent(0.2)
.domain([min, max])
.range([1, 10]);
return Object.values(state.byId).map(author => {
const messages = getAuthorMessages(author.id);
const countOfMessages = messages.length;
const countOfLikes = messages.reduce((acc, message) => {
acc += message.likes;
return acc;
}, 0);
return {
author,
score: Math.floor(scale(countOfLikes) * countOfMessages)
};
});
}
);

export const getMessagesWithUser = createSelector(messagesSelector, makeGetAuthor, (state, getAuthor) =>
Expand Down
17 changes: 17 additions & 0 deletions cmd/web/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1352,6 +1352,18 @@
dependencies:
"@babel/types" "^7.3.0"

"@types/d3-scale@^2.1.1":
version "2.1.1"
resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-2.1.1.tgz#405e58771ec6ae7b8f7b4178ee1887620759e8f7"
integrity sha512-kNTkbZQ+N/Ip8oX9PByXfDLoCSaZYm+VUOasbmsa6KD850/ziMdYepg/8kLg2plHzoLANdMqPoYQbvExevLUHg==
dependencies:
"@types/d3-time" "*"

"@types/d3-time@*":
version "1.0.10"
resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-1.0.10.tgz#d338c7feac93a98a32aac875d1100f92c7b61f4f"
integrity sha512-aKf62rRQafDQmSiv1NylKhIMmznsjRN+MnXRXTqHoqm0U/UZzVpdrtRnSIfdiLS616OuC1soYeX1dBg2n1u8Xw==

"@types/eslint-visitor-keys@^1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d"
Expand Down Expand Up @@ -6612,6 +6624,11 @@ md5.js@^1.3.4:
inherits "^2.0.1"
safe-buffer "^5.1.2"

mdi-react@^6.6.0:
version "6.6.0"
resolved "https://registry.yarnpkg.com/mdi-react/-/mdi-react-6.6.0.tgz#423d770f956119aa2e4c7e4c121508209c36e5d0"
integrity sha512-HF+Madrr2bROpLoAJaM5kLA3tevXmvnC3aCO5bb3czu6Tc5OogW3kpgpVAX64CAMVkgzWUd+IjCNKWMbAHdvCA==

mdn-data@2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b"
Expand Down

0 comments on commit f742766

Please sign in to comment.