String is easyer to decode and the sendable data in the frontend will be limited.
134 lines
4.0 KiB
Rust
134 lines
4.0 KiB
Rust
use std::sync::Arc;
|
|
|
|
use axum::{
|
|
Json,
|
|
extract::{Path, State},
|
|
http::StatusCode,
|
|
response::IntoResponse,
|
|
};
|
|
use serde_json::json;
|
|
use sqlx::query;
|
|
|
|
use crate::{
|
|
AppState,
|
|
models::{Ticket, TicketCreateScheme, TicketResponse},
|
|
};
|
|
|
|
pub async fn create_ticket(
|
|
State(data): State<Arc<AppState>>,
|
|
Json(body): Json<TicketCreateScheme>,
|
|
) -> Result<impl IntoResponse, (StatusCode, Json<serde_json::Value>)> {
|
|
let query = query(
|
|
r#"INSERT INTO tickets (category, description, betreff, room) VALUES ($1, $2, $3, $4)"#,
|
|
)
|
|
.bind(body.category.to_string())
|
|
.bind(body.description.to_string())
|
|
.bind(body.betreff.to_string())
|
|
.bind(body.room)
|
|
.execute(&data.db)
|
|
.await;
|
|
|
|
if let Err(err) = query {
|
|
return Err((
|
|
StatusCode::INTERNAL_SERVER_ERROR,
|
|
Json(json!({"status": "error", "message": format!("{:?}", err),})),
|
|
));
|
|
}
|
|
|
|
let response_status = serde_json::json!({"status": "success"});
|
|
Ok(Json(response_status))
|
|
}
|
|
|
|
pub async fn delete_ticket(
|
|
Path(id): Path<i32>,
|
|
State(data): State<Arc<AppState>>,
|
|
) -> Result<impl IntoResponse, (StatusCode, Json<serde_json::Value>)> {
|
|
let query = sqlx::query(r#"DELETE FROM tickets WHERE id = $1"#)
|
|
.bind(id)
|
|
.execute(&data.db)
|
|
.await
|
|
.map_err(|e| {
|
|
(
|
|
StatusCode::INTERNAL_SERVER_ERROR,
|
|
Json(json!({"status": "error", "message": format!("{:?}", e)})),
|
|
)
|
|
})?;
|
|
|
|
if query.rows_affected() == 0 {
|
|
let error_response = serde_json::json!({
|
|
"status": "error",
|
|
"message": format!("Ticket with ID {} not found", id)
|
|
});
|
|
return Err((StatusCode::NOT_FOUND, Json(error_response)));
|
|
}
|
|
|
|
Ok(StatusCode::NO_CONTENT)
|
|
}
|
|
|
|
pub async fn get_tickets(
|
|
State(data): State<Arc<AppState>>,
|
|
) -> Result<impl IntoResponse, (StatusCode, Json<serde_json::Value>)> {
|
|
let tickets =
|
|
sqlx::query_as(r#"SELECT * FROM tickets WHERE status <> 'Archived' ORDER BY date DESC"#)
|
|
.fetch_all(&data.db)
|
|
.await
|
|
.map_err(|e| {
|
|
let error_response = serde_json::json!({
|
|
"status": "error",
|
|
"message": format!("Database error: {}", e),
|
|
});
|
|
(StatusCode::INTERNAL_SERVER_ERROR, Json(error_response))
|
|
})?;
|
|
|
|
let ticket_response = tickets
|
|
.iter()
|
|
.map(|ticket| filter_record(&ticket))
|
|
.collect::<Vec<TicketResponse>>();
|
|
|
|
let json_response = serde_json::json!(ticket_response);
|
|
Ok(Json(json_response))
|
|
}
|
|
|
|
pub async fn get_ticket_by_id(
|
|
Path(id): Path<i32>,
|
|
State(data): State<Arc<AppState>>,
|
|
) -> Result<impl IntoResponse, (StatusCode, Json<serde_json::Value>)> {
|
|
let query = sqlx::query_as(r#"SELECT * FROM tickets WHERE id = $1"#)
|
|
.bind(id)
|
|
.fetch_one(&data.db)
|
|
.await;
|
|
|
|
match query {
|
|
Ok(ticket) => {
|
|
let ticket_response = serde_json::json!(filter_record(&ticket));
|
|
return Ok(Json(ticket_response));
|
|
}
|
|
Err(sqlx::Error::RowNotFound) => {
|
|
let error_response = serde_json::json!({
|
|
"status": "fail",
|
|
"message": format!("Ticket with ID {} not found", id)
|
|
});
|
|
return Err((StatusCode::NOT_FOUND, Json(error_response)));
|
|
}
|
|
Err(e) => {
|
|
return Err((
|
|
StatusCode::INTERNAL_SERVER_ERROR,
|
|
Json(json!({"status": "error", "message": format!("{:?}", e)})),
|
|
));
|
|
}
|
|
};
|
|
}
|
|
|
|
fn filter_record(ticket: &Ticket) -> TicketResponse {
|
|
TicketResponse {
|
|
id: ticket.id.to_owned(),
|
|
category: ticket.category.to_owned(),
|
|
betreff: ticket.betreff.to_owned(),
|
|
description: ticket.description.to_owned(),
|
|
room: ticket.room.to_owned(),
|
|
status: ticket.status.to_owned(),
|
|
date: ticket.date.to_owned(),
|
|
user_id: ticket.user_id.to_owned(),
|
|
}
|
|
}
|