diff --git a/app/assets/stylesheets/_interest.scss b/app/assets/stylesheets/_interest.scss new file mode 100644 index 0000000..0515568 --- /dev/null +++ b/app/assets/stylesheets/_interest.scss @@ -0,0 +1,18 @@ +.interest { + margin-top: $base-spacing; +} + +.new_interest { + display: flex; + align-items: stretch; + + .btn { + flex: 0 0 auto; + margin-bottom: $small-spacing; + } + + .email { + flex: 1 0 auto; + margin-right: $small-spacing; + } +} diff --git a/app/assets/stylesheets/_timer.scss b/app/assets/stylesheets/_timer.scss index 2a33de1..e14088b 100644 --- a/app/assets/stylesheets/_timer.scss +++ b/app/assets/stylesheets/_timer.scss @@ -1,5 +1,4 @@ -.timer, -.timer-explanation { +.timer { font-family: 'Source Sans Pro', sans-serif; } diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 71d07ef..117a0c1 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -8,6 +8,7 @@ @import "base/base"; @import "refills/flashes"; +@import "interest"; @import "layout"; @import "left_column"; @import "posts"; diff --git a/app/assets/stylesheets/base/_buttons.scss b/app/assets/stylesheets/base/_buttons.scss index a3d967b..13ab4dc 100644 --- a/app/assets/stylesheets/base/_buttons.scss +++ b/app/assets/stylesheets/base/_buttons.scss @@ -11,7 +11,7 @@ -webkit-font-smoothing: antialiased; font-weight: 600; line-height: 1; - padding: $small-spacing $base-spacing; + padding: 0 $base-spacing; text-align: center; text-decoration: none; transition: background-color $base-duration $base-timing; diff --git a/app/controllers/interests_controller.rb b/app/controllers/interests_controller.rb new file mode 100644 index 0000000..2eaefb4 --- /dev/null +++ b/app/controllers/interests_controller.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +class InterestsController < ApplicationController + def create + @interest = Interest.new(interest_params) + + if @interest.save + redirect_back( + fallback_location: root_path, + notice: t("interest.create.success"), + ) + else + redirect_back( + fallback_location: root_path, + alert: t("interest.create.failure"), + ) + end + end + + private + + def interest_params + params.require(:interest).permit(:email) + end +end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 8728689..addf74c 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,5 +1,9 @@ module ApplicationHelper def expiration_time - Post.order(created_at: :desc).first.created_at + 7.days + if Post.any? + Post.order(created_at: :desc).first.created_at + 7.days + else + Time.current + end end end diff --git a/app/models/interest.rb b/app/models/interest.rb new file mode 100644 index 0000000..3b94226 --- /dev/null +++ b/app/models/interest.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +class Interest < ApplicationRecord + validates :email, presence: true +end diff --git a/app/views/application/_interest.html.erb b/app/views/application/_interest.html.erb new file mode 100644 index 0000000..0a6c672 --- /dev/null +++ b/app/views/application/_interest.html.erb @@ -0,0 +1,14 @@ +
+

Want a self-destructing blog of your own?

+ +

+ Let me know. + If enough people want a blog of their own like this, + I'll turn it into something that anyone can use. +

+ + <%= simple_form_for(@interest || Interest.new) do |form| %> + <%= form.input :email, label: false, placeholder: "Email" %> + <%= form.button :submit %> + <% end %> +
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 9afebcb..49fcca6 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -20,6 +20,7 @@
<%= render "application/timer" %> + <%= render "application/interest" %>
diff --git a/config/locales/en.yml b/config/locales/en.yml index cd03b86..d001836 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -6,6 +6,16 @@ en: with_weekday: "%a %m/%d/%y" + helpers: + submit: + interest: + create: I'll take one, please. + + interest: + create: + success: Thanks for your interest! I'll send you an email if there are any updates. + failure: Damn, that didn't work. Try again? + time: formats: default: diff --git a/config/routes.rb b/config/routes.rb index 3e57383..eee4e99 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,5 +1,6 @@ Rails.application.routes.draw do resources :posts + resources :interests, only: [:create] root to: "posts#index" end diff --git a/db/migrate/20160920004216_create_interests.rb b/db/migrate/20160920004216_create_interests.rb new file mode 100644 index 0000000..4966d67 --- /dev/null +++ b/db/migrate/20160920004216_create_interests.rb @@ -0,0 +1,9 @@ +class CreateInterests < ActiveRecord::Migration[5.0] + def change + create_table :interests do |t| + t.string :email, null: false + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 11bec29..ad23c26 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160909164244) do +ActiveRecord::Schema.define(version: 20160920004216) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -30,6 +30,12 @@ t.index ["priority", "run_at"], name: "delayed_jobs_priority", using: :btree end + create_table "interests", force: :cascade do |t| + t.string "email", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + create_table "posts", force: :cascade do |t| t.string "title" t.string "tags" diff --git a/spec/controllers/posts_controller_spec.rb b/spec/controllers/posts_controller_spec.rb index 7a2dec9..db062e0 100644 --- a/spec/controllers/posts_controller_spec.rb +++ b/spec/controllers/posts_controller_spec.rb @@ -36,37 +36,6 @@ # PostsController. Be sure to keep this updated too. let(:valid_session) { {} } - describe "GET #index" do - it "assigns all posts as @posts" do - post = Post.create! valid_attributes - get :index, params: {}, session: valid_session - expect(assigns(:posts)).to eq([post]) - end - end - - describe "GET #show" do - it "assigns the requested post as @post" do - post = Post.create! valid_attributes - get :show, params: {id: post.to_param}, session: valid_session - expect(assigns(:post)).to eq(post) - end - end - - describe "GET #new" do - it "assigns a new post as @post" do - get :new, params: {}, session: valid_session - expect(assigns(:post)).to be_a_new(Post) - end - end - - describe "GET #edit" do - it "assigns the requested post as @post" do - post = Post.create! valid_attributes - get :edit, params: {id: post.to_param}, session: valid_session - expect(assigns(:post)).to eq(post) - end - end - describe "POST #create" do context "with valid params" do it "creates a new Post" do @@ -75,12 +44,6 @@ }.to change(Post, :count).by(1) end - it "assigns a newly created post as @post" do - post :create, params: {post: valid_attributes}, session: valid_session - expect(assigns(:post)).to be_a(Post) - expect(assigns(:post)).to be_persisted - end - it "redirects to the created post" do post :create, params: {post: valid_attributes}, session: valid_session expect(response).to redirect_to(Post.last) @@ -88,11 +51,6 @@ end context "with invalid params" do - it "assigns a newly created but unsaved post as @post" do - post :create, params: {post: invalid_attributes}, session: valid_session - expect(assigns(:post)).to be_a_new(Post) - end - it "re-renders the 'new' template" do post :create, params: {post: invalid_attributes}, session: valid_session expect(response).to render_template("new") @@ -113,12 +71,6 @@ skip("Add assertions for updated state") end - it "assigns the requested post as @post" do - post = Post.create! valid_attributes - put :update, params: {id: post.to_param, post: valid_attributes}, session: valid_session - expect(assigns(:post)).to eq(post) - end - it "redirects to the post" do post = Post.create! valid_attributes put :update, params: {id: post.to_param, post: valid_attributes}, session: valid_session @@ -127,12 +79,6 @@ end context "with invalid params" do - it "assigns the post as @post" do - post = Post.create! valid_attributes - put :update, params: {id: post.to_param, post: invalid_attributes}, session: valid_session - expect(assigns(:post)).to eq(post) - end - it "re-renders the 'edit' template" do post = Post.create! valid_attributes put :update, params: {id: post.to_param, post: invalid_attributes}, session: valid_session @@ -155,5 +101,4 @@ expect(response).to redirect_to(posts_url) end end - end diff --git a/spec/factories.rb b/spec/factories.rb index 3c3a012..cbf6de8 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -1,4 +1,7 @@ FactoryGirl.define do + factory :interest do + email "MyString" + end factory :post do title "MyString" tags "MyString" diff --git a/spec/features/register_interest_spec.rb b/spec/features/register_interest_spec.rb new file mode 100644 index 0000000..a9ac7d7 --- /dev/null +++ b/spec/features/register_interest_spec.rb @@ -0,0 +1,21 @@ +require "rails_helper" + +feature "Register interest" do + scenario "successfully" do + visit root_path + + fill_in "Email", with: "foo@bar.com" + click_on "I want in." + + expect(page).to have_content t("interest.create.success") + expect(Interest.last.email).to eq("foo@bar.com") + end + + scenario "unsuccessfully" do + visit root_path + + click_on "I want in." + + expect(page).to have_content t("interest.create.failure") + end +end diff --git a/spec/models/interest_spec.rb b/spec/models/interest_spec.rb new file mode 100644 index 0000000..498269f --- /dev/null +++ b/spec/models/interest_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe Interest, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end