page edition done
This commit is contained in:
parent
6652a35ae9
commit
4a72745ab4
6 changed files with 238 additions and 7 deletions
|
@ -87,6 +87,48 @@ pub async fn create(db: &mut DbHook, doll: CreateDollProfile<'_>) -> sqlx::Resul
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn edit(db: &mut DbHook, doll: CreateDollProfile<'_>) -> sqlx::Result<()> {
|
||||
sqlx::query!(
|
||||
r#"
|
||||
update doll_profiles
|
||||
set microchip_id = $1,
|
||||
name = $2,
|
||||
pronoun_subject = $3,
|
||||
pronoun_object = $4,
|
||||
pronoun_possessive = $5,
|
||||
handler_name = $6,
|
||||
handler_link = $7,
|
||||
kind = $8,
|
||||
breed = $9,
|
||||
behaviour = $10,
|
||||
description = $11,
|
||||
chassis_type = $12,
|
||||
chassis_id = $13,
|
||||
chassis_color = $14
|
||||
where id = $15
|
||||
"#,
|
||||
doll.microchip_id,
|
||||
doll.name,
|
||||
doll.pronoun_subject,
|
||||
doll.pronoun_object,
|
||||
doll.pronoun_possessive,
|
||||
doll.handler_name,
|
||||
doll.handler_link,
|
||||
doll.kind,
|
||||
doll.breed,
|
||||
doll.behaviour,
|
||||
doll.description,
|
||||
doll.chassis_type,
|
||||
doll.chassis_id,
|
||||
doll.chassis_color,
|
||||
doll.id,
|
||||
)
|
||||
.execute(&mut **db)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// deleting a doll profile only wipes the data associated to it but retains two bits of info:
|
||||
/// - the tag's ID
|
||||
/// - the account which created this tag
|
||||
|
|
|
@ -36,6 +36,8 @@ fn rocket() -> _ {
|
|||
account::change_password,
|
||||
form::register_tag::show_register,
|
||||
form::register_tag::handle_register,
|
||||
form::register_tag::show_edit_tag,
|
||||
form::register_tag::handle_edit_tag,
|
||||
account::ask_delete,
|
||||
account::confirm_delete,
|
||||
account::ask_terminate_account,
|
||||
|
|
14
src/pages.rs
14
src/pages.rs
|
@ -49,3 +49,17 @@ impl<'r> FromRequest<'r> for CommonTemplateState {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// FakeContext exists to be used as a replacement for Context when reusing a form for creation and edition, to avoid repeating lots of code.
|
||||
///
|
||||
/// Note: i made this custom context thingy because i couldn't find a way to create a real context with the right populated data.
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(crate = "rocket::serde")]
|
||||
pub struct FakeContext {
|
||||
/// Values are made to simulate the same structure as the real Context
|
||||
pub values: HashMap<&'static str, Vec<String>>,
|
||||
/// NOP, used to placehold field errors
|
||||
pub errors: HashMap<String, ()>,
|
||||
/// NOP, used to placehold global errors
|
||||
pub form_errors: Vec<()>,
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use rocket::{
|
||||
form::{self, Contextual, Form},
|
||||
response::Redirect,
|
||||
|
@ -7,11 +9,11 @@ use rocket_dyn_templates::{context, Template};
|
|||
use crate::{
|
||||
db::{
|
||||
doll,
|
||||
schema::{CreateDollProfile, DollTagsDb, User},
|
||||
schema::{CreateDollProfile, DollProfile, DollTagsDb, User},
|
||||
},
|
||||
ids::{id_public_to_db, pick_ids},
|
||||
pages::CommonTemplateState,
|
||||
routes::{error_handlers::PageResult, public},
|
||||
pages::{CommonTemplateState, FakeContext},
|
||||
routes::{account, error_handlers::PageResult, public},
|
||||
};
|
||||
|
||||
#[get("/new_tag")]
|
||||
|
@ -21,6 +23,7 @@ pub async fn show_register(db: DollTagsDb, _user: User, meta: CommonTemplateStat
|
|||
Ok(Template::render(
|
||||
"register_tag",
|
||||
context! {
|
||||
mode: "register",
|
||||
ids,
|
||||
previous: form::Context::default(),
|
||||
meta,
|
||||
|
@ -29,6 +32,78 @@ pub async fn show_register(db: DollTagsDb, _user: User, meta: CommonTemplateStat
|
|||
.into())
|
||||
}
|
||||
|
||||
impl From<DollProfile> for FakeContext {
|
||||
fn from(tag: DollProfile) -> Self {
|
||||
FakeContext {
|
||||
values: HashMap::from([
|
||||
("id", vec![format!("{:0>6}", tag.id)]),
|
||||
(
|
||||
"microchip_id",
|
||||
vec![tag.microchip_id.unwrap_or(String::from(""))],
|
||||
),
|
||||
("name", vec![tag.name]),
|
||||
("pronoun_subject", vec![tag.pronoun_subject]),
|
||||
("pronoun_object", vec![tag.pronoun_object]),
|
||||
("pronoun_possessive", vec![tag.pronoun_possessive]),
|
||||
("handler_name", vec![tag.handler_name]),
|
||||
(
|
||||
"handler_link",
|
||||
vec![tag.handler_link.unwrap_or(String::from(""))],
|
||||
),
|
||||
("kind", vec![tag.kind.unwrap_or(String::from(""))]),
|
||||
("breed", vec![tag.breed.unwrap_or(String::from(""))]),
|
||||
("behaviour", vec![tag.behaviour.unwrap_or(String::from(""))]),
|
||||
(
|
||||
"description",
|
||||
vec![tag.description.unwrap_or(String::from(""))],
|
||||
),
|
||||
(
|
||||
"chassis_type",
|
||||
vec![tag.chassis_type.unwrap_or(String::from(""))],
|
||||
),
|
||||
(
|
||||
"chassis_id",
|
||||
vec![tag.chassis_id.unwrap_or(String::from(""))],
|
||||
),
|
||||
(
|
||||
"chassis_color",
|
||||
vec![tag.chassis_color.unwrap_or(String::from(""))],
|
||||
),
|
||||
]),
|
||||
errors: HashMap::new(),
|
||||
form_errors: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/edit_tag/<id>")]
|
||||
pub async fn show_edit_tag(
|
||||
mut db: DollTagsDb,
|
||||
id: &str,
|
||||
_user: User,
|
||||
meta: CommonTemplateState,
|
||||
) -> PageResult {
|
||||
let normalized_id = match id_public_to_db(id) {
|
||||
Some(v) => v,
|
||||
None => return Ok(Redirect::to(uri!("/account", account::index)).into()),
|
||||
};
|
||||
let tag = match doll::get(&mut *db, normalized_id, "").await? {
|
||||
Some(v) => v,
|
||||
None => return Ok(Redirect::to(uri!("/account", account::index)).into()),
|
||||
};
|
||||
|
||||
Ok(Template::render(
|
||||
"register_tag",
|
||||
context! {
|
||||
mode: "edit",
|
||||
id,
|
||||
previous: FakeContext::from(tag),
|
||||
meta,
|
||||
},
|
||||
)
|
||||
.into())
|
||||
}
|
||||
|
||||
#[derive(Debug, FromForm)]
|
||||
pub struct TagForm<'a> {
|
||||
#[field(validate=validate_id())]
|
||||
|
@ -109,6 +184,7 @@ pub async fn handle_register(
|
|||
return Ok(Template::render(
|
||||
"register_tag",
|
||||
context! {
|
||||
mode: "register",
|
||||
ids,
|
||||
previous: &tag.context,
|
||||
meta,
|
||||
|
@ -160,3 +236,71 @@ pub async fn handle_register(
|
|||
|
||||
Ok(Redirect::to(uri!(public::show_profile(Some(tag.ident), microchip_id))).into())
|
||||
}
|
||||
|
||||
#[post("/edit_tag/<id>", data = "<tag>")]
|
||||
pub async fn handle_edit_tag(
|
||||
mut db: DollTagsDb,
|
||||
id: &str,
|
||||
tag: Form<Contextual<'_, TagForm<'_>>>,
|
||||
user: User,
|
||||
meta: CommonTemplateState,
|
||||
) -> PageResult {
|
||||
let id = match id_public_to_db(id) {
|
||||
None => return Ok(Redirect::to(uri!("/account", crate::routes::account::index)).into()),
|
||||
Some(v) => v,
|
||||
};
|
||||
let tag = match tag.value {
|
||||
Some(ref values) => values,
|
||||
None => {
|
||||
debug!("tag edition form invalid, context: {:?}", &tag.context);
|
||||
|
||||
return Ok(Template::render(
|
||||
"register_tag",
|
||||
context! {
|
||||
mode: "edit",
|
||||
id,
|
||||
previous: &tag.context,
|
||||
meta,
|
||||
},
|
||||
)
|
||||
.into());
|
||||
}
|
||||
};
|
||||
|
||||
debug!("editing tag: {:?}", tag);
|
||||
fn normalize_opt(opt: &str) -> Option<&str> {
|
||||
if opt.len() != 0 {
|
||||
Some(opt)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
let normalized_microchip_id = tag.microchip_id.to_lowercase();
|
||||
let microchip_id = normalize_opt(&normalized_microchip_id);
|
||||
|
||||
doll::edit(
|
||||
&mut *db,
|
||||
CreateDollProfile {
|
||||
id,
|
||||
microchip_id,
|
||||
name: tag.name,
|
||||
pronoun_subject: tag.pronoun_subject,
|
||||
pronoun_object: tag.pronoun_object,
|
||||
pronoun_possessive: tag.pronoun_possessive,
|
||||
handler_name: tag.handler_name,
|
||||
handler_link: normalize_opt(tag.handler_link),
|
||||
kind: normalize_opt(tag.kind),
|
||||
breed: normalize_opt(tag.breed),
|
||||
behaviour: normalize_opt(tag.behaviour),
|
||||
description: normalize_opt(tag.description),
|
||||
chassis_type: normalize_opt(tag.chassis_type),
|
||||
chassis_id: normalize_opt(tag.chassis_id),
|
||||
chassis_color: normalize_opt(tag.chassis_color),
|
||||
bound_to_id: &user.id,
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(Redirect::to(uri!(public::show_profile(Some(tag.ident), microchip_id))).into())
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
<h3>{{profile.name}}</h3>
|
||||
<div class="subnav">
|
||||
<a href="/profile/{{profile.id}}">Public page</a>
|
||||
<a href="/account/edit/{{profile.id}}">Edit</a>
|
||||
<a href="/account/edit_tag/{{profile.id}}">Edit</a>
|
||||
<a href="/account/delete/{{profile.id}}">Delete</a>
|
||||
</div>
|
||||
</article>
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
{% extends "base" %}
|
||||
{% import "macros/form" as form %}
|
||||
{% block title %}Register a new tag - {% endblock title %}
|
||||
|
||||
{% block title %}{% if mode == "register" %}Register a new tag{% else %}Edit {{id}}{% endif %} - {% endblock title
|
||||
%}
|
||||
{% block main %}
|
||||
<h2>Register a new tag</h2>
|
||||
<h2>{% if mode == "register" %}Register a new tag{% else %}Edit {{id}}{% endif %}</h2>
|
||||
|
||||
<aside>
|
||||
<h3>A foreword</h3>
|
||||
|
@ -15,7 +17,11 @@
|
|||
</aside>
|
||||
|
||||
<section>
|
||||
{% if mode == "register" %}
|
||||
<h3>Now, to the registration!</h3>
|
||||
{% else %}
|
||||
<h3>Now, to the editing!</h3>
|
||||
{% endif %}
|
||||
|
||||
{% if previous.form_errors | length > 0 %}
|
||||
<div class="form-error">
|
||||
|
@ -30,14 +36,24 @@
|
|||
{% endif %}
|
||||
|
||||
<form method="POST">
|
||||
{% if mode != "register" %}
|
||||
<!-- No, changing this value in the HTML won't edit the tag, sorry :c it won't do anything but risk failing the edition -->
|
||||
<input type="hidden" name="ident" value="{{id}}">
|
||||
{% endif %}
|
||||
|
||||
<section>
|
||||
<h4>Firstly, the tag's ID</h4>
|
||||
{% if mode == "register" %}
|
||||
<p>
|
||||
You may enter your own, but in case of collision it will not be usable.<br />
|
||||
To that end, here's a few free ones you may also pick from.
|
||||
</p>
|
||||
{% else %}
|
||||
<p>You can't change a tag's ID for now. If it's something you'd like to do, contact me directly.</p>
|
||||
{% endif %}
|
||||
|
||||
<div class="dual-fields bordered raised">
|
||||
{% if mode == "register" %}
|
||||
<div>
|
||||
<p class="heading"><label for="ident">Enter its ID</label></p>
|
||||
<input type="text" inputmode="numeric" pattern="\d{6}" id="ident" name="ident" required size="6"
|
||||
|
@ -60,6 +76,13 @@
|
|||
placeholder="A hexadecimal ID" {{form::value(ctx=previous, name="microchip_id" )}}>
|
||||
{{form::error(ctx=previous, name="microchip_id")}}
|
||||
</div>
|
||||
{% else %}
|
||||
<p class="heading"><label for="microchip_id">If it's microchipped,<br />you may enter the chip's
|
||||
ID</label></p>
|
||||
<input type="text" pattern="(0x)?[a-fA-F0-9]+" id="microchip_id" name="microchip_id"
|
||||
placeholder="A hexadecimal ID" {{form::value(ctx=previous, name="microchip_id" )}}>
|
||||
{{form::error(ctx=previous, name="microchip_id")}}
|
||||
{% endif %}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
@ -182,7 +205,13 @@
|
|||
</div>
|
||||
</section>
|
||||
|
||||
<button class="submit" type="submit">Register this tag!</button>
|
||||
<button class="submit" type="submit">
|
||||
{% if mode == "register" %}
|
||||
Register this tag!
|
||||
{% else %}
|
||||
Save your changes
|
||||
{% endif %}
|
||||
</button>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue