1
1
Fork 0

Bugfixes + Styling change

This commit is contained in:
Jordy van Zeeland 2024-01-18 16:36:14 +01:00
parent a8ecc8629e
commit 47ae9a846f
16 changed files with 106 additions and 94 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@ -59,7 +59,7 @@ def addChallenge(request):
if(year and challenge): if(year and challenge):
engine = create_engine('mysql+mysqldb://' + ras.settings.DATABASES['default']['USER'] + ':' + ras.settings.DATABASES['default']['PASSWORD'] + '@' + ras.settings.DATABASES['default']['HOST'] + ':3306/' + ras.settings.DATABASES['default']['NAME']) engine = create_engine('mysql+mysqldb://' + ras.settings.DATABASES['default']['USER'] + ':' + ras.settings.DATABASES['default']['PASSWORD'] + '@' + ras.settings.DATABASES['default']['HOST'] + ':3306/' + ras.settings.DATABASES['default']['NAME'])
conn = engine.connect() conn = engine.connect()
conn.execute(text("INSERT INTO book_challenge (year, nrofbooks) VALUES ('" + str(year) + "', '" + str(challenge) + "')")) conn.execute(text("INSERT INTO book_challenge (userid, year, nrofbooks) VALUES ('" + str(request.headers.get('userid')) + "', '" + str(year) + "', '" + str(challenge) + "')"))
return JsonResponse("OK", safe=False) return JsonResponse("OK", safe=False)
else: else:
return JsonResponse({'error': 'No year and challenge detected'}, safe=False) return JsonResponse({'error': 'No year and challenge detected'}, safe=False)

View File

@ -108,16 +108,20 @@ def getStats(request):
df = filterData(getBooksData(request.headers.get('userid')), request.META.get('HTTP_YEAR')) df = filterData(getBooksData(request.headers.get('userid')), request.META.get('HTTP_YEAR'))
df = df.dropna() df = df.dropna()
statsTotalBooks = df['name'].count()
statsTotalGenres = df['genre'].nunique()
avgratingsperyear = round(df['rating'].mean(), 0)
data = { if not df.empty:
'totalbooks': statsTotalBooks, statsTotalBooks = df['name'].count()
'totalgenres': statsTotalGenres, statsTotalGenres = df['genre'].nunique()
'avgyearrating': avgratingsperyear avgratingsperyear = round(df['rating'].mean(), 0)
}
data = {
'totalbooks': statsTotalBooks,
'totalgenres': statsTotalGenres,
'avgyearrating': avgratingsperyear
}
else:
data = {}
return Response(data) return Response(data)
except Exception as e: except Exception as e:

View File

@ -43,20 +43,16 @@ def filterData(df, datayear = None):
@api_view(['GET']) @api_view(['GET'])
def getStats(request): def getStats(request):
if request.META.get('HTTP_YEAR'): if request.META.get('HTTP_YEAR'):
data = []
df = filterData(getBooksData(), request.META.get('HTTP_YEAR')) df = filterData(getBooksData(), request.META.get('HTTP_YEAR'))
print(df)
df = df.dropna() df = df.dropna()
statsTotalBooks = df['name'].count() statsTotalBooks = df['name'].count()
statsTotalGenres = df['genre'].nunique() statsTotalGenres = df['genre'].nunique()
return Response({
data.append({
'totalbooks': statsTotalBooks, 'totalbooks': statsTotalBooks,
'totalgenres': statsTotalGenres 'totalgenres': statsTotalGenres
}) })
return Response(data[0])
else: else:
return Response("No year header included") return Response("No year header included")

View File

