Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
0c8df7d
Add perks data and logos for DataCamp and Red Bull
williamjaackson Mar 22, 2026
4f08932
Load perks data from sponsors config in controller
williamjaackson Mar 22, 2026
065e9be
Add member perks section below sponsors grid
williamjaackson Mar 22, 2026
785001f
Add descriptions to DataCamp and Red Bull perks
williamjaackson Mar 22, 2026
8c43001
Add perk modal Stimulus controller
williamjaackson Mar 22, 2026
a2f7d93
Wire perk cards to modal and render modal markup in sponsors partial
williamjaackson Mar 22, 2026
c3a2fa8
Move perk modal to section level and left-align content
williamjaackson Mar 22, 2026
6b51cf0
Tweak perk descriptions and rename modal button to Check it out
williamjaackson Mar 22, 2026
8e653bd
Update Red Bull description wording
williamjaackson Mar 22, 2026
b6e7fc9
Use icon logos in perk modal instead of full logos
williamjaackson Mar 22, 2026
143d86f
Add perks program section to sponsorship page
williamjaackson Mar 22, 2026
14e3b67
Restyle perks program as bold red insert card and fix 500++ typo
williamjaackson Mar 22, 2026
cb6a7a3
Move perks program section below ready to partner CTA
williamjaackson Mar 22, 2026
28c07f3
Link perk placeholder cards to sponsorship perks program section
williamjaackson Mar 22, 2026
b35b188
Revert placeholder cards back to plain divs
williamjaackson Mar 22, 2026
1d2a1bb
Add perks program link to perks intro text
williamjaackson Mar 22, 2026
d6d2e94
Reword perks intro to mention perks program with inline link
williamjaackson Mar 22, 2026
a0e1dc7
Add perks program link to footer resources column
williamjaackson Mar 22, 2026
1cb4d29
Add perks program link to navbar sponsors dropdown
williamjaackson Mar 22, 2026
4f7ef48
Make perk placeholders responsive to fill rows at each breakpoint
williamjaackson Mar 22, 2026
7f7fa67
Switch perks grid to 2/3/6 columns so one placeholder count fills all…
williamjaackson Mar 22, 2026
feb5109
Move perks 6-column grid to lg breakpoint to avoid cramping at md
williamjaackson Mar 22, 2026
3394adb
Add md:grid-cols-5 breakpoint and hide last placeholder at md
williamjaackson Mar 22, 2026
9f28457
Add sanity:check rake task to catch problematic perk counts
williamjaackson Mar 22, 2026
1519321
Add GitHub Actions workflow to run sanity checks on PRs
williamjaackson Mar 22, 2026
2a0a616
Add sanity checks step to local CI
williamjaackson Mar 22, 2026
48f2d7c
Move static 'Check it out' text from JS into the modal markup
williamjaackson Mar 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions app/components/site/footer_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
]
Expand Down
3 changes: 2 additions & 1 deletion app/components/site/navbar/component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
4 changes: 3 additions & 1 deletion app/controllers/pages_controller.rb
Original file line number Diff line number Diff line change
@@ -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

Expand Down
42 changes: 42 additions & 0 deletions app/javascript/controllers/perk_modal_controller.js
Original file line number Diff line number Diff line change
@@ -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()
}
}
49 changes: 48 additions & 1 deletion app/views/pages/landing/_sponsors.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
placeholder_count = total - 1 - sponsor_count
%>

<section id="sponsors" class="py-24 md:py-32 px-6 border-t-3 border-brand-black bg-brand-cream" data-controller="reveal">
<section id="sponsors" class="py-24 md:py-32 px-6 border-t-3 border-brand-black bg-brand-cream" data-controller="reveal perk-modal">
<div class="max-w-6xl mx-auto">
<div class="mb-16 reveal-up" data-reveal-target="item">
<%= ui_badge("OUR PARTNERS", class: "rotate-2 mb-4") %>
Expand Down Expand Up @@ -33,5 +33,52 @@
<p class="text-white font-bold">Sponsor Us &rarr;</p>
<% end %>
</div>

