minimum viable
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -4,3 +4,4 @@ app
|
|||||||
*.out
|
*.out
|
||||||
tmp
|
tmp
|
||||||
output.css
|
output.css
|
||||||
|
example.db
|
||||||
|
|||||||
@@ -4,9 +4,6 @@ Example CRUD app written in Go + HTMX + Tailwind CSS
|
|||||||
|
|
||||||
This project implements a pure dynamic web app with SPA-like features but without heavy complex Javascript or Go frameworks to keep up with. Just HTML/CSS + Go ❤️
|
This project implements a pure dynamic web app with SPA-like features but without heavy complex Javascript or Go frameworks to keep up with. Just HTML/CSS + Go ❤️
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
|
|
||||||
## Develop
|
## Develop
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
-- CREATE DATABASE IF NOT EXISTS inventory;
|
|
||||||
-- USE inventory;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS items (
|
CREATE TABLE IF NOT EXISTS items (
|
||||||
ID INTEGER PRIMARY KEY,
|
ID INTEGER PRIMARY KEY,
|
||||||
Name TEXT NOT NULL,
|
Name TEXT NOT NULL UNIQUE,
|
||||||
Notes TEXT,
|
Notes TEXT,
|
||||||
Description TEXT,
|
Description TEXT,
|
||||||
Stage INTEGER,
|
Stage INTEGER,
|
||||||
@@ -12,7 +9,7 @@ CREATE TABLE IF NOT EXISTS items (
|
|||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS boxes (
|
CREATE TABLE IF NOT EXISTS boxes (
|
||||||
ID INTEGER PRIMARY KEY,
|
ID INTEGER PRIMARY KEY,
|
||||||
Name TEXT NOT NULL,
|
Name TEXT NOT NULL UNIQUE,
|
||||||
Notes TEXT,
|
Notes TEXT,
|
||||||
Description TEXT,
|
Description TEXT,
|
||||||
Stage INTEGER,
|
Stage INTEGER,
|
||||||
@@ -20,7 +17,7 @@ CREATE TABLE IF NOT EXISTS boxes (
|
|||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS boxitems (
|
CREATE TABLE IF NOT EXISTS boxitems (
|
||||||
ItemID INTEGER,
|
ItemID INTEGER UNIQUE, -- items can only exist in a single box
|
||||||
BoxID INTEGER,
|
BoxID INTEGER,
|
||||||
PRIMARY KEY (ItemID, BoxID),
|
PRIMARY KEY (ItemID, BoxID),
|
||||||
FOREIGN KEY (ItemID) REFERENCES items(ID),
|
FOREIGN KEY (ItemID) REFERENCES items(ID),
|
||||||
|
|||||||
BIN
example.db
BIN
example.db
Binary file not shown.
12
main.go
12
main.go
@@ -46,14 +46,14 @@ func main() {
|
|||||||
router := http.NewServeMux()
|
router := http.NewServeMux()
|
||||||
// router.Handle("/css/output.css", http.FileServer(http.FS(css)))
|
// router.Handle("/css/output.css", http.FileServer(http.FS(css)))
|
||||||
|
|
||||||
router.Handle("/company/add", web.Action(companyAdd))
|
// router.Handle("/company/add", web.Action(companyAdd))
|
||||||
router.Handle("/company/add/", web.Action(companyAdd))
|
// router.Handle("/company/add/", web.Action(companyAdd))
|
||||||
|
|
||||||
router.Handle("/company/edit", web.Action(companyEdit))
|
// router.Handle("/company/edit", web.Action(companyEdit))
|
||||||
router.Handle("/company/edit/", web.Action(companyEdit))
|
// router.Handle("/company/edit/", web.Action(companyEdit))
|
||||||
|
|
||||||
router.Handle("/company", web.Action(companies))
|
// router.Handle("/company", web.Action(companies))
|
||||||
router.Handle("/company/", web.Action(companies))
|
// router.Handle("/company/", web.Action(companies))
|
||||||
|
|
||||||
router.Handle("/", web.Action(index))
|
router.Handle("/", web.Action(index))
|
||||||
router.Handle("/index.html", web.Action(index))
|
router.Handle("/index.html", web.Action(index))
|
||||||
|
|||||||
71
routes.go
71
routes.go
@@ -7,16 +7,6 @@ import (
|
|||||||
"github.com/jritsema/gotoolbox/web"
|
"github.com/jritsema/gotoolbox/web"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Delete -> DELETE /company/{id} -> delete, companys.html
|
|
||||||
|
|
||||||
// Edit -> GET /company/edit/{id} -> row-edit.html
|
|
||||||
// Save -> PUT /company/{id} -> update, row.html
|
|
||||||
// Cancel -> GET /company/{id} -> nothing, row.html
|
|
||||||
|
|
||||||
// Add -> GET /company/add/ -> companys-add.html (target body with row-add.html and row.html)
|
|
||||||
// Save -> POST /company -> add, companys.html (target body without row-add.html)
|
|
||||||
// Cancel -> GET /company -> nothing, companys.html
|
|
||||||
|
|
||||||
func index(r *http.Request) *web.Response {
|
func index(r *http.Request) *web.Response {
|
||||||
result, err := db.GetAllItems()
|
result, err := db.GetAllItems()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -25,64 +15,3 @@ func index(r *http.Request) *web.Response {
|
|||||||
|
|
||||||
return web.HTML(http.StatusOK, html, "index.html", result, nil)
|
return web.HTML(http.StatusOK, html, "index.html", result, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// GET /company/add
|
|
||||||
func companyAdd(r *http.Request) *web.Response {
|
|
||||||
return web.HTML(http.StatusOK, html, "company-add.html", data, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// /GET company/edit/{id}
|
|
||||||
func companyEdit(r *http.Request) *web.Response {
|
|
||||||
id, _ := web.PathLast(r)
|
|
||||||
row := getCompanyByID(id)
|
|
||||||
return web.HTML(http.StatusOK, html, "row-edit.html", row, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GET /company
|
|
||||||
// GET /company/{id}
|
|
||||||
// DELETE /company/{id}
|
|
||||||
// PUT /company/{id}
|
|
||||||
// POST /company
|
|
||||||
func companies(r *http.Request) *web.Response {
|
|
||||||
id, segments := web.PathLast(r)
|
|
||||||
switch r.Method {
|
|
||||||
|
|
||||||
case http.MethodDelete:
|
|
||||||
deleteCompany(id)
|
|
||||||
return web.HTML(http.StatusOK, html, "companies.html", data, nil)
|
|
||||||
|
|
||||||
//cancel
|
|
||||||
case http.MethodGet:
|
|
||||||
if segments > 1 {
|
|
||||||
//cancel edit
|
|
||||||
row := getCompanyByID(id)
|
|
||||||
return web.HTML(http.StatusOK, html, "row.html", row, nil)
|
|
||||||
} else {
|
|
||||||
//cancel add
|
|
||||||
return web.HTML(http.StatusOK, html, "companies.html", data, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
//save edit
|
|
||||||
case http.MethodPut:
|
|
||||||
row := getCompanyByID(id)
|
|
||||||
r.ParseForm()
|
|
||||||
row.Company = r.Form.Get("company")
|
|
||||||
row.Contact = r.Form.Get("contact")
|
|
||||||
row.Country = r.Form.Get("country")
|
|
||||||
updateCompany(row)
|
|
||||||
return web.HTML(http.StatusOK, html, "row.html", row, nil)
|
|
||||||
|
|
||||||
//save add
|
|
||||||
case http.MethodPost:
|
|
||||||
row := Company{}
|
|
||||||
r.ParseForm()
|
|
||||||
row.Company = r.Form.Get("company")
|
|
||||||
row.Contact = r.Form.Get("contact")
|
|
||||||
row.Country = r.Form.Get("country")
|
|
||||||
addCompany(row)
|
|
||||||
return web.HTML(http.StatusOK, html, "companies.html", data, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
return web.Empty(http.StatusNotImplemented)
|
|
||||||
}
|
|
||||||
|
|||||||
BIN
screenshot.jpeg
BIN
screenshot.jpeg
Binary file not shown.
|
Before Width: | Height: | Size: 108 KiB |
@@ -1,31 +1,8 @@
|
|||||||
<tr id="datarow-{{.ID}}" class="border-b dark:border-neutral-500">
|
<tr id="datarow-{{.ID}}" class="border-b dark:border-neutral-500">
|
||||||
<td class="whitespace-nowrap px-6 py-4">{{.ID}}</td>
|
<td class="whitespace-nowrap px-6 py-4">{{.ID}}</td>
|
||||||
<td class="whitespace-nowrap px-6 py-4">{{.Name}}</td>
|
<td class="whitespace-nowrap px-6 py-4">{{.Name}}</td>
|
||||||
<td class="whitespace-nowrap px-6 py-4">{{.Stage}}</td>
|
<td class="whitespace-nowrap px-6 py-4">{{.Stage}}</td>
|
||||||
<td class="whitespace-nowrap px-6 py-4">{{.Category}}</td>
|
<td class="whitespace-nowrap px-6 py-4">{{.Category}}</td>
|
||||||
<td class="whitespace-nowrap px-6 py-4">{{.Description}}</td>
|
<td class="whitespace-nowrap px-6 py-4">{{.Description}}</td>
|
||||||
<td class="whitespace-nowrap px-6 py-4">{{.Notes}}</td>
|
<td class="whitespace-nowrap px-6 py-4">{{.Notes}}</td>
|
||||||
<!-- <td class="whitespace-nowrap px-1 py-1">
|
</tr>
|
||||||
<a
|
|
||||||
hx-get="/company/edit/{{.ID}}"
|
|
||||||
hx-target="#datarow-{{.ID}}"
|
|
||||||
hx-swap="outerHTML"
|
|
||||||
hx-indicator="#processing"
|
|
||||||
class="hover:underline text-blue-700"
|
|
||||||
href=""
|
|
||||||
>
|
|
||||||
Edit
|
|
||||||
</a>
|
|
||||||
</td> -->
|
|
||||||
<!-- <td class="whitespace-nowrap px-1 py-1">
|
|
||||||
<a
|
|
||||||
hx-delete="/company/{{.ID}}"
|
|
||||||
hx-target="#companies"
|
|
||||||
hx-confirm="Are you sure you want to delete {{.Company}}?"
|
|
||||||
hx-indicator="#processing"
|
|
||||||
class="hover:underline text-blue-700"
|
|
||||||
href=""
|
|
||||||
>Delete</a
|
|
||||||
>
|
|
||||||
</td> -->
|
|
||||||
</tr>
|
|
||||||
|
|||||||
Reference in New Issue
Block a user