Add some styling.

This commit is contained in:
Danila Fedorin 2021-05-16 17:02:57 -07:00
parent 91205fdea9
commit 39764dd4a5
4 changed files with 150 additions and 32 deletions

85
scss/style.scss Normal file
View 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%);
}
}

View File

@ -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
} }

View File

@ -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
isSelected = sel == Just i
addedIndicator =
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 <| c.name ]
, td [] [ text <| String.join ", " <| c.instructors ] , td [] [ text <| String.join ", " <| c.instructors ]
, td [] [ text <| String.join ", " <| extractTimeCodes c ] , 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" ]

View File

@ -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