1
1
Fork 0

UI design + Ratings block

This commit is contained in:
Jordy van Zeeland 2023-03-08 16:48:02 +01:00
parent e7551b0599
commit c0e78bee2d
15 changed files with 174 additions and 16 deletions

BIN
.DS_Store vendored

Binary file not shown.

BIN
ras/.DS_Store vendored Normal file

Binary file not shown.

View File

@ -19,6 +19,7 @@ urlpatterns = [
path('books/genres', books_per_genre_per_month),
path('books/genres/count', countGenres),
path('books/ratings', avg_ratings_per_month),
path('books/ratings/count', countRatings),
path('books/authors', books_per_author),
path('books/countries', books_per_country),

View File

@ -299,3 +299,27 @@ def avg_ratings_per_month(request):
return Response(data)
else:
return Response("No year header included")
@api_view(['GET'])
def countRatings(request):
datayear = request.META.get('HTTP_YEAR')
if datayear:
data = []
# Get CSV file with book data
df = filterData(getBooksData(), request.META.get('HTTP_YEAR'))
countratings = df.groupby('rating')['rating'].count().reset_index(name="count")
countratings = countratings.sort_values(by='rating', ascending=False)
for index, row in countratings.iterrows():
data.append({
"rating": int(row['rating']),
"count": int(row['count'])
})
return Response(data)
else:
return Response("No year header included")

BIN
ras/frontend/.DS_Store vendored Normal file

Binary file not shown.

BIN
ras/frontend/src/.DS_Store vendored Normal file

Binary file not shown.

View File

@ -108,3 +108,16 @@ export const getAvgRatings = (year) => {
return data;
})
}
export const getRatingsCount = (year) => {
return fetch('/api/books/ratings/count', {
"method": "GET",
"headers": {
"year": year
}
})
.then(response => response.json())
.then(data => {
return data;
})
}

View File

@ -0,0 +1,104 @@
import React, { Component } from 'react';
import { getGenresCount, getRatingsCount } from "./Data.js";
import { initDoughnut } from "./Charts.js";
export default class Ratings extends Component {
constructor(props) {
super(props);
this.state = {
ratings: [],
totalRatings: 0
}
}
getComponentData() {
getRatingsCount(this.props.year).then(ratings => {
var total = 0;
ratings.forEach(rating => {
total += rating.count;
})
var ratingsArray = {
5: 0,
4: 0,
3: 0,
2: 0,
1: 0
}
for(var i = 5; i > 0; i--){
ratings.forEach(rating => {
if(rating.rating === i){
ratingsArray[i] = rating.count
}
});
}
console.log(Object.entries(ratingsArray));
this.setState({
ratings: Object.entries(ratingsArray),
totalRatings: total
})
})
}
componentDidMount() {
this.getComponentData();
}
componentDidUpdate(prevProps, prevState) {
if (prevProps.year !== this.props.year) {
this.getComponentData();
}
}
render() {
return (
<React.Fragment>
<div className="ratings">
<span className="block_name">Waarderingen ({this.state.totalRatings})</span>
<table id="DataTable" className="table responsive nowrap" width="100%">
<thead>
<tr>
<th>#</th>
<th>percentage</th>
<th>aantal</th>
</tr>
</thead>
<tbody>
{this.state.ratings.map((rating) => {
var ratingstars = '';
var rating_percentage = rating[1] / this.state.totalRatings * 100;
console.log(rating[1], this.state.totalRatings);
if (rating[0]) {
for (var i = 0; i < rating[0]; i++) {
ratingstars += "<i class='fas fa-star'></i>";
}
}
return(
<tr>
<td style={{width: '120px'}} className='book_rating' dangerouslySetInnerHTML={{__html: ratingstars}}></td>
<td style={{width: '257px'}}>
<div className="progress">
<div className="progress-bar progress-bar-striped" role="progressbar" style={{ width: rating_percentage + '%' }} aria-valuenow={rating_percentage} aria-valuemin="0" aria-valuemax="100">
{/* <div className="progress-bar-number">{rating_percentage}%</div> */}
</div>
</div>
</td>
<td>{rating[1]}</td>
</tr>
)
})}
</tbody>
</table>
</div>
</React.Fragment>
)
}
}

View File

