Commit 3f0dc37

mo khan <mo@mokhan.ca>
2021-05-06 03:49:49
feat: create sparkles controller
1 parent eff8b63
app/controllers/sparkles_controller.rb
@@ -0,0 +1,8 @@
+class SparklesController < ApplicationController
+  def index
+    @sparkles = Sparkle.recent.limit(50)
+  end
+
+  def create
+  end
+end
app/controllers/users_controller.rb
@@ -1,33 +1,6 @@
 class UsersController < ApplicationController
-  # GET /users
-  def index
-    @users = User.all
-  end
-
   # GET /users/1
   def show
     @user = User.find(params[:id])
   end
-
-  # GET /users/new
-  def new
-    @user = User.new
-  end
-
-  # POST /users
-  def create
-    @user = User.new(user_params)
-
-    if @user.save
-      redirect_to @user, notice: 'User was successfully created.'
-    else
-      render :new
-    end
-  end
-
-  private
-
-  def user_params
-    params.require(:user).permit(:handle)
-  end
 end
app/javascript/fonts/Alliance-No-1-Bold.woff
Binary file
app/javascript/fonts/Alliance-No-1-ExtraBold.woff
Binary file
app/javascript/fonts/Alliance-No-1-Italic.woff
Binary file
app/javascript/fonts/Alliance-No-1-Regular.woff
Binary file
app/javascript/fonts/Alliance-No-1-SemiBold.woff
Binary file
app/javascript/styles/sparkles/header.scss
@@ -0,0 +1,79 @@
+.octicon-search {
+  position: absolute;
+  top: 7px;
+  left: 8px;
+}
+
+.header-link {
+  font-weight: $font-weight-bold;
+  color: var(--color-text-white);
+  white-space: nowrap;
+
+  &:hover,
+  &:focus {
+    color: var(--color-text-white);
+    text-decoration: none;
+  }
+}
+
+.hero {
+  background: linear-gradient(114.95deg, #24292E 30.38%, #781084 120.55%);
+  clip-path: polygon(0 0, 100% 0, 100% 100%, 0 85%);
+  padding: 96px 0 200px 0;
+
+  .hero__calloutPrimary {
+    font-family: "Alliance No.1";
+    font-size: 72px;
+    font-weight: $font-weight-bold;
+    letter-spacing: -2px;
+    line-height: 72px;
+  }
+
+  .hero__calloutSecondary {
+    font-family: "Alliance No.1";
+    opacity: 0.6;
+   }
+
+  .hero-sparkle-label {
+    position: absolute;
+    top: 10px;
+    left: 20px;
+
+    @include breakpoint(sm) {
+      top: 14px;
+    }
+  }
+
+  .hero-sparkle-input {
+    padding-left: 78px;
+  }
+}
+
+.header-brand-icon-bg {
+    display: inline-block;
+    width: 32px;
+    height: 32px;
+    border-radius: 50%;
+    background: linear-gradient(152deg, #ff7300, #dc00ff, #008cff);
+    background-size: 600% 600%;
+
+    -webkit-animation: HeaderBrandBackgroundAnimation 15s ease infinite;
+    -moz-animation: HeaderBrandBackgroundAnimation 15s ease infinite;
+    animation: HeaderBrandBackgroundAnimation 15s ease infinite;
+}
+
+@-webkit-keyframes HeaderBrandBackgroundAnimation {
+    0%{background-position:14% 0%}
+    50%{background-position:87% 100%}
+    100%{background-position:14% 0%}
+}
+@-moz-keyframes HeaderBrandBackgroundAnimation {
+    0%{background-position:14% 0%}
+    50%{background-position:87% 100%}
+    100%{background-position:14% 0%}
+}
+@keyframes HeaderBrandBackgroundAnimation {
+    0%{background-position:14% 0%}
+    50%{background-position:87% 100%}
+    100%{background-position:14% 0%}
+}
app/javascript/styles/variables/colours.scss
@@ -1,4 +1,3 @@
-
 // stylelint-disable primer/no-unused-vars
 
 // Immutable (static) color system
app/javascript/styles/application.scss
@@ -1,3 +1,4 @@
+@import "variables/colours.scss";
 @import "@primer/css/alerts/index.scss";
 @import "@primer/css/avatars/index.scss";
 @import "@primer/css/blankslate/index.scss";
@@ -12,3 +13,36 @@
 @import "@primer/css/timeline/index.scss";
 @import "@primer/css/utilities/index.scss";
 @import "@primer/octicons/index.scss";
+@import "sparkles/header.scss";
+
+@font-face {
+  font-family: "Alliance No.1";
+  font-style: normal;
+  font-weight: $font-weight-normal;
+  src: url("../fonts/Alliance-No-1-Regular.woff") format("woff");
+  font-display: swap;
+}
+
+@font-face {
+  font-family: "Alliance No.1";
+  font-style: italic;
+  font-weight: $font-weight-normal;
+  src: url("../fonts/Alliance-No-1-Italic.woff") format("woff");
+  font-display: swap;
+}
+
+@font-face {
+  font-family: "Alliance No.1";
+  font-style: normal;
+  font-weight: $font-weight-semibold;
+  src: url("../fonts/Alliance-No-1-SemiBold.woff") format("woff");
+  font-display: swap;
+}
+
+@font-face {
+  font-family: "Alliance No.1";
+  font-style: normal;
+  font-weight: $font-weight-bold;
+  src: url("../fonts/Alliance-No-1-Bold.woff") format("woff");
+  font-display: swap;
+}
app/models/sparkle.rb
@@ -0,0 +1,9 @@
+class Sparkle < ApplicationRecord
+  belongs_to :sparkler, class_name: 'User'
+  belongs_to :sparklee, class_name: 'User'
+
+  validates :reason, length: { maximum: 255 }, allow_blank: true
+  validates :sparkler, :sparklee, presence: true
+
+  scope :recent, ->() { order(created_at: :desc) }
+end
app/views/sparkles/_index.html.erb
@@ -0,0 +1,26 @@
+
+<div class="d-flex flex-column flex-items-start js-flash-messages">
+  <% if flash[:sparkle_messages] %>
+    <div class="flash flash-success col-12 d-flex flex-column flex-justify-start flex-content-stretch my-4" data-flash-notice>
+      <% flash[:sparkle_messages].each do |message| %>
+        <%= content_tag(:p, message) %>
+      <% end %>
+    </div>
+  <% end %>
+</div>
+
+<div class="pagehead">
+  <h1 class="f2">Recent sparkles</h1>
+</div>
+
+<div class="col-12 d-flex flex-column flex-justify-start flex-content-stretch mt-4 js-sparkle-list-container">
+  <% if sparkles.any? %>
+    <%= render sparkles %>
+    <%= render "shared/pagination", collection: sparkles %>
+  <% else %>
+    <div class="blankslate">
+      <h3 class="mb-1">No sparkles yet.</h3>
+      <p>Hop on Slack and sparkle someone!</p>
+    </div>
+  <% end %>
+</div>
app/views/sparkles/index.html.erb
@@ -0,0 +1,30 @@
+<div class="hero p-responsive">
+  <div class="container-lg">
+    <p class="hero__calloutPrimary text-white text-shadow-dark mb-3">Show your gratitude</p>
+    <p class="hero__calloutSecondary f2-light text-white mb-4">Sparkle  ✨ your fellow hubbers to let them know you appreciate their work.</p>
+
+    <%= form_with url: sparkles_path, class: "d-flex position-relative flex-column flex-sm-row" do |form| %>
+      <%= form.label :body, "/sparkle", class: "hero-sparkle-label" %>
+
+      <%= form.text_field :body,
+        aria: { label: "large input" },
+        autocapitalize: false,
+        autocomplete: false,
+        autocorrect: false,
+        class: "hero-sparkle-input form-control flex-1 pt-2 pb-2",
+        placeholder: "kirsty for volunteering to help!",
+        spellcheck: false
+      %>
+
+    <div class="f4 mt-2 mt-sm-0">
+      <button type="submit" class="btn btn-primary btn-large ml-sm-2 d-block width-full">
+        ✨ Sparkle
+      </button>
+    </div>
+  <% end %>
+  </div>
+</div>
+
+<div class="container-lg p-responsive js-sparkle-index-root">
+  <%= render partial: "index", locals: { sparkles: @sparkles } %>
+</div>
app/views/users/_form.html.erb
@@ -1,22 +0,0 @@
-<%= form_with(model: user) do |form| %>
-  <% if user.errors.any? %>
-    <div id="error_explanation">
-      <h2><%= pluralize(user.errors.count, "error") %> prohibited this user from being saved:</h2>
-
-      <ul>
-        <% user.errors.each do |error| %>
-          <li><%= error.full_message %></li>
-        <% end %>
-      </ul>
-    </div>
-  <% end %>
-
-  <div class="field">
-    <%= form.label :handle %>
-    <%= form.text_field :handle %>
-  </div>
-
-  <div class="actions">
-    <%= form.submit %>
-  </div>
-<% end %>
app/views/users/index.html.erb
@@ -1,19 +0,0 @@
-<div class="border d-flex">
-  <div class="p-5 border bg-gray-light flex-auto">
-    <p id="notice"><%= notice %></p>
-
-    <h1>Users</h1>
-    <%= link_to 'New User', new_user_path %>
-
-    <% @users.each do |user| %>
-      <div class="TableObject">
-        <div class="TableObject-item TableObject-item--primary">
-          <input class="input-block form-control" type="text" placeholder="/sparkle <%= user.handle %> for" />
-        </div>
-        <div class="TableObject-item TableObject-item--primary">
-          <button class="btn ml-2" type="button">Sparkle</button>
-        </div>
-      </div>
-    <% end %>
-  </div>
-</div>
app/views/users/new.html.erb
@@ -1,5 +0,0 @@
-<h1>New User</h1>
-
-<%= render 'form', user: @user %>
-
-<%= link_to 'Back', users_path %>
app/views/users/show.html.erb
@@ -4,5 +4,3 @@
   <strong>Handle:</strong>
   <%= @user.handle %>
 </p>
-
-<%= link_to 'Back', users_path %>
config/routes.rb
@@ -1,7 +1,7 @@
 Rails.application.routes.draw do
   # For details on the DSL available within this file,
   # see https://guides.rubyonrails.org/routing.html
-  resources :users, only: [:index, :show, :new, :create]
-  resources :sparkles, only: [:index]
-  root "users#index"
+  resources :sparkles, only: [:index, :create]
+  resources :users, only: [:show]
+  root "sparkles#index"
 end
db/migrate/20210506021417_create_sparkles.rb
@@ -0,0 +1,11 @@
+class CreateSparkles < ActiveRecord::Migration[6.1]
+  def change
+    create_table :sparkles do |t|
+      t.string :reason
+      t.references :sparkler, index: true, null: false
+      t.references :sparklee, index: true, null: false
+
+      t.timestamps
+    end
+  end
+end
db/schema.rb
@@ -10,7 +10,17 @@
 #
 # It's strongly recommended that you check this file into your version control system.
 
-ActiveRecord::Schema.define(version: 2021_05_01_030808) do
+ActiveRecord::Schema.define(version: 2021_05_06_021417) do
+
+  create_table "sparkles", force: :cascade do |t|
+    t.string "reason"
+    t.integer "sparkler_id", null: false
+    t.integer "sparklee_id", null: false
+    t.datetime "created_at", precision: 6, null: false
+    t.datetime "updated_at", precision: 6, null: false
+    t.index ["sparklee_id"], name: "index_sparkles_on_sparklee_id"
+    t.index ["sparkler_id"], name: "index_sparkles_on_sparkler_id"
+  end
 
   create_table "users", force: :cascade do |t|
     t.string "handle", null: false
test/controllers/users_controller_test.rb
@@ -5,22 +5,6 @@ class UsersControllerTest < ActionDispatch::IntegrationTest
     @user = users(:billie)
   end
 
-  test "should get index" do
-    get users_url
-    assert_response :success
-  end
-
-  test "should get new" do
-    get new_user_url
-    assert_response :success
-  end
-
-  test "should create user" do
-    post users_url, params: { user: { handle: 'wycats' } }
-
-    assert_redirected_to user_url(User.last)
-  end
-
   test "should show user" do
     get user_url(@user)
     assert_response :success
test/fixtures/sparkles.yml
@@ -0,0 +1,11 @@
+# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
+
+one:
+  reason: MyString
+  sparkler: one
+  sparklee: one
+
+two:
+  reason: MyString
+  sparkler: two
+  sparklee: two
test/models/sparkle_test.rb
@@ -0,0 +1,7 @@
+require "test_helper"
+
+class SparkleTest < ActiveSupport::TestCase
+  # test "the truth" do
+  #   assert true
+  # end
+end