Contest Hero Development Update (Select Winners, Edit Contest, MongoDB and Express API)

in #utopian-io6 years ago

Repository

https://github.com/tobias-g1/contest-hero

Contest Hero is a new app built on top of the Steem Blockchain that allows you to easily create, manage, enter and find great contests on the Steem blockchain. The following is an update surrounding the development of Contest Hero. If you want to take a look at the site, you can use the link below:

https://contesthero.io

Although this release took slightly longer than I expected, this was mainly due to the need to implement the features mentioned below, overall this release provides a solid foundation to build upon for future releases and should allow some pretty cool features to be implemented into the site. Here's an overview of the features that have been added:

New Features

  1. MongoDB backend with Express API
  2. Contests are now pulled from DB for the Feed
  3. Ability to select random winners from entries
  4. Ability to select winners as 1st, 2nd, 3rd or General Winner.
  5. Ability to view winners on the contests page
  6. Ability to edit contest

Improvements

  1. Added dropdown to the navigation bar to allow the user to log out, contact us on Discord or report an issue via GitHub.

Bug Fixes

  1. Within this release, there was also a selection of bug fixes to resolve issues on Firefox surrounding CSS.
  2. Although not directly related to this contribution. There was an issue outside of the code related to a DNS issue that saw some readers unable to access the site following the initial development update, this has been resolved and the site should now be easily accessible to everyone.

The following pull requests can be used to references the features mentioned above:

https://github.com/tobias-g1/contest-hero/pull/65

The following provides a brief explanation of some of the new features mentioned above:

Although the original plan for contest hero was to purely pull data from the blockchain, this quickly turned out as an impossible task due to some bugs currently within the Steem API. Although I wasn't aware when I started it turns out there is an issue that prevents some posts (it seems to be random) from being pulled past the 7 day payout (at least using the common JS libraries), this obviously conflicts with the goal for contest hero and it's because of this I needed to think of a new way to gather posts to populate the site. I could have chosen to implement SteemSQL, however, in the long run, I believe implementing my own backend will provide more value. In order to do this, I decided to create a backend for the application using MongoDB and Express. The initial database consists of 3 collections, users, contests and entries. In order to create, update and read the data from the database I created the following routes:

Contests

MethodDescription
POSTCreate Contest
PUTSet Winners
PUTEdit Contest
GETAll Contests
GETContests by Category
GETContests by Permlink

Entries

MethodDescription
POSTCreate entry
GETEntries by ID

All of these routes are currently implemented within the platform for various different features around the site. They're included into the site via the services folder in contests.js and entries.js. The following is an example of the contests reference:

export default {

getContests () {
return api().get('/contests/all')
},
createContest (params) {
return api().post('/contests/create_contest', params)
},
getContestsByCategory (params) {
return api().get(/contests/${params})
},
getContestByPermlink (params) {
return api().get(/contests/permlink/${params})
},
updateWinners (params) {
return api().put('/contests/set_winners/', params)
},
editContest (params) {
return api().put('/contests/edit_contest/', params)
}
}

One of the tricker parts I found in creating this API was authenticating, this was mainly due to the want to not store any type of token in the database combined with the wish to keep the SteemConnect login client side so in order to authenticate the data that is submitted to the DB I run through a series of checks within the middleware to ensure that it's suitable for submissions to the database. As an overview it runs through:

  1. Validating the request body to ensure that the data format has been provided.
  2. Validating that the access_token submitted is valid
  3. Validating that the author who is editing or creating a contest is the same as the user found within the JWT access_token.
  4. Checking if the user is within the contest hero database yet
  5. Submit data to DB.

The following example shows an example of the contest route, as you can see below the route for creating a contest is defined as:

router.post('/create_contest',  validate(create_contest),  checkSteemConnect,  validatePermissions,  checkUser,  contest_controller.create_contest);

When a request is made it first makes a check to ensure that the body of the request contains the following information within the request (I will refine the complexity of the validation in a later release):

body:  {

access_token:  Joi.string().required(),

title:  Joi.string().required(),

author:  Joi.string().required(),

deadline:  Joi.string().required(),

category:  Joi.string().required(),

permlink:  Joi.string().required(),

body:  Joi.string().required()

}

},

If the validation is successful it will then make move to the checkSteemConnect to verify that the access_token provided is valid, within this middleware it will make a call to check the user profile for the user found within the JWT token, if successful it move into the checkPermissions middleware. Once within it will check that that the user passed in req.body.author is valid against the author that has been detected from the access token. Once complete it will then check whether or not the user is currently within the users' collection, if the user is already there it won't make any updates if the user is not there it will create the user within the database. The only thing that is currently stored against a user is their Steem username. Upon successfully moving through the mentioned middleware the request will be deemed as successful and the data will be saved.

The majority of the work mentioned above was completed in this commit:

https://github.com/tobias-g1/contest-hero/pull/65/commits/7b070779150cde4d5a7960f22ee7abbc0c6070b7

however, I restructured and added to the above in the following commit:

https://github.com/tobias-g1/contest-hero/pull/65/commits/7bd183fbdac7088cac5e2c9fdef083590d794460

Please note that the checkSteemConnect and createUser middleware is very similar to the KnackSteems middleware for this, there is only very minor adjustments. I found their repository very useful in creating this API and you would be able to see some similarities if compared

Due to the changes mentioned above, there was a considerable amount of work to move over the site to pull from the DB rather than the blockchain. Currently, the site pulls the feed, entries, winners from the database and only pulls the actual contest body of the contest or entries to allow for easy editing across multiple Steem front ends

