This commit is contained in:
2024-04-16 23:30:33 +02:00
parent d6f069d4a5
commit ffb728df64
7 changed files with 165 additions and 11 deletions

View File

@ -82,6 +82,7 @@ pub mod trees {
/// Whether the item has been "deleted", e.g. it shoudn't be shown in the view
// FIXME: this field is currently not used
#[serde(default)]
pub deleted: bool,
}

View File

@ -9,7 +9,7 @@ DB_PATH=./database
#ROCKET_PORT=8000
#ROCKET_WORKERS=[number of cpus * 2]
#ROCKET_LOG="normal"
#ROCKET_SECRET_KEY=[randomly generated at launch]
#ROCKET_SECRET_KEY=[random string, 44 or 88 for base64, 64 for hex]
#ROCKET_LIMITS="{ forms = 32768 }"
ROCKET_TEMPLATE_DIR="templates"
## =============================== ##

View File

@ -71,5 +71,10 @@ pub mod trees {
})
.collect::<Result<Result<_, _>, _>>()??)
}
pub fn put(tree: &sled::Tree, key: &K, val: &V) -> Result<(), StatusJson> {
tree.insert(serialize(key)?, serialize(val)?)?;
Ok(())
}
}
}

View File

@ -78,6 +78,8 @@ async fn main() -> io::Result<()> {
routes::pages::bump_session,
routes::pages::stats::single_stats,
routes::pages::stats::all_stats,
routes::pages::dailies::dailies,
routes::pages::dailies::new_daily,
routes::pages::weeks::weeks,
],
)

View File

@ -1,17 +1,58 @@
use rocket::{get, response::content::RawHtml, State};
use rocket::{
form::Form,
get, post,
response::{content::RawHtml, Redirect},
uri, FromForm, State,
};
use rocket_dyn_templates::Template;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
use crate::{
auth::Authorized, database::latest::trees::daily::V as Daily, status_json::StatusJson,
auth::Authorized,
database::latest::trees::daily::{self, V as Daily},
status_json::StatusJson,
};
#[get("/")]
#[derive(FromForm)]
pub struct NewDaily {
name: String,
unit: String,
unit_count: u32,
}
#[post("/dailies/new", data = "<daily>")]
pub fn new_daily(
_auth: Authorized,
db: &State<sled::Db>,
daily: Form<NewDaily>,
) -> Result<Redirect, StatusJson> {
let daily = daily.into_inner();
let daily = Daily {
name: daily.name,
unit: serde_json::from_str(&format!("\"{}\"", daily.unit)).unwrap(), // TODO
unit_count: daily.unit_count,
deleted: false,
};
let dailies_tree = db.open_tree(daily::NAME)?;
daily::put(&dailies_tree, &Uuid::new_v4(), &daily)?;
Ok(Redirect::to(uri!(dailies)))
}
#[get("/dailies")]
pub fn dailies(_auth: Authorized, db: &State<sled::Db>) -> Result<RawHtml<Template>, StatusJson> {
#[derive(Debug, Serialize, Deserialize)]
#[derive(Default, Debug, Serialize, Deserialize)]
struct TemplateContext {
dailies: Vec<Daily>,
}
todo!()
let dailies_tree = db.open_tree(daily::NAME)?;
let mut ctx = TemplateContext::default();
ctx.dailies = daily::get_all(&dailies_tree)?.into_values().collect();
ctx.dailies.sort_by(|a, b| a.name.cmp(&b.name));
Ok(RawHtml(Template::render("dailies", &ctx)))
}

View File

@ -233,6 +233,88 @@ ul.striped_list > li:nth-child(odd) ul li:nth-child(odd) { background-color:#30
display: none;
}
.dailies_list {
max-width: 40rem;
margin: auto;
display: flex;
flex-direction: column;
}
.dailies_entry {
color: wheat;
font-size: 1.5em;
background: #3a3743;
margin-bottom: 1rem;
padding: 1rem;
border-radius: 0.35rem;
border: .2rem solid #45374f;
display: flex;
cursor: pointer;
transition: background-color 0.1s;
}
.dailies_entry:hover {
background-color: #4c4858;
}
.dailies_entry:active {
background-color: #312e38;
}
.dailies_entry > span {
flex-grow: 1
}
.dailies_checkbox input[type=checkbox] {
visibility:hidden;
display:none
}
.dailies_checkbox *,
.dailies_checkbox :after,
.dailies_checkbox :before {
box-sizing:border-box
}
.dailies_checkbox .container {
cursor:pointer;
user-select:none;
font-size:25px;
display:block;
position:relative
}
.dailies_checkbox .checkmark {
--spread:10px;
background:#000;
border-radius:50px;
width:1.3em;
height:1.3em;
transition:all .7s;
position:relative;
top:0;
left:0
}
.dailies_checkbox .container input:checked~.checkmark {
box-shadow:-5px -5px var(--spread)0px #5b51d8,0 -5px var(--spread)0px #833ab4,5px -5px var(--spread)0px #e1306c,5px 0 var(--spread)0px #fd1d1d,5px 5px var(--spread)0px #f77737,0 5px var(--spread)0px #fcaf45,-5px 5px var(--spread)0px #ffdc80;
background:#000
}
.dailies_checkbox .checkmark:after {
content:"";
display:none;
position:absolute
}
.dailies_checkbox .container input:checked~.checkmark:after {
display:block
}
.dailies_checkbox .container .checkmark:after {
border:.15em solid wheat;
border-width:0 .15em .15em 0;
width:.25em;
height:.5em;
top:.34em;
left:.5em;
transform:rotate(45deg)
}
.life_calendar {
display: flex;
flex-direction: row;

View File

@ -3,12 +3,35 @@
{{> head}}
<body>
{{> header}}
<h1>Dailies</h2>
<div class="category_list">
{{#each categories}}
{{>category_entry}}
{{/each}}
<div class="striped_list dailies_list">
<h1>Dailies</h2>
{{#each dailies}}
<button class="dailies_entry">
<div class="dailies_checkbox"><label class="container"><input type="checkbox"><div class="checkmark"></div></label></div>
<span>
{{this.name}}
<span>1 gång per</span>
{{this.unit_count}}
{{this.unit}}
</span>
</button>
{{/each}}
<form action="/dailies/new" method="post">
<span>Namn</span>
<input type="text" name="name"></input>
<span>1 gång per</span>
<input type="number" name="unit_count"></input>
<select name="unit">
<option value="Day">Dag</option>
<option value="Week">Vecka</option>
<option value="Month">Månad</option>
<option value="Year">År</option>
</select>
<br>
<button type="submit">spara</button>
</form>
</div>
</body>
</html>