|
@@ -2,9 +2,11 @@ package main
|
|
|
|
|
|
import (
|
|
|
"errors"
|
|
|
+ "fmt"
|
|
|
"html/template"
|
|
|
"log"
|
|
|
"net/http"
|
|
|
+ "sync"
|
|
|
|
|
|
"github.com/masterminds/sprig"
|
|
|
)
|
|
@@ -15,6 +17,11 @@ const (
|
|
|
|
|
|
type data map[string]any
|
|
|
|
|
|
+var (
|
|
|
+ flashMessage string
|
|
|
+ flashMX sync.Mutex
|
|
|
+)
|
|
|
+
|
|
|
|
|
|
@app.route("/")
|
|
|
def index():
|
|
@@ -33,7 +40,7 @@ func contacts(cs *ContactsStore) http.HandlerFunc {
|
|
|
)
|
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
|
search := r.URL.Query().Get("q")
|
|
|
- var contacts_set []Contact
|
|
|
+ var contacts_set []*Contact
|
|
|
if search == "" {
|
|
|
contacts_set = cs.GetAll()
|
|
|
} else {
|
|
@@ -50,9 +57,6 @@ func contacts(cs *ContactsStore) http.HandlerFunc {
|
|
|
|
|
|
|
|
|
@app.route("/contacts/new", methods=['GET']) (1)
|
|
|
-def contacts_new_get():
|
|
|
-
|
|
|
- return render_template("new.html", contact=Contact()
|
|
|
*/
|
|
|
func contactsNewGet(cs *ContactsStore) http.HandlerFunc {
|
|
|
tpl := makeTemplate(
|
|
@@ -60,20 +64,67 @@ func contactsNewGet(cs *ContactsStore) http.HandlerFunc {
|
|
|
"new",
|
|
|
)
|
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
|
- c := cs.New()
|
|
|
- if err := tpl.ExecuteTemplate(w, "layout.html", c); err != nil {
|
|
|
+ contact := cs.New(nil)
|
|
|
+ if err := tpl.ExecuteTemplate(w, "layout.html", contact); err != nil {
|
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+@app.route("/contacts/new", methods=['POST'])
|
|
|
+*/
|
|
|
+func contactsNew(cs *ContactsStore) http.HandlerFunc {
|
|
|
+ tpl := makeTemplate(
|
|
|
+ "layout",
|
|
|
+ "new",
|
|
|
+ )
|
|
|
+ return func(w http.ResponseWriter, r *http.Request) {
|
|
|
+ contact := cs.New(map[string]string{
|
|
|
+ "first": r.PostFormValue("first_name"),
|
|
|
+ "last": r.PostFormValue("last_name"),
|
|
|
+ "phone": r.PostFormValue("phone"),
|
|
|
+ "email": r.PostFormValue("email"),
|
|
|
+ })
|
|
|
+ if err := cs.Save(contact); err != nil {
|
|
|
+ flash(fmt.Sprintf("Error saving contact: %v", err))
|
|
|
+ if err := tpl.ExecuteTemplate(w, "layout.html", contact); err != nil {
|
|
|
+ http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ flash("Created New Contact!")
|
|
|
+ http.Redirect(w, r, "/contacts", http.StatusSeeOther)
|
|
|
+ return
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+func flash(newFlash string) {
|
|
|
+ flashMX.Lock()
|
|
|
+ defer flashMX.Unlock()
|
|
|
+ flashMessage += newFlash
|
|
|
+}
|
|
|
+
|
|
|
+func getFlash() string {
|
|
|
+ flashMX.Lock()
|
|
|
+ defer flashMX.Unlock()
|
|
|
+ previousFlash := flashMessage
|
|
|
+ flashMessage = ""
|
|
|
+ return previousFlash
|
|
|
+}
|
|
|
+
|
|
|
func makeTemplate(first string, others ...string) *template.Template {
|
|
|
paths := append([]string{first}, others...)
|
|
|
for i, path := range paths {
|
|
|
paths[i] = "./templates/" + path + ".gohtml"
|
|
|
}
|
|
|
- tpl := template.Must(template.ParseFiles(paths...)).
|
|
|
- Funcs(sprig.FuncMap())
|
|
|
+ tpl := template.Must(
|
|
|
+ template.New(first).
|
|
|
+ Funcs(sprig.FuncMap()).
|
|
|
+ Funcs(template.FuncMap{"flash": getFlash}).
|
|
|
+ ParseFiles(paths...))
|
|
|
return tpl
|
|
|
}
|
|
|
|
|
@@ -85,6 +136,7 @@ func setupRoutes(mux *http.ServeMux, cs *ContactsStore) {
|
|
|
mux.Handle("GET /static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./static"))))
|
|
|
mux.Handle("GET /contacts", contacts(cs))
|
|
|
mux.Handle("GET /contacts/new", contactsNewGet(cs))
|
|
|
+ mux.Handle("POST /contacts/new", contactsNew(cs))
|
|
|
}
|
|
|
|
|
|
func main() {
|