diff --git a/README.md b/README.md index a09c87a..ca768ea 100644 --- a/README.md +++ b/README.md @@ -16,3 +16,14 @@ Ready to run in production? Please [check our deployment guides](https://hexdocs * Docs: https://hexdocs.pm/phoenix * Forum: https://elixirforum.com/c/phoenix-forum * Source: https://github.com/phoenixframework/phoenix + +## Dev secret template + +``` +import Config + +directus_url = "" +directus_token = "" + +config :mse25, :directus, base_url: directus_url, token: directus_token +``` diff --git a/assets/app.css b/assets/app.css index 56fff6e..09472b9 100644 --- a/assets/app.css +++ b/assets/app.css @@ -1,580 +1,688 @@ -/* -Main CSS file for madr.se -If you have any questions regarding the CSS, feel free -to contact me: yttan at madr dot se - -Table of contents, 7-1 inspired - -1. Base -2. Components -3. Layout -4. Pages -5. Themes -6. Vendors -7. Shame -*/ - -/* === 1. Base === */ - -/* -Normalize and resets. -Only properties, element and attribute selectors are allowed in this -section. - -All dynamic values that should change according to user preferences -(dark or light color mode, reduced motion etc) and agent abilities -(small handheld screen, big desktop screen) are handled by properties -when appliable. - -This is to avoid redeclarating CSS rules. -*/ - -:root { - /* colors, dark mode default */ - --color: hsl(0 0 90%); - --bgcolor: hsl(180 75% 6%); - --tree-item-accent-color: dimgrey; - --panel-bg-color: hsla(0 0 50% / 0.16); - --monospace-color: springgreen; - --monospace-color-inline: seagreen; - --a-color: gold; - - /* typography, mobile first */ - --base-font-size: 1.33em; - --page-title-font-size: 2em; - --tree-font-size: 0.85em; - --section-heading-lv2-font-size: 1.5em; - --section-heading-lv3-font-size: 1.2em; - --section-heading-lv4-font-size: 1em; - --system-serif-fonts: Cambria, Cochin, Georgia, Times, "Times New Roman", - serif; - --system-sansserif-fonts: apple-system, system-ui, BlinkMacSystemFont, - Segoe UI, Roboto, Helvetica Neue, Arial, sans-serif; - --monospace-fonts: "JetBrains mono", monaco, menlo, meslo, "Courier New", - Courier, monospace; - - /* whitespace */ - --gap-sm: 0.5em; - --gap-md: 1em; - --gap-lg: 3em; - - /* transitions */ - --animation-duration: 0.5s; - - /* dimensions and aspect ratios */ - --map-ratio: 1; - - @media (min-width: 666px) { - --base-font-size: 1.66em; - --tree-font-size: 0.67em; - } -} - -html { - color: var(--color); - background-color: var(--bgcolor); - font: normal var(--base-font-size) / 1.5 var(--system-sansserif-fonts); -} - body { + background: #e1740d; margin: 0; - - > footer > p { - margin-top: var(--gap-lg); - color: #666; - font-size: 0.66em; - } -} - -a { - color: var(--a-color); + font-family: + system-ui, + -apple-system, + BlinkMacSystemFont, + "Segoe UI", + Roboto, + Oxygen, + Ubuntu, + Cantarell, + "Open Sans", + "Helvetica Neue", + sans-serif; } input, button { - font-size: 1.2em; - padding: 0.25em; + font-size: 1.25em; } -h1, -h2, -h3 { - font-family: var(--system-serif-fonts); +dl { + display: flex; + margin: 0; + justify-content: flex-end; + align-items: center; +} + +dt { + color: #888; + padding-right: 0.25em; + font-size: 0.75em; + text-transform: uppercase; +} + +dd { + margin-left: 0; + margin-right: 1em; +} + +body > header { + margin-bottom: 3em; + background: #f1f1f1; + display: grid; + grid-template-rows: 1fr 1fr; + grid-template-columns: auto 1fr; + grid-template-areas: "name nav" "name banner"; + border: 3px solid #000; +} + +.landing { + margin: 0; + width: auto; + max-width: none; +} + +.home-hero { + height: 90vh; + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + background-color: #261603; + color: #ff7c14; + gap: 2rem; + + img { + border-radius: 50%; + width: 333px; + border: 6px solid #000; + } + + > * { + max-width: 50%; + margin: 0; + } + + > a { + color: #fff; + } +} + +.c2a { + display: flex; + gap: 1em; + + > a { + --border-color: #C0430D; + --c2a-color: #E1740D; + border: 5px solid var(--border-color); + padding: 0.75em 1.25em; + text-transform: uppercase; + background-color: var(--c2a-color); + + &:nth-child(2) { + --c2a-color: #E1740D; + } + + &:nth-child(3) { + --c2a-color: #F05F00; + } + + &:hover, + &:focus { + --border-color: #E1740D; + --c2a-color: #fff; + } + } +} + +.home-h1 { + margin: 0; + font-size: 3em; + text-wrap: pretty; + + text-shadow: 0 0 60px #c0430d; + } +} + +body > header > div { + grid-area: banner; + padding: 0.5em; +} + +body > header > strong { + grid-area: name; + font-size: 2.66em; + padding: 0.66rem; + display: flex; + place-items: center; + border-right: 3px solid #000; + + > a { + text-decoration: none; + color: inherit; + } +} + +@media (max-width: 700px) { + body > header { + grid-template-rows: auto auto; + } + body > header > strong { + writing-mode: vertical-rl; + text-orientation: mixed; + padding: 0.33rem 0; + } + + body > header > nav > ul { + flex-direction: column; + width: 100%; + } +} + +body > header > nav { + grid-area: nav; + display: flex; + align-items: center; + border-bottom: 3px solid #000; + + > ul { + list-style: none; + margin: 0; + padding: 0; + display: flex; + gap: 0.1em; + border-left-width: 0; + } + + a { + font-weight: bold; + text-decoration: none; + color: #261603; + line-height: 1; + padding: 0.5rem; + display: block; + + &:hover, + &:focus { + background-color: #261603; + color: #ff7c14; + } + + &.current { + pointer-events: none; + background-color: #c0430d; + color: #fff; + } + } } h1 { - margin: 0.5em 0; - line-height: 0.95; - font-size: var(--page-title-font-size); - - @media (min-width: 666px) { - text-transform: lowercase; - margin-top: 0.5em; - margin-bottom: 0.5em; - text-align: right; - line-height: 0.9; - color: var(--tree-item-accent-color); - font-weight: normal; - } -} - -h2, -h3 { - margin-top: 2em; - line-height: 1.1; + font-size: 1.75em; + letter-spacing: -0.066em; } h2 { - font-size: var(--section-heading-lv2-font-size); - border-bottom: 3px solid var(--panel-bg-color); + font-size: 1.33em; } -h3 { - font-size: var(--section-heading-lv3-font-size); +p, +li { + line-height: 1.66em; } +h3, h4 { - font-size: var(--section-heading-lv4-font-size); + font-size: 1em; +} + +main { + margin: 2em auto; + max-width: 40em; +} + +.cards { + display: flex; + flex-direction: column; + gap: 4em; +} + +.card { + position: relative; + background-color: #fff; + border: 6px solid #261603; + padding: 3em; + box-sizing: border-box; + + :first-child { + margin-top: 0; + } + + :last-child { + margin-bottom: 0; + } + + &.collapsed { + border-top-left-radius: 0; + border-top-right-radius: 0; + } +} + +@media (max-width: 400px) { + .card { + padding: 0.5em; + } } pre { - margin: 2em 0; - background-color: #022; - color: var(--monospace-color); + padding: 0.5em; + background-color: #1e2025; + color: #96df71; + position: relative; + margin: 1em 2em; overflow-y: auto; - padding: 0.66em; - box-shadow: 4px 4px 0 var(--panel-bg-color); - position: relative; - line-height: 1.2; - font-size: 0.8em; - > button { - font-size: 0.75em; + button { position: absolute; - top: 0.25em; - right: 0.25em; + top: 2px; + right: 2px; } } -code { - font-family: var(--monospace-fonts); - - &.inline { - color: var(--monospace-color-inline); - background: #f3f3f3; - font-size: 0.9em; - } -} - -section { - position: relative; - - & > h2 { - background: var(--bgcolor); - color: var(--color); - padding: 0.5em 0.25em; - border-bottom: 0; - } -} - -img { - max-width: 100%; - display: block; - height: auto; -} - -ul, -ol { - clear: left; -} - -p { - margin: 1em 0; -} - -article { - line-height: 1.33; -} - -figure { - margin: 0; -} - -figcaption { - text-align: center; - margin-top: 0.5em; -} - -table { - width: 100%; -} - -td, -th { - background-color: var(--background-color-l); - padding: 0.25em; - font-size: 0.8em; - border: 1px solid rgb(128, 128, 128, 0.5); -} - -th { - background-color: var(--background-color-ll); - text-transform: uppercase; - color: var(--em-color); - font-weight: normal; -} - -li { - color: var(--em-color); - margin: 0.25em 0; -} - -li:first-child { - margin-top: 0; -} - -li:last-child { - margin-bottom: 0; -} - -li::marker { - color: var(--link-color); -} - -blockquote { - color: var(--em-color); - font-size: 1.2em; - line-height: 1.2; - font-style: italic; - border-left: 5px solid var(--background-color-l); - margin: 1em 1em 1em 0; - padding-left: 1em; -} - -blockquote p::after, -blockquote p::before { - content: '"'; -} - -/* === /Base === */ -/* === 2. Components === */ - -/* -Use kebab case named classes to identify components, and nesting -to group subcomponents. - -Element selectors are preferred as subcomponents, due to the simple -nature of this site. As a general rule though, classes are the most -versatile. -*/ - -.home-search, -.profiles { - font-size: var(--tree-font-size); -} - .sr-only { position: absolute; - left: -999em; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; } -.flx { - display: flex; - justify-content: space-between; - align-items: center; +.source { + font-size: small; + background-color: #eee; + color: #888; + padding: 0.5em; + margin-top: 1rem; } -.sticky { - position: sticky; - top: 0; +blockquote { + font-style: italic; + border-left: 6px solid #aaa; + margin-left: 0; + padding-left: 1.5em; } -.interactive-map { - aspect-ratio: var(--map-ratio); -} +.breadcrumbs { + > .trail > span::after { + content: "/"; + } + color: #bbb; -.home-h1 { - font-size: 1.33em; -} - -.list-link { - &::after { - content: " →"; + a { + color: #777; } } -.feed-link { +h3.note { + font-size: 1.5em; + font-weight: normal; +} + +.head { + background: #ff7c14; + border: 10px solid #c0430d; + position: relative; + padding: 0.5em; + margin: 3em 0 7em; + font-size: 1.25em; + + padding: 1em 2em; + + :first-child { + margin-top: 0; + } + + :last-child { + margin-bottom: 0; + } + &::after { - content: " ↗"; + display: block; + width: 10px; + height: 40px; + content: ""; + background: #c0430d; + position: absolute; + left: 50%; + transform: translateX(-10px) translateY(100%); + bottom: -10px; } } .skiplink { position: absolute; - top: -5em; - transition: top var(--animation-duration) ease-out; - padding: 0.25em 0.5em; + top: -2em; + left: 1em; + background-color: #ff0; + color: #000; + text-decoration: none; + padding: 0.25em; + transition: top 0.25s ease-out; &:focus { top: 1em; } } -.tree { - list-style: none; - margin: 0; - padding: 0; - display: flex; - flex-direction: column; - gap: 0.66em; - font-size: var(--tree-font-size); +.anders { + img { + position: fixed; + top: 1em; + left: 1em; + aspect-ratio: 1; + border-radius: 50%; + width: 175px; - > li { - text-align: center; - display: grid; - grid-template-columns: 50px 1fr auto; - align-items: center; - margin: 0; - gap: 0.5em; - padding: 0.75em; - min-height: 50px; - background-color: rgba(128, 128, 128, 0.1); - border: 1px solid rgba(192, 192, 192, 0.1); - - &:focus-within { - background-color: rgba(128, 128, 128, 0.25); - } - - > small { - opacity: 0.66; - font-family: var(--monospace-fonts); - font-size: 0.66em; + &:hover { + animation: 1s ease-out 0s infinite alternate burst; } } - > .article { - --tree-item-accent-color: rebeccapurple; + img + img { + top: 12.5em; + left: 5em; + width: 125px; } - > .album { - --tree-item-accent-color: goldenrod; - } - - > .link { - --tree-item-accent-color: honeydew; - } - - > .events { - --tree-item-accent-color: firebrick; - } - - a { - color: var(--color); - text-decoration: none; - flex: 1; - - &:hover, - &:focus { - text-decoration: underline; - } + img + img + img { + top: 18.5em; + left: 0.5em; + width: 90px; } } -.landing { +body > footer { + max-width: 30em; + margin: 7em auto; display: flex; - flex-direction: column; align-items: center; - padding: 2em 0; - box-sizing: border-box; - gap: 1.66em; -} + gap: 2em; -.breadcrumbs { - display: block; - margin: var(--gap-sm) 0; - padding: var(--gap-sm); - border: 1px solid rgb(128, 128, 128, 0.25); - background-color: var(--panel-bg-color); - border-radius: 0; + img { + width: 100px; + height: 100px; + aspect-ratio: 1 / 1; + border: 6px solid #c0430d; + border-radius: 8px; + } - > span { - display: inline; + p { + background: #ff7c14; + border: 6px solid #c0430d; + border-radius: 8px; + padding: 0.5em; + position: relative; - &:after { - content: " /"; + &::before { + content: ""; + display: block; + background: #c0430d; + width: 12px; + height: 6px; + position: absolute; + top: 45%; + left: -16px; } } +} - a { - color: var(--color); +@media (max-width: 400px) { + body > footer { + gap: 10px; + margin: 2em 0.5em 0; + font-size: small; + + img { + width: 60px; + height: 60px; + } } } -.months { - grid-auto-flow: rows; - display: grid; - list-style: none; - grid-template-columns: repeat(3, 1fr); - gap: 0.5em; - padding-left: 0; - margin: 2.75em 0; +.bookmarks, +.notes { + display: flex; + flex-direction: column; + gap: 4em; +} - > li { - margin: 0; +.bookmark { + h3 { + font-weight: normal; + font-size: 1.25em; + line-height: 1.33; + margin-top: 0; + font-weight: bold; + margin-bottom: 1rem; } + + footer { + text-align: right; + font-size: 1em; + color: #888; + + a { + color: #444; + } + } +} + +.bookmark-date { + font-size: 1rem; + background-color: #000; + color: #fff; + padding: 0.5em; + position: absolute; + top: -6px; + right: -6px; +} + +#leaflet { + aspect-ratio: 5 / 4; + border: 10px solid #C0430D; +} + +figure { + padding: 0; + margin: 2em 0; } .article { - > div > p:first-child::first-letter { - @media (min-width: 500px) { - float: left; - font-size: 7em; - border: 8px double hsl(0 0 50%); - padding: 0.1em; - margin-right: 0.066em; - font-style: normal; - font-family: var(--system-serif-fonts); - } + img { + max-width: 100%; + display: block; } - > footer { - font-style: italic; - font-size: 0.8em; - text-align: right; + margin: 2.8em 0; + h3 { + margin: 0; + font-size: 1.4em; + line-height: 1.33; + } - > p { - margin-top: 2.75em; - margin-bottom: 0; - } + ul { + padding-left: 1em; + margin: 2em; + } + + li + li { + margin-top: 0.5em; + } + + footer { + margin-top: 3em; + font-size: 0.75em; + font-style: italic; + } + + h2 { + margin-top: 3rem; } } -.articles { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 3em; - grid-auto-rows: 1fr; +.vert { + position: absolute; + left: calc(-6px - 2.1em); + top: 1em; + background: #fff; + padding: 0.25em; + border: 2px solid #261603; + border-top: 0; + margin: 0; + transform: rotate(90deg); +} - > * { - display: flex; - flex-direction: column; - justify-content: flex-end; - border-top: 6px solid red; - - &:focus-within { - background-color: #333; - } +@keyframes burst { + 0% { + transform: scale(1); } - - time { - border-top: 1px solid crimson; - padding: 0.25em 0.5em; + 50% { + transform: scale(1.2); + } + 100% { + transform: scale(0.8); } } .links { - > :is(h2, h3) { - margin-top: 3em; - } + display: flex; + flex-direction: column; + gap: 3em; } -.brutal-legend { +.line { + margin-top: 1rem; display: flex; - gap: 1em; - flex-direction: row-reverse; + align-items: end; + justify-content: space-between; +} - > p { - flex: 1; - margin: 0; - } +.permalink { + border: 4px solid blue; + padding: 0.5em; + text-decoration: none; +} + +.events { + display: flex; + flex-direction: column; + gap: 4em; +} + +.event { + display: grid; + grid-template-areas: "heading poster" "text poster"; + grid-template-columns: 1fr 25%; + grid-template-rows: auto 1fr; + gap: 1em; > img { - aspect-ratio: 1; + grid-area: poster; + max-width: 100%; } -} -.profiles { - display: flex; - gap: 1.66em; - list-style: none; - margin: 0; + > div { + grid-area: text; - > li { + :first-child { + margin-top: 0; + } + } + + > h3 { + font-size: 1.5em; + text-wrap: balance; + grid-area: heading; margin: 0; - padding: 0; + } + + &:nth-child(even) { + grid-template-areas: "poster heading" "poster text"; + grid-template-columns: 25% 1fr; } } -/* === /Components === */ -/* === 3. Layout === */ -/* -Containers and wrappers for components. -Only class selectors allowed, with the following element selectors as -exceptions: aside, body, footer, header, main and nav. -*/ -body { - margin: 0 auto; - max-width: 33em; - box-sizing: border-box; - min-height: 100vh; - padding: 0 0.5em; -} -/* === /Layout === */ -/* === 4. Pages === */ -/* -Styles that should only apply to certain pages. -*/ -/* === /Pages === */ -/* === 5. Themes === */ -/* -Styles to create user-customized themes. +.home-section { + padding: 1em 0; + background: var(--hs-bg); + color: var(--hs-c); -This section adapts the design to the following user preferences: -Color theme, reduced motion -*/ -@media (prefers-color-scheme: light) { - :root { - --color: #000; - --bgcolor: #fff; - --a-color: blue; + &.articles-color { + --hs-bg: #ff7c14; + } + + &.events-color { + --hs-bg: #c0430d; + } + + &.brutal-color { + --hs-bg: #261603; + --hs-c: #fff; + } + + > * { + display: block; + width: 40rem; + margin: 1em auto; } } -@media (prefers-reduced-motion) { - :root { - --animation-duration: 0; +.home-articles { + display: flex; + gap: 1.5rem; + font-size: 1.5em; + margin-bottom: 3rem; +} + +.poster-image { + width: 100%; + aspect-ratio: 2 / 3; + object-fit: cover; + border: 6px solid var(--hg-bg); +} + +.uc { + background-color: #000; color: #fff; padding: 0.5em 1em; position: absolute; right: 0; top: 0; +} + +.cover-image { + width: 100%; + aspect-ratio: 1 / 1; + object-fit: cover; + border: 6px solid var(--hg-bg); +} + +.poster-placeholder { + width: 100%; + aspect-ratio: 4 / 5; + background-color: rgba(255, 255, 255, 0.2); + display: inline-block; +} + +.home-grid { + --hg-bg: #000; + --hg-c: #fff; + display: grid; + grid-template-columns: 1fr 1fr 1fr; + gap: 2em; + margin-top: 4em; + margin-bottom: 4em; + + > * { + display: flex; gap: 3px; + align-items: flex-start; + } + + > *:focus-within, + > *:hover { + --hg-bg: #F05F00; + --hg-c: #000; + } + + &.brutal { + grid-template-columns: 1fr 1fr 1fr 1fr; } } -@media (min-width: 800px) { - :root { - --map-ratio: 3 / 2; +.event-meta { + writing-mode: vertical-rl; + text-orientation: mixed; + color: var(--hg-c); + background-color: var(--hg-bg); + padding: 6px; + font-size: small; + + time { + color: #C0430D; } } -@media (min-width: 1000px) { - :root { - --page-title-font-size: 4em; - } +.home-search { + padding: 3em 0; } -/* === /Themes === */ -/* === 6. Vendors === */ -/* -Styles belonging to third-party components. -*/ - -.footnotes-list { - color: var(--aside-color); - font-size: 80%; -} -/* === /Vendors === */ - -/* === 7. Shame === */ -/* -Styles necessary for specifity issues and for cutting corners -(breaking the rules in short terms in waiting for an opportunity -to rewrite or fix a problem for good). - -madr.se has no reason to feel ashamed. Yet. -*/ -/* === /Shame === */ diff --git a/config/config.exs b/config/config.exs index 3031791..ab2ef2f 100644 --- a/config/config.exs +++ b/config/config.exs @@ -26,7 +26,7 @@ config :esbuild, version: "0.17.11", mse25: [ args: - ~w(js/app.js --bundle --target=es2017 --outdir=../priv/static/assets --external:/bl/* --external:/images/* --external:/*.{vcf,png,ico,pdf}), + ~w(js/app.js --bundle --target=es2017 --outdir=../priv/static/assets --external:/bl/* --external:/images/* --external:/*.{vcf,png,ico,pdf,jpg}), cd: Path.expand("../assets", __DIR__), env: %{"NODE_PATH" => Path.expand("../deps", __DIR__)} ] diff --git a/lib/mse25/directus.ex b/lib/mse25/directus.ex index de29435..8a6255a 100644 --- a/lib/mse25/directus.ex +++ b/lib/mse25/directus.ex @@ -42,6 +42,31 @@ defmodule Mse25.Directus do get("/articles?" <> params) end + def get_note(slug) do + get_item(:notes, slug) + end + + def get_notes!(options \\ []) do + params = + [ + "fields=" <> + Enum.join( + [ + "id", + "contents", + "images", + "date_created", + "location" + ], + "," + ) + ] + |> annual?(:notes, options) + |> query_params_string(options, :notes) + + get("/notes?" <> params) + end + def get_album(externalId) do case get_item( :albums, @@ -198,6 +223,13 @@ defmodule Mse25.Directus do end end + defp get_item(:notes, externalId, fields) do + case get("/notes?fields=" <> fields <> "&filter[id][_eq]=" <> externalId) do + [] -> {:not_found, externalId} + [item | _] -> {:ok, item} + end + end + defp get_item(collection, slug, fields) do case get( "/" <> to_string(collection) <> "?fields=" <> fields <> "&filter[slug][_eq]=" <> slug diff --git a/lib/mse25_web/components/breadcrumbs.ex b/lib/mse25_web/components/breadcrumbs.ex new file mode 100644 index 0000000..d396b59 --- /dev/null +++ b/lib/mse25_web/components/breadcrumbs.ex @@ -0,0 +1,54 @@ +defmodule Mse25Web.Breadcrumbs do + use Mse25Web, :html + + def breadcrumbs_html(assigns) do + ~H""" +
+ """ + end + + defp breadcrumbs(nodes) do + breadcrumbs([], "", 1, nodes) + end + + defp breadcrumbs(seen, _path, _index, []) do + Enum.reverse(seen) + end + + defp breadcrumbs(seen, path, index, [{slug, name} | nodes]) do + breadcrumbs( + [{index + 1, {path <> "/" <> to_string(slug), name}} | seen], + path <> "/" <> to_string(slug), + index + 1, + nodes + ) + end + + defp breadcrumbs(seen, path, index, [{slug, name, custom_prefix} | nodes]) do + breadcrumbs( + [{index + 1, {custom_prefix <> "/" <> to_string(slug), name}} | seen], + path <> "/" <> to_string(slug), + index + 1, + nodes + ) + end +end diff --git a/lib/mse25_web/components/layouts.ex b/lib/mse25_web/components/layouts.ex index 5b68d48..204d005 100644 --- a/lib/mse25_web/components/layouts.ex +++ b/lib/mse25_web/components/layouts.ex @@ -78,32 +78,6 @@ defmodule Mse25Web.Layouts do """ end - def breadcrumbs(nodes) do - breadcrumbs([], "", 1, nodes) - end - - def breadcrumbs(seen, _path, _index, []) do - Enum.reverse(seen) - end - - def breadcrumbs(seen, path, index, [{slug, name} | nodes]) do - breadcrumbs( - [{index + 1, {path <> "/" <> to_string(slug), name}} | seen], - path <> "/" <> to_string(slug), - index + 1, - nodes - ) - end - - def breadcrumbs(seen, path, index, [{slug, name, custom_prefix} | nodes]) do - breadcrumbs( - [{index + 1, {custom_prefix <> "/" <> to_string(slug), name}} | seen], - path <> "/" <> to_string(slug), - index + 1, - nodes - ) - end - def show_interactive_event_map?(assigns) do Map.has_key?(assigns, :events) end @@ -111,4 +85,12 @@ defmodule Mse25Web.Layouts do def show_footer?(%{heading: "Kolofon"}), do: false def show_footer?(%{}), do: true + + def current?(_key, []) do + false + end + + def current?(k, path) do + Enum.member?(path, k) + end end diff --git a/lib/mse25_web/components/layouts/app.html.heex b/lib/mse25_web/components/layouts/app.html.heex index d038bff..37de46d 100644 --- a/lib/mse25_web/components/layouts/app.html.heex +++ b/lib/mse25_web/components/layouts/app.html.heex @@ -1,36 +1,72 @@ Hoppa till innehållet - + +