diff --git a/actix_mvc_app/src/db/calendar.rs b/actix_mvc_app/src/db/calendar.rs new file mode 100644 index 0000000..e69de29 diff --git a/actix_mvc_app/src/utils/mod.rs b/actix_mvc_app/src/utils/mod.rs index 55961fe..dbd8118 100644 --- a/actix_mvc_app/src/utils/mod.rs +++ b/actix_mvc_app/src/utils/mod.rs @@ -26,11 +26,16 @@ impl std::fmt::Display for TemplateError { impl std::error::Error for TemplateError {} -/// Registers custom Tera functions +/// Registers custom Tera functions and filters pub fn register_tera_functions(tera: &mut tera::Tera) { tera.register_function("now", NowFunction); tera.register_function("format_date", FormatDateFunction); tera.register_function("local_time", LocalTimeFunction); + + // Register custom filters + tera.register_filter("format_hour", format_hour_filter); + tera.register_filter("extract_hour", extract_hour_filter); + tera.register_filter("format_time", format_time_filter); } /// Tera function to get the current date/time @@ -140,6 +145,69 @@ impl Function for LocalTimeFunction { } } +/// Tera filter to format hour with zero padding +pub fn format_hour_filter( + value: &Value, + _args: &std::collections::HashMap, +) -> tera::Result { + match value.as_i64() { + Some(hour) => Ok(Value::String(format!("{:02}", hour))), + None => Err(tera::Error::msg("Value must be a number")), + } +} + +/// Tera filter to extract hour from datetime string +pub fn extract_hour_filter( + value: &Value, + _args: &std::collections::HashMap, +) -> tera::Result { + match value.as_str() { + Some(datetime_str) => { + // Try to parse as RFC3339 first + if let Ok(dt) = DateTime::parse_from_rfc3339(datetime_str) { + Ok(Value::String(dt.format("%H").to_string())) + } else { + // Try to parse as our standard format + match DateTime::parse_from_str(datetime_str, "%Y-%m-%d %H:%M:%S%.f UTC") { + Ok(dt) => Ok(Value::String(dt.format("%H").to_string())), + Err(_) => Err(tera::Error::msg("Invalid datetime string format")), + } + } + } + None => Err(tera::Error::msg("Value must be a string")), + } +} + +/// Tera filter to format time from datetime string +pub fn format_time_filter( + value: &Value, + args: &std::collections::HashMap, +) -> tera::Result { + let format = match args.get("format") { + Some(val) => match val.as_str() { + Some(s) => s, + None => "%H:%M", + }, + None => "%H:%M", + }; + + match value.as_str() { + Some(datetime_str) => { + // Try to parse as RFC3339 first + if let Ok(dt) = DateTime::parse_from_rfc3339(datetime_str) { + Ok(Value::String(dt.format(format).to_string())) + } else { + // Try to parse as our standard format + match DateTime::parse_from_str(datetime_str, "%Y-%m-%d %H:%M:%S%.f UTC") { + Ok(dt) => Ok(Value::String(dt.format(format).to_string())), + Err(_) => Err(tera::Error::msg("Invalid datetime string format")), + } + } + } + None => Err(tera::Error::msg("Value must be a string")), + } +} + /// Formats a date for display #[allow(dead_code)] pub fn format_date(date: &DateTime, format: &str) -> String { diff --git a/actix_mvc_app/src/views/calendar/index.html b/actix_mvc_app/src/views/calendar/index.html index fcca452..1b98ca1 100644 --- a/actix_mvc_app/src/views/calendar/index.html +++ b/actix_mvc_app/src/views/calendar/index.html @@ -4,129 +4,633 @@ {% block content %}
-

Calendar

- -

View Mode: {{ view_mode }}

-

Current Date: {{ current_date }}

- -
-
- Day - Month - Year + +
+
+
+
+

Calendar

+

Manage your events and schedule

+
+
+ +
+
- - Create New Event -
- + + +
+
+
+ +
+ {{ current_date }} +
+
+ {% if view_mode == "month" %} +
+ + Use arrow keys to navigate months + | Click on any day to create an event + +
+ {% endif %} +
+
+ {% if view_mode == "month" %} -

Month View: {{ month_name }} {{ current_year }}

- - - - - - - - - - - - - - - {% for week in range(start=0, end=6) %} - - {% for day_idx in range(start=0, end=7) %} -
SunMonTueWedThuFriSat
- {% set idx = week * 7 + day_idx %} - {% if idx < calendar_days|length %} - {% set day = calendar_days[idx] %} - {% if day.day > 0 %} - {{ day.day }} + +
+
+
+ +

+ {{ month_name }} {{ current_year }} +

+ +
+
+
+
+ + + + + + + + + + + + + + {% for week in range(start=0, end=6) %} + + {% for day_idx in range(start=0, end=7) %} + {% set idx = week * 7 + day_idx %} + - {% endfor %} - - {% endfor %} + {% endfor %} + {% if day.events|length > 2 %} +
+{{ day.events|length - 2 }} more
+ {% endif %} + + {% endif %} + {% endif %} + {% endif %} + + {% endfor %} + + {% endfor %} -
SundayMondayTuesdayWednesdayThursdayFridaySaturday
+ {% if idx < calendar_days|length %} {% set day=calendar_days[idx] %} {% if day.day> 0 %} +
+ + {{ day.day }} + + {% if day.events|length > 0 %} + {{ day.events|length }} + {% endif %} +
+ {% if day.events|length > 0 %} +
+ {% for event in day.events %} + {% if loop.index <= 2 %}
+ {{ event.title }} +
{% endif %} - {% endif %} -
- {% elif view_mode == "year" %} -

Year View: {{ current_year }}

- +
+
+
+
+{% elif view_mode == "year" %} + +
+
+

+ Year {{ current_year }} +

+
+
{% for month in months %} -
-
-
{{ month.name }}
-
-

Events: {{ month.events|length }}

+
+
+
+
{{ month.name }}
+
+
+ {% if month.events|length > 0 %} +
+ {{ month.events|length }}
+

+ {% if month.events|length == 1 %} + 1 event + {% else %} + {{ month.events|length }} events + {% endif %} +

+ + {% else %} +
+ +

No events

+
+ {% endif %}
+
{% endfor %}
- {% elif view_mode == "day" %} -

Day View: {{ current_date }}

- -
-
- All Day Events +
+
+{% elif view_mode == "day" %} +

Day View: {{ current_date }}

+ +
+
+ All Day Events +
+
+ {% if events is defined and events|length > 0 %} + {% for event in events %} + {% if event.all_day %} +
+
{{ event.title }}
+

{{ event.description }}

+
+ {% endif %} + {% endfor %} + {% else %} +

No all-day events

+ {% endif %} +
+
+ +
+ {% for hour in range(start=0, end=24) %} +
+
+
+ {{ hour|format_hour }}:00
-
+
{% if events is defined and events|length > 0 %} - {% for event in events %} - {% if event.all_day %} -
-
{{ event.title }}
-

{{ event.description }}

-
- {% endif %} - {% endfor %} - {% else %} -

No all-day events

+ {% for event in events %} + {% if not event.all_day %} + {% set start_hour = event.start_time|extract_hour %} + {% if start_hour == hour|string %} +
+
{{ event.title }}
+

{{ event.start_time|format_time }} - {{ event.end_time|format_time }}

+

{{ event.description }}

+
+ {% endif %} + {% endif %} + {% endfor %} {% endif %}
- -
- {% for hour in range(start=0, end=24) %} -
-
-
- {{ "%02d"|format(value=hour) }}:00 +
+ {% endfor %} +
+{% endif %} + + + {% block extra_css %} + +{% endblock %} + +{% block extra_js %} + {% endblock %} {% endblock %} \ No newline at end of file