engage_earn_api/src/events.rs
2023-04-16 13:38:07 -05:00

256 lines
6.3 KiB
Rust

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<AppState>,
) -> 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<AppState>,
) -> 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<AppState>,
) -> 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<AppState>,
Query(get_event_query): Query<GetEventQuery>,
) -> 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<AppState>,
Json(event_req): Json<NewEventRequestEntry>,
) -> 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(),
}
}