mirror of
https://codeberg.org/JasterV/spazio-solazzo.git
synced 2026-04-26 18:20:03 +00:00
144 lines
4.3 KiB
Elixir
144 lines
4.3 KiB
Elixir
defmodule SpazioSolazzo.CalendarExt do
|
|
@moduledoc """
|
|
Extension module for Calendar with helper date and time formatting functions
|
|
"""
|
|
|
|
def format_date(date) do
|
|
Calendar.strftime(date, "%B %d, %Y")
|
|
end
|
|
|
|
def format_time_range(%{start_time: start_time, end_time: end_time}) do
|
|
start_time = Calendar.strftime(start_time, "%I:%M %p")
|
|
end_time = Calendar.strftime(end_time, "%I:%M %p")
|
|
|
|
"#{start_time} - #{end_time}"
|
|
end
|
|
|
|
@doc """
|
|
Formats a datetime as "Feb 10, 2026"
|
|
"""
|
|
def format_datetime_date(%DateTime{} = datetime) do
|
|
Calendar.strftime(datetime, "%b %d, %Y")
|
|
end
|
|
|
|
@doc """
|
|
Formats a datetime as "Monday, February 10, 2026"
|
|
"""
|
|
def format_datetime_date_long(%DateTime{} = datetime) do
|
|
Calendar.strftime(datetime, "%A, %B %d, %Y")
|
|
end
|
|
|
|
@doc """
|
|
Formats a datetime as "Monday, February 10" (for emails)
|
|
"""
|
|
def format_datetime_date_only(%DateTime{} = datetime) do
|
|
Calendar.strftime(datetime, "%A, %B %d")
|
|
end
|
|
|
|
@doc """
|
|
Formats a time or datetime as "9:00 AM"
|
|
"""
|
|
def format_time(%DateTime{} = datetime) do
|
|
datetime
|
|
|> DateTime.to_time()
|
|
|> format_time()
|
|
end
|
|
|
|
def format_time(%Time{} = time) do
|
|
Calendar.strftime(time, "%I:%M %p")
|
|
end
|
|
|
|
@doc """
|
|
Formats a time range as "9:00 AM - 5:00 PM"
|
|
Takes two Time or DateTime structs
|
|
"""
|
|
def format_time_range(%DateTime{} = start_dt, %DateTime{} = end_dt) do
|
|
start_time = DateTime.to_time(start_dt)
|
|
end_time = DateTime.to_time(end_dt)
|
|
format_time_range(start_time, end_time)
|
|
end
|
|
|
|
def format_time_range(%Time{} = start_time, %Time{} = end_time) do
|
|
"#{format_time(start_time)} - #{format_time(end_time)}"
|
|
end
|
|
|
|
@doc """
|
|
Checks if a booking spans multiple days
|
|
"""
|
|
def multi_day?(%DateTime{} = start_datetime, %DateTime{} = end_datetime) do
|
|
start_date = DateTime.to_date(start_datetime)
|
|
end_date = DateTime.to_date(end_datetime)
|
|
Date.compare(start_date, end_date) != :eq
|
|
end
|
|
|
|
@doc """
|
|
Formats a datetime range handling both single-day and multi-day bookings.
|
|
|
|
Single-day: "Feb 10, 2026 9:00 AM - 5:00 PM"
|
|
Multi-day: "Feb 10, 2026 9:00 AM - Feb 15, 2026 5:00 PM"
|
|
"""
|
|
def format_datetime_range(%DateTime{} = start_datetime, %DateTime{} = end_datetime) do
|
|
if multi_day?(start_datetime, end_datetime) do
|
|
"#{format_datetime_date(start_datetime)} #{format_time(start_datetime)} - #{format_datetime_date(end_datetime)} #{format_time(end_datetime)}"
|
|
else
|
|
"#{format_datetime_date(start_datetime)} #{format_time_range(start_datetime, end_datetime)}"
|
|
end
|
|
end
|
|
|
|
@doc """
|
|
Formats the start portion of a datetime range for table display
|
|
|
|
Single-day: "Feb 10, 2026 9:00 AM"
|
|
Multi-day: "Feb 10, 2026 9:00 AM"
|
|
"""
|
|
def format_datetime_range_start(%DateTime{} = datetime) do
|
|
"#{format_datetime_date(datetime)} #{format_time(datetime)}"
|
|
end
|
|
|
|
@doc """
|
|
Formats the end portion of a datetime range for table display
|
|
|
|
Single-day: "5:00 PM" (date not shown)
|
|
Multi-day: "Feb 15, 2026 5:00 PM"
|
|
"""
|
|
def format_datetime_range_end(%DateTime{} = start_datetime, %DateTime{} = end_datetime) do
|
|
if multi_day?(start_datetime, end_datetime) do
|
|
"#{format_datetime_date(end_datetime)} #{format_time(end_datetime)}"
|
|
else
|
|
format_time(end_datetime)
|
|
end
|
|
end
|
|
|
|
# There are 7 days displayed in the calendar
|
|
@grid_cols 7
|
|
# The calendar can show max 6 weeks for one month
|
|
@grid_rows 6
|
|
|
|
@doc """
|
|
Build a list containing all the dates to be displayed in a
|
|
Calendar grid.
|
|
|
|
6 weeks * 7 days = 42 cells
|
|
"""
|
|
def build_calendar_grid(date) do
|
|
first_day = Date.beginning_of_month(date)
|
|
# Mon=1, Sun=7
|
|
start_day_of_week = Date.day_of_week(first_day)
|
|
|
|
# Calculate days to subtract to get to the previous Monday
|
|
# If starts on Mon (1), sub 0. If Sun (7), sub 6.
|
|
days_to_sub = start_day_of_week - 1
|
|
start_date = Date.add(first_day, -days_to_sub)
|
|
|
|
# 6 weeks * 7 days = 42 grid cells
|
|
Enum.map(0..(@grid_cols * @grid_rows - 1), fn i -> Date.add(start_date, i) end)
|
|
end
|
|
|
|
@doc "Checks if a date is within a start/end range (inclusive)"
|
|
def date_in_range?(date, start_date, end_date)
|
|
when not is_nil(start_date) and not is_nil(end_date) do
|
|
Date.compare(date, start_date) != :lt and Date.compare(date, end_date) != :gt
|
|
end
|
|
|
|
def date_in_range?(_date, _start, _end), do: false
|
|
end
|