<% if @perks.any? %>
<%
perk_count = @perks.size
perk_total = [((perk_count / 6.0).ceil * 6), 6].max
perk_placeholder_count = perk_total - perk_count
%>
<div class="mt-16 reveal-up" data-reveal-target="item" style="transition-delay: 200ms;">
<p class="text-brand-gray text-base mb-6">Our <a href="/sponsorship#perks-program" class="text-brand-red font-bold hover:underline">perks program</a> partners with companies to bring exclusive deals to our members.</p>
<div class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-5 lg:grid-cols-6 gap-4">
<% @perks.each do |perk| %>
<button type="button"
class="group flex items-center justify-center relative border-3 border-brand-black bg-white !p-3 h-20 overflow-visible cursor-pointer transition-all duration-200 hover:-translate-y-1 hover:shadow-[5px_5px_0px_var(--color-brand-red)] active:translate-y-0 active:shadow-none"
data-action="perk-modal#open"
data-perk-name="<%= perk["name"] %>"
data-perk-icon="<%= perk["icon"] %>"
data-perk-description="<%= perk["description"] %>"
data-perk-website="<%= perk["website"] %>">
<%= image_tag perk["logo"], alt: perk["name"], class: "max-h-10 max-w-full object-contain" %>
<%= ui_badge(perk["name"].upcase, size: :sm, variant: :dark, class: "absolute -bottom-4 left-1/2 -translate-x-1/2 whitespace-nowrap opacity-0 group-hover:opacity-100 transition-opacity") %>
</button>
<% end %>

<% perk_placeholder_count.times do |i| %>
<% last = i == perk_placeholder_count - 1 %>
<div class="flex items-center justify-center h-20 bg-white border-3 border-dashed border-brand-black/30 text-brand-gray/40 text-sm font-bold<%= ' md:hidden lg:flex' if last %>">Your logo here</div>
<% end %>
</div>

</div>
<% end %>
</div>

<%# Perk detail modal (at section level to avoid transformed ancestor clipping fixed positioning) %>
<div data-perk-modal-target="backdrop" data-action="click->perk-modal#closeBackdrop"
class="fixed inset-0 z-50 bg-brand-black/50 flex items-center justify-center px-6 opacity-0 pointer-events-none transition-opacity duration-300">
<div data-perk-modal-target="panel"
class="bg-brand-bg border-3 border-brand-black shadow-[6px_6px_0px_var(--color-brand-black)] w-full max-w-md p-8 scale-95 opacity-0 transition-all duration-300">
<img data-perk-modal-target="icon" src="" alt="" class="max-h-16 object-contain mb-4">
<h2 data-perk-modal-target="name" class="text-2xl font-bold text-brand-black mb-3" style="font-family: 'Unbounded', sans-serif;"></h2>
<p data-perk-modal-target="description" class="text-brand-gray leading-relaxed mb-6"></p>
<a data-perk-modal-target="link" href="#" target="_blank" rel="noopener"
class="inline-flex items-center justify-center text-center font-bold border-3 border-brand-black bg-brand-red text-white px-8 py-4 text-base cursor-pointer transition-all duration-200 hover:-translate-y-1 hover:shadow-[5px_5px_0px_var(--color-brand-black)] active:translate-y-0 active:shadow-none"
style="font-family: 'Unbounded', sans-serif; font-weight: 600;">
Check it out
</a>
</div>
</div>
</section>
16 changes: 16 additions & 0 deletions app/views/pages/sponsorship/_perks.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<section id="perks-program" class="py-16 md:py-20 px-6 border-t-3 border-brand-black" data-controller="reveal">
<div class="max-w-6xl mx-auto reveal-up" data-reveal-target="item">
<div class="border-3 border-brand-black bg-brand-red p-10 md:p-14 shadow-[6px_6px_0px_var(--color-brand-black)] relative overflow-hidden">
<div class="absolute top-0 right-0 w-48 h-48 bg-white/5 -translate-y-1/2 translate-x-1/2 rotate-12"></div>
<%= ui_badge("PERKS PROGRAM", variant: :dark, class: "-rotate-1 mb-4") %>
<h2 class="text-2xl md:text-3xl font-extrabold text-white mb-4" style="font-family: 'Unbounded', sans-serif;">
Got something to offer our members?
</h2>
<p class="text-white/80 text-lg max-w-2xl leading-relaxed mb-8">
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.
</p>
<%= ui_button("Get in touch", href: "mailto:#{Rails.application.config.socials[:email]}", variant: :secondary) %>
</div>
</div>
</section>
1 change: 1 addition & 0 deletions app/views/pages/sponsorship/sponsorship.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
<%= render "pages/sponsorship/tiers" %>
<%= render "pages/sponsorship/why" %>
<%= render "pages/sponsorship/cta" %>
<%= render "pages/sponsorship/perks" %>
2 changes: 2 additions & 0 deletions config/ci.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down
12 changes: 12 additions & 0 deletions config/sponsors.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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."
22 changes: 22 additions & 0 deletions lib/tasks/sanity.rake
Original file line number Diff line number Diff line change
@@ -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
Binary file added public/sponsors/datacamp-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/sponsors/datacamp.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/sponsors/redbull-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/sponsors/redbull.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading