Port the web to bootstrap5
So it is responsive in phones.
This commit is contained in:
parent
8af2ad3758
commit
6a3da59c75
40 changed files with 1131 additions and 849 deletions
10
README.md
10
README.md
|
@ -77,14 +77,10 @@ https://gitlab.com/trantor/trantor/issues
|
||||||
|
|
||||||
All the matterial of this project is under WTFPL as described on the LICENSE
|
All the matterial of this project is under WTFPL as described on the LICENSE
|
||||||
file with the exception of:
|
file with the exception of:
|
||||||
* css/bootstrap.min.css css/bootstra-responsive.min.css js/bootstrap.min.js
|
* css/bootstrap.bundle.min.css css/bootstrap.bundle.min.css.map js/bootstrap.bundle.min.js
|
||||||
img/glyphicons-halflings-white.png img/glyphicons-halflings.png
|
js/bootstrap.bundle.min.js.map img/bootstrap-icons.svg
|
||||||
From the bootstrap framework: http://twitter.github.com/bootstrap/
|
From the bootstrap framework: https://getbootstrap.com/
|
||||||
* js/jquery.js
|
|
||||||
From jquery library: http://jquery.com/
|
|
||||||
* img/bright_squares.png
|
* img/bright_squares.png
|
||||||
From subtlepatterns: http://subtlepatterns.com/bright-squares/
|
From subtlepatterns: http://subtlepatterns.com/bright-squares/
|
||||||
* css/FredokaOne.ttf css/PTSerif.ttf
|
* css/FredokaOne.ttf css/PTSerif.ttf
|
||||||
From Google Web Fonts: http://www.google.com/webfonts
|
From Google Web Fonts: http://www.google.com/webfonts
|
||||||
* js/bootstrap-tokenfield.min.js dist/css/bootstrap-tokenfield.min.css
|
|
||||||
From Bootstrap Tokenfield: https://github.com/sliptree/bootstrap-tokenfield
|
|
||||||
|
|
9
css/bootstrap-responsive.min.css
vendored
9
css/bootstrap-responsive.min.css
vendored
File diff suppressed because one or more lines are too long
5
css/bootstrap-tokenfield.min.css
vendored
5
css/bootstrap-tokenfield.min.css
vendored
|
@ -1,5 +0,0 @@
|
||||||
/*!
|
|
||||||
* bootstrap-tokenfield
|
|
||||||
* https://github.com/sliptree/bootstrap-tokenfield
|
|
||||||
* Copyright 2013-2014 Sliptree and other contributors; Licensed MIT
|
|
||||||
*/@-webkit-keyframes blink{0%{border-color:#ededed}100%{border-color:#b94a48}}@-moz-keyframes blink{0%{border-color:#ededed}100%{border-color:#b94a48}}@keyframes blink{0%{border-color:#ededed}100%{border-color:#b94a48}}.tokenfield{height:auto;min-height:34px;padding-bottom:0}.tokenfield.focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.tokenfield .token{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;display:inline-block;border:1px solid #d9d9d9;background-color:#ededed;white-space:nowrap;margin:-1px 5px 5px 0;height:22px;vertical-align:top;cursor:default}.tokenfield .token:hover{border-color:#b9b9b9}.tokenfield .token.active{border-color:#52a8ec;border-color:rgba(82,168,236,.8)}.tokenfield .token.duplicate{border-color:#ebccd1;-webkit-animation-name:blink;animation-name:blink;-webkit-animation-duration:.1s;animation-duration:.1s;-webkit-animation-direction:normal;animation-direction:normal;-webkit-animation-timing-function:ease;animation-timing-function:ease;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}.tokenfield .token.invalid{background:0 0;border:1px solid transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;border-bottom:1px dotted #d9534f}.tokenfield .token.invalid.active{background:#ededed;border:1px solid #ededed;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.tokenfield .token .token-label{display:inline-block;overflow:hidden;text-overflow:ellipsis;padding-left:4px;vertical-align:top}.tokenfield .token .close{font-family:Arial;display:inline-block;line-height:100%;font-size:1.1em;line-height:1.49em;margin-left:5px;float:none;height:100%;vertical-align:top;padding-right:4px}.tokenfield .token-input{background:0 0;width:60px;min-width:60px;border:0;height:20px;padding:0;margin-bottom:6px;-webkit-box-shadow:none;box-shadow:none}.tokenfield .token-input:focus{border-color:transparent;outline:0;-webkit-box-shadow:none;box-shadow:none}.tokenfield.disabled{cursor:not-allowed;background-color:#eee}.tokenfield.disabled .token-input{cursor:not-allowed}.tokenfield.disabled .token:hover{cursor:not-allowed;border-color:#d9d9d9}.tokenfield.disabled .token:hover .close{cursor:not-allowed;opacity:.2;filter:alpha(opacity=20)}.has-warning .tokenfield.focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-error .tokenfield.focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-success .tokenfield.focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.tokenfield.input-sm,.input-group-sm .tokenfield{min-height:30px;padding-bottom:0}.input-group-sm .token,.tokenfield.input-sm .token{height:20px;margin-bottom:4px}.input-group-sm .token-input,.tokenfield.input-sm .token-input{height:18px;margin-bottom:5px}.tokenfield.input-lg,.input-group-lg .tokenfield{height:auto;min-height:45px;padding-bottom:4px}.input-group-lg .token,.tokenfield.input-lg .token{height:25px}.input-group-lg .token-label,.tokenfield.input-lg .token-label{line-height:23px}.input-group-lg .token .close,.tokenfield.input-lg .token .close{line-height:1.3em}.input-group-lg .token-input,.tokenfield.input-lg .token-input{height:23px;line-height:23px;margin-bottom:6px;vertical-align:top}.tokenfield.rtl{direction:rtl;text-align:right}.tokenfield.rtl .token{margin:-1px 0 5px 5px}.tokenfield.rtl .token .token-label{padding-left:0;padding-right:4px}
|
|
16
css/bootstrap.min.css
vendored
16
css/bootstrap.min.css
vendored
File diff suppressed because one or more lines are too long
1
css/bootstrap.min.css.map
Normal file
1
css/bootstrap.min.css.map
Normal file
File diff suppressed because one or more lines are too long
|
@ -10,19 +10,15 @@
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
src: local('PT Serif'), local('PTSerif-Regular'), url(/css/PTSerif.ttf) format('truetype');
|
src: local('PT Serif'), local('PTSerif-Regular'), url(/css/PTSerif.ttf) format('truetype');
|
||||||
}
|
}
|
||||||
h1, h2, h3, h4, h5, h6 {
|
h1, h2, h3, h4, h5, h6, .navbar-brand, .title {
|
||||||
font-family: 'Fredoka One', cursive;
|
font-family: 'Fredoka One', cursive;
|
||||||
}
|
}
|
||||||
p, div {
|
p, div {
|
||||||
font-family: 'PT Serif', serif;
|
font-family: 'PT Serif', serif;
|
||||||
}
|
}
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
body {
|
body {
|
||||||
background: url(/img/bright_squares.png) repeat 0 0;
|
background: url(/img/bright_squares.png) repeat 0 0;
|
||||||
}
|
}
|
||||||
.centered {
|
|
||||||
text-align:center;
|
|
||||||
}
|
|
||||||
.down {
|
|
||||||
vertical-align:text-bottom;
|
|
||||||
}
|
|
||||||
|
|
1
img/bootstrap-icons.svg
Normal file
1
img/bootstrap-icons.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 595 KiB |
7
js/bootstrap-tokenfield.min.js
vendored
7
js/bootstrap-tokenfield.min.js
vendored
File diff suppressed because one or more lines are too long
7
js/bootstrap.bundle.min.js
vendored
Normal file
7
js/bootstrap.bundle.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
js/bootstrap.bundle.min.js.map
Normal file
1
js/bootstrap.bundle.min.js.map
Normal file
File diff suppressed because one or more lines are too long
6
js/bootstrap.min.js
vendored
6
js/bootstrap.min.js
vendored
File diff suppressed because one or more lines are too long
2
js/jquery.js
vendored
2
js/jquery.js
vendored
File diff suppressed because one or more lines are too long
|
@ -27,7 +27,7 @@ func deleteHandler(h handler) {
|
||||||
}
|
}
|
||||||
book, err := h.db.GetBookID(id)
|
book, err := h.db.GetBookID(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.sess.Notify("Book not found!", "The book with id '"+id+"' is not there", "error")
|
h.sess.Notify("Book not found!", "The book with id '"+id+"' is not there", "danger")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
err = h.db.UpdateSubmissionByBook(id, "Rejected", nil)
|
err = h.db.UpdateSubmissionByBook(id, "Rejected", nil)
|
||||||
|
@ -124,7 +124,7 @@ func saveHandler(h handler) {
|
||||||
err := h.db.UpdateBook(id, book)
|
err := h.db.UpdateBook(id, book)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Updating book: ", err)
|
log.Error("Updating book: ", err)
|
||||||
h.sess.Notify("Can't modify book!", err.Error(), "error")
|
h.sess.Notify("Can't modify book!", err.Error(), "danger")
|
||||||
} else {
|
} else {
|
||||||
h.sess.Notify("Book Modified!", "", "success")
|
h.sess.Notify("Book Modified!", "", "success")
|
||||||
}
|
}
|
||||||
|
|
20
lib/list.go
20
lib/list.go
|
@ -15,7 +15,7 @@ func listHandler(h handler) {
|
||||||
list, err := h.db.GetBookList(listID)
|
list, err := h.db.GetBookList(listID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Error loading list ", listID, ": ", err)
|
log.Error("Error loading list ", listID, ": ", err)
|
||||||
h.sess.Notify("Something went wrong!", "Could not load the list", "error")
|
h.sess.Notify("Something went wrong!", "Could not load the list", "danger")
|
||||||
http.Redirect(h.w, h.r, h.r.Referer(), http.StatusFound)
|
http.Redirect(h.w, h.r, h.r.Referer(), http.StatusFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ func listPostHandler(h handler) {
|
||||||
userLists, err := h.db.GetListsByUser(h.sess.User)
|
userLists, err := h.db.GetListsByUser(h.sess.User)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Error loading user (", h.sess.User, ") lists: ", err)
|
log.Error("Error loading user (", h.sess.User, ") lists: ", err)
|
||||||
h.sess.Notify("Something went wrong!", "Could not add book to the list", "error")
|
h.sess.Notify("Something went wrong!", "Could not add book to the list", "danger")
|
||||||
http.Redirect(h.w, h.r, h.r.Referer(), http.StatusFound)
|
http.Redirect(h.w, h.r, h.r.Referer(), http.StatusFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ func listPostHandler(h handler) {
|
||||||
err = h.db.NewBookList(listID, listTitle, h.sess.User, []string{})
|
err = h.db.NewBookList(listID, listTitle, h.sess.User, []string{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Error creating list ", listTitle, " by user ", h.sess.User, ": ", err)
|
log.Error("Error creating list ", listTitle, " by user ", h.sess.User, ": ", err)
|
||||||
h.sess.Notify("Something went wrong!", "Could not add book to the list", "error")
|
h.sess.Notify("Something went wrong!", "Could not add book to the list", "danger")
|
||||||
http.Redirect(h.w, h.r, h.r.Referer(), http.StatusFound)
|
http.Redirect(h.w, h.r, h.r.Referer(), http.StatusFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -83,7 +83,7 @@ func listPostHandler(h handler) {
|
||||||
err = h.db.AddBookToList(listID, bookID)
|
err = h.db.AddBookToList(listID, bookID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Error adding book ", bookID, " to list ", listTitle, "(", listID, "): ", err)
|
log.Error("Error adding book ", bookID, " to list ", listTitle, "(", listID, "): ", err)
|
||||||
h.sess.Notify("Something went wrong!", "Could not add book to the list", "error")
|
h.sess.Notify("Something went wrong!", "Could not add book to the list", "danger")
|
||||||
http.Redirect(h.w, h.r, h.r.Referer(), http.StatusFound)
|
http.Redirect(h.w, h.r, h.r.Referer(), http.StatusFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -96,12 +96,12 @@ func listEditPostHandler(h handler) {
|
||||||
list, err := h.db.GetBookList(listID)
|
list, err := h.db.GetBookList(listID)
|
||||||
if err != nil || list == nil {
|
if err != nil || list == nil {
|
||||||
log.Error("Error loading list ", listID, ": ", err)
|
log.Error("Error loading list ", listID, ": ", err)
|
||||||
h.sess.Notify("Something went wrong!", "Could not save the list", "error")
|
h.sess.Notify("Something went wrong!", "Could not save the list", "danger")
|
||||||
http.Redirect(h.w, h.r, h.r.Referer(), http.StatusFound)
|
http.Redirect(h.w, h.r, h.r.Referer(), http.StatusFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if h.sess.User != list.User.Username {
|
if h.sess.User != list.User.Username {
|
||||||
h.sess.Notify("You are not the owner of the list!", "You can't edit it", "error")
|
h.sess.Notify("You are not the owner of the list!", "You can't edit it", "danger")
|
||||||
http.Redirect(h.w, h.r, h.r.Referer(), http.StatusFound)
|
http.Redirect(h.w, h.r, h.r.Referer(), http.StatusFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,7 @@ func listEditPostHandler(h handler) {
|
||||||
err = h.db.UpdateBookList(listID, title, description)
|
err = h.db.UpdateBookList(listID, title, description)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Error editing list ", list.Title, "(", listID, "): ", err)
|
log.Error("Error editing list ", list.Title, "(", listID, "): ", err)
|
||||||
h.sess.Notify("Something went wrong!", "Could not edit the list", "error")
|
h.sess.Notify("Something went wrong!", "Could not edit the list", "danger")
|
||||||
http.Redirect(h.w, h.r, h.r.Referer(), http.StatusFound)
|
http.Redirect(h.w, h.r, h.r.Referer(), http.StatusFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -126,12 +126,12 @@ func listRemoveHandler(h handler) {
|
||||||
list, err := h.db.GetBookList(listID)
|
list, err := h.db.GetBookList(listID)
|
||||||
if err != nil || list == nil {
|
if err != nil || list == nil {
|
||||||
log.Error("Error loading list ", listID, ": ", err)
|
log.Error("Error loading list ", listID, ": ", err)
|
||||||
h.sess.Notify("Something went wrong!", "Could not remove books from the list", "error")
|
h.sess.Notify("Something went wrong!", "Could not remove books from the list", "danger")
|
||||||
http.Redirect(h.w, h.r, h.r.Referer(), http.StatusFound)
|
http.Redirect(h.w, h.r, h.r.Referer(), http.StatusFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if h.sess.User != list.User.Username {
|
if h.sess.User != list.User.Username {
|
||||||
h.sess.Notify("You are not the owner of the list!", "You can't remove books from it", "error")
|
h.sess.Notify("You are not the owner of the list!", "You can't remove books from it", "danger")
|
||||||
http.Redirect(h.w, h.r, h.r.Referer(), http.StatusFound)
|
http.Redirect(h.w, h.r, h.r.Referer(), http.StatusFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -139,7 +139,7 @@ func listRemoveHandler(h handler) {
|
||||||
err = h.db.DeleteBookFromList(listID, bookID)
|
err = h.db.DeleteBookFromList(listID, bookID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Error remove book ", bookID, " from list ", listID, "): ", err)
|
log.Error("Error remove book ", bookID, " from list ", listID, "): ", err)
|
||||||
h.sess.Notify("Something went wrong!", "Could not remove book", "error")
|
h.sess.Notify("Something went wrong!", "Could not remove book", "danger")
|
||||||
http.Redirect(h.w, h.r, h.r.Referer(), http.StatusFound)
|
http.Redirect(h.w, h.r, h.r.Referer(), http.StatusFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ func submissionCommentHandler(h handler) {
|
||||||
err := h.db.UpdateSubmissionComment(submissionID, bookID, comment)
|
err := h.db.UpdateSubmissionComment(submissionID, bookID, comment)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Adding comment (submission: ", submissionID, ", book: ", bookID, ") <", comment, ">: ", err)
|
log.Error("Adding comment (submission: ", submissionID, ", book: ", bookID, ") <", comment, ">: ", err)
|
||||||
h.sess.Notify("Error adding a comment!", "Can't add the comment rigt now. Try again later or report it to the site admins", "error")
|
h.sess.Notify("Error adding a comment!", "Can't add the comment rigt now. Try again later or report it to the site admins", "danger")
|
||||||
} else {
|
} else {
|
||||||
h.sess.Notify("Comment added!", "", "success")
|
h.sess.Notify("Comment added!", "", "success")
|
||||||
}
|
}
|
||||||
|
@ -131,17 +131,17 @@ func storeHandler(h handler) {
|
||||||
}
|
}
|
||||||
book, err := h.db.GetBookID(id)
|
book, err := h.db.GetBookID(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.sess.Notify("Book not found!", "The book with id '"+id+"' is not there", "error")
|
h.sess.Notify("Book not found!", "The book with id '"+id+"' is not there", "danger")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.sess.Notify("An error ocurred!", err.Error(), "error")
|
h.sess.Notify("An error ocurred!", err.Error(), "danger")
|
||||||
log.Error("Error getting book for storing '", book.Title, "': ", err.Error())
|
log.Error("Error getting book for storing '", book.Title, "': ", err.Error())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
err = h.db.ActiveBook(id)
|
err = h.db.ActiveBook(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.sess.Notify("An error ocurred!", err.Error(), "error")
|
h.sess.Notify("An error ocurred!", err.Error(), "danger")
|
||||||
log.Error("Error storing book '", book.Title, "': ", err.Error())
|
log.Error("Error storing book '", book.Title, "': ", err.Error())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ var tmpl_funcs = map[string]interface{}{
|
||||||
"strings_join": stringsJoin,
|
"strings_join": stringsJoin,
|
||||||
"download_url": downloadUrl,
|
"download_url": downloadUrl,
|
||||||
"size2mb": size2mb,
|
"size2mb": size2mb,
|
||||||
|
"mul": mul,
|
||||||
}
|
}
|
||||||
|
|
||||||
type Status struct {
|
type Status struct {
|
||||||
|
@ -114,6 +115,10 @@ func size2mb(size int) float32 {
|
||||||
return float32(size) / (1024.0 * 1024.0)
|
return float32(size) / (1024.0 * 1024.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func mul(a, b int) int {
|
||||||
|
return a * b
|
||||||
|
}
|
||||||
|
|
||||||
type DevTemplateExecutor struct {
|
type DevTemplateExecutor struct {
|
||||||
assetsPath string
|
assetsPath string
|
||||||
tpe string
|
tpe string
|
||||||
|
|
|
@ -92,7 +92,7 @@ func uploadPostHandler(h handler) {
|
||||||
const _2M int64 = (1 << 20) * 2
|
const _2M int64 = (1 << 20) * 2
|
||||||
|
|
||||||
if h.ro {
|
if h.ro {
|
||||||
h.sess.Notify("Upload failed!", "The library is in Read Only mode, no books can be uploaded", "error")
|
h.sess.Notify("Upload failed!", "The library is in Read Only mode, no books can be uploaded", "danger")
|
||||||
uploadHandler(h)
|
uploadHandler(h)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -109,13 +109,13 @@ func uploadPostHandler(h handler) {
|
||||||
submission := database.Submission{
|
submission := database.Submission{
|
||||||
SubmissionID: submissionID,
|
SubmissionID: submissionID,
|
||||||
Filename: f.Filename,
|
Filename: f.Filename,
|
||||||
Status: "Waiting to be processed",
|
Status: "Waiting to be processed, reload the page in few minutes",
|
||||||
}
|
}
|
||||||
|
|
||||||
file, err := f.Open()
|
file, err := f.Open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Can not open uploaded file ", f.Filename, ": ", err)
|
log.Error("Can not open uploaded file ", f.Filename, ": ", err)
|
||||||
h.sess.Notify("Upload problem!", "There was a problem with book "+f.Filename, "error")
|
h.sess.Notify("Upload problem!", "There was a problem with book "+f.Filename, "danger")
|
||||||
submission.Status = "It was not possible to read the book"
|
submission.Status = "It was not possible to read the book"
|
||||||
h.db.AddSubmission(submission, h.sess.User)
|
h.db.AddSubmission(submission, h.sess.User)
|
||||||
continue
|
continue
|
||||||
|
|
22
lib/user.go
22
lib/user.go
|
@ -30,7 +30,7 @@ func loginPostHandler(h handler) {
|
||||||
h.sess.Notify("Successful login!", "Welcome "+user, "success")
|
h.sess.Notify("Successful login!", "Welcome "+user, "success")
|
||||||
} else {
|
} else {
|
||||||
log.Warn("User ", user, " bad user or password")
|
log.Warn("User ", user, " bad user or password")
|
||||||
h.sess.Notify("Invalid login!", "user or password invalid", "error")
|
h.sess.Notify("Invalid login!", "user or password invalid", "danger")
|
||||||
}
|
}
|
||||||
h.sess.Save(h.w, h.r)
|
h.sess.Save(h.w, h.r)
|
||||||
http.Redirect(h.w, h.r, h.r.Referer(), http.StatusFound)
|
http.Redirect(h.w, h.r, h.r.Referer(), http.StatusFound)
|
||||||
|
@ -40,16 +40,16 @@ func createUserHandler(h handler) {
|
||||||
pass := h.r.FormValue("pass")
|
pass := h.r.FormValue("pass")
|
||||||
confirmPass := h.r.FormValue("confirmPass")
|
confirmPass := h.r.FormValue("confirmPass")
|
||||||
if pass != confirmPass {
|
if pass != confirmPass {
|
||||||
h.sess.Notify("Registration error!", "Passwords don't match", "error")
|
h.sess.Notify("Registration error!", "Passwords don't match", "danger")
|
||||||
} else if pass == "" {
|
} else if pass == "" {
|
||||||
h.sess.Notify("Registration error!", "The password can't be empty", "error")
|
h.sess.Notify("Registration error!", "The password can't be empty", "danger")
|
||||||
} else {
|
} else {
|
||||||
user := strings.TrimSpace(h.r.FormValue("user"))
|
user := strings.TrimSpace(h.r.FormValue("user"))
|
||||||
err := h.db.AddUser(user, pass)
|
err := h.db.AddUser(user, pass)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
h.sess.Notify("Account created!", "Welcome "+user+". Now you can login", "success")
|
h.sess.Notify("Account created!", "Welcome "+user+". Now you can login", "success")
|
||||||
} else {
|
} else {
|
||||||
h.sess.Notify("Registration error!", err.Error(), "error")
|
h.sess.Notify("Registration error!", err.Error(), "danger")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
h.sess.Save(h.w, h.r)
|
h.sess.Save(h.w, h.r)
|
||||||
|
@ -91,14 +91,14 @@ func settingsHandler(h handler) {
|
||||||
pass2 := h.r.FormValue("password2")
|
pass2 := h.r.FormValue("password2")
|
||||||
switch {
|
switch {
|
||||||
case !h.db.ValidPassword(h.sess.User, current_pass):
|
case !h.db.ValidPassword(h.sess.User, current_pass):
|
||||||
h.sess.Notify("Password error!", "The current password given don't match with the user password. Try again", "error")
|
h.sess.Notify("Password error!", "The current password given don't match with the user password. Try again", "danger")
|
||||||
case pass1 != pass2:
|
case pass1 != pass2:
|
||||||
h.sess.Notify("Passwords don't match!", "The new password and the confirmation password don't match. Try again", "error")
|
h.sess.Notify("Passwords don't match!", "The new password and the confirmation password don't match. Try again", "danger")
|
||||||
default:
|
default:
|
||||||
err := h.db.SetPassword(h.sess.User, pass1)
|
err := h.db.SetPassword(h.sess.User, pass1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("Can't update password for user ", h.sess.User, ": ", err)
|
log.Warn("Can't update password for user ", h.sess.User, ": ", err)
|
||||||
h.sess.Notify("Password error!", "An error has ocurred updating the password in the database. Sorry.", "error")
|
h.sess.Notify("Password error!", "An error has ocurred updating the password in the database. Sorry.", "danger")
|
||||||
} else {
|
} else {
|
||||||
h.sess.Notify("Password updated!", "Your new password is correctly set.", "success")
|
h.sess.Notify("Password updated!", "Your new password is correctly set.", "success")
|
||||||
}
|
}
|
||||||
|
@ -167,14 +167,14 @@ func userAdminPostHandler(h handler) {
|
||||||
if password != "" {
|
if password != "" {
|
||||||
err := h.db.SetPassword(username, password)
|
err := h.db.SetPassword(username, password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.sess.Notify("An error ocurred!", err.Error(), "error")
|
h.sess.Notify("An error ocurred!", err.Error(), "danger")
|
||||||
} else {
|
} else {
|
||||||
h.sess.Notify("Password updated!", "", "success")
|
h.sess.Notify("Password updated!", "", "success")
|
||||||
}
|
}
|
||||||
} else if role != "" {
|
} else if role != "" {
|
||||||
err := h.db.SetRole(username, role)
|
err := h.db.SetRole(username, role)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.sess.Notify("An error ocurred!", err.Error(), "error")
|
h.sess.Notify("An error ocurred!", err.Error(), "danger")
|
||||||
} else {
|
} else {
|
||||||
h.sess.Notify("Role updated!", "", "success")
|
h.sess.Notify("Role updated!", "", "success")
|
||||||
}
|
}
|
||||||
|
@ -194,11 +194,11 @@ func addUserHandler(h handler) {
|
||||||
role := h.r.FormValue("role")
|
role := h.r.FormValue("role")
|
||||||
err := h.db.AddUser(username, password)
|
err := h.db.AddUser(username, password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.sess.Notify("An error ocurred!", err.Error(), "error")
|
h.sess.Notify("An error ocurred!", err.Error(), "danger")
|
||||||
} else {
|
} else {
|
||||||
err := h.db.SetRole(username, role)
|
err := h.db.SetRole(username, role)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.sess.Notify("An error ocurred!", err.Error(), "error")
|
h.sess.Notify("An error ocurred!", err.Error(), "danger")
|
||||||
} else {
|
} else {
|
||||||
h.sess.Notify("User created!", "", "success")
|
h.sess.Notify("User created!", "", "success")
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{{template "header.html" .S}}
|
{{template "header.html" .S}}
|
||||||
|
|
||||||
<div class="row">
|
<div class="row justify-content-center">
|
||||||
<div class="span10 offset1">
|
<div class="col-sm-10">
|
||||||
<h4>Page not found</h4>
|
<h4>Page not found</h4>
|
||||||
<p>
|
<p>
|
||||||
The requested page don't exist.
|
The requested page don't exist.
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
<h4>Donations</h4>
|
<h4>Donations</h4>
|
||||||
|
|
||||||
<p>If you feel like donate some bitcoins we'll gladly accept them. You can request one bitcoin key for you or use our public bitcoin key:</p>
|
<p>If you feel like donate some bitcoins we'll gladly accept them. You can request one bitcoin key for you or use our public bitcoin key:</p>
|
||||||
<p class="centered text-success">1JioYbSYDH4JQYbhF7tX2kGUVZc2vzvugx <br />
|
<p class="text-center text-success">1JioYbSYDH4JQYbhF7tX2kGUVZc2vzvugx <br />
|
||||||
<img src="/img/bitcoin.png" alt="1JioYbSYDH4JQYbhF7tX2kGUVZc2vzvugx" />
|
<img src="/img/bitcoin.png" alt="1JioYbSYDH4JQYbhF7tX2kGUVZc2vzvugx" />
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
|
@ -5,111 +5,165 @@
|
||||||
{{with .Book}}
|
{{with .Book}}
|
||||||
<script>
|
<script>
|
||||||
function delBook(){
|
function delBook(){
|
||||||
var div = document.getElementById('delete');
|
const div = document.getElementById('delete');
|
||||||
div.innerHTML =
|
div.classList.remove("visually-hidden");
|
||||||
'<div class="alert alert-error fade in"> \
|
}
|
||||||
<a class="close" data-dismiss="alert">×</a> \
|
function closeAlert() {
|
||||||
<h4 class="alert-heading">Do you really want to delete it?</h4> \
|
const div = document.getElementById('delete');
|
||||||
<p>Remove a book is permanent, you won\'t be able to get it back</p> \
|
div.classList.add("visually-hidden");
|
||||||
<a class="btn btn-danger" href="/delete/{{.ID}}/">Remove it</a> \
|
|
||||||
<a class="btn" href="#" data-dismiss="alert">Cancel</a> \
|
|
||||||
</div>';
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<div id="delete"></div>
|
<div id="delete" class="alert alert-danger fade visually-hidden show" role="alert">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-11">
|
||||||
|
<h4 class="alert-heading">Do you really want to delete it?</h4>
|
||||||
|
<p>Remove a book is permanent, you won't be able to get it back</p>
|
||||||
|
<a class="btn btn-danger" href="/delete/{{.ID}}/">Remove it</a>
|
||||||
|
<a class="btn" href="#" onClick="closeAlert();">Cancel</a>
|
||||||
|
</div>
|
||||||
|
<div class="col-1 justify-content-end">
|
||||||
|
<button type="button" class="btn-close" onClick="closeAlert();"></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<header class="row">
|
<header class="row justify-content-end">
|
||||||
<div class="span8 offset4">
|
|
||||||
<h1>{{.Title}}
|
<h1>{{.Title}}
|
||||||
{{if not .Active}}
|
{{if not .Active}}
|
||||||
<span class="label label-warning">waiting for moderation</span>
|
<span class="badge label-warning text-dark">waiting for moderation</span>
|
||||||
{{end}}
|
{{end}}
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
|
||||||
</header>
|
</header>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
{{if .Cover}}
|
{{if .Cover}}
|
||||||
<div class="span4">
|
<div class="col-sm-4 text-center">
|
||||||
<img src="/cover/{{.ID}}/big/{{.Title}}.jpg" alt="{{.Title}}" class="pull-right" />
|
<img src="/cover/{{.ID}}/big/{{.Title}}.jpg" alt="{{.Title}}" class="float-sm-end img-fluid" />
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
<div class="span8">
|
<div class="col-sm-8">
|
||||||
<div class="row"><p></p></div>
|
<div class="row">
|
||||||
<div class="row">
|
<div class="col-md-8">
|
||||||
<div class="span5">
|
<dl class="row">
|
||||||
<dl class="dl-horizontal">
|
{{if .Authors}}
|
||||||
{{if .Authors}}<dt>Authors</dt> <dd>{{range .Authors}}<a href="/search/?q=author:{{.}}">{{.}}</a>, {{end}}</dd>{{end}}
|
<dt class="col-sm-3 text-sm-end">Authors</dt>
|
||||||
{{if .Publisher}}<dt>Publisher</dt> <dd><a href="/search/?q=publisher:{{.Publisher}}">{{.Publisher}}</a></dd>{{end}}
|
<dd class="col-sm-9 text-start">{{range .Authors}}<a href="/search/?q=author:{{.}}">{{.}}</a>, {{end}}</dd>
|
||||||
{{if .Tags}}<dt>Tags</dt> <dd>{{range .Tags}}<a href="/search/?q=tag:{{.}}">{{.}}</a>, {{end}}</dd>{{end}}
|
{{end}}
|
||||||
{{if .Isbn}}<dt>ISBN</dt> <dd>{{.Isbn}}</dd>{{end}}
|
{{if .Publisher}}
|
||||||
{{if .Date}}<dt>Date</dt> <dd>{{.Date}}</dd>{{end}}
|
<dt class="col-sm-3 text-sm-end">Publisher</dt>
|
||||||
{{if .FileSize}}<dt>Size</dt> <dd>{{printf "%.2f" (size2mb .FileSize)}} MB</dd>{{end}}
|
<dd class="col-sm-9 text-start"><a href="/search/?q=publisher:{{.Publisher}}">{{.Publisher}}</a></dd>
|
||||||
{{if .Lang}}<dt>Lang</dt> <dd><a href="/search/?q=lang:{{.Lang}}">{{.Lang}}</a> </dd>{{end}}
|
{{end}}
|
||||||
</dl>
|
{{if .Tags}}
|
||||||
</div>
|
<dt class="col-sm-3 text-sm-end">Tags</dt>
|
||||||
<div class="span3">
|
<dd class="col-sm-9 text-start">{{range .Tags}}<a href="/search/?q=tag:{{.}}">{{.}}</a>, {{end}}</dd>
|
||||||
<div class="row">
|
{{end}}
|
||||||
<div class="btn-group pull-right">
|
{{if .Isbn}}
|
||||||
<a href="{{download_url .}}" class="btn btn-large btn-inverse"><i class="icon-download-alt icon-white"></i> download</a>
|
<dt class="col-sm-3 text-sm-end">ISBN</dt>
|
||||||
<a href="/read/{{.ID}}" class="btn btn-large btn-warning"><i class="icon-eye-open icon-white"></i> read it!</a>
|
<dd class="col-sm-9 text-start">{{.Isbn}}</dd>
|
||||||
|
{{end}}
|
||||||
|
{{if .Date}}
|
||||||
|
<dt class="col-sm-3 text-sm-end">Date</dt>
|
||||||
|
<dd class="col-sm-9 text-start">{{.Date}}</dd>
|
||||||
|
{{end}}
|
||||||
|
{{if .FileSize}}
|
||||||
|
<dt class="col-sm-3 text-sm-end">Size</dt>
|
||||||
|
<dd class="col-sm-9 text-start">{{printf "%.2f" (size2mb .FileSize)}} MB</dd>
|
||||||
|
{{end}}
|
||||||
|
{{if .Lang}}
|
||||||
|
<dt class="col-sm-3 text-sm-end">Lang</dt>
|
||||||
|
<dd class="col-sm-9 text-start"><a href="/search/?q=lang:{{.Lang}}">{{.Lang}}</a> </dd>
|
||||||
|
{{end}}
|
||||||
|
</dl>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<div class="btn-group d-flex justify-content-end">
|
||||||
|
<a href="{{download_url .}}" class="btn btn-dark btn-sm">
|
||||||
|
<svg class="bi" width="1em" height="1em" fill="currentColor">
|
||||||
|
<use xlink:href="/img/bootstrap-icons.svg#file-earmark-arrow-down"/>
|
||||||
|
</svg>
|
||||||
|
download
|
||||||
|
</a>
|
||||||
|
<a href="/read/{{.ID}}" class="btn btn-warning btn-sm">
|
||||||
|
<svg class="bi" width="1em" height="1em" fill="currentColor">
|
||||||
|
<use xlink:href="/img/bootstrap-icons.svg#eyeglasses"/>
|
||||||
|
</svg>
|
||||||
|
read it!
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="pull-right">
|
<div class="text-end">
|
||||||
<small>Downloaded: {{$downloadCounter}} times</small>
|
<small>Downloaded: {{$downloadCounter}} times</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{{if eq $role "admin" "moderator"}}
|
||||||
{{if eq $role "admin" "moderator"}}
|
<div class="row"><p></p></div>
|
||||||
<div class="row"><p></p></div>
|
<div class="btn-group d-flex justify-content-end">
|
||||||
<div class="row">
|
<a href="/edit/{{.ID}}" class="btn btn-primary btn-sm">
|
||||||
<div class="btn-group pull-right">
|
<svg class="bi" width="1em" height="1em" fill="currentColor">
|
||||||
<a href="/edit/{{.ID}}" class="btn btn-primary"><i class="icon-pencil"></i> Edit</a>
|
<use xlink:href="/img/bootstrap-icons.svg#pencil"/>
|
||||||
<a href="#" onClick="delBook();" class="btn btn-danger"><i class="icon-trash"></i> Delete</a>
|
</svg>
|
||||||
</div>
|
edit
|
||||||
</div>
|
</a>
|
||||||
{{end}}
|
<a href="#" onClick="delBook();" class="btn btn-danger btn-sm">
|
||||||
</div>
|
<svg class="bi" width="1em" height="1em" fill="currentColor">
|
||||||
</div>
|
<use xlink:href="/img/bootstrap-icons.svg#trash"/>
|
||||||
|
</svg>
|
||||||
|
delete
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="span8">
|
|
||||||
{{range .Description}}
|
{{range .Description}}
|
||||||
<p>{{.}}</p>
|
<p>{{.}}</p>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{if .Lists}}
|
{{if .Lists}}
|
||||||
<br />
|
<br />
|
||||||
<div class="row">
|
<div class="row justify-content-center">
|
||||||
<div class="span10 offset1">
|
<div class="col-10">
|
||||||
<h4>Book in lists:</h4>
|
<h4>Book in lists:</h4>
|
||||||
<ul class="nav nav-tabs nav-stacked">
|
<ul class="nav flex-column">
|
||||||
{{range .Lists}}
|
{{range .Lists}}
|
||||||
<li><a href="/list/{{.ListID}}">{{.Title}} ({{len .Books}})
|
<li class="nav-item">
|
||||||
<span class="pull-right">By {{.User.Username}}</span></a>
|
<a class="nav-link" href="/list/{{.ListID}}">
|
||||||
</li>
|
<div class="row">
|
||||||
{{end}}
|
<div class="col">{{.Title}} ({{len .Books}})</div>
|
||||||
</ul>
|
<div class="col text-end">By {{.User.Username}}</div>
|
||||||
</div>
|
</div>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{{end}}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
<br />
|
<br />
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
|
<br />
|
||||||
{{if .S.User}}
|
{{if .S.User}}
|
||||||
<div class="row">
|
<form method="POST" action="/list/">
|
||||||
<h5 class="offset1 span2">Add book to a list:</h5>
|
<div class="row g-3 align-items-start">
|
||||||
<form class="form-inline" method="POST" action="/list/">
|
<h6 class="col-sm-2 text-sm-end col-form-label">Add book to a list:</h6>
|
||||||
<input type="hidden" id="book_id" name="book_id" value="{{.Book.ID}}">
|
<input type="hidden" id="book_id" name="book_id" value="{{.Book.ID}}">
|
||||||
<div class="input-append">
|
<div class="col-sm-5">
|
||||||
<input type="text" data-provide="typeahead" data-source='["{{strings_join .UserLists}}"]' data-items="4" id="list" name="list" autocomplete="off">
|
<div class="input-group">
|
||||||
<button type="submit" class="btn btn-primary">Add</button>
|
<input class="form-control" list="bookListOptions" id="list" name="list" placeholder="Write a name of a list to create or add">
|
||||||
|
<datalist id="bookListOptions">
|
||||||
|
{{range .UserLists}}
|
||||||
|
<option value="{{.}}">
|
||||||
|
{{end}}
|
||||||
|
</datalist>
|
||||||
|
<button type="submit" class="btn btn-primary">Add</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</div>
|
||||||
</div>
|
</form>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{template "footer.html" .S}}
|
{{template "footer.html" .S}}
|
||||||
|
|
|
@ -1,25 +1,39 @@
|
||||||
{{range .}}
|
{{range .}}
|
||||||
<div class="row">
|
<div class="card mb-3">
|
||||||
<div class="span1">
|
<div class="row g-0">
|
||||||
<p class="pull-right"><a href="/book/{{.ID}}" title="{{.Description}}">{{if .Cover}}<img class="img-rounded" src="/cover/{{.ID}}/small/{{.Title}}.jpg" alt="{{.Title}}" />{{end}}</a></p>
|
<div class="col-md-1 d-flex align-items-center justify-content-center">
|
||||||
</div>
|
<a href="/book/{{.ID}}" title="{{.Description}}">
|
||||||
<div class="span10 well">
|
{{if .Cover}}<img class="rounded" src="/cover/{{.ID}}/small/{{.Title}}.jpg" alt="{{.Title}}" />{{end}}
|
||||||
<div class="row">
|
</a>
|
||||||
<div class="span7">
|
|
||||||
<p>
|
|
||||||
<span class="muted">[{{if .Lang}}{{.Lang}}{{end}}]</span>
|
|
||||||
<a href="/book/{{.ID}}" title="{{.Description}}"><strong>{{.Title}}</strong></a>
|
|
||||||
<span class="muted">{{if .Publisher}}{{.Publisher}}{{end}}</span><br />
|
|
||||||
{{range .Authors}}{{.}}, {{end}}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="span3">
|
|
||||||
<div class="btn-group pull-right">
|
|
||||||
<a href="{{download_url .}}" class="btn btn-inverse"><i class="icon-download-alt icon-white"></i> download</a>
|
|
||||||
<a href="/read/{{.ID}}" class="btn btn-warning"><i class="icon-eye-open icon-white"></i> read it!</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-md-11">
|
||||||
|
<div class="card-body">
|
||||||
|
<p class="card-title">
|
||||||
|
<span class="text-muted">[{{if .Lang}}{{.Lang}}{{end}}]</span>
|
||||||
|
<a href="/book/{{.ID}}" title="{{.Description}}"><strong>{{.Title}}</strong></a>
|
||||||
|
<span class="text-muted">{{if .Publisher}}{{.Publisher}}{{end}}</span>
|
||||||
|
</p>
|
||||||
|
<div class="card-text row">
|
||||||
|
<p class="col-9">{{range .Authors}}{{.}}, {{end}}</p>
|
||||||
|
<div class="col-3">
|
||||||
|
<div class="btn-group d-flex justify-content-end">
|
||||||
|
<a href="{{download_url .}}" class="btn btn-dark btn-sm">
|
||||||
|
<svg class="bi" width="1em" height="1em" fill="currentColor">
|
||||||
|
<use xlink:href="/img/bootstrap-icons.svg#file-earmark-arrow-down"/>
|
||||||
|
</svg>
|
||||||
|
download
|
||||||
|
</a>
|
||||||
|
<a href="/read/{{.ID}}" class="btn btn-warning btn-sm">
|
||||||
|
<svg class="bi" width="1em" height="1em" fill="currentColor">
|
||||||
|
<use xlink:href="/img/bootstrap-icons.svg#eyeglasses"/>
|
||||||
|
</svg>
|
||||||
|
read it!
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
@ -2,35 +2,70 @@
|
||||||
|
|
||||||
<h4>Dashboard</h4>
|
<h4>Dashboard</h4>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row justify-content-center">
|
||||||
<div class="span8 offset2">
|
<div class="col-sm-8">
|
||||||
<ul class="nav nav-tabs nav-stacked">
|
<ul class="nav flex-column">
|
||||||
{{if eq .S.Role "admin" "moderator"}}
|
{{if eq .S.Role "admin" "moderator"}}
|
||||||
<li><a href="/submission/moderate/"><i class="icon-book"></i> Moderate submissions</a></li>
|
<li class="nav-item">
|
||||||
{{if eq .S.Role "admin"}}
|
<a class="nav-link" href="/submission/moderate/">
|
||||||
<li><a href="/news/edit"><i class="icon-certificate"></i> Edit news</a></li>
|
<svg class="bi" width="1em" height="1em" fill="currentColor">
|
||||||
{{end}}
|
<use xlink:href="/img/bootstrap-icons.svg#journal-check"/>
|
||||||
<li class="divider"></li>
|
</svg>
|
||||||
{{end}}
|
Moderate submissions
|
||||||
<li><a href="/submission/"><i class="icon-folder-open"></i> Submissions</a></li>
|
</a>
|
||||||
<li><a href="/settings/"><i class="icon-wrench"></i> Settings</a></li>
|
</li>
|
||||||
<li class="divider"></li>
|
{{if eq .S.Role "admin"}}
|
||||||
<li><a href="/logout/"><i class="icon-off"></i> Log Out</a></li>
|
<li class="nav-item">
|
||||||
</ul>
|
<a class="nav-link" href="/news/edit">
|
||||||
|
<svg class="bi" width="1em" height="1em" fill="currentColor">
|
||||||
|
<use xlink:href="/img/bootstrap-icons.svg#newspaper"/>
|
||||||
|
</svg>
|
||||||
|
Edit news
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{{end}}
|
||||||
|
{{end}}
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="/submission/">
|
||||||
|
<svg class="bi" width="1em" height="1em" fill="currentColor">
|
||||||
|
<use xlink:href="/img/bootstrap-icons.svg#journal-arrow-up"/>
|
||||||
|
</svg>
|
||||||
|
Submissions
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="/settings/">
|
||||||
|
<svg class="bi" width="1em" height="1em" fill="currentColor">
|
||||||
|
<use xlink:href="/img/bootstrap-icons.svg#gear"/>
|
||||||
|
</svg>
|
||||||
|
Settings
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="/logout/">
|
||||||
|
<svg class="bi" width="1em" height="1em" fill="currentColor">
|
||||||
|
<use xlink:href="/img/bootstrap-icons.svg#power"/>
|
||||||
|
</svg>
|
||||||
|
Log Out
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{if .Lists}}
|
{{if .Lists}}
|
||||||
<br />
|
<br />
|
||||||
<h4>My book lists</h4>
|
<h4>My book lists</h4>
|
||||||
<div class="row">
|
<div class="row justify-content-center">
|
||||||
<div class="span8 offset2">
|
<div class="col-8">
|
||||||
<ul class="nav nav-tabs nav-stacked">
|
<ul class="nav flex-column">
|
||||||
{{range .Lists}}
|
{{range .Lists}}
|
||||||
<li><a href="/list/{{.ListID}}">{{.Title}} ({{len .Books}})</a></li>
|
<li class="nav-item">
|
||||||
{{end}}
|
<a class="nav-link" href="/list/{{.ListID}}">{{.Title}} ({{len .Books}})</a>
|
||||||
|
</li>
|
||||||
|
{{end}}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
|
|
|
@ -1,90 +1,113 @@
|
||||||
{{template "header.html" .S}}
|
{{template "header.html" .S}}
|
||||||
|
|
||||||
|
<!-- TODO: tokenfield -->
|
||||||
|
|
||||||
{{$submissionID := .SubmissionID}}
|
{{$submissionID := .SubmissionID}}
|
||||||
{{with .Book}}
|
{{with .Book}}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
{{if .Cover}}
|
{{if .Cover}}
|
||||||
<div class="span4">
|
<div class="d-none d-sm-block col-sm-4">
|
||||||
<img src="/cover/{{.ID}}/big/{{.Title}}.jpg" alt="{{.Title}}" class="pull-right" />
|
<img src="/cover/{{.ID}}/big/{{.Title}}.jpg" alt="{{.Title}}" class="img-fluid float-end" />
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
<div class="span8">
|
<div class="col-sm-8">
|
||||||
<form class="form-horizontal" method="POST"
|
<form method="POST"
|
||||||
{{if $submissionID}}
|
{{if $submissionID}}
|
||||||
action="/submission/{{$submissionID}}/save/{{.ID}}">
|
action="/submission/{{$submissionID}}/save/{{.ID}}">
|
||||||
{{else}}
|
{{else}}
|
||||||
action="/save/{{.ID}}">
|
action="/save/{{.ID}}">
|
||||||
{{end}}
|
{{end}}
|
||||||
<fieldset>
|
<div class="row g-3 align-items-center">
|
||||||
<div class="control-group">
|
<div class="col-sm-2 text-sm-end">
|
||||||
<label class="control-label" for="title">Title</label>
|
<label class="col-form-label" for="title">Title</label>
|
||||||
<div class="controls">
|
</div>
|
||||||
<input class="input-xlarge" type="text" id="title" value="{{.Title}}" name="title">
|
<div class="col-sm-10">
|
||||||
</div>
|
<input class="form-control" type="text" id="title" value="{{.Title}}" name="title">
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</div>
|
||||||
<fieldset>
|
<br />
|
||||||
<div class="control-group">
|
<div class="row g-3 align-items-center">
|
||||||
<label class="control-label" for="author">Author</label>
|
<div class="col-sm-2 text-sm-end">
|
||||||
<div class="controls">
|
<label class="col-form-label" for="author">Author</label>
|
||||||
{{range .Authors}}
|
</div>
|
||||||
<input class="input-xlarge" type="text" id="author" value="{{.}}" name="author">
|
<div class="col-sm-10">
|
||||||
{{end}}
|
<div class="row">
|
||||||
<input class="input-xlarge" type="text" id="author" placeholder="Add author" name="author">
|
{{range .Authors}}
|
||||||
</div>
|
<div class="col-sm-6">
|
||||||
</div>
|
<input class="form-control" type="text" id="author" value="{{.}}" name="author">
|
||||||
<div class="control-group">
|
</div>
|
||||||
<label class="control-label" for="publisher">Publisher</label>
|
{{end}}
|
||||||
<div class="controls">
|
<div class="col-sm-6">
|
||||||
<input class="input-xlarge" type="text" id="publisher" value="{{.Publisher}}" name="publisher">
|
<input class="form-control" type="text" id="author" placeholder="Add author" name="author">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="control-group">
|
</div>
|
||||||
<label class="control-label" for="tags">Tags</label>
|
</div>
|
||||||
<div class="controls">
|
<br />
|
||||||
<input class="input-xlarge" type="text" id="tags" value="{{range .Tags}}{{.}},{{end}}" name="tags" placeholder="Add tag and hit enter">
|
<div class="row g-3 align-items-center">
|
||||||
</div>
|
<div class="col-sm-2 text-sm-end">
|
||||||
</div>
|
<label class="col-form-label" for="publisher">Publisher</label>
|
||||||
<div class="control-group">
|
</div>
|
||||||
<label class="control-label" for="tags">ISBN</label>
|
<div class="col-sm-10">
|
||||||
<div class="controls">
|
<input class="form-control" type="text" id="publisher" value="{{.Publisher}}" name="publisher">
|
||||||
<input class="input-xlarge" type="text" id="isbn" value="{{.Isbn}}" name="isbn">
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<br />
|
||||||
<div class="control-group">
|
<div class="row g-3 align-items-center">
|
||||||
<label class="control-label" for="date">Date</label>
|
<div class="col-sm-2 text-sm-end">
|
||||||
<div class="controls">
|
<label class="col-form-label" for="tags">Tags</label>
|
||||||
<input class="input-xlarge" type="text" id="date" value="{{.Date}}" name="date">
|
</div>
|
||||||
</div>
|
<div class="col-sm-10">
|
||||||
</div>
|
<input class="form-control" type="text" id="tags" value="{{range .Tags}}{{.}},{{end}}" name="tags" placeholder="Add tag and hit enter">
|
||||||
<div class="control-group">
|
</div>
|
||||||
<label class="control-label" for="lang">Lang</label>
|
</div>
|
||||||
<div class="controls">
|
<br />
|
||||||
<input class="input-xlarge" type="text" id="langs" value="{{.Lang}}" name="lang">
|
<div class="row g-3 align-items-center">
|
||||||
</div>
|
<div class="col-sm-2 text-sm-end">
|
||||||
</div>
|
<label class="col-form-label" for="tags">ISBN</label>
|
||||||
</fieldset>
|
</div>
|
||||||
<fieldset>
|
<div class="col-sm-10">
|
||||||
<div class="control-group">
|
<input class="form-control" type="text" id="isbn" value="{{.Isbn}}" name="isbn">
|
||||||
<label class="control-label" for="description">Description</label>
|
</div>
|
||||||
<div class="controls">
|
</div>
|
||||||
<textarea class="input-xlarge" id="description" rows="5" name="description">{{.Description}}</textarea>
|
<br />
|
||||||
</div>
|
<div class="row g-3 align-items-center">
|
||||||
</div>
|
<div class="col-sm-2 text-sm-end">
|
||||||
<div class="form-actions">
|
<label class="col-form-label" for="date">Date</label>
|
||||||
<button type="submit" class="btn btn-primary">Save</button>
|
</div>
|
||||||
<a href="/book/{{.ID}}" class="btn">Cancel</a>
|
<div class="col-sm-10">
|
||||||
</div>
|
<input class="form-control" type="text" id="date" value="{{.Date}}" name="date">
|
||||||
</fieldset>
|
</div>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<div class="row g-3 align-items-center">
|
||||||
|
<div class="col-sm-2 text-sm-end">
|
||||||
|
<label class="col-form-label" for="lang">Lang</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input class="form-control" type="text" id="langs" value="{{.Lang}}" name="lang">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<div class="row g-3 align-items-center">
|
||||||
|
<div class="col-sm-2 text-sm-end">
|
||||||
|
<label class="col-form-label" for="description">Description</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<textarea class="form-control" id="description" rows="5" name="description">{{.Description}}</textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<div class="form-actions">
|
||||||
|
<button type="submit" class="btn btn-primary">Save</button>
|
||||||
|
<a href="/book/{{.ID}}" class="btn">Cancel</a>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
<script src="/js/bootstrap-tokenfield.min.js"></script>
|
<!-- TODO: tokenfield -->
|
||||||
<script>
|
|
||||||
$('#tags').tokenfield();
|
|
||||||
</script>
|
|
||||||
|
|
||||||
{{template "footer.html" .S}}
|
{{template "footer.html" .S}}
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
<h4>Add News:</h4>
|
<h4>Add News:</h4>
|
||||||
<form method="POST" action="/news/edit">
|
<form method="POST" action="/news/edit">
|
||||||
<textarea class="field span10" name="text" rows="3"></textarea> <br />
|
<textarea class="col-12" name="text" rows="3"></textarea> <br />
|
||||||
<button type="submit" class="btn">Add</button>
|
<button type="submit" class="btn btn-primary">Add</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
{{template "footer.html" .S}}
|
{{template "footer.html" .S}}
|
||||||
|
|
|
@ -1,21 +1,24 @@
|
||||||
</div> <!-- container open in index.html -->
|
</div> <!-- container open in index.html -->
|
||||||
<footer class="container footer">
|
</main>
|
||||||
|
<footer>
|
||||||
|
<div class="container">
|
||||||
<hr />
|
<hr />
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="span6">
|
<div class="col">
|
||||||
<p><small>Chief Librarian: Las Zenow <zenow@riseup.net><br />
|
<p><small>Chief Librarian: Las Zenow <zenow@riseup.net><br />
|
||||||
Fork the source code from <a href="https://gitlab.com/trantor">gitlab</a></small>.</p>
|
Fork the source code from <a href="https://gitlab.com/trantor">gitlab</a></small>.</p>
|
||||||
</div>
|
</div>
|
||||||
{{if not .IsOnion}}
|
{{if not .IsOnion}}
|
||||||
<div class="span6">
|
<div class="col">
|
||||||
<p class="pull-right"><small>This is a mirror of the <a href="https://www.torproject.org/">Tor</a> onion service:<br />
|
<p class="d-flex justify-content-end"><small>This is a mirror of the <a href="https://www.torproject.org/">Tor</a> onion service:<br />
|
||||||
<a href="http://kx5thpx2olielkihfyo4jgjqfb7zx7wxr3sd4xzt26ochei4m6f7tayd.onion/">http://kx5thpx2olielkihfyo4jgjqfb7zx7wxr3sd4xzt26ochei4m6f7tayd.onion</a></small></p>
|
<a href="http://kx5thpx2olielkihfyo4jgjqfb7zx7wxr3sd4xzt26ochei4m6f7tayd.onion/">http://kx5thpx2olielkihfyo4jgjqfb7zx7wxr3sd4xzt26ochei4m6f7tayd.onion</a></small></p>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
</div> <!-- container -->
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
<!-- Placed at the end of the document so the pages load faster -->
|
<!-- Placed at the end of the document so the pages load faster -->
|
||||||
<script src="/js/bootstrap.min.js"></script>
|
<script src="/js/bootstrap.bundle.min.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,106 +1,155 @@
|
||||||
<!DOCTYPE HTML>
|
<!DOCTYPE HTML>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
|
|
||||||
<link href="/img/favicon.ico" rel="icon" type="image/x-icon" />
|
<link href="/img/favicon.ico" rel="icon" type="image/x-icon" />
|
||||||
<link href="/css/bootstrap.min.css" rel="stylesheet">
|
<link href="/css/bootstrap.min.css" rel="stylesheet">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<link href="/css/bootstrap-responsive.min.css" rel="stylesheet">
|
|
||||||
<link href="/css/bootstrap-tokenfield.min.css" rel="stylesheet">
|
|
||||||
<link href="/css/custom.css" rel="stylesheet">
|
<link href="/css/custom.css" rel="stylesheet">
|
||||||
<link rel="alternate" type="application/rss+xml" title="{{.Title}}" href="/search/?fmt=rss&q={{.Search}}" />
|
<link rel="alternate" type="application/rss+xml" title="{{.Title}}" href="/search/?fmt=rss&q={{.Search}}" />
|
||||||
|
|
||||||
<title>{{.Title}}</title>
|
<title>{{.Title}}</title>
|
||||||
<script src="/js/jquery.js"></script>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
<header>
|
||||||
<!-- login screen -->
|
<!-- login screen -->
|
||||||
<form class="form-horizontal modal hide" id="login" method="POST" action="/login/" enctype="application/x-www-form-urlencoded">
|
<div class="modal fade" id="loginModal" tabindex="-1" aria-labelledby="loginModalLabel" aria-hidden="true">
|
||||||
<div class="modal-header">
|
<div class="modal-dialog">
|
||||||
<a type="button" class="close" data-dismiss="modal">×</a>
|
<div class="modal-content">
|
||||||
<h3>Log In</h3>
|
<div class="modal-header">
|
||||||
<small><a href="/login/">Or create an account -></a></small>
|
<h5 class="modal-title" id="loginModalLabel">Log In</h5>
|
||||||
</div>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
<div class="modal-body">
|
|
||||||
<fieldset>
|
|
||||||
<div class="control-group">
|
|
||||||
<div class="controls">
|
|
||||||
<div class="input-prepend">
|
|
||||||
<div class="add-on"><i class="icon-user"></i></div>
|
|
||||||
<input type="text" placeholder="Username" size="16" name="user" autofocus="autofocus">
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="d-flex justify-content-end">
|
||||||
|
<small><a href="/login/">Or create an account -></a></small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<form id="login" method="POST" action="/login/" enctype="application/x-www-form-urlencoded">
|
||||||
<div class="control-group">
|
<div class="modal-body">
|
||||||
<div class="controls">
|
<div class="input-group mb-3">
|
||||||
<div class="input-prepend">
|
<span class="input-group-text" id="user">
|
||||||
<div class="add-on"><i class="icon-lock"></i></div>
|
<svg class="bi" width="1.5em" height="1.5em" fill="currentColor">
|
||||||
<input type="password" placeholder="Password" size="16" name="pass">
|
<use xlink:href="/img/bootstrap-icons.svg#person-fill"/>
|
||||||
</div>
|
</svg>
|
||||||
</div>
|
</span>
|
||||||
</div>
|
<input type="text" class="form-control" placeholder="Username" name="user" autofocus="autofocus" aria-label="Username" aria-describedby="user">
|
||||||
</fieldset>
|
</div>
|
||||||
</div>
|
<div class="input-group mb-3">
|
||||||
<div class="modal-footer">
|
<span class="input-group-text" id="pass">
|
||||||
<fieldset>
|
<svg class="bi" width="1.5em" height="1.5em" fill="currentColor">
|
||||||
<a href="#" class="btn" data-dismiss="modal">Cancel</a>
|
<use xlink:href="/img/bootstrap-icons.svg#key-fill"/>
|
||||||
<input class="btn btn-primary" type="submit" name="submit" value="Log In"/>
|
</svg>
|
||||||
</fieldset>
|
</span>
|
||||||
</div>
|
<input type="password" class="form-control" placeholder="Password" name="pass" aria-label="Password" aria-describedby="pass">
|
||||||
</form>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
||||||
|
<input class="btn btn-primary" type="submit" name="submit" value="Log In"/>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div> <!-- modal-content -->
|
||||||
|
</div> <!-- modal-dialog -->
|
||||||
|
</div> <!-- modal -->
|
||||||
|
|
||||||
<div class="navbar navbar-inverse">
|
<nav class="navbar navbar-expand-md navbar-dark bg-dark">
|
||||||
<div class="navbar-inner">
|
<div class="container-fluid">
|
||||||
<div class="container">
|
<a class="navbar-brand" href="/">Imperial Library</a>
|
||||||
<a class="brand" href="/">Imperial Library</a>
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
||||||
<div class="nav-collapse">
|
<span class="navbar-toggler-icon"></span>
|
||||||
<ul class="nav">
|
</button>
|
||||||
<li {{if .Home}}class="active"{{end}}><a href="/">Home</a></li>
|
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||||
<li {{if .About}}class="active"{{end}}><a href="/about/">About</a></li>
|
<ul class="navbar-nav me-auto">
|
||||||
<li {{if .News}}class="active"{{end}}><a href="/news/">News</a></li>
|
<li class="nav-item"><a class="nav-link {{if .Home}}active{{end}}" href="/">Home</a></li>
|
||||||
<li {{if .Upload}}class="active"{{end}}><a href="/upload/">Upload</a></li>
|
<li class="nav-item"><a class="nav-link {{if .About}}active{{end}}" href="/about/">About</a></li>
|
||||||
<li><a href="/forum/">Forum</a></li>
|
<li class="nav-item"><a class="nav-link {{if .News}}active{{end}}" href="/news/">News</a></li>
|
||||||
</ul>
|
<li class="nav-item"><a class="nav-link {{if .Upload}}active{{end}}" href="/upload/">Upload</a></li>
|
||||||
|
<li class="nav-item"><a class="nav-link" href="/forum/">Forum</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<ul class="nav pull-right">
|
<ul class="navbar-nav justify-content-end">
|
||||||
<li class="divider-vertical"></li>
|
<li class="nav-item"><a class="nav-link {{if .Help}}active{{end}}" href="/help/">Help</a></li>
|
||||||
{{if .User}}
|
</ul>
|
||||||
<li class="dropdown">
|
<form class="d-flex" action="/search/">
|
||||||
<a href="/dashboard/" class="dropdown-toggle" data-toggle="dropdown">
|
<input type="search" class="form-control" name="q" {{if .Search}}value="{{.Search}}"{{else}}placeholder="Search"{{end}} />
|
||||||
<i class="icon-user icon-white"></i> {{.User}}<b class="caret"></b>
|
</form>
|
||||||
</a>
|
<ul class="navbar-nav">
|
||||||
<ul class="dropdown-menu">
|
{{if .User}}
|
||||||
<li><a href="/dashboard/"><i class="icon-tasks"></i> Dashboard</a></li>
|
<li class="nav-item dropdown">
|
||||||
{{if eq .Role "admin" "moderator"}}
|
<a class="nav-link dropdown-toggle" href="/dashboard/" id="navbarScrollingDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||||
<li><a href="/submission/moderate/"><i class="icon-book"></i> Moderate submissions</a></li>
|
{{.User}}
|
||||||
{{if eq .Role "admin"}}
|
</a>
|
||||||
<li><a href="/news/edit"><i class="icon-certificate"></i> Edit news</a></li>
|
<ul class="dropdown-menu dropdown-menu-dark dropdown-menu-end" aria-labelledby="navbarScrollingDropdown">
|
||||||
<li><a href="/admin/users/"><i class="icon-user"></i> Users admin</a></li>
|
<li><a href="/dashboard/" class="dropdown-item">
|
||||||
{{end}}
|
<svg class="bi" width="1em" height="1em" fill="currentColor">
|
||||||
<li class="divider"></li>
|
<use xlink:href="/img/bootstrap-icons.svg#card-list"/>
|
||||||
{{end}}
|
</svg>
|
||||||
<li><a href="/submission/"><i class="icon-folder-open"></i> Submissions</a></li>
|
Dashboard
|
||||||
<li><a href="/settings/"><i class="icon-wrench"></i> Settings</a></li>
|
</a></li>
|
||||||
<li class="divider"></li>
|
{{if eq .Role "admin" "moderator"}}
|
||||||
<li><a href="/logout/"><i class="icon-off"></i> Log Out</a></li>
|
<li><a href="/submission/moderate/" class="dropdown-item">
|
||||||
</ul>
|
<svg class="bi" width="1em" height="1em" fill="currentColor">
|
||||||
|
<use xlink:href="/img/bootstrap-icons.svg#journal-check"/>
|
||||||
|
</svg>
|
||||||
|
Moderate submissions
|
||||||
|
</a></li>
|
||||||
|
{{if eq .Role "admin"}}
|
||||||
|
<li><a href="/news/edit" class="dropdown-item">
|
||||||
|
<svg class="bi" width="1em" height="1em" fill="currentColor">
|
||||||
|
<use xlink:href="/img/bootstrap-icons.svg#newspaper"/>
|
||||||
|
</svg>
|
||||||
|
Edit news
|
||||||
|
</a></li>
|
||||||
|
<li><a href="/admin/users/" class="dropdown-item">
|
||||||
|
<svg class="bi" width="1em" height="1em" fill="currentColor">
|
||||||
|
<use xlink:href="/img/bootstrap-icons.svg#people"/>
|
||||||
|
</svg>
|
||||||
|
Users admin
|
||||||
|
</a></li>
|
||||||
|
{{end}}
|
||||||
|
<li><hr class="dropdown-divider"></li>
|
||||||
|
{{end}}
|
||||||
|
<li><a href="/submission/" class="dropdown-item">
|
||||||
|
<svg class="bi" width="1em" height="1em" fill="currentColor">
|
||||||
|
<use xlink:href="/img/bootstrap-icons.svg#journal-arrow-up"/>
|
||||||
|
</svg>
|
||||||
|
Submissions
|
||||||
|
</a></li>
|
||||||
|
<li><a href="/settings/" class="dropdown-item">
|
||||||
|
<svg class="bi" width="1em" height="1em" fill="currentColor">
|
||||||
|
<use xlink:href="/img/bootstrap-icons.svg#gear"/>
|
||||||
|
</svg>
|
||||||
|
Settings
|
||||||
|
</a></li>
|
||||||
|
<li><hr class="dropdown-divider"></li>
|
||||||
|
<li><a href="/logout/" class="dropdown-item">
|
||||||
|
<svg class="bi" width="1em" height="1em" fill="currentColor">
|
||||||
|
<use xlink:href="/img/bootstrap-icons.svg#power"/>
|
||||||
|
</svg>
|
||||||
|
Log Out
|
||||||
|
</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
{{else}}
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" data-toggle="modal" href="/login/#login" data-bs-toggle="modal" data-bs-target="#loginModal">
|
||||||
|
<small>Login/SignUp</small>
|
||||||
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{{else}}
|
{{end}}
|
||||||
<li><a data-toggle="modal" href="/login/#login"><i class="icon-user icon-white"></i> <small>Login/SignUp</small></a></li>
|
</ul>
|
||||||
{{end}}
|
</div><!--/.nav-collapse -->
|
||||||
</ul>
|
</div><!--/.nav-container-fluid-->
|
||||||
</div><!--/.nav-collapse -->
|
</nav>
|
||||||
<form class="navbar-search pull-right" action="/search/">
|
</header>
|
||||||
<input type="search" class="search-query span3" name="q" {{if .Search}}value="{{.Search}}"{{else}}placeholder="Search"{{end}} />
|
|
||||||
</form>
|
<main>
|
||||||
<ul class="nav pull-right">
|
<div class="container">
|
||||||
<li {{if .Help}}class="active"{{end}}><a href="/help/">Help</a></li>
|
<br />
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="container">
|
|
||||||
{{range .Notif}}
|
{{range .Notif}}
|
||||||
<div class="alert alert-{{.Type}}">
|
<div class="alert alert-{{.Type}} alert-dismissible fade show" role="alert">
|
||||||
<button class="close" data-dismiss="alert">×</button>
|
<strong>{{.Title}}</strong> {{.Msg}}
|
||||||
<strong>{{.Title}}</strong> {{.Msg}}
|
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
@ -1,80 +1,43 @@
|
||||||
{{template "header.html" .S}}
|
{{template "header.html" .S}}
|
||||||
|
|
||||||
{{range .News}}
|
{{range .News}}
|
||||||
<div class="row">
|
<div class="row justify-content-center">
|
||||||
<div class="offset2 span8 alert alert-info">
|
<div class="col-sm-10 alert alert-info">
|
||||||
<a href="/news/"><strong>News!</strong></a> {{.Text}}
|
<a href="/news/"><strong>News!</strong></a> {{.Text}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<p class="centered">There are {{.Count}} books on the library.</p>
|
<p class="text-center">There are {{.Count}} books on the library.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<h4>Last books added:
|
<div class="col">
|
||||||
<span class="pull-right">
|
<h4>Last books added:</h4>
|
||||||
<small>(<a href="/search/?q=">more</a>)</small>
|
</div>
|
||||||
<a href="/search/?fmt=rss&q="><img src="/img/feed.png"/></a>
|
<div class="col text-end title">
|
||||||
</span>
|
<small>(<a href="/search/?q=">more</a>)</small>
|
||||||
</h4>
|
<a href="/search/?fmt=rss&q="><img src="/img/feed.png"/></a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ul class="row thumbnails">
|
<div class="row">
|
||||||
{{with .Books}}
|
{{with .Books}}
|
||||||
{{range .}}
|
{{range .}}
|
||||||
<li class="span2">
|
<div class="col-sm-2">
|
||||||
<div class="thumbnail centered" style="border:none;">
|
<div class="thumbnail text-center" style="border:none;">
|
||||||
<a href="/book/{{.ID}}" title="{{.Description}}">
|
<a href="/book/{{.ID}}" title="{{.Description}}">
|
||||||
{{if .Cover}}<div class="down"><img class="img-rounded" src="/cover/{{.ID}}/small/{{.Title}}.jpg" alt="{{.Title}}" /></div>{{end}}
|
{{if .Cover}}<div class="down"><img class="rounded" src="/cover/{{.ID}}/small/{{.Title}}.jpg" alt="{{.Title}}" /></div>{{end}}
|
||||||
<p><strong>{{.Title}}</strong></p>
|
<p><strong>{{.Title}}</strong></p>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
</ul>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
<div class="row">
|
|
||||||
<h4>Most visited books:</h4>
|
|
||||||
</div>
|
</div>
|
||||||
<ul class="row thumbnails">
|
|
||||||
{{with .VisitedBooks}}
|
|
||||||
{{range .}}
|
|
||||||
<li class="span2">
|
|
||||||
<div class="thumbnail centered" style="border:none;">
|
|
||||||
<a href="/book/{{.ID}}" title="{{.Description}}">
|
|
||||||
{{if .Cover}}<div class="down"><img class="img-rounded" src="/cover/{{.ID}}/small/{{.Title}}.jpg" alt="{{.Title}}" /></div>{{end}}
|
|
||||||
<p><strong>{{.Title}}</strong></p>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
{{end}}
|
|
||||||
{{end}}
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<h4>Most downloaded books:</h4>
|
<p class="text-center">{{range .Tags}}<a class="badge bg-secondary" href="/search/?q=tag:{{.}}">{{.}}</a> {{end}}</p>
|
||||||
</div>
|
|
||||||
<ul class="row thumbnails">
|
|
||||||
{{with .DownloadedBooks}}
|
|
||||||
{{range .}}
|
|
||||||
<li class="span2">
|
|
||||||
<div class="thumbnail centered" style="border:none;">
|
|
||||||
<a href="/book/{{.ID}}" title="{{.Description}}">
|
|
||||||
{{if .Cover}}<div class="down"><img class="img-rounded" src="/cover/{{.ID}}/small/{{.Title}}.jpg" alt="{{.Title}}" /></div>{{end}}
|
|
||||||
<p><strong>{{.Title}}</strong></p>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
{{end}}
|
|
||||||
{{end}}
|
|
||||||
</ul>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<p class="centered">{{range .Tags}}<a class="label" href="/search/?q=tag:{{.}}">{{.}}</a> {{end}}</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{template "footer.html" .S}}
|
{{template "footer.html" .S}}
|
||||||
|
|
|
@ -1,11 +1,16 @@
|
||||||
{{template "header.html" .S}}
|
{{template "header.html" .S}}
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<h4 class="span10">{{.List.Title}} <a href="/list/{{.List.ListID}}?fmt=rss"><img src="/img/feed.png"/></a></h4>
|
<h4 class="col-sm-10">{{.List.Title}} <a href="/list/{{.List.ListID}}?fmt=rss"><img src="/img/feed.png"/></a></h4>
|
||||||
|
|
||||||
<p class="span2 pull-right">
|
<p class="col-sm-2 text-end">
|
||||||
{{if eq .S.User .List.User.Username}}
|
{{if eq .S.User .List.User.Username}}
|
||||||
<a href="/list/{{.List.ListID}}/edit" class="btn btn-primary"><i class="icon-pencil"></i> Edit</a>
|
<a href="/list/{{.List.ListID}}/edit" class="btn btn-primary">
|
||||||
|
<svg class="bi" width="1em" height="1em" fill="currentColor">
|
||||||
|
<use xlink:href="/img/bootstrap-icons.svg#pencil"/>
|
||||||
|
</svg>
|
||||||
|
Edit
|
||||||
|
</a>
|
||||||
{{else}}
|
{{else}}
|
||||||
By {{.List.User.Username}}
|
By {{.List.User.Username}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
@ -1,54 +1,56 @@
|
||||||
{{template "header.html" .S}}
|
{{template "header.html" .S}}
|
||||||
|
|
||||||
{{with .List}}
|
{{with .List}}
|
||||||
<form class="form-horizontal" method="POST" action="/list/{{.ListID}}">
|
<form method="POST" action="/list/{{.ListID}}">
|
||||||
<fieldset>
|
<div class="mb-3">
|
||||||
<div class="control-group">
|
<label class="form-label" for="title">Title</label>
|
||||||
<label class="control-label" for="title">Title</label>
|
<input class="form-control" type="text" id="title" value="{{.Title}}" name="title">
|
||||||
<div class="controls">
|
|
||||||
<input class="input-xlarge" type="text" id="title" value="{{.Title}}" name="title">
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
<div class="mb-3">
|
||||||
<fieldset>
|
<label class="form-label" for="description">Description</label>
|
||||||
<div class="control-group">
|
<textarea class="form-control" id="description" rows="5" name="description">{{range .Description}}{{.}}{{end}}</textarea>
|
||||||
<label class="control-label" for="description">Description</label>
|
|
||||||
<div class="controls">
|
|
||||||
<textarea class="input-xlarge" id="description" rows="5" name="description">{{range .Description}}{{.}}
|
|
||||||
{{end}}</textarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="form-actions">
|
<div class="text-end">
|
||||||
<button type="submit" class="btn btn-primary">Save</button>
|
<button type="submit" class="btn btn-primary">Save</button>
|
||||||
<a href="/list/{{.ListID}}" class="btn">Cancel</a>
|
<a href="/list/{{.ListID}}" class="btn btn-secondary">Cancel</a>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
|
||||||
</form>
|
</form>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
{{$listID := .List.ListID}}
|
{{$listID := .List.ListID}}
|
||||||
{{range .List.Books}}
|
{{range .List.Books}}
|
||||||
<div class="row">
|
<div class="card mb-3">
|
||||||
<div class="span1">
|
<div class="row g-0">
|
||||||
<p class="pull-right"><a href="/book/{{.ID}}">{{if .Cover}}<img class="img-rounded" src="/cover/{{.ID}}/small/{{.Title}}.jpg" alt="{{.Title}}" />{{end}}</a></p>
|
<div class="col-md-1 d-flex align-items-center justify-content-center">
|
||||||
</div>
|
<a href="/book/{{.ID}}" title="{{.Description}}">
|
||||||
<div class="span10 well">
|
{{if .Cover}}<img class="rounded" src="/cover/{{.ID}}/small/{{.Title}}.jpg" alt="{{.Title}}" />{{end}}
|
||||||
<div class="row">
|
</a>
|
||||||
<div class="span7">
|
|
||||||
<p>
|
|
||||||
<span class="muted">[{{if .Lang}}{{.Lang}}{{end}}]</span>
|
|
||||||
<a href="/book/{{.ID}}"><strong>{{.Title}}</strong></a>
|
|
||||||
<span class="muted">{{if .Publisher}}{{.Publisher}}{{end}}</span><br />
|
|
||||||
{{range .Authors}}{{.}}, {{end}}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="span3">
|
|
||||||
<div class="pull-right">
|
|
||||||
<a href="/list/{{$listID}}/remove/{{.ID}}" class="btn btn-danger"><i class="icon-remove"></i> remove</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-md-11">
|
||||||
|
<div class="card-body">
|
||||||
|
<p class="card-title">
|
||||||
|
<span class="text-muted">[{{if .Lang}}{{.Lang}}{{end}}]</span>
|
||||||
|
<a href="/book/{{.ID}}" title="{{.Description}}"><strong>{{.Title}}</strong></a>
|
||||||
|
<span class="text-muted">{{if .Publisher}}{{.Publisher}}{{end}}</span>
|
||||||
|
</p>
|
||||||
|
<div class="card-text row">
|
||||||
|
<p class="col-9">{{range .Authors}}{{.}}, {{end}}</p>
|
||||||
|
<div class="col-3">
|
||||||
|
<div class="btn-group d-flex justify-content-end">
|
||||||
|
<a href="/list/{{$listID}}/remove/{{.ID}}" class="btn btn-danger">
|
||||||
|
<svg class="bi" width="1em" height="1em" fill="currentColor">
|
||||||
|
<use xlink:href="/img/bootstrap-icons.svg#trash"/>
|
||||||
|
</svg>
|
||||||
|
remove
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
|
|
|
@ -21,46 +21,67 @@ function checkPasswordMatch() {
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="offset1 span4">
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-sm-4">
|
||||||
<h3>Log In</h3>
|
<h3>Log In</h3>
|
||||||
<form id="login" method="POST" action="/login/" enctype="application/x-www-form-urlencoded">
|
<form id="login" method="POST" action="/login/" enctype="application/x-www-form-urlencoded">
|
||||||
<div class="input-prepend">
|
<div class="input-group mb-3">
|
||||||
<div class="add-on"><i class="icon-user"></i></div>
|
<span class="input-group-text" id="user">
|
||||||
<input type="text" placeholder="Username" size="16" name="user" autofocus="autofocus">
|
<svg class="bi" width="1.5em" height="1.5em" fill="currentColor">
|
||||||
</div>
|
<use xlink:href="/img/bootstrap-icons.svg#person-fill"/>
|
||||||
<div class="input-prepend">
|
</svg>
|
||||||
<div class="add-on"><i class="icon-lock"></i></div>
|
</span>
|
||||||
<input type="password" placeholder="Password" size="16" name="pass">
|
<input type="text" class="form-control" placeholder="Username" name="user" autofocus="autofocus" aria-label="Username" aria-describedby="user">
|
||||||
</div>
|
</div>
|
||||||
<input class="btn btn-primary" type="submit" name="submit" value="Log In"/>
|
<div class="input-group mb-3">
|
||||||
|
<span class="input-group-text" id="pass">
|
||||||
|
<svg class="bi" width="1.5em" height="1.5em" fill="currentColor">
|
||||||
|
<use xlink:href="/img/bootstrap-icons.svg#key-fill"/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
<input type="password" class="form-control" placeholder="Password" name="pass" aria-label="Password" aria-describedby="pass">
|
||||||
|
</div>
|
||||||
|
<input class="btn btn-primary" type="submit" name="submit" value="Log In"/>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="span2">
|
<div class="col-sm-2">
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
<h3 class="centered">Or</h3>
|
<h3 class="centered">Or</h3>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
</div>
|
</div>
|
||||||
<div class="span4">
|
<div class="col-sm-4">
|
||||||
<h3>Create an Account</h3>
|
<h3>Create an Account</h3>
|
||||||
<form id="login" method="POST" action="/create_user/" enctype="application/x-www-form-urlencoded">
|
<form id="login" method="POST" action="/create_user/" enctype="application/x-www-form-urlencoded">
|
||||||
<div class="input-prepend">
|
<div class="input-group mb-3">
|
||||||
<div class="add-on"><i class="icon-user"></i></div>
|
<span class="input-group-text" id="user">
|
||||||
<input type="text" placeholder="Username" size="16" name="user">
|
<svg class="bi" width="1.5em" height="1.5em" fill="currentColor">
|
||||||
</div>
|
<use xlink:href="/img/bootstrap-icons.svg#person-fill"/>
|
||||||
<div class="input-prepend">
|
</svg>
|
||||||
<div class="add-on"><i class="icon-lock"></i></div>
|
</span>
|
||||||
<input type="password" placeholder="Password" size="16" name="pass" id="pass">
|
<input type="text" class="form-control" placeholder="Username" name="user" autofocus="autofocus" aria-label="Username" aria-describedby="user">
|
||||||
</div>
|
</div>
|
||||||
<div class="control-group" id="passCheck">
|
<div class="input-group mb-3">
|
||||||
<div class="controls input-prepend">
|
<span class="input-group-text" id="pass">
|
||||||
<div class="add-on"><i class="icon-lock"></i></div>
|
<svg class="bi" width="1.5em" height="1.5em" fill="currentColor">
|
||||||
<input type="password" placeholder="Confirm password" size="16" name="confirmPass" id="confirmPass">
|
<use xlink:href="/img/bootstrap-icons.svg#key-fill"/>
|
||||||
</div>
|
</svg>
|
||||||
<span id="passCheckHelp" class="help-inline"></span>
|
</span>
|
||||||
</div>
|
<input type="password" class="form-control" placeholder="Password" name="pass" aria-label="Password" aria-describedby="pass" id="pass">
|
||||||
<input class="btn btn-primary" type="submit" name="submit" value="Create"/>
|
</div>
|
||||||
|
<div class="input-group mb-3">
|
||||||
|
<span class="input-group-text" id="pass">
|
||||||
|
<svg class="bi" width="1.5em" height="1.5em" fill="currentColor">
|
||||||
|
<use xlink:href="/img/bootstrap-icons.svg#key-fill"/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
<input type="password" class="form-control" placeholder="Confirm password" name="confirmPass" aria-label="Password" aria-describedby="confirmPass" id="confirmPass">
|
||||||
|
</div>
|
||||||
|
<input class="btn btn-primary" type="submit" name="submit" value="Create" />
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{{template "footer.html" .S}}
|
{{template "footer.html" .S}}
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
{{template "header.html" .S}}
|
{{template "header.html" .S}}
|
||||||
|
|
||||||
<h4>News:
|
<div class="row">
|
||||||
<a href="/news/?fmt=rss" class="pull-right"><img src="/img/feed.png"/></a>
|
<h4 class="col">News:</h4>
|
||||||
</h4>
|
<a href="/news/?fmt=rss" class="col text-end"><img src="/img/feed.png"/></a>
|
||||||
|
|
||||||
<dl class="dl-horizontal">
|
|
||||||
{{range .News}}
|
|
||||||
<div class="well well-small">
|
|
||||||
<dt>{{.Date}}</dt>
|
|
||||||
<dd>{{.Text}}</dd>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<dl>
|
||||||
|
{{range .News}}
|
||||||
|
<div class="row">
|
||||||
|
<dt class="col-sm-2 text-sm-end">{{.Date}}</dt>
|
||||||
|
<dd class="col-sm-10">{{.Text}}</dd>
|
||||||
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
|
|
|
@ -3,68 +3,80 @@
|
||||||
|
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="span4">
|
|
||||||
{{range .Chapters}}
|
|
||||||
{{range .In}}
|
|
||||||
<ul id="bookMenu" class="nav nav-list hidden-phone">
|
|
||||||
{{end}}
|
|
||||||
<li {{if .Active}}class="active"{{end}}><a href="{{.Link}}">{{.Label}}</a></li>
|
|
||||||
{{range .Out}}
|
|
||||||
</ul>
|
|
||||||
{{end}}
|
|
||||||
{{end}}
|
|
||||||
{{if .Chapters}}
|
|
||||||
</ul>
|
|
||||||
{{end}}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="span8">
|
|
||||||
<script type="text/javascript">
|
{{if .Chapters}}
|
||||||
function resizeIframe() {
|
<div class="col-md-4">
|
||||||
var contentHeight = $("#bookContent").contents().find("html").height();
|
<nav id="index" class="navbar navbar-expand-md navbar-light bg-light flex-column">
|
||||||
$("#bookContent").height(ContentHeight);
|
<div class="row">
|
||||||
}
|
<div class="col d-flex justify-content-start">
|
||||||
</script>
|
<a class="navbar-brand" href="#">Index</a>
|
||||||
|
</div>
|
||||||
|
<div class="d-block d-md-none col d-flex justify-content-end">
|
||||||
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#indexContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapse navbar-collapse" id="indexContent">
|
||||||
|
{{range .Chapters}}
|
||||||
|
{{range .In}}
|
||||||
|
<nav class="nav nav-pills flex-column">
|
||||||
|
{{end}}
|
||||||
|
<a class="nav-link ms-{{mul 2 .Depth}}{{if .Active}} active{{end}}" href="{{.Link}}">{{.Label}}</a>
|
||||||
|
{{range .Out}}
|
||||||
|
</nav>
|
||||||
|
{{end}}
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
<ul class="pager">
|
<div class="col">
|
||||||
{{if .Prev}}
|
<script type="text/javascript">
|
||||||
<li class="previous">
|
function resizeIframe() {
|
||||||
<a href="{{.Prev}}">← Prev</a>
|
var contentHeight = $("#bookContent").contents().find("html").height();
|
||||||
</li>
|
$("#bookContent").height(ContentHeight);
|
||||||
{{end}}
|
}
|
||||||
{{if .Book.Active}}
|
</script>
|
||||||
<li class="">
|
|
||||||
<a href="{{.Back}}">Back</a>
|
{{if not .Book.Active}}
|
||||||
</li>
|
<div class="text-center">
|
||||||
{{else}}
|
<p class="badge bg-warning">waiting for moderation</p>
|
||||||
<span class="label label-warning">waiting for moderation</span>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if .Next}}
|
<nav class="d-flex justify-content-center" arial-label="Book navigation">
|
||||||
<li class="next">
|
<ul class="pagination">
|
||||||
<a href="{{.Next}}">Next →</a>
|
<li class="page-item {{if not .Prev}}disabled{{end}}">
|
||||||
</li>
|
<a class="page-link" href="{{.Prev}}">← Prev</a>
|
||||||
{{end}}
|
</li>
|
||||||
</ul>
|
<li class="page-item">
|
||||||
|
<a class="page-link" href="{{.Back}}">Back</a>
|
||||||
<iframe id="bookContent" onload="resizeIframe();" style="width: 100%; height: 1080px; border: 0;" scrolling="auto" src="{{.Content}}" seamless="seamless" sandbox="allow-same-origin" frameborder=0></iframe>
|
</li>
|
||||||
|
<li class="page-item {{if not .Next}}disabled{{end}}">
|
||||||
<ul class="pager">
|
<a class="page-link" href="{{.Next}}">Next →</a>
|
||||||
{{if .Prev}}
|
</li>
|
||||||
<li class="previous">
|
</ul>
|
||||||
<a href="{{.Prev}}">← Prev</a>
|
</nav>
|
||||||
</li>
|
|
||||||
{{end}}
|
<iframe id="bookContent" onload="resizeIframe();" style="width: 100%; height: 1080px; border: 0;" scrolling="auto" src="{{.Content}}" seamless="seamless" sandbox="allow-same-origin" frameborder=0></iframe>
|
||||||
<li class="">
|
|
||||||
<a href="{{.Back}}">Back</a>
|
<nav class="d-flex justify-content-center" arial-label="Book navigation">
|
||||||
</li>
|
<ul class="pagination">
|
||||||
{{if .Next}}
|
<li class="page-item {{if not .Prev}}disabled{{end}}">
|
||||||
<li class="next">
|
<a class="page-link" href="{{.Prev}}">← Prev</a>
|
||||||
<a href="{{.Next}}">Next →</a>
|
</li>
|
||||||
</li>
|
<li class="page-item">
|
||||||
{{end}}
|
<a class="page-link" href="{{.Back}}">Back</a>
|
||||||
</ul>
|
</li>
|
||||||
|
<li class="page-item {{if not .Next}}disabled{{end}}">
|
||||||
</div>
|
<a class="page-link" href="{{.Next}}">Next →</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,45 +1,50 @@
|
||||||
{{template "header.html" .S}}
|
{{template "header.html" .S}}
|
||||||
|
|
||||||
|
|
||||||
<ul class="pager">
|
<p class="text-center">Found {{.Found}} books <a href="{{.S.FullURL}}&fmt=rss"><img src="/img/feed.png"/></a> <br />
|
||||||
{{if .Prev}}
|
<nav class="d-flex justify-content-center" arial-label="Book search page navigation">
|
||||||
<li class="previous">
|
<ul class="pagination">
|
||||||
<a href="{{.Prev}}">← Prev</a>
|
<li class="page-item {{if not .Prev}}disabled{{end}}">
|
||||||
</li>
|
<a class="page-link" href="{{.Prev}}">← Prev</a>
|
||||||
{{else}}
|
</li>
|
||||||
<div class="span1"></div>
|
<li class="page-item disabled">
|
||||||
{{end}}
|
<a class="page-link" href="#">Page {{.Page}}</a>
|
||||||
<p class="centered span9">Found {{.Found}} books. Page {{.Page}} <a href="{{.S.FullURL}}&fmt=rss"><img src="/img/feed.png"/></a> <br />
|
</li>
|
||||||
{{if .Next}}
|
<li class="page-item {{if not .Next}}disabled{{end}}">
|
||||||
<li class="next">
|
<a class="page-link" href="{{.Next}}">Next →</a>
|
||||||
<a href="{{.Next}}">Next →</a>
|
</li>
|
||||||
</li>
|
</ul>
|
||||||
{{end}}
|
</nav>
|
||||||
</ul>
|
|
||||||
|
|
||||||
{{template "book_list.html" .Books}}
|
{{template "book_list.html" .Books}}
|
||||||
|
|
||||||
<ul class="pager">
|
<nav class="d-flex justify-content-center" arial-label="Book search page navigation">
|
||||||
{{if .Prev}}
|
<ul class="pagination">
|
||||||
<li class="previous">
|
<li class="page-item {{if not .Prev}}disabled{{end}}">
|
||||||
<a href="{{.Prev}}">← Prev</a>
|
<a class="page-link" href="{{.Prev}}">← Prev</a>
|
||||||
</li>
|
</li>
|
||||||
{{else}}
|
<li class="page-item disabled">
|
||||||
<div class="span1"></div>
|
<a class="page-link" href="#">Page {{.Page}}</a>
|
||||||
{{end}}
|
</li>
|
||||||
<form class="form-inline span9 centered">
|
<li class="page-item {{if not .Next}}disabled{{end}}">
|
||||||
<label>Books per page: </label>
|
<a class="page-link" href="{{.Next}}">Next →</a>
|
||||||
<div class="input-append" action="/search/">
|
</li>
|
||||||
<input class="span1" name="num" type="text" value="{{.ItemsPage}}" />
|
</ul>
|
||||||
<button type="submit" class="btn">Ok</button>
|
</nav>
|
||||||
</div>
|
|
||||||
<input class="hidden span1" name="q" type="text" value="{{.S.Search}}" />
|
<form class="d-flex justify-content-center" action="/search/">
|
||||||
|
<div class="row g-3 align-items-center">
|
||||||
|
<div class="col-auto">
|
||||||
|
<label for="inputNum" class="col-form-label">Books per page: </label>
|
||||||
|
</div>
|
||||||
|
<div class="col-auto">
|
||||||
|
<input name="num" size="3" type="text" value="{{.ItemsPage}}" id="inputNum" class="form-control" />
|
||||||
|
</div>
|
||||||
|
<div class="col-auto">
|
||||||
|
<button type="submit" class="btn btn-primary">Ok</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<input name="q" type="hidden" value="{{.S.Search}}" />
|
||||||
</form>
|
</form>
|
||||||
{{if .Next}}
|
|
||||||
<li class="next">
|
|
||||||
<a href="{{.Next}}">Next →</a>
|
|
||||||
</li>
|
|
||||||
{{end}}
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
{{template "footer.html" .S}}
|
{{template "footer.html" .S}}
|
||||||
|
|
|
@ -1,51 +1,36 @@
|
||||||
{{template "header.html" .S}}
|
{{template "header.html" .S}}
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function () {
|
|
||||||
$("#passCheck").keyup(checkPasswordMatch);
|
|
||||||
});
|
|
||||||
|
|
||||||
function checkPasswordMatch() {
|
function checkPasswordMatch() {
|
||||||
var password = $("#password1").val();
|
var password = document.forms["passwordChange"]["password1"].value;
|
||||||
var confirmPassword = $("#password2").val();
|
var confirmPassword = document.forms["passwordChange"]["password2"].value;
|
||||||
|
|
||||||
if (password != confirmPassword) {
|
if (password != confirmPassword) {
|
||||||
$("#passCheck").removeClass("success");
|
document.getElementById("password2").classList.remove("is-valid");
|
||||||
$("#passCheck").addClass("error");
|
document.getElementById("password2").classList.add("is-invalid");
|
||||||
$("#passCheckHelp").html("Passwords don't match!");
|
|
||||||
} else {
|
} else {
|
||||||
$("#passCheck").removeClass("error");
|
document.getElementById("password2").classList.remove("is-invalid");
|
||||||
$("#passCheck").addClass("success");
|
document.getElementById("password2").classList.add("is-valid");
|
||||||
$("#passCheckHelp").html("");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<h2>Settings</h2>
|
<h2>Settings</h2>
|
||||||
|
|
||||||
<form class="form-horizontal" method="POST" action="/settings/">
|
<form name="passwordChange" method="POST" action="/settings/">
|
||||||
<legend>Change your pasword</legend>
|
<legend>Change your pasword</legend>
|
||||||
<div class="control-group">
|
<div class="mb-3">
|
||||||
<label class="control-label" for="currpass">Current password:</label>
|
<label class="form-label" for="currpass">Current password:</label>
|
||||||
<div class="controls">
|
<input class="form-control" type="password" name="currpass" id="currpass" /><br />
|
||||||
<input type="password" name="currpass" id="currpass" /><br />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="control-group" id="passCheck">
|
<div class="mb-3">
|
||||||
<label class="control-label" for="password1">New password:</label>
|
<label class="form-label" for="password1">New password:</label>
|
||||||
<div class="controls">
|
<input class="form-control" type="password" name="password1" id="password1" onchange="checkPasswordMatch()" />
|
||||||
<input type="password" name="password1" id="password1" />
|
<label class="form-label" for="password2">Confirm password:</label>
|
||||||
</div>
|
<input class="form-control" type="password" name="password2" id="password2" onchange="checkPasswordMatch()" />
|
||||||
<label class="control-label" for="password2">Confirm password:</label>
|
<div class="invalid-feedback">Passwords don't match!</div>
|
||||||
<div class="controls">
|
|
||||||
<input type="password" name="password2" id="password2" />
|
|
||||||
</div>
|
|
||||||
<div id="passCheckHelp" class="controls text-error"></div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="control-group">
|
<button type="submit" class="btn btn-primary">Change password</button>
|
||||||
<div class="controls">
|
|
||||||
<button type="submit" class="btn">Change password</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
<ul>
|
<ul>
|
||||||
<li>Check if the book is already in the library, please remove the books that are already in the library in a better or similar edition/quality. You can click on the title or the authors to search for similar books in the library.</li>
|
<li>Check if the book is already in the library, please remove the books that are already in the library in a better or similar edition/quality. You can click on the title or the authors to search for similar books in the library.</li>
|
||||||
<li>Edit if needed the title, authors, publisher, ...</li>
|
<li>Edit if needed the title, authors, publisher, ...</li>
|
||||||
|
<li>Take into account that your submission might be waiting to process, reload this page in few minutes to see it already processed</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p>Thank you for your submission.</p>
|
<p>Thank you for your submission.</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -13,66 +14,97 @@
|
||||||
{{$submissionID := .SubmissionID}}
|
{{$submissionID := .SubmissionID}}
|
||||||
{{range .Submissions}}
|
{{range .Submissions}}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="row">
|
<p>
|
||||||
<div class="span9">
|
<b>{{.Filename}}</b>
|
||||||
<p><b>{{.Filename}}</b>
|
{{if not .Book}}
|
||||||
{{if not .Book}}
|
<span class="badge bg-danger">
|
||||||
<span class="label label-important">
|
{{else if .Book.Active}}
|
||||||
{{else if .Book.Active}}
|
<span class="badge bg-success">
|
||||||
<span class="label label-success">
|
{{else}}
|
||||||
{{else}}
|
<span class="badge bg-warning">
|
||||||
<span class="label label-warning">
|
{{end}}
|
||||||
{{end}}
|
{{.Status}}</span>
|
||||||
{{.Status}}</span></p>
|
</p>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{with .Book}}
|
|
||||||
|
|
||||||
{{if .}}
|
|
||||||
<div class="span1">
|
|
||||||
<p class="pull-right"><a href="/book/{{.ID}}">{{if .Cover}}<img class="img-rounded" src="/cover/{{.ID}}/small/{{.Title}}.jpg" alt="{{.Title}}" />{{end}}</a></p>
|
|
||||||
</div>
|
|
||||||
<div class="span10 well">
|
|
||||||
<div class="row">
|
|
||||||
<div class="span7">
|
|
||||||
<p>
|
|
||||||
<span class="muted">[{{if .Lang}}{{.Lang}}{{end}}]</span>
|
|
||||||
<a href="/search/?q=title:{{.Title}}"><strong>{{.Title}}</strong></a><br />
|
|
||||||
{{if .Authors}}<strong>Authors:</strong> {{range .Authors}}<a href="/search/?q=author:{{.}}">{{.}}</a>, {{end}}<br />{{end}}
|
|
||||||
{{if .Publisher}}<strong>Publisher:</strong> <a href="/search/?q=publisher:{{.Publisher}}">{{.Publisher}}</a><br />{{end}}
|
|
||||||
{{if .Tags}}<strong>Tags:</strong> {{range .Tags}}<a href="/search/?q=tag:{{.}}">{{.}}</a>, {{end}}<br />{{end}}
|
|
||||||
{{if .Isbn}}<strong>ISBN:</strong> {{.Isbn}}<br />{{end}}
|
|
||||||
{{if .Date}}<strong>Date:</strong> {{.Date}}<br />{{end}}
|
|
||||||
{{.Description}}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="span3">
|
|
||||||
{{if and .ID (not .Active)}}
|
|
||||||
<div class="row btn-group pull-right">
|
|
||||||
{{if eq $role "admin" "moderator"}}
|
|
||||||
<a href="/store/{{.ID}}/" class="btn btn-success"><i class="icon-ok"></i> Save</a>
|
|
||||||
{{end}}
|
|
||||||
<a href="/submission/{{$submissionID}}/edit/{{.ID}}" class="btn btn-primary"><i class="icon-pencil"></i> Edit</a>
|
|
||||||
<a href="/submission/{{$submissionID}}/delete/{{.ID}}/" class="btn btn-danger"><i class="icon-remove"></i> Delete</a>
|
|
||||||
</div>
|
|
||||||
<div class="row"><p></p></div>
|
|
||||||
{{end}}
|
|
||||||
<div class="row btn-group pull-right">
|
|
||||||
<a href="{{download_url .}}" class="btn btn-inverse"><i class="icon-download-alt icon-white"></i> download</a>
|
|
||||||
<a href="/read/{{.ID}}" class="btn btn-warning"><i class="icon-eye-open icon-white"></i> read it!</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{end}}
|
|
||||||
{{end}}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{if .Book}}
|
{{$comment := .Comment}}
|
||||||
<form class="row form-inline" method="POST" action="/submission/{{$submissionID}}/comment/{{.Book.ID}}">
|
{{with .Book}}
|
||||||
<textarea class="span11" id="comment" rows="2" name="comment" placeholder="Comments about this book submission. Is it a better version than an existing one in the library?">{{.Comment}}</textarea>
|
{{if .}}
|
||||||
<button type="submit" class="btn btn-primary">Send comment</button>
|
<div class="card mb-3">
|
||||||
</form>
|
<div class="row g-0">
|
||||||
|
<div class="col-md-1 d-flex align-items-center justify-content-center">
|
||||||
|
<a href="/book/{{.ID}}" title="{{.Description}}">
|
||||||
|
{{if .Cover}}<img class="rounded" src="/cover/{{.ID}}/small/{{.Title}}.jpg" alt="{{.Title}}" />{{end}}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-11">
|
||||||
|
<div class="card-body">
|
||||||
|
<p class="card-title">
|
||||||
|
<a href="/search/?q=title:{{.Title}}"><strong>{{.Title}}</strong></a>
|
||||||
|
</p>
|
||||||
|
<div class="card-text row">
|
||||||
|
<p class="col-md-8">
|
||||||
|
{{if .Authors}}<strong>Authors:</strong> {{range .Authors}}<a href="/search/?q=author:{{.}}">{{.}}</a>, {{end}}<br />{{end}}
|
||||||
|
{{if .Publisher}}<strong>Publisher:</strong> <a href="/search/?q=publisher:{{.Publisher}}">{{.Publisher}}</a><br />{{end}}
|
||||||
|
{{if .Tags}}<strong>Tags:</strong> {{range .Tags}}<a href="/search/?q=tag:{{.}}">{{.}}</a>, {{end}}<br />{{end}}
|
||||||
|
{{if .Isbn}}<strong>ISBN:</strong> {{.Isbn}}<br />{{end}}
|
||||||
|
{{if .Date}}<strong>Date:</strong> {{.Date}}<br />{{end}}
|
||||||
|
{{if .Lang}}<strong>Lang:</strong> <a href="/search/?q=lang:{{.Lang}}">{{.Lang}}</a> <br />{{end}}
|
||||||
|
</p>
|
||||||
|
<div class="col-md-4">
|
||||||
|
{{if and .ID (not .Active)}}
|
||||||
|
<div class="btn-group d-flex justify-content-end">
|
||||||
|
{{if eq $role "admin" "moderator"}}
|
||||||
|
<a href="/store/{{.ID}}/" class="btn btn-success">
|
||||||
|
<svg class="bi" width="1em" height="1em" fill="currentColor">
|
||||||
|
<use xlink:href="/img/bootstrap-icons.svg#check"/>
|
||||||
|
</svg>
|
||||||
|
save
|
||||||
|
</a>
|
||||||
|
{{end}}
|
||||||
|
<a href="/submission/{{$submissionID}}/edit/{{.ID}}" class="btn btn-primary">
|
||||||
|
<svg class="bi" width="1em" height="1em" fill="currentColor">
|
||||||
|
<use xlink:href="/img/bootstrap-icons.svg#pencil"/>
|
||||||
|
</svg>
|
||||||
|
edit
|
||||||
|
</a>
|
||||||
|
<a href="/submission/{{$submissionID}}/delete/{{.ID}}/" class="btn btn-danger">
|
||||||
|
<svg class="bi" width="1em" height="1em" fill="currentColor">
|
||||||
|
<use xlink:href="/img/bootstrap-icons.svg#trash"/>
|
||||||
|
</svg>
|
||||||
|
delete
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
<div class="btn-group d-flex justify-content-end">
|
||||||
|
<a href="{{download_url .}}" class="btn btn-dark btn-sm">
|
||||||
|
<svg class="bi" width="1em" height="1em" fill="currentColor">
|
||||||
|
<use xlink:href="/img/bootstrap-icons.svg#file-earmark-arrow-down"/>
|
||||||
|
</svg>
|
||||||
|
download
|
||||||
|
</a>
|
||||||
|
<a href="/read/{{.ID}}" class="btn btn-warning btn-sm">
|
||||||
|
<svg class="bi" width="1em" height="1em" fill="currentColor">
|
||||||
|
<use xlink:href="/img/bootstrap-icons.svg#eyeglasses"/>
|
||||||
|
</svg>
|
||||||
|
read it!
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p>{{.Description}}</p>
|
||||||
|
|
||||||
|
{{if not .Active}}
|
||||||
|
<form method="POST" action="/submission/{{$submissionID}}/comment/{{.ID}}">
|
||||||
|
<textarea class="form-control" id="comment" rows="2" name="comment" placeholder="Comments about this book submission. Is it a better version than an existing one in the library?">{{$comment}}</textarea>
|
||||||
|
<button type="submit" class="btn btn-primary">Update comment</button>
|
||||||
|
</form>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
|
|
|
@ -1,89 +1,153 @@
|
||||||
{{template "header.html" .S}}
|
{{template "header.html" .S}}
|
||||||
|
|
||||||
<form class="centered" action="/submission/moderate/">
|
<form action="/submission/moderate/">
|
||||||
<input type="search" class="search-query span8" name="q" {{if .Search}}value="{{.Search}}"{{else}}placeholder="Search"{{end}} />
|
<div class="row justify-content-center">
|
||||||
|
<input type="search" class="col-sm-8" name="q" {{if .Search}}value="{{.Search}}"{{else}}placeholder="Search"{{end}} />
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
<br />
|
||||||
|
|
||||||
{{if .Books}}
|
{{if .Books}}
|
||||||
<div class="centered btn-group">
|
<div class="btn-group">
|
||||||
<a href="/store/{{range .Books}}{{.B.ID}}/{{end}}" class="btn btn-large btn-success"><i class="icon-ok"></i> Save All</a>
|
<a href="/store/{{range .Books}}{{.B.ID}}/{{end}}" class="btn btn-lg btn-success">
|
||||||
<a href="/delete/{{range .Books}}{{.B.ID}}/{{end}}" class="btn btn-large btn-danger"><i class="icon-remove"></i> Delete All</a>
|
<svg class="bi" width="1.5em" height="1.5em" fill="currentColor">
|
||||||
|
<use xlink:href="/img/bootstrap-icons.svg#check-all"/>
|
||||||
|
</svg>
|
||||||
|
Save All
|
||||||
|
</a>
|
||||||
|
<a href="/delete/{{range .Books}}{{.B.ID}}/{{end}}" class="btn btn-lg btn-danger">
|
||||||
|
<svg class="bi" width="1.5em" height="1.5em" fill="currentColor">
|
||||||
|
<use xlink:href="/img/bootstrap-icons.svg#trash-fill"/>
|
||||||
|
</svg>
|
||||||
|
Delete All
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
<p class="centered">Found {{.Found}} books.<br /></p>
|
|
||||||
<ul class="pager">
|
<p class="text-center">Found {{.Found}} books.<br /></p>
|
||||||
{{if .Prev}}
|
<nav class="d-flex justify-content-center" arial-label="Book moderate page navigation">
|
||||||
<li class="previous">
|
<ul class="pagination">
|
||||||
<a href="{{.Prev}}">← Prev</a>
|
<li class="page-item {{if not .Prev}}disabled{{end}}">
|
||||||
</li>
|
<a class="page-link" href="{{.Prev}}">← Prev</a>
|
||||||
{{end}}
|
</li>
|
||||||
{{if .Next}}
|
<li class="page-item disabled">
|
||||||
<li class="next">
|
<a class="page-link" href="#">Page {{.Page}}</a>
|
||||||
<a href="{{.Next}}">Next →</a>
|
</li>
|
||||||
</li>
|
<li class="page-item {{if not .Next}}disabled{{end}}">
|
||||||
{{end}}
|
<a class="page-link" href="{{.Next}}">Next →</a>
|
||||||
</ul>
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
|
||||||
{{range .Books}}
|
{{range .Books}}
|
||||||
{{$titleFound := .TitleFound}}
|
{{$titleFound := .TitleFound}}
|
||||||
{{$authorFound := .AuthorFound}}
|
{{$authorFound := .AuthorFound}}
|
||||||
{{with .B}}
|
{{with .B}}
|
||||||
<div class="row">
|
<div class="card mb-3">
|
||||||
<div class="span1">
|
<div class="row g-0">
|
||||||
<p class="pull-right">{{if .Cover}}<img src="/cover/{{.ID}}/small/{{.Title}}.jpg" alt="{{.Title}}" />{{end}}</p>
|
<div class="col-md-1 d-flex align-items-center justify-content-center">
|
||||||
</div>
|
<a href="/book/{{.ID}}" title="{{.Description}}">
|
||||||
<div class="span9">
|
{{if .Cover}}<img class="rounded" src="/cover/{{.ID}}/small/{{.Title}}.jpg" alt="{{.Title}}" />{{end}}
|
||||||
<p><a href="/search/?q=title:{{.Title}}"><strong>{{.Title}}</strong></a> <!--<small>({{$titleFound}})</small>--><br />
|
</a>
|
||||||
{{if .Authors}}<strong>Authors:</strong> {{range .Authors}}<a href="/search/?q=author:{{.}}">{{.}}</a>, {{end}} <!--<small>({{$authorFound}})</small>--><br />{{end}}
|
|
||||||
{{if .Publisher}}<strong>Publisher:</strong> <a href="/search/?q=publisher:{{.Publisher}}">{{.Publisher}}</a><br />{{end}}
|
|
||||||
{{if .Tags}}<strong>Tags:</strong> {{range .Tags}}<a href="/search/?q=tag:{{.}}">{{.}}</a>, {{end}}<br />{{end}}
|
|
||||||
{{if .Isbn}}<strong>ISBN:</strong> {{.Isbn}}<br />{{end}}
|
|
||||||
{{if .Date}}<strong>Date:</strong> {{.Date}}<br />{{end}}
|
|
||||||
{{if .Lang}}<strong>Lang:</strong> <a href="/search/?q=lang:{{.Lang}}">{{.Lang}}</a> <br />{{end}}
|
|
||||||
{{.Description}}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="span2">
|
|
||||||
<div class="row btn-group pull-right">
|
|
||||||
<a href="/store/{{.ID}}/" class="btn btn-success"><i class="icon-ok"></i> Save</a>
|
|
||||||
<a href="/edit/{{.ID}}" class="btn btn-primary"><i class="icon-pencil"></i> Edit</a>
|
|
||||||
<a href="/delete/{{.ID}}/" class="btn btn-danger"><i class="icon-remove"></i> Delete</a>
|
|
||||||
</div>
|
|
||||||
<div class="row"><p></p></div>
|
|
||||||
<div class="row btn-group pull-right">
|
|
||||||
<a href="{{download_url .}}" class="btn btn-inverse"><i class="icon-download-alt icon-white"></i> download</a>
|
|
||||||
<a href="/read/{{.ID}}" class="btn btn-warning"><i class="icon-eye-open icon-white"></i> read it!</a>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-md-11">
|
||||||
|
<div class="card-body">
|
||||||
|
<p class="card-title">
|
||||||
|
<a href="/search/?q=title:{{.Title}}"><strong>{{.Title}}</strong></a> <!--<small>({{$titleFound}})</small>-->
|
||||||
|
</p>
|
||||||
|
<div class="card-text row">
|
||||||
|
<p class="col-md-8">
|
||||||
|
{{if .Authors}}<strong>Authors:</strong> {{range .Authors}}<a href="/search/?q=author:{{.}}">{{.}}</a>, {{end}} <!--<small>({{$authorFound}})</small>--><br />{{end}}
|
||||||
|
{{if .Publisher}}<strong>Publisher:</strong> <a href="/search/?q=publisher:{{.Publisher}}">{{.Publisher}}</a><br />{{end}}
|
||||||
|
{{if .Tags}}<strong>Tags:</strong> {{range .Tags}}<a href="/search/?q=tag:{{.}}">{{.}}</a>, {{end}}<br />{{end}}
|
||||||
|
{{if .Isbn}}<strong>ISBN:</strong> {{.Isbn}}<br />{{end}}
|
||||||
|
{{if .Date}}<strong>Date:</strong> {{.Date}}<br />{{end}}
|
||||||
|
{{if .Lang}}<strong>Lang:</strong> <a href="/search/?q=lang:{{.Lang}}">{{.Lang}}</a> <br />{{end}}
|
||||||
|
</p>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<div class="btn-group d-flex justify-content-end">
|
||||||
|
<a href="/store/{{.ID}}/" class="btn btn-success">
|
||||||
|
<svg class="bi" width="1em" height="1em" fill="currentColor">
|
||||||
|
<use xlink:href="/img/bootstrap-icons.svg#check"/>
|
||||||
|
</svg>
|
||||||
|
save
|
||||||
|
</a>
|
||||||
|
<a href="/edit/{{.ID}}" class="btn btn-primary">
|
||||||
|
<svg class="bi" width="1em" height="1em" fill="currentColor">
|
||||||
|
<use xlink:href="/img/bootstrap-icons.svg#pencil"/>
|
||||||
|
</svg>
|
||||||
|
edit
|
||||||
|
</a>
|
||||||
|
<a href="/delete/{{.ID}}/" class="btn btn-danger">
|
||||||
|
<svg class="bi" width="1em" height="1em" fill="currentColor">
|
||||||
|
<use xlink:href="/img/bootstrap-icons.svg#trash"/>
|
||||||
|
</svg>
|
||||||
|
delete
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="btn-group d-flex justify-content-end">
|
||||||
|
<a href="{{download_url .}}" class="btn btn-dark btn-sm">
|
||||||
|
<svg class="bi" width="1em" height="1em" fill="currentColor">
|
||||||
|
<use xlink:href="/img/bootstrap-icons.svg#file-earmark-arrow-down"/>
|
||||||
|
</svg>
|
||||||
|
download
|
||||||
|
</a>
|
||||||
|
<a href="/read/{{.ID}}" class="btn btn-warning btn-sm">
|
||||||
|
<svg class="bi" width="1em" height="1em" fill="currentColor">
|
||||||
|
<use xlink:href="/img/bootstrap-icons.svg#eyeglasses"/>
|
||||||
|
</svg>
|
||||||
|
read it!
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p>{{.Description}}</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if .Comment}}
|
{{if .Comment}}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="span1">
|
<div class="col-md-1">
|
||||||
<b>Comment:</b>
|
<b>Comment:</b>
|
||||||
</div>
|
</div>
|
||||||
<div class="span10 well">
|
<div class="col-md-11">
|
||||||
<p>{{.Comment}}</p>
|
<p>{{.Comment}}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<br />
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
<ul class="pager">
|
|
||||||
{{if .Prev}}
|
<nav class="d-flex justify-content-center" arial-label="Book moderate page navigation">
|
||||||
<li class="previous">
|
<ul class="pagination">
|
||||||
<a href="{{.Prev}}">← Prev</a>
|
<li class="page-item {{if not .Prev}}disabled{{end}}">
|
||||||
</li>
|
<a class="page-link" href="{{.Prev}}">← Prev</a>
|
||||||
{{end}}
|
</li>
|
||||||
{{if .Next}}
|
<li class="page-item disabled">
|
||||||
<li class="next">
|
<a class="page-link" href="#">Page {{.Page}}</a>
|
||||||
<a href="{{.Next}}">Next →</a>
|
</li>
|
||||||
</li>
|
<li class="page-item {{if not .Next}}disabled{{end}}">
|
||||||
{{end}}
|
<a class="page-link" href="{{.Next}}">Next →</a>
|
||||||
</ul>
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
|
||||||
{{if .Books}}
|
{{if .Books}}
|
||||||
<div class="centered btn-group">
|
<div class="btn-group">
|
||||||
<a href="/store/{{range .Books}}{{.B.ID}}/{{end}}" class="btn btn-large btn-success"><i class="icon-ok"></i> Save All</a>
|
<a href="/store/{{range .Books}}{{.B.ID}}/{{end}}" class="btn btn-lg btn-success">
|
||||||
<a href="/delete/{{range .Books}}{{.B.ID}}/{{end}}" class="btn btn-large btn-danger"><i class="icon-remove"></i> Delete All</a>
|
<svg class="bi" width="1.5em" height="1.5em" fill="currentColor">
|
||||||
|
<use xlink:href="/img/bootstrap-icons.svg#check-all"/>
|
||||||
|
</svg>
|
||||||
|
Save All
|
||||||
|
</a>
|
||||||
|
<a href="/delete/{{range .Books}}{{.B.ID}}/{{end}}" class="btn btn-lg btn-danger">
|
||||||
|
<svg class="bi" width="1.5em" height="1.5em" fill="currentColor">
|
||||||
|
<use xlink:href="/img/bootstrap-icons.svg#trash-fill"/>
|
||||||
|
</svg>
|
||||||
|
Delete All
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
|
|
|
@ -7,70 +7,98 @@
|
||||||
{{$role := .S.Role}}
|
{{$role := .S.Role}}
|
||||||
{{range .Submissions}}
|
{{range .Submissions}}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="row">
|
<p>
|
||||||
<div class="span9">
|
<b>{{.Filename}}</b>
|
||||||
<p><b>{{.Filename}}</b>
|
{{if not .Book}}
|
||||||
{{if not .Book}}
|
<span class="badge bg-danger">
|
||||||
<span class="label label-important">
|
{{else if .Book.Active}}
|
||||||
{{else if .Book.Active}}
|
<span class="badge bg-success">
|
||||||
<span class="label label-success">
|
{{else}}
|
||||||
{{else}}
|
<span class="badge bg-warning">
|
||||||
<span class="label label-warning">
|
{{end}}
|
||||||
{{end}}
|
{{.Status}}</span>
|
||||||
{{.Status}}</span></p>
|
</p>
|
||||||
</div>
|
|
||||||
<div class="span3">
|
|
||||||
<h6 class="pull-right"><a href="/submission/{{.SubmissionID}}">Submission {{.SubmissionID}}</a></h6>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{$submissionID := .SubmissionID}}
|
|
||||||
{{with .Book}}
|
|
||||||
|
|
||||||
{{if .}}
|
|
||||||
<div class="span1">
|
|
||||||
<p class="pull-right"><a href="/book/{{.ID}}">{{if .Cover}}<img class="img-rounded" src="/cover/{{.ID}}/small/{{.Title}}.jpg" alt="{{.Title}}" />{{end}}</a></p>
|
|
||||||
</div>
|
|
||||||
<div class="span10 well">
|
|
||||||
<div class="row">
|
|
||||||
<div class="span7">
|
|
||||||
<p>
|
|
||||||
<span class="muted">[{{if .Lang}}{{.Lang}}{{end}}]</span>
|
|
||||||
<a href="/search/?q=title:{{.Title}}"><strong>{{.Title}}</strong></a><br />
|
|
||||||
{{if .Authors}}<strong>Authors:</strong> {{range .Authors}}<a href="/search/?q=author:{{.}}">{{.}}</a>, {{end}}<br />{{end}}
|
|
||||||
{{if .Publisher}}<strong>Publisher:</strong> <a href="/search/?q=publisher:{{.Publisher}}">{{.Publisher}}</a><br />{{end}}
|
|
||||||
{{if .Tags}}<strong>Tags:</strong> {{range .Tags}}<a href="/search/?q=tag:{{.}}">{{.}}</a>, {{end}}<br />{{end}}
|
|
||||||
{{if .Isbn}}<strong>ISBN:</strong> {{.Isbn}}<br />{{end}}
|
|
||||||
{{if .Date}}<strong>Date:</strong> {{.Date}}<br />{{end}}
|
|
||||||
{{.Description}}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="span3">
|
|
||||||
{{if and .ID (not .Active)}}
|
|
||||||
<div class="row btn-group pull-right">
|
|
||||||
{{if eq $role "admin" "moderator"}}
|
|
||||||
<a href="/store/{{.ID}}/" class="btn btn-success"><i class="icon-ok"></i> Save</a>
|
|
||||||
{{end}}
|
|
||||||
<a href="/submission/{{$submissionID}}/edit/{{.ID}}" class="btn btn-primary"><i class="icon-pencil"></i> Edit</a>
|
|
||||||
<a href="/submission/{{$submissionID}}/delete/{{.ID}}/" class="btn btn-danger"><i class="icon-remove"></i> Delete</a>
|
|
||||||
</div>
|
|
||||||
<div class="row"><p></p></div>
|
|
||||||
{{end}}
|
|
||||||
<div class="row btn-group pull-right">
|
|
||||||
<a href="{{download_url .}}" class="btn btn-inverse"><i class="icon-download-alt icon-white"></i> download</a>
|
|
||||||
<a href="/read/{{.ID}}" class="btn btn-warning"><i class="icon-eye-open icon-white"></i> read it!</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{end}}
|
|
||||||
{{end}}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{if .Book}}
|
{{$comment := .Comment}}
|
||||||
<form class="row form-inline" method="POST" action="/submission/{{.SubmissionID}}/comment/{{.Book.ID}}">
|
{{$submissionID := .SubmissionID}}
|
||||||
<textarea class="span11" id="comment" rows="2" name="comment" placeholder="Comments about this book submission. Is it a better version than an existing one in the library?">{{.Comment}}</textarea>
|
{{with .Book}}
|
||||||
<button type="submit" class="btn btn-primary">Send comment</button>
|
{{if .}}
|
||||||
</form>
|
<div class="card mb-3">
|
||||||
|
<div class="row g-0">
|
||||||
|
<div class="col-md-1 d-flex align-items-center justify-content-center">
|
||||||
|
<a href="/book/{{.ID}}" title="{{.Description}}">
|
||||||
|
{{if .Cover}}<img class="rounded" src="/cover/{{.ID}}/small/{{.Title}}.jpg" alt="{{.Title}}" />{{end}}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-11">
|
||||||
|
<div class="card-body">
|
||||||
|
<p class="card-title">
|
||||||
|
<a href="/search/?q=title:{{.Title}}"><strong>{{.Title}}</strong></a>
|
||||||
|
</p>
|
||||||
|
<div class="card-text row">
|
||||||
|
<p class="col-md-8">
|
||||||
|
{{if .Authors}}<strong>Authors:</strong> {{range .Authors}}<a href="/search/?q=author:{{.}}">{{.}}</a>, {{end}}<br />{{end}}
|
||||||
|
{{if .Publisher}}<strong>Publisher:</strong> <a href="/search/?q=publisher:{{.Publisher}}">{{.Publisher}}</a><br />{{end}}
|
||||||
|
{{if .Tags}}<strong>Tags:</strong> {{range .Tags}}<a href="/search/?q=tag:{{.}}">{{.}}</a>, {{end}}<br />{{end}}
|
||||||
|
{{if .Isbn}}<strong>ISBN:</strong> {{.Isbn}}<br />{{end}}
|
||||||
|
{{if .Date}}<strong>Date:</strong> {{.Date}}<br />{{end}}
|
||||||
|
{{if .Lang}}<strong>Lang:</strong> <a href="/search/?q=lang:{{.Lang}}">{{.Lang}}</a> <br />{{end}}
|
||||||
|
</p>
|
||||||
|
<div class="col-md-4">
|
||||||
|
{{if and .ID (not .Active)}}
|
||||||
|
<div class="btn-group d-flex justify-content-end">
|
||||||
|
{{if eq $role "admin" "moderator"}}
|
||||||
|
<a href="/store/{{.ID}}/" class="btn btn-success">
|
||||||
|
<svg class="bi" width="1em" height="1em" fill="currentColor">
|
||||||
|
<use xlink:href="/img/bootstrap-icons.svg#check"/>
|
||||||
|
</svg>
|
||||||
|
save
|
||||||
|
</a>
|
||||||
|
{{end}}
|
||||||
|
<a href="/submission/{{$submissionID}}/edit/{{.ID}}" class="btn btn-primary">
|
||||||
|
<svg class="bi" width="1em" height="1em" fill="currentColor">
|
||||||
|
<use xlink:href="/img/bootstrap-icons.svg#pencil"/>
|
||||||
|
</svg>
|
||||||
|
edit
|
||||||
|
</a>
|
||||||
|
<a href="/submission/{{$submissionID}}/delete/{{.ID}}/" class="btn btn-danger">
|
||||||
|
<svg class="bi" width="1em" height="1em" fill="currentColor">
|
||||||
|
<use xlink:href="/img/bootstrap-icons.svg#trash"/>
|
||||||
|
</svg>
|
||||||
|
delete
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
<div class="btn-group d-flex justify-content-end">
|
||||||
|
<a href="{{download_url .}}" class="btn btn-dark btn-sm">
|
||||||
|
<svg class="bi" width="1em" height="1em" fill="currentColor">
|
||||||
|
<use xlink:href="/img/bootstrap-icons.svg#file-earmark-arrow-down"/>
|
||||||
|
</svg>
|
||||||
|
download
|
||||||
|
</a>
|
||||||
|
<a href="/read/{{.ID}}" class="btn btn-warning btn-sm">
|
||||||
|
<svg class="bi" width="1em" height="1em" fill="currentColor">
|
||||||
|
<use xlink:href="/img/bootstrap-icons.svg#eyeglasses"/>
|
||||||
|
</svg>
|
||||||
|
read it!
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p>{{.Description}}</p>
|
||||||
|
|
||||||
|
{{if not .Active}}
|
||||||
|
<form method="POST" action="/submission/{{$submissionID}}/comment/{{.ID}}">
|
||||||
|
<textarea class="form-control" id="comment" rows="2" name="comment" placeholder="Comments about this book submission. Is it a better version than an existing one in the library?">{{$comment}}</textarea>
|
||||||
|
<button type="submit" class="btn btn-primary">Update comment</button>
|
||||||
|
</form>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,14 @@
|
||||||
|
|
||||||
<p>Upload your epubs to help the library.</p>
|
<p>Upload your epubs to help the library.</p>
|
||||||
|
|
||||||
<form class="well form-inline" method="POST" enctype="multipart/form-data">
|
<div class="row justify-content-center">
|
||||||
<input accept="application/epub+zip" type="file" name="epub" multiple="multiple" />
|
<form class="col-sm-11" method="POST" enctype="multipart/form-data">
|
||||||
<button type="submit" class="btn">Submit</button>
|
<div class="input-group mb-3">
|
||||||
</form>
|
<input accept="application/epub+zip" type="file" name="epub" multiple="multiple" />
|
||||||
|
<button type="submit" class="btn btn-outline-secondary">Upload</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
<p>The uploaded books will be reviewed by the librarians and included if they comply our quality standards. Do not upload epubs converted from PDFs or any book that is not pleasant to read.</p>
|
<p>The uploaded books will be reviewed by the librarians and included if they comply our quality standards. Do not upload epubs converted from PDFs or any book that is not pleasant to read.</p>
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,33 @@
|
||||||
{{template "header.html" .S}}
|
{{template "header.html" .S}}
|
||||||
|
|
||||||
|
<h4>Add user:</h4>
|
||||||
|
<form class="row" method="POST" action="/admin/users/add/">
|
||||||
|
<div class="col-6 col-md-3">
|
||||||
|
<label class="col-form-label" for="username">Username</label>
|
||||||
|
<input class="form-control" type="text" id="username" name="username">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-6 col-md-3">
|
||||||
|
<label class="col-form-label" for="role">Role</label>
|
||||||
|
<input class="form-control" type="text" id="role" name="role" value="moderator">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-6 col-md-3">
|
||||||
|
<label class="col-form-label" for="password">Password</label>
|
||||||
|
<input class="form-control" type="password" id="password" name="password">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-6 col-md-3">
|
||||||
|
<br />
|
||||||
|
<button type="submit" class="btn btn-primary" id="submit">Create</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<br />
|
||||||
<h4>Users:</h4>
|
<h4>Users:</h4>
|
||||||
|
|
||||||
<table class="table table-hover">
|
<div class="table-responsive-md">
|
||||||
|
<table class="table">
|
||||||
<thead>
|
<thead>
|
||||||
<th>username</th>
|
<th>username</th>
|
||||||
<th>role</th>
|
<th>role</th>
|
||||||
|
@ -13,16 +38,24 @@
|
||||||
{{range .Users}}
|
{{range .Users}}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{.Username}}</td>
|
<td>{{.Username}}</td>
|
||||||
<td><form class="row form-inline" method="POST" action="/admin/users/">
|
<td><form class="row" method="POST" action="/admin/users/">
|
||||||
<input type="hidden" id="username" name="username" value="{{.Username}}">
|
<input type="hidden" id="username" name="username" value="{{.Username}}">
|
||||||
|
<div class="col">
|
||||||
<input type="text" id="role" name="role" value="{{.Role}}">
|
<input type="text" id="role" name="role" value="{{.Role}}">
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
<button type="submit" class="btn btn-primary">Update</button>
|
<button type="submit" class="btn btn-primary">Update</button>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</td>
|
</td>
|
||||||
<td><form class="row form-inline" method="POST" action="/admin/users/">
|
<td><form class="row form-inline" method="POST" action="/admin/users/">
|
||||||
<input type="hidden" id="username" name="username" value="{{.Username}}">
|
<input type="hidden" id="username" name="username" value="{{.Username}}">
|
||||||
<input type="password" id="password" name="password" placeholder="password">
|
<div class="col">
|
||||||
<button type="submit" class="btn btn-primary">Update</button>
|
<input type="password" id="password" name="password" placeholder="password">
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<button type="submit" class="btn btn-primary">Update</button>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</td>
|
</td>
|
||||||
<td>{{.LastLogin.Format "2006-01-02"}}</td>
|
<td>{{.LastLogin.Format "2006-01-02"}}</td>
|
||||||
|
@ -30,33 +63,6 @@
|
||||||
{{end}}
|
{{end}}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
<h4>Add user:</h4>
|
|
||||||
<form class="form-horizontal" method="POST" action="/admin/users/add/">
|
|
||||||
<div class="control-group">
|
|
||||||
<label class="control-label" for="username">Username</label>
|
|
||||||
<div class="controls">
|
|
||||||
<input type="text" id="username" name="username">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="control-group">
|
|
||||||
<label class="control-label" for="role">Role</label>
|
|
||||||
<div class="controls">
|
|
||||||
<input type="text" id="role" name="role" value="moderator">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="control-group">
|
|
||||||
<label class="control-label" for="password">Password</label>
|
|
||||||
<div class="controls">
|
|
||||||
<input type="password" id="password" name="password">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-actions">
|
|
||||||
<button type="submit" class="btn btn-primary">Submit</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
{{template "footer.html" .S}}
|
{{template "footer.html" .S}}
|
||||||
|
|
Reference in a new issue