public/js/components/AtomEmbed/CurrentTargets.js (116 lines of code) (raw):
import React from 'react';
import {PropTypes} from 'prop-types';
import { atomPropType } from '../../constants/atomPropType';
import {
fetchTargetsForAtomPath,
deleteTarget,
} from '../../services/TargetingApi';
import distanceInWordsToNow from 'date-fns/distance_in_words_to_now';
import CreateTargetForm from './CreateTargetForm';
import { connect } from 'react-redux';
import { updateFormErrors } from '../../actions/FormErrorActions/updateFormErrors';
import { doesAtomTypeRequireTagging } from '../../constants/atomData';
const taggingRequiredError = {
title: 'required',
message: 'You must add at least one tag before publishing your atom',
};
class CurrentTargets extends React.Component {
static propTypes = {
atom: atomPropType,
dispatch: PropTypes.func,
};
state = {
targets: [],
fetching: false,
editing: false,
};
componentDidMount() {
this.fetchTargets();
}
calculateAtomPath = () => {
const atom = this.props.atom;
return `/atom/${atom.atomType.toLowerCase()}/${atom.id}`;
};
fetchTargets = () => {
this.setState({ fetching: true });
fetchTargetsForAtomPath(this.calculateAtomPath()).then(targets => {
this.setState({
targets: targets,
fetching: false,
});
});
};
componentDidUpdate = () => {
if (doesAtomTypeRequireTagging(this.props.atom.atomType)) {
this.props.dispatch(
updateFormErrors({
currentTargets: {
'Tags required':
this.state.targets.length > 0 ? [] : [taggingRequiredError],
},
})
);
}
};
toggleEditMode = () => {
this.setState({
editing: !this.state.editing,
currentTarget: {},
});
};
deleteTarget = target => {
deleteTarget(target.id).then(() => {
this.fetchTargets();
});
};
renderTarget = (target, i) => {
return (
<div className="targeting__target">
<div className="targeting__target__title">Target {i + 1}</div>
<a
className="targeting__target__delete"
onClick={this.deleteTarget.bind(this, target)}
>
<img
className="targeting__target__delete"
src="/assets/images/delete-icon.svg"
/>
</a>
<ul className="targeting__target__tags">
{target.tagPaths.map(tagPath => (
<li key={tagPath}>{tagPath}</li>
))}
</ul>
<div>
Expires{' '}
{distanceInWordsToNow(target.activeUntil, { addSuffix: true })}{' '}
</div>
</div>
);
};
renderTargets() {
if (this.state.fetching) {
return <div>Fetching...</div>;
}
if (!this.state.targets || !this.state.targets.length) {
return;
}
return (
<div className="targeting__targets">
{this.state.targets.map(this.renderTarget)}
</div>
);
}
render() {
return (
<div className="targeting">
{this.renderTargets()}
{this.state.editing ? (
<CreateTargetForm
atomPath={this.calculateAtomPath()}
title={this.props.atom.title}
triggerTargetFetch={this.fetchTargets}
toggleEditMode={this.toggleEditMode}
/>
) : (
<button className="btn" onClick={this.toggleEditMode}>
Add tag
</button>
)}
</div>
);
}
}
export default connect()(CurrentTargets);