add stat cards to index page, new pattern, misc
This commit is contained in:
8
src/days.rs
Normal file
8
src/days.rs
Normal 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()
|
||||||
|
}
|
||||||
@@ -12,8 +12,7 @@ pub fn init_service(ctx: &Context, guild_id: &GuildId) {
|
|||||||
info!("Initialising discord member count service...");
|
info!("Initialising discord member count service...");
|
||||||
|
|
||||||
if guild_id != MAIN_GUILD_ID {
|
if guild_id != MAIN_GUILD_ID {
|
||||||
info!("Guild member count service not initialised; Bot not running on main guild.");
|
info!("Guild member count service initialised, but bot not running on main guild.");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use tokio::net::TcpListener;
|
use tokio::net::TcpListener;
|
||||||
|
|
||||||
|
mod days;
|
||||||
mod discordbot;
|
mod discordbot;
|
||||||
mod router;
|
mod router;
|
||||||
mod setup;
|
mod setup;
|
||||||
mod website;
|
mod website;
|
||||||
|
|
||||||
|
const SHRUG: &'static str = "¯\\_(ツ)_/¯";
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<(), Box<dyn Error>> {
|
async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
setup::dotenv_and_tracing();
|
setup::dotenv_and_tracing();
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
use axum::{Router, http::StatusCode, routing::get};
|
use axum::{Router, http::StatusCode, routing::get};
|
||||||
use chrono::{NaiveDate, Utc};
|
|
||||||
use tower::service_fn;
|
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;
|
mod redirects;
|
||||||
|
|
||||||
@@ -28,7 +29,7 @@ async fn api_fallback() -> (StatusCode, String) {
|
|||||||
|
|
||||||
async fn get_member_count() -> (StatusCode, String) {
|
async fn get_member_count() -> (StatusCode, String) {
|
||||||
match crate::discordbot::get_member_count().await {
|
match crate::discordbot::get_member_count().await {
|
||||||
Some(count) => (StatusCode::OK, format!("{count}")),
|
Some(count) => (StatusCode::OK, count.to_string()),
|
||||||
None => (
|
None => (
|
||||||
StatusCode::INTERNAL_SERVER_ERROR,
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
format!("An error occured - could not fetch discord member count."),
|
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 {
|
async fn get_days_since_community_formation() -> String {
|
||||||
let formation = NaiveDate::from_ymd_opt(2020, 6, 7).unwrap();
|
days_of_community_existence().to_string()
|
||||||
let today = Utc::now().date_naive();
|
|
||||||
let days = today.signed_duration_since(formation).num_days();
|
|
||||||
|
|
||||||
days.to_string()
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,14 +4,30 @@ use axum::{
|
|||||||
response::{Html, IntoResponse, Response},
|
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)]
|
#[derive(Template)]
|
||||||
#[template(path = "index.html")]
|
#[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 {
|
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() {
|
match a.render() {
|
||||||
Ok(res) => (StatusCode::OK, Html(res)).into_response(),
|
Ok(res) => (StatusCode::OK, Html(res)).into_response(),
|
||||||
Err(_e) => (StatusCode::INTERNAL_SERVER_ERROR, INTERNAL_SERVER_ERROR_MSG).into_response(),
|
Err(_e) => (StatusCode::INTERNAL_SERVER_ERROR, INTERNAL_SERVER_ERROR_MSG).into_response(),
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
{% extends "base.html" %} {# # # # # # # # # # # # # # # # # # # # # # # # # #}
|
{% extends "base.html" %} {# # # # # # # # # # # # # # # # # # # # # # # # # #}
|
||||||
|
{%- import "statcard.html" as statcard -%} {# # # # # # # # # # # # # # # # # #}
|
||||||
{% block title %}gractwo.pl | Witamy!{% endblock %} {% block pagecontent %}
|
{% block title %}gractwo.pl | Witamy!{% endblock %} {% block pagecontent %}
|
||||||
|
|
||||||
<div
|
<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" %}
|
{% include "gractwo.svg" %}
|
||||||
</div>
|
</div>
|
||||||
<h1
|
<h1
|
||||||
@@ -50,7 +51,12 @@
|
|||||||
YouTube</a
|
YouTube</a
|
||||||
>
|
>
|
||||||
</div>
|
</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>
|
</div>
|
||||||
|
|
||||||
{% include "footer.html" %} {# # # # # # # # # # # # # # # # # # # # # # # # #}
|
{% include "footer.html" %} {% endblock %}
|
||||||
{% endblock %}
|
|
||||||
|
|||||||
@@ -16,6 +16,56 @@
|
|||||||
linear-gradient(to right, #ff637e 15%, #00d3f2 100%);
|
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 {
|
.dashed-bottom-fade-grid {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
|
|||||||
8
web/statcard.html
Normal file
8
web/statcard.html
Normal 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 %}
|
||||||
Reference in New Issue
Block a user