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, EventWithConfirmed, GetEventQuery, NewEventRequestEntry, Role}, AppState, }; 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#" SELECT id, title, description, time_start, time_end, event_type AS "event_type!: EventType", points, place, price, created_by FROM events WHERE time_start BETWEEN now() AND now() + interval '1 week' ORDER BY time_start LIMIT 10; "# ) .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_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_recent_events( AuthBearer(token): AuthBearer, State(app_state): State, ) -> impl IntoResponse { let token_data = match handle_token(token, &app_state, Role::Student) { Ok(token_data) => token_data, Err(err) => return err, }; let result = query_as!( EventWithConfirmed, r#" SELECT e.id, e.title, e.description, e.time_start, e.time_end, e.event_type AS "event_type!: EventType", e.points, e.place, e.price, e.created_by, ea.confirmed FROM events e INNER JOIN event_attendees ea ON ea.event_id = e.id WHERE ea.user_id = $1 ; "#, token_data.id ) .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( AuthBearer(token): AuthBearer, State(app_state): State, Json(event_req): Json, ) -> impl IntoResponse { let token_data = match handle_token(token, &app_state, Role::Teacher) { Ok(value) => value, Err(value) => return value, }; let result = query!( r#" INSERT INTO events (title, description, time_start, time_end, event_type, points, place, price, created_by) VALUES ( $1, $2, $3, $4, $5, $6, $7, $8, $9 ) RETURNING id "#, event_req.title, event_req.description, event_req.time_start, event_req.time_end, event_req.event_type as EventType, event_req.points, event_req.place, event_req.price, token_data.id, ).fetch_one(&app_state.db_pool).await; match result { Ok(record) => (StatusCode::OK, Json(json!({ "data": record.id }))).into_response(), Err(err) => ( StatusCode::BAD_REQUEST, Json(json!({ "error": format!("Unknown error creating event: {:?}", err) })), ) .into_response(), } }