๐Ÿ“ฆ sleepyfran / duets

๐Ÿ“„ Calendar.fs ยท 52 lines
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52[<AutoOpen>]
module Duets.Cli.Components.Calendar

open Duets.Agents
open Duets.Cli.Components
open Duets.Cli.Text
open Duets.Entities
open Duets.Simulation

/// <summary>
/// Renders a calendar for the given season of the given year highlighting the
/// dates provided.
/// </summary>
/// <param name="year">Year to display</param>
/// <param name="season">Season to display</param>
/// <param name="events">List of dates to highlight</param>
let showCalendar (year: int<years>) season (events: Date list) =
    let today =
        Queries.Calendar.today (State.get ())
        |> Calendar.Transform.resetDayMoment

    (*
    Get a set of dates for quickly contains checking and make sure that their
    day moments are set to the start of the day to be able to match by equality.
    *)
    let eventSet =
        events |> List.map Calendar.Transform.resetDayMoment |> Set.ofList

    let tableColumns =
        [ "Mon"; "Tue"; "Wed"; "Thu"; "Fri"; "Sat"; "Sun" ]
        |> List.map Styles.header

    let firstDayOfSeason = Calendar.Date.fromSeasonAndYear season year

    let tableRows =
        Calendar.Query.seasonDaysFrom firstDayOfSeason
        |> List.ofSeq
        |> List.map (fun date ->
            let normalizedDate = date |> Calendar.Transform.resetDayMoment
            let hasEvent = Set.contains normalizedDate eventSet

            let style =
                if normalizedDate = today then Styles.faded
                elif hasEvent then Styles.highlight
                else Styles.number

            style date.Day)
        |> List.splitInto 3

    let title = Calendar.Date.fromSeasonAndYear season year |> Date.seasonYear
    showTableWithTitle title tableColumns tableRows