diff --git a/frontend/src/components/HelloWorld.vue b/frontend/src/components/HelloWorld.vue
deleted file mode 100644
index f91553d..0000000
--- a/frontend/src/components/HelloWorld.vue
+++ /dev/null
@@ -1,95 +0,0 @@
-
-
-
-
-
-
-
Get started
-
Edit src/App.vue and save to test HMR
-
-
-
-
-
-
-
-
-
-
Documentation
-
Your questions, answered
-
-
-
-
-
Connect with us
-
Join the Vite community
-
-
-
-
-
-
-
diff --git a/frontend/src/components/TargetManager.vue b/frontend/src/components/TargetManager.vue
index 2b65f21..ad1720c 100644
--- a/frontend/src/components/TargetManager.vue
+++ b/frontend/src/components/TargetManager.vue
@@ -26,7 +26,10 @@
+
@@ -61,6 +64,7 @@
{{ target.last_scan_at ? new Date(target.last_scan_at).toLocaleString() : 'Never' }}
+
|
@@ -79,7 +83,8 @@
import { ref, onMounted } from 'vue'
const targets = ref([])
-const form = ref({ name: '', address: '', schedule: 'manual', customSchedule: '' })
+const form = ref({ id: null, name: '', address: '', schedule: 'manual', customSchedule: '' })
+const isEditing = ref(false)
const loadTargets = async () => {
try {
@@ -101,19 +106,58 @@ const addTarget = async () => {
}
}
- await fetch('/api/targets', {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify({
- name: form.value.name,
- address: form.value.address,
- schedule: finalSchedule
+ if (isEditing.value) {
+ await fetch(`/api/targets/${form.value.id}`, {
+ method: 'PUT',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({
+ name: form.value.name,
+ address: form.value.address,
+ schedule: finalSchedule
+ })
})
- })
- form.value = { name: '', address: '', schedule: 'manual', customSchedule: '' }
+ } else {
+ await fetch('/api/targets', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({
+ name: form.value.name,
+ address: form.value.address,
+ schedule: finalSchedule
+ })
+ })
+ }
+
+ cancelEdit()
loadTargets()
}
+const editTarget = (target) => {
+ isEditing.value = true
+ let sched = target.schedule
+ let custom = ''
+
+ if (['manual', '@midnight', '@hourly', '0 0 * * 0'].includes(sched)) {
+ // Standard schedule
+ } else {
+ custom = sched
+ sched = 'custom'
+ }
+
+ form.value = {
+ id: target.id,
+ name: target.name,
+ address: target.address,
+ schedule: sched,
+ customSchedule: custom
+ }
+}
+
+const cancelEdit = () => {
+ isEditing.value = false
+ form.value = { id: null, name: '', address: '', schedule: 'manual', customSchedule: '' }
+}
+
const deleteTarget = async (id) => {
if (!confirm('Delete target?')) return
await fetch(`/api/targets/${id}`, { method: 'DELETE' })
diff --git a/internal/api/handlers.go b/internal/api/handlers.go
index 0e687dd..d71a0c9 100644
--- a/internal/api/handlers.go
+++ b/internal/api/handlers.go
@@ -18,6 +18,7 @@ func RegisterRoutes(mux *http.ServeMux) {
mux.HandleFunc("GET /api/targets", AuthMiddleware(getTargets))
mux.HandleFunc("POST /api/targets", AuthMiddleware(createTarget))
+ mux.HandleFunc("PUT /api/targets/{id}", AuthMiddleware(updateTarget))
mux.HandleFunc("DELETE /api/targets/{id}", AuthMiddleware(deleteTarget))
mux.HandleFunc("POST /api/targets/{id}/scan", AuthMiddleware(triggerScan))
mux.HandleFunc("GET /api/scans", AuthMiddleware(getScans))
@@ -65,6 +66,33 @@ func createTarget(w http.ResponseWriter, r *http.Request) {
json.NewEncoder(w).Encode(t)
}
+func updateTarget(w http.ResponseWriter, r *http.Request) {
+ idStr := r.PathValue("id")
+ id, err := strconv.Atoi(idStr)
+ if err != nil {
+ http.Error(w, "invalid id", http.StatusBadRequest)
+ return
+ }
+
+ var t models.Target
+ if err := json.NewDecoder(r.Body).Decode(&t); err != nil {
+ http.Error(w, err.Error(), http.StatusBadRequest)
+ return
+ }
+
+ _, err = db.DB.Exec("UPDATE targets SET name = ?, address = ?, schedule = ? WHERE id = ?", t.Name, t.Address, t.Schedule, id)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ scheduler.ReloadScheduler()
+
+ w.Header().Set("Content-Type", "application/json")
+ t.ID = id
+ json.NewEncoder(w).Encode(t)
+}
+
func deleteTarget(w http.ResponseWriter, r *http.Request) {
idStr := r.PathValue("id")
id, err := strconv.Atoi(idStr)
Connect with us
-Join the Vite community
---
-
-
- GitHub
-
-
- -
-
-
- Discord
-
-
- -
-
-
- X.com
-
-
- -
-
-
- Bluesky
-
-
-
-