diff --git a/src/main.rs b/src/main.rs index 7669472..8149f35 100644 --- a/src/main.rs +++ b/src/main.rs @@ -129,7 +129,8 @@ async fn main() -> Result<(), Error> { .route("/update/:id", get(tasks::update_form)) .route("/update/:id", post(tasks::update_backend)) .route("/create", get(tasks::create_form)) - .route("/create", post(tasks::create_backend)); + .route("/create", post(tasks::create_backend)) + .route("/:id", get(tasks::task_detail)); let serve_dir = get_service(ServeDir::new( config.static_dir.unwrap_or_else(|| "static".into()), @@ -200,7 +201,7 @@ async fn homepage( .await?; let tasks: Vec = - sqlx::query_as("select title,description,status from tasks where owner=$1") + sqlx::query_as("select id,title,description,status from tasks where owner=$1") .bind(id) .fetch_all(&*pool) .await?; diff --git a/src/tasks.rs b/src/tasks.rs index d99514d..6cb00d9 100644 --- a/src/tasks.rs +++ b/src/tasks.rs @@ -19,6 +19,7 @@ use tera::Tera; #[derive(FromRow, Serialize, Deserialize)] pub struct RawTask { + pub id: i32, pub title: String, pub description: String, pub status: i32, @@ -37,6 +38,7 @@ pub enum Status { #[derive(Serialize)] pub struct Task { + pub id: i32, pub title: String, pub description: String, pub status: Status, @@ -45,6 +47,7 @@ pub struct Task { impl From for Task { fn from(t: RawTask) -> Self { Self { + id: t.id, title: t.title, description: t.description, status: Status::from(t.status), @@ -67,7 +70,7 @@ pub async fn update_form( .await?; let task: Option = - sqlx::query_as("select title,description,status from tasks where id=$1 and owner=$2") + sqlx::query_as("select id,title,description,status from tasks where id=$1 and owner=$2") .bind(id) .bind(user_id) .fetch_optional(&*pool) @@ -142,3 +145,36 @@ pub async fn create_backend( Ok(Redirect::to("/")) } + +pub async fn task_detail( + Path(id): Path, + Extension(tera): Extension>, + Extension(pool): Extension>>, + session: ReadableSession, +) -> Result, Error> { + let username = login_or_redirect!(session, "/login"); + + let (user_id,): (i32,) = sqlx::query_as("select id from users where username=$1") + .bind(&username) + .fetch_one(&*pool) + .await?; + + let task: Option = + sqlx::query_as("select id,title,description,status from tasks where id=$1 and owner=$2") + .bind(id) + .bind(user_id) + .fetch_optional(&*pool) + .await?; + + if let Some(task) = task.map(Task::from) { + let c = ctx! { + "task" => task + }; + + let rendered = tera.render("tasks/detail.html", &c)?; + + return Ok(Html(rendered)); + } + + Err(StatusCode::NOT_FOUND.into()) +} diff --git a/templates/home.html b/templates/home.html index 058f406..7795e08 100644 --- a/templates/home.html +++ b/templates/home.html @@ -5,7 +5,7 @@

{{task.title}}

{{task.status}}

diff --git a/templates/tasks/detail.html b/templates/tasks/detail.html new file mode 100644 index 0000000..e371deb --- /dev/null +++ b/templates/tasks/detail.html @@ -0,0 +1,8 @@ +{% extends 'base.html' %} +{% block content %} +
+

{{task.title}}

+

{{task.description}}

+

{{task.status}}

+
+{% endblock %}