Add create job endpoint

This commit is contained in:
2025-02-23 19:16:55 +01:00
parent bc2640dee0
commit b5699bd7c2
9 changed files with 100 additions and 4 deletions

View File

@@ -0,0 +1,18 @@
{% extends "website/base.html" %} {% block content %}
<div class="w-full mt-16"></div>
<form method="post" class="flex flex-col gap-2 text-black" action="/api/jobs">
<label for="position">Position</label>
<input type="text" name="position" id="position" class="p-2 border border-gray-300 rounded-md" required>
<label for="company">Company</label>
<input type="text" name="company" id="company" class="p-2 border border-gray-300 rounded-md" required>
<label for="technologies">Technologies</label>
<input type="text" name="technologies" id="technologies" class="p-2 border border-gray-300 rounded-md" required>
<label for="start_date">Start date</label>
<input type="date" name="start_date" id="start_date" class="p-2 border border-gray-300 rounded-md" required>
<label for="end_date">End date</label>
<input type="date" name="end_date" id="end_date" class="p-2 border border-gray-300 rounded-md">
<label for="still_working">Still working</label>
<input type="checkbox" name="still_working" id="still_working" value="true">
<button type="submit" class="p-2 text-gray-900 bg-yellow-500 rounded-sm shadow hover:bg-yellow-600">Submit</button>
</form>
{% endblock content%}

View File

@@ -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())

27
src/controllers/job.rs Normal file
View File

@@ -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<AppContext>,
Form(job_data): Form<CreateJobForm>,
) -> Result<Response> {
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))
}

View File

@@ -3,3 +3,4 @@ pub mod website;
pub mod data;
pub mod project;
pub mod job;

View File

@@ -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<TeraView>,
State(ctx): State<AppContext>,
) -> Result<impl IntoResponse> {
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))
}

View File

@@ -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 {
@@ -17,3 +19,14 @@ pub struct JobWithTechnologies {
pub technologies: Vec<String>,
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<NaiveDate>,
pub technologies: String,
pub still_working: bool,
}

View File

@@ -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<Vec<Model>> {
@@ -32,3 +32,19 @@ pub async fn get_all_jobs_with_technologies(ctx: &AppContext) -> Result<Vec<JobW
.collect();
Ok(jobs_with_technologies)
}
pub async fn create_job_from_form(ctx: &AppContext, job_data: &CreateJobForm) -> Result<Model> {
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)
}

5
src/views/job.rs Normal file
View File

@@ -0,0 +1,5 @@
use loco_rs::prelude::*;
pub async fn create_job(v: impl ViewRenderer) -> Result<impl IntoResponse> {
format::render().view(&v, "website/create-job.html", data!({}))
}

View File

@@ -2,3 +2,4 @@ pub mod auth;
pub mod data;
pub mod website;
pub mod projects;
pub mod job;