From b9b1f9a69e41da6a738a45ab8510fa83c65fda96 Mon Sep 17 00:00:00 2001 From: Yevhenii Hurin Date: Sat, 7 Oct 2023 13:38:43 +0300 Subject: [PATCH] Add TweetsController with views --- app/assets/stylesheets/style.scss | 21 +++++++++++++++ app/controllers/tweets_controller.rb | 21 +++++++++++++++ app/views/layouts/application.html.slim | 3 ++- app/views/shared/_navbar.html.slim | 16 ++++++++++++ app/views/tweets/index.html.slim | 32 +++++++++++++++++++++++ app/views/tweets/show.html.slim | 34 +++++++++++++++++++++++++ app/views/welcome/index.html.slim | 18 +------------ config/routes.rb | 2 ++ spec/requests/tweets_spec.rb | 33 ++++++++++++++++++++++++ 9 files changed, 162 insertions(+), 18 deletions(-) create mode 100644 app/controllers/tweets_controller.rb create mode 100644 app/views/shared/_navbar.html.slim create mode 100644 app/views/tweets/index.html.slim create mode 100644 app/views/tweets/show.html.slim create mode 100644 spec/requests/tweets_spec.rb diff --git a/app/assets/stylesheets/style.scss b/app/assets/stylesheets/style.scss index 00f8a95..a75ffc4 100644 --- a/app/assets/stylesheets/style.scss +++ b/app/assets/stylesheets/style.scss @@ -6,3 +6,24 @@ .title { font-family: Source Code Pro; } + +h1.rotated { + transform: rotate(-90deg); + transform-origin: bottom left; + white-space: nowrap; + position: absolute; + bottom: 40%; + left: 9vw; + font-family: Source Code Pro; + font-size: 3rem; +} + +@media (max-width: 768px) { + h1.rotated { + transform: none; + position: static; + bottom: auto; + left: auto; + font-size: 2rem; + } +} diff --git a/app/controllers/tweets_controller.rb b/app/controllers/tweets_controller.rb new file mode 100644 index 0000000..6011305 --- /dev/null +++ b/app/controllers/tweets_controller.rb @@ -0,0 +1,21 @@ +class TweetsController < ApplicationController + def index + @tweets = Tweet.all + + respond_to do |format| + format.html # renders index.html.slim + end + end + + def show + @tweet = Tweet.find(params[:id]) + + respond_to do |format| + format.html # renders show.html.slim + format.json do + # TODO: add filtering by date range and by metrics subset + render json: @tweet.tweet_metrics.to_json + end + end + end +end diff --git a/app/views/layouts/application.html.slim b/app/views/layouts/application.html.slim index a361ba6..654fc4e 100644 --- a/app/views/layouts/application.html.slim +++ b/app/views/layouts/application.html.slim @@ -8,9 +8,10 @@ html = stylesheet_link_tag 'application', 'data-turbo-track': 'reload' = javascript_include_tag 'application', 'data-turbo-track': 'reload', defer: true link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.3/css/bulma.min.css" - script src="https://kit.fontawesome.com/08b1825a15.js" crossorigin="anonymous" link rel="preconnect" href="https://fonts.googleapis.com" link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="crossorigin" link href="https://fonts.googleapis.com/css2?family=Source+Code+Pro&display=swap" rel="stylesheet" + script src="https://kit.fontawesome.com/08b1825a15.js" crossorigin="anonymous" + script src="https://code.highcharts.com/highcharts.js" body == yield diff --git a/app/views/shared/_navbar.html.slim b/app/views/shared/_navbar.html.slim new file mode 100644 index 0000000..d2cc1a4 --- /dev/null +++ b/app/views/shared/_navbar.html.slim @@ -0,0 +1,16 @@ +header.navbar + .container + .navbar-brand + a.navbar-item href="/" + | X-Tracker + span.navbar-burger.burger data-target="navbarMenuHeroA" + span + span + span + .navbar-menu id="navbarMenuHeroA" + .navbar-end + a.navbar-item href="/" + | Home + = link_to "Tweets", tweets_path, class: "navbar-item" + / a.navbar-item href="/contact" + / | Contact diff --git a/app/views/tweets/index.html.slim b/app/views/tweets/index.html.slim new file mode 100644 index 0000000..ec85051 --- /dev/null +++ b/app/views/tweets/index.html.slim @@ -0,0 +1,32 @@ +section.hero.is-info + .hero-head + = render "shared/navbar" +.section + .columns.is-centered + .column.is-1 + h1.rotated.has-text-grey Tracked Tweets + .column.is-10 + - @tweets.each do |tweet| + .card + .card-content + .media + .media-left + figure class="image is-48x48" + img src="#{tweet.author_avatar_url}" class="is-rounded" + .media-content + p class="title is-4" + = link_to tweet.author_name, tweet.author_url, target: "_blank" + p class="subtitle is-6" + = tweet.body.truncate(280) + .content + / TODO: render a small chart here + footer.card-footer + = link_to tweet_path(tweet), class: "card-footer-item" do + span View Metrics + span.icon + i class="fa fa-chevron-right" + = link_to tweet.url, class: "card-footer-item", target: "_blank" do + span View Tweet + span.icon + i class="fa fa-chevron-right" + .column.is-1 diff --git a/app/views/tweets/show.html.slim b/app/views/tweets/show.html.slim new file mode 100644 index 0000000..a060098 --- /dev/null +++ b/app/views/tweets/show.html.slim @@ -0,0 +1,34 @@ +section.hero.is-info + .hero-head + = render "shared/navbar" +.section + .columns.is-centered + .column.is-1 + h1.rotated.has-text-grey= @tweet.author_name + .column.is-10 + .card + .card-content + .content + .columns.is-centered + .column.is-6 + .box + h2.title.is-4.has-text-dark + | Tweet + .content + p= @tweet.body + .column.is-6 + .box + h2.title.is-4.has-text-dark + | Metrics + .content + p + | Likes: #{number_with_delimiter(@tweet.likes)} + p + | Retweets: #{number_with_delimiter(@tweet.reposts)} + p + | Comments: #{number_with_delimiter(@tweet.replies)} + p + | Views: #{number_with_delimiter(@tweet.views)} + .section + h4.title.is-4.has-text-dark + | Charts diff --git a/app/views/welcome/index.html.slim b/app/views/welcome/index.html.slim index 57e65ee..bd97868 100644 --- a/app/views/welcome/index.html.slim +++ b/app/views/welcome/index.html.slim @@ -1,22 +1,6 @@ section.hero.is-fullheight.is-info .hero-head - header.navbar - .container - .navbar-brand - a.navbar-item href="/" - | X-Tracker - span.navbar-burger.burger data-target="navbarMenuHeroA" - span - span - span - .navbar-menu id="navbarMenuHeroA" - .navbar-end - a.navbar-item href="/" - | Home - / a.navbar-item href="/about" - / | About - / a.navbar-item href="/contact" - / | Contact + = render "shared/navbar" .hero-body .container diff --git a/config/routes.rb b/config/routes.rb index a8216b4..0386a9c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,3 +1,5 @@ Rails.application.routes.draw do + resources :tweets, only: %i[index show] + root "welcome#index" end diff --git a/spec/requests/tweets_spec.rb b/spec/requests/tweets_spec.rb new file mode 100644 index 0000000..b634c6c --- /dev/null +++ b/spec/requests/tweets_spec.rb @@ -0,0 +1,33 @@ +require 'rails_helper' + +RSpec.describe "Tweets", type: :request do + let!(:tweet) { create(:tweet) } + + describe "GET index" do + subject { get "/tweets" } + + it "returns http success" do + subject + expect(response).to have_http_status(:success) + end + + it "returns a list of tweets" do + subject + expect(response.body).to include(tweet.author) + end + end + + describe "GET show" do + subject { get "/tweets/#{tweet.id}" } + + it "returns http success" do + subject + expect(response).to have_http_status(:success) + end + + it "returns a tweet" do + subject + expect(response.body).to include(tweet.author) + end + end +end