From d110c64e7ade3dfccebdceabd48efff3b345013d Mon Sep 17 00:00:00 2001 From: Chris Jean-Marie Date: Mon, 4 Nov 2024 22:11:41 +0000 Subject: [PATCH 1/5] Initial secret-gift-exchange --- ...241103140734_secret-gift-exchange.down.sql | 5 +++ ...20241103140734_secret-gift-exchange.up.sql | 27 ++++++++++++ backend/src/secret_gift_exchange.rs | 42 +++++++++++++++++++ 3 files changed, 74 insertions(+) create mode 100644 backend/migrations/20241103140734_secret-gift-exchange.down.sql create mode 100644 backend/migrations/20241103140734_secret-gift-exchange.up.sql create mode 100644 backend/src/secret_gift_exchange.rs diff --git a/backend/migrations/20241103140734_secret-gift-exchange.down.sql b/backend/migrations/20241103140734_secret-gift-exchange.down.sql new file mode 100644 index 0000000..506c33d --- /dev/null +++ b/backend/migrations/20241103140734_secret-gift-exchange.down.sql @@ -0,0 +1,5 @@ +-- Add down migration script here +drop table gift_exchange; +drop table gift_exchange_participants; + +delete from role_permissions where item = '/giftexchange'; diff --git a/backend/migrations/20241103140734_secret-gift-exchange.up.sql b/backend/migrations/20241103140734_secret-gift-exchange.up.sql new file mode 100644 index 0000000..ce169d2 --- /dev/null +++ b/backend/migrations/20241103140734_secret-gift-exchange.up.sql @@ -0,0 +1,27 @@ +-- Add up migration script here +CREATE TABLE + `gift_exchange` ( + `id` integer not null primary key autoincrement, + `created_at` INTEGER not null default CURRENT_TIMESTAMP, + `created_by` ineger null, + `updated_at` INTEGER null default CURRENT_TIMESTAMP, + `updated_by` integer null, + `name` varchar(255) null, + `exchange_date` INTEGER null, + unique (`id`) + ); + + CREATE TABLE + `gift_exchange_participants` ( + `id` integer not null primary key autoincrement, + `created_at` INTEGER not null default CURRENT_TIMESTAMP, + `created_by` ineger null, + `updated_at` INTEGER null default CURRENT_TIMESTAMP, + `updated_by` integer null, + `exchange_id` INTEGER not null, + `participant_id` INTEGER not null, + `gifter_id` INTEGER null, + unique (`id`) + ); + +insert into `role_permissions` (`created_at`, `created_by`, `id`, `item`, `role_id`, `updated_at`, `updated_by`) values ('0', '0', '10', '/giftexchange', '2', '0', '0') \ No newline at end of file diff --git a/backend/src/secret_gift_exchange.rs b/backend/src/secret_gift_exchange.rs new file mode 100644 index 0000000..a5dc4cd --- /dev/null +++ b/backend/src/secret_gift_exchange.rs @@ -0,0 +1,42 @@ +/// Select participants from user list +/// create group id for exchange +/// allow user to only see their recipient but whole list of participants +/// link to recipient wish list +/// button to create selections +/// +/// Database schema +/// Table - gift_exchange +/// Columns - id -> number +/// - created_by -> number +/// - created_at -> number +/// - updated_by -> number +/// - updated_at -> number +/// - name -> text +/// - exchange_date -> number +/// +/// Table - gift_exchange_participants +/// Columns - id -> number +/// - created_by -> number +/// - created_at -> number +/// - updated_by -> number +/// - updated_at -> number +/// - exchange_id -> number (reference gift_exchange table) +/// - participant_id -> number (reference user table) +/// - gifter_id -> number (reference user table) +/// +/// Pages - sge_list +/// - list of gift exchanges user is part of +/// - sge_exchange +/// - exchange details +/// - list of participants +/// - sge_edit +/// - create new exchange +/// - edit existing exchange +/// - sge_participant_edit +/// - add or remove participant to exchange +/// +/// API - select gifters + +pub fn select_gifters() { + +} From a590bf114a8845876623b327a02a61a2f0e5ef5a Mon Sep 17 00:00:00 2001 From: Chris Jean-Marie Date: Tue, 5 Nov 2024 21:35:06 +0000 Subject: [PATCH 2/5] Add bootstrap-table --- backend/src/wishlist.rs | 57 ++++++++++++++++------------ backend/templates/authorized.html | 1 + backend/templates/base.html | 14 +++++-- backend/templates/useradmin.html | 6 +-- backend/templates/userwishlist.html | 6 +-- backend/templates/userwishlists.html | 6 +-- 6 files changed, 53 insertions(+), 37 deletions(-) diff --git a/backend/src/wishlist.rs b/backend/src/wishlist.rs index b42fa6c..3e1e2f8 100644 --- a/backend/src/wishlist.rs +++ b/backend/src/wishlist.rs @@ -1,12 +1,19 @@ use askama_axum::{IntoResponse, Response, Template}; -use axum::{extract::{Path, State}, response::Redirect, Extension, Form}; +use axum::{ + extract::{Path, State}, + response::Redirect, + Extension, Form, +}; use axum_extra::response::Html; use chrono::Utc; use http::StatusCode; use serde::Deserialize; -use sqlx::{SqlitePool, Row}; +use sqlx::{Row, SqlitePool}; -use crate::{middlewares::is_authorized, user::{get_user_roles_display, get_user_wishlist_items, UserData, UserWishlistItem}}; +use crate::{ + middlewares::is_authorized, + user::{get_user_roles_display, get_user_wishlist_items, UserData, UserWishlistItem}, +}; struct HtmlTemplate(T); @@ -48,17 +55,17 @@ pub async fn wishlists( .await .unwrap(); - let userid = user_data.as_ref().map(|s| s.id.clone()).unwrap_or_default(); + let userid = user_data.as_ref().map(|s| s.id.clone()).unwrap_or_default(); - if is_authorized("/userwishlists", user_data, db_pool.clone()).await { - // Get user roles - let user_roles = get_user_roles_display(userid, &db_pool.clone()).await; + if is_authorized("/userwishlists", user_data, db_pool.clone()).await { + // Get user roles + let user_roles = get_user_roles_display(userid, &db_pool.clone()).await; - let template = WishListsTemplate { - logged_in, - name, - users, - user_roles, + let template = WishListsTemplate { + logged_in, + name, + users, + user_roles, }; HtmlTemplate(template).into_response() } else { @@ -97,11 +104,11 @@ pub async fn user_wishlist( .await .unwrap(); - if is_authorized("/wishlist", user_data, db_pool.clone()).await { - // Get user roles - let user_roles = get_user_roles_display(userid, &db_pool.clone()).await; + if is_authorized("/wishlist", user_data, db_pool.clone()).await { + // Get user roles + let user_roles = get_user_roles_display(userid, &db_pool.clone()).await; - // Get user wishlist + // Get user wishlist let user_wishlist_items = get_user_wishlist_items(user_id, &db_pool.clone()).await; // Is viewed and viewing user the same (my wishlist)? @@ -151,10 +158,10 @@ pub async fn user_wishlist_add( let userid = user_data.as_ref().map(|s| s.id.clone()).unwrap_or_default(); if is_authorized("/wishlist", user_data, db_pool.clone()).await { - // Get user roles - let user_roles = get_user_roles_display(userid, &db_pool.clone()).await; + // Get user roles + let user_roles = get_user_roles_display(userid, &db_pool.clone()).await; - // Get user wishlist items + // Get user wishlist items let user_wishlist_items = get_user_wishlist_items(user_id, &db_pool.clone()).await; // Create the wishlist template. @@ -181,7 +188,7 @@ pub async fn user_wishlist_add_item( Path(user_id): Path, State(db_pool): State, Extension(user_data): Extension>, - Form(item_form): Form + Form(item_form): Form, ) -> impl IntoResponse { if is_authorized("/wishlist", user_data.clone(), db_pool.clone()).await { // Insert new item to database @@ -209,12 +216,12 @@ pub async fn user_wishlist_add_item( pub async fn user_wishlist_bought_item( Path(user_id): Path, State(db_pool): State, - Extension(user_data): Extension> + Extension(user_data): Extension>, ) -> impl IntoResponse { if is_authorized("/wishlist", user_data.clone(), db_pool.clone()).await { // Update item to purchased sqlx::query("update wishlist_items set purchased_by = ? where id = ?") - .bind(user_data.as_ref().unwrap().id)// Created by current user + .bind(user_data.as_ref().unwrap().id) // Created by current user .bind(user_id) .execute(&db_pool) .await @@ -222,7 +229,7 @@ pub async fn user_wishlist_bought_item( // Redirect to user wishlist // Extract the user data. - let row = sqlx::query( "SELECT user_id FROM wishlist_items WHERE id = ?") + let row = sqlx::query("SELECT user_id FROM wishlist_items WHERE id = ?") .bind(user_id) .fetch_one(&db_pool) .await @@ -239,14 +246,14 @@ pub async fn user_wishlist_bought_item( pub async fn user_wishlist_received_item( Path(user_id): Path, State(db_pool): State, - Extension(user_data): Extension> + Extension(user_data): Extension>, ) -> impl IntoResponse { if is_authorized("/wishlist", user_data.clone(), db_pool.clone()).await { // Update item received time let now = Utc::now().timestamp(); sqlx::query("update wishlist_items set received_at = ? where id = ?") - .bind(now)// Received now + .bind(now) // Received now .bind(user_id) .execute(&db_pool) .await diff --git a/backend/templates/authorized.html b/backend/templates/authorized.html index 1c8500a..f3429f7 100644 --- a/backend/templates/authorized.html +++ b/backend/templates/authorized.html @@ -9,6 +9,7 @@
  • Web links
  • Cottage Calendar
  • Wish lists
  • +
  • Gift Exchanges
  • {% for user_role in user_roles %} {% if user_role.role_name == "admin" %} diff --git a/backend/templates/base.html b/backend/templates/base.html index 66b687b..2662a1a 100644 --- a/backend/templates/base.html +++ b/backend/templates/base.html @@ -8,10 +8,14 @@ - + - + + + +
    @@ -51,7 +55,11 @@
    - + + + \ No newline at end of file diff --git a/backend/templates/useradmin.html b/backend/templates/useradmin.html index 0418cd4..e252f6c 100644 --- a/backend/templates/useradmin.html +++ b/backend/templates/useradmin.html @@ -2,11 +2,11 @@ {% block title %}User Administration{% endblock %} {% block center %}

    Users

    - +
    - - + + diff --git a/backend/templates/userwishlist.html b/backend/templates/userwishlist.html index 85e76d7..93de39f 100644 --- a/backend/templates/userwishlist.html +++ b/backend/templates/userwishlist.html @@ -12,11 +12,11 @@ Add {% endif %}
    -
    NameemailNameemail
    +
    - - + + diff --git a/backend/templates/userwishlists.html b/backend/templates/userwishlists.html index be9e49a..b857ea7 100644 --- a/backend/templates/userwishlists.html +++ b/backend/templates/userwishlists.html @@ -2,11 +2,11 @@ {% block title %}Wish Lists{% endblock %} {% block center %}

    Wishlists

    -
    ItemStateItemState Action
    +
    - - + + From f362fa8c932cf4e78d75110bba60e90fc550466e Mon Sep 17 00:00:00 2001 From: Chris Jean-Marie Date: Tue, 5 Nov 2024 21:35:40 +0000 Subject: [PATCH 3/5] Basic giftexchange view funtionality --- ...20241103140734_secret-gift-exchange.up.sql | 19 +- backend/src/main.rs | 4 + backend/src/secret_gift_exchange.rs | 174 +++++++++++++++++- backend/templates/giftexchange.html | 52 ++++++ backend/templates/giftexchanges.html | 29 +++ 5 files changed, 264 insertions(+), 14 deletions(-) create mode 100644 backend/templates/giftexchange.html create mode 100644 backend/templates/giftexchanges.html diff --git a/backend/migrations/20241103140734_secret-gift-exchange.up.sql b/backend/migrations/20241103140734_secret-gift-exchange.up.sql index ce169d2..0d5946a 100644 --- a/backend/migrations/20241103140734_secret-gift-exchange.up.sql +++ b/backend/migrations/20241103140734_secret-gift-exchange.up.sql @@ -3,11 +3,12 @@ CREATE TABLE `gift_exchange` ( `id` integer not null primary key autoincrement, `created_at` INTEGER not null default CURRENT_TIMESTAMP, - `created_by` ineger null, - `updated_at` INTEGER null default CURRENT_TIMESTAMP, - `updated_by` integer null, - `name` varchar(255) null, - `exchange_date` INTEGER null, + `created_by` integer not null default 0, + `updated_at` INTEGER not null default CURRENT_TIMESTAMP, + `updated_by` integer not null default 0, + `name` varchar(255) not null, + `exchange_date` INTEGER not null, + `status` INTEGER not null default 0, unique (`id`) ); @@ -15,12 +16,12 @@ CREATE TABLE `gift_exchange_participants` ( `id` integer not null primary key autoincrement, `created_at` INTEGER not null default CURRENT_TIMESTAMP, - `created_by` ineger null, - `updated_at` INTEGER null default CURRENT_TIMESTAMP, - `updated_by` integer null, + `created_by` integer not null default 0, + `updated_at` INTEGER not null default CURRENT_TIMESTAMP, + `updated_by` integer not null default 0, `exchange_id` INTEGER not null, `participant_id` INTEGER not null, - `gifter_id` INTEGER null, + `gifter_id` INTEGER not null, unique (`id`) ); diff --git a/backend/src/main.rs b/backend/src/main.rs index ca6db55..b646d04 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -2,6 +2,7 @@ use std::net::SocketAddr; use axum::{ middleware, routing::{get, get_service}, Extension, Router }; +use secret_gift_exchange::{giftexchange, giftexchanges}; use sqlx::{sqlite::SqlitePoolOptions, SqlitePool}; use sqlx::migrate::Migrator; use tower_http::services::ServeDir; @@ -13,6 +14,7 @@ mod routes; mod user; mod wishlist; mod email; +mod secret_gift_exchange; use error_handling::AppError; use middlewares::inject_user_data; @@ -62,6 +64,8 @@ async fn main() { .route("/userwishlist/add/:user_id", get(user_wishlist_add).post(user_wishlist_add_item)) .route("/userwishlist/bought/:user_id", get(user_wishlist_bought_item)) .route("/userwishlist/received/:user_id", get(user_wishlist_received_item)) + .route("/giftexchanges", get(giftexchanges)) + .route("/giftexchange/:giftexchange_id", get(giftexchange)) .nest_service("/assets", ServeDir::new("templates/assets") .fallback(get_service(ServeDir::new("templates/assets")))) .route("/", get(index)) diff --git a/backend/src/secret_gift_exchange.rs b/backend/src/secret_gift_exchange.rs index a5dc4cd..eb5cd4d 100644 --- a/backend/src/secret_gift_exchange.rs +++ b/backend/src/secret_gift_exchange.rs @@ -1,9 +1,26 @@ +use askama::Template; +use askama_axum::{IntoResponse, Response}; +use axum::{ + extract::{Path, State}, + response::Redirect, + Extension, +}; +use axum_extra::response::Html; +use http::StatusCode; +use serde::{Deserialize, Serialize}; +use sqlx::{FromRow, SqlitePool}; + +use crate::{ + middlewares::is_authorized, + user::{get_user_roles_display, UserData}, +}; + /// Select participants from user list /// create group id for exchange /// allow user to only see their recipient but whole list of participants /// link to recipient wish list /// button to create selections -/// +/// /// Database schema /// Table - gift_exchange /// Columns - id -> number @@ -13,7 +30,7 @@ /// - updated_at -> number /// - name -> text /// - exchange_date -> number -/// +/// /// Table - gift_exchange_participants /// Columns - id -> number /// - created_by -> number @@ -23,7 +40,7 @@ /// - exchange_id -> number (reference gift_exchange table) /// - participant_id -> number (reference user table) /// - gifter_id -> number (reference user table) -/// +/// /// Pages - sge_list /// - list of gift exchanges user is part of /// - sge_exchange @@ -34,9 +51,156 @@ /// - edit existing exchange /// - sge_participant_edit /// - add or remove participant to exchange -/// +/// /// API - select gifters -pub fn select_gifters() { +struct HtmlTemplate(T); +impl IntoResponse for HtmlTemplate +where + T: Template, +{ + fn into_response(self) -> Response { + match self.0.render() { + Ok(html) => Html(html).into_response(), + Err(err) => ( + StatusCode::INTERNAL_SERVER_ERROR, + format!("Failed to render template. Error: {}", err), + ) + .into_response(), + } + } } + +#[derive(Default, Clone, Debug, Serialize, Deserialize, FromRow)] +struct GiftExchange { + id: i64, + created_at: i64, + created_by: i64, + updated_at: i64, + updated_by: i64, + name: String, + exchange_date: i64, + status: i64, +} + +#[derive(Template)] +#[template(path = "giftexchanges.html")] +struct GiftExchangesTemplate { + logged_in: bool, + name: String, + user_roles: Vec, + giftexchanges: Vec, +} + +pub async fn giftexchanges( + Extension(user_data): Extension>, + State(db_pool): State, +) -> impl IntoResponse { + let user_name = user_data.as_ref().map(|s| s.name.clone()); + let logged_in = user_name.is_some(); + let name = user_name.unwrap_or_default(); + + let giftexchanges = sqlx::query_as::<_, GiftExchange>("SELECT * FROM gift_exchange") + .fetch_all(&db_pool) + .await + .unwrap(); + + let userid = user_data.as_ref().map(|s| s.id.clone()).unwrap_or_default(); + + if is_authorized("/giftexchange", user_data, db_pool.clone()).await { + // Get user roles + let user_roles = get_user_roles_display(userid, &db_pool.clone()).await; + + let template = GiftExchangesTemplate { + logged_in, + name, + user_roles, + giftexchanges, + }; + HtmlTemplate(template).into_response() + } else { + Redirect::to("/").into_response() + } +} + +#[derive(Default, Clone, Debug, Serialize, Deserialize, FromRow)] +struct GiftExchangeParticipant { + id: i64, + created_at: i64, + created_by: i64, + updated_at: i64, + updated_by: i64, + exchange_id: i64, + participant_id: i64, + gifter_id: i64, +} + +#[derive(Template)] +#[template(path = "giftexchange.html")] +struct GiftExchangeTemplate { + logged_in: bool, + name: String, + user_roles: Vec, + giftexchange: GiftExchange, + participants: Vec, + non_participants: Vec, +} + +pub async fn giftexchange( + Path(exchange_id): Path, + Extension(user_data): Extension>, + State(db_pool): State, +) -> impl IntoResponse { + let user_name = user_data.as_ref().map(|s| s.name.clone()); + let logged_in = user_name.is_some(); + let name = user_name.unwrap_or_default(); + let userid = user_data.as_ref().map(|s| s.id.clone()).unwrap_or_default(); + + if is_authorized("/giftexchange", user_data, db_pool.clone()).await { + // Get user roles + let user_roles = get_user_roles_display(userid, &db_pool.clone()).await; + + // Get gift exchange + let giftexchange = match sqlx::query_as!(GiftExchange, "SELECT * FROM gift_exchange WHERE id = ?", exchange_id) + .fetch_one(&db_pool) + .await { + Ok(giftexchange) => giftexchange, + Err(_) => { + GiftExchange::default() + }}; + + // Get participants + let participants = sqlx::query_as::<_, GiftExchangeParticipant>( + "SELECT * FROM gift_exchange_participants WHERE exchange_id = ?", + ) + .bind(exchange_id) + .fetch_all(&db_pool) + .await + .unwrap(); + + // Get non participants + let non_participants = sqlx::query_as::<_, UserData>( + "select * from users where users.id not in (select participant_id from gift_exchange_participants where exchange_id = ?)", + ) + .bind(exchange_id) + .fetch_all(&db_pool) + .await + .unwrap(); + + let template = GiftExchangeTemplate { + logged_in, + name, + user_roles, + giftexchange, + participants, + non_participants, + }; + HtmlTemplate(template).into_response() + } else { + Redirect::to("/").into_response() + } +} + +pub fn select_gifters() {} + diff --git a/backend/templates/giftexchange.html b/backend/templates/giftexchange.html new file mode 100644 index 0000000..bbcb762 --- /dev/null +++ b/backend/templates/giftexchange.html @@ -0,0 +1,52 @@ +{% extends "authorized.html" %} +{% block title %}Gift Exchange{% endblock %} +{% block center %} +
    + +
    +
    + Exchange Name: +
    +
    +
    +
    NameemailNameemail
    + + + + + + + {% for participant in non_participants %} + + + + {% endfor %} + +
    Name
    {{ participant.name }}
    + +
    +
    + + +
    +
    +
    + + + + + + + + {% for participant in participants %} + + + + {% endfor %} + +
    Name
    {{ participant.participant_id }}
    +
    + +{% endblock center %} \ No newline at end of file diff --git a/backend/templates/giftexchanges.html b/backend/templates/giftexchanges.html new file mode 100644 index 0000000..bffbc3f --- /dev/null +++ b/backend/templates/giftexchanges.html @@ -0,0 +1,29 @@ +{% extends "authorized.html" %} +{% block title %}Gift Exchanges{% endblock %} +{% block center %} +
    + +
    +
    + + + + + + + + + + {% for giftexchange in giftexchanges %} + + + + + + {% endfor %} + +
    NameDateStatus
    {{ giftexchange.name }}{{ giftexchange.exchange_date }}{{ giftexchange.status }}
    +
    +{% endblock center %} \ No newline at end of file From 0326c0c27a15ae07fb5f8ca026a33c48e7b37539 Mon Sep 17 00:00:00 2001 From: Chris Jean-Marie Date: Fri, 8 Nov 2024 03:45:03 +0000 Subject: [PATCH 4/5] Add slush bucket page --- backend/src/main.rs | 4 +- backend/src/secret_gift_exchange.rs | 46 +++++-- backend/templates/base.html | 3 +- backend/templates/giftexchange.html | 188 +++++++++++++++++++++------- backend/templates/useradmin.html | 2 +- 5 files changed, 181 insertions(+), 62 deletions(-) diff --git a/backend/src/main.rs b/backend/src/main.rs index b646d04..80e3b9e 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -2,7 +2,7 @@ use std::net::SocketAddr; use axum::{ middleware, routing::{get, get_service}, Extension, Router }; -use secret_gift_exchange::{giftexchange, giftexchanges}; +use secret_gift_exchange::{giftexchange, giftexchange_save, giftexchanges}; use sqlx::{sqlite::SqlitePoolOptions, SqlitePool}; use sqlx::migrate::Migrator; use tower_http::services::ServeDir; @@ -65,7 +65,7 @@ async fn main() { .route("/userwishlist/bought/:user_id", get(user_wishlist_bought_item)) .route("/userwishlist/received/:user_id", get(user_wishlist_received_item)) .route("/giftexchanges", get(giftexchanges)) - .route("/giftexchange/:giftexchange_id", get(giftexchange)) + .route("/giftexchange/:giftexchange_id", get(giftexchange).post(giftexchange_save)) .nest_service("/assets", ServeDir::new("templates/assets") .fallback(get_service(ServeDir::new("templates/assets")))) .route("/", get(index)) diff --git a/backend/src/secret_gift_exchange.rs b/backend/src/secret_gift_exchange.rs index eb5cd4d..fe999ee 100644 --- a/backend/src/secret_gift_exchange.rs +++ b/backend/src/secret_gift_exchange.rs @@ -1,11 +1,10 @@ use askama::Template; use askama_axum::{IntoResponse, Response}; use axum::{ - extract::{Path, State}, - response::Redirect, - Extension, + extract::{Path, State}, response::Redirect, routing::post, Extension, Form }; use axum_extra::response::Html; +use chrono::Utc; use http::StatusCode; use serde::{Deserialize, Serialize}; use sqlx::{FromRow, SqlitePool}; @@ -143,7 +142,7 @@ struct GiftExchangeTemplate { name: String, user_roles: Vec, giftexchange: GiftExchange, - participants: Vec, + participants: Vec, non_participants: Vec, } @@ -162,17 +161,21 @@ pub async fn giftexchange( let user_roles = get_user_roles_display(userid, &db_pool.clone()).await; // Get gift exchange - let giftexchange = match sqlx::query_as!(GiftExchange, "SELECT * FROM gift_exchange WHERE id = ?", exchange_id) + let giftexchange = match sqlx::query_as!( + GiftExchange, + "SELECT * FROM gift_exchange WHERE id = ?", + exchange_id + ) .fetch_one(&db_pool) - .await { + .await + { Ok(giftexchange) => giftexchange, - Err(_) => { - GiftExchange::default() - }}; + Err(_) => GiftExchange::default(), + }; // Get participants - let participants = sqlx::query_as::<_, GiftExchangeParticipant>( - "SELECT * FROM gift_exchange_participants WHERE exchange_id = ?", + let participants = sqlx::query_as::<_, UserData>( + "select * from users where users.id in (select participant_id from gift_exchange_participants where exchange_id = ?)", ) .bind(exchange_id) .fetch_all(&db_pool) @@ -202,5 +205,24 @@ pub async fn giftexchange( } } -pub fn select_gifters() {} +#[derive(Deserialize, Debug)] +pub struct ExchangeForm { + name: String, + exchange_date: String, + non_participants: Vec, +} +pub async fn giftexchange_save( + Path(exchange_id): Path, + Extension(user_data): Extension>, + State(db_pool): State, + Form(item_form): Form, +) -> impl IntoResponse { + println!("Saving gift exchange: {:?}", item_form); + if is_authorized("/giftexchange", user_data.clone(), db_pool.clone()).await { + // Insert new item to database + let now = Utc::now().timestamp(); + + } + Redirect::to("/").into_response() +} diff --git a/backend/templates/base.html b/backend/templates/base.html index 2662a1a..e02004d 100644 --- a/backend/templates/base.html +++ b/backend/templates/base.html @@ -18,7 +18,7 @@ -
    +