Setup RSVP model

This commit is contained in:
Max Wofford 2025-05-07 23:07:54 -04:00
parent 5e4e5313d4
commit 6dda3f4f52
13 changed files with 97 additions and 53 deletions

View file

@ -77,3 +77,6 @@ gem "letter_opener_web", group: :development
gem "rails_live_reload"
gem "awesome_print", "~> 1.9"
# Environment variables
gem "dotenv-rails", groups: [:development, :test]

View file

@ -109,6 +109,9 @@ GEM
irb (~> 1.10)
reline (>= 0.3.8)
dotenv (3.1.8)
dotenv-rails (3.1.8)
dotenv (= 3.1.8)
railties (>= 6.1)
drb (2.2.1)
ed25519 (1.3.0)
erubi (1.13.1)
@ -440,6 +443,7 @@ DEPENDENCIES
capybara
debug
dotenv
dotenv-rails
image_processing (~> 1.2)
importmap-rails
jbuilder

View file

@ -1,5 +1,4 @@
class LandingController < ApplicationController
def index
@authenticated = current_user.present?
end
end
end

View file

@ -0,0 +1,16 @@
class RsvpsController < ApplicationController
def create
@rsvp = Rsvp.find_or_create_by_email!(rsvp_params[:email])
flash[:success] = "Thanks for your interest! We'll be in touch soon."
redirect_to root_path
rescue ActiveRecord::RecordInvalid
flash[:error] = "Please enter a valid email address."
redirect_to root_path
end
private
def rsvp_params
params.permit(:email)
end
end

View file

@ -1,26 +1,2 @@
class SessionsController < ApplicationController
def new
puts "😺"
end
def create
email = params[:email].downcase
user = User.find_or_create_by(email: email)
user.update!(login_code: "%06d" % rand(6 ** 6), login_code_expires_at: 1.hour.from_now)
SessionMailer.login_code(email: email, login_code: user.login_code).deliver_now
end
def exchange_code
user = User.find_by(login_code: params[:code], login_code_expires_at: Time.current..)
if user
session[:user_id] = user.id
redirect_to root_path, notice: "congrats"
@authenticated = true
else # no user
redirect_to root_path, alert: "no"
end
end
end
end

7
app/models/rsvp.rb Normal file
View file

@ -0,0 +1,7 @@
class Rsvp < ApplicationRecord
validates :email, presence: true, uniqueness: true, format: { with: URI::MailTo::EMAIL_REGEXP }
def self.find_or_create_by_email!(email)
find_or_create_by!(email: email.downcase.strip)
end
end

View file

