From 8e15dbd73035c2a2198a2828a20ddcebe0739823 Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Tue, 3 Jul 2018 13:58:57 -0400 Subject: Implemented streams Currently there are no links to the pages for editing stream updates, and the admin panel for managing streams could probably have a better look & feel, but here's some basic working functionality. refs #8 --- app/assets/stylesheets/admin/layout.scss | 14 +++- app/assets/stylesheets/main/entries.scss | 105 ++++++++++++++++++---------- app/assets/stylesheets/main/records.scss | 4 ++ app/controllers/admin/streams_controller.rb | 52 ++++++++++++++ app/controllers/admin/updates_controller.rb | 52 ++++++++++++++ app/controllers/streams_controller.rb | 7 ++ app/helpers/streams_helper.rb | 2 + app/models/stream.rb | 13 ++++ app/models/update.rb | 12 ++++ app/views/admin/blogs/edit.html.haml | 2 +- app/views/admin/blogs/new.html.haml | 2 +- app/views/admin/streams/_form.html.haml | 25 +++++++ app/views/admin/streams/edit.html.haml | 2 + app/views/admin/streams/index.html.haml | 13 ++++ app/views/admin/streams/new.html.haml | 2 + app/views/admin/updates/_form.html.haml | 22 ++++++ app/views/admin/updates/edit.html.haml | 2 + app/views/admin/updates/new.html.haml | 2 + app/views/blogs/_blog.html.haml | 2 +- app/views/layouts/admin.html.haml | 4 ++ app/views/streams/_stream.html.haml | 6 ++ app/views/streams/show.html.haml | 2 + app/views/updates/_update.html.haml | 3 + config/routes.rb | 6 ++ db/migrate/20180702220722_create_streams.rb | 11 +++ db/migrate/20180702221133_create_updates.rb | 10 +++ db/schema.rb | 19 ++++- 27 files changed, 355 insertions(+), 41 deletions(-) create mode 100644 app/controllers/admin/streams_controller.rb create mode 100644 app/controllers/admin/updates_controller.rb create mode 100644 app/controllers/streams_controller.rb create mode 100644 app/helpers/streams_helper.rb create mode 100644 app/models/stream.rb create mode 100644 app/models/update.rb create mode 100644 app/views/admin/streams/_form.html.haml create mode 100644 app/views/admin/streams/edit.html.haml create mode 100644 app/views/admin/streams/index.html.haml create mode 100644 app/views/admin/streams/new.html.haml create mode 100644 app/views/admin/updates/_form.html.haml create mode 100644 app/views/admin/updates/edit.html.haml create mode 100644 app/views/admin/updates/new.html.haml create mode 100644 app/views/streams/_stream.html.haml create mode 100644 app/views/streams/show.html.haml create mode 100644 app/views/updates/_update.html.haml create mode 100644 db/migrate/20180702220722_create_streams.rb create mode 100644 db/migrate/20180702221133_create_updates.rb diff --git a/app/assets/stylesheets/admin/layout.scss b/app/assets/stylesheets/admin/layout.scss index bbe5383..6645709 100644 --- a/app/assets/stylesheets/admin/layout.scss +++ b/app/assets/stylesheets/admin/layout.scss @@ -80,7 +80,7 @@ body { background-color: #eee; } -#blog-form { +#entry-form { display: flex; fieldset { @@ -163,6 +163,18 @@ body { td { padding: .25em; } + + .admin-actions { + margin: 0; + + li { + display: inline; + + &+li:before { + content: " - "; + } + } + } } .details-module { diff --git a/app/assets/stylesheets/main/entries.scss b/app/assets/stylesheets/main/entries.scss index bd0b5ba..b2a07c5 100644 --- a/app/assets/stylesheets/main/entries.scss +++ b/app/assets/stylesheets/main/entries.scss @@ -26,54 +26,87 @@ margin-bottom: 0; font-weight: normal; } +} - #blog-content { - hyphens: auto; - word-wrap: break-word; +#stream-post { + h2 { + background-color: #98FB98; + display: block; + font-size: 20px; font-family: 'Roboto', sans-serif; - text-align: justify; + padding: 0.5em 20px; + border-top: 1px solid #7BCC70; + border-bottom: 1px solid #7BCC70; + } - a { - text-decoration: none; - font-weight: bold; + #stream-intro { + font-size: 16px; + margin: 0 20px; + } - &, &:visited { - color: #ee2c2c; - } + .stream-update { + font-size: 16px; + padding: 0 20px; + border-top: 1px solid #DEDEDE; - &:hover { - text-decoration: underline; - color: #9ea1ad; - } + .update-posted { + display: block; + font-style: italic; + text-align: right; + color: #989898; + font-size: 14px; + margin-top: .5em; } + } +} + +.entry-content { + hyphens: auto; + word-wrap: break-word; + text-align: justify; + font-family: 'Roboto', sans-serif; + + a { + text-decoration: none; + font-weight: bold; - li { - & + li { - margin-top: 1em; - } + &, &:visited { + color: #ee2c2c; } - img { - max-width: 100%; - box-sizing: border-box; + &:hover { + text-decoration: underline; + color: #9ea1ad; } + } - figure { - background-color: #eee; + li { + & + li { + margin-top: 1em; + } + } + + img { + max-width: 100%; + box-sizing: border-box; + } + + figure { + background-color: #eee; + border: 1px solid #bbb; + padding: 0.25em 0.25em 0 0.25em; + font-size: 0.75em; + line-height: 24px; + + img { + display: block; border: 1px solid #bbb; - padding: 0.25em 0.25em 0 0.25em; - font-size: 0.75em; - - img { - display: block; - border: 1px solid #bbb; - } - - figcaption { - font-style: italic; - text-align: center; - margin: 0.25em; - } + } + + figcaption { + font-style: italic; + text-align: center; + margin: 0.25em; } } } diff --git a/app/assets/stylesheets/main/records.scss b/app/assets/stylesheets/main/records.scss index dd4eac1..f57dded 100644 --- a/app/assets/stylesheets/main/records.scss +++ b/app/assets/stylesheets/main/records.scss @@ -52,6 +52,10 @@ &.entry-type-blog { background-color: #90fefb; } + + &.entry-type-stream, &.entry-type-update { + background-color: #98FB98; + } } & + li { diff --git a/app/controllers/admin/streams_controller.rb b/app/controllers/admin/streams_controller.rb new file mode 100644 index 0000000..86dec06 --- /dev/null +++ b/app/controllers/admin/streams_controller.rb @@ -0,0 +1,52 @@ +class Admin::StreamsController < Admin::AdminController + before_action :set_section + + def index + @streams = Stream.order(created_at: :desc) + end + + def new + @stream = Stream.new + end + + def create + @stream = Stream.new(stream_params) + + if @stream.save + flash.notice = "Stream created successfully!" + + render :edit + else + flash.alert = "Error creating stream." + + render :new + end + end + + def edit + @stream = Stream.find(params[:id]) + end + + def update + @stream = Stream.find(params[:id]) + + if @stream.update_attributes(stream_params) + flash.notice = "Stream updated successfully!" + else + flash.alert = "Error updating stream." + end + + render :edit + end + + private + + def stream_params + params.require(:stream).permit(:title, :body, :slug, records_attributes: [:description, :_destroy]) + end + + def set_section + @section = "streams" + end + +end diff --git a/app/controllers/admin/updates_controller.rb b/app/controllers/admin/updates_controller.rb new file mode 100644 index 0000000..9bf9caf --- /dev/null +++ b/app/controllers/admin/updates_controller.rb @@ -0,0 +1,52 @@ +class Admin::UpdatesController < Admin::AdminController + before_action :set_section + + def new + @stream = Stream.find(params[:stream_id]) + @update = @stream.updates.build + end + + def create + @stream = Stream.find(params[:stream_id]) + @update = @stream.updates.build(update_params) + + if @update.save + flash.notice = "Update created successfully!" + + render :edit + else + flash.alert = "Error creating update." + + render :new + end + end + + def edit + @stream = Stream.find(params[:stream_id]) + @update = Update.find(params[:id]) + end + + def update + @stream = Stream.find(params[:stream_id]) + @update = Update.find(params[:id]) + + if @update.update_attributes(update_params) + flash.notice = "Update updated successfully!" + else + flash.alert = "Error updating update." + end + + render :edit + end + + private + + def update_params + params.require(:update).permit(:body, records_attributes: [:description, :_destroy]) + end + + def set_section + @section = "streams" + end + +end diff --git a/app/controllers/streams_controller.rb b/app/controllers/streams_controller.rb new file mode 100644 index 0000000..664f533 --- /dev/null +++ b/app/controllers/streams_controller.rb @@ -0,0 +1,7 @@ +class StreamsController < ApplicationController + + def show + @stream = Stream.find_by_slug(params[:slug]) + end + +end diff --git a/app/helpers/streams_helper.rb b/app/helpers/streams_helper.rb new file mode 100644 index 0000000..ad2665b --- /dev/null +++ b/app/helpers/streams_helper.rb @@ -0,0 +1,2 @@ +module StreamsHelper +end diff --git a/app/models/stream.rb b/app/models/stream.rb new file mode 100644 index 0000000..7faa370 --- /dev/null +++ b/app/models/stream.rb @@ -0,0 +1,13 @@ +class Stream < ApplicationRecord + has_many :records, as: :recordable, inverse_of: :recordable + has_many :updates + + validates :title, presence: true + validates :slug, presence: true, format: /\A[-a-z0-9]+\z/ + + accepts_nested_attributes_for :records, allow_destroy: true + + def path + "/thinks/#{slug}" + end +end diff --git a/app/models/update.rb b/app/models/update.rb new file mode 100644 index 0000000..41cc453 --- /dev/null +++ b/app/models/update.rb @@ -0,0 +1,12 @@ +class Update < ApplicationRecord + has_many :records, as: :recordable, inverse_of: :recordable + belongs_to :stream + + validates :stream, :body, presence: true + + accepts_nested_attributes_for :records, allow_destroy: true + + def path + "/thinks/#{stream.slug}\#update-#{id}" + end +end diff --git a/app/views/admin/blogs/edit.html.haml b/app/views/admin/blogs/edit.html.haml index 3f4d412..f356069 100644 --- a/app/views/admin/blogs/edit.html.haml +++ b/app/views/admin/blogs/edit.html.haml @@ -1,2 +1,2 @@ -= form_for @blog, url: admin_blog_url(@blog), html: { id: "blog-form" } do |f| += form_for @blog, url: admin_blog_url(@blog), html: { id: "entry-form" } do |f| = render partial: "form", locals: { f: f } diff --git a/app/views/admin/blogs/new.html.haml b/app/views/admin/blogs/new.html.haml index 914f27b..0005278 100644 --- a/app/views/admin/blogs/new.html.haml +++ b/app/views/admin/blogs/new.html.haml @@ -1,2 +1,2 @@ -= form_for @blog, url: admin_blogs_url, html: { id: "blog-form" } do |f| += form_for @blog, url: admin_blogs_url, html: { id: "entry-form" } do |f| = render partial: "form", locals: { f: f } diff --git a/app/views/admin/streams/_form.html.haml b/app/views/admin/streams/_form.html.haml new file mode 100644 index 0000000..ce457cb --- /dev/null +++ b/app/views/admin/streams/_form.html.haml @@ -0,0 +1,25 @@ +%fieldset#content + .title-field + = f.label :title + = f.text_field :title, placeholder: "Title" + .slug-field + = f.label :slug, "https://feffernoo.se/thinks/" + = f.text_field :slug, placeholder: "insert-slug-here" + .body-field + = f.label :body + = f.cktext_area :body +%fieldset#details + - if f.object.errors.any? + #errors.details-module + %h3 Error! + %ul + - f.object.errors.full_messages.each do |error| + %li= error + .details-module + = f.fields_for :records, Record.new do |builder| + .should-create-record-field + = builder.check_box :_destroy, {checked: false}, "0", "1" + = builder.label :_destroy, "Create record?" + .record-description-field + = builder.text_area :description, placeholder: "record text" + .details-module= f.submit diff --git a/app/views/admin/streams/edit.html.haml b/app/views/admin/streams/edit.html.haml new file mode 100644 index 0000000..1b58331 --- /dev/null +++ b/app/views/admin/streams/edit.html.haml @@ -0,0 +1,2 @@ += form_for @stream, url: admin_stream_url(@stream), html: { id: "entry-form" } do |f| + = render partial: "form", locals: { f: f } diff --git a/app/views/admin/streams/index.html.haml b/app/views/admin/streams/index.html.haml new file mode 100644 index 0000000..c69c6f9 --- /dev/null +++ b/app/views/admin/streams/index.html.haml @@ -0,0 +1,13 @@ +%table#entries + %tr + %th Title + %th Date created + %th + - @streams.each do |stream| + %tr{ class: cycle("even", "odd") } + %td= stream.title + %td= stream.created_at.strftime("%B %d, %Y, %l:%M%P") + %td + %ul.admin-actions + %li= link_to "Edit", edit_admin_stream_url(stream) + %li= link_to "Add Update", new_admin_stream_update_url(stream) diff --git a/app/views/admin/streams/new.html.haml b/app/views/admin/streams/new.html.haml new file mode 100644 index 0000000..52febf5 --- /dev/null +++ b/app/views/admin/streams/new.html.haml @@ -0,0 +1,2 @@ += form_for @stream, url: admin_streams_url, html: { id: "entry-form" } do |f| + = render partial: "form", locals: { f: f } diff --git a/app/views/admin/updates/_form.html.haml b/app/views/admin/updates/_form.html.haml new file mode 100644 index 0000000..9dd8741 --- /dev/null +++ b/app/views/admin/updates/_form.html.haml @@ -0,0 +1,22 @@ +%fieldset#content + .title-field + = f.label :title + = f.text_field :title, value: @stream.title, readonly: true + .body-field + = f.label :body + = f.cktext_area :body +%fieldset#details + - if f.object.errors.any? + #errors.details-module + %h3 Error! + %ul + - f.object.errors.full_messages.each do |error| + %li= error + .details-module + = f.fields_for :records, Record.new do |builder| + .should-create-record-field + = builder.check_box :_destroy, {checked: false}, "0", "1" + = builder.label :_destroy, "Create record?" + .record-description-field + = builder.text_area :description, placeholder: "record text" + .details-module= f.submit diff --git a/app/views/admin/updates/edit.html.haml b/app/views/admin/updates/edit.html.haml new file mode 100644 index 0000000..5651d23 --- /dev/null +++ b/app/views/admin/updates/edit.html.haml @@ -0,0 +1,2 @@ += form_for @update, url: admin_stream_update_url(@stream, @update), html: { id: "entry-form" } do |f| + = render partial: "form", locals: { f: f } diff --git a/app/views/admin/updates/new.html.haml b/app/views/admin/updates/new.html.haml new file mode 100644 index 0000000..14c6d77 --- /dev/null +++ b/app/views/admin/updates/new.html.haml @@ -0,0 +1,2 @@ += form_for @update, url: admin_stream_updates_url(@stream), html: { id: "entry-form" } do |f| + = render partial: "form", locals: { f: f } diff --git a/app/views/blogs/_blog.html.haml b/app/views/blogs/_blog.html.haml index e83d21a..91b1d20 100644 --- a/app/views/blogs/_blog.html.haml +++ b/app/views/blogs/_blog.html.haml @@ -1,3 +1,3 @@ %article#blog-post %h2#blog-title= blog.title - %section#blog-content= blog.body.html_safe + %section#blog-content.entry-content= blog.body.html_safe diff --git a/app/views/layouts/admin.html.haml b/app/views/layouts/admin.html.haml index 7f8c171..68bbd96 100644 --- a/app/views/layouts/admin.html.haml +++ b/app/views/layouts/admin.html.haml @@ -24,5 +24,9 @@ = link_to "Blogs", admin_blogs_url, class: "major-link" %ul.minors %li.minor= link_to "New blog", new_admin_blog_url + %li{major_sidebar_attrs("streams")} + = link_to "Streams", admin_streams_url, class: "major-link" + %ul.minors + %li.minor= link_to "New stream", new_admin_stream_url #main = yield diff --git a/app/views/streams/_stream.html.haml b/app/views/streams/_stream.html.haml new file mode 100644 index 0000000..84a6478 --- /dev/null +++ b/app/views/streams/_stream.html.haml @@ -0,0 +1,6 @@ +%article#stream-post + %h2#stream-title= stream.title + - unless stream.body.blank? + %header#stream-intro.entry-content= stream.body.html_safe + - unless stream.updates.empty? + = render stream.updates diff --git a/app/views/streams/show.html.haml b/app/views/streams/show.html.haml new file mode 100644 index 0000000..dcec0a2 --- /dev/null +++ b/app/views/streams/show.html.haml @@ -0,0 +1,2 @@ +.breadcrumb= link_to "← Back to home page", root_path += render @stream diff --git a/app/views/updates/_update.html.haml b/app/views/updates/_update.html.haml new file mode 100644 index 0000000..c8ce224 --- /dev/null +++ b/app/views/updates/_update.html.haml @@ -0,0 +1,3 @@ +%section.stream-update.entry-content{ id: "update-#{update.id}" } + %time.update-posted= update.created_at.strftime("%b #{update.created_at.day.ordinalize} %Y at %-I:%M:%S%P") + = update.body.html_safe diff --git a/config/routes.rb b/config/routes.rb index cf0bdd6..7369514 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -3,6 +3,10 @@ Rails.application.routes.draw do get '/', to: 'dashboard#index' resources :blogs, except: [:show] + + resources :streams, except: [:show] do + resources :updates, except: [:index, :show] + end end mount Ckeditor::Engine => '/ckeditor' @@ -16,5 +20,7 @@ Rails.application.routes.draw do get 'says/:slug', to: 'blogs#show' + get 'thinks/:slug', to: 'streams#show' + mount Pokeviewer::Engine => '/poke3' end diff --git a/db/migrate/20180702220722_create_streams.rb b/db/migrate/20180702220722_create_streams.rb new file mode 100644 index 0000000..bb8255e --- /dev/null +++ b/db/migrate/20180702220722_create_streams.rb @@ -0,0 +1,11 @@ +class CreateStreams < ActiveRecord::Migration[5.1] + def change + create_table :streams do |t| + t.string :title + t.text :body + t.string :slug + + t.timestamps + end + end +end diff --git a/db/migrate/20180702221133_create_updates.rb b/db/migrate/20180702221133_create_updates.rb new file mode 100644 index 0000000..05cc35a --- /dev/null +++ b/db/migrate/20180702221133_create_updates.rb @@ -0,0 +1,10 @@ +class CreateUpdates < ActiveRecord::Migration[5.1] + def change + create_table :updates do |t| + t.references :stream, foreign_key: true + t.text :body + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index e036b75..2ca0b58 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: 20180702214240) do +ActiveRecord::Schema.define(version: 20180702221133) do create_table "blogs", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin" do |t| t.string "title" @@ -228,6 +228,22 @@ ActiveRecord::Schema.define(version: 20180702214240) do t.index ["recordable_type", "recordable_id"], name: "index_records_on_recordable_type_and_recordable_id" end + create_table "streams", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci" do |t| + t.string "title" + t.text "body" + t.string "slug" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + create_table "updates", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci" do |t| + t.bigint "stream_id" + t.text "body" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["stream_id"], name: "index_updates_on_stream_id" + end + create_table "users", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin" do |t| t.string "login", default: "", null: false t.string "email", default: "", null: false @@ -253,4 +269,5 @@ ActiveRecord::Schema.define(version: 20180702214240) do add_foreign_key "pokeviewer_pokedex_entries", "pokeviewer_trainers", column: "trainer_id" add_foreign_key "pokeviewer_pokemon", "pokeviewer_revisions", column: "current_id" add_foreign_key "pokeviewer_revisions", "pokeviewer_species", column: "species_id" + add_foreign_key "updates", "streams" end -- cgit 1.4.1