Quite a few things
This commit is contained in:
parent
56427140b5
commit
087e5a2f4c
13 changed files with 151 additions and 29 deletions
23
assets/style.css
Normal file
23
assets/style.css
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
body {
|
||||||
|
max-width: 940px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 1em;
|
||||||
|
font-family: Verdana;
|
||||||
|
}
|
||||||
|
|
||||||
|
section {
|
||||||
|
padding: 1em;
|
||||||
|
background-color: peachpuff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cols {
|
||||||
|
display: grid;
|
||||||
|
row-gap: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 650px) {
|
||||||
|
.cols {
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
grid-gap: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -9,6 +9,7 @@ type (
|
||||||
Env string
|
Env string
|
||||||
CertFile string
|
CertFile string
|
||||||
KeyFile string
|
KeyFile string
|
||||||
|
AssetsDir string
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -19,5 +20,6 @@ func New() *Config {
|
||||||
Env: os.Getenv("ENV"),
|
Env: os.Getenv("ENV"),
|
||||||
CertFile: os.Getenv("CERT_FILE"),
|
CertFile: os.Getenv("CERT_FILE"),
|
||||||
KeyFile: os.Getenv("CERT_KEY_FILE"),
|
KeyFile: os.Getenv("CERT_KEY_FILE"),
|
||||||
|
AssetsDir: os.Getenv("ASSETS_DIR"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,14 +9,26 @@ var TplCommonMap = map[string]string{
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<link rel="stylesheet" href="/style.css"/>
|
<title>status cafe</title>
|
||||||
<title>Status</title>
|
<meta name="description" content="your friends' updates">
|
||||||
|
<link rel="stylesheet" href="/assets/style.css"/>
|
||||||
{{ template "head" . }}
|
{{ template "head" . }}
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<header>
|
||||||
|
<h1>status.cafe</h1>
|
||||||
|
</header>
|
||||||
|
<main>
|
||||||
{{ template "content" . }}
|
{{ template "content" . }}
|
||||||
|
</main>
|
||||||
|
<footer>
|
||||||
|
This is the footer
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ define "head" }}{{ end }}`,
|
{{ define "head" }}{{ end }}
|
||||||
|
`,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,20 @@ package form
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
type StatusForm struct {
|
type StatusForm struct {
|
||||||
|
Id int64
|
||||||
Content string
|
Content string
|
||||||
Error string
|
Error string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewStatusForm(r *http.Request) *StatusForm {
|
func NewStatusForm(r *http.Request) *StatusForm {
|
||||||
|
var id int64
|
||||||
|
id, _ = strconv.ParseInt(r.FormValue("id"), 10, 64)
|
||||||
return &StatusForm{
|
return &StatusForm{
|
||||||
|
Id: id,
|
||||||
Content: r.FormValue("content"),
|
Content: r.FormValue("content"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -71,11 +71,14 @@ func New(cfg *config.Config, sess *session.Session, data *storage.Storage) (http
|
||||||
router.HandleFunc("/register", h.handleRegister)
|
router.HandleFunc("/register", h.handleRegister)
|
||||||
router.HandleFunc("/logout", h.logout).Methods(http.MethodGet)
|
router.HandleFunc("/logout", h.logout).Methods(http.MethodGet)
|
||||||
|
|
||||||
router.HandleFunc("/statuses/new", h.showNewStatusView).Methods(http.MethodGet)
|
//router.HandleFunc("/statuses/new", h.showNewStatusView).Methods(http.MethodGet)
|
||||||
router.HandleFunc("/statuses/save", h.saveStatus).Methods(http.MethodPost)
|
router.HandleFunc("/status-save", h.saveStatus).Methods(http.MethodPost)
|
||||||
router.HandleFunc("/statuses/{id}/edit", h.showEditStatusView).Methods(http.MethodGet)
|
router.HandleFunc("/statuses/{id}/edit", h.showEditStatusView).Methods(http.MethodGet)
|
||||||
router.HandleFunc("/statuses/{id}/update", h.updateStatus).Methods(http.MethodPost)
|
router.HandleFunc("/statuses/{id}/update", h.updateStatus).Methods(http.MethodPost)
|
||||||
router.HandleFunc("/statuses/{id}/remove", h.handleRemoveStatus)
|
//router.HandleFunc("/statuses/{id}/remove", h.handleRemoveStatus)
|
||||||
|
//router.HandleFunc("/status-remove", h.handleRemoveStatus)
|
||||||
|
|
||||||
|
router.PathPrefix("/").Handler(http.FileServer(http.Dir(cfg.AssetsDir)))
|
||||||
|
|
||||||
return router, nil
|
return router, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,8 @@ var TplMap = map[string]string{
|
||||||
"confirm_remove_status": `{{ define "content" }}
|
"confirm_remove_status": `{{ define "content" }}
|
||||||
Are you sure you you want to delete the following status?
|
Are you sure you you want to delete the following status?
|
||||||
<p>{{ .status.Content }}</p>
|
<p>{{ .status.Content }}</p>
|
||||||
<form action="/statuses/{{ .status.Id }}/remove" method="post">
|
<form action="/remove-status" method="post">
|
||||||
|
<input type="hidden" name="id"/>
|
||||||
<input type="submit" value="Submit">
|
<input type="submit" value="Submit">
|
||||||
</form>
|
</form>
|
||||||
{{ end }}`,
|
{{ end }}`,
|
||||||
|
|
@ -35,19 +36,41 @@ Are you sure you you want to delete the following status?
|
||||||
{{ end }}
|
{{ end }}
|
||||||
<form action="/statuses/{{ .status.Id }}/update" method="post">
|
<form action="/statuses/{{ .status.Id }}/update" method="post">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<input type="text" name="content" placeholder="What's new?" required autofocus value="{{ .status.Content }}"/>
|
<div class="field">
|
||||||
|
<textarea name="content" placeholder="What's new?" required style="width: 100%; box-sizing: border-box;" autofocus>{{ .status.Content }}</textarea>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<input type="submit" value="Submit">
|
<input type="submit" value="Submit">
|
||||||
</form>
|
</form>
|
||||||
{{ end }}`,
|
{{ end }}`,
|
||||||
"index": `{{ define "content" }}
|
"index": `{{ define "content" }}
|
||||||
<p><a href="javascript:void(open('http://localhost:8000/statuses/new','status.cafe','resizable,scrollbars,width=360,height=200'))">Update your status</a></p>
|
<div class="cols">
|
||||||
{{ range .statuses }}
|
<section>
|
||||||
<article class="status">
|
<h2>Set your status</h2>
|
||||||
<div class="username"><a href="/{{ .User }}">{{ .User }}</a>, {{ .TimeAgo }}</div>
|
{{ if .form.Error }}
|
||||||
<p>{{ .Content }}</p>
|
<p>{{ .form.Error }}</p>
|
||||||
</article>
|
{{ end }}
|
||||||
{{ end }}
|
{{ if .flash }}
|
||||||
|
<p>{{ .flash }}</p>
|
||||||
|
{{ end }}
|
||||||
|
<form action="/status-save" method="post">
|
||||||
|
<div class="field">
|
||||||
|
<textarea name="content" placeholder="What's new?" required style="width: 100%; box-sizing: border-box;" autofocus></textarea>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<input type="submit" value="Submit">
|
||||||
|
</form>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<h2>Status stream</h2>
|
||||||
|
{{ range .statuses }}
|
||||||
|
<article class="status">
|
||||||
|
<div class="username"><a href="/{{ .User }}">{{ .User }}</a>, {{ .TimeAgo }}</div>
|
||||||
|
<p>{{ .Content }}</p>
|
||||||
|
</article>
|
||||||
|
{{ end }}
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
{{ end }}`,
|
{{ end }}`,
|
||||||
"login": `{{ define "content" }}
|
"login": `{{ define "content" }}
|
||||||
<h1>Login</h1>
|
<h1>Login</h1>
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,24 @@
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<link rel="stylesheet" href="/style.css"/>
|
<title>status cafe</title>
|
||||||
<title>Status</title>
|
<meta name="description" content="your friends' updates">
|
||||||
|
<link rel="stylesheet" href="/assets/style.css"/>
|
||||||
{{ template "head" . }}
|
{{ template "head" . }}
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<header>
|
||||||
|
<h1>status.cafe</h1>
|
||||||
|
</header>
|
||||||
|
<main>
|
||||||
{{ template "content" . }}
|
{{ template "content" . }}
|
||||||
|
</main>
|
||||||
|
<footer>
|
||||||
|
This is the footer
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ define "head" }}{{ end }}
|
{{ define "head" }}{{ end }}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
{{ define "content" }}
|
{{ define "content" }}
|
||||||
Are you sure you you want to delete the following status?
|
Are you sure you you want to delete the following status?
|
||||||
<p>{{ .status.Content }}</p>
|
<p>{{ .status.Content }}</p>
|
||||||
<form action="/statuses/{{ .status.Id }}/remove" method="post">
|
<form action="/remove-status" method="post">
|
||||||
|
<input type="hidden" name="id"/>
|
||||||
<input type="submit" value="Submit">
|
<input type="submit" value="Submit">
|
||||||
</form>
|
</form>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
@ -8,7 +8,9 @@
|
||||||
{{ end }}
|
{{ end }}
|
||||||
<form action="/statuses/{{ .status.Id }}/update" method="post">
|
<form action="/statuses/{{ .status.Id }}/update" method="post">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<input type="text" name="content" placeholder="What's new?" required autofocus value="{{ .status.Content }}"/>
|
<div class="field">
|
||||||
|
<textarea name="content" placeholder="What's new?" required style="width: 100%; box-sizing: border-box;" autofocus>{{ .status.Content }}</textarea>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<input type="submit" value="Submit">
|
<input type="submit" value="Submit">
|
||||||
</form>
|
</form>
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,29 @@
|
||||||
{{ define "content" }}
|
{{ define "content" }}
|
||||||
<p><a href="javascript:void(open('http://localhost:8000/statuses/new','status.cafe','resizable,scrollbars,width=360,height=200'))">Update your status</a></p>
|
<div class="cols">
|
||||||
{{ range .statuses }}
|
<section>
|
||||||
<article class="status">
|
<h2>Set your status</h2>
|
||||||
<div class="username"><a href="/{{ .User }}">{{ .User }}</a>, {{ .TimeAgo }}</div>
|
{{ if .form.Error }}
|
||||||
<p>{{ .Content }}</p>
|
<p>{{ .form.Error }}</p>
|
||||||
</article>
|
{{ end }}
|
||||||
{{ end }}
|
{{ if .flash }}
|
||||||
|
<p>{{ .flash }}</p>
|
||||||
|
{{ end }}
|
||||||
|
<form action="/status-save" method="post">
|
||||||
|
<div class="field">
|
||||||
|
<textarea name="content" placeholder="What's new?" required style="width: 100%; box-sizing: border-box;" autofocus></textarea>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<input type="submit" value="Submit">
|
||||||
|
</form>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<h2>Status stream</h2>
|
||||||
|
{{ range .statuses }}
|
||||||
|
<article class="status">
|
||||||
|
<div class="username"><a href="/{{ .User }}">{{ .User }}</a>, {{ .TimeAgo }}</div>
|
||||||
|
<p>{{ .Content }}</p>
|
||||||
|
</article>
|
||||||
|
{{ end }}
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package handler
|
package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -10,12 +11,29 @@ type Update struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handler) showIndexView(w http.ResponseWriter, r *http.Request) {
|
func (h *Handler) showIndexView(w http.ResponseWriter, r *http.Request) {
|
||||||
|
user, err := h.getUser(r)
|
||||||
|
if err != nil {
|
||||||
|
unauthorized(w)
|
||||||
|
return
|
||||||
|
}
|
||||||
statuses, err := h.storage.LatestStatuses()
|
statuses, err := h.storage.LatestStatuses()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
serverError(w, err)
|
serverError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
session, err := h.sess.Store.Get(r, "ichi")
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
flash := ""
|
||||||
|
if flashes := session.Flashes(); len(flashes) > 0 {
|
||||||
|
flash = flashes[0].(string)
|
||||||
|
}
|
||||||
|
session.Save(r, w)
|
||||||
|
fmt.Println(user)
|
||||||
h.renderLayout(w, "index", map[string]interface{}{
|
h.renderLayout(w, "index", map[string]interface{}{
|
||||||
"statuses": statuses,
|
"statuses": statuses,
|
||||||
|
"flash": flash,
|
||||||
}, "")
|
}, "")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"status/web/handler/form"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (h *Handler) handleRemoveStatus(w http.ResponseWriter, r *http.Request) {
|
func (h *Handler) handleRemoveStatus(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
@ -10,7 +11,8 @@ func (h *Handler) handleRemoveStatus(w http.ResponseWriter, r *http.Request) {
|
||||||
unauthorized(w)
|
unauthorized(w)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
status, err := h.storage.StatusById(RouteInt64Param(r, "id"))
|
f := form.NewStatusForm(r)
|
||||||
|
status, err := h.storage.StatusById(f.Id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
serverError(w, err)
|
serverError(w, err)
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -39,5 +39,5 @@ func (h *Handler) saveStatus(w http.ResponseWriter, r *http.Request) {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
http.Redirect(w, r, "/statuses/new", http.StatusFound)
|
http.Redirect(w, r, "/", http.StatusFound)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue