feat: add global search across beneficiaries and drivers

This commit is contained in:
Arnaud Delcasse
2026-02-26 14:54:22 +01:00
parent bb525f174d
commit b79cc08b06
5 changed files with 103 additions and 0 deletions

View File

@@ -0,0 +1,47 @@
package application
import (
"context"
mobilityaccountsstorage "git.coopgo.io/coopgo-platform/mobility-accounts/storage"
"github.com/rs/zerolog/log"
)
type GlobalSearchResult struct {
Beneficiaries []mobilityaccountsstorage.Account
SolidarityDrivers []mobilityaccountsstorage.Account
OrganizedCarpoolDrivers []mobilityaccountsstorage.Account
}
func (h *ApplicationHandler) GlobalSearch(ctx context.Context, query string) (*GlobalSearchResult, error) {
result := &GlobalSearchResult{}
if h.config.GetBool("modules.beneficiaries.enabled") {
beneficiaries, err := h.getBeneficiariesWithFilters(ctx, query, false)
if err != nil {
log.Error().Err(err).Msg("global search: error retrieving beneficiaries")
} else {
result.Beneficiaries = beneficiaries
}
}
if h.config.GetBool("modules.solidarity_transport.enabled") {
drivers, err := h.solidarityDrivers(ctx, query, false)
if err != nil {
log.Error().Err(err).Msg("global search: error retrieving solidarity drivers")
} else {
result.SolidarityDrivers = drivers
}
}
if h.config.GetBool("modules.organized_carpool.enabled") {
drivers, err := h.getOrganizedCarpoolDrivers(ctx, query, false)
if err != nil {
log.Error().Err(err).Msg("global search: error retrieving organized carpool drivers")
} else {
result.OrganizedCarpoolDrivers = drivers
}
}
return result, nil
}

20
renderer/search.go Normal file
View File

@@ -0,0 +1,20 @@
package renderer
import (
"net/http"
mobilityaccountsstorage "git.coopgo.io/coopgo-platform/mobility-accounts/storage"
)
func (renderer *Renderer) GlobalSearchResults(w http.ResponseWriter, r *http.Request, query string, beneficiaries []mobilityaccountsstorage.Account, solidarityDrivers []mobilityaccountsstorage.Account, organizedCarpoolDrivers []mobilityaccountsstorage.Account) {
files := renderer.ThemeConfig.GetStringSlice("views.search.results.files")
state := NewState(r, renderer.ThemeConfig, "")
state.ViewState = map[string]any{
"query": query,
"beneficiaries": beneficiaries,
"solidarity_drivers": solidarityDrivers,
"organized_carpool_drivers": organizedCarpoolDrivers,
}
renderer.Render("search results", w, r, files, state)
}

View File

@@ -0,0 +1,9 @@
package web
import (
"github.com/gorilla/mux"
)
func (ws *WebServer) setupSearchRoutes(appRouter *mux.Router) {
appRouter.HandleFunc("/search", ws.appHandler.GlobalSearchHTTPHandler())
}

View File

@@ -0,0 +1,26 @@
package application
import (
"net/http"
"github.com/rs/zerolog/log"
)
func (h *Handler) GlobalSearchHTTPHandler() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
query := r.URL.Query().Get("q")
if query == "" {
http.Redirect(w, r, "/app/", http.StatusFound)
return
}
result, err := h.applicationHandler.GlobalSearch(r.Context(), query)
if err != nil {
log.Error().Err(err).Msg("error performing global search")
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
return
}
h.renderer.GlobalSearchResults(w, r, query, result.Beneficiaries, result.SolidarityDrivers, result.OrganizedCarpoolDrivers)
}
}

View File

@@ -8,6 +8,7 @@ func (ws *WebServer) setupApplicationRoutes(r *mux.Router) {
application := r.PathPrefix("/app").Subrouter()
// Setup all application route groups
ws.setupSearchRoutes(application)
ws.setupDashboardRoutes(application)
setupMiscRoutes(application, ws.applicationHandler)
ws.setupDirectoryRoutes(application)