@ -22,8 +22,8 @@ const Challenge = (props) => {
<div className="stat-block challenge" style={{ marginBottom: '20px' }}> <div className="stat-block challenge" style={{ marginBottom: '20px' }}>
<span className="block_name">Book Challenge ({challenge} boeken)</span> <span className="block_name">Book Challenge ({challenge} boeken)</span>
<div className="progress"> <div className="progress">
<div className="progress-bar" role="progressbar" style={{ width: challengePercentage + '%' }} aria-valuenow={challengePercentage} aria-valuemin="0" aria-valuemax="100"> <div className="progress-bar" role="progressbar" style={{ width: challengePercentage ? challengePercentage + '%' : 0 + '%' }} aria-valuenow={challengePercentage ? challengePercentage : 0} aria-valuemin="0" aria-valuemax="100">
<div className="progress-bar-number">{challengePercentage}%</div> <div className="progress-bar-number">{challengePercentage ? challengePercentage : 0}%</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -94,7 +94,8 @@ export const initChart = (data, ratings, year) => {
*/ */
$("canvas#chart").remove(); $("canvas#chart").remove();
$("div.books-per-month").append('<canvas id="chart"></canvas>'); data && data.length > 0 ? $(".no-data-msg").remove() : $("canvas#chartGenres").remove();
data && data.length > 0 ? $("div.books-per-month").append('<canvas id="chart"></canvas>') : $("div.books-per-month").append('<div class="no-data-msg">Geen data beschikbaar</div>');
const legendMargin = { const legendMargin = {
id: 'legendMargin', id: 'legendMargin',
@ -136,7 +137,6 @@ export const initChart = (data, ratings, year) => {
beginAtZero: true, beginAtZero: true,
color: "#333", color: "#333",
size: 11, size: 11,
fontFamily: "Poppins",
}, },
stacked: true, stacked: true,
}, },
@ -149,7 +149,6 @@ export const initChart = (data, ratings, year) => {
stepSize: 1, stepSize: 1,
color: "#333", color: "#333",
size: 11, size: 11,
fontFamily: "Poppins",
}, },
stacked: true stacked: true
} }
@ -163,14 +162,9 @@ export const initChart = (data, ratings, year) => {
padding: 20, padding: 20,
font: { font: {
size: 11, size: 11,
weight: 300,
family: 'Poppins',
} }
} }
} }
},
tooltips: {
bodyFont: 'Poppins'
} }
}, },
plugins: [legendMargin], plugins: [legendMargin],
@ -178,8 +172,6 @@ export const initChart = (data, ratings, year) => {
} }
export const initDoughnut = (data) => { export const initDoughnut = (data) => {
var labels = []; var labels = [];
var counts = []; var counts = [];
@ -204,8 +196,9 @@ export const initDoughnut = (data) => {
}; };
$("canvas#chartGenres").remove(); $("canvas#chartGenres").remove();
$("div.genresPercent").append('<canvas id="chartGenres"></canvas>'); data && data.length > 0 ? $(".no-data-msg").remove() : $("canvas#chartGenres").remove();
data && data.length > 0 ? $("div.genresPercent").append('<canvas id="chartGenres"></canvas>') : $("div.genresPercent").append('<div class="no-data-msg">Geen data beschikbaar</div>');
var ctx = document.getElementById("chartGenres"); var ctx = document.getElementById("chartGenres");
var myChart = new Chart(ctx, { var myChart = new Chart(ctx, {
type: 'pie', type: 'pie',
@ -255,8 +248,6 @@ export const initDoughnut = (data) => {
color: "#333", color: "#333",
font: { font: {
size: 11, size: 11,
weight: 300,
family: 'Poppins'
} }
} }
} }

View File

@ -56,7 +56,8 @@ export const insertChallenge = (data) => {
"headers": { "headers": {
"Authorization": "Bearer " + localStorage.getItem("token"), "Authorization": "Bearer " + localStorage.getItem("token"),
'Content-Type': 'application/x-www-form-urlencoded', 'Content-Type': 'application/x-www-form-urlencoded',
"X-CSRFToken": readCookie('csrftoken') "X-CSRFToken": readCookie('csrftoken'),
"userid": localStorage.getItem('id')
}, },
"body": data "body": data
}) })

View File

@ -44,7 +44,7 @@ const Ratings = (props) => {
<React.Fragment> <React.Fragment>
<div className="ratings"> <div className="ratings">
<span className="block_name">Ratings</span> <span className="block_name">Ratings</span>
<table className="ratingstable responsive nowrap" width="100%"> {ratings && ratings.length > 0 ? <table className="ratingstable responsive nowrap" width="100%">
<thead> <thead>
<tr> <tr>
<th>#</th> <th>#</th>
@ -68,7 +68,7 @@ const Ratings = (props) => {
<td style={{width: '200px'}} className='book_rating' dangerouslySetInnerHTML={{__html: ratingstars}}></td> <td style={{width: '200px'}} className='book_rating' dangerouslySetInnerHTML={{__html: ratingstars}}></td>
<td style={{width: '257px'}}> <td style={{width: '257px'}}>
<div className="progress"> <div className="progress">
<div className="progress-bar" role="progressbar" style={{ width: rating_percentage + '%' }} aria-valuenow={rating_percentage} aria-valuemin="0" aria-valuemax="100"></div> <div className="progress-bar" role="progressbar" style={{ width: rating_percentage ? rating_percentage : 0 + '%' }} aria-valuenow={rating_percentage ? rating_percentage : 0} aria-valuemin="0" aria-valuemax="100"></div>
</div> </div>
</td> </td>
<td>{rating[1]}</td> <td>{rating[1]}</td>
@ -76,7 +76,7 @@ const Ratings = (props) => {
) )
})} })}
</tbody> </tbody>
</table> </table> : <div className='no-data-msg'>Geen data beschikbaar</div> }
</div> </div>
</React.Fragment> </React.Fragment>
) )

