Make calendar general

This commit is contained in:
Chris Jean-Marie 2024-12-07 22:00:58 +00:00
parent 2ead3f79c3
commit ea0d26e4dd
5 changed files with 104 additions and 35 deletions

View File

@ -1,7 +1,7 @@
use askama::Template; use askama::Template;
use askama_axum::{IntoResponse, Response}; use askama_axum::{IntoResponse, Response};
use axum::{ use axum::{
extract::State, extract::{Path, State},
response::{Html, Json, Redirect}, response::{Html, Json, Redirect},
Extension, Extension,
}; };
@ -31,15 +31,21 @@ where
} }
} }
struct Calendar {
name: String,
colour: String,
}
#[derive(Template)] #[derive(Template)]
#[template(path = "cottagecalendar.html")] #[template(path = "calendar.html")]
struct CottageCalendarTemplate { struct CalendarTemplate {
logged_in: bool, logged_in: bool,
user: UserData, user: UserData,
user_roles: Vec<crate::user::UserRolesDisplay>, user_roles: Vec<crate::user::UserRolesDisplay>,
calendars: Vec<Calendar>,
} }
pub async fn cottagecalendar( pub async fn calendar(
Extension(user_data): Extension<Option<UserData>>, Extension(user_data): Extension<Option<UserData>>,
State(db_pool): State<SqlitePool>, State(db_pool): State<SqlitePool>,
) -> impl IntoResponse { ) -> impl IntoResponse {
@ -51,14 +57,26 @@ pub async fn cottagecalendar(
let user = user_data.as_ref().unwrap().clone(); let user = user_data.as_ref().unwrap().clone();
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("/cottagecalendar", user_data, db_pool.clone()).await { if is_authorized("/calendar", user_data, db_pool.clone()).await {
// Get user roles // Get user roles
let user_roles = get_user_roles_display(userid, &db_pool.clone()).await; let user_roles = get_user_roles_display(userid, &db_pool.clone()).await;
let template = CottageCalendarTemplate { let calendars: Vec<Calendar> = vec![
Calendar {
name: "Cottage".to_string(),
colour: "green".to_string(),
},
Calendar {
name: "Personal".to_string(),
colour: "blue".to_string(),
},
];
let template = CalendarTemplate {
logged_in, logged_in,
user, user,
user_roles, user_roles,
calendars,
}; };
HtmlTemplate(template).into_response() HtmlTemplate(template).into_response()
} else { } else {
@ -70,12 +88,27 @@ pub async fn cottagecalendar(
} }
pub async fn get_events( pub async fn get_events(
Extension(user_data): Extension<Option<UserData>>, Path(calendar): Path<String>,
State(db_pool): State<SqlitePool>, State(db_pool): State<SqlitePool>,
Extension(user_data): Extension<Option<UserData>>,
) -> String { ) -> String {
let events = "[{\"title\": \"Chris and Terri\", \"start\": \"2024-12-23T14:00:00\", \"end\": \"2024-12-27T10:00:00\", \"allDay\": false}, {\"title\": \"Stephen\", \"start\": \"2024-12-27T14:00:00\", \"end\": \"2024-12-31T10:00:00\", \"allDay\": false}]"; println!("Calendar: {}", calendar);
// Is the user logged in?
let logged_in = user_data.is_some();
println!("{}", events); // Set default events
let mut events = "[]";
if logged_in {
// Extract the user data.
let user = user_data.as_ref().unwrap().clone();
let userid = user_data.as_ref().map(|s| s.id.clone()).unwrap_or_default();
if is_authorized("/calendar", user_data, db_pool.clone()).await {
// Get requested calendar events from database
events = "[{\"title\": \"Chris and Terri\", \"start\": \"2024-12-23T14:00:00\", \"end\": \"2024-12-27T10:00:00\", \"allDay\": false}, {\"title\": \"Stephen\", \"start\": \"2024-12-27T14:00:00\", \"end\": \"2024-12-31T10:00:00\", \"allDay\": false}]";
}
}
events.to_string() events.to_string()
} }

View File

@ -4,7 +4,6 @@ use axum::{
Extension, Router, Extension, Router,
}; };
use secret_gift_exchange::{giftexchange, giftexchange_save, giftexchanges}; use secret_gift_exchange::{giftexchange, giftexchange_save, giftexchanges};
use calendar::cottagecalendar;
use sqlx::migrate::Migrator; use sqlx::migrate::Migrator;
use sqlx::{sqlite::SqlitePoolOptions, SqlitePool}; use sqlx::{sqlite::SqlitePoolOptions, SqlitePool};
use std::net::SocketAddr; use std::net::SocketAddr;
@ -25,6 +24,7 @@ use google_oauth::{google_auth_return, login, logout};
use middlewares::inject_user_data; use middlewares::inject_user_data;
use routes::{about, contact, 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 user::{add_user_role, delete_user_role, UserData};
use calendar::{calendar, get_events};
use wishlist::{user_wishlist, user_wishlist_add, user_wishlist_add_item, user_wishlist_bought_item, user_wishlist_delete_item, user_wishlist_edit_item, user_wishlist_received_item, user_wishlist_returned_item, user_wishlist_save_item, wishlists}; use wishlist::{user_wishlist, user_wishlist_add, user_wishlist_add_item, user_wishlist_bought_item, user_wishlist_delete_item, user_wishlist_edit_item, user_wishlist_received_item, user_wishlist_returned_item, user_wishlist_save_item, wishlists};
//use email::send_emails; //use email::send_emails;
@ -68,8 +68,8 @@ async fn main() {
.route("/roles/:user_id/:user_role_id/delete", get(delete_user_role)) .route("/roles/:user_id/:user_role_id/delete", get(delete_user_role))
// Calendar // Calendar
.route("/cottagecalendar", get(cottagecalendar)) .route("/calendar", get(calendar))
.route("/getevents", get(calendar::get_events)) .route("/getevents/:calendar", get(get_events))
// Wishlist // Wishlist
.route("/wishlists", get(wishlists)) .route("/wishlists", get(wishlists))

View File

@ -254,8 +254,23 @@ pub async fn about(Extension(user_data): Extension<Option<UserData>>) -> impl In
// Is the user logged in? // Is the user logged in?
let logged_in = user_data.is_some(); let logged_in = user_data.is_some();
// Extract the user data. // Set empty user
let user = user_data.as_ref().unwrap().clone(); let mut user = UserData {
id: 0,
email: "".to_string(),
created_at: 0,
created_by: 0,
updated_at: 0,
updated_by: 0,
name: "".to_string(),
family_name: "".to_string(),
given_name: "".to_string(),
};
if logged_in {
// Extract the user data.
user = user_data.as_ref().unwrap().clone();
}
let template = AboutTemplate { logged_in, user }; let template = AboutTemplate { logged_in, user };
HtmlTemplate(template) HtmlTemplate(template)
@ -272,8 +287,23 @@ pub async fn contact(Extension(user_data): Extension<Option<UserData>>) -> impl
// Is the user logged in? // Is the user logged in?
let logged_in = user_data.is_some(); let logged_in = user_data.is_some();
// Extract the user data. // Set empty user
let user = user_data.as_ref().unwrap().clone(); let mut user = UserData {
id: 0,
email: "".to_string(),
created_at: 0,
created_by: 0,
updated_at: 0,
updated_by: 0,
name: "".to_string(),
family_name: "".to_string(),
given_name: "".to_string(),
};
if logged_in {
// Extract the user data.
user = user_data.as_ref().unwrap().clone();
}
let template = ContactTemplate { logged_in, user }; let template = ContactTemplate { logged_in, user };
HtmlTemplate(template) HtmlTemplate(template)

View File

@ -6,7 +6,7 @@
<h2>Menu</h2> <h2>Menu</h2>
<ul> <ul>
<li><a href="/dashboard">Web links</a></li> <li><a href="/dashboard">Web links</a></li>
<li><a href="/cottagecalendar">Cottage Calendar</a></li> <li><a href="/calendar">Calendar</a></li>
<li><a href="/wishlists">Wish lists</a></li> <li><a href="/wishlists">Wish lists</a></li>
</ul> </ul>
{% for user_role in user_roles %} {% for user_role in user_roles %}

View File

@ -4,7 +4,7 @@
<link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/@fullcalendar/daygrid@4.3.0/main.min.css'> <link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/@fullcalendar/daygrid@4.3.0/main.min.css'>
{% endblock links %} {% endblock links %}
{% block center %} {% block center %}
<h1>Cottage Calendar</h1> <h1>Calendar</h1>
<div class="mh-100"> <div class="mh-100">
<div id="calendar" class="fc"></div> <div id="calendar" class="fc"></div>
</div> </div>
@ -22,30 +22,36 @@
selectable: true, selectable: true,
displayEventTime: true, displayEventTime: true,
displayEventEnd: true, displayEventEnd: true,
slotDuration: {hours: 12}, slotDuration: { hours: 12 },
slotLabelInterval: {hours: 24}, slotLabelInterval: { hours: 24 },
headerToolbar: { headerToolbar: {
left: 'prev,next today', left: 'prev,next today',
center: 'title', center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay,multiMonthYear' right: 'dayGridMonth,timeGridWeek,timeGridDay,multiMonthYear'
}, },
events: '/getevents', eventSources: [
{% for calendar in calendars %}
select: function (info) { {
alert('selected ' + info.startStr + ' to ' + info.endStr); url: '/getevents/{{calendar.name}}',
let enddate = new Date(info.endStr); color: '{{calendar.colour}}',
enddate.setDate(enddate.getDate() - 1); },
info.view.calendar.addEvent({ {% endfor %}
id: uuidv4(), ],
title: 'New Event', select: function (info) {
start: info.startStr+'T14:00:00', alert('selected ' + info.startStr + ' to ' + info.endStr);
end: info.endStr+'T10:00:00', let enddate = new Date(info.endStr);
allDay: false enddate.setDate(enddate.getDate() - 1);
}); info.view.calendar.addEvent({
} id: uuidv4(),
title: 'New Event',
start: info.startStr + 'T14:00:00',
end: info.endStr + 'T10:00:00',
allDay: false
});
}
}); });
calendar.render(); calendar.render();
}); });
</script> </script>
{% endblock scripts %} {% endblock scripts %}