Skip to content

Commit

Permalink
Merge pull request #106 from realstorypro/pending-stories
Browse files Browse the repository at this point in the history
Added ability to approve & deny stories
  • Loading branch information
Leonid Medovyy committed Jul 27, 2023
2 parents b79eb1c + 7096004 commit dc341a5
Show file tree
Hide file tree
Showing 16 changed files with 323 additions and 91 deletions.
14 changes: 14 additions & 0 deletions app/controllers/page_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,20 @@ class PageController < ApplicationController
include RestrictedAccess
def index
@topics = Topic.with_active_subtopic.order(:name)

@pending_stories_count = Story.needs_approval.count
@unpublished_discussions = Discussion.unpublished.count
@pending_tweets = Tweet.needs_approval.count

@published_discussions = Discussion.published.count
@published_tweets = Tweet.published.count

@denied_stories = Story.denied_stories.count
@denied_tweets = Tweet.denied.count

@approved_stories = Story.approved_stories.count
@approved_tweets = Tweet.approved_tweets.count

@feeds_count = Feed.count
@feed_items_count = FeedItem.count
@stories_count = Story.count
Expand Down
20 changes: 18 additions & 2 deletions app/controllers/stories_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,27 @@ def show
@images = Image.where(story: @story, invalid_prompt: false)
end

def approve
@story = Story.find(params[:id])
@story.update(approved: true)
redirect_to story_path(@story)
end

def disapprove
@story = Story.find(params[:id])
@story.update(approved: false)
redirect_to story_path(@story)
end

private

def set_scope
if params[:scope] && params[:scope] == 'unpublished'
return 'unpublished_stories'
if params[:scope] && params[:scope] == 'pending'
return 'needs_approval'
elsif params[:scope] && params[:scope] == 'approved'
return 'approved_stories'
elsif params[:scope] && params[:scope] == 'denied'
return 'denied_stories'
elsif params[:scope] && params[:scope] == 'published'
return 'published_stories'
end
Expand Down
21 changes: 15 additions & 6 deletions app/models/story.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
# processed :boolean default(FALSE)
# invalid_json :boolean default(FALSE)
# invalid_images :boolean default(FALSE)
# approved :boolean
#

################ logic #################
Expand Down Expand Up @@ -49,12 +50,12 @@ class Story < ApplicationRecord
scope :without_images, lambda {
joins("LEFT JOIN images ON images.story_id = stories.id")
.where("images.id IS NULL")
.where(invalid_images: false, invalid_json: false)
.where(approved: true, invalid_images: false, invalid_json: false)
}

scope :with_stem_and_valid_processed_images, lambda {
joins(:images)
.where(processed: true, invalid_json: false)
.where(approved: true, processed: true, invalid_json: false)
.where(images: { processed: true, invalid_prompt: false, uploaded: true })
.group('stories.id')
.having('count(images.id) = 3')
Expand All @@ -66,14 +67,22 @@ class Story < ApplicationRecord
.where(discussions: { id: nil })
}

