Get calendar events from database

This commit is contained in:
Chris Jean-Marie 2024-12-14 04:57:13 +00:00
parent 939f87d820
commit 462716633e
4 changed files with 109 additions and 54 deletions

View File

@ -1,12 +1,12 @@
use askama::Template; use askama::Template;
use askama_axum::{IntoResponse, Response}; use askama_axum::{IntoResponse, Response};
use axum::{ use axum::{
extract::{Path, State}, body::Body, extract::{Path, Query, Request, State}, response::{Html, Redirect}, Extension
response::{Html, Redirect},
Extension,
}; };
use http::StatusCode; use http::StatusCode;
use sqlx::PgPool; use serde::{Deserialize, Serialize};
use serde_json::json;
use sqlx::{types::Json, PgPool, Row};
use crate::{ use crate::{
middlewares::is_authorized, middlewares::is_authorized,
@ -87,17 +87,24 @@ pub async fn calendar(
} }
} }
#[derive(Deserialize, Serialize, Debug)]
pub struct EventParams {
start: String,
end: String,
}
pub async fn get_events( pub async fn get_events(
Path(calendar): Path<String>, Path(calendar): Path<String>,
State(db_pool): State<PgPool>, State(db_pool): State<PgPool>,
Query(params): Query<EventParams>,
Extension(user_data): Extension<Option<UserData>>, Extension(user_data): Extension<Option<UserData>>,
) -> String { ) -> String {
println!("Calendar: {}", calendar); println!("Calendar: {}", calendar);
//println!("Paramters: {:?}", params);
// Is the user logged in? // Is the user logged in?
let logged_in = user_data.is_some(); let logged_in = user_data.is_some();
// Set default events // Set default events
let mut events = "[]"; let mut eventstring: String = "[]".to_string();
if logged_in { if logged_in {
// Extract the user data. // Extract the user data.
@ -106,9 +113,32 @@ pub async fn get_events(
if is_authorized("/calendar", user_data, db_pool.clone()).await { if is_authorized("/calendar", user_data, db_pool.clone()).await {
// Get requested calendar events from database // 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}]"; let events = sqlx::query(r#"select to_json(json_agg(json_build_object(
'title', ce.title,
'start', ce.start_time,
'end', ce.end_time,
'allDay', false)))
from calendar_events ce
join calendar c on c.id = ce.calendar_id
join calendar_event_types cet on cet.id = ce.event_type_id
where ce.celebrate = true
and c.name = $1
and start_time > $2
and start_time < $3"#)
.bind(calendar)
.bind(chrono::DateTime::parse_from_rfc3339(&params.start).unwrap())
.bind(chrono::DateTime::parse_from_rfc3339(&params.end).unwrap())
.fetch_one(&db_pool)
.await;
if let Ok(json_string) = events {
if let Ok(stringevents) = json_string.try_get_raw(0).map(|v| v.as_str().unwrap_or("")) {
println!("PgValue: {:?}", stringevents);
eventstring = stringevents.to_string();
}
}
} }
} }
events.to_string() eventstring
} }

View File

@ -5,16 +5,19 @@
<div id="menu" class="col-md-2 bg-light"> <div id="menu" class="col-md-2 bg-light">
<h2>Menu</h2> <h2>Menu</h2>
<ul> <ul>
<li><a href="/dashboard">Web links</a></li> <li><a href="/dashboard">Dashboard</a></li>
<li><a href="/calendar">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>
{% for user_role in user_roles %} {% for user_role in user_roles %}
{% if user_role.role_name == "admin" %} {% if user_role.role_name == "admin" %}
<li>Administration</li>
<ul>
<li><a href="/useradmin">User Administration</a></li> <li><a href="/useradmin">User Administration</a></li>
<li><a href="/giftexchanges">Gift Exchanges</a></li> <li><a href="/giftexchanges">Gift Exchanges</a></li>
</ul>
{% endif %} {% endif %}
{% endfor %} {% endfor %}
</ul>
</div> </div>
<!-- Center panel --> <!-- Center panel -->
@ -27,5 +30,4 @@
<h2>Events</h2> <h2>Events</h2>
</div> </div>
</div> </div>
</div>
{% endblock content %} {% endblock content %}

View File

