diff --git a/src/events.rs b/src/events.rs index 109549f..0ab1d63 100644 --- a/src/events.rs +++ b/src/events.rs @@ -1,15 +1,28 @@ -use axum::{extract::State, http::StatusCode, response::IntoResponse, Json}; +use axum::{ + extract::{Query, State}, + http::StatusCode, + response::IntoResponse, + Json, +}; use axum_auth::AuthBearer; use serde_json::json; use sqlx::{query, query_as}; use crate::{ jwt::handle_token, - models::{Event, EventType, NewEventRequestEntry, Role}, + models::{Event, EventType, GetEventQuery, NewEventRequestEntry, Role}, AppState, }; -pub async fn get_events_preview(State(app_state): State) -> impl IntoResponse { +pub async fn get_events_preview( + AuthBearer(token): AuthBearer, + State(app_state): State, +) -> impl IntoResponse { + match handle_token(token, &app_state, Role::Student) { + Ok(_) => {} + Err(err) => return err, + }; + let result = query_as!( Event, r#" @@ -46,6 +59,112 @@ LIMIT })), ), } + .into_response() +} + +pub async fn get_all_events( + AuthBearer(token): AuthBearer, + State(app_state): State, +) -> impl IntoResponse { + match handle_token(token, &app_state, Role::Student) { + Ok(_) => {} + Err(err) => return err, + }; + + let result = query_as!( + Event, + r#" +SELECT + id, + title, + description, + time_start, + time_end, + event_type AS "event_type!: EventType", + points, + place, + price, + created_by +FROM + events +WHERE + time_start > now() +ORDER BY + time_start +LIMIT + 100; + "# + ) + .fetch_all(&app_state.db_pool) + .await; + + match result { + Ok(events) => (StatusCode::OK, Json(json!(events))), + Err(err) => ( + StatusCode::INTERNAL_SERVER_ERROR, + Json(json!({ + "error": format!("Unknown error getting events: {}", err) + })), + ), + } + .into_response() +} + +pub async fn get_event( + AuthBearer(token): AuthBearer, + State(app_state): State, + Query(get_event_query): Query, +) -> impl IntoResponse { + match handle_token(token, &app_state, Role::Student) { + Ok(_) => {} + Err(err) => return err, + }; + + let result = query_as!( + Event, + r#" + SELECT + id, + title, + description, + time_start, + time_end, + event_type AS "event_type!: EventType", + points, + place, + price, + created_by + FROM + events + WHERE + id = $1 + "#, + get_event_query.id + ) + .fetch_one(&app_state.db_pool) + .await; + + match result { + Ok(event) => (StatusCode::OK, Json(json!(event))), + Err(err) => { + if matches!(err, sqlx::Error::RowNotFound) { + ( + StatusCode::NOT_FOUND, + Json(json!({ + "error": format!("Event {} not found.", get_event_query.id) + })), + ) + } else { + ( + StatusCode::INTERNAL_SERVER_ERROR, + Json(json!({ + "error": format!("Unknown error getting event: {}", err) + })), + ) + } + } + } + .into_response() } pub async fn create_event( diff --git a/src/main.rs b/src/main.rs index bf769cc..81dca1d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -43,8 +43,9 @@ async fn main() { .route("/", get(root)) .route("/user/signup", post(signup)) .route("/user/signin", post(signin)) - .route("/event", post(events::create_event)) + .route("/event", post(events::create_event).get(events::get_event)) .route("/event/preview", get(events::get_events_preview)) + .route("/event/all", get(events::get_all_events)) .route("/report", get(report::get_report)) .with_state(AppState { db_pool, diff --git a/src/models.rs b/src/models.rs index 1425ff9..c115359 100644 --- a/src/models.rs +++ b/src/models.rs @@ -30,6 +30,14 @@ pub struct NewEventRequestEntry { pub price: BigDecimal, } +/// The model for the get event request. +#[derive( + sqlx::Type, Copy, Clone, Hash, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, +)] +pub struct GetEventQuery { + pub id: i32, +} + /// The model for an Event in the db. #[derive(Clone, Serialize, Debug)] pub struct Event { diff --git a/src/report.rs b/src/report.rs index d00ba19..aeb0a91 100644 --- a/src/report.rs +++ b/src/report.rs @@ -12,10 +12,7 @@ use axum::{ use axum_auth::AuthBearer; use lazy_static::lazy_static; use serde_json::json; -use sqlx::{ - query_as, - types::chrono::{DateTime, Local, NaiveDate}, -}; +use sqlx::{query_as, types::chrono::Local}; use tera::{Context, Tera}; lazy_static! { @@ -37,8 +34,8 @@ pub async fn get_report( State(app_state): State, Query(report_query): Query, ) -> impl IntoResponse { - let token_data = match handle_token(token, &app_state, Role::Teacher) { - Ok(token_data) => token_data, + match handle_token(token, &app_state, Role::Teacher) { + Ok(_) => {} Err(err) => return err, };