index should almost be done
This commit is contained in:
parent
8e82ec9523
commit
bbc7cda33f
3 changed files with 269 additions and 63 deletions
86
froxy-templates/examples/index.rs
Normal file
86
froxy-templates/examples/index.rs
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use froxy_templates::index::{self, ClusterData, IndexData, LocationData, MapPos, PcIssue};
|
||||
use smol_str::SmolStr;
|
||||
|
||||
fn main() {
|
||||
let mut env = minijinja::Environment::new();
|
||||
index::add_to_context(&mut env);
|
||||
|
||||
let data = index::render(
|
||||
&env,
|
||||
IndexData {
|
||||
clusters: HashMap::from([(
|
||||
SmolStr::new_static("F1"),
|
||||
ClusterData {
|
||||
users: 80,
|
||||
max_pc: 100,
|
||||
dead_pc: 1,
|
||||
silent: false,
|
||||
piscine: true,
|
||||
issues: [
|
||||
(SmolStr::new_static("F1r1s1"), PcIssue::Dead),
|
||||
(SmolStr::new_static("F1r2s1"), PcIssue::Attention),
|
||||
]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
map: index::Map {
|
||||
rows: [
|
||||
index::MapRow {
|
||||
range: SmolStr::new_static("R1"),
|
||||
col: [
|
||||
MapPos::Empty,
|
||||
MapPos::Flex,
|
||||
MapPos::Wall,
|
||||
MapPos::Door,
|
||||
MapPos::Empty,
|
||||
]
|
||||
.to_vec(),
|
||||
},
|
||||
index::MapRow {
|
||||
range: SmolStr::new_static("R2"),
|
||||
col: [
|
||||
MapPos::Empty,
|
||||
MapPos::Flex,
|
||||
MapPos::Pc(SmolStr::new_static("F1r1s1")),
|
||||
MapPos::Pc(SmolStr::new_static("F1r2s1")),
|
||||
MapPos::Pc(SmolStr::new_static("F1r3s1")),
|
||||
MapPos::Pc(SmolStr::new_static("F1r4s1")),
|
||||
MapPos::Pc(SmolStr::new_static("F1r5s1")),
|
||||
MapPos::Empty,
|
||||
]
|
||||
.to_vec(),
|
||||
},
|
||||
index::MapRow {
|
||||
range: SmolStr::new_static("R3"),
|
||||
col: [
|
||||
MapPos::Empty,
|
||||
MapPos::Flex,
|
||||
MapPos::Wall,
|
||||
MapPos::Door,
|
||||
MapPos::Empty,
|
||||
]
|
||||
.to_vec(),
|
||||
},
|
||||
]
|
||||
.to_vec(),
|
||||
},
|
||||
},
|
||||
)]),
|
||||
locations: [(SmolStr::new_static("F1r5s1"), LocationData {
|
||||
login: "maiboyer".into(),
|
||||
image: "https://friends.42paris.fr/proxy/resize/512/03c61af252becbca11aac5ff49a2e61c/maiboyer.jpg".into(),
|
||||
me: false,
|
||||
friend: false,
|
||||
close_friend: false,
|
||||
pooled: false,
|
||||
})]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
current_cluster: SmolStr::new_static("F1"),
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
println!("{data}");
|
||||
}
|
||||
|
|
@ -1,3 +1,7 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use smol_str::SmolStr;
|
||||
|
||||
pub use crate::templates::INDEX;
|
||||
|
||||
pub fn add_to_context(env: &mut minijinja::Environment) {
|
||||
|
|
@ -8,4 +12,110 @@ pub fn add_to_context(env: &mut minijinja::Environment) {
|
|||
crate::open_modal::add_to_context(env);
|
||||
}
|
||||
env.add_template("index.html", INDEX).unwrap();
|
||||
env.add_function("max", |a: i32, b: i32| -> i32 { a.max(b) });
|
||||
}
|
||||
|
||||
pub fn render(env: &minijinja::Environment, data: IndexData) -> Result<String, minijinja::Error> {
|
||||
let template = env.get_template("index.html")?;
|
||||
template.render(data)
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct LocationData {
|
||||
pub login: SmolStr,
|
||||
pub image: String,
|
||||
pub me: bool,
|
||||
pub friend: bool,
|
||||
pub close_friend: bool,
|
||||
pub pooled: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct ClusterData {
|
||||
pub users: u32,
|
||||
pub dead_pc: u32,
|
||||
pub max_pc: u32,
|
||||
pub silent: bool,
|
||||
pub piscine: bool,
|
||||
pub map: Map,
|
||||
pub issues: HashMap<SmolStr, PcIssue>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Default)]
|
||||
#[serde(try_from = "SmolStr", into = "SmolStr")]
|
||||
pub enum PcIssue {
|
||||
#[default]
|
||||
Dead,
|
||||
Attention,
|
||||
}
|
||||
|
||||
impl TryFrom<SmolStr> for PcIssue {
|
||||
type Error = &'static str;
|
||||
fn try_from(value: SmolStr) -> Result<Self, &'static str> {
|
||||
Ok(match value.as_str() {
|
||||
"dead" => Self::Dead,
|
||||
"attention" => Self::Attention,
|
||||
_ => return Err("Invalid string"),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PcIssue> for SmolStr {
|
||||
fn from(val: PcIssue) -> Self {
|
||||
match val {
|
||||
PcIssue::Dead => SmolStr::new_static("dead"),
|
||||
PcIssue::Attention => SmolStr::new_static("attention"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
#[serde(from = "SmolStr", into = "SmolStr")]
|
||||
pub enum MapPos {
|
||||
Wall,
|
||||
Flex,
|
||||
Empty,
|
||||
Door,
|
||||
Pc(SmolStr),
|
||||
}
|
||||
|
||||
impl From<SmolStr> for MapPos {
|
||||
fn from(value: SmolStr) -> Self {
|
||||
match value.as_str() {
|
||||
"x" => Self::Wall,
|
||||
"f" => Self::Flex,
|
||||
"" => Self::Empty,
|
||||
"d" => Self::Door,
|
||||
_ => Self::Pc(value),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl From<MapPos> for SmolStr {
|
||||
fn from(val: MapPos) -> Self {
|
||||
match val {
|
||||
MapPos::Wall => SmolStr::new_static("x"),
|
||||
MapPos::Flex => SmolStr::new_static("f"),
|
||||
MapPos::Door => SmolStr::new_static("d"),
|
||||
MapPos::Empty => SmolStr::new_static(""),
|
||||
MapPos::Pc(s) => s,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct MapRow {
|
||||
pub range: SmolStr,
|
||||
pub col: Vec<MapPos>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct Map {
|
||||
pub rows: Vec<MapRow>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct IndexData {
|
||||
pub locations: HashMap<SmolStr, LocationData>,
|
||||
pub clusters: HashMap<SmolStr, ClusterData>,
|
||||
pub current_cluster: SmolStr,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,13 +58,48 @@
|
|||
|
||||
<div class="text-center">
|
||||
<div class="btn-group mb-1 btn-width" role="group" aria-label="Change cluster">
|
||||
{% for cluster in clusters %}
|
||||
{% for name in clusters %}
|
||||
<input type="radio" class="btn-check cluster_radios" name="btn-radio"
|
||||
data-cluster="{{ cluster.name }}" id="radio{{ cluster.name }}"
|
||||
autocomplete="off" {{ "checked" if actual_cluster == cluster['name'] else "" }}>
|
||||
<label title="{{ (int(cluster.users / (cluster.maximum_places - cluster.dead_pc) * 100) if (cluster.maximum_places - cluster.dead_pc) > 0 else 0 ) }}%" class="btn btn-outline-{{ place_to_btn(cluster) }} m-t" for="radio{{ cluster.name }}">
|
||||
{{ ('<i class="fa-solid fa-person-swimming text-info"></i>' if cluster.name in piscine else '') | safe }}{{ (' ' if cluster.name in piscine and cluster.name in silent else '') | safe }}{{ ('<i class="fa-solid fa-volume-xmark text-secondary"></i> ' if cluster.name in silent else '') | safe }}{{ cluster.name }}
|
||||
<span class="text-muted">{{ cluster.users }}/{{ cluster.maximum_places - cluster.dead_pc }}</span></label>
|
||||
data-cluster="{{ name }}" id="radio{{ name }}"
|
||||
autocomplete="off">
|
||||
{% set cluster = clusters[name] %}
|
||||
{% set piscine = "" %}
|
||||
{% set silent = "" %}
|
||||
{% set spacer = "" %}
|
||||
|
||||
{%- if cluster.piscine -%}
|
||||
{% set piscine = '<i class="fa-solid fa-person-swimming text-info"></i>' %}
|
||||
{%- endif -%}
|
||||
{%- if cluster.silent -%}
|
||||
{% set piscine = '<i class="fa-solid fa-volume-xmark text-secondary"></i>' %}
|
||||
{%- endif -%}
|
||||
|
||||
{%- if cluster.piscine and cluster.silent -%}
|
||||
{% set spacer = " " %}
|
||||
{%- endif -%}
|
||||
|
||||
{% set u = cluster.users %}
|
||||
{% set m = cluster.max_pc - cluster.dead_pc %}
|
||||
|
||||
{%- if m < 0 -%}
|
||||
{% set m = 0 %}
|
||||
{%- endif -%}
|
||||
|
||||
{% set percent = 0 %}
|
||||
{%- if m > 0 -%}
|
||||
{% set percent = (u * 100) / m %}
|
||||
{%- endif -%}
|
||||
|
||||
{% set fill_level = 'primary' %}
|
||||
{%- if percent > 75 -%}
|
||||
{% set fill_level = 'danger' %}
|
||||
{%- elif percent > 65 -%}
|
||||
{% set fill_level = 'warning' %}
|
||||
{% endif%}
|
||||
|
||||
<label title="{{ percent | int }}%" class="btn btn-outline-{{ fill_level }} m-t" for="radio{{ name }}">
|
||||
{{ piscine | safe }}{{ spacer | safe }}{{ silent | safe }} {{ name }}
|
||||
<span class="text-muted">{{ u }}/{{ m }}</span></label>
|
||||
{%- endfor -%}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -72,86 +107,61 @@
|
|||
<table class="grid text-center">
|
||||
<tbody>
|
||||
|
||||
{% for index, x in enumerate(map[1:], 0) %}
|
||||
{% set map = clusters[current_cluster].map %}
|
||||
{% set cluster = clusters[current_cluster] %}
|
||||
{% for row in map.rows %}
|
||||
<tr>
|
||||
{%- set countB = namespace(value=1) -%}
|
||||
<td class="range">{{ map[0][index] }}</td>
|
||||
{%- for y in x -%}
|
||||
{%- if y == 'x' -%}
|
||||
{%- set countB = 0 -%}
|
||||
<td class="range">{{ row.range }}</td>
|
||||
{%- for col in row.col -%}
|
||||
{%- if col == 'x' -%}
|
||||
<td class="range"> </td>
|
||||
{%- elif y == '|' -%}
|
||||
{%- elif col == '|' -%}
|
||||
<td class="range-no-color"></td>
|
||||
{%- elif y == 'h' -%}
|
||||
{%- elif col == 'h' -%}
|
||||
<td></td>
|
||||
{%- elif y == 'd' -%}
|
||||
{%- elif col == 'd' -%}
|
||||
<td><i class="fa-solid fa-person-walking fa-2xl"></i></td>
|
||||
{%- elif y == 'f' -%}
|
||||
{%- elif col == 'f' -%}
|
||||
<td><i class="fa-solid fa-laptop fa-xl"></i></td>
|
||||
{%- elif exrypz(y) == False -%}
|
||||
{%- elif col == '' -%}
|
||||
<td class="small-colors"></td>
|
||||
{%- else -%}
|
||||
{%- set text_color = '' -%}
|
||||
{%- set img = '<i class="fa-solid fa-user"></i>' -%}
|
||||
{%- if y in locations -%}
|
||||
{%- set img = '<img loading="lazy" class="profile-pic2" alt="" src="' + (custom_image(locations[y]['user']['login']) if locations[y]['has_custom_image'] else proxy_images(locations[y]['user']['image']['versions']['small'])) + '">' -%}
|
||||
{%- elif actual_cluster in piscine and y in tutor_station -%}
|
||||
{%- set img = '<i class="fa-solid fa-shield tutor-shield"></i>' -%}
|
||||
{%- if col in locations -%}
|
||||
{%- set img = '<img loading="lazy" class="profile-pic2" alt="" src="' + locations[col].image + '">' -%}
|
||||
{%- endif -%}
|
||||
|
||||
{%- if actual_cluster in piscine and y in tutor_station -%}
|
||||
{%- set text_color = 'tutor-shield' -%}
|
||||
{%- endif -%}
|
||||
|
||||
{%- set relation = '' -%}
|
||||
{%- set currently_in_piscine = y in locations and (locations[y]['user']['pool_month'], locations[y]['user']['pool_year']) in piscine_date -%}
|
||||
{%- set in_piscine_cluster = actual_cluster in piscine -%}
|
||||
{%- if y in locations and locations[y]['user']['id'] not in tutors and currently_in_piscine != in_piscine_cluster -%}
|
||||
{%- set relation = 'wrong-cluster' -%}
|
||||
{%- endif -%}
|
||||
{%- if focus and focus == y %}
|
||||
{%- if focus and focus == col %}
|
||||
{%- set relation = 'focus' -%}
|
||||
{%- elif y in locations and locations[y]['me'] -%}
|
||||
{%- elif col in locations and locations[col].me -%}
|
||||
{%- set relation = 'me' -%}
|
||||
{%- elif y in locations and locations[y]['whitelist'] -%}
|
||||
{%- set relation = 'whitelist' -%}
|
||||
{%- elif y in locations and locations[y]['close_friend'] -%}
|
||||
{%- elif col in locations and locations[col].close_friend -%}
|
||||
{%- set relation = 'close_friend' -%}
|
||||
{%- elif y in locations and locations[y]['friend'] -%}
|
||||
{%- elif col in locations and locations[col].friend -%}
|
||||
{%- set relation = 'friend' -%}
|
||||
{%- elif y in issues_map and issues_map[y]['count'] >= 1 and issues_map[y]['issue'] == 1 -%}
|
||||
{%- set relation = 'dead' -%}
|
||||
{%- elif y in issues_map and issues_map[y]['count'] >= 1 and issues_map[y]['issue'] == 2 -%}
|
||||
{%- set relation = 'attention' -%}
|
||||
{%- elif y in locations and locations[y]['pool'] and actual_cluster not in piscine -%}
|
||||
{%- elif col in cluster.issues -%}
|
||||
{%- set relation = cluster.issues[col] -%}
|
||||
{%- elif col in locations and locations[col]['pool'] and not cluster.piscine -%}
|
||||
{%- set relation = 'pooled' -%}
|
||||
{%- endif -%}
|
||||
|
||||
{%- if actual_cluster in piscine and y in locations and locations[y]['user']['id'] in tutors -%}
|
||||
{%- set relation = 'tutor' -%}
|
||||
{%- set text_color = '' -%}
|
||||
{%- elif actual_cluster in piscine and y in locations and not locations[y]['user']['tutor'] in tutors and y in tutor_station -%}
|
||||
{%- set relation = 'tutor-spot' -%}
|
||||
{%- set text_color = '' -%}
|
||||
{%- endif -%}
|
||||
{%- if y in locations and locations[y]['admin'] -%}
|
||||
{%- set relation = 'admin' -%}
|
||||
{%- endif -%}
|
||||
|
||||
{%- if countB.value % 2 == 0 -%}
|
||||
<td data-pos="{{ y }}"
|
||||
data-login="{{ locations[y]['user']['login'] if y in locations else '' }}"
|
||||
class="sm-t case {{ relation }} {{ text_color }}">{{ img|safe }}<br>{{ y.replace(actual_cluster, '') }}
|
||||
{% set loc_name = col|replace(current_cluster, "") %}
|
||||
<td data-pos="{{ col }}"
|
||||
data-login="{{ locations[col].login if col in locations else '' }}"
|
||||
class="sm-t case {{ relation }}">
|
||||
{%- if countB % 2 == 0 -%}
|
||||
{{ img|safe }}<br>{{ loc_name }}
|
||||
{%- else -%}
|
||||
{{ loc_name }}<br>{{ img|safe }}
|
||||
{%- endif -%}
|
||||
</td>
|
||||
{%- else -%}
|
||||
<td data-pos="{{ y }}"
|
||||
data-login="{{ locations[y]['user']['login'] if y in locations else '' }}"
|
||||
class="sm-t case {{ relation }} {{ text_color }}">{{ y.replace(actual_cluster, '') }}<br>{{ img|safe }}
|
||||
</td>
|
||||
{%- endif -%}
|
||||
{%- endif -%}
|
||||
{%- set countB.value = countB.value + 1 -%}
|
||||
{%- set countB = (countB + 1) % 2 -%}
|
||||
{%- endfor -%}
|
||||
<td class="range">{{ map[0][index] }}</td>
|
||||
<td class="range">{{ row.range }}</td>
|
||||
</tr>
|
||||
{%- endfor -%}
|
||||
</tbody>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue