#5 Added more data to stats page and improved CSS
This commit is contained in:
parent
7c27aa31b6
commit
60cb8d7951
@ -46,7 +46,7 @@ class DatabaseController(ABC):
|
|||||||
for attr, value in with_fields.items():
|
for attr, value in with_fields.items():
|
||||||
try:
|
try:
|
||||||
setattr(obj, attr, value)
|
setattr(obj, attr, value)
|
||||||
except KeyError:
|
except AttributeError:
|
||||||
return of(value)
|
return of(value)
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
from .database import DatabaseController
|
from .database import DatabaseController
|
||||||
from models.stats import Stats
|
from models.stats import Stats
|
||||||
from datetime import datetime
|
from datetime import datetime, timedelta
|
||||||
from utils.general_utils import is_within_x_days
|
from utils.general_utils import is_within_x_days
|
||||||
|
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ class StatsController(DatabaseController):
|
|||||||
return self.get_many(query, params)
|
return self.get_many(query, params)
|
||||||
|
|
||||||
def read_days(self, product_id: int, prev_days: int = 7
|
def read_days(self, product_id: int, prev_days: int = 7
|
||||||
) -> dict[int, list[Stats]] | None:
|
) -> dict[datetime, list[Stats]] | None:
|
||||||
""" Returns data from within the given number of days """
|
""" Returns data from within the given number of days """
|
||||||
data = self.read_product(product_id)
|
data = self.read_product(product_id)
|
||||||
|
|
||||||
@ -64,16 +64,19 @@ class StatsController(DatabaseController):
|
|||||||
data
|
data
|
||||||
))
|
))
|
||||||
|
|
||||||
day_views: dict[int, list[Stats]] = dict()
|
day_views: dict[str, list[Stats]] = dict()
|
||||||
|
|
||||||
for i in range(0, prev_days):
|
for i in range(0, prev_days):
|
||||||
day_views[i] = list()
|
key = datetime.today() - timedelta(days=i)
|
||||||
|
day_views[key.strftime('%b-%d')] = list()
|
||||||
|
|
||||||
|
print(list(day_views))
|
||||||
# Organise data into distinct
|
# Organise data into distinct
|
||||||
for view in filtered_data:
|
for view in filtered_data:
|
||||||
diff = datetime.now()-view.viewDate
|
key = datetime.today() - (datetime.today() - view.viewDate)
|
||||||
day_views[diff.days].append(view)
|
day_views[key.strftime('%b-%d')].append(view)
|
||||||
|
|
||||||
|
print(list(day_views))
|
||||||
return day_views
|
return day_views
|
||||||
|
|
||||||
def read_product_views(self, id: int):
|
def read_product_views(self, id: int):
|
||||||
|
@ -31,14 +31,16 @@ def view_product_stats(id: int):
|
|||||||
prev_days: int = request.args.get('prev_days', 7, int)
|
prev_days: int = request.args.get('prev_days', 7, int)
|
||||||
data = db.read_days(id, prev_days)
|
data = db.read_days(id, prev_days)
|
||||||
|
|
||||||
|
# Recent Views
|
||||||
product_view_frequency_data = dict(map(
|
product_view_frequency_data = dict(map(
|
||||||
lambda k, v: (k, random.randint(0, 100)),
|
lambda k, v: (k, random.randint(70, 100)),
|
||||||
# lambda k, v: (k, len(v)),
|
# lambda k, v: (k, len(v)),
|
||||||
data.keys(),
|
data.keys(),
|
||||||
data.values()
|
data.values()
|
||||||
))
|
))
|
||||||
|
|
||||||
print(db.read_product_views(id))
|
# Total Views
|
||||||
|
total_views = db.read_product_views(id)
|
||||||
|
|
||||||
db = ProductController()
|
db = ProductController()
|
||||||
product = db.read_id(id)
|
product = db.read_id(id)
|
||||||
@ -62,7 +64,7 @@ def view_product_stats(id: int):
|
|||||||
"age": time_since_posted,
|
"age": time_since_posted,
|
||||||
"ranking": 0,
|
"ranking": 0,
|
||||||
"views": {
|
"views": {
|
||||||
"total": 0,
|
"total": total_views,
|
||||||
"headings": list(reversed(product_view_frequency_data.keys())),
|
"headings": list(reversed(product_view_frequency_data.keys())),
|
||||||
"data": list(reversed(product_view_frequency_data.values()))
|
"data": list(reversed(product_view_frequency_data.values()))
|
||||||
},
|
},
|
||||||
@ -72,8 +74,7 @@ def view_product_stats(id: int):
|
|||||||
return render_template(
|
return render_template(
|
||||||
"index.html",
|
"index.html",
|
||||||
content="stats.html",
|
content="stats.html",
|
||||||
headings=list(reversed(product_view_frequency_data.keys())),
|
data=data
|
||||||
data=list(reversed(product_view_frequency_data.values()))
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -57,11 +57,11 @@ CREATE TABLE IF NOT EXISTS Views (
|
|||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY,
|
||||||
userID INTEGER
|
userID INTEGER
|
||||||
REFERENCES Users (id)
|
REFERENCES Users (id)
|
||||||
ON DELETE NO ACTION
|
ON DELETE CASCADE
|
||||||
ON UPDATE NO ACTION,
|
ON UPDATE NO ACTION,
|
||||||
productID INTEGER NOT NULL
|
productID INTEGER NOT NULL
|
||||||
REFERENCES Users (id)
|
REFERENCES Users (id)
|
||||||
ON DELETE NO ACTION
|
ON DELETE CASCADE
|
||||||
ON UPDATE NO ACTION,
|
ON UPDATE NO ACTION,
|
||||||
viewDate TIMESTAMP NOT NULL
|
viewDate TIMESTAMP NOT NULL
|
||||||
)
|
)
|
||||||
|
6
static/css/stats.css
Normal file
6
static/css/stats.css
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
.stats {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
@ -1,10 +1,30 @@
|
|||||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/products.css') }}">
|
<link rel="stylesheet" href="{{ url_for('static', filename='css/products.css') }}">
|
||||||
|
<link rel="stylesheet" href="{{ url_for('static', filename='css/stats.css') }}">
|
||||||
|
|
||||||
|
<div class="stats">
|
||||||
<div>
|
<div>
|
||||||
<canvas id="myChart" width="800px" height="500px"></canvas>
|
<canvas id="myChart" width="800px" height="500px"></canvas>
|
||||||
|
<br >
|
||||||
|
<form method="GET">
|
||||||
|
<input type="radio" id="7days" name="prev_days" value=7>
|
||||||
|
<label for="7days">7 Days</label><br>
|
||||||
|
<input type="radio" id="31days" name="prev_days" value=31>
|
||||||
|
<label for="31days">31 Days</label><br>
|
||||||
|
<input type="radio" id="1year" name="prev_days" value=365>
|
||||||
|
<label for="1year">1 Year</label>
|
||||||
|
<input type="submit">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p>Age: {{data['age']}}</p>
|
||||||
|
<p>Ranking: {{data['ranking']}}</p>
|
||||||
|
<p>Stock Level: {{data['stocklevel']}}</p>
|
||||||
|
<p>Total Views: {{data['views']['total']}}</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -13,10 +33,10 @@
|
|||||||
new Chart(ctx, {
|
new Chart(ctx, {
|
||||||
type: 'line',
|
type: 'line',
|
||||||
data: {
|
data: {
|
||||||
labels: {{headings}},
|
labels: {{data['views']['headings']|safe}},
|
||||||
datasets: [{
|
datasets: [{
|
||||||
label: '# of Views',
|
label: '# of Views',
|
||||||
data: {{data}},
|
data: {{data['views']['data']}},
|
||||||
borderWidth: 1
|
borderWidth: 1
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
@ -38,11 +58,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="product-container">
|
|
||||||
{% if data != None %}
|
|
||||||
{% for stat in data %}
|
|
||||||
{% endfor %}
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
Loading…
Reference in New Issue
Block a user