Add calendar tables
This commit is contained in:
parent
8bc418ebb2
commit
158fef7902
|
|
@ -0,0 +1,5 @@
|
|||
-- Add down migration script here
|
||||
|
||||
drop table if exists `calendar_events`;
|
||||
drop table if exists `calendar_event_types`;
|
||||
drop table if exists `calendar`;
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
-- Add up migration script here
|
||||
|
||||
-- Calendars
|
||||
-- 1 - Cottage
|
||||
-- 2 - Family tree
|
||||
create table calendar (
|
||||
id integer not null primary key autoincrement,
|
||||
created_at integer not null default CURRENT_TIMESTAMP,
|
||||
created_by integer not null default 0,
|
||||
updated_at integer null default CURRENT_TIMESTAMP,
|
||||
updated_by integer not null default 0,
|
||||
name varchar(255) not null
|
||||
)
|
||||
|
||||
-- Event types
|
||||
-- 1 - Rental
|
||||
-- 2 - Life event
|
||||
create table calendar_event_types (
|
||||
id integer not null primary key autoincrement,
|
||||
created_at integer not null default CURRENT_TIMESTAMP,
|
||||
created_by integer not null default 0,
|
||||
updated_at integer null default CURRENT_TIMESTAMP,
|
||||
updated_by integer not null default 0,
|
||||
name varchar(255) not null
|
||||
)
|
||||
|
||||
create table calendar_events (
|
||||
id integer not null primary key autoincrement,
|
||||
created_at integer not null default CURRENT_TIMESTAMP,
|
||||
created_by integer not null default 0,
|
||||
updated_at integer null default CURRENT_TIMESTAMP,
|
||||
updated_by integer not null default 0,
|
||||
calendar_id integer not null,
|
||||
event_type_id integer not null,
|
||||
title varchar(255) not null,
|
||||
description varchar(255) null,
|
||||
start_time integer null,
|
||||
end_time integer null,
|
||||
repeat_type integer not null default 0, -- 0 - None, 1 - Daily, 2 - Weekly, 3 - Monthly, 4 - Yearly, 5 - Day of week, 6 - Day of month
|
||||
repeat_interval integer not null default 0,
|
||||
celebrate boolean not null default 0
|
||||
|
||||
foreign key (calendar_id) references calendar(id),
|
||||
foreign key (event_type_id) references calendar_event_types(id)
|
||||
)
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
use askama::Template;
|
||||
use askama_axum::{IntoResponse, Response};
|
||||
use axum::{
|
||||
extract::State,
|
||||
response::{Html, Redirect},
|
||||
Extension,
|
||||
};
|
||||
use http::StatusCode;
|
||||
use sqlx::SqlitePool;
|
||||
|
||||
use crate::{
|
||||
middlewares::is_authorized,
|
||||
user::{get_user_roles_display, UserData},
|
||||
};
|
||||
|
||||
struct HtmlTemplate<T>(T);
|
||||
|
||||
impl<T> IntoResponse for HtmlTemplate<T>
|
||||
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(Template)]
|
||||
#[template(path = "cottagecalendar.html")]
|
||||
struct CottageCalendarTemplate {
|
||||
logged_in: bool,
|
||||
name: String,
|
||||
user_roles: Vec<crate::user::UserRolesDisplay>,
|
||||
}
|
||||
|
||||
pub async fn cottagecalendar(
|
||||
Extension(user_data): Extension<Option<UserData>>,
|
||||
State(db_pool): State<SqlitePool>,
|
||||
) -> 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 user_id = user_data.as_ref().map(|s| s.id.clone()).unwrap_or_default();
|
||||
|
||||
if is_authorized("/cottagecalendar", user_data, db_pool.clone()).await {
|
||||
// Get user roles
|
||||
let user_roles = get_user_roles_display(user_id, &db_pool.clone()).await;
|
||||
|
||||
let template = CottageCalendarTemplate {
|
||||
logged_in,
|
||||
name,
|
||||
user_roles,
|
||||
};
|
||||
HtmlTemplate(template).into_response()
|
||||
} else {
|
||||
Redirect::to("/").into_response()
|
||||
}
|
||||
}
|
||||
|
||||
async fn get_next_event(db_pool: &SqlitePool) -> Option<String> {
|
||||
let next_event = sqlx::query_as::<_, (String, String)>(
|
||||
"SELECT date, title FROM events ORDER BY date ASC LIMIT 1",
|
||||
)
|
||||
.fetch_one(db_pool)
|
||||
.await;
|
||||
|
||||
next_event.map(|(date, title)| format!("{} - {}", date, title))
|
||||
}
|
||||
|
|
@ -1,30 +1,37 @@
|
|||
use std::net::SocketAddr;
|
||||
use axum::{
|
||||
middleware, routing::{get, get_service}, Extension, Router
|
||||
middleware,
|
||||
routing::{get, get_service},
|
||||
Extension, Router,
|
||||
};
|
||||
use sqlx::{sqlite::SqlitePoolOptions, SqlitePool};
|
||||
use calendar::cottagecalendar;
|
||||
use sqlx::migrate::Migrator;
|
||||
use sqlx::{sqlite::SqlitePoolOptions, SqlitePool};
|
||||
use std::net::SocketAddr;
|
||||
use tower_http::services::ServeDir;
|
||||
|
||||
mod calendar;
|
||||
mod email;
|
||||
mod error_handling;
|
||||
mod google_oauth;
|
||||
mod middlewares;
|
||||
mod routes;
|
||||
mod user;
|
||||
mod wishlist;
|
||||
mod email;
|
||||
|
||||
use error_handling::AppError;
|
||||
use google_oauth::{google_auth_return, login, logout};
|
||||
use middlewares::inject_user_data;
|
||||
use google_oauth::{login, logout, google_auth_return};
|
||||
use routes::{about, contact, cottagecalendar, dashboard, index, profile, user_profile, useradmin};
|
||||
use routes::{about, contact, dashboard, index, profile, user_profile, useradmin};
|
||||
use user::{add_user_role, delete_user_role, UserData};
|
||||
use wishlist::{user_wishlist, user_wishlist_add, user_wishlist_add_item, user_wishlist_bought_item, user_wishlist_edit_item, user_wishlist_received_item, user_wishlist_save_item, wishlists};
|
||||
use wishlist::{
|
||||
user_wishlist, user_wishlist_add, user_wishlist_add_item, user_wishlist_bought_item,
|
||||
user_wishlist_edit_item, user_wishlist_received_item, user_wishlist_save_item, wishlists,
|
||||
};
|
||||
//use email::send_emails;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AppState {
|
||||
pub db_pool: SqlitePool
|
||||
pub db_pool: SqlitePool,
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
|
|
@ -37,7 +44,9 @@ async fn main() {
|
|||
.connect("sqlite://db/db.sqlite3")
|
||||
.await;
|
||||
|
||||
let app_state = AppState {db_pool:db_pool.expect("Failed to get db_pool")};
|
||||
let app_state = AppState {
|
||||
db_pool: db_pool.expect("Failed to get db_pool"),
|
||||
};
|
||||
|
||||
static MIGRATOR: Migrator = sqlx::migrate!();
|
||||
|
||||
|
|
@ -50,31 +59,51 @@ async fn main() {
|
|||
|
||||
// build our application with some routes
|
||||
let app = Router::new()
|
||||
.route("/dashboard", get(dashboard))
|
||||
.route("/cottagecalendar", get(cottagecalendar))
|
||||
.route("/dashboard", get(dashboard))
|
||||
.route("/profile", get(profile))
|
||||
.route("/useradmin", get(useradmin))
|
||||
.route("/users/:user_id", get(user_profile))
|
||||
.route("/roles/:user_id/:role_id/add", get(add_user_role))
|
||||
.route("/roles/:user_id/:user_role_id/delete", get(delete_user_role))
|
||||
.route(
|
||||
"/roles/:user_id/:user_role_id/delete",
|
||||
get(delete_user_role),
|
||||
)
|
||||
.route("/wishlists", get(wishlists))
|
||||
.route("/userwishlist/:user_id", get(user_wishlist))
|
||||
.route("/userwishlist/add/:user_id", get(user_wishlist_add).post(user_wishlist_add_item))
|
||||
.route("/userwishlist/edit/:item_id", get(user_wishlist_edit_item).post(user_wishlist_save_item))
|
||||
.route("/userwishlist/bought/:user_id", get(user_wishlist_bought_item))
|
||||
.route("/userwishlist/received/:user_id", get(user_wishlist_received_item))
|
||||
.nest_service("/assets", ServeDir::new("templates/assets")
|
||||
.fallback(get_service(ServeDir::new("templates/assets"))))
|
||||
.route(
|
||||
"/userwishlist/add/:user_id",
|
||||
get(user_wishlist_add).post(user_wishlist_add_item),
|
||||
)
|
||||
.route(
|
||||
"/userwishlist/edit/:item_id",
|
||||
get(user_wishlist_edit_item).post(user_wishlist_save_item),
|
||||
)
|
||||
.route(
|
||||
"/userwishlist/bought/:user_id",
|
||||
get(user_wishlist_bought_item),
|
||||
)
|
||||
.route(
|
||||
"/userwishlist/received/:user_id",
|
||||
get(user_wishlist_received_item),
|
||||
)
|
||||
.nest_service(
|
||||
"/assets",
|
||||
ServeDir::new("templates/assets")
|
||||
.fallback(get_service(ServeDir::new("templates/assets"))),
|
||||
)
|
||||
.route("/", get(index))
|
||||
.route("/about", get(about))
|
||||
.route("/contactus", get(contact))
|
||||
.route("/login", get(login))
|
||||
.route("/logout", get(logout))
|
||||
.route("/google_auth_return", get(google_auth_return))
|
||||
.route_layer(middleware::from_fn_with_state(app_state.db_pool.clone(), inject_user_data))
|
||||
.route_layer(middleware::from_fn_with_state(
|
||||
app_state.db_pool.clone(),
|
||||
inject_user_data,
|
||||
))
|
||||
.with_state(app_state.db_pool.clone())
|
||||
.layer(Extension(user_data))
|
||||
;
|
||||
.layer(Extension(user_data));
|
||||
|
||||
// Send email indicating server has started
|
||||
//let recipients = get_useremails_by_role("admin".to_string(), &app_state.db_pool).await;
|
||||
|
|
@ -87,5 +116,4 @@ async fn main() {
|
|||
.serve(app.into_make_service())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -246,32 +246,3 @@ pub async fn contact(Extension(user_data): Extension<Option<UserData>>) -> impl
|
|||
let template = ContactTemplate { logged_in, name };
|
||||
HtmlTemplate(template)
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "cottagecalendar.html")]
|
||||
struct CottageCalendarTemplate {
|
||||
logged_in: bool,
|
||||
name: String,
|
||||
user_roles: Vec<crate::user::UserRolesDisplay>,
|
||||
}
|
||||
|
||||
pub async fn cottagecalendar(
|
||||
Extension(user_data): Extension<Option<UserData>>,
|
||||
State(db_pool): State<SqlitePool>,
|
||||
) -> 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 user_id = user_data.as_ref().map(|s| s.id.clone()).unwrap_or_default();
|
||||
|
||||
if is_authorized("/cottagecalendar", user_data, db_pool.clone()).await {
|
||||
// Get user roles
|
||||
let user_roles = get_user_roles_display(user_id, &db_pool.clone()).await;
|
||||
|
||||
let template = CottageCalendarTemplate { logged_in, name, user_roles };
|
||||
HtmlTemplate(template).into_response()
|
||||
} else {
|
||||
Redirect::to("/").into_response()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue