gohorsejobs/backend/internal/handlers/company_follower_handler.go
GoHorse Deploy ae475e41a9 feat: implement careerjet gap analysis improvements
- Video Interview system (backend + frontend)
- Date Posted filter (24h, 7d, 30d)
- Company filter in jobs listing
- Recent searches persistence (LocalStorage)
- Job Alerts with email confirmation
- Favorite jobs with API
- Company followers system
- Careerjet URL compatibility (s/l aliases)
2026-02-14 19:37:25 +00:00

111 lines
3.2 KiB
Go

package handlers
import (
"encoding/json"
"net/http"
"strings"
"github.com/rede5/gohorsejobs/backend/internal/api/middleware"
"github.com/rede5/gohorsejobs/backend/internal/models"
)
type CompanyFollowerServiceInterface interface {
Follow(userID, companyID string) (*models.CompanyFollower, error)
Unfollow(userID, companyID string) error
GetFollowing(userID string) ([]models.CompanyFollowerWithCompany, error)
IsFollowing(userID, companyID string) (bool, error)
GetCompaniesWithJobs(limit, offset int) ([]models.CompanyFollowerWithCompany, error)
}
type CompanyFollowerHandler struct {
Service CompanyFollowerServiceInterface
}
func NewCompanyFollowerHandler(service CompanyFollowerServiceInterface) *CompanyFollowerHandler {
return &CompanyFollowerHandler{Service: service}
}
func (h *CompanyFollowerHandler) Follow(w http.ResponseWriter, r *http.Request) {
userID, ok := r.Context().Value(middleware.ContextUserID).(string)
if !ok || userID == "" {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
companyID := strings.TrimPrefix(r.URL.Path, "/api/v1/companies/follow/")
follower, err := h.Service.Follow(userID, companyID)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(follower)
}
func (h *CompanyFollowerHandler) Unfollow(w http.ResponseWriter, r *http.Request) {
userID, ok := r.Context().Value(middleware.ContextUserID).(string)
if !ok || userID == "" {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
companyID := strings.TrimPrefix(r.URL.Path, "/api/v1/companies/follow/")
err := h.Service.Unfollow(userID, companyID)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusNoContent)
}
func (h *CompanyFollowerHandler) GetMyFollowing(w http.ResponseWriter, r *http.Request) {
userID, ok := r.Context().Value(middleware.ContextUserID).(string)
if !ok || userID == "" {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
following, err := h.Service.GetFollowing(userID)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(following)
}
func (h *CompanyFollowerHandler) CheckFollowing(w http.ResponseWriter, r *http.Request) {
userID, ok := r.Context().Value(middleware.ContextUserID).(string)
if !ok || userID == "" {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
companyID := strings.TrimPrefix(r.URL.Path, "/api/v1/companies/")
isFollowing, err := h.Service.IsFollowing(userID, companyID)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]bool{"isFollowing": isFollowing})
}
func (h *CompanyFollowerHandler) GetCompanies(w http.ResponseWriter, r *http.Request) {
companies, err := h.Service.GetCompaniesWithJobs(20, 0)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(companies)
}