Refine HTML layout 0.6.0
authorJan Dittberner <jandd@cacert.org>
Fri, 2 Aug 2019 23:39:55 +0000 (01:39 +0200)
committerJan Dittberner <jandd@cacert.org>
Fri, 2 Aug 2019 23:39:55 +0000 (01:39 +0200)
This commit improves the page structure and unifies the layout. Some
reusable parts of the HTML code have been moved into
page_fragments.html.

13 files changed:
boardvoting.go
boardvoting/templates/create_motion_form.html
boardvoting/templates/denied.html
boardvoting/templates/direct_vote_form.html
boardvoting/templates/edit_motion_form.html
boardvoting/templates/footer.html
boardvoting/templates/header.html
boardvoting/templates/motion.html
boardvoting/templates/motion_fragments.html
boardvoting/templates/motions.html
boardvoting/templates/page_fragments.html [new file with mode: 0644]
boardvoting/templates/proxy_vote_form.html
boardvoting/templates/withdraw_motion_form.html

index 7228849..e58bee1 100644 (file)
@@ -219,7 +219,9 @@ func motionListHandler(w http.ResponseWriter, r *http.Request) {
                templateContext.PrevPage = params.Page - 1
        }
 
-       renderTemplate(w, r, []string{"motions.html", "motion_fragments.html", "header.html", "footer.html"}, templateContext)
+       renderTemplate(w, r, []string{
+               "motions.html", "motion_fragments.html", "page_fragments.html", "header.html", "footer.html",
+       }, templateContext)
 }
 
 func motionHandler(w http.ResponseWriter, r *http.Request) {
@@ -252,7 +254,7 @@ func motionHandler(w http.ResponseWriter, r *http.Request) {
        }
        templateContext.Decision = decision
        templateContext.PageTitle = fmt.Sprintf("Motion %s: %s", decision.Tag, decision.Title)
-       renderTemplate(w, r, []string{"motion.html", "motion_fragments.html", "header.html", "footer.html"}, templateContext)
+       renderTemplate(w, r, []string{"motion.html", "motion_fragments.html", "page_fragments.html", "header.html", "footer.html"}, templateContext)
 }
 
 func singleDecisionHandler(w http.ResponseWriter, r *http.Request, tag string, handler func(http.ResponseWriter, *http.Request)) {
@@ -326,7 +328,7 @@ func (a *withDrawMotionAction) Handle(w http.ResponseWriter, r *http.Request) {
                http.Error(w, http.StatusText(http.StatusPreconditionFailed), http.StatusPreconditionFailed)
                return
        }
-       templates := []string{"withdraw_motion_form.html", "header.html", "footer.html", "motion_fragments.html"}
+       templates := []string{"withdraw_motion_form.html", "header.html", "footer.html", "motion_fragments.html", "page_fragments.html"}
        var templateContext struct {
                PageTitle string
                Decision  *DecisionForDisplay
@@ -366,7 +368,7 @@ func (h *newMotionHandler) Handle(w http.ResponseWriter, r *http.Request) {
                http.Error(w, http.StatusText(http.StatusPreconditionFailed), http.StatusPreconditionFailed)
        }
 
-       templates := []string{"create_motion_form.html", "header.html", "footer.html"}
+       templates := []string{"create_motion_form.html", "page_fragments.html", "header.html", "footer.html"}
        var templateContext struct {
                Form      NewDecisionForm
                PageTitle string
@@ -428,7 +430,7 @@ func (a editMotionAction) Handle(w http.ResponseWriter, r *http.Request) {
                http.Error(w, http.StatusText(http.StatusPreconditionFailed), http.StatusPreconditionFailed)
                return
        }
-       templates := []string{"edit_motion_form.html", "header.html", "footer.html"}
+       templates := []string{"edit_motion_form.html", "page_fragments.html", "header.html", "footer.html"}
        var templateContext struct {
                Form      EditDecisionForm
                PageTitle string
@@ -560,7 +562,7 @@ func (h *directVoteHandler) Handle(w http.ResponseWriter, r *http.Request) {
 
                http.Redirect(w, r, "/motions/", http.StatusMovedPermanently)
        default:
-               templates := []string{"direct_vote_form.html", "header.html", "footer.html", "motion_fragments.html"}
+               templates := []string{"direct_vote_form.html", "header.html", "footer.html", "motion_fragments.html", "page_fragments.html"}
                var templateContext struct {
                        Decision   *DecisionForDisplay
                        VoteChoice VoteChoice
@@ -601,7 +603,7 @@ func (h *proxyVoteHandler) Handle(w http.ResponseWriter, r *http.Request) {
                http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
                return
        }
-       templates := []string{"proxy_vote_form.html", "header.html", "footer.html", "motion_fragments.html"}
+       templates := []string{"proxy_vote_form.html", "header.html", "footer.html", "motion_fragments.html", "page_fragments.html"}
        var templateContext struct {
                Form      ProxyVoteForm
                Decision  *DecisionForDisplay
index ef72ec6..2d8db12 100644 (file)
@@ -1,74 +1,66 @@
 {{ template "header.html" . }}
-<div class="column">
-    <div class="ui basic segment">
-        <div class="ui floated right secondary menu">
-            <a href="/motions/" class="item" title="Show all votes">Back to motions</a>
-        </div>
-    </div>
-</div>
-<div class="column">
-    <div class="ui raised segment">
-        <form action="/newmotion/" method="post">
+{{ template "return_header" . }}
+<div class="ui raised segment">
+    <form action="/newmotion/" method="post">
         {{ csrfField }}
-            <div class="ui form{{ if .Form.Errors }} error{{ end }}">
-                <div class="three fields">
-                    <div class="field">
-                        <label>ID:</label>
-                        (generated on submit)
-                    </div>
-                    <div class="field">
-                        <label>Proponent:</label>
-                        {{ .Voter.Name }}
-                    </div>
-                    <div class="field">
-                        <label>Proposed date/time:</label>
-                        (auto filled to current date/time)
-                    </div>
+        <div class="ui form{{ if .Form.Errors }} error{{ end }}">
+            <div class="three fields">
+                <div class="field">
+                    <label>ID:</label>
+                    (generated on submit)
                 </div>
-                <div class="required field{{ if .Form.Errors.Title }} error{{ end }}">
-                    <label for="Title">Title:</label>
-                    <input id="Title" name="Title" type="text" value="{{ .Form.Title }}">
+                <div class="field">
+                    <label>Proponent:</label>
+                    {{ .Voter.Name }}
                 </div>
-                <div class="required field{{ if .Form.Errors.Content }} error{{ end }}">
-                    <label for="Content">Text:</label>
-                    <textarea id="Content" name="Content">{{ .Form.Content }}</textarea>
+                <div class="field">
+                    <label>Proposed date/time:</label>
+                    (auto filled to current date/time)
                 </div>
-                <div class="two fields">
-                    <div class="required field{{ if .Form.Errors.VoteType }} error{{ end }}">
-                        <label for="VoteType">Vote type:</label>
-                        <select id="VoteType" name="VoteType">
-                            <option value="0"
-                                    {{ if eq "0" .Form.VoteType }}selected{{ end }}>
-                                Motion
-                            </option>
-                            <option value="1"
-                                    {{ if eq "1" .Form.VoteType }}selected{{ end }}>
-                                Veto
-                            </option>
-                        </select>
-                    </div>
-                    <div class="required field{{ if .Form.Errors.Due }} error{{ end }}">
-                        <label for="Due">Due: (autofilled from chosen
-                            option)</label>
-                        <select id="Due" name="Due">
-                            <option value="+3 days">In 3 Days</option>
-                            <option value="+7 days">In 1 Week</option>
-                            <option value="+14 days">In 2 Weeks</option>
-                            <option value="+28 days">In 4 Weeks</option>
-                        </select>
-                    </div>
+            </div>
+            <div class="required field{{ if .Form.Errors.Title }} error{{ end }}">
+                <label for="Title">Title:</label>
+                <input id="Title" name="Title" type="text" value="{{ .Form.Title }}">
+            </div>
+            <div class="required field{{ if .Form.Errors.Content }} error{{ end }}">
+                <label for="Content">Text:</label>
+                <textarea id="Content" name="Content">{{ .Form.Content }}</textarea>
+            </div>
+            <div class="two fields">
+                <div class="required field{{ if .Form.Errors.VoteType }} error{{ end }}">
+                    <label for="VoteType">Vote type:</label>
+                    <select id="VoteType" name="VoteType">
+                        <option value="0"
+                                {{ if eq "0" .Form.VoteType }}selected{{ end }}>
+                            Motion
+                        </option>
+                        <option value="1"
+                                {{ if eq "1" .Form.VoteType }}selected{{ end }}>
+                            Veto
+                        </option>
+                    </select>
                 </div>
-                {{ with .Form.Errors }}
+                <div class="required field{{ if .Form.Errors.Due }} error{{ end }}">
+                    <label for="Due">Due: (autofilled from chosen
+                        option)</label>
+                    <select id="Due" name="Due">
+                        <option value="+3 days">In 3 Days</option>
+                        <option value="+7 days">In 1 Week</option>
+                        <option value="+14 days">In 2 Weeks</option>
+                        <option value="+28 days">In 4 Weeks</option>
+                    </select>
+                </div>
+            </div>
+            {{ with .Form.Errors }}
                 <div class="ui error message">
                     {{ with .Title }}<p>{{ . }}</p>{{ end }}
                     {{ with .Content }}<p>{{ . }}</p>{{ end }}
                     {{ with .VoteType }}<p>{{ . }}</p>{{ end }}
                     {{ with .Due }}<p>{{ . }}</p>{{ end }}
                 </div>
-                {{ end }}
-                <button class="ui button" type="submit">Propose</button>
-            </div>
-        </form>
-    </div>
+            {{ end }}
+            <button class="ui button" type="submit">Propose</button>
+        </div>
+    </form>
 </div>
 {{ template "footer.html" . }}
\ No newline at end of file
index 53bb364..fc89505 100644 (file)
@@ -1,17 +1,23 @@
 {{ template "header.html" . }}
-<div class="column">
-    <div class="ui negative message">
-        <div class="header.html">You are not authorized to act here!</div>
-        <p>If you think this is in error, please contact the administrator.</p>
-        <p>If you don't know who that is, it is definitely not an error ;)</p>
-        {{ if .Emails }}
-        <p>The following addresses were present in your certificate:<p>
-        <ul>
-            {{ range .Emails }}
-            <li>{{ . }}</li>
+<div class="ui container">
+    <div class="ui negative icon message">
+        <i class="ban icon "></i>
+        <div class="content">
+            <div class="header">You are not authorized to act here!</div>
+            <p>If you think this is in error, please contact the administrator.</p>
+            <p>If you don't know who that is, it is definitely not an error ;)</p>
+            {{ if .Emails }}
+                <p>The following addresses were present in your certificate:<p>
+                <div class="ui list">
+                    {{ range .Emails }}
+                        <div class="item">
+                            <i class="address card outline icon"></i>
+                            <div class="content">{{ . }}</div>
+                        </div>
+                    {{ end }}
+                </div>
             {{ end }}
-        </ul>
-        {{ end }}
+        </div>
     </div>
 </div>
 {{ template "footer.html" . }}
\ No newline at end of file
index 66e21a9..fff77eb 100644 (file)
@@ -1,31 +1,23 @@
 {{ template "header.html" . }}
-<div class="column">
-    <div class="ui basic segment">
-        <div class="ui floated right secondary menu">
-            <a href="/motions/" class="item" title="Show all votes">Back to motions</a>
-        </div>
-    </div>
-</div>
+{{ template "return_header" . }}
 {{ with .Decision }}
-<div class="column">
     <div class="ui raised segment">
-    {{ template "motion_fragment" . }}
+        {{ template "motion_fragment" . }}
     </div>
-</div>
 {{ end }}
 <form action="/vote/{{ .Decision.Tag }}/{{ .VoteChoice }}" method="post">
-{{ csrfField }}
+    {{ csrfField }}
     <div class="ui form">
-    {{ if eq 1 .VoteChoice }}
-        <button class="ui right labeled green icon button" type="submit"><i class="check circle icon"></i>
-            Vote {{ .VoteChoice }}</button>
-    {{ else if eq -1 .VoteChoice }}
-        <button class="ui right labeled red icon button" type="submit"><i class="minus circle icon"></i>
-            Vote {{ .VoteChoice }}</button>
-    {{ else }}
-        <button class="ui right labeled grey icon button" type="submit"><i class="circle icon"></i>
-            Vote {{ .VoteChoice }}</button>
-    {{ end }}
+        {{ if eq 1 .VoteChoice }}
+            <button class="ui right labeled green icon button" type="submit"><i class="check circle icon"></i>
+                Vote {{ .VoteChoice }}</button>
+        {{ else if eq -1 .VoteChoice }}
+            <button class="ui right labeled red icon button" type="submit"><i class="minus circle icon"></i>
+                Vote {{ .VoteChoice }}</button>
+        {{ else }}
+            <button class="ui right labeled grey icon button" type="submit"><i class="circle icon"></i>
+                Vote {{ .VoteChoice }}</button>
+        {{ end }}
     </div>
 </form>
 {{ template "footer.html" . }}
\ No newline at end of file
index 845442d..1798b27 100644 (file)
@@ -1,72 +1,66 @@
 {{ template "header.html" . }}
-<div class="column">
-    <div class="ui floated right secondary menu">
-        <a href="/motions/" class="item" title="Show all votes">Back to
-            motions</a>
-    </div>
-</div>
-<div class="column">
-    <div class="ui raised segment">
-        <form action="/motions/{{ .Form.Decision.Tag }}/edit" method="post">
-            <div class="ui form{{ if .Form.Errors }} error{{ end }}">
-                <div class="three fields">
-                    <div class="field">
-                        <label>ID:</label>
-                        <a href="/motions/{{ .Form.Decision.Tag }}">{{ .Form.Decision.Tag }}</a>
-                    </div>
-                    <div class="field">
-                        <label>Proponent:</label>
-                        {{ .Voter.Name }}
-                    </div>
-                    <div class="field">
-                        <label>Proposed date/time:</label>
-                        {{ .Form.Decision.Proposed|date "2006-01-02 15:04:05 UTC" }}
-                    </div>
+{{ template "return_header" . }}
+<div class="ui raised segment">
+    <form action="/motions/{{ .Form.Decision.Tag }}/edit" method="post">
+        {{ csrfField }}
+        <div class="ui form{{ if .Form.Errors }} error{{ end }}">
+            <div class="three fields">
+                <div class="field">
+                    <label>ID:</label>
+                    <a href="/motions/{{ .Form.Decision.Tag }}">{{ .Form.Decision.Tag }}</a>
                 </div>
-                <div class="required field{{ if .Form.Errors.Title }} error{{ end }}">
-                    <label for="Title">Title:</label>
-                    <input name="Title" type="text" value="{{ .Form.Title }}">
+                <div class="field">
+                    <label>Proponent:</label>
+                    {{ .Voter.Name }}
                 </div>
-                <div class="required field{{ if .Form.Errors.Content }} error{{ end }}">
-                    <label for="Content">Text:</label>
-                    <textarea name="Content">{{ .Form.Content }}</textarea>
+                <div class="field">
+                    <label>Proposed date/time:</label>
+                    {{ .Form.Decision.Proposed|date "2006-01-02 15:04:05 UTC" }}
                 </div>
-                <div class="two fields">
-                    <div class="required field{{ if .Form.Errors.VoteType }} error{{ end }}">
-                        <label for="VoteType">Vote type:</label>
-                        <select name="VoteType">
-                            <option value="0"
-                                    {{ if eq "0" .Form.VoteType }}selected{{ end }}>
-                                Motion
-                            </option>
-                            <option value="1"
-                                    {{ if eq "1" .Form.VoteType }}selected{{ end }}>
-                                Veto
-                            </option>
-                        </select>
-                    </div>
-                    <div class="required field{{ if .Form.Errors.Due }} error{{ end }}">
-                        <label for="Due">Due: (autofilled from chosen
-                            option)</label>
-                        <select name="Due">
-                            <option value="+3 days">In 3 Days</option>
-                            <option value="+7 days">In 1 Week</option>
-                            <option value="+14 days">In 2 Weeks</option>
-                            <option value="+28 days">In 4 Weeks</option>
-                        </select>
-                    </div>
+            </div>
+            <div class="required field{{ if .Form.Errors.Title }} error{{ end }}">
+                <label for="Title">Title:</label>
+                <input name="Title" type="text" value="{{ .Form.Title }}">
+            </div>
+            <div class="required field{{ if .Form.Errors.Content }} error{{ end }}">
+                <label for="Content">Text:</label>
+                <textarea name="Content">{{ .Form.Content }}</textarea>
+            </div>
+            <div class="two fields">
+                <div class="required field{{ if .Form.Errors.VoteType }} error{{ end }}">
+                    <label for="VoteType">Vote type:</label>
+                    <select name="VoteType">
+                        <option value="0"
+                                {{ if eq "0" .Form.VoteType }}selected{{ end }}>
+                            Motion
+                        </option>
+                        <option value="1"
+                                {{ if eq "1" .Form.VoteType }}selected{{ end }}>
+                            Veto
+                        </option>
+                    </select>
                 </div>
-                {{ with .Form.Errors }}
+                <div class="required field{{ if .Form.Errors.Due }} error{{ end }}">
+                    <label for="Due">Due: (autofilled from chosen
+                        option)</label>
+                    <select name="Due">
+                        <option value="+3 days">In 3 Days</option>
+                        <option value="+7 days">In 1 Week</option>
+                        <option value="+14 days">In 2 Weeks</option>
+                        <option value="+28 days">In 4 Weeks</option>
+                    </select>
+                </div>
+            </div>
+            {{ with .Form.Errors }}
                 <div class="ui error message">
                     {{ with .Title }}<p>{{ . }}</p>{{ end }}
                     {{ with .Content }}<p>{{ . }}</p>{{ end }}
                     {{ with .VoteType }}<p>{{ . }}</p>{{ end }}
                     {{ with .Due }}<p>{{ . }}</p>{{ end }}
                 </div>
-                {{ end }}
-                <button class="ui button" type="submit">Propose</button>
-            </div>
-        </form>
-    </div>
+            {{ end }}
+            <button class="ui button" type="submit">Propose</button>
+        </div>
+    </form>
 </div>
 {{ template "footer.html" . }}
\ No newline at end of file
index fa873e5..da6699c 100644 (file)
@@ -1,12 +1,12 @@
 {{ define "footer.html" }}
-</div>
-<script type="text/javascript">
-    $(document).ready(function() {
-       $('.message .close').on('click', function() {
-           $(this).closest('.message').transition('fade');
-       });
-    });
-</script>
+    </div>
+    <script type="text/javascript">
+        $(document).ready(function () {
+            $('.message .close').on('click', function () {
+                $(this).closest('.message').transition('fade');
+            });
+        });
+    </script>
 </body>
 </html>
 {{ end }}
\ No newline at end of file
index d4f9621..acf8d18 100644 (file)
@@ -7,20 +7,35 @@
     <link rel="stylesheet" type="text/css" href="/static/semantic.min.css"/>
     <script type="text/javascript" src="/static/jquery.min.js"></script>
     <script type="text/javascript" src="/static/semantic.min.js"></script>
+    <link rel="icon" href="/static/images/favicon.ico">
 </head>
-<body class="site">
+<body id="cacert-boardvoting">
+<div class="pusher">
+    <div class="ui vertical masthead center aligned segment">
+        <div class="ui left secondary container">
+            <img src="/static/images/CAcert-logo-colour.svg" alt="CAcert" height="40rem"/>
+        </div>
+        <div class="ui text container">
+            <h1 class="ui header">
+                {{ template "pagetitle" . }}
+                {{ if .Voter }}
+                    <div class="ui left pointing label">Authenticated as {{ .Voter.Name }} &lt;{{ .Voter.Reminder }}&gt;
+                    </div>{{ end }}
+            </h1>
+        </div>
+    </div>
+</div>
 <div class="ui container">
-    <h1 class="ui header">{{ template "pagetitle" . }}{{ if .Voter }}<div class="ui left pointing label">Authenticated as {{ .Voter.Name }} &lt;{{ .Voter.Reminder }}&gt;</div>{{ end }}</h1>
     {{ with .Flashes }}
-        <div class="ui info message">
-            <i class="close icon"></i>
-            <div class="ui list">
-                {{ range . }}
-                <div class="ui item">{{ . }}</div>
-                {{ end }}
+        <div class="basic segment">
+            <div class="ui info message">
+                <i class="close icon"></i>
+                <div class="ui list">
+                    {{ range . }}
+                        <div class="ui item">{{ . }}</div>
+                    {{ end }}
+                </div>
             </div>
         </div>
     {{ end }}
-</div>
-<div class="ui one column grid container">
 {{ end }}
index e78a955..a4c3a30 100644 (file)
@@ -1,19 +1,20 @@
 {{ template "header.html" . }}
 {{ $voter := .Voter }}
-<div class="column">
-    <div class="ui basic segment">
-        <div class="ui floated right secondary menu">
-            <a href="/motions/" class="item" title="Show all votes">All votes</a>
-            {{ if $voter }}<a href="/motions/?unvoted=1" class="item" title="Show my outstanding votes">My outstanding votes</a>{{ end }}
-        </div>
+<div class="ui basic segment">
+    <div class="ui secondary pointing menu">
+        <a href="/motions/" class="item" title="Show all votes">All votes</a>
+        {{ if $voter }}
+            <a href="/motions/?unvoted=1" class="item" title="Show my outstanding votes">My outstanding votes</a>
+            <div class="right item">
+                <a class="ui primary button" href="/newmotion/">New motion</a>
+            </div>
+        {{ end }}
     </div>
 </div>
 {{ with .Decision }}
-<div class="column">
     <div class="ui raised segment">
         {{ template "motion_fragment" . }}
         {{ if $voter }}{{ template "motion_actions" . }}{{ end }}
     </div>
-</div>
 {{ end}}
 {{ template "footer.html" . }}
\ No newline at end of file
index 96a1938..876e586 100644 (file)
@@ -1,64 +1,68 @@
 {{ define "motion_fragment" }}
-<span class="ui {{ template "status_class" .Status }} ribbon label">{{ .Status|toString|title }}</span>
-<span class="header.html">{{ .Modified|date "2006-01-02 15:04:05 UTC" }}</span>
-<h3 class="header.html"><a href="/motions/{{ .Tag }}">{{ .Tag }}: {{ .Title }}</a></h3>
-<p>{{ wrap 76 .Content | nl2br }}</p>
-<table class="ui small definition table">
-    <tbody>
-    <tr>
-        <td>Due</td>
-        <td>{{.Due|date "2006-01-02 15:04:05 UTC"}}</td>
-    </tr>
-    <tr>
-        <td>Proposed</td>
-        <td>{{.Proposer}} ({{.Proposed|date "2006-01-02 15:04:05 UTC"}})</td>
-    </tr>
-    <tr>
-        <td>Vote type:</td>
-        <td>{{ .VoteType|toString|title }}</td>
-    </tr>
-    <tr>
-        <td>Votes:</td>
-        <td>
-            <div class="ui labels">
-                <div class="ui basic label green"><i
-                        class="check circle icon"></i>Aye
-                    <div class="detail">{{.Ayes}}</div>
+    <span class="ui {{ template "status_class" .Status }} ribbon label">{{ .Status|toString|title }}</span>
+    <span class="header.html">{{ .Modified|date "2006-01-02 15:04:05 UTC" }}</span>
+    <h3 class="header.html"><a href="/motions/{{ .Tag }}">{{ .Tag }}: {{ .Title }}</a></h3>
+    <p>{{ wrap 76 .Content | nl2br }}</p>
+    <table class="ui small definition table">
+        <tbody>
+        <tr>
+            <td>Due</td>
+            <td>{{.Due|date "2006-01-02 15:04:05 UTC"}}</td>
+        </tr>
+        <tr>
+            <td>Proposed</td>
+            <td>{{.Proposer}} ({{.Proposed|date "2006-01-02 15:04:05 UTC"}})</td>
+        </tr>
+        <tr>
+            <td>Vote type:</td>
+            <td>{{ .VoteType|toString|title }}</td>
+        </tr>
+        <tr>
+            <td>Votes:</td>
+            <td>
+                <div class="ui labels">
+                    <div class="ui basic label green"><i
+                                class="check circle icon"></i>Aye
+                        <div class="detail">{{.Ayes}}</div>
+                    </div>
+                    <div class="ui basic label red"><i
+                                class="minus circle icon"></i>Naye
+                        <div class="detail">{{.Nayes}}</div>
+                    </div>
+                    <div class="ui basic label grey"><i class="circle icon"></i>Abstain
+                        <div class="detail">{{.Abstains}}</div>
+                    </div>
                 </div>
-                <div class="ui basic label red"><i
-                        class="minus circle icon"></i>Naye
-                    <div class="detail">{{.Nayes}}</div>
-                </div>
-                <div class="ui basic label grey"><i class="circle icon"></i>Abstain
-                    <div class="detail">{{.Abstains}}</div>
-                </div>
-            </div>
-            {{ if .Votes }}
-            <div class="list">
-                {{ range .Votes }}
-                <div class="item">{{ .Name }}: {{ .Vote.Vote }}</div>
+                {{ if .Votes }}
+                    <div class="list">
+                        {{ range .Votes }}
+                            <div class="item">{{ .Name }}: {{ .Vote.Vote }}</div>
+                        {{ end }}
+                    </div>
+                    <a href="/motions/{{ .Tag }}">Hide Votes</a>
+                {{ else if or ((ne 0 .Ayes) (ne 0 .Nayes) (ne 0 .Abstains)) }}
+                    <a href="/motions/{{ .Tag }}?showvotes=1">Show Votes</a>
                 {{ end }}
-            </div>
-            <a href="/motions/{{ .Tag }}">Hide Votes</a>
-            {{ else if or ((ne 0 .Ayes) (ne 0 .Nayes) (ne 0 .Abstains)) }}
-            <a href="/motions/{{ .Tag }}?showvotes=1">Show Votes</a>
-            {{ end }}
-        </td>
-    </tr>
-    </tbody>
-</table>
+            </td>
+        </tr>
+        </tbody>
+    </table>
 {{ end }}
 
-{{ define "status_class" }}{{ if eq . 0 }}blue{{ else if eq . 1 }}green{{ else if eq . -1 }}red{{ else if eq . -2 }}grey
-{{ end }}{{ end }}
+{{ define "status_class" }}{{ if eq . 0 }}blue{{ else if eq . 1 }}green{{ else if eq . -1 }}red{{ else if eq . -2 }}grey{{ end }}{{ end }}
 
 {{ define "motion_actions" }}
-{{ if eq .Status 0 }}
-<a class="ui compact right labeled green icon button" href="/vote/{{ .Tag }}/aye"><i class="check circle icon"></i> Aye</a>
-<a class="ui compact right labeled red icon button" href="/vote/{{ .Tag }}/naye"><i class="minus circle icon"></i> Naye</a>
-<a class="ui compact right labeled grey icon button" href="/vote/{{ .Tag }}/abstain"><i class="circle icon"></i> Abstain</a>
-<a class="ui compact left labeled icon button" href="/proxy/{{ .Tag }}"><i class="users icon"></i> Proxy Vote</a>
-<a class="ui compact left labeled icon button" href="/motions/{{ .Tag }}/edit"><i class="edit icon"></i> Modify</a>
-<a class="ui compact left labeled icon button" href="/motions/{{ .Tag }}/withdraw"><i class="trash icon"></i> Withdraw</a>
-{{ end }}
+    {{ if eq .Status 0 }}
+        <a class="ui compact right labeled green icon button" href="/vote/{{ .Tag }}/aye"><i
+                    class="check circle icon"></i> Aye</a>
+        <a class="ui compact right labeled red icon button" href="/vote/{{ .Tag }}/naye"><i
+                    class="minus circle icon"></i> Naye</a>
+        <a class="ui compact right labeled grey icon button" href="/vote/{{ .Tag }}/abstain"><i class="circle icon"></i>
+            Abstain</a>
+        <a class="ui compact left labeled icon button" href="/proxy/{{ .Tag }}"><i class="users icon"></i> Proxy
+            Vote</a>
+        <a class="ui compact left labeled icon button" href="/motions/{{ .Tag }}/edit"><i class="edit icon"></i> Modify</a>
+        <a class="ui compact left labeled icon button" href="/motions/{{ .Tag }}/withdraw"><i class="trash icon"></i>
+            Withdraw</a>
+    {{ end }}
 {{ end }}
index 625dc57..159cda5 100644 (file)
@@ -1,52 +1,45 @@
 {{ template "header.html" . }}
 {{ $voter := .Voter }}
-<div class="column">
-    <div class="ui basic segment">
-        <div class="ui floated right secondary menu">
-
-            <a href="/motions/" class="{{ if not .Params.Flags.Unvoted }}active {{ end }}item" title="Show all votes">All votes</a>
-            {{ if $voter }}<a href="/motions/?unvoted=1" class="{{ if .Params.Flags.Unvoted }}active {{ end}}item" title="Show my outstanding votes">My outstanding votes</a>{{ end }}
-        </div>
-        {{ if $voter }}<a class="ui primary button" href="/newmotion/">New motion</a>{{ end }}
-        {{ if .PrevPage -}}
-        <a href="?page={{ .PrevPage }}{{ if .Params.Flags.Unvoted }}&unvoted=1{{ end }}"
-           class="ui left labeled icon button" title="newer motions"><i class="left arrow icon"></i> newer</a>
-        {{- end }}
-        {{ if .NextPage -}}
-        <a href="?page={{ .NextPage }}{{ if .Params.Flags.Unvoted }}&unvoted=1{{ end }}"
-           class="ui right labeled icon button" title="older motions"><i class="right arrow icon"></i> older</a>
-        {{- end }}
+{{ $page := . }}
+<div class="ui basic segment">
+    <div class="ui secondary pointing menu">
+        <a href="/motions/" class="{{ if not .Params.Flags.Unvoted }}active {{ end }}item" title="Show all votes">All
+            votes</a>
+        {{ if $voter }}
+            <a href="/motions/?unvoted=1" class="{{ if .Params.Flags.Unvoted }}active {{ end}}item"
+               title="Show my outstanding votes">My outstanding votes</a>
+            <div class="right item">
+                <a class="ui primary button" href="/newmotion/">New motion</a>
+            </div>
+        {{ end }}
     </div>
 </div>
 {{ if .Decisions }}
+    <div class="ui labeled icon menu">
+        {{ template "pagination_fragment" $page }}
+    </div>
     {{ range .Decisions }}
-    <div class="column">
         <div class="ui raised segment">
-        {{ template "motion_fragment" . }}
-        {{ if $voter }}{{ template "motion_actions" . }}{{ end }}
+            {{ template "motion_fragment" . }}
+            {{ if $voter }}{{ template "motion_actions" . }}{{ end }}
         </div>
-    </div>
     {{ end }}
-<div class="column">
-    <div class="ui basic segment">
-{{ if $voter }}<a class="ui primary button" href="/newmotion/">New motion</a>{{ end }}
-{{ if .PrevPage -}}
-    <a href="?page={{ .PrevPage }}{{ if .Params.Flags.Unvoted }}&unvoted=1{{ end }}"
-       class="ui left labeled icon button" title="newer motions">
-        <i class="left arrow icon"></i> newer</a>
-{{- end }}
-{{ if .NextPage -}}
-    <a href="?page={{ .NextPage }}{{ if .Params.Flags.Unvoted }}&unvoted=1{{ end }}"
-       class="ui right labeled icon button" title="older motions">
-       <i class="right arrow icon"></i> older</a>
-{{- end }}
+    <div class="ui labeled icon menu">
+        {{ template "pagination_fragment" $page }}
     </div>
-</div>
 {{ else }}
-    {{ if .Params.Flags.Unvoted }}
-    <p>There are no motions requiring a vote from you.</p>
-    {{ else }}
-    <p>There are no motions in the system yet.</p>
-    {{ end }}
+    <div class="ui basic segment">
+        <div class="ui icon message">
+            <i class="inbox icon"></i>
+            <div class="content">
+                <div class="header">No motions available</div>
+                {{ if .Params.Flags.Unvoted }}
+                    <p>There are no motions requiring a vote from you.</p>
+                {{ else }}
+                    <p>There are no motions in the system yet.</p>
+                {{ end }}
+            </div>
+        </div>
+    </div>
 {{ end }}
 {{ template "footer.html" . }}
\ No newline at end of file
diff --git a/boardvoting/templates/page_fragments.html b/boardvoting/templates/page_fragments.html
new file mode 100644 (file)
index 0000000..6a6dedf
--- /dev/null
@@ -0,0 +1,20 @@
+{{ define "pagination_fragment" }}
+    {{ if .PrevPage -}}
+        <a class="item" href="?page={{ .PrevPage }}{{ if .Params.Flags.Unvoted }}&unvoted=1{{ end }}">
+            <i class="left arrow icon"></i> newer
+        </a>
+    {{- end }}
+    {{ if .NextPage -}}
+        <a class="right item" href="?page={{ .NextPage }}{{ if .Params.Flags.Unvoted }}&unvoted=1{{ end }}">
+            <i class="right arrow icon"></i> older
+        </a>
+    {{- end }}
+{{ end }}
+
+{{ define "return_header" }}
+    <div class="ui basic segment">
+        <div class="ui secondary pointing menu">
+            <a href="/motions/" class="item" title="Show all votes">Back to motions</a>
+        </div>
+    </div>
+{{ end }}
\ No newline at end of file
index 97ae86b..a6ab5ee 100644 (file)
@@ -1,56 +1,47 @@
 {{ template "header.html" . }}
+{{ template "return_header" . }}
 {{ $form := .Form }}
-<div class="column">
-    <div class="ui basic segment">
-        <div class="ui floated right secondary menu">
-            <a href="/motions/" class="item" title="Show all votes">Back to
-                motions</a>
-        </div>
-    </div>
-</div>
-<div class="column">
-    <div class="ui raised segment">
+<div class="ui raised segment">
     {{ with .Decision }}
         {{ template "motion_fragment" . }}
-        {{ end }}
-        <form action="/proxy/{{ .Decision.Tag }}" method="post">
+    {{ end }}
+    <form action="/proxy/{{ .Decision.Tag }}" method="post">
         {{ csrfField }}
-            <div class="ui form{{ if .Form.Errors }} error{{ end }}">
-                <div class="two fields">
-                    <div class="required field{{ if .Form.Errors.Voter }} error{{ end }}">
-                        <label for="Voter">Voter</label>
-                        <select name="Voter">
+        <div class="ui form{{ if .Form.Errors }} error{{ end }}">
+            <div class="two fields">
+                <div class="required field{{ if .Form.Errors.Voter }} error{{ end }}">
+                    <label for="Voter">Voter</label>
+                    <select name="Voter">
                         {{ range .Voters }}
                             <option value="{{ .Id }}"
-                            {{ if eq (.Id | print) $form.Voter }}
-                                    selected{{ end }}>{{ .Name }}</option>
+                                    {{ if eq (.Id | print) $form.Voter }}
+                            selected{{ end }}>{{ .Name }}</option>
                         {{ end }}
-                        </select>
-                    </div>
-                    <div class="required field{{ if .Form.Errors.Vote }} error{{ end }}">
-                        <label for="Vote">Vote</label>
-                        <select name="Vote">
-                            <option value="1"{{ if eq .Form.Vote "1" }} selected{{ end }}>Aye</option>
-                            <option value="0"{{ if eq .Form.Vote "0" }} selected{{ end }}>Abstain</option>
-                            <option value="-1"{{ if eq .Form.Vote "-1" }} selected{{ end }}>Naye</option>
-                        </select>
-                    </div>
+                    </select>
                 </div>
-                <div class="required field{{ if .Form.Errors.Justification }} error{{ end }}">
-                    <label for="Justification">Justification</label>
-                    <textarea name="Justification" rows="2">{{ .Form.Justification }}</textarea>
+                <div class="required field{{ if .Form.Errors.Vote }} error{{ end }}">
+                    <label for="Vote">Vote</label>
+                    <select name="Vote">
+                        <option value="1"{{ if eq .Form.Vote "1" }} selected{{ end }}>Aye</option>
+                        <option value="0"{{ if eq .Form.Vote "0" }} selected{{ end }}>Abstain</option>
+                        <option value="-1"{{ if eq .Form.Vote "-1" }} selected{{ end }}>Naye</option>
+                    </select>
                 </div>
+            </div>
+            <div class="required field{{ if .Form.Errors.Justification }} error{{ end }}">
+                <label for="Justification">Justification</label>
+                <textarea name="Justification" rows="2">{{ .Form.Justification }}</textarea>
+            </div>
             {{ with .Form.Errors }}
                 <div class="ui error message">
-                {{ with .Voter }}<p>{{ . }}</p>{{ end }}
-                {{ with .Vote }}<p>{{ . }}</p>{{ end }}
-                {{ with .Justification }}<p>{{ . }}</p>{{ end }}
+                    {{ with .Voter }}<p>{{ . }}</p>{{ end }}
+                    {{ with .Vote }}<p>{{ . }}</p>{{ end }}
+                    {{ with .Justification }}<p>{{ . }}</p>{{ end }}
                 </div>
             {{ end }}
-                <button class="ui primary left labeled icon button" type="submit"><i class="users icon"></i> Proxy Vote
-                </button>
-            </div>
-        </form>
-    </div>
+            <button class="ui primary left labeled icon button" type="submit"><i class="users icon"></i> Proxy Vote
+            </button>
+        </div>
+    </form>
 </div>
 {{ template "footer.html" . }}
\ No newline at end of file
index 7b444e7..b549cea 100644 (file)
@@ -1,22 +1,17 @@
 {{ template "header.html" . }}
-<div class="column">
-    <div class="ui basic segment">
-        <div class="ui floated right secondary menu">
-            <a href="/motions/" class="item" title="Show all votes">Back to motions</a>
-        </div>
-    </div>
-</div>
+{{ template "return_header" . }}
 {{ with .Decision }}
-<div class="column">
     <div class="ui raised segment">
-    {{ template "motion_fragment" . }}
+        {{ template "motion_fragment" . }}
     </div>
-</div>
 {{ end }}
-<form action="/motions/{{ .Decision.Tag }}/withdraw" method="post">
-{{ csrfField }}
-    <div class="ui form">
-        <button class="ui primary left labeled icon button" type="submit"><i class="trash icon"></i> Withdraw</button>
-    </div>
-</form>
-{{ template "footer.html" . }}
+<div class="ui basic segment">
+    <form action="/motions/{{ .Decision.Tag }}/withdraw" method="post">
+        {{ csrfField }}
+        <div class="ui form">
+            <button class="ui primary left labeled icon button" type="submit"><i class="trash icon"></i> Withdraw
+            </button>
+        </div>
+    </form>
+</div>
+{{ template "footer.html" . }}
\ No newline at end of file