diff --git a/core/application/search.go b/core/application/search.go new file mode 100644 index 0000000..00bec37 --- /dev/null +++ b/core/application/search.go @@ -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 +} diff --git a/renderer/search.go b/renderer/search.go new file mode 100644 index 0000000..536ea3d --- /dev/null +++ b/renderer/search.go @@ -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) +} diff --git a/servers/web/app_search_routes.go b/servers/web/app_search_routes.go new file mode 100644 index 0000000..eb1963d --- /dev/null +++ b/servers/web/app_search_routes.go @@ -0,0 +1,9 @@ +package web + +import ( + "github.com/gorilla/mux" +) + +func (ws *WebServer) setupSearchRoutes(appRouter *mux.Router) { + appRouter.HandleFunc("/search", ws.appHandler.GlobalSearchHTTPHandler()) +} diff --git a/servers/web/application/search.go b/servers/web/application/search.go new file mode 100644 index 0000000..792b3cc --- /dev/null +++ b/servers/web/application/search.go @@ -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) + } +} diff --git a/servers/web/application_routes.go b/servers/web/application_routes.go index 5053814..69d4950 100644 --- a/servers/web/application_routes.go +++ b/servers/web/application_routes.go @@ -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)