diff --git a/internal/handler/deals.go b/internal/handler/deals.go
index 1c7f6df..da05cd9 100644
--- a/internal/handler/deals.go
+++ b/internal/handler/deals.go
@@ -302,6 +302,83 @@ func (h *Handler) handleFolderReorder(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/deals/"+dealID, http.StatusSeeOther)
}
+func (h *Handler) handleDealSearch(w http.ResponseWriter, r *http.Request) {
+ // /deals/search/{dealID}?q=...
+ dealID := strings.TrimPrefix(r.URL.Path, "/deals/search/")
+ q := r.URL.Query().Get("q")
+
+ if q == "" {
+ w.Write([]byte(`
Type to search files, folders, and requests.
`))
+ return
+ }
+
+ pattern := "%" + q + "%"
+ w.Header().Set("Content-Type", "text/html")
+
+ html := ``
+
+ // Search files
+ rows, _ := h.db.Query("SELECT id, name, folder_id FROM files WHERE deal_id = ? AND name LIKE ?", dealID, pattern)
+ if rows != nil {
+ hasFiles := false
+ for rows.Next() {
+ if !hasFiles {
+ html += `
Files
`
+ hasFiles = true
+ }
+ var id, name, folderID string
+ rows.Scan(&id, &name, &folderID)
+ html += fmt.Sprintf(`
`, id, name)
+ }
+ rows.Close()
+ }
+
+ // Search folders
+ rows2, _ := h.db.Query("SELECT id, name FROM folders WHERE deal_id = ? AND name LIKE ?", dealID, pattern)
+ if rows2 != nil {
+ hasFolders := false
+ for rows2.Next() {
+ if !hasFolders {
+ html += `
Folders
`
+ hasFolders = true
+ }
+ var id, name string
+ rows2.Scan(&id, &name)
+ html += fmt.Sprintf(`
`, dealID, id, name)
+ }
+ rows2.Close()
+ }
+
+ // Search requests
+ rows3, _ := h.db.Query("SELECT id, item_number, description FROM diligence_requests WHERE deal_id = ? AND description LIKE ?", dealID, pattern)
+ if rows3 != nil {
+ hasReqs := false
+ for rows3.Next() {
+ if !hasReqs {
+ html += `
Request Items
`
+ hasReqs = true
+ }
+ var id, itemNum, desc string
+ rows3.Scan(&id, &itemNum, &desc)
+ html += fmt.Sprintf(`
`, itemNum, desc)
+ }
+ rows3.Close()
+ }
+
+ html += `
`
+ w.Write([]byte(html))
+}
+
func (h *Handler) getLastActivityByDeal(dealID string) *time.Time {
var t time.Time
err := h.db.QueryRow("SELECT MAX(created_at) FROM deal_activity WHERE deal_id = ?", dealID).Scan(&t)
diff --git a/internal/handler/handler.go b/internal/handler/handler.go
index 87f88fc..7515939 100644
--- a/internal/handler/handler.go
+++ b/internal/handler/handler.go
@@ -87,6 +87,7 @@ mux.HandleFunc("/auth/logout", h.handleLogout)
mux.HandleFunc("/deals/files/delete", h.requireAuth(h.handleFileDelete))
mux.HandleFunc("/deals/files/download/", h.requireAuth(h.handleFileDownload))
mux.HandleFunc("/deals/files/comments/", h.requireAuth(h.handleFileComments))
+ mux.HandleFunc("/deals/search/", h.requireAuth(h.handleDealSearch))
// HTMX partials
mux.HandleFunc("/htmx/request-comment", h.requireAuth(h.handleUpdateComment))
diff --git a/templates/dealroom.templ b/templates/dealroom.templ
index c20f8a4..9bdb40b 100644
--- a/templates/dealroom.templ
+++ b/templates/dealroom.templ
@@ -21,6 +21,17 @@ templ DealRoomDetail(profile *model.Profile, deal *model.Deal, folders []*model.