Crayonsification of Listings form (#10429)
* i dont know how to test * fix i guess * layout update * layout updates * edit * edit listing * fix * tags field * specs| * Update app/javascript/listings/__tests__/ContactViaConnect.test.jsx Co-authored-by: Fernando Valverde <fernando@visualcosita.com> Co-authored-by: Fernando Valverde <fernando@visualcosita.com>
This commit is contained in:
parent
d7976a75d6
commit
90d04a73db
21 changed files with 399 additions and 462 deletions
|
|
@ -82,6 +82,18 @@
|
|||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&--inverted {
|
||||
.crayons-layout__sidebar-right {
|
||||
order: -1;
|
||||
}
|
||||
@media (min-width: $breakpoint-m) {
|
||||
--layout: var(--layout-content-width) var(--layout-sidebar-left-width);
|
||||
.crayons-layout__sidebar-right {
|
||||
order: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.crayons-layout--3-cols {
|
||||
|
|
|
|||
|
|
@ -1,230 +1,6 @@
|
|||
@import 'variables';
|
||||
@import 'mixins';
|
||||
|
||||
.listings-container {
|
||||
&.listings-form-container {
|
||||
form {
|
||||
margin: 60px auto 0px;
|
||||
width: 100%;
|
||||
max-width: 580px;
|
||||
background: var(--card-bg);
|
||||
box-sizing: border-box;
|
||||
border: 1px solid var(--card-color-tertiary);
|
||||
@media screen and (min-width: 580px) {
|
||||
border-radius: 8px;
|
||||
margin: 20px auto 20px;
|
||||
}
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
header {
|
||||
padding: 25px 22px;
|
||||
border-top-left-radius: 8px;
|
||||
border-top-right-radius: 8px;
|
||||
}
|
||||
.listing-form-inner,
|
||||
.listings-form-inner {
|
||||
padding: 0px 15px 40px;
|
||||
@media screen and (min-width: 580px) {
|
||||
padding: 0px 15px 18px;
|
||||
}
|
||||
}
|
||||
.listing-back-button {
|
||||
font-size: 0.8em;
|
||||
margin: 2px 0px 8px;
|
||||
display: block;
|
||||
}
|
||||
h2 {
|
||||
font-size: 1.45em;
|
||||
color: var(--accent-brand);
|
||||
margin: 0px;
|
||||
}
|
||||
.listing-errors {
|
||||
background: $red;
|
||||
color: $black;
|
||||
padding: 20px;
|
||||
border-radius: 3px;
|
||||
h2 {
|
||||
color: $black;
|
||||
}
|
||||
}
|
||||
label {
|
||||
display: inline-block;
|
||||
font-size: 0.7em;
|
||||
margin: 12px 0px 3px;
|
||||
border-radius: 3px;
|
||||
padding: 6px 0px;
|
||||
font-weight: bold;
|
||||
}
|
||||
input {
|
||||
width: 100%;
|
||||
font-size: 18px;
|
||||
padding: 10px 7px;
|
||||
border-radius: 3px;
|
||||
border: 1px solid var(--form-border);
|
||||
background: var(--form-bg);
|
||||
color: var(--body-color);
|
||||
&[type='checkbox'] {
|
||||
width: 100px;
|
||||
}
|
||||
}
|
||||
textarea {
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
padding: 5px;
|
||||
font-size: 17px;
|
||||
border-radius: 3px;
|
||||
background: var(--form-bg);
|
||||
color: var(--body-color);
|
||||
border: 1px solid var(--form-border);
|
||||
}
|
||||
select {
|
||||
width: 100%;
|
||||
font-size: 20px;
|
||||
}
|
||||
details {
|
||||
cursor: pointer;
|
||||
font-size: 0.8em;
|
||||
padding: 8px 0px;
|
||||
color: var(--card-color-tertiary);
|
||||
}
|
||||
.cta-main-listing-form {
|
||||
border: 0px;
|
||||
padding: 12px 0px;
|
||||
border-radius: 3px;
|
||||
background-color: $dark-purple;
|
||||
background-image: linear-gradient(
|
||||
141deg,
|
||||
$dark-purple 0%,
|
||||
#1f89db 51%,
|
||||
#2981e5 75%
|
||||
);
|
||||
border-radius: 100px;
|
||||
font-size: 1.4em;
|
||||
color: white;
|
||||
margin-top: 20px;
|
||||
width: 380px;
|
||||
max-width: 90%;
|
||||
margin: 35px auto;
|
||||
display: block;
|
||||
text-align: center;
|
||||
@include themeable(
|
||||
box-shadow,
|
||||
theme-container-box-shadow,
|
||||
2px 2px 8px darken($light-medium-gray, 5%)
|
||||
);
|
||||
&.cta-draft {
|
||||
color: $black;
|
||||
background: $yellow;
|
||||
}
|
||||
}
|
||||
.listings-current-credits {
|
||||
position: fixed;
|
||||
bottom: 0px;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
padding: 18px 0px;
|
||||
background-color: #aecfef;
|
||||
background-image: linear-gradient(
|
||||
141deg,
|
||||
#aecfef 0%,
|
||||
#ddeeff 51%,
|
||||
#c8ebf1 75%
|
||||
);
|
||||
color: #32325d;
|
||||
text-align: center;
|
||||
z-index: 20;
|
||||
font-size: 0.85em;
|
||||
.listings-current-credits-inner {
|
||||
display: inline-block;
|
||||
margin: 20px;
|
||||
select {
|
||||
width: initial;
|
||||
}
|
||||
}
|
||||
a {
|
||||
text-decoration: underline;
|
||||
display: inline-block;
|
||||
color: var(--link-brand-color);
|
||||
}
|
||||
@media screen and (min-width: 580px) {
|
||||
font-size: 1.1em;
|
||||
}
|
||||
}
|
||||
.listings-unpublish {
|
||||
background: $red;
|
||||
}
|
||||
p {
|
||||
font-size: 0.8em;
|
||||
color: var(--card-color-tertiary);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.listingform__bodymarkdown {
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
padding: 5px;
|
||||
font-size: 17px;
|
||||
border-radius: 3px;
|
||||
background: var(--card-bg);
|
||||
margin-top: 10px;
|
||||
color: var(--body-color);
|
||||
border: 1px solid $light-medium-gray;
|
||||
}
|
||||
|
||||
.listingform__tagsoptions {
|
||||
border: 1px solid var(--card-color-tertiary);
|
||||
border-bottom-left-radius: 3px;
|
||||
border-bottom-right-radius: 3px;
|
||||
}
|
||||
|
||||
.listingform__tagoptionrow {
|
||||
padding: 10px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
&:hover {
|
||||
background: lighten($green, 27%);
|
||||
color: $black;
|
||||
}
|
||||
}
|
||||
|
||||
.listingform__tagsoptionsbottomrow,
|
||||
.listingform__tagsoptionrulesbutton,
|
||||
.listingform__tagrules--inactive {
|
||||
display: none; //not yet fully functional or relevant
|
||||
}
|
||||
|
||||
.listingform__tagoptionrow--active {
|
||||
background: $green;
|
||||
color: $black;
|
||||
&:hover {
|
||||
background: darken($green, 10%);
|
||||
}
|
||||
}
|
||||
|
||||
.listingform__label {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
font-size: 0.7em;
|
||||
margin: 8px 0px 3px 0px;
|
||||
border-radius: 3px;
|
||||
padding: 6px 0px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.listings-modal-background {
|
||||
z-index: 15;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.dashboard-listings-container {
|
||||
width: 800px;
|
||||
max-width: 96%;
|
||||
|
|
|
|||
|
|
@ -261,10 +261,8 @@
|
|||
}
|
||||
|
||||
&__tagname {
|
||||
font-family: var(--ff-monospace);
|
||||
color: var(--base-90);
|
||||
letter-spacing: -0.05em;
|
||||
font-weight: bold;
|
||||
font-weight: var(--fw-medium);
|
||||
}
|
||||
|
||||
&__tagoptionrow {
|
||||
|
|
|
|||
|
|
@ -35,3 +35,59 @@
|
|||
color: var(--card-color-tertiary);
|
||||
}
|
||||
}
|
||||
|
||||
// New/Edit Listing form
|
||||
// Tags dropdown
|
||||
// TODO: componetize styling..
|
||||
|
||||
.listingform {
|
||||
&__tagsoptions {
|
||||
@include generate-box(
|
||||
$level: 2,
|
||||
$bg: var(--card-bg),
|
||||
$border: var(--card-color),
|
||||
$color: var(--card-color)
|
||||
);
|
||||
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: calc(100%);
|
||||
z-index: 100;
|
||||
padding: var(--su-1);
|
||||
left: calc(var(--su-1) * -1);
|
||||
right: calc(var(--su-1) * -1);
|
||||
}
|
||||
|
||||
&__tagname {
|
||||
color: var(--base-90);
|
||||
font-weight: var(--fw-medium);
|
||||
}
|
||||
|
||||
&__tagoptionrow {
|
||||
cursor: pointer;
|
||||
color: var(--link-color);
|
||||
padding: var(--su-3);
|
||||
|
||||
&:hover {
|
||||
background: var(--link-bg-hover);
|
||||
.crayons-tag {
|
||||
color: var(--link-color-hover);
|
||||
}
|
||||
}
|
||||
|
||||
&--active {
|
||||
background: var(--link-bg-hover);
|
||||
.crayons-article-form__tagname {
|
||||
color: var(--link-color-hover);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__tagrules,
|
||||
&__tagsoptionrulesbutton,
|
||||
&__tagsoptionsbottomrow,
|
||||
&__tagrules--inactive {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ describe('<BodyMarkdown />', () => {
|
|||
const textArea = getByLabelText('Body Markdown');
|
||||
|
||||
expect(textArea.getAttribute('placeholder')).toEqual(
|
||||
'400 characters max, 12 line break max, no images allowed, *markdown is encouraged*',
|
||||
'...',
|
||||
);
|
||||
expect(textArea.getAttribute('maxLength')).toEqual('400');
|
||||
expect(textArea.value).toEqual(defaultValue);
|
||||
|
|
|
|||
|
|
@ -16,28 +16,22 @@ describe('<ContactViaConnect />', () => {
|
|||
|
||||
it('should render a checked check box opting in to open DMs', () => {
|
||||
const onChange = jest.fn();
|
||||
const { queryByLabelText } = render(
|
||||
const { getByText } = render(
|
||||
<ContactViaConnect onChange={onChange} checked />,
|
||||
);
|
||||
|
||||
expect(
|
||||
queryByLabelText(
|
||||
'Allow Users to Message Me Via In-App Chat (DEV Connect)',
|
||||
),
|
||||
).toBeDefined();
|
||||
expect(getByText('Allow Users to message me via Connect.')).toBeDefined();
|
||||
});
|
||||
|
||||
it('should fire a change event when clicking the checkbox', () => {
|
||||
const onChange = jest.fn();
|
||||
const { getByLabelText } = render(
|
||||
const { getByText } = render(
|
||||
<ContactViaConnect onChange={onChange} checked />,
|
||||
);
|
||||
|
||||
const checkbox = getByLabelText(
|
||||
'Allow Users to Message Me Via In-App Chat (DEV Connect)',
|
||||
);
|
||||
const checkbox = getByText('Allow Users to message me via Connect.');
|
||||
|
||||
fireEvent.input(checkbox, { target: { checked: true } });
|
||||
fireEvent.click(checkbox);
|
||||
|
||||
expect(onChange).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,19 +2,23 @@ import { h } from 'preact';
|
|||
import PropTypes from 'prop-types';
|
||||
|
||||
const BodyMarkdown = ({ onChange, defaultValue }) => (
|
||||
<div className="field">
|
||||
<label className="listingform__label" htmlFor="body_markdown">
|
||||
<div className="crayons-field">
|
||||
<label className="crayons-field__label" htmlFor="body_markdown">
|
||||
Body Markdown
|
||||
<textarea
|
||||
className="listingform__input listingform__bodymarkdown"
|
||||
id="body_markdown"
|
||||
name="listing[body_markdown]"
|
||||
maxLength="400"
|
||||
placeholder="400 characters max, 12 line break max, no images allowed, *markdown is encouraged*"
|
||||
value={defaultValue}
|
||||
onInput={onChange}
|
||||
/>
|
||||
</label>
|
||||
<textarea
|
||||
className="crayons-textfield"
|
||||
id="body_markdown"
|
||||
name="listing[body_markdown]"
|
||||
maxLength="400"
|
||||
placeholder="..."
|
||||
value={defaultValue}
|
||||
onInput={onChange}
|
||||
/>
|
||||
<p className="crayons-field__description">
|
||||
400 characters max, 12 line break max, no images allowed, *markdown is
|
||||
encouraged*
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@ class Categories extends Component {
|
|||
details = () => {
|
||||
const { categoriesForDetails } = this.props;
|
||||
const rules = categoriesForDetails.map((category) => {
|
||||
const paragraphText = `${category.name}: ${category.rules}`;
|
||||
return <p>{paragraphText}</p>;
|
||||
const paragraphText = <li><strong>{category.name}:</strong> {category.rules}</li>;
|
||||
return <ul>{paragraphText}</ul>;
|
||||
});
|
||||
|
||||
return (
|
||||
|
|
@ -35,19 +35,21 @@ class Categories extends Component {
|
|||
render() {
|
||||
const { onChange } = this.props;
|
||||
return (
|
||||
<div className="field">
|
||||
<label className="listingform__label" htmlFor="category">
|
||||
Category
|
||||
</label>
|
||||
<select
|
||||
id="category"
|
||||
className="listingform__input"
|
||||
name="listing[listing_category_id]"
|
||||
onChange={onChange}
|
||||
onBlur={onChange}
|
||||
>
|
||||
{this.options()}
|
||||
</select>
|
||||
<div>
|
||||
<div className="crayons-field mb-4">
|
||||
<label className="crayons-field__label" htmlFor="category">
|
||||
Category
|
||||
</label>
|
||||
<select
|
||||
id="category"
|
||||
className="crayons-select"
|
||||
name="listing[listing_category_id]"
|
||||
onChange={onChange}
|
||||
onBlur={onChange}
|
||||
>
|
||||
{this.options()}
|
||||
</select>
|
||||
</div>
|
||||
{this.details()}
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -2,22 +2,26 @@ import { h } from 'preact';
|
|||
import PropTypes from 'prop-types';
|
||||
|
||||
const ContactViaConnect = ({ onChange, checked }) => (
|
||||
<div className="field">
|
||||
<label
|
||||
id="label-contact-via-connect"
|
||||
className="listingform__label"
|
||||
htmlFor="contact_via_connect"
|
||||
>
|
||||
Allow Users to Message Me Via In-App Chat (DEV Connect)
|
||||
</label>
|
||||
<div className="crayons-field crayons-field--checkbox">
|
||||
<input
|
||||
type="checkbox"
|
||||
className="listingform__input listingform__contact_via_connect"
|
||||
className="crayons-checkbox"
|
||||
id="contact_via_connect"
|
||||
name="listing[contact_via_connect]"
|
||||
onInput={onChange}
|
||||
checked={checked}
|
||||
/>
|
||||
|
||||
<label
|
||||
id="label-contact-via-connect"
|
||||
className="crayons-field__label"
|
||||
htmlFor="contact_via_connect"
|
||||
>
|
||||
Connect messaging
|
||||
<p className="crayons-field__description">
|
||||
Allow Users to message me via Connect.
|
||||
</p>
|
||||
</label>
|
||||
</div>
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -10,14 +10,16 @@ const ExpireDate = ({ onChange, defaultValue }) => {
|
|||
[monthFromToday] = monthFromToday.toISOString().split('T');
|
||||
|
||||
return (
|
||||
<div className="field">
|
||||
<label className="listingform__label" htmlFor="expires_at">
|
||||
Custom Expire Date (if applicable for time sensitive events, deadlines,
|
||||
etc.)
|
||||
<div className="crayons-field">
|
||||
<label className="crayons-field__label" htmlFor="expires_at">
|
||||
Custom Expire Date
|
||||
<p class="crayons-field__description">
|
||||
If applicable for time sensitive events, deadlines, etc.
|
||||
</p>
|
||||
</label>
|
||||
<input
|
||||
type="date"
|
||||
className="listingform__input"
|
||||
className="crayons-textfield m:max-w-50"
|
||||
id="expires_at"
|
||||
name="listing[expires_at]"
|
||||
value={defaultValue}
|
||||
|
|
|
|||
|
|
@ -4,13 +4,11 @@ import { h } from 'preact';
|
|||
const domId = 1;
|
||||
|
||||
const Title = ({ onChange, defaultValue }) => (
|
||||
<div className="field">
|
||||
<label className="listingform__label" htmlFor={domId}>
|
||||
Title
|
||||
</label>
|
||||
<div className="crayons-field">
|
||||
<label className="crayons-field__label" htmlFor={domId}>Title</label>
|
||||
<input
|
||||
type="text"
|
||||
className="listingform__input"
|
||||
className="crayons-textfield"
|
||||
id={domId}
|
||||
name="listing[title]"
|
||||
maxLength="128"
|
||||
|
|
|
|||
|
|
@ -64,24 +64,28 @@ export default class ListingForm extends Component {
|
|||
|
||||
const selectOrg =
|
||||
organizations && organizations.length > 0 ? (
|
||||
<div className="field">
|
||||
<label htmlFor="organizationId">Post under an organization:</label>
|
||||
<div className="crayons-field">
|
||||
<label htmlFor="organizationId" className="crayons-field__label">
|
||||
Post under an organization
|
||||
</label>
|
||||
<OrganizationPicker
|
||||
name="listing[organization_id]"
|
||||
id="listing_organization_id"
|
||||
className="crayons-select m:max-w-50"
|
||||
organizations={organizations}
|
||||
organizationId={organizationId}
|
||||
onToggle={this.handleOrgIdChange}
|
||||
/>
|
||||
<p>
|
||||
<em>Posting on behalf of org spends org credits.</em>
|
||||
<p className="crayons-field__description">
|
||||
Posting on behalf of an organization spends the organization's
|
||||
credits.
|
||||
</p>
|
||||
</div>
|
||||
) : null;
|
||||
|
||||
if (id === null) {
|
||||
return (
|
||||
<div>
|
||||
<div className="grid gap-6">
|
||||
<Title defaultValue={title} onChange={linkState(this, 'title')} />
|
||||
<BodyMarkdown
|
||||
defaultValue={bodyMarkdown}
|
||||
|
|
@ -93,16 +97,19 @@ export default class ListingForm extends Component {
|
|||
onChange={linkState(this, 'category')}
|
||||
category={category}
|
||||
/>
|
||||
<Tags
|
||||
defaultValue={tagList}
|
||||
category={category}
|
||||
onInput={linkState(this, 'tagList')}
|
||||
classPrefix="listingform"
|
||||
maxTags={8}
|
||||
autocomplete="off"
|
||||
listing
|
||||
pattern={DEFAULT_TAG_FORMAT}
|
||||
/>
|
||||
<div className="relative">
|
||||
<Tags
|
||||
defaultValue={tagList}
|
||||
category={category}
|
||||
onInput={linkState(this, 'tagList')}
|
||||
classPrefix="listingform"
|
||||
fieldClassName="crayons-textfield"
|
||||
maxTags={8}
|
||||
autocomplete="off"
|
||||
listing
|
||||
pattern={DEFAULT_TAG_FORMAT}
|
||||
/>
|
||||
</div>
|
||||
<ExpireDate
|
||||
defaultValue={expireDate}
|
||||
onChange={linkState(this, 'expireDate')}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ function loadElement() {
|
|||
categoriesForDetails={categoriesForDetails}
|
||||
/>,
|
||||
root,
|
||||
root.firstElementChild,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,16 +2,18 @@ const orgCreditsSelect = document.getElementById('org-credits-select');
|
|||
const orgCreditsNumber = document.getElementById('org-credits-number');
|
||||
const orgCreditsLink = document.getElementById('org-credits-purchase-link');
|
||||
|
||||
orgCreditsNumber.innerText =
|
||||
orgCreditsSelect.selectedOptions[0].dataset.credits;
|
||||
if (orgCreditsSelect) {
|
||||
orgCreditsNumber.innerText =
|
||||
orgCreditsSelect.selectedOptions[0].dataset.credits;
|
||||
|
||||
const changeOrgCredits = event => {
|
||||
const selectedOrgCreditsCount =
|
||||
event.target.selectedOptions[0].dataset.credits;
|
||||
const selectedOrgId = event.target.selectedOptions[0].value;
|
||||
const changeOrgCredits = (event) => {
|
||||
const selectedOrgCreditsCount =
|
||||
event.target.selectedOptions[0].dataset.credits;
|
||||
const selectedOrgId = event.target.selectedOptions[0].value;
|
||||
|
||||
orgCreditsNumber.innerText = selectedOrgCreditsCount;
|
||||
orgCreditsLink.href = `/credits/purchase?organization_id=${selectedOrgId}`;
|
||||
};
|
||||
orgCreditsNumber.innerText = selectedOrgCreditsCount;
|
||||
orgCreditsLink.href = `/credits/purchase?organization_id=${selectedOrgId}`;
|
||||
};
|
||||
|
||||
orgCreditsSelect.addEventListener('change', changeOrgCredits);
|
||||
orgCreditsSelect.addEventListener('change', changeOrgCredits);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -430,8 +430,8 @@ class Tags extends Component {
|
|||
}
|
||||
|
||||
return (
|
||||
<div className={`${classPrefix}__tagswrapper`}>
|
||||
{listing && <label htmlFor="Tags">Tags</label>}
|
||||
<div className={`${classPrefix}__tagswrapper crayons-field`}>
|
||||
{listing && <label htmlFor="Tags" class="crayons-field__label">Tags</label>}
|
||||
<input
|
||||
data-testid="tag-input"
|
||||
aria-label="Post Tags"
|
||||
|
|
|
|||
|
|
@ -1,9 +1,5 @@
|
|||
<%= form_with(model: listing, local: true) do |form| %>
|
||||
<header>
|
||||
<a href="/listings/dashboard" class="listings-back-button">< return to listings dashboard</a>
|
||||
<h2>Create a Community Listing</h2>
|
||||
</header>
|
||||
<div class="listing-form-inner">
|
||||
<div class="crayons-card p-6 mb-6 grid gap-6">
|
||||
<%= render partial: "form_errors", locals: { listing: listing } %>
|
||||
|
||||
<div id="listingform-data"
|
||||
|
|
@ -11,23 +7,28 @@
|
|||
data-organizations="<%= @organizations.to_json(only: %i[id name]) %>"
|
||||
data-categories-for-select="<%= select_options_for_categories.to_json %>"
|
||||
data-categories-for-details="<%= categories_available.transform_values { |value_hash| value_hash.except(:cost) }.values.to_json %>">
|
||||
<div style="height: 745px;">
|
||||
<div class="field">
|
||||
<%= form.label "title" %>
|
||||
<%= form.text_field "title", placeholder: "128 characters max, plain text" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= form.label "body_markdown", "Body Markdown" %>
|
||||
<%= form.text_area "body_markdown", placeholder: "400 characters max, 12 line break max, no images allowed" %>
|
||||
<div class="grid gap-6">
|
||||
<div class="crayons-field">
|
||||
<%= form.label "title", class: "crayons-label" %>
|
||||
<%= form.text_field "title", placeholder: "128 characters max, plain text", class: "crayons-textfield" %>
|
||||
</div>
|
||||
|
||||
<div class="field" style="padding-top: 9px">
|
||||
<label>Category</label>
|
||||
<select>
|
||||
<option>
|
||||
Conference CFP (1 Credit)
|
||||
</option>
|
||||
</select>
|
||||
<div class="crayons-field">
|
||||
<%= form.label "body_markdown", "Body Markdown", class: "crayons-field__label" %>
|
||||
<%= form.text_area "body_markdown", placeholder: "...", class: "crayons-textfield" %>
|
||||
<p class="crayons-field__description">400 characters max, 12 line break max, no images allowed, *markdown is encouraged*</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="crayons-field mb-4">
|
||||
<label class="crayons-field__label" id="listing_category_placeholder">Category</label>
|
||||
<select class="crayons-select" id="listing_category_placeholder">
|
||||
<option>
|
||||
Conference CFP (1 Credit)
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<details>
|
||||
<summary>Category details/rules</summary>
|
||||
</details>
|
||||
|
|
@ -37,59 +38,71 @@
|
|||
SSR. By having the form field loaded on the DOM first with this view,
|
||||
we prevent the screen from "jumping" once the deferred JS is loaded
|
||||
and executed. %>
|
||||
<div class="field">
|
||||
<%= form.label "tag_list", "Tags" %>
|
||||
<%= form.text_field "tag_list", placeholder: "8 tags max, comma separated, no spaces or special characters" %>
|
||||
<div class="crayons-field">
|
||||
<%= form.label "tag_list", "Tags", class: "crayons-field__label" %>
|
||||
<%= form.text_field "tag_list", placeholder: "Add up to 8 tags...", class: "crayons-textfield" %>
|
||||
</div>
|
||||
<% if @organizations.present? && @organizations.size > 0 %>
|
||||
<div class="field">
|
||||
<%= form.label "organization_id", "Post under an organization:" %>
|
||||
<%= form.select :organization_id, "None" => "None" %>
|
||||
<p><em>Posting on behalf of an organization spends the organization's credits.</em></p>
|
||||
|
||||
<div class="crayons-field">
|
||||
<label class="crayons-field__label" for="expires_at_placeholder">
|
||||
Custom Expire Date
|
||||
<p class="crayons-field__description">
|
||||
If applicable for time sensitive events, deadlines, etc.
|
||||
</p>
|
||||
</label>
|
||||
<input
|
||||
type="date"
|
||||
class="crayons-textfield m:max-w-50"
|
||||
id="expires_at_placeholder" />
|
||||
</div>
|
||||
|
||||
<% if @organizations.present? && @organizations.size > 0 %>
|
||||
<div class="crayons-field">
|
||||
<%= form.label "organization_id", "Post under an organization", class: "crayons-field__label" %>
|
||||
<%= form.select :organization_id, { "None" => "None"}, {}, {class: "crayons-select m:max-w-50"} %>
|
||||
<p class="crayons-field__description">Posting on behalf of an organization spends the organization's credits.</p>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="crayons-field crayons-field--checkbox">
|
||||
<input
|
||||
type="checkbox"
|
||||
class="crayons-checkbox"
|
||||
id="contact_via_connect_placeholder"
|
||||
checked=true />
|
||||
|
||||
<label class="crayons-field__label" for="contact_via_connect_placeholder">
|
||||
Connect messaging
|
||||
<p class="crayons-field__description">Allow Users to message me via Connect.</p>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% unless @organizations.present? %>
|
||||
<%= javascript_packs_with_chunks_tag "listingForm", defer: true %>
|
||||
<% end %>
|
||||
<div class="field">
|
||||
<%= form.label "location", "Location (If applicable for events, etc.)" %>
|
||||
<%= form.text_field "location", placeholder: "32 characters max, plain text" %>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<br />
|
||||
<p>You will not be charged credits to save a draft.</p>
|
||||
<%= form.button "SAVE DRAFT", type: "submit", name: "listing[action]", class: "cta cta-main-listing-form cta-draft", value: "draft" %>
|
||||
<% if @credits.size > 0 || (@organizations.present? && @organizations.sum(:unspent_credits_count) > 0) %>
|
||||
<%= form.submit "PUBLISH LISTING", class: "cta cta-main-listing-form" %>
|
||||
<% else %>
|
||||
<p>You need at least one credit to create a listing.</p>
|
||||
<a href="/credits/new" class="cta cta-main-listing-form" data-no-instant>Purchase Credits Now</a>
|
||||
<% end %>
|
||||
</div>
|
||||
<p><em><%= community_name %> admins may modify tags and categories to ensure accuracy. We may also take down and refund inappropriate listings.</em></p>
|
||||
<p><em>Listings expire 30 days after they are published or "bumped".</em></p>
|
||||
<div class="listings-current-credits">
|
||||
<% if @credits.size == 0 && (@organizations.blank? || @organizations.sum(:unspent_credits_count).zero?) %>
|
||||
<h3>Listings Require Credits</h3>
|
||||
<% end %>
|
||||
<div class="listings-current-credits-inner">
|
||||
You have <%= pluralize @credits.size, "credit" %> available — <a target="_blank" rel="noopener noreferrer" href="/credits/purchase" data-no-instant>Buy More</a>
|
||||
</div>
|
||||
<% if @organizations.present? %>
|
||||
<div class="listings-current-credits-inner">
|
||||
<select id="org-credits-select" class="org-credits-select">
|
||||
<% @organizations.each do |org| %>
|
||||
<option value="<%= org.id %>" data-credits="<%= org.credits.unspent.size %>"><%= org.name %></option>
|
||||
<% end %>
|
||||
</select>
|
||||
has <span id="org-credits-number"><%= @organizations.first.credits.unspent.size %></span> credits -
|
||||
<a id="org-credits-purchase-link" target="_blank" rel="noopener noreferrer" href="/credits/purchase?organization_id=<%= @organizations.first.id %>" data-no-instant>Buy More</a>
|
||||
</div>
|
||||
<%= javascript_packs_with_chunks_tag "listingForm", "orgCreditsSelector", defer: true %>
|
||||
<% end %>
|
||||
<% unless @organizations.present? %>
|
||||
<%= javascript_packs_with_chunks_tag "listingForm", defer: true %>
|
||||
<% end %>
|
||||
|
||||
<div class="crayons-field">
|
||||
<%= form.label "location", "Location (If applicable for events, etc.)", class: "crayons-field__label" %>
|
||||
<%= form.text_field "location", placeholder: "New York", class: "crayons-textfield m:max-w-50" %>
|
||||
<p class="crayons-field__description">32 characters max, plain text</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="px-4 m:px-0">
|
||||
<% unless @credits.size > 0 || (@organizations.present? && @organizations.sum(:unspent_credits_count) > 0) %>
|
||||
<div class="crayons-notice mb-4">You need at least one credit to create a listing.</div>
|
||||
<% end %>
|
||||
<div class="flex mb-4 items-center">
|
||||
<% if @credits.size > 0 || (@organizations.present? && @organizations.sum(:unspent_credits_count) > 0) %>
|
||||
<%= form.submit "Publish listing", class: "crayons-btn mr-2" %>
|
||||
<% else %>
|
||||
<a href="/credits/new" class="crayons-btn mr-2" data-no-instant>Purchase credits</a>
|
||||
<% end %>
|
||||
<%= form.button "Save draft", type: "submit", name: "listing[action]", class: "crayons-btn crayons-btn--secondary", value: "draft" %>
|
||||
</div>
|
||||
|
||||
<p class="fs-s color-base-70 mb-6">You will not be charged credits to save a draft.</p>
|
||||
</div>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<% if listing.errors.any? %>
|
||||
<div class="listing-errors">
|
||||
<h2><%= pluralize(listing.errors.count, "error") %> prohibited this listing from being saved:</h2>
|
||||
<div class="crayons-notice crayons-notice--danger">
|
||||
<h2 class="fs-l"><%= pluralize(listing.errors.count, "error") %> prohibited this listing from being saved:</h2>
|
||||
<ul>
|
||||
<% listing.errors.full_messages.each do |message| %>
|
||||
<li><%= message %></li>
|
||||
|
|
|
|||
|
|
@ -1,82 +1,111 @@
|
|||
<% title "Edit Listing" %>
|
||||
|
||||
<div class="listings-container listings-form-container">
|
||||
<%= form_for(@listing) do |f| %>
|
||||
<header>
|
||||
<a href="/listings/dashboard" class="listings-back-button">< return to listings dashboard</a>
|
||||
<h2>You can only edit title/body/tags of drafts or within the first 24 hours of listing or bumping</h2>
|
||||
</header>
|
||||
<div class="listings-form-inner">
|
||||
<%= render partial: "form_errors", locals: { listing: @listing } %>
|
||||
<header class="crayons-layout crayons-layout--limited flex items-center justify-between p-2 l:p-4 l:pb-0">
|
||||
<h1 class="fs-2xl s:fs-3xl">Edit Listing</h1>
|
||||
</header>
|
||||
|
||||
<% if (@listing.bumped_at && @listing.bumped_at > 24.hours.ago) || @listing.updated_at && !@listing.published %>
|
||||
<div class="field">
|
||||
<%= f.label "title", "Title" %>
|
||||
<%= f.text_field "title", maxlength: 128, placeholder: "128 characters max, plain text" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label "body_markdown", "Body Markdown" %>
|
||||
<%= f.text_area "body_markdown", maxlength: 400, placeholder: "400 characters max, 12 line break max, no images allowed" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label "tag_list", "Tags" %>
|
||||
<%= f.text_field "tag_list", value: @listing.cached_tag_list, placeholder: "8 tags max, comma separated, no spaces or special characters" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label "location", "Location" %>
|
||||
<%= f.text_field "location", maxlength: 32, placeholder: "32 characters max, plain text" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label "expires_at", "Custom Expire Date" %>
|
||||
<%= f.date_field "expires_at", min: Date.tomorrow, max: @listing.natural_expiration_date %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label "contact_via_connect", "Allow Users to Message Me Via In-App Chat (#{community_name} Connect)" %>
|
||||
<%= f.check_box "contact_via_connect" %>
|
||||
</div>
|
||||
<% if @listing.published %>
|
||||
<%= f.submit "Update Listings Info", class: "cta cta-main-listing-form" %>
|
||||
<main class="crayons-layout crayons-layout--2-cols crayons-layout--2-cols--inverted crayons-layout--limited">
|
||||
<div class="crayons-layout__content">
|
||||
<div class="crayons-card mb-6 p-6">
|
||||
<%= form_for(@listing, html: { class: "grid gap-6 mb-6" }) do |f| %>
|
||||
<div class="crayons-notice">You can only edit title/body/tags of drafts or within the first 24 hours of listing or bumping</div>
|
||||
|
||||
<%= render partial: "form_errors", locals: { listing: @listing } %>
|
||||
|
||||
<% if (@listing.bumped_at && @listing.bumped_at > 24.hours.ago) || @listing.updated_at && !@listing.published %>
|
||||
<div class="crayons-field">
|
||||
<%= f.label "title", "Title", class: "crayons-field__label" %>
|
||||
<%= f.text_field "title", maxlength: 128, placeholder: "128 characters max, plain text", class: "crayons-textfield" %>
|
||||
</div>
|
||||
<div class="crayons-field">
|
||||
<%= f.label "body_markdown", "Body Markdown", class: "crayons-field__label" %>
|
||||
<%= f.text_area "body_markdown", maxlength: 400, placeholder: "...", class: "crayons-textfield" %>
|
||||
<p class="crayons-field__description">400 characters max, 12 line break max, no images allowed, *markdown is encouraged*</p>
|
||||
</div>
|
||||
<div class="crayons-field">
|
||||
<%= f.label "tag_list", "Tags", class: "crayons-field__label" %>
|
||||
<%= f.text_field "tag_list", value: @listing.cached_tag_list, placeholder: "8 tags max, comma separated, no spaces or special characters", class: "crayons-textfield" %>
|
||||
</div>
|
||||
<div class="crayons-field">
|
||||
<%= f.label "expires_at", "Custom Expire Date", class: "crayons-field__label" %>
|
||||
<%= f.date_field "expires_at", min: Date.tomorrow, max: @listing.natural_expiration_date, class: "crayons-textfield m:max-w-50" %>
|
||||
<p class="crayons-field__description">
|
||||
If applicable for time sensitive events, deadlines, etc.
|
||||
</p>
|
||||
</div>
|
||||
<div class="crayons-field crayons-field--checkbox">
|
||||
<%= f.check_box "contact_via_connect", class: "crayons-checkbox" %>
|
||||
<label class="crayons-field__label" for="contact_via_connect">
|
||||
Connect messaging
|
||||
<p class="crayons-field__description">Allow Users to message me via Connect.</p>
|
||||
</label>
|
||||
</div>
|
||||
<div class="crayons-field">
|
||||
<%= f.label "location", "Location", class: "crayons-field__label" %>
|
||||
<%= f.text_field "location", maxlength: 32, placeholder: "New York", class: "crayons-textfield m:max-w-50" %>
|
||||
<p class="crayons-field__description">32 characters max, plain text</p>
|
||||
</div>
|
||||
<div>
|
||||
<% if @listing.published %>
|
||||
<%= f.submit "Update listing", class: "crayons-btn" %>
|
||||
<% else %>
|
||||
<%= f.submit "Update draft", class: "crayons-btn crayons-btn--secondary" %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<%= form_for(@listing, html: { class: "pt-6 mt-6 border-t-1 border-solid border-0 border-base-20 flex items-center" }) do |f| %>
|
||||
<% if @listing.published == false %>
|
||||
<input type="hidden" name="listing[action]" value="publish" />
|
||||
<%= f.submit "Publish listing", class: "crayons-btn mr-4" %>
|
||||
<p>This listing is <strong class="color-accent-danger">not</strong> published.</p>
|
||||
<% else %>
|
||||
<%= f.submit "Update Draft", class: "cta cta-main-listing-form cta-draft" %>
|
||||
<input type="hidden" name="listing[action]" value="unpublish" />
|
||||
<%= f.submit "Unpublish listing", class: "crayons-btn crayons-btn--danger" %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% if @listing.bumped_at %>
|
||||
<%= form_for(@listing) do |f| %>
|
||||
<header>
|
||||
<a href="<%= @listing.path %>" class="listings-back-button" style="font-size: 1.1em;">Last Published/Bumped: <%= time_ago_in_words @listing.bumped_at %> ago</a>
|
||||
<h2>You can bump your listing for the same price as the original listing</h2>
|
||||
</header>
|
||||
<div class="listing-form-inner">
|
||||
<% if (@listing.natural_expiration_date) < Date.today %>
|
||||
<h4>
|
||||
(Expired <%= time_ago_in_words @listing.natural_expiration_date %> ago)
|
||||
</h4>
|
||||
<% else %>
|
||||
<h4>
|
||||
(Expires in <%= time_ago_in_words @listing.natural_expiration_date %>)
|
||||
</h4>
|
||||
<% end %>
|
||||
|
||||
<% if @listing.bumped_at %>
|
||||
<%= form_for(@listing, html: { class: "crayons-card grid gap-6 p-6 mb-6" }) do |f| %>
|
||||
<header>
|
||||
<h2 class="mb-2">Bump your listing</h2>
|
||||
<p>You can bump your listing for the same price as the original listing</p>
|
||||
</header>
|
||||
<div class="flex items-center">
|
||||
<%= f.submit "Bump listing", class: "crayons-btn crayons-btn--secondary mr-4" %>
|
||||
<p class="color-base-70">Last Published/Bumped: <%= time_ago_in_words @listing.bumped_at %> ago</p>
|
||||
</div>
|
||||
<input type="hidden" name="listing[action]" value="bump" />
|
||||
<%= f.submit "Bump Listing", class: "cta cta-main-listing-form" %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<%= form_for(@listing) do |f| %>
|
||||
<div class="listing-form-inner">
|
||||
<% unless @listing.published %>
|
||||
<h2 style="text-align: center; margin-top: 15px;">
|
||||
This listing is not published
|
||||
</h2>
|
||||
<% end %>
|
||||
<% if @listing.published == false %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<aside class="crayons-layout__sidebar-right px-3 m:px-0">
|
||||
<% unless @listing.published %>
|
||||
<%= form_for(@listing, html: { class: "crayons-card crayons-card--secondary p-3 m:p-4 mb-2 m:mb-4" }) do |f| %>
|
||||
<p class="pb-4">
|
||||
This listing is <strong class="color-accent-danger">not</strong> published
|
||||
</p>
|
||||
<input type="hidden" name="listing[action]" value="publish" />
|
||||
<%= f.submit "Publish Listing", class: "cta listings-publish cta-main-listing-form" %>
|
||||
<% else %>
|
||||
<input type="hidden" name="listing[action]" value="unpublish" />
|
||||
<%= f.submit "Unpublish Listing", class: "cta listings-unpublish cta-main-listing-form" %>
|
||||
<%= f.submit "Publish listing", class: "crayons-btn w-100" %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<div class="crayons-card crayons-card--secondary p-3 m:p-4 mb-2 m:mb-4">
|
||||
<p>
|
||||
<% if (@listing.natural_expiration_date) < Date.today %>
|
||||
Expired <%= time_ago_in_words @listing.natural_expiration_date %> ago
|
||||
<% else %>
|
||||
Expires in <%= time_ago_in_words @listing.natural_expiration_date %>
|
||||
<% end %>
|
||||
</p>
|
||||
<% if @listing.bumped_at %>
|
||||
<p class="pt-3 mt-3 border-t-1 border-solid border-0 border-base-10">
|
||||
Last Published/Bumped: <%= time_ago_in_words @listing.bumped_at %> ago
|
||||
</p>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</aside>
|
||||
</main>
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
<% end %>
|
||||
|
||||
<header class="crayons-layout flex items-center justify-between p-2 l:p-4 l:pb-0">
|
||||
<h1 class="">Listings</h1>
|
||||
<h1 class="fs-2xl s:fs-3xl">Listings</h1>
|
||||
|
||||
<div class="flex items-center">
|
||||
<a href="<%= new_listing_path %>" class="crayons-btn crayons-btn--secondary">Create</a>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,44 @@
|
|||
<% title "New Listing" %>
|
||||
|
||||
<div class="listings-container listings-form-container" id="listings-container">
|
||||
<%= render "form", listing: @listing %>
|
||||
</div>
|
||||
<header class="crayons-layout crayons-layout--limited flex items-center justify-between p-2 l:p-4 l:pb-0">
|
||||
<h1 class="fs-2xl s:fs-3xl">Create a Community Listing</h1>
|
||||
</header>
|
||||
|
||||
<main class="crayons-layout crayons-layout--2-cols crayons-layout--2-cols--inverted crayons-layout--limited">
|
||||
<div class="crayons-layout__content">
|
||||
<%= render "form", listing: @listing %>
|
||||
</div>
|
||||
<aside class="crayons-layout__sidebar-right px-3 m:px-0">
|
||||
<div class="crayons-card crayons-card--secondary p-3 m:p-6 mb-2 m:mb-4">
|
||||
<span class="color-base-60">Personal credits</span>
|
||||
<div class="flex m:flex-col items-center m:items-start justify-between">
|
||||
<strong class="fs-2xl m:fs-3xl lh-tight color-base-90 m:mb-4 block" id="test-credits-size"><%= @credits.size %></strong>
|
||||
<a target="_blank" rel="noopener noreferrer" class="crayons-btn crayons-btn--secondary m:w-100" href="/credits/purchase" data-no-instant>Buy more</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<% if @organizations.present? %>
|
||||
<div class="crayons-card crayons-card--secondary p-3 m:p-6 mb-4">
|
||||
<span class="color-base-60">Organization credits</label>
|
||||
<% if @organizations.size > 1 %>
|
||||
<select id="org-credits-select" class="org-credits-select crayons-select my-2">
|
||||
<% @organizations.each do |org| %>
|
||||
<option value="<%= org.id %>" data-credits="<%= org.credits.unspent.size %>"><%= org.name %></option>
|
||||
<% end %>
|
||||
</select>
|
||||
<% end %>
|
||||
<div class="flex m:flex-col items-center m:items-start justify-between">
|
||||
<strong class="fs-2xl m:fs-3xl lh-tight color-base-90 m:mb-4 block" id="org-credits-number"><%= @organizations.first.credits.unspent.size %></strong>
|
||||
<a id="org-credits-purchase-link" target="_blank" rel="noopener noreferrer" class="crayons-btn crayons-btn--secondary m:w-100" href="/credits/purchase?organization_id=<%= @organizations.first.id %>" data-no-instant>Buy more</a>
|
||||
</div>
|
||||
<%= javascript_packs_with_chunks_tag "listingForm", "orgCreditsSelector", defer: true %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="fs-s color-base-60 mb-4">
|
||||
<h3 class="fs-base fw-bold color-base-70 mb-2">Disclaimer</h3>
|
||||
<p class="mb-2"><%= community_name %> admins may modify tags and categories to ensure accuracy. We may also take down and refund inappropriate listings.</p>
|
||||
<p>Listings expire 30 days after they are published or "bumped".</p>
|
||||
</div>
|
||||
</aside>
|
||||
</main>
|
||||
|
|
|
|||
|
|
@ -91,7 +91,6 @@ RSpec.describe "/listings", type: :request do
|
|||
context "when the user has no credits" do
|
||||
it "shows the proper messages" do
|
||||
get "/listings/new"
|
||||
expect(response.body).to include "Listings Require Credits"
|
||||
expect(response.body).to include "You need at least one credit to create a listing."
|
||||
end
|
||||
end
|
||||
|
|
@ -101,7 +100,8 @@ RSpec.describe "/listings", type: :request do
|
|||
random_number = rand(2..100)
|
||||
create_list(:credit, random_number, user: user)
|
||||
get "/listings/new"
|
||||
expect(response.body).to include "You have #{random_number} credits available"
|
||||
expect(response.body).to include "Personal credits"
|
||||
expect(response.body).to include random_number.to_s
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -112,21 +112,23 @@ RSpec.describe "/listings", type: :request do
|
|||
|
||||
it "shows the proper message when both user and org have no credits" do
|
||||
get "/listings/new"
|
||||
expect(response.body).to include "Listings Require Credits"
|
||||
expect(response.body).to include "You need at least one credit to create a listing."
|
||||
end
|
||||
|
||||
it "shows the number of credits of the user if the user has credits but the org has no credits" do
|
||||
random_number = rand(2..100)
|
||||
create_list(:credit, random_number, user: user)
|
||||
get "/listings/new"
|
||||
expect(response.body).to include "You have #{random_number} credits available"
|
||||
expect(response.body).to include "Personal credits"
|
||||
expect(response.body).to include random_number.to_s
|
||||
end
|
||||
|
||||
it "shows the number of credits of the organization if the org has credits" do
|
||||
random_number = rand(2..100)
|
||||
create_list(:credit, random_number, organization: organization)
|
||||
get "/listings/new"
|
||||
expect(response.body).to include "has <span id=\"org-credits-number\">#{random_number}</span> credits"
|
||||
expect(response.body).to include "Organization credits"
|
||||
expect(response.body).to include random_number.to_s
|
||||
end
|
||||
|
||||
it "shows the number of credits of both the user and the organization if they both have credits" do
|
||||
|
|
@ -134,8 +136,8 @@ RSpec.describe "/listings", type: :request do
|
|||
create_list(:credit, random_number, organization: organization)
|
||||
create_list(:credit, random_number, user: user)
|
||||
get "/listings/new"
|
||||
expect(response.body).to include "has <span id=\"org-credits-number\">#{random_number}</span> credits"
|
||||
expect(response.body).to include "You have #{random_number} credits available"
|
||||
expect(response.body).to include "Personal credits"
|
||||
expect(response.body).to include random_number.to_s
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue