diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml new file mode 100644 index 0000000..eb11720 --- /dev/null +++ b/.github/workflows/checks.yml @@ -0,0 +1,19 @@ +name: Checks + +on: + pull_request: + branches: [master] + +jobs: + sanity: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + bundler-cache: true + + - name: Sanity checks + run: bin/rails sanity:check diff --git a/app/components/site/footer_component.rb b/app/components/site/footer_component.rb index e270594..9427e82 100644 --- a/app/components/site/footer_component.rb +++ b/app/components/site/footer_component.rb @@ -14,6 +14,7 @@ class FooterComponent < ViewComponent::Base title: "Resources", links: [ { label: "Sponsorship", href: "/sponsorship#" }, + { label: "Perks Program", href: "/sponsorship#perks-program" }, { label: "Executive Team", href: "/about#team" }, { label: "Design System", href: "/design_system" } ] diff --git a/app/components/site/navbar/component.rb b/app/components/site/navbar/component.rb index 50db548..10fc173 100644 --- a/app/components/site/navbar/component.rb +++ b/app/components/site/navbar/component.rb @@ -10,7 +10,8 @@ class Component < ViewComponent::Base { label: "Community", href: "/#community" }, { label: "Sponsors", href: "/#sponsors", children: [ { label: "Our Sponsors", href: "/#sponsors" }, - { label: "Become a Sponsor", href: "/sponsorship#" } + { label: "Become a Sponsor", href: "/sponsorship#" }, + { label: "Perks Program", href: "/sponsorship#perks-program" } ] } ].freeze diff --git a/app/controllers/pages_controller.rb b/app/controllers/pages_controller.rb index e62bc35..b752181 100644 --- a/app/controllers/pages_controller.rb +++ b/app/controllers/pages_controller.rb @@ -1,6 +1,8 @@ class PagesController < ApplicationController def home - @sponsors = YAML.load_file(Rails.root.join("config/sponsors.yml"))["sponsors"] || [] + config = YAML.load_file(Rails.root.join("config/sponsors.yml")) + @sponsors = config["sponsors"] || [] + @perks = config["perks"] || [] render "pages/landing/home" end diff --git a/app/javascript/controllers/perk_modal_controller.js b/app/javascript/controllers/perk_modal_controller.js new file mode 100644 index 0000000..01b1c1a --- /dev/null +++ b/app/javascript/controllers/perk_modal_controller.js @@ -0,0 +1,42 @@ +import { Controller } from "@hotwired/stimulus" + +export default class extends Controller { + static targets = ["backdrop", "panel", "icon", "name", "description", "link"] + + connect() { + this._onKeydown = this._onKeydown.bind(this) + } + + open(event) { + const card = event.currentTarget + const { perkName, perkIcon, perkDescription, perkWebsite } = card.dataset + + this.iconTarget.src = perkIcon + this.iconTarget.alt = perkName + this.nameTarget.textContent = perkName + this.descriptionTarget.textContent = perkDescription + this.linkTarget.href = perkWebsite + + this.backdropTarget.classList.remove("opacity-0", "pointer-events-none") + this.backdropTarget.classList.add("opacity-100", "pointer-events-auto") + this.panelTarget.classList.remove("scale-95", "opacity-0") + this.panelTarget.classList.add("scale-100", "opacity-100") + document.addEventListener("keydown", this._onKeydown) + } + + close() { + this.backdropTarget.classList.add("opacity-0", "pointer-events-none") + this.backdropTarget.classList.remove("opacity-100", "pointer-events-auto") + this.panelTarget.classList.add("scale-95", "opacity-0") + this.panelTarget.classList.remove("scale-100", "opacity-100") + document.removeEventListener("keydown", this._onKeydown) + } + + closeBackdrop(event) { + if (event.target === this.backdropTarget) this.close() + } + + _onKeydown(event) { + if (event.key === "Escape") this.close() + } +} diff --git a/app/views/pages/landing/_sponsors.html.erb b/app/views/pages/landing/_sponsors.html.erb index 3d40665..51a6ec1 100644 --- a/app/views/pages/landing/_sponsors.html.erb +++ b/app/views/pages/landing/_sponsors.html.erb @@ -5,7 +5,7 @@ placeholder_count = total - 1 - sponsor_count %> -
+
<%= ui_badge("OUR PARTNERS", class: "rotate-2 mb-4") %> @@ -33,5 +33,52 @@

Sponsor Us →

<% end %>
+ + <% if @perks.any? %> + <% + perk_count = @perks.size + perk_total = [((perk_count / 6.0).ceil * 6), 6].max + perk_placeholder_count = perk_total - perk_count + %> +
+

Our perks program partners with companies to bring exclusive deals to our members.

+
+ <% @perks.each do |perk| %> + + <% end %> + + <% perk_placeholder_count.times do |i| %> + <% last = i == perk_placeholder_count - 1 %> +
Your logo here
+ <% end %> +
+ +
+ <% end %> +
+ + <%# Perk detail modal (at section level to avoid transformed ancestor clipping fixed positioning) %> +
+
diff --git a/app/views/pages/sponsorship/_perks.html.erb b/app/views/pages/sponsorship/_perks.html.erb new file mode 100644 index 0000000..81c4afe --- /dev/null +++ b/app/views/pages/sponsorship/_perks.html.erb @@ -0,0 +1,16 @@ +
+
+
+
+ <%= ui_badge("PERKS PROGRAM", variant: :dark, class: "-rotate-1 mb-4") %> +

+ Got something to offer our members? +

+

+ If your company offers a product or service that benefits students, we'd love to feature you in our perks program. + Members get access to exclusive deals, and your brand gets in front of <%= Rails.application.config.meta[:member_count] %> engaged tech students. +

+ <%= ui_button("Get in touch", href: "mailto:#{Rails.application.config.socials[:email]}", variant: :secondary) %> +
+
+
diff --git a/app/views/pages/sponsorship/sponsorship.html.erb b/app/views/pages/sponsorship/sponsorship.html.erb index d83b182..fda19ea 100644 --- a/app/views/pages/sponsorship/sponsorship.html.erb +++ b/app/views/pages/sponsorship/sponsorship.html.erb @@ -2,3 +2,4 @@ <%= render "pages/sponsorship/tiers" %> <%= render "pages/sponsorship/why" %> <%= render "pages/sponsorship/cta" %> +<%= render "pages/sponsorship/perks" %> diff --git a/config/ci.rb b/config/ci.rb index 7922ae9..360e706 100644 --- a/config/ci.rb +++ b/config/ci.rb @@ -6,6 +6,8 @@ step "Tests: Rails", "bin/rails test" step "Tests: Seeds", "env RAILS_ENV=test bin/rails db:seed:replant" + step "Sanity checks", "bin/rails sanity:check" + # Optional: Run system tests # step "Tests: System", "bin/rails test:system" diff --git a/config/sponsors.yml b/config/sponsors.yml index 52c6258..ef02975 100644 --- a/config/sponsors.yml +++ b/config/sponsors.yml @@ -4,3 +4,15 @@ sponsors: [] # tier: Amber # logo: /sponsors/acme.png # website: https://acme.com + +perks: + - name: DataCamp + logo: /sponsors/datacamp.png + icon: /sponsors/datacamp-icon.png + website: https://www.datacamp.com/ + description: "Members get free access to DataCamp's full learning platform, covering Python, R, SQL, and more through hands-on courses and real-world projects." + - name: Red Bull + logo: /sponsors/redbull.png + icon: /sponsors/redbull-icon.png + website: https://www.redbull.com/au-en + description: "Red Bull keeps our members fuelled with free drinks at club events, hackathons, and more." diff --git a/lib/tasks/sanity.rake b/lib/tasks/sanity.rake new file mode 100644 index 0000000..046a98e --- /dev/null +++ b/lib/tasks/sanity.rake @@ -0,0 +1,22 @@ +namespace :sanity do + desc "Run content and config sanity checks" + task check: :environment do + checks_passed = true + + # Perk count must not be a multiple of 6. + # The perks grid uses 2/3/5/6 column breakpoints. A multiple of 6 fills the + # 6-col row but leaves an uneven last row at md:grid-cols-5. When this fires, + # revisit the grid layout in the perks partial. + perks = YAML.load_file(Rails.root.join("config/sponsors.yml")).fetch("perks", []) + perk_count = perks.size + + if perk_count > 0 && (perk_count % 6).zero? + puts "FAIL: Perk count is #{perk_count} (multiple of 6). Revisit the perks grid layout." + checks_passed = false + else + puts "PASS: Perk count is #{perk_count} (not a multiple of 6)." + end + + abort "Sanity checks failed." unless checks_passed + end +end diff --git a/public/sponsors/datacamp-icon.png b/public/sponsors/datacamp-icon.png new file mode 100644 index 0000000..3095b8b Binary files /dev/null and b/public/sponsors/datacamp-icon.png differ diff --git a/public/sponsors/datacamp.png b/public/sponsors/datacamp.png new file mode 100644 index 0000000..056e5bb Binary files /dev/null and b/public/sponsors/datacamp.png differ diff --git a/public/sponsors/redbull-icon.png b/public/sponsors/redbull-icon.png new file mode 100644 index 0000000..c05f3ac Binary files /dev/null and b/public/sponsors/redbull-icon.png differ diff --git a/public/sponsors/redbull.png b/public/sponsors/redbull.png new file mode 100644 index 0000000..88a4d44 Binary files /dev/null and b/public/sponsors/redbull.png differ