Show respondent names on admin page

This commit is contained in:
Brandon Dyck 2020-10-04 14:54:41 -06:00
parent 235b826dbb
commit 3ad9b2955f
4 changed files with 56 additions and 35 deletions

View File

@ -215,7 +215,7 @@ type GetEventResponseSummaryQuery struct {
}
type GetEventResponseSummaryResult struct {
TotalResponses int
RespondentNames []string
PerHourCounts map[date.Date]map[int]int
}
@ -242,13 +242,14 @@ func (s *Store) GetEventResponseSummary(ctx context.Context, query GetEventRespo
}
var result GetEventResponseSummaryResult
const responseCountQuery = `
SELECT COUNT(*)
const respondentNameQuery = `
SELECT guest_name
FROM response
WHERE event_id = ?;`
err = sqlitex.Exec(conn, responseCountQuery,
WHERE event_id = ?
ORDER BY guest_name ASC;`
err = sqlitex.Exec(conn, respondentNameQuery,
func(stmt *sqlite.Stmt) error {
result.TotalResponses = stmt.ColumnInt(0)
result.RespondentNames = append(result.RespondentNames, stmt.ColumnText(0))
return nil
}, query.EventID)
if err != nil {

View File

@ -2,7 +2,10 @@ package back_test
import (
"context"
"math/rand"
"sort"
"testing"
"time"
"github.com/matryer/is"
"github.com/rickb777/date"
@ -61,29 +64,6 @@ func TestGetEventResponseSummary(t *testing.T) {
return event.EventID
}
getTotalResponses := func(is *is.I, eventID string) int {
responses, err := store.GetEventResponseSummary(context.Background(), back.GetEventResponseSummaryQuery{
EventID: eventID,
})
is.NoErr(err)
return responses.TotalResponses
}
t.Run("TotalResponses counts the number of responses created", func(t *testing.T) {
is := is.New(t)
eventID := createEvent(is)
is.Equal(getTotalResponses(is, eventID), 0)
const respondTimes = 5
for i := 1; i <= respondTimes; i++ {
_, err = store.CreateEventResponse(context.Background(), back.CreateEventResponseCommand{
EventID: eventID,
})
is.NoErr(err)
is.Equal(getTotalResponses(is, eventID), i)
}
})
t.Run("does not include responses to other events", func(t *testing.T) {
is := is.New(t)
@ -109,11 +89,45 @@ func TestGetEventResponseSummary(t *testing.T) {
is.NoErr(err)
is.Equal(summary, back.GetEventResponseSummaryResult{
TotalResponses: 0,
RespondentNames: nil,
PerHourCounts: map[date.Date]map[int]int{},
})
})
t.Run("RespondentNames lists all respondents alphabetically", func(t *testing.T) {
is := is.New(t)
var names = []string{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j"}
rand.Shuffle(len(names), func(i, j int) {
names[i], names[j] = names[j], names[i]
})
d := date.New(1963, time.May, 1)
event, err := store.CreateEvent(context.Background(), back.CreateEventCommand{
Name: "It's my party!",
Description: "I can cry if I want to.",
Latest: d,
Earliest: d,
})
is.NoErr(err)
for _, name := range names {
_, err = store.CreateEventResponse(context.Background(), back.CreateEventResponseCommand{
EventID: event.EventID,
GuestName: name,
})
is.NoErr(err)
}
summary, err := store.GetEventResponseSummary(context.Background(), back.GetEventResponseSummaryQuery{
EventID: event.EventID,
})
is.NoErr(err)
sort.Strings(names)
is.Equal(summary.RespondentNames, names)
})
t.Run("PerHourCounts counts votes per hour", func(t *testing.T) {
is := is.New(t)

View File

@ -365,6 +365,12 @@ func (h *handler) handleAdmin(w http.ResponseWriter, r *http.Request) {
return
}
// Build the respondents list
respondentsList := e.Ul()()
for _, r := range summary.RespondentNames {
respondentsList.Children = append(respondentsList.Children, e.Li()(hm.Text(r)))
}
// Build the counts table
dateSpan := metadata.Latest.Sub(metadata.Earliest)
var dates []date.Date
@ -426,8 +432,9 @@ func (h *handler) handleAdmin(w http.ResponseWriter, r *http.Request) {
a.Disabled(true),
),
),
e.H3()(hm.Text("Responses")),
e.P()(hm.Text(strconv.Itoa(summary.TotalResponses))),
e.H3()(hm.Text("Respondents")),
respondentsList,
e.H3()(hm.Text("Results")),
countsTable,
}
_ = h.writePage(w, "Edit your event", body)

View File

@ -1,7 +1,6 @@
Essential:
------------
Show response after submission
Show respondent names on admin page
Make earliest and latest dates required for creation
Prevent blank event names and guest names
Consider some front-end, regex-based field validation