From b5699bd7c2118a9f276a7705965d15d54be11919 Mon Sep 17 00:00:00 2001 From: Gabriel Kaszewski Date: Sun, 23 Feb 2025 19:16:55 +0100 Subject: [PATCH] Add create job endpoint --- assets/views/website/create-job.html | 18 ++++++++++++++++++ src/app.rs | 1 + src/controllers/job.rs | 27 +++++++++++++++++++++++++++ src/controllers/mod.rs | 3 ++- src/controllers/website.rs | 14 ++++++++++++++ src/models/jobs.rs | 13 +++++++++++++ src/services/jobs.rs | 20 ++++++++++++++++++-- src/views/job.rs | 5 +++++ src/views/mod.rs | 3 ++- 9 files changed, 100 insertions(+), 4 deletions(-) create mode 100644 assets/views/website/create-job.html create mode 100644 src/controllers/job.rs create mode 100644 src/views/job.rs diff --git a/assets/views/website/create-job.html b/assets/views/website/create-job.html new file mode 100644 index 0000000..d360a22 --- /dev/null +++ b/assets/views/website/create-job.html @@ -0,0 +1,18 @@ +{% extends "website/base.html" %} {% block content %} +
+
+ + + + + + + + + + + + + +
+{% endblock content%} \ No newline at end of file diff --git a/src/app.rs b/src/app.rs index 06c80ed..932b84c 100644 --- a/src/app.rs +++ b/src/app.rs @@ -48,6 +48,7 @@ impl Hooks for App { fn routes(_ctx: &AppContext) -> AppRoutes { AppRoutes::with_default_routes() // controller routes below + .add_route(controllers::job::routes()) .add_route(controllers::project::routes()) .add_route(controllers::data::routes()) .add_route(controllers::auth::routes()) diff --git a/src/controllers/job.rs b/src/controllers/job.rs new file mode 100644 index 0000000..cbac206 --- /dev/null +++ b/src/controllers/job.rs @@ -0,0 +1,27 @@ +#![allow(clippy::missing_errors_doc)] +#![allow(clippy::unnecessary_struct_initialization)] +#![allow(clippy::unused_async)] +use loco_rs::prelude::*; + +use crate::{ + models::{jobs::CreateJobForm, users}, + services, +}; + +async fn create_job( + auth: auth::JWT, + State(ctx): State, + Form(job_data): Form, +) -> Result { + match users::Model::find_by_pid(&ctx.db, &auth.claims.pid).await { + Ok(_) => {} + Err(_) => return unauthorized("Unauthorized"), + } + + let job = services::jobs::create_job_from_form(&ctx, &job_data).await?; + format::json(&job) +} + +pub fn routes() -> Routes { + Routes::new().prefix("api/jobs/").add("/", post(create_job)) +} diff --git a/src/controllers/mod.rs b/src/controllers/mod.rs index f7d7a76..3503c40 100644 --- a/src/controllers/mod.rs +++ b/src/controllers/mod.rs @@ -2,4 +2,5 @@ pub mod auth; pub mod website; pub mod data; -pub mod project; \ No newline at end of file +pub mod project; +pub mod job; \ No newline at end of file diff --git a/src/controllers/website.rs b/src/controllers/website.rs index b934dae..52d5546 100644 --- a/src/controllers/website.rs +++ b/src/controllers/website.rs @@ -80,6 +80,19 @@ pub async fn render_data( views::data::list(v, &ctx).await } +async fn render_create_job( + auth: auth::JWT, + ViewEngine(v): ViewEngine, + State(ctx): State, +) -> Result { + match users::Model::find_by_pid(&ctx.db, &auth.claims.pid).await { + Ok(_) => {} + Err(_) => return unauthorized("Unauthorized"), + } + + views::job::create_job(v).await +} + pub fn routes() -> Routes { Routes::new() .add("/", get(render_index)) @@ -89,6 +102,7 @@ pub fn routes() -> Routes { .add("/projects/create", get(render_create_project)) .add("/projects/:id", get(render_project_detail)) .add("/projects/project/:name", get(render_project_detail_from_name)) + .add("/jobs/create", get(render_create_job)) .add("/data", get(render_data)) .add("/about", get(render_about)) } diff --git a/src/models/jobs.rs b/src/models/jobs.rs index 53d6e26..67c0b19 100644 --- a/src/models/jobs.rs +++ b/src/models/jobs.rs @@ -1,6 +1,8 @@ use super::_entities::jobs::{ActiveModel, Entity}; use sea_orm::entity::prelude::*; use serde::{Deserialize, Serialize}; +use chrono::NaiveDate; + pub type Jobs = Entity; impl ActiveModelBehavior for ActiveModel { @@ -16,4 +18,15 @@ pub struct JobWithTechnologies { pub end_date: Option, pub technologies: Vec, pub still_working: bool, +} + +#[derive(Serialize, Deserialize)] +pub struct CreateJobForm { + pub position: String, + pub company: String, + pub start_date: NaiveDate, + #[serde(default)] + pub end_date: Option, + pub technologies: String, + pub still_working: bool, } \ No newline at end of file diff --git a/src/services/jobs.rs b/src/services/jobs.rs index 245436c..e100392 100644 --- a/src/services/jobs.rs +++ b/src/services/jobs.rs @@ -2,8 +2,8 @@ use loco_rs::prelude::*; use sea_orm::QueryOrder; use crate::{models::{ - _entities::jobs::{Column, Entity, Model}, - jobs::JobWithTechnologies, + _entities::jobs::{ActiveModel, Column, Entity, Model}, + jobs::{CreateJobForm, JobWithTechnologies}, }, shared::get_technologies_from_string::get_technologies_from_string}; pub async fn get_all_jobs(ctx: &AppContext) -> Result> { @@ -32,3 +32,19 @@ pub async fn get_all_jobs_with_technologies(ctx: &AppContext) -> Result Result { + let new_job = ActiveModel { + company: Set(job_data.company.clone()), + position: Set(job_data.position.clone()), + start_date: Set(job_data.start_date.clone()), + end_date: Set(job_data.end_date.clone()), + technologies: Set(job_data.technologies.clone()), + still_working: Set(job_data.still_working), + ..Default::default() + }; + + let job = new_job.insert(&ctx.db).await?; + + Ok(job) +} diff --git a/src/views/job.rs b/src/views/job.rs new file mode 100644 index 0000000..de19b54 --- /dev/null +++ b/src/views/job.rs @@ -0,0 +1,5 @@ +use loco_rs::prelude::*; + +pub async fn create_job(v: impl ViewRenderer) -> Result { + format::render().view(&v, "website/create-job.html", data!({})) +} diff --git a/src/views/mod.rs b/src/views/mod.rs index 6f9d696..314d6a1 100644 --- a/src/views/mod.rs +++ b/src/views/mod.rs @@ -1,4 +1,5 @@ pub mod auth; pub mod data; pub mod website; -pub mod projects; \ No newline at end of file +pub mod projects; +pub mod job; \ No newline at end of file