Developing UI
This commit is contained in:
parent
b0008014f6
commit
767ef48e62
|
@ -2,7 +2,9 @@ from django.urls import path
|
||||||
from .views import *
|
from .views import *
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
|
path('books/years', getYears),
|
||||||
|
path('books/stats', getStats),
|
||||||
path('books/genres', books_per_genre_per_month),
|
path('books/genres', books_per_genre_per_month),
|
||||||
path('books/genres/count', countGenres),
|
path('books/genres/count', countGenres),
|
||||||
path('ratings', avg_ratings_per_month)
|
path('books/countries', books_per_country),
|
||||||
]
|
]
|
120
ras/api/views.py
120
ras/api/views.py
|
@ -17,23 +17,24 @@ def getBooksData():
|
||||||
|
|
||||||
return df
|
return df
|
||||||
|
|
||||||
@api_view(['GET'])
|
def filterData(df, datayear = None):
|
||||||
def books_per_genre_per_month(request):
|
|
||||||
|
|
||||||
datayear = request.META.get('HTTP_YEAR')
|
|
||||||
|
|
||||||
if datayear:
|
|
||||||
|
|
||||||
data = []
|
|
||||||
|
|
||||||
df = getBooksData()
|
|
||||||
|
|
||||||
df['readed'] = pd.to_datetime(df['readed'], format='%Y-%m-%d')
|
df['readed'] = pd.to_datetime(df['readed'], format='%Y-%m-%d')
|
||||||
df['readed'] = df['readed'].dt.strftime('%m-%Y')
|
df['readed'] = df['readed'].dt.strftime('%m-%Y')
|
||||||
|
|
||||||
# Filter data on year
|
# Filter data on year
|
||||||
|
if datayear and datayear is not None:
|
||||||
df = df.where(df['readed'].str.contains(datayear))
|
df = df.where(df['readed'].str.contains(datayear))
|
||||||
|
|
||||||
|
return df
|
||||||
|
|
||||||
|
|
||||||
|
@api_view(['GET'])
|
||||||
|
def books_per_genre_per_month(request):
|
||||||
|
if request.META.get('HTTP_YEAR'):
|
||||||
|
|
||||||
|
data = []
|
||||||
|
df = filterData(getBooksData(), request.META.get('HTTP_YEAR'))
|
||||||
|
|
||||||
# Filter array on genre and date
|
# Filter array on genre and date
|
||||||
booksPerMonth = df.groupby(['genre','readed'])['genre'].count().reset_index(name="count")
|
booksPerMonth = df.groupby(['genre','readed'])['genre'].count().reset_index(name="count")
|
||||||
booksPerMonth = booksPerMonth.sort_values(by=['readed', 'count'], ascending=False)
|
booksPerMonth = booksPerMonth.sort_values(by=['readed', 'count'], ascending=False)
|
||||||
|
@ -49,49 +50,13 @@ def books_per_genre_per_month(request):
|
||||||
else:
|
else:
|
||||||
return Response("No year header included")
|
return Response("No year header included")
|
||||||
|
|
||||||
@api_view(['GET'])
|
|
||||||
def avg_ratings_per_month(request):
|
|
||||||
datayear = request.META.get('HTTP_YEAR')
|
|
||||||
|
|
||||||
if datayear:
|
|
||||||
data = []
|
|
||||||
|
|
||||||
# Get CSV file with book data
|
|
||||||
df = getBooksData()
|
|
||||||
|
|
||||||
df['readed'] = pd.to_datetime(df['readed'], format='%Y-%m-%d')
|
|
||||||
df['readed'] = df['readed'].dt.strftime('%m-%Y')
|
|
||||||
|
|
||||||
# Filter data on year
|
|
||||||
df = df.where(df['readed'].str.contains(datayear))
|
|
||||||
|
|
||||||
avgratingspermonth = df.groupby('readed')['rating'].mean().reset_index(name="rating")
|
|
||||||
|
|
||||||
for index, row in avgratingspermonth.iterrows():
|
|
||||||
|
|
||||||
data.append({
|
|
||||||
"date": row['readed'],
|
|
||||||
"rating": int(row['rating'])
|
|
||||||
})
|
|
||||||
|
|
||||||
return Response(data)
|
|
||||||
else:
|
|
||||||
return Response("No year header included")
|
|
||||||
|
|
||||||
@api_view(['GET'])
|
@api_view(['GET'])
|
||||||
def countGenres(request):
|
def countGenres(request):
|
||||||
datayear = request.META.get('HTTP_YEAR')
|
if request.META.get('HTTP_YEAR'):
|
||||||
|
|
||||||
if datayear:
|
|
||||||
data = []
|
data = []
|
||||||
|
df = filterData(getBooksData(), request.META.get('HTTP_YEAR'))
|
||||||
|
|
||||||
# Get CSV file with book data
|
|
||||||
df = getBooksData()
|
|
||||||
|
|
||||||
df['readed'] = pd.to_datetime(df['readed'], format='%Y-%m-%d')
|
|
||||||
df['readed'] = df['readed'].dt.strftime('%m-%Y')
|
|
||||||
|
|
||||||
df = df.where(df['readed'].str.contains(datayear))
|
|
||||||
genres = df.groupby('genre')['genre'].count().reset_index(name="count")
|
genres = df.groupby('genre')['genre'].count().reset_index(name="count")
|
||||||
genres = genres.sort_values(by='count', ascending=False)
|
genres = genres.sort_values(by='count', ascending=False)
|
||||||
|
|
||||||
|
@ -106,3 +71,60 @@ def countGenres(request):
|
||||||
else:
|
else:
|
||||||
return Response("No year header included")
|
return Response("No year header included")
|
||||||
|
|
||||||
|
@api_view(['GET'])
|
||||||
|
def books_per_country(request):
|
||||||
|
if request.META.get('HTTP_YEAR'):
|
||||||
|
data = []
|
||||||
|
df = filterData(getBooksData(), request.META.get('HTTP_YEAR'))
|
||||||
|
|
||||||
|
countries = df.groupby('country')['country'].count().reset_index(name="count")
|
||||||
|
countries = countries.sort_values(by='count', ascending=False)
|
||||||
|
|
||||||
|
for index, row in countries.iterrows():
|
||||||
|
|
||||||
|
data.append({
|
||||||
|
"country": row['country'],
|
||||||
|
"count": int(row['count'])
|
||||||
|
})
|
||||||
|
|
||||||
|
return Response(data)
|
||||||
|
else:
|
||||||
|
return Response("No year header included")
|
||||||
|
|
||||||
|
@api_view(['GET'])
|
||||||
|
def getStats(request):
|
||||||
|
if request.META.get('HTTP_YEAR'):
|
||||||
|
data = []
|
||||||
|
df = filterData(getBooksData(), request.META.get('HTTP_YEAR'))
|
||||||
|
df = df.dropna()
|
||||||
|
|
||||||
|
statsTotalBooks = df['name'].count()
|
||||||
|
statsTotalPages = df['pages'].astype(int).sum()
|
||||||
|
statsTotalWriters = df['author'].nunique()
|
||||||
|
statsTotalCountries = df['country'].nunique()
|
||||||
|
statsTotalGenres = df['genre'].nunique()
|
||||||
|
|
||||||
|
|
||||||
|
data.append({
|
||||||
|
'totalbooks': statsTotalBooks,
|
||||||
|
'totalpages': statsTotalPages,
|
||||||
|
'totalauthors': statsTotalWriters,
|
||||||
|
'totalcountries': statsTotalCountries,
|
||||||
|
'totalgenres': statsTotalGenres
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
return Response(data[0])
|
||||||
|
else:
|
||||||
|
return Response("No year header included")
|
||||||
|
|
||||||
|
@api_view(['GET'])
|
||||||
|
def getYears(request):
|
||||||
|
df = filterData(getBooksData())
|
||||||
|
|
||||||
|
df['readed'] = pd.to_datetime(df['readed'], errors='coerce')
|
||||||
|
df['year']= df['readed'].dt.year
|
||||||
|
|
||||||
|
years = df.groupby('year')['year'].count().reset_index(name="count")
|
||||||
|
|
||||||
|
return Response(years['year'])
|
|
@ -5,15 +5,95 @@ export default class App extends Component {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
year: new Date().getFullYear(),
|
year: new Date().getFullYear(),
|
||||||
|
readingYears: [],
|
||||||
|
totalbooks: 0,
|
||||||
|
totalpages: 0,
|
||||||
|
totalauthors: 0,
|
||||||
|
totalcountries: 0,
|
||||||
|
totalgenres: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
this.yearsArray = [];
|
this.yearsArray = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
changeYear(event) {
|
changeYear(event) {
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
year: event.target.value
|
year: event.target.value
|
||||||
})
|
})
|
||||||
|
|
||||||
|
fetch('/api/books/stats', {
|
||||||
|
"method": "GET",
|
||||||
|
"headers": {
|
||||||
|
"year": event.target.value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
this.setState({
|
||||||
|
totalbooks: data.totalbooks,
|
||||||
|
totalpages: data.totalpages,
|
||||||
|
totalauthors: data.totalauthors,
|
||||||
|
totalcountries: data.totalcountries,
|
||||||
|
totalgenres: data.totalgenres
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
initHorBar(data){
|
||||||
|
|
||||||
|
var countries = [];
|
||||||
|
var counts = [];
|
||||||
|
|
||||||
|
data.forEach((count) => {
|
||||||
|
if (!countries.includes(count.country)) {
|
||||||
|
countries.push(count.country)
|
||||||
|
}
|
||||||
|
|
||||||
|
counts.push(count.count)
|
||||||
|
})
|
||||||
|
|
||||||
|
$("canvas#countryChart").remove();
|
||||||
|
$("div.books-per-country").append('<canvas id="countryChart"></canvas>');
|
||||||
|
|
||||||
|
var ctx = document.getElementById("countryChart");
|
||||||
|
new Chart(ctx, {
|
||||||
|
type: 'bar',
|
||||||
|
options: {
|
||||||
|
indexAxis: 'y',
|
||||||
|
plugins: {
|
||||||
|
legend: {
|
||||||
|
display: false
|
||||||
|
},
|
||||||
|
},
|
||||||
|
scales: {
|
||||||
|
x: {
|
||||||
|
ticks: {
|
||||||
|
beginAtZero: true,
|
||||||
|
color: "white",
|
||||||
|
},
|
||||||
|
stacked: true,
|
||||||
|
},
|
||||||
|
y: {
|
||||||
|
ticks: {
|
||||||
|
beginAtZero: true,
|
||||||
|
stepSize: 1,
|
||||||
|
color: "white",
|
||||||
|
},
|
||||||
|
stacked: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
labels: countries,
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
label: "Boeken",
|
||||||
|
data: counts,
|
||||||
|
backgroundColor: '#696ffc'
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
initDoughnut(data) {
|
initDoughnut(data) {
|
||||||
|
@ -50,12 +130,11 @@ export default class App extends Component {
|
||||||
options: {
|
options: {
|
||||||
//cutoutPercentage: 40,
|
//cutoutPercentage: 40,
|
||||||
responsive: true,
|
responsive: true,
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
initChart(data, ratings, year) {
|
initChart(data, year) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
----------------------------------
|
----------------------------------
|
||||||
|
@ -110,39 +189,6 @@ export default class App extends Component {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
----------------------------------
|
|
||||||
Avarage ratings per month
|
|
||||||
----------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
var avgRatings = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
|
||||||
|
|
||||||
for (var j = 0; j < 12; j++) {
|
|
||||||
|
|
||||||
if (j < 9) {
|
|
||||||
var month = "0" + (j + 1)
|
|
||||||
} else {
|
|
||||||
month = (j + 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0; i < ratings.length; i++) {
|
|
||||||
if (ratings[i].date == month + '-' + year) {
|
|
||||||
avgRatings[j] = ratings[i].rating;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dataSet.push({
|
|
||||||
label: 'Gemiddelde beoordeling',
|
|
||||||
data: avgRatings,
|
|
||||||
backgroundColor: '#ffa500',
|
|
||||||
borderColor: '#ffa500',
|
|
||||||
tension: 0.4,
|
|
||||||
type: 'line',
|
|
||||||
order: 1
|
|
||||||
})
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
----------------------------------
|
----------------------------------
|
||||||
Stacked bar chart
|
Stacked bar chart
|
||||||
|
@ -196,6 +242,8 @@ export default class App extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate() {
|
componentDidUpdate() {
|
||||||
|
var $this = this;
|
||||||
|
|
||||||
fetch('/api/books/genres', {
|
fetch('/api/books/genres', {
|
||||||
"method": "GET",
|
"method": "GET",
|
||||||
"headers": {
|
"headers": {
|
||||||
|
@ -204,17 +252,7 @@ export default class App extends Component {
|
||||||
})
|
})
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(books => {
|
.then(books => {
|
||||||
fetch('/api/ratings', {
|
this.initChart(books, this.state.year);
|
||||||
"method": "GET",
|
|
||||||
"headers": {
|
|
||||||
"year": this.state.year
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(ratings => {
|
|
||||||
this.initChart(books, ratings, this.state.year);
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
fetch('/api/books/genres/count', {
|
fetch('/api/books/genres/count', {
|
||||||
|
@ -227,10 +265,26 @@ export default class App extends Component {
|
||||||
.then(data => {
|
.then(data => {
|
||||||
this.initDoughnut(data);
|
this.initDoughnut(data);
|
||||||
})
|
})
|
||||||
|
|
||||||
|
fetch('/api/books/countries', {
|
||||||
|
"method": "GET",
|
||||||
|
"headers": {
|
||||||
|
"year": this.state.year
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
this.initHorBar(data);
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
|
||||||
|
var $this = this;
|
||||||
|
|
||||||
var currentyear = this.state.year ? this.state.year : new Date().getFullYear()
|
var currentyear = this.state.year ? this.state.year : new Date().getFullYear()
|
||||||
|
|
||||||
fetch('/api/books/genres', {
|
fetch('/api/books/genres', {
|
||||||
|
@ -241,17 +295,7 @@ export default class App extends Component {
|
||||||
})
|
})
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(books => {
|
.then(books => {
|
||||||
fetch('/api/ratings', {
|
this.initChart(books, currentyear);
|
||||||
"method": "GET",
|
|
||||||
"headers": {
|
|
||||||
"year": currentyear
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(ratings => {
|
|
||||||
this.initChart(books, ratings, currentyear);
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
fetch('/api/books/genres/count', {
|
fetch('/api/books/genres/count', {
|
||||||
|
@ -264,60 +308,106 @@ export default class App extends Component {
|
||||||
.then(data => {
|
.then(data => {
|
||||||
this.initDoughnut(data);
|
this.initDoughnut(data);
|
||||||
})
|
})
|
||||||
|
|
||||||
|
fetch('/api/books/countries', {
|
||||||
|
"method": "GET",
|
||||||
|
"headers": {
|
||||||
|
"year": this.state.year
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
this.initHorBar(data);
|
||||||
|
})
|
||||||
|
|
||||||
|
fetch('/api/books/stats', {
|
||||||
|
"method": "GET",
|
||||||
|
"headers": {
|
||||||
|
"year": this.state.year
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
$this.setState({
|
||||||
|
totalbooks: data.totalbooks,
|
||||||
|
totalpages: data.totalpages,
|
||||||
|
totalauthors: data.totalauthors,
|
||||||
|
totalcountries: data.totalcountries,
|
||||||
|
totalgenres: data.totalgenres
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
fetch('/api/books/years', {
|
||||||
|
"method": "GET",
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
this.setState({
|
||||||
|
readingYears: data
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<div className="sidebar">
|
|
||||||
<ul className="sidebar_menu">
|
|
||||||
<li className="menu-item">
|
|
||||||
<div className="menu-item-label">
|
|
||||||
<div className="menu-item-label-name"><i className="fa fa-chart-bar"></i> Dashboard</div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<div className="menu-item-label">
|
|
||||||
<div className="menu-item-label-name"><i class="fa fa-book-open"></i> Boeken</div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div className="content">
|
<div className="content">
|
||||||
<div className="filter">
|
|
||||||
<div className="container-fluid">
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-md-4">
|
|
||||||
<span style={{ color: '#ffffff', display: 'inline-block', width: 'auto' }}>Jaar: </span>
|
|
||||||
<select style={{ display: 'inline-block', width: 'auto' }} defaultValue={this.state.year} onChange={(event) => this.changeYear(event)}>
|
|
||||||
<option value="2020">2020</option>
|
|
||||||
<option value="2021">2021</option>
|
|
||||||
<option value="2022">2022</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="col-md-4"></div>
|
|
||||||
|
|
||||||
<div className="col-md-4"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="books-stats">
|
<div className="books-stats">
|
||||||
<div className="container-fluid">
|
<div className="container-fluid">
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-md-4">
|
<div className="col-md-2">
|
||||||
<div className="stat-block">
|
<div className="stat-block">
|
||||||
<span>Boeken</span>
|
<i class="fa fa-calendar"></i>
|
||||||
<span>17</span>
|
<span className="stats-number">
|
||||||
<span>-20%</span>
|
<select className="yearselector" defaultValue={this.state.year} onChange={(event) => this.changeYear(event)}>
|
||||||
|
{this.state.readingYears.map((year) => {
|
||||||
|
|
||||||
|
if(year === this.state.year){
|
||||||
|
var selected = 'selected'
|
||||||
|
}else{
|
||||||
|
selected = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
return(<option selected={selected} value={year}>{year}</option>)
|
||||||
|
})}
|
||||||
|
</select>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-4">
|
|
||||||
|
<div className="col-md-2">
|
||||||
<div className="stat-block">
|
<div className="stat-block">
|
||||||
<span>Bladzijdes</span>
|
<i class="fa fa-book"></i>
|
||||||
<span>512</span>
|
<span className="stats-number">{this.state.totalbooks}</span>
|
||||||
<span>+5%</span>
|
<span className="stats-label">Boeken</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-2">
|
||||||
|
<div className="stat-block">
|
||||||
|
<i class="fa fa-book-open"></i>
|
||||||
|
<span className="stats-number">{this.state.totalpages}</span>
|
||||||
|
<span className="stats-label">Bladzijdes</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-2">
|
||||||
|
<div className="stat-block">
|
||||||
|
<i class="fa fa-pen"></i>
|
||||||
|
<span className="stats-number">{this.state.totalauthors}</span>
|
||||||
|
<span className="stats-label">Schrijvers</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-2">
|
||||||
|
<div className="stat-block">
|
||||||
|
<i class="fa fa-book"></i>
|
||||||
|
<span className="stats-number">{this.state.totalgenres}</span>
|
||||||
|
<span className="stats-label">Genres</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-2">
|
||||||
|
<div className="stat-block">
|
||||||
|
<i class="fa fa-globe"></i>
|
||||||
|
<span className="stats-number">{this.state.totalcountries}</span>
|
||||||
|
<span className="stats-label">Landen</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -334,6 +424,17 @@ export default class App extends Component {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="container-fluid">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-6">
|
||||||
|
<div className="books-per-country"><canvas id="countryChart"></canvas></div>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
)
|
)
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -36,30 +36,11 @@
|
||||||
padding: 20px 0;
|
padding: 20px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.books-per-month, .genresPercent{
|
.books-per-month, .genresPercent, .books-per-country{
|
||||||
background: #1f2940;
|
background: #1f2940;
|
||||||
padding:20px;
|
padding:20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar{
|
|
||||||
position: fixed;
|
|
||||||
background-color: #1f2940;
|
|
||||||
width: 255px;
|
|
||||||
height: 100%;
|
|
||||||
box-shadow: 0 0 20px rgb(0 0 0 / 10%);
|
|
||||||
/* overflow-y: scroll; */
|
|
||||||
z-index: 999998;
|
|
||||||
transition: width .25s;
|
|
||||||
-ms-overflow-style: none;
|
|
||||||
scrollbar-width: none;
|
|
||||||
padding-top: 56px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content{
|
|
||||||
width: 100%;
|
|
||||||
padding-left: 255px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar .menu-item-label-name {
|
.sidebar .menu-item-label-name {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
|
@ -96,6 +77,58 @@
|
||||||
padding-left: 15px;
|
padding-left: 15px;
|
||||||
padding-right: 15px;
|
padding-right: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.books-stats{
|
||||||
|
margin:20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.books-stats .stat-block{
|
||||||
|
background: #1f2940;
|
||||||
|
padding: 10px 5px;
|
||||||
|
color:#ffffff;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.books-stats .stat-block i{
|
||||||
|
font-weight: 900;
|
||||||
|
font-size: 25px;
|
||||||
|
border-radius: 50%;
|
||||||
|
padding: 20px;
|
||||||
|
width: 70px;
|
||||||
|
height: 70px;
|
||||||
|
line-height: 30px;
|
||||||
|
text-align: center;
|
||||||
|
background: #696ffc;
|
||||||
|
box-shadow: 7px 7px 10px rgba(20,27,45,0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.books-stats .stat-block .stats-number{
|
||||||
|
font-weight: bold;
|
||||||
|
display: inline-block;
|
||||||
|
margin-left: 10px;
|
||||||
|
font-size: 25px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.books-stats .stat-block .stats-label{
|
||||||
|
color: rgba(255,255,255,0.5);
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.yearselector{
|
||||||
|
display: inline-block;
|
||||||
|
width: auto;
|
||||||
|
background: #1f2940;
|
||||||
|
border: none;
|
||||||
|
color: #fff;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container-fluid{
|
||||||
|
margin-bottom:20px !important;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue