forked from reactplay/react-play
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Leader Board : Shows Top Play Contributor of the month and Top Play C…
…ontributors of all time (reactplay#843) * Adding leader board page. * 1. Heading to next line. 2. sorting based on date when monthly contributor play count is same. * Addressing review comment. * Fixing lint errors. * Added the API env file * header styles. * Removeing eslint rule form component. * Fixing responsive issues. * Adding a test and fixing breaking tests. * Adding tooltip. * Bigger resolution fix. Co-authored-by: Nagarjun Shroff <[email protected]> Co-authored-by: Tapas Adhikary <[email protected]>
- Loading branch information
1 parent
f4157cf
commit 8e84d87
Showing
12 changed files
with
281 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
REACT_APP_NHOST_BACKEND_URL=https://rgkjmwftqtbpayoyolwh.nhost.run/ | ||
REACT_APP_NHOST_VERSION=v1 | ||
REACT_APP_NHOST_ENDPOINT=graphql | ||
DISABLE_ESLINT_PLUGIN=true | ||
REACT_APP_PLAY_WEB_SVC=https://api.reactplay.io/.netlify/functions/server | ||
DISABLE_ESLINT_PLUGIN=true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
export const TWEET_COUNT = 10; | ||
export const TWEET_COUNT = 11; | ||
export const CONTRIBUTORS_COUNT = 29; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import { useState, useEffect, useCallback } from 'react'; | ||
import { submit } from '../services/request'; | ||
import { FetchPlayCountByUser } from 'common/services/request/query/fetch-leaderboard-data'; | ||
import TopPlayCreatorOfTheMonth from './TopPlayCreatorOfTheMonth'; | ||
import TopPlayCreators from './TopPlayCreators'; | ||
import { Watch } from 'react-loader-spinner'; | ||
import { groupBy } from 'lodash'; | ||
import { format, lastDayOfMonth } from 'date-fns'; | ||
|
||
const LeaderBoard = () => { | ||
const [top10Contributors, updateTop10Contributors] = useState([]); | ||
const [topContributorOfTheMonth, updateTopContributorOfTheMonth] = useState([]); | ||
const [publishedPlays, updatePublishedPlays] = useState([]); | ||
const { getAllPlaysByUser, getAllPlaysByUserByMonth } = FetchPlayCountByUser; | ||
|
||
const formatData = useCallback((data, monthlyContribution = false) => { | ||
const formattedData = []; | ||
const finalData = []; | ||
const filteredData = data.filter((d) => publishedPlays.includes(d.slug)); | ||
filteredData.map((d) => { | ||
formattedData.push({ | ||
created_at: d.created_at, | ||
displayName: d.user.displayName, | ||
avatarUrl: d.user.avatarUrl | ||
}); | ||
}); | ||
const groupByUser = groupBy(formattedData, 'displayName'); | ||
Object.values(groupByUser).map((v) => | ||
finalData.push({ | ||
displayName: v[0].displayName, | ||
avatarUrl: v.map((t) => t.avatarUrl)[0], | ||
count: v.length, | ||
created_at: v[0].created_at | ||
}) | ||
); | ||
const sortByCount = finalData.sort((a, b) => b.count - a.count); | ||
if (monthlyContribution) { | ||
// once the data being sorted based on created date, will pick the first one. | ||
return sortByCount.sort((a, b) => new Date(b.created_at) - new Date(a.created_at))[0]; | ||
} | ||
|
||
return sortByCount.slice(0, 10); | ||
}); | ||
|
||
useEffect(() => { | ||
async function fetchData() { | ||
const res = await fetch(`${process.env.REACT_APP_PLAY_WEB_SVC}/api/plays/published`); | ||
const data = await res.json(); | ||
updatePublishedPlays(data); | ||
} | ||
fetchData(); | ||
}, []); | ||
|
||
useEffect(() => { | ||
async function fetchTopContributors() { | ||
const data = await submit(getAllPlaysByUser()); | ||
updateTop10Contributors(formatData(data)); | ||
} | ||
|
||
async function fetchTopContributorOfTheMonth() { | ||
const firstDateOfMonth = format(new Date(), 'yyyy-MM-01'); | ||
const lastDateOfMonth = format(lastDayOfMonth(new Date()), 'yyyy-MM-dd'); | ||
const data = await submit(getAllPlaysByUserByMonth(firstDateOfMonth, lastDateOfMonth)); | ||
updateTopContributorOfTheMonth(formatData(data, true)); | ||
} | ||
|
||
fetchTopContributors(); | ||
fetchTopContributorOfTheMonth(); | ||
}, [publishedPlays]); | ||
|
||
return ( | ||
<main className="app-body app-body-overflow-hidden"> | ||
{publishedPlays.length && (topContributorOfTheMonth || top10Contributors) ? ( | ||
<div className=" overflow-auto lg:flex flex-row justify-center"> | ||
{topContributorOfTheMonth && ( | ||
<TopPlayCreatorOfTheMonth topPlayCreatorOfTheMonth={topContributorOfTheMonth} /> | ||
)} | ||
<div className="flex flex-col m-4 items-center"> | ||
{publishedPlays && top10Contributors && ( | ||
<> | ||
<div className="leaderboard-heading">Top play creators of all time</div> | ||
<div> | ||
<TopPlayCreators topPlayCreators={top10Contributors} /> | ||
</div> | ||
</> | ||
)} | ||
</div> | ||
</div> | ||
) : ( | ||
<div className="leaderboard-loader"> | ||
<Watch color="#0096AB" height="100" width="100" /> | ||
</div> | ||
)} | ||
</main> | ||
); | ||
}; | ||
|
||
export default LeaderBoard; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { format } from 'date-fns'; | ||
|
||
const TopPlayCreatorOfTheMonth = ({ topPlayCreatorOfTheMonth }) => { | ||
return ( | ||
<div className="m-4 text-center flex lg:flex flex-col gap-4 items-center"> | ||
<div className="flex flex-col lg:w-[600px] md:w-[600px]"> | ||
<div className="leaderboard-heading">Top play creator of the month</div> | ||
<div className="leaderboard-heading">{format(new Date(), 'LLLL yyyy')}</div> | ||
</div> | ||
<div className="flex flex-col items-center m-1"> | ||
<div> | ||
<img | ||
alt="profile pic" | ||
className="rounded-full border-solid h-48 lg:h-80" | ||
src={topPlayCreatorOfTheMonth.avatarUrl} | ||
title={topPlayCreatorOfTheMonth.displayName} | ||
/> | ||
</div> | ||
<div className="flex flex-col m-8 items-center"> | ||
<div className="leaderboard-text">{topPlayCreatorOfTheMonth.displayName}</div> | ||
<div className="flex flex-row gap-2 items-center"> | ||
<div className="font-medium text-sm">Number of play(s) created:</div> | ||
<div className="font-medium text-sm">{topPlayCreatorOfTheMonth.count}</div> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default TopPlayCreatorOfTheMonth; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import Table from '@mui/material/Table'; | ||
import TableBody from '@mui/material/TableBody'; | ||
import TableCell from '@mui/material/TableCell'; | ||
import TableContainer from '@mui/material/TableContainer'; | ||
import TableHead from '@mui/material/TableHead'; | ||
import TableRow from '@mui/material/TableRow'; | ||
import './leaderBoard.css'; | ||
|
||
const TopPlayCreators = ({ topPlayCreators }) => { | ||
const profilePicture = (name, avatarUrl) => { | ||
return ( | ||
<div className="flex flex-row items-center gap-4"> | ||
<img | ||
alt={name} | ||
className="rounded-full border-solid h-8 w-8" | ||
src={avatarUrl} | ||
title={name} | ||
/> | ||
<div className="leaderboard-table-cell">{name}</div> | ||
</div> | ||
); | ||
}; | ||
|
||
return ( | ||
<TableContainer> | ||
<Table aria-label="leader board"> | ||
<TableHead> | ||
<TableRow> | ||
<TableCell align="left" className="leaderboard-table-header"> | ||
Name | ||
</TableCell> | ||
<TableCell align="center" className="leaderboard-table-header"> | ||
Number of plays | ||
</TableCell> | ||
</TableRow> | ||
</TableHead> | ||
<TableBody> | ||
{topPlayCreators.map((creator) => ( | ||
<TableRow | ||
key={creator.displayName} | ||
sx={{ '&:last-child td, &:last-child th': { border: 0 } }} | ||
> | ||
<TableCell align="left" className="leaderboard-table-cell" component="th" scope="row"> | ||
{profilePicture(creator.displayName, creator.avatarUrl)} | ||
</TableCell> | ||
<TableCell align="center" className="leaderboard-table-cell"> | ||
{creator.count} | ||
</TableCell> | ||
</TableRow> | ||
))} | ||
</TableBody> | ||
</Table> | ||
</TableContainer> | ||
); | ||
}; | ||
|
||
export default TopPlayCreators; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
.leaderboard-table-cell { | ||
padding: 6px !important; | ||
} | ||
|
||
.leaderboard-table-header { | ||
font-weight: 700 !important; | ||
font-family: var(--ff-accent) !important; | ||
} | ||
|
||
.leaderboard-heading { | ||
font-family: var(--ff-accent); | ||
font-size: 32px !important; | ||
} | ||
|
||
.leaderboard-text { | ||
font-family: var(--ff-accent) !important; | ||
font-size: var(--fs-md) !important; | ||
} | ||
|
||
.leaderboard-loader { | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
height: 100vh; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
41 changes: 41 additions & 0 deletions
41
src/common/services/request/query/fetch-leaderboard-data.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
const allPlaysByUser = { | ||
display: 'Fetch play count group by the creator', | ||
name: 'Fetch_Play_By_Users', | ||
function: 'plays', | ||
return: [ | ||
'created_at', | ||
'slug', | ||
{ | ||
user: ['avatarUrl', 'displayName', 'id', 'email'] | ||
} | ||
] | ||
}; | ||
|
||
export const FetchPlayCountByUser = { | ||
getAllPlaysByUser() { | ||
return { ...allPlaysByUser }; | ||
}, | ||
|
||
getAllPlaysByUserByMonth(gte, lte) { | ||
return { | ||
...allPlaysByUser, | ||
where: { | ||
clause: { | ||
operator: 'and', | ||
conditions: [ | ||
{ | ||
field: 'created_at', | ||
operator: 'lte', | ||
value: lte | ||
}, | ||
{ | ||
field: 'created_at', | ||
operator: 'gte', | ||
value: gte | ||
} | ||
] | ||
} | ||
} | ||
}; | ||
} | ||
}; |