Skip to content
This repository has been archived by the owner on May 10, 2023. It is now read-only.

Commit

Permalink
Merge pull request #219 from MichaelKohler/feature/show-rejected-sent…
Browse files Browse the repository at this point in the history
…ences

feat: show rejected sentences (fixes #159)
  • Loading branch information
MichaelKohler authored May 25, 2019
2 parents 937598d + b69aa29 commit 0dc836e
Show file tree
Hide file tree
Showing 9 changed files with 111 additions and 3 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ dist
.env
docker-compose.prod.yml
.ignored_files
.vscode
.vscode
.DS_Store
4 changes: 4 additions & 0 deletions shared/db.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,10 @@ export default class DB {
return this.sentences.vote(language, validated, invalidated);
}

async getAllRejectedByUsername(languages, username) {
return this.sentences.getAllRejectedByUsername(languages, username);
}

async getLanguageInfoForMe(language) {
try {
const [ submitted, validated ] = await Promise.all([
Expand Down
22 changes: 21 additions & 1 deletion shared/db/collections/sentences-meta.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,14 +165,34 @@ export default class SentencesMeta {
return result.data;
}

getAllRejectedByUsername(languages, username) {
const rejectedSentences = {};

const promises = languages.map((language) => this.getAllUnapprovedByUsername(language, username));

return Promise.all(promises)
.then((unapprovedPerLanguage) => {
return unapprovedPerLanguage.reduce((rejectedSentences, unapproved, index) => {
if (unapproved) {
// we can use the index here, as Promise.all guarantees that its
// resolved values will be in the same order
rejectedSentences[languages[index]] = unapproved;
}

return rejectedSentences;
}, {});
});
}

async getAllUnapprovedByUsername(language, username) {
const collection = await this.getCollection(language);
const filters = {
username,
approved: false,
};
const result = await collection.listRecords({ filters });
return result.data;
const unapprovedSentencesWithoutDetail = result.data.map((record) => record.sentence);
return unapprovedSentencesWithoutDetail;
}

async getAllByUsername(language, username) {
Expand Down
6 changes: 6 additions & 0 deletions web/css/root.css
Original file line number Diff line number Diff line change
Expand Up @@ -219,4 +219,10 @@ form button {
font-size: 80%;
font-weight: 800;
width: 40%;
}

.no-bullets {
list-style: none;
margin-left: 0;
padding-left: 0;
}
3 changes: 3 additions & 0 deletions web/src/components/app.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import Home from '../containers/home';
import HowTo from './pages/how-to';
import Login from '../containers/login';
import Profile from '../containers/profile';
import Rejected from '../containers/rejected';
import Add from '../containers/add';
import Review from '../containers/review';

Expand All @@ -35,6 +36,8 @@ export default class App extends React.Component {
path="/review" component={Review} />
<PrivateRoute authed={this.props.authed}
path="/review/:language" component={Review} />
<PrivateRoute authed={this.props.authed}
path="/rejected" component={Rejected} />
<Route render={() => (
<Redirect
to={{
Expand Down
1 change: 1 addition & 0 deletions web/src/components/header.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const Header = (props) => {
<NavLink to="/how-to" exact>How-to</NavLink>
<NavLink to="/add" exact key="add">Add</NavLink>
<NavLink to="/review" key="review">Review</NavLink>
<NavLink to="/rejected" key="rejected">Rejected Sentences</NavLink>
{ props.authed ? (
<NavLink to="/profile" exact key="profile">Profile</NavLink>
) : (
Expand Down
60 changes: 60 additions & 0 deletions web/src/components/pages/rejected.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React from 'react';

import WebDB from '../../web-db';

export default class Rejected extends React.Component {
constructor() {
super();
this.state = {
loading: true,
rejectedSentences: {},
};
}

async loadRejected() {
if (!this.props.languages || this.props.languages.length < 1) {
return;
}

const db = new WebDB(this.props.username, this.props.password);
const rejectedSentences = await db.getAllRejectedByUsername(this.props.languages, this.props.username);
this.setState({
rejectedSentences,
loading: false,
});
}

componentDidMount() {
this.loadRejected();
}

render() {
const { rejectedSentences, loading } = this.state;

return (
<>
<h1>Your rejected sentences</h1>

{ loading && (
<p>Loading rejected sentences..</p>
)}

{ !loading && Object.keys(rejectedSentences).length === 0 && (
<p>No rejected sentences found!</p>
)}

{ Object.keys(rejectedSentences).map((language) => (
<section>
<h2 key={language}>{language}</h2>

<ul className="no-bullets">
{ rejectedSentences[language].map((sentence) => (
<li key={sentence}>{sentence}</li>
))}
</ul>
</section>
))}
</>
);
}
}
2 changes: 1 addition & 1 deletion web/src/components/review-form.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ export default class ReviewForm extends React.Component {
</section>
)) }

<section class="review-footer">
<section className="review-footer">
<section id="confirm-buttons" className="divCenter">
{ this.state.pendingSentences ?
<SpinnerButton></SpinnerButton> :
Expand Down
13 changes: 13 additions & 0 deletions web/src/containers/rejected.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { connect } from 'react-redux';

import Rejected from '../components/pages/rejected';

function mapStateToProps(state) {
return {
username: state.username,
password: state.password,
languages: state.languages,
};
}

export default connect(mapStateToProps)(Rejected);

0 comments on commit 0dc836e

Please sign in to comment.