Commit e2d47bcd authored by Christopher League's avatar Christopher League 🖥

Front page is styled fairly well

Need to make name and image environment settings.
parent a9f8a744
...@@ -113,7 +113,7 @@ instance Yesod App where ...@@ -113,7 +113,7 @@ instance Yesod App where
pc <- pc <-
widgetToPageContent $ do widgetToPageContent $ do
let fontFamily = let fontFamily =
asText "'Play', 'Helvetica Neue', Helvetica, Arial, sans-serif" asText "'Sura', 'Helvetica Neue', Helvetica, Arial, sans-serif"
addScriptL addScriptL
(StaticR js_jquery_3_3_1_min_js) (StaticR js_jquery_3_3_1_min_js)
"https://code.jquery.com/jquery-3.3.1.min.js" "https://code.jquery.com/jquery-3.3.1.min.js"
...@@ -125,7 +125,7 @@ instance Yesod App where ...@@ -125,7 +125,7 @@ instance Yesod App where
"https://cdn.jsdelivr.net/npm/js-cookie@2.2.0/src/js.cookie.min.js" "https://cdn.jsdelivr.net/npm/js-cookie@2.2.0/src/js.cookie.min.js"
[] []
addStylesheetRemote addStylesheetRemote
"https://fonts.googleapis.com/css?family=Play:400,700" "https://fonts.googleapis.com/css?family=Sura:400,700"
addStylesheetL addStylesheetL
(StaticR css_bootstrap_3_3_7_min_css) (StaticR css_bootstrap_3_3_7_min_css)
"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
......
...@@ -49,8 +49,8 @@ getHomeR ...@@ -49,8 +49,8 @@ getHomeR
-- Produce form for query and display parameters: appointment length, -- Produce form for query and display parameters: appointment length,
-- 12/24-hour time, time zone, location. -- 12/24-hour time, time zone, location.
qOpt <- runMaybeT QF.fromSession qOpt <- runMaybeT QF.fromSession
(queryWidget, enctype) <- generateFormPost $ QF.queryForm qOpt (idReset, idSpinner, idAvail, idAlert) <- newIdent4
(idSpinner, idAvail, idAlert) <- newIdent3 (queryWidget, enctype) <- generateFormPost $ QF.queryForm idReset qOpt
defaultLayout $(widgetFile "homepage") defaultLayout $(widgetFile "homepage")
-- | Ensure a successful form submission, or else throw a 400. -- | Ensure a successful form submission, or else throw a 400.
...@@ -65,7 +65,7 @@ formSuccess ((formResult, _), _) = ...@@ -65,7 +65,7 @@ formSuccess ((formResult, _), _) =
-- parameters, and show them as buttons. -- parameters, and show them as buttons.
getAvailR :: Handler Html getAvailR :: Handler Html
getAvailR = do getAvailR = do
QF.QueryForm {..} <- formSuccess =<< runFormGet (QF.queryForm Nothing) QF.QueryForm {..} <- formSuccess =<< runFormGet (QF.queryForm "" Nothing)
App { appSettings = AppSettings {appApptLengthsMinutes, appLookaheadWeeks} App { appSettings = AppSettings {appApptLengthsMinutes, appLookaheadWeeks}
, appCalendarCache , appCalendarCache
} <- getYesod } <- getYesod
...@@ -79,7 +79,7 @@ getAvailR = do ...@@ -79,7 +79,7 @@ getAvailR = do
postHomeR :: Handler Html postHomeR :: Handler Html
postHomeR = do postHomeR = do
q@QF.QueryForm {..} <- formSuccess =<< runFormPost (QF.queryForm Nothing) q@QF.QueryForm {..} <- formSuccess =<< runFormPost (QF.queryForm "" Nothing)
slot <- runInputPost QF.timeInput slot <- runInputPost QF.timeInput
QF.toSessionWithSlot q slot QF.toSessionWithSlot q slot
redirect BookR redirect BookR
......
...@@ -5,5 +5,11 @@ module Import ...@@ -5,5 +5,11 @@ module Import
import Foundation as Import import Foundation as Import
import Import.NoFoundation as Import import Import.NoFoundation as Import
newIdent2 :: MonadHandler m => m (Text, Text)
newIdent2 = (,) <$> newIdent <*> newIdent
newIdent3 :: MonadHandler m => m (Text, Text, Text) newIdent3 :: MonadHandler m => m (Text, Text, Text)
newIdent3 = (,,) <$> newIdent <*> newIdent <*> newIdent newIdent3 = (,,) <$> newIdent <*> newIdent <*> newIdent
newIdent4 :: MonadHandler m => m (Text, Text, Text, Text)
newIdent4 = (,,,) <$> newIdent <*> newIdent <*> newIdent <*> newIdent
...@@ -209,6 +209,11 @@ locationChoiceField = Field {..} ...@@ -209,6 +209,11 @@ locationChoiceField = Field {..}
locs <- appLocations . appSettings <$> getYesod locs <- appLocations . appSettings <$> getYesod
$(widgetFile "query-locations") $(widgetFile "query-locations")
tzChars :: Char -> Text
tzChars '_' = " "
tzChars '/' = " » "
tzChars c = singleton c
zonesByContinent :: Map Text [(Text, Text)] zonesByContinent :: Map Text [(Text, Text)]
zonesByContinent = zonesByContinent =
Map.fromList $ map continent $ groupAllOn fst $ map splitTz allZones Map.fromList $ map continent $ groupAllOn fst $ map splitTz allZones
...@@ -216,11 +221,8 @@ zonesByContinent = ...@@ -216,11 +221,8 @@ zonesByContinent =
allZones :: [TZLabelW] allZones :: [TZLabelW]
allZones = [minBound..maxBound] allZones = [minBound..maxBound]
space '_' = ' '
space c = c
splitTz :: TZLabelW -> (Text, (Text, Text)) splitTz :: TZLabelW -> (Text, (Text, Text))
splitTz tz = (cont, (txt, omap space (drop 1 city))) splitTz tz = (cont, (txt, concatMap tzChars (drop 1 city)))
where (cont, city) = break (== '/') txt where (cont, city) = break (== '/') txt
txt = toPathPiece tz txt = toPathPiece tz
...@@ -229,36 +231,27 @@ zonesByContinent = ...@@ -229,36 +231,27 @@ zonesByContinent =
continent ((x,y):xys) = (x, y : map snd xys) continent ((x,y):xys) = (x, y : map snd xys)
-- | Present time zone choices. -- | Present time zone choices.
tzSelectorField :: Field Handler TZLabelW tzSelectorField :: Text -> Field Handler TZLabelW
tzSelectorField = Field {..} tzSelectorField idReset = Field {..}
where where
fieldEnctype = UrlEncoded fieldEnctype = UrlEncoded
fieldParse (txt:_) _ = return $ Right $ fromPathPiece txt fieldParse (txt:_) _ = return $ Right $ fromPathPiece txt
fieldParse _ _ = return $ Left $ SomeMessage $ MsgInvalidEntry "Timezone" fieldParse _ _ = return $ Left $ SomeMessage $ MsgInvalidEntry "Timezone"
fieldView _ name attrs val _ = do fieldView _ name attrs val _ = do
AppSettings{appDefaultTimeZone} <- appSettings <$> getYesod AppSettings{appDefaultTimeZone} <- appSettings <$> getYesod
(idTextTz, idSelectTz) <- newIdent2
let currentTz = toPathPiece $ either (const appDefaultTimeZone) id val let currentTz = toPathPiece $ either (const appDefaultTimeZone) id val
isDefaultTz = currentTz == toPathPiece appDefaultTimeZone
cityAttrs = [(asText "class", "tzsel " <> qControl)] cityAttrs = [(asText "class", "tzsel " <> qControl)]
[whamlet| $(widgetFile "timezone")
<input type=hidden name=#{name} value=#{currentTz}>
<select name=#{name}-con *{attrs}>
$forall c <- Map.keys zonesByContinent
<option value=#{c} :isPrefixOf c currentTz:selected>#{c}
$forall c <- Map.keys zonesByContinent
<select name=#{name}-#{c} :not(isPrefixOf c currentTz):style="display:none"
*{cityAttrs}>
$maybe zs <- lookup c zonesByContinent
$forall (z,txt) <- zs
<option value=#{toPathPiece z} :z == currentTz:selected>#{txt}
|]
qControl :: Text qControl :: Text
qControl = "qcontrol" qControl = "qcontrol"
-- | The complete query form for the front page. -- | The complete query form for the front page.
queryForm :: queryForm ::
Maybe QueryForm -> Html -> MForm Handler (FormResult QueryForm, Widget) Text -> Maybe QueryForm -> Html -> MForm Handler (FormResult QueryForm, Widget)
queryForm qOpt extra = do queryForm idReset qOpt extra = do
AppSettings {..} <- appSettings <$> getYesod AppSettings {..} <- appSettings <$> getYesod
let qs n = "" {fsName = Just (qiName n), fsAttrs = [("class", qControl)]} let qs n = "" {fsName = Just (qiName n), fsAttrs = [("class", qControl)]}
(lenRes, lenView) <- (lenRes, lenView) <-
...@@ -278,7 +271,7 @@ queryForm qOpt extra = do ...@@ -278,7 +271,7 @@ queryForm qOpt extra = do
(queryLocation <$> qOpt <|> headMay appLocations) (queryLocation <$> qOpt <|> headMay appLocations)
(tzRes, tzView) <- (tzRes, tzView) <-
mreq mreq
tzSelectorField (tzSelectorField idReset)
(qs idTzLabel) (qs idTzLabel)
(queryTzLabel <$> qOpt <|> Just appDefaultTimeZone) (queryTzLabel <$> qOpt <|> Just appDefaultTimeZone)
return return
......
...@@ -42,15 +42,3 @@ $newline never ...@@ -42,15 +42,3 @@ $newline never
document.documentElement.className = document.documentElement.className.replace(/\bno-js\b/,'js'); document.documentElement.className = document.documentElement.className.replace(/\bno-js\b/,'js');
<body> <body>
^{pageBody pc} ^{pageBody pc}
$maybe analytics <- appAnalytics $ appSettings master
<script>
if(!window.location.href.match(/localhost/)){
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', '#{analytics}', 'auto');
ga('send', 'pageview');
}
<nav .navbar.navbar-default>
<div .container>
<div .navbar-header>
<a .navbar-brand href=@{HomeR}>
<span .glyphicon.glyphicon-calendar aria-hidden="true">
<p .navbar-text>
Prof. League
<div .container>
<div .row #avatar>
<div .col-md-12.hidden-md.hidden-lg>
<img .img-circle width=100 height=100 src="https://avatars3.githubusercontent.com/u/50286?s=100&v=4">
<div .container> <div .container>
$maybe msg <- mmsg $maybe msg <- mmsg
......
...@@ -2,44 +2,19 @@ body { ...@@ -2,44 +2,19 @@ body {
font-family: #{fontFamily}; font-family: #{fontFamily};
} }
.navbar { #avatar {
background-color: rgb(27, 28, 29); margin-top: -60px;
margin-bottom: 1ex;
} }
#avatar img {
.navbar-default .navbar-nav > .active > a { float: right;
background-color: transparent;
border-bottom: 2px solid white;
}
.navbar-nav {
padding-bottom: 1em;
}
/* Common styles for all types */
.bs-callout {
padding: 20px;
margin: 20px 0;
border: 1px solid #eee;
border-left-width: 5px;
border-radius: 3px;
} }
.bs-callout p:last-child { h1 {
margin-bottom: 0; font-size: 28px;
} margin: 0 0 1ex 0;
.bs-callout-info {
border-left-color: #1b809e;
}
/* Space things out */
.bs-docs-section {
margin-bottom: 60px;
}
.bs-docs-section:last-child {
margin-bottom: 0;
} }
#message { #message {
margin-bottom: 40px; margin-bottom: 10px;
} }
<h1>Book an appointment <h1>
Choose an appointment
<a ##{idReset} href=@{ClearR} :isNothing qOpt:style="display:none">
<sup .text-danger title="Reset to default options">
<span .glyphicon.glyphicon-remove style="font-size:70%">
<form method=post action=@{HomeR} enctype=#{enctype}> <form method=post action=@{HomeR} enctype=#{enctype}>
^{queryWidget} ^{queryWidget}
......
// -*- js -*- // -*- js -*-
$(function(){
$("#showTzControls").click(function(){
$("#tzControls").show();
});
});
function sendQuery() { function sendQuery() {
$("##{rawJS idSpinner}").show(); $("##{rawJS idSpinner}").show();
$("##{rawJS idAvail}").hide(); $("##{rawJS idAvail}").hide();
......
...@@ -2,14 +2,14 @@ ...@@ -2,14 +2,14 @@
<p> <p>
Show Show
^{fvInput lenView} ^{fvInput lenView}
meeting times using meeting times
<p>
using
^{fvInput fmtView} ^{fvInput fmtView}
notation notation
<p> ^{fvInput tzView}
for the time zone
^{fvInput tzView}
  <a href=@{ClearR}>(Reset to defaults)</a>
<p> <div style="margin: 3ex 0">
^{fvInput locView} ^{fvInput locView}
...@@ -3,6 +3,7 @@ $(function(){ ...@@ -3,6 +3,7 @@ $(function(){
sendQuery(); sendQuery();
}); });
function juggleTimeZone() { function juggleTimeZone() {
$("##{rawJS idReset}").show();
if($(this).hasClass("tzsel") || $(this).attr("name") == "tz-con") { if($(this).hasClass("tzsel") || $(this).attr("name") == "tz-con") {
var continent = $("select[name=tz-con]").val(); var continent = $("select[name=tz-con]").val();
var cityElt = $("select[name=tz-"+continent+"]"); var cityElt = $("select[name=tz-"+continent+"]");
......
<input type=hidden name=#{name} value=#{currentTz}>
$if isDefaultTz
<p #showDefaultTz>
in time zone: 
<span #textTz>
<span .glyphicon.glyphicon-globe style="position:relative; top:2px;">
#{concatMap tzChars currentTz}
<div #selectTz :isDefaultTz:style="display:none">
<p>
in time zone:
<p>
<span .glyphicon.glyphicon-globe style="font-size:140%;position:relative;top:5px;">
<select name=#{name}-con *{attrs}>
$forall c <- Map.keys zonesByContinent
<option value=#{c} :isPrefixOf c currentTz:selected>#{c}
$forall c <- Map.keys zonesByContinent
<select name=#{name}-#{c} :not(isPrefixOf c currentTz):style="display:none"
*{cityAttrs}>
$maybe zs <- lookup c zonesByContinent
$forall (z,txt) <- zs
<option value=#{toPathPiece z} :z == currentTz:selected>#{txt}
$(function() {
$("#textTz").click(function(){
$("#showDefaultTz").hide();
$("#selectTz").show();
$("##{rawJS idReset}").show();
});
})
#textTz {
cursor: pointer;
color: #000;
}
.tzToggle:hover {
cursor: pointer;
}
.tzVariant .glyphicon {
position: relative;
top: 3px;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment