diff --git a/.gitignore b/.gitignore index 214f149..b7c8ba0 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,4 @@ cabal.sandbox.config dist-newstyle/ result/ logs/ +demo_files/ diff --git a/README.md b/README.md index 1316cde..8b8abea 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,13 @@ cachix use jassob # Only needed once cachix use pingu # Probably more up to date as of 5/6-24 ``` +### Updating the view? +Currently, the css framework used is [TailwindCSS](https://tailwindcss.com). +To generate the css file, visit the website, wait until menus have loaded, and then save the html to `demo.html`. +Then use [Tailwinds cli](https://tailwindcss.com/blog/standalone-cli) program to generate the new css by running `tailwindcss --content demo.html --output static/style.css --minify`. + +Worth noting is that the css is embedded in the binary, and changes to it aren't well captured by cabal, so `cabal clean && cabal run` or `docker compose up --build` might be needed to see the updated styling. + ## Credits Favicon made by Freepik from + +Lunch at Chalmers

Today / 2024-10-24

Kårrestaurangen 

  • Greens

    Tofu kung pao, salladslök, paprika, basmatiris, koriander, lime
  • Street food

    Bakad fisk,tikka masala ,koriander, basmatiris & yoghurt
  • Nordic

    Fläsk karré, bakad potatis, rödvinssås & örtsmör

S.M.A.K. 

  • Dagens

    Pumpacurry, kikärtor & bönor, koriander, chili & ris

L's Kitchen 

  • Kött

    Fläskfärsbiff, grön curry, ingefära, nudlar, soja, misokräm & koriander
  • Fisk

    Ångad fisk, musselsås, potatismos, gröna ärtor, haricot verts & citron
  • Vegan

    Falafel, couscoussallad, "vegansk raita, koriander
  • Sallad

    Bulgur, kokt ägg, räkor, dillkräm, rädisor
  • Sallad

    Caesarsallad; kyckling, grana padano, bacon, krutonger

Wijkanders 

  • Veg

    Pasta med grönkålspesto, bakade tomater, grana padano & ruccola
  • Fisk

    Mandelbakad fisk, brynt smör, blomkålspuré & svamp
  • Kött

    Nattbakad fläskkarrè, chimichurri, rostad sötpotatis & mojo rojo

Café Linsen 

  • Högrevsburgare.

    Bacon Chutney, Picklad Gurka/Sallad, Brioche, Ost, Friterad Klyftpotatis.
  • Italiensk fisksoppa.

    Räkor, Musslor, Tomat, Grönsaker, Krutonger, Potatis.
  • Grillost Burgare.

    Svamp Chutney, Picklad Gurka , Sallad, Brioche, Fritera Klyftpotatis.
\ No newline at end of file diff --git a/flake.nix b/flake.nix index 0ccdf67..5e533dd 100644 --- a/flake.nix +++ b/flake.nix @@ -52,9 +52,10 @@ packages = p: [ self.packages.${system}.mat ]; withHoogle = true; buildInputs = - [ - pkgs.zlib - ] ++ + (with pkgs; [ + zlib + tailwindcss + ]) ++ (with haskellPackages; [ haskell-language-server cabal-install diff --git a/src/View.hs b/src/View.hs index 9902311..b2e0601 100644 --- a/src/View.hs +++ b/src/View.hs @@ -1,4 +1,4 @@ -{-# LANGUAGE OverloadedStrings, TemplateHaskell, RecordWildCards #-} +{-# LANGUAGE OverloadedStrings, RecordWildCards #-} module View ( View(..) @@ -6,18 +6,10 @@ module View ) where -import Data.FileEmbed import qualified Data.Text.Lazy as T -import qualified Data.Text.Lazy.Builder as T import Data.Thyme ( defaultTimeLocale , formatTime ) -import Lens.Micro.Platform ( (&) - , (%~) - , both - ) import Lucid -import qualified Text.CSS.Parse as CSS -import qualified Text.CSS.Render as CSS import Model import Model.Types ( NoMenu(..) ) @@ -28,42 +20,38 @@ render v = renderText (renderView v) renderView :: View -> Html () renderView View {..} = doctypehtml_ $ do sitehead - body_ $ div_ [class_ "container-fluid main"] $ do - h1_ $ do - toHtml day - " / " - toHtml (formatTime defaultTimeLocale "%F" date) - if null restaurants - then div_ . box_ . h3_ $ ("No lunches " >> toHtml day) - else div_ $ uncurry - mappend - ( splitAt 4 (map renderRest restaurants) - & both - %~ (div_ [class_ "row"] . mconcat) - ) + body_ [class_ "bg-[#e9e7e7]"] $ do + div_ [class_ "px-4 py-4 mx-auto"] $ do + h1_ [class_ "text-4xl"] $ do + toHtml day + " / " + toHtml (formatTime defaultTimeLocale "%F" date) + if null restaurants + then div_ . box_ . h3_ $ ("No lunches " >> toHtml day) + else div_ [class_ "grid grid-cols-1 md:grid-cols-4"] . mconcat $ map renderRest restaurants - sitefooter + sitefooter renderRest :: Restaurant -> Html () renderRest Restaurant {..} = box_ $ do - h2_ (toHtml name >> " " >> a_ [href_ (T.toStrict url)] "☛") + h2_ [class_ "text-2xl text-orange-500"] (toHtml name >> " " >> a_ [href_ (T.toStrict url)] "☛") ul_ [class_ "food-menu"] $ case menu of Left NoLunch -> li_ "No lunch this day!" Left _ -> li_ "Something went wrong, " <> a_ - [href_ $ T.toStrict "https://github.com/dtekcth/mat-chalmers/issues/new"] + [href_ "https://github.com/dtekcth/mat-chalmers/issues/new", class_ "text-orange-500 visited:text-orange-800"] "please file an issue." Right menus -> mconcat (map renderMenu menus) renderMenu :: Menu -> Html () -renderMenu (Menu lunch spec) = li_ +renderMenu (Menu lunch spec) = li_ [class_ "text-lg"] (do - h3_ (toHtml lunch) - span_ [class_ "invisible-space"] " " + h3_ [class_ "inline-block font-bold text-orange-500"](toHtml lunch) + span_ [class_ "invisible"] " " toHtml spec ) box_ :: Html () -> Html () -box_ = div_ [class_ "col-xs-12 col-sm-6 col-md-3 food"] +box_ = div_ [class_ "relative mt-5"] sitehead :: Html () sitehead = head_ @@ -71,24 +59,18 @@ sitehead = head_ meta_ [charset_ "utf-8"] meta_ [name_ "viewport", content_ "width=device-width, initial-scale=1"] link_ [rel_ "icon", type_ "image/png", href_ "icon.png"] - style_ [] css + link_ [rel_ "stylesheet", href_ "style.css"] title_ "Lunch at Chalmers" ) sitefooter :: Html () sitefooter = footer_ - [class_ "col-xs-12 col-sm-12 col-md-12"] + [class_ "py-6 relative justify-self-end"] (do "Eat at your own risk :) // " "Problems? " - a_ [href_ "https://github.com/dtekcth/mat-chalmers/issues/new"] + a_ [href_ "https://github.com/dtekcth/mat-chalmers/issues/new", class_ "text-orange-500 visited:text-orange-800"] "File an issue!" " // " - a_ [href_ "https://kortladdning3.chalmerskonferens.se/"] "Top-up your card" + a_ [href_ "https://kortladdning3.chalmerskonferens.se/", class_ "text-orange-500 visited:text-orange-800"] "Top-up your card" ) - --- brittany-disable-next-binding -css :: T.Text -css = - (either error (T.toLazyText . CSS.renderNestedBlocks) . CSS.parseNestedBlocks) - $(embedStringFile "static/style.css") diff --git a/static/style.css b/static/style.css index 792671e..539c2eb 100644 --- a/static/style.css +++ b/static/style.css @@ -1,122 +1 @@ -@font-face { - font-family: "Anonymous Pro"; - src: url("fonts/AnonymousPro-Regular.ttf"); - font-weight: 400; -} -@font-face { - font-family: "Anonymous Pro"; - src: url("fonts/AnonymousPro-Bold.ttf"); - font-weight: 700; -} -* { - box-sizing: border-box; -} -html { - font-size: 10px; -} -body { - font-family: "Anonymous Pro"; - font-size: 14px; - line-height: 1.42857143; - background: #fdf7e2; - color: #333; - margin: 0; -} -h1, -h2, -h3 { - line-height: 1.1; - font-weight: 500; - margin: 0; - margin-bottom: 10px; -} -h1 { - padding-left: 15px; - font-size: 36px; - margin-top: 20px; -} -h2 { - font-size: 140%; - font-weight: bold; -} -h3 { - margin-right: 10px; - margin-bottom: 0; - display: inline-block; - font-size: 100%; - font-weight: bold; - color: #bd3613; -} -.invisible-space { - width: 0px; - font-size: 0px; -} -p { - font-size: 10vh; -} -a { - color: #428bca; - text-decoration: none; -} -ul { - padding: 0; - list-style-type: none; - margin-top: 0; - margin-bottom: 10px; -} -li { - width: 100%; - font-weight: 400; - padding-bottom: 5px; -} -.food { - position: relative; - margin-top: 20px; -} -.row { - display: flex; - flex-wrap: wrap; -} -footer { - font-size: 0.9em; - margin-top: 20px; -} -/* Emulate Bootstrap Grid layout */ -.container-fluid { - padding-left: 15px; - padding-right: 15px; - margin-left: auto; - margin-right: auto; -} -.row { - margin-left: -15px; - margin-right: -15px; -} -.col-xs-12, -.col-sm-12, -.col-md-12, -.col-sm-6, -.col-md-3 { - padding-left: 15px; - padding-right: 15px; - position: relative; -} -.col-xs-12 { - width: 100%; -} -@media (min-width: 768px) { - .col-sm-12 { - width: 100%; - } - .col-sm-6 { - width: 50%; - } -} -@media (min-width: 992px) { - .col-md-3 { - width: 25%; - } - .col-md-12 { - width: 100%; - } -} +*,::backdrop,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/*! tailwindcss v3.4.13 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e7eb;box-sizing:border-box}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-tap-highlight-color:transparent}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-size:1em;font-variation-settings:normal}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{color:inherit;font-family:inherit;font-feature-settings:inherit;font-size:100%;font-variation-settings:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]{display:none}.invisible{visibility:hidden}.absolute{position:absolute}.relative{position:relative}.mx-auto{margin-left:auto;margin-right:auto}.mt-5{margin-top:1.25rem}.inline-block{display:inline-block}.grid{display:grid}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.justify-self-end{justify-self:end}.bg-\[\#e9e7e7\]{--tw-bg-opacity:1;background-color:rgb(233 231 231/var(--tw-bg-opacity))}.px-4{padding-left:1rem;padding-right:1rem}.py-4{padding-bottom:1rem;padding-top:1rem}.py-6{padding-bottom:1.5rem;padding-top:1.5rem}.text-2xl{font-size:1.5rem;line-height:2rem}.text-4xl{font-size:2.25rem;line-height:2.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.font-bold{font-weight:700}.text-orange-500{--tw-text-opacity:1;color:rgb(249 115 22/var(--tw-text-opacity))}.visited\:text-orange-800:visited{color:#9a3412}@media (min-width:768px){.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}} \ No newline at end of file diff --git a/tailwind.config.js b/tailwind.config.js new file mode 100644 index 0000000..cc63384 --- /dev/null +++ b/tailwind.config.js @@ -0,0 +1,11 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [], + theme: { + extend: {}, + }, + plugins: [ + require('@tailwindcss/typography'), + ], +} +