init
This commit is contained in:
commit
14a9704249
10 changed files with 1837 additions and 0 deletions
50
src/config.rs
Normal file
50
src/config.rs
Normal file
|
@ -0,0 +1,50 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
pub struct Config {
|
||||
pub projects: HashMap<String, Project>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
pub struct Project {
|
||||
pub name: String,
|
||||
pub description: String,
|
||||
pub website: Option<String>,
|
||||
pub documentation: Option<String>,
|
||||
pub since: Option<String>,
|
||||
pub contact: Option<ContactInfo>,
|
||||
pub sub: HashMap<String, Project>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
pub struct ContactInfo {
|
||||
pub email: Option<String>,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn load(path: &str) -> Self {
|
||||
serde_yml::from_str(&std::fs::read_to_string(path).unwrap()).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl Project {
|
||||
pub fn build(&self, card_id: &str) -> maud::PreEscaped<String> {
|
||||
let subcard_id = format!("{card_id}_sub");
|
||||
// todo : info
|
||||
|
||||
maud::html!(
|
||||
div class="card" id=(card_id) {
|
||||
h3 { (self.name) };
|
||||
p { "Description" };
|
||||
button class="expand-button" onclick=(format!("toggleSubcards('{subcard_id}')")) { "Expand" };
|
||||
div class="subcards" id=(subcard_id) {
|
||||
@for (id, prj) in &self.sub {
|
||||
(prj.build(id))
|
||||
}
|
||||
};
|
||||
};
|
||||
)
|
||||
}
|
||||
}
|
20
src/main.rs
Normal file
20
src/main.rs
Normal file
|
@ -0,0 +1,20 @@
|
|||
use config::Config;
|
||||
use rocket::{get, launch, routes, State};
|
||||
|
||||
mod config;
|
||||
mod site;
|
||||
|
||||
#[get("/")]
|
||||
pub fn main_page(c: &State<Config>) -> String {
|
||||
site::gen_site(c)
|
||||
}
|
||||
|
||||
#[launch]
|
||||
async fn rocket() -> _ {
|
||||
let conf_path: String = std::env::args()
|
||||
.next()
|
||||
.unwrap_or("./config.yml".to_string());
|
||||
let conf = config::Config::load(&conf_path);
|
||||
|
||||
rocket::build().mount("/", routes![main_page]).manage(conf)
|
||||
}
|
8
src/script.js
Normal file
8
src/script.js
Normal file
|
@ -0,0 +1,8 @@
|
|||
function toggleSubcards(id) {
|
||||
var subcards = document.getElementById(id);
|
||||
if (subcards.style.display === "block") {
|
||||
subcards.style.display = "none";
|
||||
} else {
|
||||
subcards.style.display = "block";
|
||||
}
|
||||
}
|
26
src/site.rs
Normal file
26
src/site.rs
Normal file
|
@ -0,0 +1,26 @@
|
|||
use crate::config::Config;
|
||||
|
||||
pub fn gen_site(c: &Config) -> String {
|
||||
maud::html!(
|
||||
(maud::DOCTYPE)
|
||||
html {
|
||||
head {
|
||||
meta charset="UTF-8";
|
||||
meta name="viewport" content="width=device-width, initial-scale=1.0";
|
||||
title { "Umbrella ☂️"};
|
||||
link rel="stylesheet" href="https://unpkg.com/@picocss/pico@latest/css/pico.min.css";
|
||||
style { (include_str!("style.css")) };
|
||||
};
|
||||
body {
|
||||
script { (include_str!("script.js")) };
|
||||
main class="container" {
|
||||
h1 { "Umbrella ☂️" };
|
||||
|
||||
@for (id, card) in &c.projects {
|
||||
(card.build(id));
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
).into_string()
|
||||
}
|
29
src/style.css
Normal file
29
src/style.css
Normal file
|
@ -0,0 +1,29 @@
|
|||
.card {
|
||||
border: 1px solid #ccc;
|
||||
padding: 1rem;
|
||||
margin: 1rem 0;
|
||||
position: relative;
|
||||
transition: max-height 0.3s ease-in-out;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.subcards {
|
||||
display: none;
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
.expand-button {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
background-color: #141414;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 0.3rem 0.6rem;
|
||||
cursor: pointer;
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
|
||||
.expand-button:hover {
|
||||
background-color: #0056b3;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue