diff --git a/.forgejo/workflows/deploy.yml b/.forgejo/workflows/deploy.yml index 434f8d38..787303ae 100644 --- a/.forgejo/workflows/deploy.yml +++ b/.forgejo/workflows/deploy.yml @@ -1,25 +1,53 @@ on: push: branches: [main] + workflow_dispatch: + +concurrency: + group: deploy-main + cancel-in-progress: true jobs: deploy: - runs-on: docker + runs-on: self-hosted steps: - - uses: actions/checkout@v4 - - - name: Restart Nomad allocation + - name: Build Astro and restart Nomad env: NOMAD_ADDR: ${{ secrets.NOMAD_ADDR }} NOMAD_TOKEN: ${{ secrets.NOMAD_TOKEN }} + REPO_URL: https://git.bcgen.ie/familyfedie/familyfedie-website.git run: | - set -e - ALLOC_ID=$(curl -sf \ - -H "X-Nomad-Token: $NOMAD_TOKEN" \ - "$NOMAD_ADDR/v1/job/familyfed/allocations" \ - | python3 -c "import sys,json; allocs=json.load(sys.stdin); print(next(a['ID'] for a in allocs if a['ClientStatus']=='running'))") + set -eu + rm -rf source + export REF_NAME="${GITHUB_REF_NAME:-main}" + + nix --extra-experimental-features "nix-command flakes" \ + shell nixpkgs#git \ + -c git clone --depth 1 --branch "$REF_NAME" "$REPO_URL" source + + cd source + nix --extra-experimental-features "nix-command flakes" \ + shell nixpkgs#nodejs_24 \ + -c npm ci + rm -rf dist + nix --extra-experimental-features "nix-command flakes" \ + shell nixpkgs#nodejs_24 \ + -c npm run build + + test -f dist/index.html + test -f dist/speeches/index.html + test -f dist/assets/icons/familyfed-favicon.png + + ALLOC_ID=$(nix --extra-experimental-features "nix-command flakes" \ + shell nixpkgs#curl nixpkgs#jq \ + -c sh -c 'curl -sf -H "X-Nomad-Token: $NOMAD_TOKEN" "$NOMAD_ADDR/v1/job/familyfed/allocations" | jq -r "map(select(.ClientStatus == \"running\"))[0].ID"') + + test -n "$ALLOC_ID" + test "$ALLOC_ID" != "null" echo "Stopping allocation to trigger fresh prestart: $ALLOC_ID" - curl -sf -X POST \ - -H "X-Nomad-Token: $NOMAD_TOKEN" \ - "$NOMAD_ADDR/v1/allocation/$ALLOC_ID/stop" - echo "Deploy triggered — Nomad will schedule a new alloc that re-fetches the site." + nix --extra-experimental-features "nix-command flakes" \ + shell nixpkgs#curl \ + -c curl -sf -X POST \ + -H "X-Nomad-Token: $NOMAD_TOKEN" \ + "$NOMAD_ADDR/v1/allocation/$ALLOC_ID/stop" + echo "Deploy triggered. Nomad will schedule a new alloc that re-fetches the site." diff --git a/assets/icons/familyfed-favicon.png b/assets/icons/familyfed-favicon.png new file mode 100644 index 00000000..1c82fb24 Binary files /dev/null and b/assets/icons/familyfed-favicon.png differ diff --git a/assets/icons/familyfed-logo.webp b/assets/icons/familyfed-logo.webp new file mode 100644 index 00000000..1f2c0d9a Binary files /dev/null and b/assets/icons/familyfed-logo.webp differ diff --git a/astro.config.mjs b/astro.config.mjs index 33c3ea43..b1b39a5a 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -1,6 +1,7 @@ import { defineConfig } from "astro/config"; export default defineConfig({ + site: "https://familyfed.ie", output: "static", outDir: "dist", build: { diff --git a/css/site.css b/css/site.css index b6efa167..ac567378 100644 --- a/css/site.css +++ b/css/site.css @@ -30,7 +30,7 @@ body.custom-background { background-color: #ffffff; } .speech-filters { display: grid; - grid-template-columns: minmax(240px, 2fr) repeat(3, minmax(150px, 1fr)) auto; + grid-template-columns: minmax(240px, 2fr) repeat(2, minmax(150px, 1fr)) auto; gap: 12px; align-items: end; margin: 0 0 18px; @@ -100,18 +100,16 @@ body.custom-background { background-color: #ffffff; } } .speech-result p { - margin: 0 0 10px; + margin: 0; } -.speech-result-meta, -.speech-result-categories { +.speech-result-meta { display: flex; flex-wrap: wrap; gap: 6px; } -.speech-result-meta span, -.speech-result-categories span { +.speech-result-meta span { display: inline-flex; align-items: center; min-height: 22px; @@ -158,238 +156,6 @@ body.custom-background { background-color: #ffffff; } } } -/* Events calendar. */ -.events-page-shell { - box-sizing: border-box; - width: min(1100px, calc(100% - 40px)); - margin: 0 auto; - padding: 28px 0 44px; -} - -.events-page-header { - margin: 0 0 22px; -} - -.events-page-kicker { - margin: 0 0 6px; - color: #5f7f38; - font-size: 13px; - font-weight: 700; - letter-spacing: 0; - text-transform: uppercase; -} - -.events-page-header h1, -.events-calendar-heading h2, -.events-past h2, -.events-past-item h3 { - color: #2f332c; -} - -.events-page-header h1 { - margin: 0 0 8px; - font-size: 32px; - line-height: 1.18; -} - -.events-page-header p:last-child { - max-width: 680px; - margin: 0; - color: #5a5d56; - font-size: 16px; - line-height: 1.55; -} - -.events-calendar-panel, -.events-past { - border: 1px solid #e5e2d8; - border-radius: 8px; - background: #ffffff; -} - -.events-calendar-panel { - overflow: hidden; -} - -.events-calendar-heading { - display: flex; - flex-wrap: wrap; - gap: 12px 18px; - align-items: center; - justify-content: space-between; - padding: 20px 22px; - border-bottom: 1px solid #e5e2d8; - background: #fafbf7; -} - -.events-calendar-heading h2, -.events-past h2 { - margin: 0; - font-size: 24px; - line-height: 1.25; -} - -.events-calendar-heading p { - margin: 0; - padding: 7px 11px; - border: 1px solid #d6e3c1; - border-radius: 999px; - color: #3d662c; - background: #f0f7e8; - font-size: 14px; - line-height: 1.25; -} - -.events-calendar-grid { - display: grid; - grid-template-columns: repeat(7, minmax(0, 1fr)); - background: #e9e5db; - gap: 1px; -} - -.events-calendar-weekday, -.events-calendar-day { - box-sizing: border-box; - min-width: 0; - background: #ffffff; -} - -.events-calendar-weekday { - min-height: 42px; - padding: 12px 8px; - color: #676961; - font-size: 12px; - font-weight: 700; - line-height: 1.2; - text-align: center; - text-transform: uppercase; -} - -.events-calendar-day { - display: flex; - align-items: flex-start; - min-height: 92px; - padding: 10px; - color: #34372f; - font-size: 15px; - font-weight: 700; - line-height: 1; -} - -.events-calendar-day--weekend { - background: #fbfaf7; -} - -.events-calendar-day--outside-month { - color: #97978f; - background: #f5f4ef; -} - -.events-calendar-day--today { - color: #ffffff; - background: #5f7f38; -} - -.events-past { - margin-top: 24px; - padding: 22px; -} - -.events-past-list { - display: grid; - gap: 14px; - margin-top: 16px; -} - -.events-past-item { - display: grid; - grid-template-columns: 76px minmax(0, 1fr); - gap: 16px; - align-items: center; - padding: 14px; - border: 1px solid #ece8dd; - border-radius: 6px; - background: #fdfdfb; -} - -.events-past-date { - display: grid; - place-items: center; - min-height: 76px; - border: 1px solid #d9d3c5; - border-radius: 6px; - color: #575b50; - background: #ffffff; - line-height: 1.1; - text-align: center; - text-transform: uppercase; -} - -.events-past-date strong { - color: #bf4d28; - font-size: 27px; - line-height: 1; -} - -.events-past-date span { - font-size: 12px; - font-weight: 700; -} - -.events-past-item p { - margin: 0 0 4px; - color: #6b6d66; - font-size: 13px; -} - -.events-past-item h3 { - margin: 0; - font-size: 20px; - line-height: 1.25; -} - -@media (max-width: 760px) { - .events-page-shell { - width: min(100% - 24px, 1100px); - padding-top: 20px; - } - - .events-page-header h1 { - font-size: 27px; - } - - .events-calendar-heading, - .events-past { - padding: 16px; - } - - .events-calendar-grid { - overflow-x: auto; - grid-template-columns: repeat(7, minmax(52px, 1fr)); - } - - .events-calendar-weekday { - min-height: 36px; - padding: 10px 4px; - font-size: 11px; - } - - .events-calendar-day { - min-height: 58px; - padding: 8px; - font-size: 14px; - } - - .events-past-item { - grid-template-columns: 64px minmax(0, 1fr); - gap: 12px; - } - - .events-past-date { - min-height: 64px; - } -} - /* Contact page form. */ .contact-form { display: grid; @@ -448,3 +214,251 @@ body.custom-background { background-color: #ffffff; } margin: 0; color: #5c5c56; } + +/* Static events calendar. */ +.events-calendar-page .entry-content { + max-width: 100%; +} + +.familyfed-calendar { + display: grid; + gap: 16px; +} + +.calendar-toolbar, +.calendar-actions { + display: flex; + flex-wrap: wrap; + gap: 10px; + align-items: center; +} + +.calendar-toolbar { + justify-content: space-between; +} + +.calendar-title { + margin: 0; + color: #333333; + font-size: 28px; + line-height: 1.2; + text-align: center; +} + +.calendar-nav-button, +.calendar-secondary-button { + min-height: 38px; + border: 1px solid #d8d8d0; + border-radius: 4px; + color: #333333; + background: #ffffff; + cursor: pointer; +} + +.calendar-nav-button { + width: 42px; + font-size: 26px; + line-height: 1; +} + +.calendar-secondary-button { + padding: 8px 12px; +} + +.calendar-nav-button:hover, +.calendar-nav-button:focus, +.calendar-secondary-button:hover, +.calendar-secondary-button:focus { + border-color: #bf4d28; + color: #bf4d28; +} + +.calendar-layout { + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(240px, 300px); + gap: 18px; + align-items: start; +} + +.calendar-grid-wrap, +.calendar-panel { + border: 1px solid #eeeeee; + border-radius: 6px; + background: #ffffff; +} + +.calendar-weekdays, +.calendar-grid { + display: grid; + grid-template-columns: repeat(7, minmax(0, 1fr)); +} + +.calendar-weekdays { + border-bottom: 1px solid #eeeeee; + background: #fbfbf8; +} + +.calendar-weekdays span { + padding: 10px 8px; + color: #5c5c56; + font-size: 12px; + font-weight: 700; + text-align: center; + text-transform: uppercase; +} + +.calendar-day { + display: grid; + grid-template-rows: auto 1fr; + gap: 6px; + min-height: 112px; + padding: 8px; + border: 0; + border-right: 1px solid #eeeeee; + border-bottom: 1px solid #eeeeee; + color: #333333; + background: #ffffff; + text-align: left; + cursor: pointer; +} + +.calendar-day:nth-child(7n) { + border-right: 0; +} + +.calendar-day:hover, +.calendar-day:focus { + outline: 2px solid #bf4d28; + outline-offset: -2px; +} + +.calendar-day-muted { + color: #8c8c86; + background: #fbfbf8; +} + +.calendar-day-today .calendar-day-number { + border-color: #d5e6b3; + color: #365d26; + background: #f2f7e8; +} + +.calendar-day-selected { + box-shadow: inset 0 0 0 2px #bf4d28; +} + +.calendar-day-number { + display: inline-flex; + align-items: center; + justify-content: center; + width: 28px; + min-height: 28px; + border: 1px solid transparent; + border-radius: 50%; + font-weight: 700; +} + +.calendar-day-events { + display: grid; + gap: 4px; + align-content: start; +} + +.calendar-event-pill, +.calendar-event-more { + overflow: hidden; + padding: 3px 6px; + border-radius: 4px; + font-size: 12px; + line-height: 1.25; + text-overflow: ellipsis; + white-space: nowrap; +} + +.calendar-event-pill { + color: #365d26; + background: #f2f7e8; +} + +.calendar-event-more { + color: #5c5c56; + background: #f7f7f2; +} + +.calendar-panel { + padding: 16px; +} + +.calendar-panel h3 { + margin: 0 0 12px; + font-size: 20px; +} + +.calendar-event-list { + display: grid; + gap: 12px; +} + +.calendar-event-card { + padding: 12px; + border: 1px solid #eeeeee; + border-radius: 6px; + background: #fbfbf8; +} + +.calendar-event-card h4 { + margin: 0 0 6px; + font-size: 18px; + line-height: 1.25; +} + +.calendar-event-card p { + margin: 0 0 7px; +} + +.calendar-event-date { + color: #5c5c56; + font-size: 12px; + font-weight: 700; + text-transform: uppercase; +} + +.calendar-empty { + margin: 0; + color: #5c5c56; +} + +@media (max-width: 900px) { + .calendar-layout { + grid-template-columns: 1fr; + } +} + +@media (max-width: 640px) { + .calendar-title { + font-size: 22px; + } + + .calendar-actions { + align-items: stretch; + } + + .calendar-actions > * { + width: 100%; + } + + .calendar-weekdays span { + padding: 8px 2px; + font-size: 11px; + } + + .calendar-day { + min-height: 78px; + padding: 5px; + } + + .calendar-event-pill, + .calendar-event-more { + font-size: 11px; + } +} diff --git a/src/components/SiteLayout.astro b/src/components/SiteLayout.astro index 82344a8e..b56edd27 100644 --- a/src/components/SiteLayout.astro +++ b/src/components/SiteLayout.astro @@ -14,7 +14,10 @@ const { parabolaSettings = { masonry: "0", magazine: "0", mobile: "1", fitvids: "1" }, } = Astro.props; const parabolaSettingsScript = `var parabola_settings = ${JSON.stringify(parabolaSettings)};`; -const canonicalUrl = canonical ?? pathname; +const siteOrigin = Astro.site?.origin ?? "https://familyfed.ie"; +const absoluteUrl = (value) => value ? new URL(value, siteOrigin).toString() : undefined; +const canonicalUrl = absoluteUrl(canonical ?? pathname); +const imageUrl = absoluteUrl(image); const metaTitle = title .replace(/–|–/g, "-") .replace(/‘|’|‘|’/g, "'") @@ -27,7 +30,6 @@ const metaTitle = title
-We’re conveniently located in Dublin City Centre, directly across from the James Joyce Center. Feel free to drop by anytime, since most days someone is around to offer you a cup of tea and a friendly chat about our beliefs.
Our address is:
19 North Great Georges St.
Dublin 1, Ireland
Feel free to email us any questions you may have or to book an appointment to hear our lecture series of the Divine Principle or to organize a religious event at our church center: directors@familyfed.ie
+Feel free to email us any questions you may have or to book an appointment to hear our lecture series of the Divine Principle or to organize a religious event at our church center.
+