Add some styling.
This commit is contained in:
parent
91205fdea9
commit
39764dd4a5
85
scss/style.scss
Normal file
85
scss/style.scss
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
$off-grey-color: #ededed;
|
||||||
|
$off-color: #eef2f9;
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main {
|
||||||
|
margin: auto;
|
||||||
|
max-width: 1600px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.split-pane {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: vertical;
|
||||||
|
}
|
||||||
|
|
||||||
|
.split-elem {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-wrapper {
|
||||||
|
border: 1px solid $off-grey-color;
|
||||||
|
padding-top: 0.5rem;
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
display: inline-block;
|
||||||
|
margin-top: 1rem;
|
||||||
|
box-shadow: 0px 0px 5px rgba(grey, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.class-table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
|
||||||
|
th, td {
|
||||||
|
padding: 0.5rem;
|
||||||
|
padding-left: 1rem;
|
||||||
|
padding-right: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr {
|
||||||
|
transition: background-color 0.2s;
|
||||||
|
|
||||||
|
&:nth-child(2n+3) {
|
||||||
|
background-color: $off-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.hoverable:hover {
|
||||||
|
background-color: lighten(yellow, 30%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.selected {
|
||||||
|
border: 1px dashed black;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.feather {
|
||||||
|
vertical-align: middle;
|
||||||
|
height: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
border: 1px solid black;
|
||||||
|
padding: 0.25rem;
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
|
||||||
|
vertical-align: middle;
|
||||||
|
|
||||||
|
&.color-green {
|
||||||
|
background-color: lighten(#5bc275, 30%);
|
||||||
|
border-color: #5bc275;
|
||||||
|
color: darken(#5bc275, 30%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.color-red {
|
||||||
|
background-color: lighten(#c25b75, 30%);
|
||||||
|
border-color: #c25b75;
|
||||||
|
color: darken(#c25b75, 30%);
|
||||||
|
}
|
||||||
|
}
|
|
@ -49,29 +49,20 @@ type alias Course =
|
||||||
, times : List (DayOfWeek, Time, Time)
|
, times : List (DayOfWeek, Time, Time)
|
||||||
}
|
}
|
||||||
|
|
||||||
type CourseStatus = None | Selected | Added
|
type CourseStatus = NotAdded | Added
|
||||||
|
|
||||||
isSelected : CourseStatus -> Bool
|
|
||||||
isSelected cs =
|
|
||||||
case cs of
|
|
||||||
Selected -> True
|
|
||||||
_ -> False
|
|
||||||
|
|
||||||
isAdded : CourseStatus -> Bool
|
|
||||||
isAdded cs =
|
|
||||||
case cs of
|
|
||||||
Added -> True
|
|
||||||
_ -> False
|
|
||||||
|
|
||||||
type alias Flags = ()
|
type alias Flags = ()
|
||||||
|
|
||||||
type Msg
|
type Msg
|
||||||
= SearchInput String
|
= SearchInput String
|
||||||
| SelectTerm String
|
| SelectTerm String
|
||||||
| MarkCourse Int CourseStatus
|
| SelectCourse Int
|
||||||
|
| AddCourse Int
|
||||||
|
| RemoveCourse Int
|
||||||
|
|
||||||
type alias Model =
|
type alias Model =
|
||||||
{ terms : Dict String (List (CourseStatus, Course))
|
{ terms : Dict String (List (CourseStatus, Course))
|
||||||
, term : String
|
, term : String
|
||||||
|
, selected : Maybe Int
|
||||||
, searchInput : String
|
, searchInput : String
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,15 @@
|
||||||
module ClassSchedule.View exposing (..)
|
module ClassSchedule.View exposing (..)
|
||||||
import ClassSchedule.Model exposing (..)
|
import ClassSchedule.Model exposing (..)
|
||||||
import Html exposing (Html, div, text, table, td, th, tr, span, input, h1)
|
import Html exposing (Html, Attribute, div, text, table, td, th, tr, span, input, h1)
|
||||||
import Html.Attributes exposing (class, classList, type_)
|
import Html.Attributes exposing (class, classList, type_)
|
||||||
|
import Html.Events exposing (onClick)
|
||||||
import Tuple exposing (..)
|
import Tuple exposing (..)
|
||||||
import Dict exposing (..)
|
import Dict exposing (..)
|
||||||
|
import FeatherIcons
|
||||||
|
|
||||||
|
iconButton : String -> FeatherIcons.Icon -> String -> List (Attribute Msg) -> Html Msg
|
||||||
|
iconButton c i s attrs = span ([ class "button", class ("color-" ++ c) ] ++ attrs)
|
||||||
|
[ FeatherIcons.toHtml [] i, text s ]
|
||||||
|
|
||||||
viewDept : Department -> String
|
viewDept : Department -> String
|
||||||
viewDept d =
|
viewDept d =
|
||||||
|
@ -50,7 +56,7 @@ unique l =
|
||||||
|
|
||||||
extractTimes : Course -> List (Time, Time)
|
extractTimes : Course -> List (Time, Time)
|
||||||
extractTimes c =
|
extractTimes c =
|
||||||
let extractTime (d, t1, t2) = (t2, t2)
|
let extractTime (d, t1, t2) = (t1, t2)
|
||||||
in unique <| List.map extractTime (c.times)
|
in unique <| List.map extractTime (c.times)
|
||||||
|
|
||||||
extractClasses : Course -> (Time, Time) -> List DayOfWeek
|
extractClasses : Course -> (Time, Time) -> List DayOfWeek
|
||||||
|
@ -66,25 +72,41 @@ extractTimeCodes c =
|
||||||
in dayCodes ++ " " ++ viewTimeRange tr
|
in dayCodes ++ " " ++ viewTimeRange tr
|
||||||
in List.map fromTime <| extractTimes c
|
in List.map fromTime <| extractTimes c
|
||||||
|
|
||||||
viewClass : Course -> Html Msg
|
viewClass : Maybe Int -> Int -> (CourseStatus, Course) -> Html Msg
|
||||||
viewClass c = tr []
|
viewClass sel i (cs, c) =
|
||||||
[ td [] [ text <| viewCrn (c.crn) ]
|
let
|
||||||
, td [] [ text <| c.name ]
|
isSelected = sel == Just i
|
||||||
, td [] [ text <| String.join ", " <| c.instructors ]
|
addedIndicator =
|
||||||
, td [] [ text <| String.join ", " <| extractTimeCodes c ]
|
case cs of
|
||||||
]
|
Added -> [ FeatherIcons.check |> FeatherIcons.toHtml [] ]
|
||||||
|
NotAdded -> []
|
||||||
|
in
|
||||||
|
tr [ class "hoverable", onClick (SelectCourse i), classList [("selected", isSelected)] ]
|
||||||
|
[ td [] addedIndicator
|
||||||
|
, td [] [ text <| viewCrn (c.crn) ]
|
||||||
|
, td [] [ text <| c.name ]
|
||||||
|
, td [] [ text <| String.join ", " <| c.instructors ]
|
||||||
|
, td [] [ text <| String.join ", " <| extractTimeCodes c ]
|
||||||
|
, td [] <|
|
||||||
|
case (isSelected, cs) of
|
||||||
|
(True, NotAdded) -> [ iconButton "green" (FeatherIcons.check) "Add" [ onClick (AddCourse i)] ]
|
||||||
|
(True, Added) -> [ iconButton "red" (FeatherIcons.x) "Remove" [onClick (RemoveCourse i)] ]
|
||||||
|
_ -> []
|
||||||
|
]
|
||||||
|
|
||||||
viewClassTable : List (CourseStatus, Course) -> Html Msg
|
viewClassTable : Maybe Int -> List (CourseStatus, Course) -> Html Msg
|
||||||
viewClassTable =
|
viewClassTable sel =
|
||||||
let
|
let
|
||||||
header = tr []
|
header = tr []
|
||||||
[ th [] [ text "Crn." ]
|
[ th [] [ ]
|
||||||
|
, th [] [ text "Crn." ]
|
||||||
, th [] [ text "Course Name" ]
|
, th [] [ text "Course Name" ]
|
||||||
, th [] [ text "Instructors" ]
|
, th [] [ text "Instructors" ]
|
||||||
, th [] [ text "Times" ]
|
, th [] [ text "Times" ]
|
||||||
|
, th [] []
|
||||||
]
|
]
|
||||||
in
|
in
|
||||||
table [] << (::) header << List.map (viewClass << second)
|
div [ class "table-wrapper" ] << List.singleton << table [ class "class-table" ] << (::) header << List.indexedMap (viewClass sel)
|
||||||
|
|
||||||
viewToolbar : Model -> Html Msg
|
viewToolbar : Model -> Html Msg
|
||||||
viewToolbar m = div []
|
viewToolbar m = div []
|
||||||
|
@ -95,12 +117,14 @@ viewClassList : Model -> Html Msg
|
||||||
viewClassList m = div []
|
viewClassList m = div []
|
||||||
[ viewToolbar m
|
[ viewToolbar m
|
||||||
, case get (m.term) (m.terms) of
|
, case get (m.term) (m.terms) of
|
||||||
Just cs -> viewClassTable cs
|
Just cs -> viewClassTable (m.selected) cs
|
||||||
Nothing -> text "Please select a term!"
|
Nothing -> text "Please select a term!"
|
||||||
]
|
]
|
||||||
|
|
||||||
viewClassSchedule : Model -> Html Msg
|
viewClassSchedule : Model -> Html Msg
|
||||||
viewClassSchedule m = text "Class schedule goes here!"
|
viewClassSchedule m = div [ class "table-wrapper" ]
|
||||||
|
[ text "Nothing here yet!"
|
||||||
|
]
|
||||||
|
|
||||||
viewModel : Model -> Html Msg
|
viewModel : Model -> Html Msg
|
||||||
viewModel m = div [ class "main" ]
|
viewModel m = div [ class "main" ]
|
||||||
|
|
24
src/Main.elm
24
src/Main.elm
|
@ -34,14 +34,19 @@ classes =
|
||||||
, instructors = ["Eric Walkingshaw"]
|
, instructors = ["Eric Walkingshaw"]
|
||||||
, times = onDays [Monday, Wednesday] <| oneHour <| nAm 10
|
, times = onDays [Monday, Wednesday] <| oneHour <| nAm 10
|
||||||
}
|
}
|
||||||
|
, { crn = (ComputerScience, 582)
|
||||||
|
, name = "Programming Languages II"
|
||||||
|
, instructors = ["Martin Erwig"]
|
||||||
|
, times = onDays [Monday, Wednesday] <| oneHour <| nPm 4
|
||||||
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
terms : Dict String (List (CourseStatus, Course))
|
terms : Dict String (List (CourseStatus, Course))
|
||||||
terms = Dict.singleton "Spring 2021"
|
terms = Dict.singleton "Spring 2021"
|
||||||
<| List.map (pair None) classes
|
<| List.map (pair NotAdded) classes
|
||||||
|
|
||||||
init : Flags -> (Model, Cmd Msg)
|
init : Flags -> (Model, Cmd Msg)
|
||||||
init () = ({ terms = terms, term = "Spring 2021", searchInput = "" }, Cmd.none)
|
init () = ({ terms = terms, term = "Spring 2021", searchInput = "", selected = Nothing }, Cmd.none)
|
||||||
|
|
||||||
view : Model -> Document Msg
|
view : Model -> Document Msg
|
||||||
view m =
|
view m =
|
||||||
|
@ -49,8 +54,21 @@ view m =
|
||||||
, body = [ viewModel m ]
|
, body = [ viewModel m ]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
modifyCurrent : (List (CourseStatus, Course) -> List (CourseStatus, Course)) -> Model -> Model
|
||||||
|
modifyCurrent f m = { m | terms = Dict.update (m.term) (Maybe.map f) (m.terms) }
|
||||||
|
|
||||||
|
changeCourse : Int -> CourseStatus -> List (CourseStatus, Course) -> List (CourseStatus, Course)
|
||||||
|
changeCourse i ncs =
|
||||||
|
let updateCourses j (cs, c) = if i == j then (ncs, c) else (cs, c)
|
||||||
|
in List.indexedMap updateCourses
|
||||||
|
|
||||||
update : Msg -> Model -> (Model, Cmd Msg)
|
update : Msg -> Model -> (Model, Cmd Msg)
|
||||||
update msg m = (m, Cmd.none)
|
update msg m =
|
||||||
|
case msg of
|
||||||
|
SelectCourse i -> ({ m | selected = Just i}, Cmd.none)
|
||||||
|
AddCourse i -> (modifyCurrent (changeCourse i Added) m, Cmd.none)
|
||||||
|
RemoveCourse i -> (modifyCurrent (changeCourse i NotAdded) m, Cmd.none)
|
||||||
|
_ -> (m, Cmd.none)
|
||||||
|
|
||||||
subscriptions : Model -> Sub Msg
|
subscriptions : Model -> Sub Msg
|
||||||
subscriptions m = Sub.none
|
subscriptions m = Sub.none
|
||||||
|
|
Loading…
Reference in New Issue
Block a user