scope :unpublished_stories, lambda {
joins(:discussion)
.where(discussions: { uploaded: false, processed: true, invalid_json: false })
scope :needs_approval, lambda {
where(approved: nil, invalid_json: false)
}

scope :denied_stories, lambda {
where(approved: false, invalid_json: false)
}

scope :approved_stories, lambda {
where(approved: true, invalid_json: false)
}

scope :published_stories, lambda {
joins(:discussion)
.where(discussions: { uploaded: true })
.where(invalid_json: false,
discussions: { uploaded: true })
}

# seems like the stems with less then 1200 characters are spammy
Expand Down
16 changes: 0 additions & 16 deletions app/models/tweet.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,6 @@
# updated_at :datetime not null
# approved :boolean
#
################ logic #################
# - the `processed` tag is used to determine if the stem has been created by the ai.
# * it is set to true in tweets/make_stem_job.rb
#
# - the `invalid_json` tag is set to true if the ai fails to create a stem for the discussion.
# * it is set to true in tweets/make_stem_job.rb
#
# - the `uploaded` tag is used to determine if the discussion has been uploaded to Ayrshare
# * it is set to true in tweets/publish_tweet_job.rb
#
# - the `published_at` tag is the date when the item was published to Ayrshare
# * it is set to true in tweets/publish_tweet_job.rb
#
# - the `approved` tag is set in the tweet controller and is used as a part of the scope to
# determine tweets that need publishing.
########################################

class Tweet < ApplicationRecord
belongs_to :discussion
Expand Down
6 changes: 3 additions & 3 deletions app/views/discussions/index.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@
=r ux.div 'text-right'
= link_to 'Show Full Discussion', discussion_path(discussion)

=r ux.h4 text: discussion.parsed_stem["title"], class: '!mb-0'

=r ux.div 'text-blue-800 font-bold mb-4'
= "Tag: #{discussion.story.tag.name}"

=r ux.h3 text: discussion.parsed_stem["title"], class: '!mb-2'

=r ux.text text: discussion.parsed_stem["summary"], class: 'mb-8'

- if discussion.story.images.count.positive?
=r ux.div 'mb-2 bg-green-100 px-2 py-2 border-solid border-2 border-green-500'
=r ux.div 'mb-2 bg-green-100 px-2 py-2 border-solid border-2 border-green-500 mb-8'
= "#{pluralize(discussion.story.images.count, 'Image')} Generated"

- if discussion.story.images.first&.card_imagination.present? && discussion.story.images.first.card_imagination.payload["imageUrl"].present?
Expand Down
10 changes: 8 additions & 2 deletions app/views/layouts/application.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,14 @@ html lang="en"
| Stories
=r ux.icon 'dropdown'
=r ux.menu
= link_to stories_path(scope: :unpublished), class: "item"
| Unpublished
= link_to stories_path(scope: :pending), class: "item"
| Pending
=r ux.divider
= link_to stories_path(scope: :approved), class: "item"
| Approved
=r ux.divider
= link_to stories_path(scope: :denied), class: "item"
| Denied
=r ux.divider
= link_to stories_path(scope: :published), class: "item"
| Published
Expand Down
196 changes: 177 additions & 19 deletions app/views/page/index.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -2,51 +2,209 @@
=r ux.row
=r ux.column width: 16

=r ux.segment '!bg-gray-900 inverted !mb-16 !py-3 !rounded'
=r ux.h3 'center aligned !font-mono !mb-0'
| Statistics
=r ux.segment '!bg-slate-900 inverted !mb-8 !py-2 !rounded-sm'
=r ux.h3 'center aligned !font-mono !mb-0 flex items-center !text-sm !font-normal'
div.mx-auto
=r ux.icon 'bullhorn !text-sm !mb-1 !mr-2'
| Networks

=r ux.statistics 'tiny !mb-8 justify-center'

=r ux.statistic
=r ux.value ui: false,
class: '!text-slate-800'
- if ENV['FACEBOOK_ENABLED']
=r ux.div 'mx-auto mb-2 w-3 h-3 bg-green-500 rounded-full'
- else
=r ux.div 'mx-auto mb-2 w-3 h-3 bg-gray-300 rounded-full'

=r ux.label text: 'Facebook', ui: false,
class: '!font-mono !text-slate-700 !font-normal'

=r ux.statistic
=r ux.value ui: false,
class: '!text-slate-800'
- if ENV['TWITTER_ENABLED']
=r ux.div 'mx-auto mb-2 w-3 h-3 bg-green-500 rounded-full'
- else
=r ux.div 'mx-auto mb-2 w-3 h-3 bg-gray-300 rounded-full'

=r ux.label text: 'Twitter', ui: false,
class: '!font-mono !text-slate-700 !font-normal'

=r ux.statistic
=r ux.value ui: false,
class: '!text-slate-800'
- if ENV['LINKEDIN_ENABLED']
=r ux.div 'mx-auto mb-2 w-3 h-3 bg-green-500 rounded-full'
- else
=r ux.div 'mx-auto mb-2 w-3 h-3 bg-gray-300 rounded-full'

=r ux.label text: 'LinkedIn', ui: false,
class: '!font-mono !text-slate-700 !font-normal'

=r ux.statistic
=r ux.value ui: false,
class: '!text-slate-800'
- if ENV['INSTAGRAM_ENABLED']
=r ux.div 'mx-auto mb-2 w-3 h-3 bg-green-500 rounded-full'
- else
=r ux.div 'mx-auto mb-2 w-3 h-3 bg-gray-300 rounded-full'

=r ux.label text: 'Instagram', ui: false,
class: '!font-mono !text-slate-700 !font-normal'


=r ux.statistic
=r ux.value ui: false,
class: '!text-slate-800'
- if ENV['PINTEREST_ENABLED']
=r ux.div 'mx-auto mb-2 w-3 h-3 bg-green-500 rounded-full'
- else
=r ux.div 'mx-auto mb-2 w-3 h-3 bg-gray-300 rounded-full'

=r ux.label text: 'Pinterest', ui: false,
class: '!font-mono !text-slate-700 !font-normal'




=r ux.segment '!bg-slate-700 inverted !mb-6 !py-2 !rounded-sm w-11/12 !mx-auto'
=r ux.h3 'center aligned !font-mono !mb-0 flex items-center !text-sm !font-normal'
div.mx-auto
=r ux.icon 'hourglass end !text-sm !mb-1 !mr-2'
| Pending

=r ux.statistics 'tiny !mb-4 justify-center'
=r ux.statistic
=r ux.value text: number_with_delimiter(@pending_stories_count, :delimiter => ','), ui: false,
class: '!text-slate-800'
=r ux.label text: 'Stories', ui: false,
class: '!font-mono !text-slate-700 !font-normal'

=r ux.statistic
=r ux.value text: number_with_delimiter(@unpublished_discussions, :delimiter => ','), ui: false,
class: '!text-slate-800'
=r ux.label text: 'Discussions'.html_safe, ui: false,
class: '!font-mono !text-slate-700 !font-normal'

=r ux.statistic
=r ux.value text: number_with_delimiter(@pending_tweets, :delimiter => ','), ui: false,
class: '!text-slate-800'
=r ux.label text: 'Tweets', ui: false,
class: '!font-mono !text-slate-700 !font-normal'

=r ux.segment '!bg-slate-600 inverted !mb-6 !py-2 !rounded-sm w-10/12 !mx-auto'
=r ux.h3 'center aligned !font-mono !mb-0 flex items-center !text-sm !font-normal'
div.mx-auto
=r ux.icon 'thumbs down !text-sm !mb-1 !mr-2'
| Denied

=r ux.statistics 'tiny !mb-4 justify-center'
=r ux.statistic
=r ux.value text: number_with_delimiter(@denied_stories, :delimiter => ','), ui: false,
class: '!text-gray-700'
=r ux.label text: 'Stories', ui: false,
class: '!font-mono !text-gray-700 !font-normal'

=r ux.statistic
=r ux.value text: number_with_delimiter(@denied_tweets, :delimiter => ','), ui: false,
class: '!text-gray-700'
=r ux.label text: 'Tweets', ui: false,
class: '!font-mono !text-gray-700 !font-normal'


=r ux.segment '!bg-slate-800 inverted !mb-6 !py-2 !rounded-sm w-9/12 !mx-auto'
=r ux.h3 'center aligned !font-mono !mb-0 flex items-center !text-sm !font-normal'
div.mx-auto
=r ux.icon 'glass cheers !text-sm !mb-1 !mr-2'
| Approved

=r ux.statistics 'tiny !mb-4 justify-center'
=r ux.statistic
=r ux.value text: number_with_delimiter(@approved_stories, :delimiter => ','), ui: false,
class: '!text-slate-800'
=r ux.label text: 'Stories', ui: false,
class: '!font-mono !text-slate-700 !font-normal'

=r ux.statistics 'small !mb-16 justify-center'
=r ux.statistic
=r ux.value text: number_with_delimiter(@feeds_count, :delimiter => ','), ui: false
=r ux.label text: 'Feeds', ui: false, class: '!font-mono'
=r ux.value text: number_with_delimiter(@approved_tweets, :delimiter => ','), ui: false,
class: '!text-slate-800'
=r ux.label text: 'Tweets', ui: false,
class: '!font-mono !text-slate-700 !font-normal'



=r ux.segment '!bg-slate-900 inverted !mb-6 !py-2 !rounded-sm w-8/12 !mx-auto'
=r ux.h3 'center aligned !font-mono !mb-0 flex items-center !text-sm !font-normal'
div.mx-auto
=r ux.icon 'newspaper !text-sm !mb-1 !mr-2'
| Published

=r ux.statistics 'tiny !mb-4 justify-center'
=r ux.statistic
=r ux.value text: number_with_delimiter(@published_discussions, :delimiter => ','), ui: false,
class: '!text-slate-800'
=r ux.label text: 'Discussions', ui: false,
class: '!font-mono !text-slate-700 !font-normal'

=r ux.statistic
=r ux.value text: number_with_delimiter(@published_tweets, :delimiter => ','), ui: false,
class: '!text-slate-800'
=r ux.label text: 'Tweets', ui: false,
class: '!font-mono !text-slate-700 !font-normal'


=r ux.segment '!bg-slate-800 inverted !mb-8 !py-2 !rounded-sm w-10/12 !mx-auto'
=r ux.h3 'center aligned !font-mono !mb-0 flex items-center !text-sm !font-normal'
div.mx-auto
=r ux.icon 'calculator !text-sm !mb-1 !mr-2'
| Totals

=r ux.statistics 'tiny !mb-4 justify-center'
=r ux.statistic
=r ux.value text: number_with_delimiter(@feed_items_count, :delimiter => ','), ui: false
=r ux.label text: 'Feed Items', ui: false, class: '!font-mono'
=r ux.value text: number_with_delimiter(@feeds_count, :delimiter => ','), ui: false,
class: '!text-slate-800'
=r ux.label text: 'Feeds', ui: false,
class: '!font-mono !text-slate-700 !font-normal'

=r ux.statistic
=r ux.value text: number_with_delimiter(@feed_items_count, :delimiter => ','), ui: false,
class: '!text-slate-800'
=r ux.label text: 'Feed Items', ui: false, class: '!font-mono !text-slate-700 !font-normal'

=r ux.statistic
=r ux.value text: number_with_delimiter(@stories_count, :delimiter => ','), ui: false
=r ux.label text: 'Stories', ui: false, class: '!font-mono'
=r ux.label text: 'Stories', ui: false, class: '!font-mono !text-slate-700 !font-normal'

=r ux.statistic
=r ux.value text: number_with_delimiter(@discussions_count, :delimiter => ','), ui: false
=r ux.label text: 'Discussions', ui: false, class: '!font-mono'
=r ux.label text: 'Discussions', ui: false, class: '!font-mono !text-slate-700 !font-normal'

=r ux.statistic
=r ux.value text: number_with_delimiter(@imaginations_count, :delimiter => ','), ui: false
=r ux.label text: 'Imaginations', ui: false, class: '!font-mono'
=r ux.label text: 'Imaginations', ui: false, class: '!font-mono !text-slate-700 !font-normal'

=r ux.statistic
=r ux.value text: number_with_delimiter(@tweets_count, :delimiter => ','), ui: false
=r ux.label text: 'Tweets', ui: false, class: '!font-mono'

=r ux.label text: 'Tweets', ui: false, class: '!font-mono !text-slate-700 !font-normal'

=r ux.segment '!bg-gray-900 inverted mb-0 !py-3 !rounded'
=r ux.h3 'center aligned !font-mono !mb-0'
| Topics
=r ux.label text: @topics.count, class: 'circular purple !bg-gray-100 !text-gray-900'
=r ux.segment '!bg-slate-700 inverted mb-0 !py-2 !rounded-sm w-11/12 !mx-auto'
=r ux.h3 'center aligned !font-mono !mb-0 flex items-center !text-sm !font-normal'
div.mx-auto
=r ux.icon 'book reader !text-sm !mb-1 !mr-2'
| Feed Topics

=r ux.div 'flex flex-wrap'
- @topics.each do |topic|
=r ux.div '!mb-10 !bg-black-100 !border-2 !border-blue-100 !px-10 !py-10 !w-1/2'
=r ux.h5 'center aligned'
= topic.name
=r ux.label text: topic.active_subtopics.count, class: 'circular !bg-gray-700 !text-white mini'
=r ux.label text: topic.active_subtopics.count, class: 'circular !bg-slate-600 !text-white mini'
=r ux.divider
- topic.active_subtopics.each do |sub_topic|
=r ux.div 'flex justify-end'
=r ux.h5 text: sub_topic.name, class: '!text-right !text-shadow-sm !mt-0 !mt-[-4px] !mr-2 !mb-2'
=r ux.h5 text: sub_topic.name, class: '!text-shadow-sm !font-normal !mt-0 !mt-[-4px] !mr-2 !mb-2'
- if sub_topic.feeds.last.present?
-if sub_topic.feeds.last.created_at.strftime("%m/%d/%Y") == Time.now.utc.to_date.strftime("%m/%d/%Y")
=r ux.div 'w-3 h-3 bg-green-500 rounded-full'
Expand Down
Loading

0 comments on commit dc341a5

Please sign in to comment.