Listing Dashboard: Handle expired listings (#3442)
* wip filter active and expired listings * add published attribute to listings json * add expired class to listings row * filter through state * make span button tabbable * remove unused state * update snapshot test * add indicator and styles for expired * linting errors * clean up link * remove function argument * Update listingDashboard snapshot
This commit is contained in:
parent
d02324ed1c
commit
36535e546d
5 changed files with 125 additions and 54 deletions
|
|
@ -689,11 +689,15 @@ form.listings-contact-via-connect {
|
|||
}
|
||||
}
|
||||
|
||||
.dashboard-listings-sorting {
|
||||
.dashboard-listings-actions {
|
||||
padding-bottom: 15px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.listings-dashboard-filter-buttons {
|
||||
margin-bottom: -10px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 426px) {
|
||||
flex-direction: column;
|
||||
|
|
@ -736,7 +740,9 @@ form.listings-contact-via-connect {
|
|||
border-radius: 3px;
|
||||
position: relative;
|
||||
background: var(--theme-container-background, #fff);
|
||||
|
||||
&.expired {
|
||||
opacity: 0.7;
|
||||
}
|
||||
.listing-org {
|
||||
@include themeable(
|
||||
background,
|
||||
|
|
|
|||
|
|
@ -7,18 +7,24 @@ preact-render-spy (1 nodes)
|
|||
<span
|
||||
onClick={[Function onClick]}
|
||||
class="rounded-btn active"
|
||||
role="button"
|
||||
tabIndex="0"
|
||||
>
|
||||
Personal
|
||||
</span>
|
||||
<span
|
||||
onClick={[Function onClick]}
|
||||
class="rounded-btn "
|
||||
role="button"
|
||||
tabIndex="0"
|
||||
>
|
||||
Yoyodyne
|
||||
</span>
|
||||
<span
|
||||
onClick={[Function onClick]}
|
||||
class="rounded-btn "
|
||||
role="button"
|
||||
tabIndex="0"
|
||||
>
|
||||
Infotrode
|
||||
</span>
|
||||
|
|
@ -39,7 +45,33 @@ preact-render-spy (1 nodes)
|
|||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dashboard-listings-sorting">
|
||||
<div class="dashboard-listings-actions">
|
||||
<div class="listings-dashboard-filter-buttons">
|
||||
<span
|
||||
onClick={[Function onClick]}
|
||||
class="rounded-btn active"
|
||||
role="button"
|
||||
tabIndex="0"
|
||||
>
|
||||
All
|
||||
</span>
|
||||
<span
|
||||
onClick={[Function onClick]}
|
||||
class="rounded-btn "
|
||||
role="button"
|
||||
tabIndex="0"
|
||||
>
|
||||
Active
|
||||
</span>
|
||||
<span
|
||||
onClick={[Function onClick]}
|
||||
class="rounded-btn "
|
||||
role="button"
|
||||
tabIndex="0"
|
||||
>
|
||||
Expired
|
||||
</span>
|
||||
</div>
|
||||
<select onChange={[Function sortListings]}>
|
||||
<option
|
||||
value="created_at"
|
||||
|
|
@ -51,41 +83,29 @@ preact-render-spy (1 nodes)
|
|||
</select>
|
||||
</div>
|
||||
<div class="dashboard-listings-view">
|
||||
<div class="dashboard-listing-row">
|
||||
<a href="cfp/asdfasdf-2ea8">
|
||||
<h2>asdfasdf</h2>
|
||||
<div class="dashboard-listing-row expired">
|
||||
<span class="listing-org">Infotrode</span>
|
||||
<a href="cfp/hehhehe-5hld">
|
||||
<h2>hehhehe (expired)</h2>
|
||||
</a>
|
||||
<span class="dashboard-listing-date">Jun 11</span>
|
||||
<span class="dashboard-listing-category">
|
||||
<a href="/listings/cfp/">cfp</a>
|
||||
</span>
|
||||
<span class="dashboard-listing-tags">
|
||||
<a
|
||||
href="/listings?t=computerscience"
|
||||
data-no-instant={true}
|
||||
>
|
||||
#computerscience
|
||||
</a>
|
||||
<a
|
||||
href="/listings?t=career"
|
||||
data-no-instant={true}
|
||||
>
|
||||
#career
|
||||
</a>
|
||||
</span>
|
||||
<span class="dashboard-listing-tags"></span>
|
||||
<div class="listing-row-actions">
|
||||
<a
|
||||
href="/listings/23/edit"
|
||||
href="/listings/25/edit"
|
||||
class="dashboard-listing-edit-button cta pill green"
|
||||
>
|
||||
EDIT
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dashboard-listing-row">
|
||||
<div class="dashboard-listing-row expired">
|
||||
<span class="listing-org">Yoyodyne</span>
|
||||
<a href="events/yoyoyoyoyoooooooo-4jcb">
|
||||
<h2>YOYOYOYOYOOOOOOOO</h2>
|
||||
<h2>YOYOYOYOYOOOOOOOO (expired)</h2>
|
||||
</a>
|
||||
<span class="dashboard-listing-date">Jun 11</span>
|
||||
<span class="dashboard-listing-category">
|
||||
|
|
@ -120,19 +140,31 @@ preact-render-spy (1 nodes)
|
|||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dashboard-listing-row">
|
||||
<span class="listing-org">Infotrode</span>
|
||||
<a href="cfp/hehhehe-5hld">
|
||||
<h2>hehhehe</h2>
|
||||
<div class="dashboard-listing-row expired">
|
||||
<a href="cfp/asdfasdf-2ea8">
|
||||
<h2>asdfasdf (expired)</h2>
|
||||
</a>
|
||||
<span class="dashboard-listing-date">Jun 11</span>
|
||||
<span class="dashboard-listing-category">
|
||||
<a href="/listings/cfp/">cfp</a>
|
||||
</span>
|
||||
<span class="dashboard-listing-tags"></span>
|
||||
<span class="dashboard-listing-tags">
|
||||
<a
|
||||
href="/listings?t=computerscience"
|
||||
data-no-instant={true}
|
||||
>
|
||||
#computerscience
|
||||
</a>
|
||||
<a
|
||||
href="/listings?t=career"
|
||||
data-no-instant={true}
|
||||
>
|
||||
#career
|
||||
</a>
|
||||
</span>
|
||||
<div class="listing-row-actions">
|
||||
<a
|
||||
href="/listings/25/edit"
|
||||
href="/listings/23/edit"
|
||||
class="dashboard-listing-edit-button cta pill green"
|
||||
>
|
||||
EDIT
|
||||
|
|
|
|||
|
|
@ -19,18 +19,18 @@ export const ListingRow = ({ listing }) => {
|
|||
day: '2-digit',
|
||||
month: 'short',
|
||||
});
|
||||
const orgName = l =>
|
||||
l.organization_id ? (
|
||||
<span className="listing-org">{l.author.name}</span>
|
||||
) : (
|
||||
''
|
||||
);
|
||||
|
||||
const orgName = listing.organization_id ? (
|
||||
<span className="listing-org">{listing.author.name}</span>
|
||||
) : (
|
||||
''
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="dashboard-listing-row">
|
||||
{orgName(listing)}
|
||||
<a href={`${`${listing.category}/${listing.slug}`}`}>
|
||||
<h2>{listing.title}</h2>
|
||||
<div className={`dashboard-listing-row ${listing.published ? '' : 'expired'}`}>
|
||||
{orgName}
|
||||
<a href={`${listing.category}/${listing.slug}`}>
|
||||
<h2>{listing.title + (listing.published ? '' : " (expired)")}</h2>
|
||||
</a>
|
||||
<span className="dashboard-listing-date">
|
||||
{listingDate}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ export class ListingDashboard extends Component {
|
|||
orgs: [],
|
||||
userCredits: 0,
|
||||
selectedListings: 'user',
|
||||
filter: 'All',
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
|
|
@ -16,7 +17,7 @@ export class ListingDashboard extends Component {
|
|||
let listings = [];
|
||||
let orgs = [];
|
||||
let orgListings = [];
|
||||
listings = JSON.parse(container.dataset.listings);
|
||||
listings = JSON.parse(container.dataset.listings).sort((a,b) => (a.created_at > b.created_at) ? -1 : 1);
|
||||
orgs = JSON.parse(container.dataset.orgs);
|
||||
orgListings = JSON.parse(container.dataset.orglistings);
|
||||
const userCredits = container.dataset.usercredits;
|
||||
|
|
@ -30,18 +31,32 @@ export class ListingDashboard extends Component {
|
|||
userCredits,
|
||||
orgs,
|
||||
selectedListings,
|
||||
filter,
|
||||
} = this.state;
|
||||
|
||||
const showListings = (selected, userListings, organizationListings) => {
|
||||
return selected === 'user'
|
||||
? userListings.map(listing => <ListingRow listing={listing} />)
|
||||
: organizationListings.map(listing =>
|
||||
listing.organization_id === selected ? (
|
||||
<ListingRow listing={listing} />
|
||||
) : (
|
||||
''
|
||||
),
|
||||
);
|
||||
const filterListings = (listingsToFilter, selectedFilter) => {
|
||||
if (selectedFilter === "Expired") {
|
||||
return listingsToFilter.filter(listing => listing.published === false)
|
||||
} if (selectedFilter === "Active") {
|
||||
return listingsToFilter.filter(listing => listing.published === true)
|
||||
}
|
||||
return listingsToFilter
|
||||
}
|
||||
|
||||
const showListings = (selected, userListings, organizationListings, selectedFilter) => {
|
||||
let displayedListings;
|
||||
if (selected === 'user') {
|
||||
displayedListings = filterListings(userListings, selectedFilter)
|
||||
return displayedListings.map(listing => <ListingRow listing={listing} />)
|
||||
}
|
||||
displayedListings = filterListings(organizationListings, selectedFilter)
|
||||
return displayedListings.map(listing =>
|
||||
listing.organization_id === selected ? (
|
||||
<ListingRow listing={listing} />
|
||||
) : (
|
||||
''
|
||||
),
|
||||
);
|
||||
};
|
||||
|
||||
const sortListings = (event) => {
|
||||
|
|
@ -49,8 +64,22 @@ export class ListingDashboard extends Component {
|
|||
this.setState({listings: sortedListings});
|
||||
}
|
||||
|
||||
const filters = ["All", "Active", "Expired"];
|
||||
const filterButtons = filters.map(f => (
|
||||
<span
|
||||
onClick={(event) => {this.setState( {filter:event.target.textContent} )}}
|
||||
className={`rounded-btn ${filter === f ? 'active' : ''}`}
|
||||
role="button"
|
||||
tabIndex="0">
|
||||
{f}
|
||||
</span>
|
||||
))
|
||||
|
||||
const sortingDropdown = (
|
||||
<div class="dashboard-listings-sorting">
|
||||
<div class="dashboard-listings-actions">
|
||||
<div className="listings-dashboard-filter-buttons">
|
||||
{filterButtons}
|
||||
</div>
|
||||
<select onChange={sortListings} >
|
||||
<option value="created_at" selected="selected">Recently Created</option>
|
||||
<option value="bumped_at">Recently Bumped</option>
|
||||
|
|
@ -62,6 +91,8 @@ export class ListingDashboard extends Component {
|
|||
<span
|
||||
onClick={() => this.setState({ selectedListings: org.id })}
|
||||
className={`rounded-btn ${selectedListings === org.id ? 'active' : ''}`}
|
||||
role="button"
|
||||
tabIndex="0"
|
||||
>
|
||||
{org.name}
|
||||
</span>
|
||||
|
|
@ -100,6 +131,8 @@ export class ListingDashboard extends Component {
|
|||
className={`rounded-btn ${
|
||||
selectedListings === 'user' ? 'active' : ''
|
||||
}`}
|
||||
role="button"
|
||||
tabIndex="0"
|
||||
>
|
||||
Personal
|
||||
</span>
|
||||
|
|
@ -120,7 +153,7 @@ export class ListingDashboard extends Component {
|
|||
</div>
|
||||
{sortingDropdown}
|
||||
<div className="dashboard-listings-view">
|
||||
{showListings(selectedListings, listings, orgListings)}
|
||||
{showListings(selectedListings, listings, orgListings, filter)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
|
||||
<div id="classifieds-listings-dashboard" data-listings="<%= @classified_listings.to_json(
|
||||
only: %i[title tag_list created_at bumped_at updated_at category id user_id slug organization_id location],
|
||||
only: %i[title tag_list created_at bumped_at updated_at category id user_id slug organization_id location published],
|
||||
include: {
|
||||
author: { only: %i[username name], methods: %i[username profile_image_90] },
|
||||
},
|
||||
)%>" data-usercredits="<%= @user_credits %>"
|
||||
data-orglistings="<%= @org_listings.to_json(
|
||||
only: %i[title tag_list created_at bumped_at updated_at category id user_id slug organization_id location],
|
||||
only: %i[title tag_list created_at bumped_at updated_at category id user_id slug organization_id location published],
|
||||
include: {
|
||||
author: { only: %i[username name], methods: %i[username profile_image_90] },
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue