diff --git a/app/assets/images/pushpin.svg b/app/assets/images/pushpin.svg new file mode 100644 index 000000000..3b84f8926 --- /dev/null +++ b/app/assets/images/pushpin.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/assets/stylesheets/articles.scss b/app/assets/stylesheets/articles.scss index 1430b8ff4..c05c2384d 100644 --- a/app/assets/stylesheets/articles.scss +++ b/app/assets/stylesheets/articles.scss @@ -216,6 +216,44 @@ } } } + .pinned-articles { + @include themeable(background, theme-container-background, $white); + @include themeable( + border, + theme-container-border, + 1px solid $outline-color + ); + padding: 8px 0px; + margin: auto; + margin-top: 8px; + @media screen and (min-width: 750px) { + border-radius: 3px; + box-sizing: border-box; + padding: 8px 8px; + padding-right: 9px; + width: calc(100% + 2px); + max-width: 722px; + } + .pinned-articles-indicator { + text-align: left; + font-size: 15px; + font-weight: bold; + padding-top: 8px; + padding-left: 2.8%; + @media screen and (min-width: 750px) { + padding-left: 22px; + } + @media screen and (min-width: 950px) { + padding-left: 2px; + } + img { + width: 20px; + transform: rotate(-8deg); + vertical-align: -5px; + @include themeable(filter, theme-social-icon-invert, invert(0)); + } + } + } a { @include themeable(color, theme-container-color, $black); } diff --git a/app/assets/stylesheets/dashboard.scss b/app/assets/stylesheets/dashboard.scss index ed283dfc0..2b2c16be3 100644 --- a/app/assets/stylesheets/dashboard.scss +++ b/app/assets/stylesheets/dashboard.scss @@ -513,13 +513,13 @@ .dashboard-actions { padding: 7px 0px 10px; - - .mute-form { + + form { margin: 0; padding: 0; display: inline; - input[type='submit'] { + input[type='submit'], button { height: 30.4px; border: 2px solid transparent; } @@ -747,6 +747,19 @@ padding: 50px 0px 120px; margin-bottom: -160px; line-height: 1.3em; + .manage-page-error { + background:$red; + color:white; + padding:20px 10px; + line-height: 1.4em; + border-radius: 3px; + } + .manage-page-success { + background:$green; + padding:20px 10px; + line-height: 1.4em; + border-radius: 3px; + } li { margin: 20px auto; } diff --git a/app/controllers/profile_pins_controller.rb b/app/controllers/profile_pins_controller.rb new file mode 100644 index 000000000..29d89dbc2 --- /dev/null +++ b/app/controllers/profile_pins_controller.rb @@ -0,0 +1,30 @@ +class ProfilePinsController < ApplicationController + before_action :authenticate_user!, only: %i[create] + + def create + @profile_pin = ProfilePin.new + @profile_pin.profile_id = current_user.id + @profile_pin.profile_type = "User" + @profile_pin.pinnable_id = profile_pin_params[:pinnable_id].to_i + @profile_pin.pinnable_type = "Article" + if @profile_pin.save! + flash[:pins_success] = "📌 Pinned! (pinned posts display chronologically, 5 max)" + else + flash[:pins_error] = "You can only have five pins" + end + redirect_back(fallback_location: "/dashboard") + end + + def update + # for removing pinnable + ProfilePin.find(params[:id]).destroy + flash[:pins_success] = "🗑 Pin removed" + redirect_back(fallback_location: "/dashboard") + end + + private + + def profile_pin_params + params.require(:profile_pin).permit(:pinnable_id) + end +end diff --git a/app/controllers/stories_controller.rb b/app/controllers/stories_controller.rb index 615e31701..317180e94 100644 --- a/app/controllers/stories_controller.rb +++ b/app/controllers/stories_controller.rb @@ -164,8 +164,12 @@ class StoriesController < ApplicationController return end assign_user_comments + @pinned_stories = Article.published.where(id: @user.profile_pins.pluck(:pinnable_id)). + limited_column_select. + order("published_at DESC").decorate @stories = ArticleDecorator.decorate_collection(@user.articles.published. limited_column_select. + where.not(id: @pinned_stories.pluck(:id)). order("published_at DESC").page(@page).per(user_signed_in? ? 2 : 5)) @article_index = true @list_of = "articles" diff --git a/app/javascript/history/history.jsx b/app/javascript/history/history.jsx index ae76a84b1..4096e2837 100644 --- a/app/javascript/history/history.jsx +++ b/app/javascript/history/history.jsx @@ -184,9 +184,8 @@ min read・ ); - } - return ''; - + } + return ''; } render() { diff --git a/app/javascript/listings/__tests__/listingDashboard.test.jsx b/app/javascript/listings/__tests__/listingDashboard.test.jsx index db9b15f79..3809e6c9a 100644 --- a/app/javascript/listings/__tests__/listingDashboard.test.jsx +++ b/app/javascript/listings/__tests__/listingDashboard.test.jsx @@ -5,12 +5,106 @@ import { ListingDashboard } from '../listingDashboard'; const doc = new JSDOM('
'); global.document = doc; -const l = [{id:23,bumped_at:"2019-06-11T16:45:37.229Z",category:"cfp",organization_id:null,slug:"asdfasdf-2ea8",title:"asdfasdf",updated_at:"2019-06-11T16:45:37.237Z",user_id:11,tag_list:["computerscience","career"],author:{name:"MarioSee",username:"mariocsee",profile_image_90:"/uploads/user/profile_image/11/e594d777-b57b-41d6-a793-5d8127bd11b3.jpeg"}},{id:24,bumped_at:"2019-06-11T16:59:16.312Z",category:"events",organization_id:2,slug:"yoyoyoyoyoooooooo-4jcb",title:"YOYOYOYOYOOOOOOOO",updated_at:"2019-06-11T16:59:16.316Z",user_id:11,tag_list:["computerscience","conference","career"],author:{name:"Yoyodyne",username:"org3737",profile_image_90:"/uploads/organization/profile_image/2/5edb1e49-bea9-4e99-bc32-acc10c52a935.png"}},{id:25,bumped_at:"2019-06-11T17:01:25.143Z",category:"cfp",organization_id:3,slug:"hehhehe-5hld",title:"hehhehe",updated_at:"2019-06-11T17:01:25.169Z",user_id:11,tag_list:[],author:{name:"Infotrode",username:"org5254",profile_image_90:"/uploads/organization/profile_image/3/04d4e1f1-c2e0-4147-81e2-bc8a2657296b.png"}}]; -global.document.body.innerHTML = ``; +const l = [ + { + id: 23, + bumped_at: '2019-06-11T16:45:37.229Z', + category: 'cfp', + organization_id: null, + slug: 'asdfasdf-2ea8', + title: 'asdfasdf', + updated_at: '2019-06-11T16:45:37.237Z', + user_id: 11, + tag_list: ['computerscience', 'career'], + author: { + name: 'MarioSee', + username: 'mariocsee', + profile_image_90: + '/uploads/user/profile_image/11/e594d777-b57b-41d6-a793-5d8127bd11b3.jpeg', + }, + }, + { + id: 24, + bumped_at: '2019-06-11T16:59:16.312Z', + category: 'events', + organization_id: 2, + slug: 'yoyoyoyoyoooooooo-4jcb', + title: 'YOYOYOYOYOOOOOOOO', + updated_at: '2019-06-11T16:59:16.316Z', + user_id: 11, + tag_list: ['computerscience', 'conference', 'career'], + author: { + name: 'Yoyodyne', + username: 'org3737', + profile_image_90: + '/uploads/organization/profile_image/2/5edb1e49-bea9-4e99-bc32-acc10c52a935.png', + }, + }, + { + id: 25, + bumped_at: '2019-06-11T17:01:25.143Z', + category: 'cfp', + organization_id: 3, + slug: 'hehhehe-5hld', + title: 'hehhehe', + updated_at: '2019-06-11T17:01:25.169Z', + user_id: 11, + tag_list: [], + author: { + name: 'Infotrode', + username: 'org5254', + profile_image_90: + '/uploads/organization/profile_image/3/04d4e1f1-c2e0-4147-81e2-bc8a2657296b.png', + }, + }, +]; +global.document.body.innerHTML = ``; global.window = doc.defaultView; -const listingState = { listings: - [ { id: 23, +const listingState = { + listings: [ + { + id: 23, bumped_at: '2019-06-11T16:45:37.229Z', category: 'cfp', organization_id: null, @@ -19,8 +113,10 @@ const listingState = { listings: updated_at: '2019-06-11T16:45:37.237Z', user_id: 11, tag_list: [Array], - author: [Object] }, - { id: 24, + author: [Object], + }, + { + id: 24, bumped_at: '2019-06-11T16:59:16.312Z', category: 'events', organization_id: 2, @@ -29,8 +125,10 @@ const listingState = { listings: updated_at: '2019-06-11T16:59:16.316Z', user_id: 11, tag_list: [Array], - author: [Object] }, - { id: 25, + author: [Object], + }, + { + id: 25, bumped_at: '2019-06-11T17:01:25.143Z', category: 'cfp', organization_id: 3, @@ -39,9 +137,12 @@ const listingState = { listings: updated_at: '2019-06-11T17:01:25.169Z', user_id: 11, tag_list: [], - author: [Object] } ], - orgListings: - [ { id: 24, + author: [Object], + }, + ], + orgListings: [ + { + id: 24, bumped_at: '2019-06-11T16:59:16.312Z', category: 'events', organization_id: 2, @@ -50,8 +151,10 @@ const listingState = { listings: updated_at: '2019-06-11T16:59:16.316Z', user_id: 11, tag_list: [Array], - author: [Object] }, - { id: 25, + author: [Object], + }, + { + id: 25, bumped_at: '2019-06-11T17:01:25.143Z', category: 'cfp', organization_id: 3, @@ -60,24 +163,22 @@ const listingState = { listings: updated_at: '2019-06-11T17:01:25.169Z', user_id: 11, tag_list: [], - author: [Object] } ], - orgs: - [ { id: 2, - name: 'Yoyodyne', - slug: 'org3737', - unspent_credits_count: 1 }, - { id: 3, - name: 'Infotrode', - slug: 'org5254', - unspent_credits_count: 1 } ], - userCredits: '3', - selectedListings: 'user' }; + author: [Object], + }, + ], + orgs: [ + { id: 2, name: 'Yoyodyne', slug: 'org3737', unspent_credits_count: 1 }, + { id: 3, name: 'Infotrode', slug: 'org5254', unspent_credits_count: 1 }, + ], + userCredits: '3', + selectedListings: 'user', +}; describe('