@ -6,18 +6,26 @@
<div class="landing-text-container">
<%= image_tag "landing/landinglogo.png", style: "width: 100%;" %>
<% if @authenticated %>
<%= link_to "you're currently signed in; click here to enter the highway!", posts_path, class: "bg-[#544FFF] p-4 px-8 rounded border-2 border-white" %>
<% else %>
<div class="landing-input-container">
<%= form_with url: signin_path, method: :post, local: true do |form| %>
<div class="border-4 border-[#544FFF] rounded-lg flex items-center max-w-md justify-center items-center">
<%= form.text_field :email, placeholder: "Enter your email", class: "landing-input bg-white text-black px-4 py-2 flex-grow" %>
<%= form.submit "→", class: "landing-button bg-[#544FFF] text-white px-4 py-2 font-bold" %>
</div>
<% end %>
<% if flash[:notice] %>
<div class="bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded relative mb-4" role="alert">
<span class="block sm:inline"><%= flash[:notice] %></span>
</div>
<% end %>
<% if flash[:alert] %>
<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative mb-4" role="alert">
<span class="block sm:inline"><%= flash[:alert] %></span>
</div>
<% end %>
<div class="landing-input-container">
<%= form_with url: rsvp_path, method: :post, local: true do |form| %>
<div class="border-4 border-[#544FFF] rounded-lg flex items-center max-w-md justify-center items-center">
<%= form.text_field :email, placeholder: "Enter your email", class: "landing-input bg-white text-black px-4 py-2 flex-grow" %>
<%= form.submit "→", class: "landing-button bg-[#544FFF] text-white px-4 py-2 font-bold" %>
</div>
<% end %>
</div>
</div>
<%= image_tag "landing/tracks1.png", class: "w-full -mt-8" %>
@ -118,16 +126,12 @@
<p class="text-3xl font-bold">By the way, free stickers when you sign up!</p>
</div>
<div class="flex justify-center items-center mt-4">
<% if @authenticated %>
<%= link_to "you're currently signed in; click here to enter the highway!", posts_path, class: "bg-[#544FFF] p-4 px-8 rounded border-2 border-white" %>
<% else %>
<div class="landing-input-container">
<%= form_with url: signin_path, method: :post, local: true do |form| %>
<%= form.text_field :email, placeholder: "Enter your email", class: "landing-input" %>
<%= form.submit "Enter", class: "landing-button" %>
<% end %>
</div>
<% end %>
<div class="landing-input-container">
<%= form_with url: signin_path, method: :post, local: true do |form| %>
<%= form.text_field :email, placeholder: "Enter your email", class: "landing-input" %>
<%= form.submit "Enter", class: "landing-button" %>
<% end %>
</div>
</div>
</div>
@ -223,9 +227,9 @@
<div class="grid xl:grid-cols-3 md:grid-cols-2 grid-cols-1 gap-4 mx-24 my-8 mx-auto">
<%= render partial: "card", locals: { title: "Eligibility", content: "Anyone 18 or below in high school is welcome! If you're in middle school or a gap year student, check in with us at [email]. You will need to verify with ID when we send you your grant!" } %>
<%= render partial: "card", locals: { title: "Are teams allowed for Highway projects?", content: "You are free to make the hardware project with a friend! However, you both need to make posts, and the grant will be shared between you two." } %>
<%= render partial: "card", locals: { title: "Who's running this?", content: "A group of ~15 teenagers around the world! Were funded by Hack Club, a [503 non-profit who have had donations from x, y, z]." } %>
<%= render partial: "card", locals: { title: "I'm new to hardware, can I join?", content: "Highway is for makers of all skill levels! We have a bunch of tutorials to follow if its your first time - from making your own [macropad], to [x], to [y]. No worries if this is your first time!" } %>
<%= render partial: "card", locals: { title: "Is this legit?", content: "Yup! Last summer, we ran [Arcade], and last winter, we ran [High Seas], both sponsored by GitHub. As for hackathons, weve run [apocalypse, boreal, outernet, scrapyard, juice etc!]" } %>
<%= render partial: "card", locals: { title: "Who's running this?", content: "A group of ~15 teenagers around the world! We're funded by Hack Club, a [503 non-profit who have had donations from x, y, z]." } %>
<%= render partial: "card", locals: { title: "I'm new to hardware, can I join?", content: "Highway is for makers of all skill levels! We have a bunch of tutorials to follow if it's your first time - from making your own [macropad], to [x], to [y]. No worries if this is your first time!" } %>
<%= render partial: "card", locals: { title: "Is this legit?", content: "Yup! Last summer, we ran [Arcade], and last winter, we ran [High Seas], both sponsored by GitHub. As for hackathons, we've run [apocalypse, boreal, outernet, scrapyard, juice etc!]" } %>
<%= render partial: "card", locals: { title: "I need help!", content: "Read the expanded FAQ of our site [here]. Feel free to also ask in #highway-help in the Hack Club Slack!" } %>
</div>

View file

@ -6,10 +6,10 @@ require "rails/all"
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
module Site
module Highway
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 8.0
config.load_defaults 7.1
# Please, add to the `ignore` list any other `lib` subdirectories that do
# not contain `.rb` files, or that should not be reloaded or eager loaded.
@ -23,5 +23,8 @@ module Site
#
# config.time_zone = "Central Time (US & Canada)"
# config.eager_load_paths << Rails.root.join("extras")
# Set secret_key_base from environment variable
config.secret_key_base = ENV["SECRET_KEY_BASE"]
end
end

View file

@ -31,6 +31,7 @@ Rails.application.routes.draw do
post "/signin", to: "sessions#create", as: :signin
get "/auth/code/:code", to: "sessions#exchange_code", as: :exchange_code
post "/rsvp", to: "rsvps#create", as: :rsvp
if Rails.env.development?
mount LetterOpenerWeb::Engine, at: "/letter_opener"

View file

@ -0,0 +1,10 @@
class CreateRsvps < ActiveRecord::Migration[8.0]
def change
create_table :rsvps do |t|
t.string :email
t.timestamps
end
add_index :rsvps, :email, unique: true
end
end

9
db/schema.rb generated
View file

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[8.0].define(version: 2025_05_08_022535) do
ActiveRecord::Schema[8.0].define(version: 2025_05_08_025519) do
create_table "action_text_rich_texts", force: :cascade do |t|
t.string "name", null: false
t.text "body"
@ -49,6 +49,13 @@ ActiveRecord::Schema[8.0].define(version: 2025_05_08_022535) do
t.index ["blob_id", "variation_digest"], name: "index_active_storage_variant_records_uniqueness", unique: true
end
create_table "rsvps", force: :cascade do |t|
t.string "email"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["email"], name: "index_rsvps_on_email", unique: true
end
create_table "users", force: :cascade do |t|
t.string "email"
t.string "login_code"

7
test/fixtures/rsvps.yml vendored Normal file
View file

@ -0,0 +1,7 @@
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
one:
email: MyString
two:
email: MyString

7
test/models/rsvp_test.rb Normal file
View file

@ -0,0 +1,7 @@
require "test_helper"
class RsvpTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
end