Skip to content

Commit

Permalink
implemented poiView with htmx-get
Browse files Browse the repository at this point in the history
  • Loading branch information
crmejia committed Aug 23, 2023
1 parent dd5705f commit af480b6
Show file tree
Hide file tree
Showing 9 changed files with 128 additions and 30 deletions.
60 changes: 51 additions & 9 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func (s *Server) HandleGuides() http.HandlerFunc {
}

if r.Header.Get("HX-Trigger") == "search" {
err = s.templateRegistry.renderPartial(w, rowsTemplate, guides)
err = s.templateRegistry.renderPartial(w, guideRowsTemplate, guides)
if err != nil {
http.Error(w, "internal server error", http.StatusInternalServerError)
}
Expand Down Expand Up @@ -280,6 +280,45 @@ func (s *Server) HandleDeleteGuide() http.HandlerFunc {
}
}

func (s *Server) HandlePoi() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
guideIDString := mux.Vars(r)["guideID"]
if guideIDString == "" {
http.Error(w, "no guide ID provided", http.StatusBadRequest)
return
}
poiIDString := mux.Vars(r)["poiID"]
if poiIDString == "" {
http.Error(w, "no poi ID provided", http.StatusBadRequest)
return
}
guideID, err := strconv.ParseInt(guideIDString, 10, 64)
if err != nil {
http.Error(w, "not able to parse guide ID", http.StatusBadRequest)
return
}
poiID, err := strconv.ParseInt(poiIDString, 10, 64)
if err != nil {
http.Error(w, "not able to parse poi ID", http.StatusBadRequest)
return
}

poi, err := s.store.GetPoi(guideID, poiID)
if err != nil {
http.Error(w, "internal server error", http.StatusInternalServerError)
return
}
if poi == nil {
http.Error(w, "point of interest not found", http.StatusNotFound)
return
}