By creating a database this provided a nice platform to create bespoke features for contest Hero, one of these includes the ability to select winners for a contest. A contest creator can now select their winners by selecting the following option shown in the vertical dot menu shown about their contest:

screely-1540161733511.png

Once pressed you will be taken to the select winner's page. On the left, you can see all of the entries that have been made to a particular contest and on the right, you can see your selection of winners. Currently, there are two ways to select winners within the platform, you can manually select winners using the options shown next to each entry card or alternatively, you can select random winners. The following shows an example of how this page currently looks:

screely-1540162047049.png

Upon selecting the randomize option you will be presented with a modal and from there you're able to select the number of winners that they wish to select for a contest. Upon clicking randomize the getRandomWinners method will be triggered. The select random winner's dialog can be seen in the image below:

screely-1540162234585.png

In order to create the random winner's feature I used the following method:

getRandomWinners  (count)  {

this.winners  = []

let  random  =  _.shuffle(this.contest.entries)

let  randomList  =  random.splice(0,  count)

randomList.forEach(element  =>  {

this.winners.push({

'entry_details':  element,

'place':  1000

})

})

}

When this method is called I first clear this.winner which is an array that holds previously selected winners and then using lodash I shuffle the array of entries to that particular contest. Using count I then splice the total number of entries using the index that was passed into the method as count. Using this array I then push each entry into the this.winner array and assign it a place of 1000. The reason is this is set to 1000 is that it allows for easy sorting of when places 1 - 3 are present whilst still allowing for plenty of room for adjustments to places in the future.

Once winners have been selected contest the winners will be shown on the main contest page, any winner who has received first, second or third place will have a medal to indicate their position. This can be seen in the image below:

screely-1540163189976.png

The ability to select winners was implemented in the following commit:

https://github.com/tobias-g1/contest-hero/pull/65/commits/58138d94d18a7fe81b488cfc2bc2468fb38ad60c

Finally I created the ability to created the ability to edit contests, currently, you can edit a contest using the vertical dot menu show to the top right of a post, this will only be visible if the post author matches the author who is authenticated to the application. Upon click of the edit contest button they will be redirected to the following page:

screely-1540162354286.png

Upon saving their edits it will first submit the changes to the Steem blockchain via SteemConnect and following that it will submit the changes to the contest hero DB.

The work completed for the editing of contests can be seen in this commit:

https://github.com/tobias-g1/contest-hero/pull/65/commits/b2f6c9ad46ea8e8cbe6e1d7366cfc012a6613b99

however additional work was required once I implemented the database this can be seen in the following commit:

https://github.com/tobias-g1/contest-hero/pull/65/commits/e39a5a68ebd348d3124b534ace48be5ff9fe1be1

What's next?

The following features will be implemented next, I hope that these will come a little quicker than this update did.

  1. User Profile with entries and contests
  2. Ability to edit entries
  3. Contest types with comment entries

Once these items are complete along with a few other bug fixes I plan to promote the site to the wider Steem community.

GitHub Account

A link to my GitHub account can be found below:

https://github.com/tobias-g1

Sort:  

contesthero looks amazing, @tobias-g!

It has such a clear and minimalist design. I want to utilize it in the next couple of days.

A couple minor notes:

  • I see you keep /dist inside the repository. Are there any specific reason for that? It's a good practice to add /dist directories into .gitignore since they're auto-populated on the environment they run.

  • Adding/Editing contests has a couple replicated code (ex: getting images via regex, constructing the Comment operation). It might be good to make it reusable function and use it in seperate views for the maintenance in the future.


Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.

To view those questions and the relevant answers related to your post, click here.


Need help? Write a ticket on https://support.utopian.io/.
Chat with us on Discord.
[utopian-moderator]

Thanks for the feedback, I really like the feedback I get from the development team, always a little thing I can improve on so it's very much appreciated.

In terms of your points:

  1. No reason, I was building it prior to pushing it Heroku previously however it's now built during deploy so no need for this now :), I will remove this in the next release.
  2. I agree I need to move a few features into a mixin so they're shared it's pretty annoying already and definitely wanted to get these sorted out in a release in the near future.

Once again thanks for the feedback :D

Thank you for your review, @emrebeyler!

So far this week you've reviewed 7 contributions. Keep up the good work!

I really need to think of a contest so I have an excuse to use your amazing website, haha.

Hi @tobias-g!

Your post was upvoted by @steem-ua, new Steem dApp, using UserAuthority for algorithmic post curation!
Your post is eligible for our upvote, thanks to our collaboration with @utopian-io!
Feel free to join our @steem-ua Discord server

Hi, @tobias-g!

You just got a 6.99% upvote from SteemPlus!
To get higher upvotes, earn more SteemPlus Points (SPP). On your Steemit wallet, check your SPP balance and click on "How to earn SPP?" to find out all the ways to earn.
If you're not using SteemPlus yet, please check our last posts in here to see the many ways in which SteemPlus can improve your Steem experience on Steemit and Busy.

Hey, @tobias-g!

Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!

Get higher incentives and support Utopian.io!
Simply set @utopian.pay as a 5% (or higher) payout beneficiary on your contribution post (via SteemPlus or Steeditor).

Want to chat? Join us on Discord https://discord.gg/h52nFrV.

Vote for Utopian Witness!

Coin Marketplace

STEEM 0.24
TRX 0.21
JST 0.036
BTC 97936.99
ETH 3366.06
USDT 1.00
SBD 3.35