Skip to content

Commit

Permalink
Allow admins to view additional quote details (#11)
Browse files Browse the repository at this point in the history
* Allow admins to see who submitted a quote and when

* Adjust error positioning
  • Loading branch information
willbicks authored Dec 19, 2022
1 parent 032e97c commit e8c4cd7
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 34 deletions.
6 changes: 6 additions & 0 deletions internal/server/http/frontend/page.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,15 @@ func (PrivacyPage) viewName() string {

// QuotesPage lists all quotes by year
type QuotesPage struct {
// RenderAdmin is true if the page should render admin controls / info
RenderAdmin bool

Error error
Quote model.Quote
Quotes []model.Quote

// Users is a map of user ID to user, and should only be populated if RenderAdmin is true
Users map[string]model.User
}

func (QuotesPage) viewName() string {
Expand Down
31 changes: 21 additions & 10 deletions internal/server/http/frontend/public/styles/app.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{{define "error"}}
{{with getIssues .}}
<div class="bg-red-100 border-l-4 border-red-500 text-red-700 p-4" role="alert">
<div class="bg-red-100 border-l-4 border-red-500 text-red-700 p-4 my-3" role="alert">
<p class="font-bold">Error: </p>
{{range .}}
<p>{{ . }}</p>
Expand Down
35 changes: 22 additions & 13 deletions internal/server/http/frontend/templates/views/quotes.gohtml
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
{{template "base" .}}
{{ template "base" . }}

{{define "body"}}
{{ define "body" }}
<div class="section text-center">
<h1 class="h1">💬 {{.Title}}</h1>
</div>
<div class="section my-8 max-w-md">
<form action="{{.Paths.Quotes}}" method="post">
<h2 class="text-3xl font-semibold text-center">Submit a new quote:</h2>

{{ template "error" .Page.Error }}

<div class="mt-8">
<div class="grid grid-cols-1 gap-6">
<label class="block">
Expand All @@ -27,30 +25,41 @@
<input name="quotee" type="text" class="mt-1 block w-full dark:bg-gray-800"
placeholder="Jaustin Ross" value="{{.Page.Quote.Quotee}}" />
</label>

{{ template "error" .Page.Error }}

<input class="button" type="submit" value="Submit" />
</div>
</div>
</form>
</div>
<div class="wide-section my-12">
{{ $renderAdmin := .Page.RenderAdmin }}
{{ $users := .Page.Users }}
{{ $byYear := quotesByYear .Page.Quotes }}
{{ range $year := orderedYearKeys $byYear }}
<h3 class="text-3xl mb-4">{{ $year }}</h3>
<hr class="mb-4" />
<div class="masonry-container mb-6">
{{ range index $byYear $year }}
<div class="bg-gray-100 dark:bg-gray-900 p-4">
{{with .Context}}<p class="text-lg dark:text-white font-light lowercase mb-3">{{.}}</p>{{end}}
<p class="text-xl text-gray-800 dark:text-gray-200 font-medium mb-3">{{.Quote}}</p>
<p class="text-xl text-gray-600 dark:text-gray-300 font-medium text-right">- {{.Quotee}}</p>
{{ range (index $byYear $year) }}
<div>
<div class="bg-gray-100 dark:bg-gray-900 p-4">
{{ with .Context }}<p class="text-lg dark:text-white font-light lowercase mb-3">{{ . }}</p>{{end}}
<p class="text-xl text-gray-800 dark:text-gray-200 font-medium mb-3">{{ .Quote }}</p>
<p class="text-xl text-gray-600 dark:text-gray-300 font-medium text-right">- {{ .Quotee }}</p>
</div>
{{ if $renderAdmin }}
<p class="mt-2 text-gray-500 dark:text-gray-500">Submitted by {{ (index $users .SubmitterID).Name }} on {{
.Created.Format "2006-01-02 (Mon) at 15:04" }}</p>
{{ end }}
</div>
{{ end }}
</div>
{{end}}
{{ end }}
</div>
{{end}}
{{ end }}

{{define "scripts"}}
{{ define "scripts" }}
<script src="/static/scripts/macy.js"></script>
<script>
var macyInstances = []
Expand All @@ -69,4 +78,4 @@
}))
});
</script>
{{end}}
{{ end }}
17 changes: 17 additions & 0 deletions internal/server/http/frontend/templating_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,23 @@ func Test_TemplateEngine_RenderPage(t *testing.T) {
},
},
},
QuotesPage{
RenderAdmin: true,
Quotes: []model.Quote{
{
Quotee: "Test Quotee",
Quote: "Test Quote",
Context: "Test Context",
SubmitterID: "x123",
},
},
Users: map[string]model.User{
"x123": {
ID: "x123",
Name: "Test User",
},
},
},
QuizPage{
Questions: []service.QuizQuestion{
{
Expand Down
47 changes: 37 additions & 10 deletions internal/server/http/quotes_handler.go
Original file line number Diff line number Diff line change
@@ -1,25 +1,53 @@
package http

import (
"context"
"net/http"

"github.com/willbicks/epigram/internal/ctxval"
"github.com/willbicks/epigram/internal/model"
"github.com/willbicks/epigram/internal/server/http/frontend"
)

func (s *QuoteServer) getQuotesPage(ctx context.Context) (frontend.QuotesPage, error) {
quotes, err := s.QuoteService.GetAllQuotes(ctx)
if err != nil {
return frontend.QuotesPage{}, err
}

page := frontend.QuotesPage{
Quotes: quotes,
}

if ctxval.UserFromContext(ctx).Admin {
page.RenderAdmin = true

users, err := s.UserService.GetAllUsers(ctx)
if err != nil {
return frontend.QuotesPage{}, err
}

page.Users = make(map[string]model.User)
for _, u := range users {
page.Users[u.ID] = u
}
}

return page, nil
}

// quotesHandler handles requests to the quotes page, either GET requests to render
// quotes, or POST requests to submit a new quote
func (s *QuoteServer) quotesHandler(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case "GET":
quotes, err := s.QuoteService.GetAllQuotes(r.Context())
page, err := s.getQuotesPage(r.Context())
if err != nil {
s.serverError(w, r, err)
return
}
err = s.tmpl.RenderPage(w, frontend.QuotesPage{
Quotes: quotes,
})

err = s.tmpl.RenderPage(w, page)
if err != nil {
s.serverError(w, r, err)
s.Logger.Warn(err.Error())
Expand All @@ -38,16 +66,15 @@ func (s *QuoteServer) quotesHandler(w http.ResponseWriter, r *http.Request) {
createErr := s.QuoteService.CreateQuote(r.Context(), &q)

if createErr != nil {
quotes, err := s.QuoteService.GetAllQuotes(r.Context())
page, err := s.getQuotesPage(r.Context())
if err != nil {
s.serverError(w, r, err)
return
}
err = s.tmpl.RenderPage(w, frontend.QuotesPage{
Error: createErr,
Quote: q,
Quotes: quotes,
})
page.Quote = q
page.Error = createErr

err = s.tmpl.RenderPage(w, page)
if err != nil {
s.serverError(w, r, err)
return
Expand Down

0 comments on commit e8c4cd7

Please sign in to comment.