Business Logic

Matching the Pairs

All of the functionality, the database, the select inputs, and everything in else, all surround matching the pairs from the events.

So participants attend an event, spend a bit of time talking to one another, and list the people they liked. Now the event manager has to

The onchange function ended up being a bit longer than usual:

let changePicks = (params) => {
// Params contains the current state of the select with the recent change
let a = params || [];
// Picks contains the previous state, the one currently in the database
let b = picks || [];
// We can compare the two to determine, was someone added to the list or removed
let addedPicks = a.filter(el => !b.includes(el))
let removedPicks = b.filter(el => !a.includes(el))
let personIndex = session.participants.findIndex(el => el._id === person._id)
session.participants[personIndex].picks = a || [];
let participants = session.participants;
let likesIds = person.picks.map(el => el.value)
Pack up the pencil and paper

Before PairUp the client used to determine all the matches by hand, and it reportedly took many weeks per event. Shortly before having PairUp built the client started using a matrix on paper similar to a Punnet Square, that alone saved them tons of time and helped reveal that there indeed was a better way.

Sortable Table

One of the pages shows a table containing the data for all the participants saved in the database thus far. Here we can edit any participants details and download a spreadsheet.

Since the downloadable csv would be sortable in any spreadsheet editor we really only needed to worry about sorting the data as it appears in-app. This means we can store the sort in state, and then map across the data after sorting it with state. So each button changes the state, sort by first name, last name, age, and so on. We can also add a Boolean state to reverse the sort when we click the button again, so we can sort z-a and a-z or 0-9 and 9-0.

Now that I think of it, it would be really easy to add a filter For searching too. Be right back, I’m gonna go implement that.

<div className="tab-container row-container">
<table>
<thead>
<tr>
<td><Button onClick={() => { setSort('first'); setReverse() }}>First Name</Button></td>
<td><Button onClick={() => { setSort('last'); setReverse() }}>Last Name</Button></td>
<td><Button onClick={() => { setSort('age'); setReverse() }}>Age</Button></td>
<td><Button onClick={() => { setSort('sex'); setReverse() }}>Sex</Button></td>
<td><Button onClick={() => { setSort('email'); setReverse() }}>Email</Button></td>
<td><Button onClick={() => { setSort('phone'); setReverse() }}>Phone</Button></td>
</tr>
</thead>
<tbody>
{reverseFunction([...list].sort(sortRows[sortType].fn)).map(person => {
return <PeopleRow key={person._id} person={person} />
})}
</tbody>
</table>
</div>

Don't Delete That!

When someone is deleted from the list of participants what happens to the people who liked them or matched with them. If they remain on the lists it could lead to bugs or confusion from the user, especially if the list of participants is long.

Tackling this was a bit harder than I anticipated because of a few different moving parts.

For one, the state of each react-select was not accessible to the other rows.

In the end I just edited the entire event object, pushed the new object to the database, and then sent back the update, which is fine because we are using a desktop electron application, a server api call would be far too costly and time consuming.

let removeParticipant = () => {
console.log(session.participants.map(el => el.matches.map(el => el.first)))
let updated = session;
let participation = session.participants;
let updatedParticipants = participation.filter(el => !el._id.includes(person._id))
let removedPick = updatedParticipants.map(el => {
el.picks = el.picks.filter(l => !l.value.includes(person._id))
el.matches = el.matches.filter(l => !l.value.includes(person._id))
return el;
})
// console.log(removedPick)
updated.participants = removedPick;
window.electron.ipcRenderer.send('addPicks', { updated })
setPicks(person.picks)
forceUpdate();
console.log(session.participants.map(el => el.matches.map(el => el.first)))
}