tmtd/src/web.rs
2022-05-23 16:45:46 +02:00

177 lines
6.3 KiB
Rust

/*
* tmtd - Suckless To Do list
* Copyright (C) 2022 C4TG1RL5
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
use crate::{database::Database, task, templates};
use actix_web::{http::StatusCode, web, HttpResponse, HttpResponseBuilder, HttpServer, Responder};
use askama::Template;
use std::net::SocketAddr;
use std::sync::Arc;
pub struct App {
pub server: actix_web::dev::Server,
}
impl App {
pub async fn new(addr: SocketAddr, db: Arc<Database>) -> anyhow::Result<Self> {
let db = db.clone();
let server = HttpServer::new(move || {
actix_web::App::new().service((
web::resource("/")
.app_data(web::Data::new(db.clone()))
.route(web::get().to(index)),
web::resource("/users")
.app_data(web::Data::new(db.clone()))
.route(web::get().to(users)),
web::resource("/task")
.app_data(web::Data::new(db.clone()))
.route(web::get().to(tasks)),
web::resource("/admin")
.app_data(web::Data::new(db.clone()))
.route(web::get().to(admin)),
web::resource("/create")
.app_data(web::Data::new(db.clone()))
.route(web::get().to(create)),
web::resource("/login")
.app_data(web::Data::new(db.clone()))
.route(web::get().to(login)),
web::resource("/register")
.app_data(web::Data::new(db.clone()))
.route(web::get().to(register)),
web::resource("/api/task/create")
.app_data(web::Data::new(db.clone()))
.route(web::post().to(create_task)),
web::resource("/api/task/move")
.app_data(web::Data::new(db.clone()))
.route(web::post().to(move_task)),
//web::resource("/api/task/sort").route(web::post().to(sort_task)),
web::resource("/api/login")
.app_data(web::Data::new(db.clone()))
.route(web::post().to(login_user)),
web::resource("/api/register")
.app_data(web::Data::new(db.clone()))
.route(web::post().to(register_user)),
web::resource("/api/logout")
.app_data(web::Data::new(db.clone()))
.route(web::get().to(logout)),
))
})
.bind(addr)?
.run();
Ok(App { server })
}
}
async fn index(db: web::Data<Arc<Database>>) -> impl Responder {
let logged_in = db.logged_in().await;
let index = templates::Index { logged_in };
let html = index.render().unwrap();
HttpResponseBuilder::new(StatusCode::OK).body(html)
}
async fn tasks(db: web::Data<Arc<Database>>) -> impl Responder {
let tasks = db.get_tasks().await;
let html = tasks.render().unwrap();
HttpResponseBuilder::new(StatusCode::OK).body(html)
}
async fn users(db: web::Data<Arc<Database>>) -> impl Responder {
let logged_in = db.logged_in().await;
let users = templates::Users { logged_in };
let html = users.render().unwrap();
HttpResponseBuilder::new(StatusCode::OK).body(html)
}
async fn admin(db: web::Data<Arc<Database>>) -> impl Responder {
let logged_in = db.logged_in().await;
let admin_panel = templates::AdminPanel { logged_in };
let html = admin_panel.render().unwrap();
HttpResponseBuilder::new(StatusCode::OK).body(html)
}
async fn create(db: web::Data<Arc<Database>>) -> impl Responder {
let logged_in = db.logged_in().await;
let create = templates::CreateTask { logged_in };
let html = create.render().unwrap();
HttpResponseBuilder::new(StatusCode::OK).body(html)
}
async fn login(db: web::Data<Arc<Database>>) -> impl Responder {
let logged_in = db.logged_in().await;
let login = templates::Login { logged_in };
let html = login.render().unwrap();
HttpResponseBuilder::new(StatusCode::OK).body(html)
}
async fn register(db: web::Data<Arc<Database>>) -> impl Responder {
let logged_in = db.logged_in().await;
let register = templates::Register { logged_in };
let html = register.render().unwrap();
HttpResponseBuilder::new(StatusCode::OK).body(html)
}
async fn create_task(
req: web::Form<task::CreateTask>,
db: web::Data<Arc<Database>>,
) -> impl Responder {
let task = req.into_inner();
db.create_task(&task).await;
HttpResponse::SeeOther()
.insert_header(("Location", "/task"))
.finish()
}
async fn move_task(req: web::Form<task::MoveTask>, db: web::Data<Arc<Database>>) -> impl Responder {
let task = req.into_inner();
db.move_task(&task).await;
HttpResponse::SeeOther()
.insert_header(("Location", "/task"))
.finish()
}
async fn sort_task(req: web::Form<task::SortTask>) -> impl Responder {
// TODO: save selected categories in a cookie or something
HttpResponse::SeeOther()
.insert_header(("Location", "/task"))
.finish()
}
async fn login_user(req: web::Form<task::Login>, db: web::Data<Arc<Database>>) -> impl Responder {
db.login(&req.username, &req.password).await;
HttpResponse::SeeOther()
.insert_header(("Location", "/"))
.finish()
}
async fn register_user(
req: web::Form<task::Register>,
db: web::Data<Arc<Database>>,
) -> impl Responder {
db.register(&req.username, &req.password).await;
HttpResponse::SeeOther()
.insert_header(("Location", "/"))
.finish()
}
async fn logout(db: web::Data<Arc<Database>>) -> impl Responder {
// TODO: log the user out
HttpResponse::SeeOther()
.insert_header(("Location", "/"))
.finish()
}