Begin working on Habit Screens project

Created a small MVP for digitizing my weekly habits. Much more to come.

Lots of things happening:

- Copied the boilerplate to get started
- Added a brief project-level README
- Outlined my ambitions in design.md

See README and design.md for more context on this project.
This commit is contained in:
William Carroll 2020-10-10 17:04:24 +01:00
parent 02ce74eada
commit 9d331f3077
12 changed files with 414 additions and 0 deletions

View file

@ -0,0 +1,169 @@
module Habits exposing (render)
import Browser
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Set
import State
import Time exposing (Weekday(..))
morning : List State.Habit
morning =
[ "Make bed"
, "Brush teeth"
, "Shower"
, "Do push-ups"
, "Meditate"
]
evening : List State.Habit
evening =
[ "Read (30 minutes)"
, "Record in State.Habit Journal"
]
monday : List State.Habit
monday =
[ "Bikram Yoga @ 17:00 (90 min)"
]
tuesday : List State.Habit
tuesday =
[ "Bikram Yoga @ 18:00 (90 min)"
]
wednesday : List State.Habit
wednesday =
[ "Shave"
, "Bikram Yoga @ 17:00 (90 min)"
]
thursday : List State.Habit
thursday =
[]
friday : List State.Habit
friday =
[ "Bikram Yoga @ 17:00 (60 min)"
, "Take-out trash"
, "Shop for groceries"
]
saturday : List State.Habit
saturday =
[ "Nap"
]
sunday : List State.Habit
sunday =
[ "Shampoo"
, "Shave"
, "Trim nails"
, "Combine trash cans"
, "Mop tile and wood floors"
, "Laundry"
, "Vacuum bedroom"
, "Dust surfaces"
, "Clean mirrors"
, "Clean desk"
]
weekdayName : Weekday -> String
weekdayName weekday =
case weekday of
Mon ->
"Monday"
Tue ->
"Tuesday"
Wed ->
"Wednesday"
Thu ->
"Thursday"
Fri ->
"Friday"
Sat ->
"Saturday"
Sun ->
"Sunday"
habitsFor : Weekday -> List State.Habit
habitsFor weekday =
case weekday of
Mon ->
monday
Tue ->
tuesday
Wed ->
wednesday
Thu ->
thursday
Fri ->
friday
Sat ->
saturday
Sun ->
sunday
tailwind : List ( String, Bool ) -> Attribute msg
tailwind classes =
classes
|> List.filter (\( k, v ) -> v)
|> List.map (\( k, v ) -> k)
|> String.join " "
|> class
render : State.Model -> Html State.Msg
render { dayOfWeek, completed } =
case dayOfWeek of
Nothing ->
p [] [ text "Unable to display habits because we do not know what day of the week it is." ]
Just weekday ->
div [ class "font-mono py-6 px-6" ]
[ h1 [ class "text-2xl text-center" ] [ text (weekdayName weekday) ]
, ul []
(weekday
|> habitsFor
|> List.indexedMap
(\i x ->
li [ class "text-xl" ]
[ button
[ class "py-5 px-6"
, tailwind
[ ( "line-through"
, Set.member i completed
)
]
, onClick (State.ToggleHabit i)
]
[ text x ]
]
)
)
]

View file

@ -0,0 +1,27 @@
module Main exposing (main)
import Browser
import Habits
import Html exposing (..)
import State
subscriptions : State.Model -> Sub State.Msg
subscriptions model =
Sub.none
view : State.Model -> Html State.Msg
view model =
case model.view of
State.Habits ->
Habits.render model
main =
Browser.element
{ init = \() -> State.init
, subscriptions = subscriptions
, update = State.update
, view = view
}

View file

@ -0,0 +1,80 @@
module State exposing (..)
import Date
import Set exposing (Set)
import Task
import Time exposing (Weekday(..))
type Msg
= DoNothing
| SetView View
| ReceiveDate Date.Date
| ToggleHabit Int
type View
= Habits
type HabitType
= Daily
| Weekly
| Yearly
type alias Habit =
String
type alias Model =
{ isLoading : Bool
, view : View
, dayOfWeek : Maybe Weekday
, completed : Set Int
}
{-| The initial state for the application.
-}
init : ( Model, Cmd Msg )
init =
( { isLoading = False
, view = Habits
, dayOfWeek = Nothing
, completed = Set.empty
}
, Date.today |> Task.perform ReceiveDate
)
{-| Now that we have state, we need a function to change the state.
-}
update : Msg -> Model -> ( Model, Cmd Msg )
update msg ({ completed } as model) =
case msg of
DoNothing ->
( model, Cmd.none )
SetView x ->
( { model
| view = x
, isLoading = True
}
, Cmd.none
)
ReceiveDate x ->
( { model | dayOfWeek = Just Sun }, Cmd.none )
ToggleHabit i ->
( { model
| completed =
if Set.member i completed then
Set.remove i completed
else
Set.insert i completed
}
, Cmd.none
)