155 lines
5.0 KiB
Go
155 lines
5.0 KiB
Go
package handlers
|
|
|
|
import (
|
|
"net/http"
|
|
"strconv"
|
|
"time"
|
|
|
|
"go-crm/internal/db"
|
|
|
|
"github.com/go-chi/chi/v5"
|
|
)
|
|
|
|
func ListClients(w http.ResponseWriter, r *http.Request) {
|
|
limit, _ := strconv.Atoi(r.URL.Query().Get("limit"))
|
|
offset, _ := strconv.Atoi(r.URL.Query().Get("offset"))
|
|
if limit == 0 {
|
|
limit = 20
|
|
}
|
|
|
|
clients, err := db.ListClients(DB, limit, offset)
|
|
if err != nil {
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "text/html")
|
|
w.Write([]byte(`<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>Clients</title>
|
|
<script src="https://unpkg.com/htmx.org@1.9.10"></script>
|
|
<style>
|
|
.edit-form { display:none; margin-top:0.5rem; padding:0.5rem; border:1px solid #ccc; }
|
|
.edit-row { display:none; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<h1>Clients</h1>
|
|
<button class="btn" onclick="document.getElementById('clientForm').style.display='block'">Add Client</button>
|
|
<div id="clientForm" style="display:none; margin-top:1rem;">
|
|
<form hx-post="/clients" hx-target="#clientList" hx-swap="innerHTML">
|
|
<input type="text" name="name" placeholder="Name" required>
|
|
<input type="tel" name="phone" placeholder="Phone">
|
|
<input type="email" name="email" placeholder="Email">
|
|
<input type="text" name="address" placeholder="Address">
|
|
<textarea name="notes" placeholder="Notes"></textarea>
|
|
<button type="submit">Add Client</button>
|
|
</form>
|
|
</div>
|
|
<table>
|
|
<thead>
|
|
<tr><th>Name</th><th>Phone</th><th>Email</th><th>Actions</th></tr>
|
|
</thead>
|
|
<tbody id="clientList">
|
|
`))
|
|
for _, c := range clients {
|
|
w.Write([]byte(`<tr>
|
|
<td>` + c.Name + `</td>
|
|
<td>` + c.Phone + `</td>
|
|
<td>` + c.Email + `</td>
|
|
<td>
|
|
<a href="/clients/` + strconv.FormatInt(c.ClientID, 10) + `">View</a>
|
|
<button type="button" onclick="document.getElementById('editForm` + strconv.FormatInt(c.ClientID, 10) + `').style.display='block'">Edit</button>
|
|
<form method="DELETE" style="display:inline" hx-delete="/clients/` + strconv.FormatInt(c.ClientID, 10) + `" hx-target="closest tr">
|
|
<button type="submit">Delete</button>
|
|
</form>
|
|
<tr id="editForm` + strconv.FormatInt(c.ClientID, 10) + `" class="edit-row"><td colspan="4">
|
|
<form hx-put="/clients/` + strconv.FormatInt(c.ClientID, 10) + `" hx-target="#clientList" hx-swap="innerHTML">
|
|
<input type="text" name="name" value="` + c.Name + `">
|
|
<input type="tel" name="phone" value="` + c.Phone + `">
|
|
<input type="email" name="email" value="` + c.Email + `">
|
|
<input type="text" name="address" value="` + c.Address + `">
|
|
<textarea name="notes">` + c.Notes + `</textarea>
|
|
<button type="submit">Save</button>
|
|
</form>
|
|
</td></tr>
|
|
</td>
|
|
</tr>`))
|
|
}
|
|
w.Write([]byte(`</tbody></table></body></html>`))
|
|
}
|
|
|
|
func CreateClient(w http.ResponseWriter, r *http.Request) {
|
|
r.ParseForm()
|
|
client := db.Client{
|
|
Name: r.FormValue("name"),
|
|
Phone: r.FormValue("phone"),
|
|
Email: r.FormValue("email"),
|
|
Address: r.FormValue("address"),
|
|
Notes: r.FormValue("notes"),
|
|
CreatedAt: time.Now().Unix(),
|
|
}
|
|
|
|
if err := client.Create(DB); err != nil {
|
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "text/html")
|
|
w.Header().Set("HX-Refresh", "true")
|
|
}
|
|
|
|
func ViewClient(w http.ResponseWriter, r *http.Request) {
|
|
id, _ := strconv.ParseInt(chi.URLParam(r, "id"), 10, 64)
|
|
client, err := db.GetClientByID(DB, id)
|
|
if err != nil {
|
|
http.Error(w, "Client not found", http.StatusNotFound)
|
|
return
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "text/html")
|
|
w.Write([]byte(`<!DOCTYPE html>
|
|
<html>
|
|
<head></head>
|
|
<body>
|
|
<h1>` + client.Name + `</h1>
|
|
<p>Client ID: ` + strconv.FormatInt(client.ClientID, 10) + `</p>
|
|
<p>Phone: ` + client.Phone + `</p>
|
|
<p>Email: ` + client.Email + `</p>
|
|
<p>Address: ` + client.Address + `</p>
|
|
<p>Notes: ` + client.Notes + `</p>
|
|
<a href="/clients">Back</a>
|
|
</body></html>`))
|
|
}
|
|
|
|
func UpdateClient(w http.ResponseWriter, r *http.Request) {
|
|
id, _ := strconv.ParseInt(chi.URLParam(r, "id"), 10, 64)
|
|
r.ParseForm()
|
|
client := db.Client{
|
|
ClientID: id,
|
|
Name: r.FormValue("name"),
|
|
Phone: r.FormValue("phone"),
|
|
Email: r.FormValue("email"),
|
|
Address: r.FormValue("address"),
|
|
Notes: r.FormValue("notes"),
|
|
}
|
|
|
|
if err := client.Update(DB); err != nil {
|
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
w.Header().Set("HX-Refresh", "true")
|
|
}
|
|
|
|
func DeleteClient(w http.ResponseWriter, r *http.Request) {
|
|
id, _ := strconv.ParseInt(chi.URLParam(r, "id"), 10, 64)
|
|
if err := (&db.Client{}).Delete(DB, id); err != nil {
|
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "text/html")
|
|
w.Write([]byte("OK"))
|
|
} |