@ -9,6 +9,7 @@ function Sidebar(){
<li><NavLink to="/"><i className="fa fa-chart-bar"></i> Dashboard</NavLink></li>
<li><NavLink to="/booklist"><i className="fas fa-book"></i> Boekenlijst</NavLink></li>
</ul>
</div>
</React.Fragment>
)

View File

@ -6,8 +6,9 @@ import Countries from "../components/Countries";
import Pages from "../components/Pages";
import Genres from "../components/Genres";
import Books from "../components/Books";
import { getReadingYears } from "../components/Data.js";
import { getRatingsCount, getReadingYears } from "../components/Data.js";
import Sidebar from "../components/Sidebar";
import Ratings from "../components/Ratings";
export default class Dashboard extends Component {
@ -31,6 +32,10 @@ export default class Dashboard extends Component {
readingYears: data
})
})
getRatingsCount(this.state.year).then(data => {
console.log(data);
})
}
render() {
@ -65,14 +70,15 @@ export default class Dashboard extends Component {
<div className="container-fluid">
<div className="row">
<div className="col-md-9">
<div className="col-md-8">
<Books year={this.state.year} />
<Pages year={this.state.year} />
</div>
<div className="col-md-3">
<div className="col-md-4">
<Countries year={this.state.year} />
<Genres year={this.state.year} />
<Ratings year={this.state.year} />
</div>
</div>
</div>

BIN
ras/frontend/static/.DS_Store vendored Normal file

Binary file not shown.

View File

@ -47,7 +47,7 @@ html, body{
height:600px !important;
}
.books-per-month, .genresPercent, .books-per-country, .book{
.books-per-month, .genresPercent, .books-per-country, .book, .ratings{
background: #ffffff;
padding: 20px;
box-shadow: 0 2px 0px 1px rgb(0 0 0 / 3%);
@ -85,7 +85,7 @@ html, body{
.sidebar{
background: #363a53;
width: 100%;
height: 54px;
padding: 15px 10px;
}
.sidebar .menu-item{
@ -108,6 +108,7 @@ html, body{
.sidebar ul {
padding: 0;
margin:0;
}
.sidebar ul li {
@ -120,21 +121,19 @@ html, body{
.sidebar ul li a {
color: #a9b7d0;
text-decoration: none;
padding: 15px 0;
padding-left: 15px;
padding-right: 15px;
padding: 12px 15px;
display:block;
width:100%;
border-radius: 10px;
}
.sidebar ul li:has(> a.active) {
background: #333f54 !important;
border-bottom: solid 3px #8066ee;
}
.sidebar ul li a.active {
color: #ffffff;
background: rgba(0,0,0,0.2) !important;
background: rgba(0,0,0,0.3) !important;
}
.sidebar ul li a.active i {
@ -148,7 +147,7 @@ html, body{
display: inline-block;
text-align: center;
line-height: 1;
margin-right: 1.125rem;
margin-right: 12px;
}
.books-stats{
@ -268,7 +267,7 @@ html, body{
margin-bottom: 10px;
}
.progress{
.stat-block .progress{
background: #f8f8fa;
height: 50px;
border: solid 2px #efefef;
@ -279,14 +278,20 @@ html, body{
overflow: visible;
}
.progress-bar{
.stat-block .progress-bar{
background-color: #8066ee;
position: relative;
overflow: visible;
border-right: solid 2px #333;
}
.progress-bar-number{
.progress-bar{
background-color: #8066ee;
position: relative;
overflow: visible;
}
.stat-block .progress-bar-number{
position: absolute;
right: 0;
background: #333;

View File

@ -1,2 +1,2 @@
/*! For license information please see src_components_Data_js.js.LICENSE.txt */
"use strict";(self.webpackChunkfrontend=self.webpackChunkfrontend||[]).push([["src_components_Data_js"],{"./src/components/Data.js":(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{eval('__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "getAllBooks": () => (/* binding */ getAllBooks),\n/* harmony export */ "getAvgRatings": () => (/* binding */ getAvgRatings),\n/* harmony export */ "getBooksPerYearPerGenres": () => (/* binding */ getBooksPerYearPerGenres),\n/* harmony export */ "getChallenge": () => (/* binding */ getChallenge),\n/* harmony export */ "getCountries": () => (/* binding */ getCountries),\n/* harmony export */ "getGenresCount": () => (/* binding */ getGenresCount),\n/* harmony export */ "getReadingYears": () => (/* binding */ getReadingYears),\n/* harmony export */ "getShortestLongestBook": () => (/* binding */ getShortestLongestBook),\n/* harmony export */ "getStats": () => (/* binding */ getStats)\n/* harmony export */ });\nconst getAllBooks = () => {\n return fetch(\'/api/books\', {\n "method": "GET"\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getStats = year => {\n return fetch(\'/api/books/stats\', {\n "method": "GET",\n "headers": {\n "year": year\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getChallenge = year => {\n return fetch(\'/api/books/challenge\', {\n "method": "GET",\n "headers": {\n "year": year\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getReadingYears = () => {\n return fetch(\'/api/books/years\', {\n "method": "GET"\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getCountries = year => {\n return fetch(\'/api/books/countries\', {\n "method": "GET",\n "headers": {\n "year": year\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getShortestLongestBook = year => {\n return fetch(\'/api/books/pages/stats\', {\n "method": "GET",\n "headers": {\n "year": year\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getBooksPerYearPerGenres = year => {\n return fetch(\'/api/books/genres\', {\n "method": "GET",\n "headers": {\n "year": year\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getGenresCount = year => {\n return fetch(\'/api/books/genres/count\', {\n "method": "GET",\n "headers": {\n "year": year\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getAvgRatings = year => {\n return fetch(\'/api/books/ratings\', {\n "method": "GET",\n "headers": {\n "year": year\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\n\n//# sourceURL=webpack://frontend/./src/components/Data.js?')}}]);
"use strict";(self.webpackChunkfrontend=self.webpackChunkfrontend||[]).push([["src_components_Data_js"],{"./src/components/Data.js":(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{eval('__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "getAllBooks": () => (/* binding */ getAllBooks),\n/* harmony export */ "getAvgRatings": () => (/* binding */ getAvgRatings),\n/* harmony export */ "getBooksPerYearPerGenres": () => (/* binding */ getBooksPerYearPerGenres),\n/* harmony export */ "getChallenge": () => (/* binding */ getChallenge),\n/* harmony export */ "getCountries": () => (/* binding */ getCountries),\n/* harmony export */ "getGenresCount": () => (/* binding */ getGenresCount),\n/* harmony export */ "getRatingsCount": () => (/* binding */ getRatingsCount),\n/* harmony export */ "getReadingYears": () => (/* binding */ getReadingYears),\n/* harmony export */ "getShortestLongestBook": () => (/* binding */ getShortestLongestBook),\n/* harmony export */ "getStats": () => (/* binding */ getStats)\n/* harmony export */ });\nconst getAllBooks = () => {\n return fetch(\'/api/books\', {\n "method": "GET"\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getStats = year => {\n return fetch(\'/api/books/stats\', {\n "method": "GET",\n "headers": {\n "year": year\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getChallenge = year => {\n return fetch(\'/api/books/challenge\', {\n "method": "GET",\n "headers": {\n "year": year\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getReadingYears = () => {\n return fetch(\'/api/books/years\', {\n "method": "GET"\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getCountries = year => {\n return fetch(\'/api/books/countries\', {\n "method": "GET",\n "headers": {\n "year": year\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getShortestLongestBook = year => {\n return fetch(\'/api/books/pages/stats\', {\n "method": "GET",\n "headers": {\n "year": year\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getBooksPerYearPerGenres = year => {\n return fetch(\'/api/books/genres\', {\n "method": "GET",\n "headers": {\n "year": year\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getGenresCount = year => {\n return fetch(\'/api/books/genres/count\', {\n "method": "GET",\n "headers": {\n "year": year\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getAvgRatings = year => {\n return fetch(\'/api/books/ratings\', {\n "method": "GET",\n "headers": {\n "year": year\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getRatingsCount = year => {\n return fetch(\'/api/books/ratings/count\', {\n "method": "GET",\n "headers": {\n "year": year\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\n\n//# sourceURL=webpack://frontend/./src/components/Data.js?')}}]);

File diff suppressed because one or more lines are too long

View File

@ -26,6 +26,10 @@
!*** ./src/components/Genres.js ***!
\**********************************/
/*!***********************************!*\
!*** ./src/components/Ratings.js ***!
\***********************************/
/*!***********************************!*\
!*** ./src/components/Sidebar.js ***!
\***********************************/