Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dl/add waiting list #102

Merged
merged 2 commits into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
20 changes: 20 additions & 0 deletions app/controllers/waiting_lists_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# app/controllers/waiting_lists_controller.rb
class WaitingListsController < ApplicationController
def create
@waiting_list = WaitingList.new(waiting_list_params)

if @waiting_list.save
flash[:notice] = "Thanks for joining our waiting list!"
else
error_message = @waiting_list.errors.full_messages.to_sentence
flash[:alert] = "There was an error: #{error_message}"
end
redirect_to root_path
end

private

def waiting_list_params
params.require(:waiting_list).permit(:email)
end
end
2 changes: 2 additions & 0 deletions app/helpers/waiting_lists_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
module WaitingListsHelper
end
8 changes: 8 additions & 0 deletions app/jobs/send_waiting_list_report_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# app/jobs/send_waiting_list_report_job.rb
class SendWaitingListReportJob < ApplicationJob
queue_as :default

def perform
WaitingListMailer.daily_report('[email protected]').deliver_now
end
end
13 changes: 13 additions & 0 deletions app/mailers/waiting_list_mailer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# app/mailers/waiting_list_mailer.rb
class WaitingListMailer < ApplicationMailer
default from: '[email protected]'

def daily_report(email)
@waiting_list = WaitingList.all
@total_count = @waiting_list.count
@today_count = @waiting_list.where('created_at >= ?', Time.zone.now.beginning_of_day).count
@url = 'https://linkarooie.com'

mail(to: email, subject: 'Daily Waiting List Report - Linkarooie')
end
end
6 changes: 6 additions & 0 deletions app/models/waiting_list.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# app/models/waiting_list.rb
class WaitingList < ApplicationRecord
validates :email, presence: true,
uniqueness: { case_sensitive: false },
format: { with: URI::MailTo::EMAIL_REGEXP }
end
2 changes: 1 addition & 1 deletion app/views/layouts/application.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@

<body class="bg-gray-900 text-white">
<header class="bg-gray-800 shadow relative">
<div class="absolute top-0 right-0 mt-2 mr-2">
<div class="absolute top-0 right-0 mt-2 mr-2 z-50">
<% if notice %>
<div class="bg-green-100 border-l-4 border-green-500 text-green-700 p-4 relative" role="alert">
<p class="font-bold">Notice:</p>
Expand Down
14 changes: 14 additions & 0 deletions app/views/pages/home.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,20 @@
</div>
</section>

<!-- Waiting List Form Section -->
<section class="py-16 text-white w-full">
<div class="text-center">
<h2 class="text-3xl font-bold mb-4">Join Our Waiting List</h2>
<p class="text-lg mb-8">
Be the first to know when Linkarooie is available. Enter your email to join our waiting list!
</p>
<%= form_with model: WaitingList.new, url: waiting_lists_path, local: true, class: "flex flex-col items-center w-full max-w-md mx-auto" do |form| %>
<%= form.email_field :email, placeholder: "Enter your email", class: "p-2 w-full rounded bg-gray-700 text-white focus:outline-none focus:ring-2 focus:ring-lime-400 mb-4" %>
<%= form.submit "Join Now", class: "w-full bg-lime-500 hover:bg-lime-600 text-white font-bold py-2 px-4 rounded cursor-pointer transition duration-300" %>
<% end %>
</div>
</section>

<!-- New Feature-Rich Platform Section -->
<section class="py-8 w-full bg-gray-900 text-center">
<div class="max-w-2xl mx-auto">
Expand Down
63 changes: 63 additions & 0 deletions app/views/waiting_list_mailer/daily_report.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<!-- app/views/waiting_list_mailer/daily_report.html.erb -->
<!DOCTYPE html>
<html>
<head>
<meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
<style>
body {
font-family: Arial, sans-serif;
line-height: 1.6;
color: #333;
}
.container {
max-width: 600px;
margin: 0 auto;
padding: 20px;
}
h1 {
color: #4a5568;
}
.stats {
background-color: #f0fff4;
border: 1px solid #9ae6b4;
border-radius: 5px;
padding: 15px;
margin-bottom: 20px;
}
ul {
list-style-type: none;
padding-left: 0;
}
li {
margin-bottom: 10px;
}
.footer {
margin-top: 30px;
font-size: 0.9em;
color: #718096;
}
</style>
</head>
<body>
<div class="container">
<h1>Daily Waiting List Report - Linkarooie</h1>

<div class="stats">
<p><strong>Total subscribers:</strong> <%= @total_count %></p>
<p><strong>New subscribers today:</strong> <%= @today_count %></p>
</div>

<h2>All Subscribers:</h2>
<ul>
<% @waiting_list.each do |subscriber| %>
<li><%= subscriber.email %> (joined: <%= subscriber.created_at.strftime('%B %d, %Y') %>)</li>
<% end %>
</ul>

<div class="footer">
<p>Visit Linkarooie at: <a href="<%= @url %>"><%= @url %></a></p>
<p>This is an automated message from Linkarooie. Please do not reply to this email.</p>
</div>
</div>
</body>
</html>
2 changes: 2 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
# Health check route
get 'up' => 'rails/health#show', as: :rails_health_check

resources :waiting_lists, only: [:create]

# Root route
root to: 'pages#home'

Expand Down
4 changes: 4 additions & 0 deletions config/sidekiq_scheduler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@ aggregate_metrics:
backup_database:
cron: '0 2 * * *' # Runs daily at 2 AM
class: BackupDatabaseJob

send_waiting_list_report:
cron: '0 3 * * *' # Runs daily at 3 AM
class: SendWaitingListReportJob
9 changes: 9 additions & 0 deletions db/migrate/20240904121238_create_waiting_lists.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class CreateWaitingLists < ActiveRecord::Migration[7.1]
def change
create_table :waiting_lists do |t|
t.string :email

t.timestamps
end
end
end
8 changes: 7 additions & 1 deletion db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

50 changes: 50 additions & 0 deletions spec/controllers/waiting_lists_controller_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# spec/controllers/waiting_lists_controller_spec.rb
require 'rails_helper'

RSpec.describe WaitingListsController, type: :controller do
describe "POST #create" do
context "with valid params" do
it "creates a new WaitingList" do
expect {
post :create, params: { waiting_list: attributes_for(:waiting_list) }
}.to change(WaitingList, :count).by(1)
end

it "redirects to the root path with a success notice" do
post :create, params: { waiting_list: attributes_for(:waiting_list) }
expect(response).to redirect_to(root_path)
expect(flash[:notice]).to eq("Thanks for joining our waiting list!")
end
end

context "with invalid params" do
it "does not create a new WaitingList" do
expect {
post :create, params: { waiting_list: { email: "invalid_email" } }
}.to_not change(WaitingList, :count)
end

it "redirects to the root path with an error alert" do
post :create, params: { waiting_list: { email: "invalid_email" } }
expect(response).to redirect_to(root_path)
expect(flash[:alert]).to include("There was an error")
end
end

context "with duplicate email" do
before { create(:waiting_list, email: "[email protected]") }

it "does not create a new WaitingList" do
expect {
post :create, params: { waiting_list: { email: "[email protected]" } }
}.to_not change(WaitingList, :count)
end

it "redirects to the root path with an error alert" do
post :create, params: { waiting_list: { email: "[email protected]" } }
expect(response).to redirect_to(root_path)
expect(flash[:alert]).to include("Email has already been taken")
end
end
end
end
6 changes: 6 additions & 0 deletions spec/factories/waiting_lists.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# spec/factories/waiting_lists.rb
FactoryBot.define do
factory :waiting_list do
sequence(:email) { |n| "user#{n}@example.com" }
end
end
6 changes: 6 additions & 0 deletions spec/helpers/waiting_lists_helper_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# spec/helpers/waiting_lists_helper_spec.rb
require 'rails_helper'

RSpec.describe WaitingListsHelper, type: :helper do
# Add helper specs here if you create any helper methods in the future
end
26 changes: 26 additions & 0 deletions spec/models/waiting_list_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# spec/models/waiting_list_spec.rb
require 'rails_helper'

RSpec.describe WaitingList, type: :model do
it "has a valid factory" do
expect(build(:waiting_list)).to be_valid
end

describe "validations" do
it { should validate_presence_of(:email) }
it { should validate_uniqueness_of(:email).case_insensitive }

it "validates email format" do
valid_emails = ["[email protected]", "[email protected]", "[email protected]"]
invalid_emails = ["user@example,com", "user_at_foo.org", "user.name@example.", "foo@bar_baz.com", "foo@bar+baz.com"]

valid_emails.each do |email|
expect(build(:waiting_list, email: email)).to be_valid
end

invalid_emails.each do |email|
expect(build(:waiting_list, email: email)).to be_invalid
end
end
end
end
44 changes: 44 additions & 0 deletions spec/requests/waiting_lists_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# spec/requests/waiting_lists_spec.rb
require 'rails_helper'

RSpec.describe "WaitingLists", type: :request do
describe "POST /waiting_lists" do
context "with valid parameters" do
it "creates a new waiting list entry" do
expect {
post waiting_lists_path, params: { waiting_list: { email: "[email protected]" } }
}.to change(WaitingList, :count).by(1)

expect(response).to redirect_to(root_path)
follow_redirect!
expect(response.body).to include("Thanks for joining our waiting list!")
end
end

context "with invalid parameters" do
it "does not create a new waiting list entry" do
expect {
post waiting_lists_path, params: { waiting_list: { email: "invalid_email" } }
}.not_to change(WaitingList, :count)

expect(response).to redirect_to(root_path)
follow_redirect!
expect(response.body).to include("There was an error")
end
end

context "with duplicate email" do
before { WaitingList.create(email: "[email protected]") }

it "does not create a new waiting list entry" do
expect {
post waiting_lists_path, params: { waiting_list: { email: "[email protected]" } }
}.not_to change(WaitingList, :count)

expect(response).to redirect_to(root_path)
follow_redirect!
expect(response.body).to include("Email has already been taken")
end
end
end
end
Loading