@ -2,18 +2,35 @@
{% block center %} {% block center %}
<div class="row align-items-stretch"> <div class="row align-items-stretch">
<div class="col-md-6"> <div class="col-md-6">
<h2>Points of Interest</h2> <div class="card">
<a href="https://www.tlccreations.ca" target="_blank" rel="noopener noreferrer"><img title="TLC Creations" <div class="card-body">
src="https://www.tlccreations.ca/assets/images/banner.png" class="img-fluid" alt="TLC Creations"></a> <h5 class="card-title">Points of Interest</h5>
<a href="https://www.seguin.ca" target="_blank" rel="noopener noreferrer"><img title="Seguin" <div class="col-md-6">
src="https://www.seguin.ca/en/images/structure/badge.svg" class="img-fluid" alt="Seguin Township"></a> <a href="https://www.tlccreations.ca" target="_blank" rel="noopener noreferrer"><img
title="TLC Creations" src="https://www.tlccreations.ca/assets/images/banner.png"
class="img-fluid" alt="TLC Creations"></a>
</div>
<div class="col-md-6">
<a href="https://www.seguin.ca" target="_blank" rel="noopener noreferrer"><img
title="Seguin Township" src="https://www.seguin.ca/en/images/structure/badge.svg"
class="img-fluid" alt="Seguin Township"></a>
</div> </div>
</div> </div>
<div class="row align-items-stretch" id="firerating">
<a href="https://www.seguin.ca/en/explore-play/firerating.aspx" target="_blank" rel="noopener noreferrer"><img
title="Fire Rating: MODERATE" src="https://www.seguin.ca/en/resources/firemodseguin.jpg"
class="img-fluid" alt="Fire Rating: MODERATE"></a>
</div> </div>
</div>
<div class="col-md-6">
<div class="card">
<div class="card-body">
<h5 class="card-title">Seguin Fire Rating</h5>
<a href="https://www.seguin.ca/en/explore-play/firerating.aspx" target="_blank"
rel="noopener noreferrer"><img title="Fire Rating: MODERATE"
src="https://www.seguin.ca/en/resources/firemodseguin.jpg" class="img-fluid"
alt="Fire Rating: MODERATE"></a>
</div>
</div>
</div>
</div>
<div class="row align-items-stretch">
<div> <div>
<h2>Web links</h2> <h2>Web links</h2>
<h3>Fonts</h3> <h3>Fonts</h3>
@ -21,12 +38,18 @@
<li><a href="https://fonts.google.com" target="_blank" rel="noopener noreferrer">Google fonts</a></li> <li><a href="https://fonts.google.com" target="_blank" rel="noopener noreferrer">Google fonts</a></li>
<li><a href="https://www.fontspace.com" target="_blank" rel="noopener noreferrer">Font Space</a></li> <li><a href="https://www.fontspace.com" target="_blank" rel="noopener noreferrer">Font Space</a></li>
</ul> </ul>
<h3>Family tree</h3> <div class="card">
<div class="card-body">
<h5 class="card-title">Family tree</h5>
<ul> <ul>
<li><a href="https://www.ancestry.ca" target="_blank" rel="noopener noreferrer">Ancestry</a></li> <li><a href="https://www.ancestry.ca" target="_blank" rel="noopener noreferrer">Ancestry</a></li>
<li><a href="https://www.geni.com" target="_blank" rel="noopener noreferrer">Geni</a></li> <li><a href="https://www.geni.com" target="_blank" rel="noopener noreferrer">Geni</a></li>
<li><a href="http://www.tracingroots.ca/" target="_blank" rel="noopener noreferrer">Tracing Roots - Forth Family <li><a href="http://www.tracingroots.ca/" target="_blank" rel="noopener noreferrer">Tracing Roots -
Forth Family
Tree</a></li> Tree</a></li>
</ul> </ul>
</div> </div>
</div>
</div>
</div>
{% endblock center %} {% endblock center %}

View File

@ -2,6 +2,6 @@ cargo build --release
ssh chris@192.168.59.31 'pkill jean-marie' ssh chris@192.168.59.31 'pkill jean-marie'
scp target/release/jean-marie chris@192.168.59.31:/opt/jean-marie scp target/release/jean-marie chris@192.168.59.31:/opt/jean-marie
scp runsite.sh chris@192.168.59.31:/opt/jean-marie scp runsite.sh chris@192.168.59.31:/opt/jean-marie
scp .env chris@192.168.59.31:/opt/jean-marie #scp .env chris@192.168.59.31:/opt/jean-marie
scp -r templates chris@192.168.59.31:/opt/jean-marie scp -r templates chris@192.168.59.31:/opt/jean-marie
ssh chris@192.168.59.31 '/opt/jean-marie/runsite.sh' ssh chris@192.168.59.31 '/opt/jean-marie/runsite.sh'