#5 Added more data to stats page and improved CSS

This commit is contained in:
Luke Else 2024-02-09 22:01:25 +00:00
parent 7c27aa31b6
commit 60cb8d7951
6 changed files with 50 additions and 27 deletions

View File

@ -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

View File

@ -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):

View File

@ -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()))
) )

View File

@ -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
View File

@ -0,0 +1,6 @@
.stats {
display: flex;
justify-content: center;
align-items: center;
gap: 1rem;
}

View File

@ -1,9 +1,29 @@
<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>
<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>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script> <script src="https://cdn.jsdelivr.net/npm/chart.js"></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
}] }]
}, },
@ -39,10 +59,3 @@
} }
}); });
</script> </script>
<div class="product-container">
{% if data != None %}
{% for stat in data %}
{% endfor %}
{% endif %}
</div>