add stat cards to index page, new pattern, misc

This commit is contained in:
2025-10-09 19:32:51 +02:00
parent d3a71827e1
commit 3b83bc89a0
8 changed files with 104 additions and 17 deletions

8
src/days.rs Normal file
View File

@@ -0,0 +1,8 @@
use chrono::{NaiveDate, Utc};
pub fn days_of_community_existence() -> i64 {
let formation = NaiveDate::from_ymd_opt(2020, 6, 7).unwrap();
let today = Utc::now().date_naive();
today.signed_duration_since(formation).num_days()
}

View File

@@ -12,8 +12,7 @@ pub fn init_service(ctx: &Context, guild_id: &GuildId) {
info!("Initialising discord member count service...");
if guild_id != MAIN_GUILD_ID {
info!("Guild member count service not initialised; Bot not running on main guild.");
return;
info!("Guild member count service initialised, but bot not running on main guild.");
}
tokio::spawn(async move {

View File

@@ -1,11 +1,14 @@
use std::error::Error;
use tokio::net::TcpListener;
mod days;
mod discordbot;
mod router;
mod setup;
mod website;
const SHRUG: &'static str = "¯\\_(ツ)_/¯";
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
setup::dotenv_and_tracing();

View File

@@ -1,8 +1,9 @@
use axum::{Router, http::StatusCode, routing::get};
use chrono::{NaiveDate, Utc};
use tower::service_fn;
use crate::{router::redirects::redirects, website::website_service};
use crate::{
days::days_of_community_existence, router::redirects::redirects, website::website_service,
};
mod redirects;
@@ -28,7 +29,7 @@ async fn api_fallback() -> (StatusCode, String) {
async fn get_member_count() -> (StatusCode, String) {
match crate::discordbot::get_member_count().await {
Some(count) => (StatusCode::OK, format!("{count}")),
Some(count) => (StatusCode::OK, count.to_string()),
None => (
StatusCode::INTERNAL_SERVER_ERROR,
format!("An error occured - could not fetch discord member count."),
@@ -37,9 +38,5 @@ async fn get_member_count() -> (StatusCode, String) {
}
async fn get_days_since_community_formation() -> String {
let formation = NaiveDate::from_ymd_opt(2020, 6, 7).unwrap();
let today = Utc::now().date_naive();
let days = today.signed_duration_since(formation).num_days();
days.to_string()
days_of_community_existence().to_string()
}

View File

@@ -4,14 +4,30 @@ use axum::{
response::{Html, IntoResponse, Response},
};
use crate::website::pages::INTERNAL_SERVER_ERROR_MSG;
use crate::{
SHRUG, days::days_of_community_existence, discordbot::get_member_count,
website::pages::INTERNAL_SERVER_ERROR_MSG,
};
#[derive(Template)]
#[template(path = "index.html")]
struct PageIndex;
struct PageIndex {
/// approximate discord server member count
dsc_members: String,
days_community: i64,
}
pub async fn page_index() -> Response {
let a = PageIndex;
let a = PageIndex {
dsc_members: match get_member_count().await {
Some(count) => match count {
..=512 => format!("{count}"),
_ => format!("~{count}"),
},
None => SHRUG.into(),
},
days_community: days_of_community_existence(),
};
match a.render() {
Ok(res) => (StatusCode::OK, Html(res)).into_response(),
Err(_e) => (StatusCode::INTERNAL_SERVER_ERROR, INTERNAL_SERVER_ERROR_MSG).into_response(),

View File

@@ -1,10 +1,11 @@
{% extends "base.html" %} {# # # # # # # # # # # # # # # # # # # # # # # # # #}
{%- import "statcard.html" as statcard -%} {# # # # # # # # # # # # # # # # # #}
{% block title %}gractwo.pl | Witamy!{% endblock %} {% block pagecontent %}
<div
class="bg-gractwo-index-light flex flex-col items-center text-center w-full h-full flex-1 pb-48"
class="bg-gractwo-index-light flex flex-col items-center text-center w-full h-full flex-1"
>
<div class="mt-16 md:mt-60 mx-auto [&>svg]:size-24">
<div class="mt-16 md:mt-56 mx-auto [&>svg]:size-24">
{% include "gractwo.svg" %}
</div>
<h1
@@ -50,7 +51,12 @@
YouTube</a
>
</div>
<div class="my-16 flex flex-col sm:flex-row gap-4">
{%call statcard::statcard(dsc_members, "członków na discordzie")%}
{%call statcard::statcard(days_community, "dni istnienia
społeczności")%}
<!--{% call statcard::statcard("0", "dni od powstania stowarzyszenia") %}-->
</div>
</div>
{% include "footer.html" %} {# # # # # # # # # # # # # # # # # # # # # # # # #}
{% endblock %}
{% include "footer.html" %} {% endblock %}

View File

@@ -16,6 +16,56 @@
linear-gradient(to right, #ff637e 15%, #00d3f2 100%);
}
.dashed-top-fade-grid {
position: absolute;
inset: 0;
z-index: 0;
background-image:
linear-gradient(to right, #e7e5e4 1px, transparent 1px),
linear-gradient(to bottom, #e7e5e4 1px, transparent 1px);
background-size: 20px 20px;
background-position:
0 0,
0 0;
mask-image:
repeating-linear-gradient(
to right,
black 0px,
black 3px,
transparent 3px,
transparent 8px
),
repeating-linear-gradient(
to bottom,
black 0px,
black 3px,
transparent 3px,
transparent 8px
),
radial-gradient(ellipse 70% 60% at 50% 0%, #000 60%, transparent 100%);
-webkit-mask-image:
repeating-linear-gradient(
to right,
black 0px,
black 3px,
transparent 3px,
transparent 8px
),
repeating-linear-gradient(
to bottom,
black 0px,
black 3px,
transparent 3px,
transparent 8px
),
radial-gradient(ellipse 70% 60% at 50% 0%, #000 60%, transparent 100%);
mask-composite: intersect;
-webkit-mask-composite: source-in;
}
.dashed-bottom-fade-grid {
position: absolute;
inset: 0;

8
web/statcard.html Normal file
View File

@@ -0,0 +1,8 @@
{% macro statcard(number, description) %}
<div
class="min-w-64 flex-1 p-4 bg-neutral-100 border border-neutral-300 shadow rounded"
>
<h1 class="font-bold text-2xl">{{ number }}</h1>
<p class="text-neutral-500 whitespace-nowrap">{{ description }}</p>
</div>
{% endmacro %}