Create detailed task view
This commit is contained in:
parent
d24ec3ee51
commit
88df6bb956
|
@ -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<RawTask> =
|
||||
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?;
|
||||
|
|
38
src/tasks.rs
38
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<RawTask> 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<RawTask> =
|
||||
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<i32>,
|
||||
Extension(tera): Extension<Arc<Tera>>,
|
||||
Extension(pool): Extension<Arc<Pool<Postgres>>>,
|
||||
session: ReadableSession,
|
||||
) -> Result<Html<String>, 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<RawTask> =
|
||||
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())
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<h3>{{task.title}}</h3>
|
||||
<p>{{task.status}}</p>
|
||||
<div class="text-align-right">
|
||||
<a href="/tasks/1"> <!-- TODO: make this actually use the task ID -->
|
||||
<a href="/tasks/{{task.id}}"> <!-- TODO: make this actually use the task ID -->
|
||||
<button>More Info »</button>
|
||||
</a>
|
||||
</div>
|
||||
|
|
8
templates/tasks/detail.html
Normal file
8
templates/tasks/detail.html
Normal file
|
@ -0,0 +1,8 @@
|
|||
{% extends 'base.html' %}
|
||||
{% block content %}
|
||||
<div class="card">
|
||||
<h3>{{task.title}}</h3>
|
||||
<p>{{task.description}}</p>
|
||||
<p>{{task.status}}</p>
|
||||
</div>
|
||||
{% endblock %}
|
Loading…
Reference in a new issue