View File

@ -25,7 +25,7 @@ const BookStats = (props) =>{
<div className="stat-block"> <div className="stat-block">
<i className="fas fa-book-open"></i> <i className="fas fa-book-open"></i>
<span className="stats-label">Gelezen boeken:</span> <span className="stats-label">Gelezen boeken:</span>
<span className="stats-number">{totalbooks}</span> <span className="stats-number">{totalbooks ? totalbooks : 0}</span>
</div> </div>
</div> </div>
@ -34,7 +34,7 @@ const BookStats = (props) =>{
<div className="stat-block"> <div className="stat-block">
<i className="fas fa-book-open"></i> <i className="fas fa-book-open"></i>
<span className="stats-label">Genres:</span> <span className="stats-label">Genres:</span>
<span className="stats-number">{totalgenres}</span> <span className="stats-number">{totalgenres ? totalgenres : 0}</span>
</div> </div>
</div> </div>
@ -43,7 +43,7 @@ const BookStats = (props) =>{
<div className="stat-block"> <div className="stat-block">
<i className="fas fa-star"></i> <i className="fas fa-star"></i>
<span className="stats-label">Jaarbeoordeling:</span> <span className="stats-label">Jaarbeoordeling:</span>
<span className="stats-number">{yearrating}</span> <span className="stats-number">{yearrating? yearrating : 0}</span>
</div> </div>
</div> </div>
</div> </div>

View File

@ -76,6 +76,7 @@ const Challenges = (props) => {
{challenges.map((challenge, i) => { {challenges.map((challenge, i) => {
var challengePercentage = Math.round((challenge.booksread / challenge.nrofbooks) * 100, 0); var challengePercentage = Math.round((challenge.booksread / challenge.nrofbooks) * 100, 0);
console.log(challengePercentage);
return ( return (
<tr key={challenge.id}> <tr key={challenge.id}>
@ -84,8 +85,8 @@ const Challenges = (props) => {
<td>{challenge.booksread}</td> <td>{challenge.booksread}</td>
<td> <td>
<div className="progress"> <div className="progress">
<div className="progress-bar progress-bar" role="progressbar" style={{ width: challengePercentage + '%' }} aria-valuenow={challengePercentage} aria-valuemin="0" aria-valuemax="100"> <div className="progress-bar progress-bar" role="progressbar" style={{ width: challengePercentage ? challengePercentage : 0 + '%' }} aria-valuenow={challengePercentage ? challengePercentage : 0} aria-valuemin="0" aria-valuemax="100">
<div className="progress-bar-number">{challengePercentage}%</div> <div className="progress-bar-number">{challengePercentage ? challengePercentage : 0}%</div>
</div> </div>
</div> </div>
</td> </td>

View File

@ -7,7 +7,8 @@ import Challenge from "../components/Challenge";
import Sidebar from "../components/Sidebar"; import Sidebar from "../components/Sidebar";
const Dashboard = (props) => { const Dashboard = (props) => {
const [year, setYear] = useState(new Date().getFullYear()); const currentyear = new Date().getFullYear();
const [year, setYear] = useState(currentyear);
const [readingYears, setReadingYears] = useState([]); const [readingYears, setReadingYears] = useState([]);
const getData = async () => { const getData = async () => {
@ -16,6 +17,11 @@ const Dashboard = (props) => {
setReadingYears(getYears); setReadingYears(getYears);
} }
const logout = () => {
localStorage.clear();
window.location.href = "/";
}
useEffect(() => { useEffect(() => {
getData(); getData();
}, [year]); }, [year]);
@ -23,19 +29,28 @@ const Dashboard = (props) => {
return ( return (
<React.Fragment> <React.Fragment>
<div className="topbar"> <div className="topbar">
<img className="logo" src="/static/images/logo_white.png" />
<div className="chooseYear"> <div className="chooseYear">
<i className="fa fa-calendar"></i> <i className="fa fa-calendar"></i>
<span className="stats-label" style={{ marginRight: '0px' }}>Selecteer jaar</span> <span className="stats-number" style={{ marginRight: '0px' }}>
<span className="stats-number" style={{ marginRight: '0px' }}> <select className="yearselector" value={year} onChange={(event) => setYear(event.target.value)}>
<select className="yearselector" value={year} onChange={(event) => setYear(event.target.value)}> {readingYears.map((year, i) => {
{readingYears.map((year, i) => { return (<option key={i} value={year}>{year}</option>)
return (<option key={i} value={year}>{year}</option>) })}
})} {!readingYears.includes(currentyear) ? <option key={currentyear} value={currentyear}>{currentyear}</option> : ''}
</select> </select>
</span> </span>
</div> </div>
<div className="topbar_right">
<ul>
<li><i className="fas fa-book"></i></li>
<li style={{ borderRight: "solid 1px rgba(255,255,255,0.5)", paddingRight: '20px' }}><i className="fas fa-tasks"></i></li>
<li onClick={() => logout()}><i className="fas fa-power-off"></i></li>
</ul>
</div>
</div> </div>
<Sidebar /> {/* <Sidebar /> */}
<div className="content"> <div className="content">
<div className="container-fluid"> <div className="container-fluid">
{/* <div className="row"> {/* <div className="row">

View File

@ -28,8 +28,6 @@ html, body{
.content{ .content{
padding: 30px; padding: 30px;
padding-top: 90px;
padding-left: 230px;
} }
.content-manage{ .content-manage{
@ -283,7 +281,7 @@ html, body{
border-top: solid 1px rgba(255,255,255,0.2); border-top: solid 1px rgba(255,255,255,0.2);
} }
.sidebar button{ .topbar button{
background: none; background: none;
border: none; border: none;
width: 100%; width: 100%;
@ -312,26 +310,25 @@ html, body{
} }
.chooseYear{ .chooseYear{
padding: 10px; padding: 15px 25px;
color:#333; color:#fff;
display: inline-block;
} }
.chooseYear span{ .chooseYear span{
display: inline-block; display: inline-block;
color:#333; color:#fff;
} }
.chooseYear i{ .chooseYear i{
color: #333; color: rgba(255,255,255,0.5);
font-size:13px; font-size:13px;
margin-right: 10px;
} }
.chooseYear select{ .chooseYear select{
font-size:13px; font-size:13px;
background: none; background: none;
color:#333; color:#fff;
border: solid 1px #eee;
padding: 5px; padding: 5px;
} }
@ -339,26 +336,6 @@ html, body{
border:none !important; border:none !important;
outline: none !important; outline: none !important;
} }
/* .books-stats .col-md-2:nth-child(2) i{
background: #f1fcf8;
color: #58c8d6;
}
.books-stats .col-md-2:nth-child(3) i{
background: #fff5f6;
color: #fe4c62;
}
.books-stats .col-md-2:nth-child(4) i{
background: #f2f9ff;
color: #49b8fd;
}
.books-stats .col-md-2:nth-child(5) i{
background: #fffaee;
color: #ffbe0e;
}
.books-stats .col-md-2:nth-child(6) i{
background: #f8f5fc;
color: #8066ee;
} */
.stat-block i{ .stat-block i{
font-weight: 900; font-weight: 900;
@ -373,7 +350,6 @@ html, body{
color:#ffffff; color:#ffffff;
float:left; float:left;
margin-left:15px; margin-left:15px;
/* box-shadow: 2px 2px 0px 0px rgba(0, 0, 0, 0.3); */
} }
.col-md-4:nth-child(2) .stat-block i{ .col-md-4:nth-child(2) .stat-block i{
@ -387,16 +363,13 @@ html, body{
.books-stats .stat-block .stats-number, .stats-number{ .books-stats .stat-block .stats-number, .stats-number{
font-weight: 600; font-weight: 600;
display: inline-block; display: inline-block;
margin-left: 10px; margin-left: 5px;
font-size: 20px; font-size: 20px;
margin-right: 10px; margin-right: 10px;
color: #333; color: #333;
} }
.books-stats .stat-block .stats-label, .stats-label{ .books-stats .stat-block .stats-label, .stats-label{
color: #a7adbd;
font-weight: 400;
font-size: 12px;
display: block; display: block;
} }
@ -655,12 +628,43 @@ html, body{
} }
.topbar{ .topbar{
background: #ffffff; background: #343d50;
width: 100%; width: 100%;
min-height: 50px; min-height: 50px;
position: absolute;
box-shadow: 0px 1px 1px 1px #eee; box-shadow: 0px 1px 1px 1px #eee;
padding-left:230px; padding-left:30px;
}
.topbar .logo{
width:150px;
display:inline-block;
padding: 15px 0;
}
.topbar_right{
float:right;
padding: 25px 0;
margin-right: 30px;
}
.topbar_right ul{
margin: 0;
}
.topbar_right ul li{
list-style-type: none;
display: inline-block;
margin: 0 10px;
cursor: pointer;
}
.topbar_right ul li i{
color: rgba(255,255,255,0.5);
font-size: 14px;
}
.topbar_right ul li:hover i{
color: #ffffff;
} }
.stats{ .stats{

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long