aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGalen Guyer <galen@galenguyer.com>2022-08-11 12:58:11 -0400
committerGalen Guyer <galen@galenguyer.com>2022-08-11 12:58:11 -0400
commitdf2d07e98c1e7a6fa341d75af7ec035eb8bf031f (patch)
tree9807ec69b1c81811bc18af8c976aa7332675b84b
parentb39025e49766337fa839c26371032e2d0ea79109 (diff)
Allow creation of polls with ranked choice
-rw-r--r--README.md1
-rw-r--r--database/poll.go4
-rw-r--r--database/simple_vote.go (renamed from database/vote.go)4
-rw-r--r--main.go33
-rw-r--r--templates/create.tmpl8
5 files changed, 36 insertions, 14 deletions
diff --git a/README.md b/README.md
index d85b0a7..8e78757 100644
--- a/README.md
+++ b/README.md
@@ -23,3 +23,4 @@ VOTE_STATE=
- [x] Custom vote options
- [x] Write-in votes
- [ ] Ranked choice voting
+- [ ] Show options that got no votes
diff --git a/database/poll.go b/database/poll.go
index 3763656..72d493d 100644
--- a/database/poll.go
+++ b/database/poll.go
@@ -14,6 +14,7 @@ type Poll struct {
CreatedBy string `bson:"createdBy"`
ShortDescription string `bson:"shortDescription"`
LongDescription string `bson:"longDescription"`
+ VoteType string `bson:"voteType"`
Options []string `bson:"options"`
Open bool `bson:"open"`
Hidden bool `bson:"hidden"`
@@ -25,6 +26,9 @@ type Result struct {
Count int `bson:"count"`
}
+const POLL_TYPE_SIMPLE = "simple"
+const POLL_TYPE_RANKED = "ranked"
+
func GetPoll(id string) (*Poll, error) {
ctx, cancel := context.WithTimeout(context.TODO(), 10*time.Second)
defer cancel()
diff --git a/database/vote.go b/database/simple_vote.go
index 03b1a12..ef97f6c 100644
--- a/database/vote.go
+++ b/database/simple_vote.go
@@ -7,14 +7,14 @@ import (
"go.mongodb.org/mongo-driver/bson/primitive"
)
-type Vote struct {
+type SimpleVote struct {
Id string `bson:"_id,omitempty"`
PollId primitive.ObjectID `bson:"pollId"`
UserId string `bson:"userId"`
Option string `bson:"option"`
}
-func CastVote(vote *Vote) error {
+func CastVote(vote *SimpleVote) error {
ctx, cancel := context.WithTimeout(context.TODO(), 10*time.Second)
defer cancel()
diff --git a/main.go b/main.go
index f9ad93d..177d9a1 100644
--- a/main.go
+++ b/main.go
@@ -110,10 +110,14 @@ func main() {
CreatedBy: claims.UserInfo.Username,
ShortDescription: c.PostForm("shortDescription"),
LongDescription: c.PostForm("longDescription"),
+ VoteType: database.POLL_TYPE_SIMPLE,
Open: true,
Hidden: false,
AllowWriteIns: c.PostForm("allowWriteIn") == "true",
}
+ if c.PostForm("rankedChoice") == "true" {
+ poll.VoteType = database.POLL_TYPE_RANKED
+ }
switch c.PostForm("options") {
case "pass-fail-conditional":
@@ -214,22 +218,27 @@ func main() {
return
}
- vote := database.Vote{
- Id: "",
- PollId: pId,
- UserId: claims.UserInfo.Username,
- Option: c.PostForm("option"),
- }
+ if poll.VoteType == database.POLL_TYPE_SIMPLE {
+ vote := database.SimpleVote{
+ Id: "",
+ PollId: pId,
+ UserId: claims.UserInfo.Username,
+ Option: c.PostForm("option"),
+ }
- if hasOption(poll, c.PostForm("option")) {
- vote.Option = c.PostForm("option")
- } else if poll.AllowWriteIns && c.PostForm("option") == "writein" {
- vote.Option = c.PostForm("writeinOption")
+ if hasOption(poll, c.PostForm("option")) {
+ vote.Option = c.PostForm("option")
+ } else if poll.AllowWriteIns && c.PostForm("option") == "writein" {
+ vote.Option = c.PostForm("writeinOption")
+ } else {
+ c.JSON(400, gin.H{"error": "Invalid Option"})
+ return
+ }
+ database.CastVote(&vote)
} else {
- c.JSON(500, gin.H{"error": "Invalid Option"})
+ c.JSON(500, gin.H{"error": "Unknown Poll Type"})
return
}
- database.CastVote(&vote)
if poll, err := database.GetPoll(c.Param("id")); err == nil {
if results, err := poll.GetResult(); err == nil {
diff --git a/templates/create.tmpl b/templates/create.tmpl
index e835a64..eaa6c40 100644
--- a/templates/create.tmpl
+++ b/templates/create.tmpl
@@ -63,6 +63,14 @@
value="true"
/>
<span>Allow Write-In Votes</span>
+ </div>
+ <div class="form-group">
+ <input
+ type="checkbox"
+ name="rankedChoice"
+ value="true"
+ />
+ <span>Ranked Choice Vote</span>
</div>
<input type="submit" class="btn btn-primary" value="Create" />
</form>