err = s.templateRegistry.renderPartial(w, poiViewTemplate, poi)
if err != nil {
http.Error(w, "internal server error", http.StatusInternalServerError)
}
}
}
func (s *Server) HandleCreatePoiGet() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
guideID := mux.Vars(r)["id"]
Expand Down Expand Up @@ -374,7 +413,7 @@ func (s *Server) HandleDeletePoi() http.HandlerFunc {
http.Error(w, "no guide ID provided", http.StatusBadRequest)
return
}
poiIDString := mux.Vars(r)["id"]
poiIDString := mux.Vars(r)["poiID"]
if poiIDString == "" {
http.Error(w, "no poi ID provided", http.StatusBadRequest)
return
Expand Down Expand Up @@ -447,9 +486,10 @@ func (s *Server) Routes() http.Handler {
router.HandleFunc("/guide/{id}/edit", s.HandleEditGuidePost()).Methods(http.MethodPost)

//POI *-> guide
router.HandleFunc("/guide/poi/create/{id}", s.HandleCreatePoiGet()).Methods(http.MethodGet)
router.HandleFunc("/guide/poi/create/{id}", s.HandleCreatePoiPost()).Methods(http.MethodPost)
router.HandleFunc("/guide/{guideID}/poi/{id}", s.HandleDeletePoi()).Methods(http.MethodDelete)
router.HandleFunc("/guide/{id}/poi/create", s.HandleCreatePoiGet()).Methods(http.MethodGet)
router.HandleFunc("/guide/{id}/poi/create", s.HandleCreatePoiPost()).Methods(http.MethodPost)
router.HandleFunc("/guide/{guideID}/poi/{poiID}", s.HandlePoi()).Methods(http.MethodGet)
router.HandleFunc("/guide/{guideID}/poi/{poiID}", s.HandleDeletePoi()).Methods(http.MethodDelete)
router.HandleFunc("/", HandleIndex())
return router
}
Expand All @@ -460,9 +500,9 @@ func templateRoutes() *templateRegistry {

//todo iterate over template dir
for _, templateName := range []string{indexTemplate, guideTemplate, createGuideFormTemplate, editGuideFormTemplate, createPoiFormTemplate} {
pageTemplates[templateName] = template.Must(template.ParseFS(fs, templatesDir+templateName, templatesDir+baseTemplate, templatesDir+rowsTemplate))
pageTemplates[templateName] = template.Must(template.ParseFS(fs, templatesDir+templateName, templatesDir+baseTemplate, templatesDir+guideRowsTemplate, templatesDir+poiRowsTemplate))
}
for _, templateName := range []string{rowsTemplate} {
for _, templateName := range []string{guideRowsTemplate, poiViewTemplate} {
partialTemplates[templateName] = template.Must(template.ParseFS(fs, templatesDir+templateName))
}

Expand Down Expand Up @@ -496,7 +536,7 @@ func (t *templateRegistry) renderPartial(w io.Writer, templateFile string, data
tmpl, ok := t.partialTemplates[templateFile]
if ok {
return tmpl.Execute(w, data)
//return tmpl.ExecuteTemplate(w, rowsTemplate, data)
//return tmpl.ExecuteTemplate(w, guideRowsTemplate, data)
}
return errors.New("Template not found ->" + templateFile)
}
Expand All @@ -505,9 +545,11 @@ const (
templatesDir = "templates/"
baseTemplate = "base.html"
indexTemplate = "index.html"
rowsTemplate = "rows.html"
guideRowsTemplate = "guideRows.html"
poiRowsTemplate = "poiRows.html"
guideTemplate = "guide.html"
createGuideFormTemplate = "createGuideForm.html"
editGuideFormTemplate = "editGuideForm.html"
createPoiFormTemplate = "createPoiForm.html"
poiViewTemplate = "poiView.html"
)
46 changes: 43 additions & 3 deletions server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,35 @@ func TestDeleteGuideHandlerDeletesGuide(t *testing.T) {
}
}

func TestPoiHandlerRendersView(t *testing.T) {
t.Parallel()
server := newProvisionedServer(t)
rec := httptest.NewRecorder()
req := httptest.NewRequest(http.MethodGet, "/", nil)
req = mux.SetURLVars(req, map[string]string{
"guideID": "1",
"poiID": "1",
})

handler := server.HandlePoi()
handler(rec, req)

result := rec.Result()
if result.StatusCode != http.StatusOK {
t.Errorf("expected status 200 OK, body %d", result.StatusCode)
}
body, err := io.ReadAll(result.Body)
if err != nil {
t.Fatal(err)
}
want := "test 1"
got := string(body)
if !strings.Contains(got, want) {
t.Errorf("want result to contain %s\nGot:\n%s", want, got)

}
}

func TestCreatePoiHandlerGetRendersForm(t *testing.T) {
t.Parallel()
s := openTmpStorage(t)
Expand Down Expand Up @@ -477,7 +506,7 @@ func TestCreatePoiHandlerGetRendersForm(t *testing.T) {
}
}

// TODO {"/guide/poi/create/1", http.StatusNotFound, "guide not found"},
// TODO {"/guide/poi/create/1", http.StatusNotFound, "guide not found"}, test poi create on non-existing guide id
func TestCreatePoiHandlerErrors(t *testing.T) {
t.Parallel()
testCases := []struct {
Expand Down Expand Up @@ -771,15 +800,26 @@ func openTmpStorage(t *testing.T) guide.Storage {
func newProvisionedServer(t *testing.T) *guide.Server {
storage := openTmpStorage(t)
input := []string{"test 1", "guide 1", "test 2"}
for _, name := range input {
g, err := guide.NewGuide(name, guide.WithValidStringCoordinates("10", "10"))
for _, guideName := range input {
g, err := guide.NewGuide(guideName, guide.WithValidStringCoordinates("10", "10"))
if err != nil {
t.Fatal(err)
}
err = storage.CreateGuide(&g)
if err != nil {
t.Fatal(err)
}
for _, poiName := range input {
p, err := guide.NewPointOfInterest(poiName, g.Id, guide.PoiWithValidStringCoordinates("10", "10"))
if err != nil {
t.Fatal(err)
}

err = storage.CreatePoi(&p)
if err != nil {
t.Fatal(err)
}
}
}

freePort, err := freeport.GetFreePort()
Expand Down
2 changes: 1 addition & 1 deletion store.go
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ func (s *sqliteStore) GetAllPois(guideId int64) []pointOfInterest {
}

func (s *sqliteStore) Search(query string) ([]guide, error) {
rows, err := s.db.Query(searchGuides, query+"%")
rows, err := s.db.Query(searchGuides, "%"+query+"%")
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion templates/createPoiForm.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<p class="message-body"> {{ . }}</p>
{{end}}
</article>
<form class="form" action="/guide/poi/create/{{.GuideID}}" method="post">
<form class="form" action="/guide/{{.GuideID}}/poi/create" method="post">
<fieldset>
<legend>POI Values</legend>
<input type="hidden" name="gid" value="{{.GuideID}}">
Expand Down
26 changes: 12 additions & 14 deletions templates/guide.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

{{define "mapscript"}}
<!-- ---------------------------->
<!--TODO template this script-->
<!--TODO move to another file-->
<!-- ---------------------------->
<script>
let map = L.map('map').setView([{{.Coordinate.Latitude}}, {{.Coordinate.Longitude}}], 15);
Expand All @@ -27,9 +27,12 @@
Delete Guide
</button>
<p class="content"> {{.Description}}</p>
<p class="content">Lat: {{.Coordinate.Latitude}}, Lon:{{.Coordinate.Longitude}}</p>
<div id="map" style="width: 600px; height: 400px;">
{{template "mapscript" .}}
</div>
<div class="columns">
<div class="column">
<table class="table">
<thead>
<tr>
Expand All @@ -38,22 +41,17 @@
</tr>
</thead>
<tbody>
{{range .Pois}}
<tr>
<td> {{.Name}}</td>
<td>{{.Description}}</td>
<td>
<a href="#">Edit</a>
<a href="#" hx-delete="/guide/{{.GuideID}}/poi/{{.Id}}" hx-swap="outerHTML swap:1s" hx-confirm="Are you sure you want to delete this poi?" hx-target="closest tr">Delete</a>
</td>
</tr>
{{end}}
{{template "poiRows.html" .}}
</tbody>
</table>
<div>
<a href="/guide/poi/create/{{.Id}}"> Add Poi</a>
<a href="/guides">back</a>
</div>
<div class="column" id="poi-focus">
</div>
</div>
<p>
<a class="button" href="/guide/{{.Id}}/poi/create">Add Poi</a>
<a href="/guides">back</a>
</p>
</body>
</html>
{{end}}
2 changes: 1 addition & 1 deletion templates/rows.html → templates/guideRows.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{{define "rows.html"}}
{{define "guideRows.html"}}
{{range .}}
<tr>
<td><a href="/guide/{{.Id}}">{{.Name}}</td>
Expand Down
2 changes: 1 addition & 1 deletion templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
</tr>
</thead>
<tbody id="search-results">
{{template "rows.html" .}}
{{template "guideRows.html" .}}
</tbody>
</table>
<p class="content">
Expand Down
13 changes: 13 additions & 0 deletions templates/poiRows.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{{define "poiRows.html"}}
{{range .Pois}}
<tr>
<td><a href="#" hx-get="/guide/{{.GuideID}}/poi/{{.Id}}" hx-target="#poi-focus">{{.Name}}</a></td>
<td>{{.Description}}</td>
<td>
<a href="#">Edit</a>
<a href="#" hx-delete="/guide/{{.GuideID}}/poi/{{.Id}}" hx-swap="outerHTML swap:1s"
hx-confirm="Are you sure you want to delete this poi?" hx-target="closest tr">Delete</a>
</td>
</tr>
{{end}}
{{end}}
5 changes: 5 additions & 0 deletions templates/poiView.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{{define "poiView.html"}}
<strong class="content">{{.Name}}</strong>
<p class="content">{{.Description}}</p>
<p class="content">Lat: {{.Coordinate.Latitude}}, Lon:{{.Coordinate.Longitude}}</p>
{{end}}

0 comments on commit af480b6

Please sign in to comment.