104 lines
2.7 KiB
Go
104 lines
2.7 KiB
Go
package http
|
|
|
|
import (
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"primaya-api/cpone-middleware/internal/repository"
|
|
)
|
|
|
|
const (
|
|
defaultDokterPerPage = 15
|
|
maxDokterPerPage = 100
|
|
)
|
|
|
|
type DokterPaginationResponse struct {
|
|
CurrentPage int `json:"current_page"`
|
|
Data []repository.Dokter `json:"data"`
|
|
FirstPageURL string `json:"first_page_url"`
|
|
From *int `json:"from"`
|
|
LastPage int `json:"last_page"`
|
|
LastPageURL string `json:"last_page_url"`
|
|
Links map[string]any `json:"links"`
|
|
NextPageURL *string `json:"next_page_url"`
|
|
Total int `json:"total"`
|
|
PerPage int `json:"per_page"`
|
|
}
|
|
|
|
func (h Handler) ListDokter(w http.ResponseWriter, r *http.Request) {
|
|
page := parseDokterPage(r.URL.Query().Get("page"))
|
|
perPage := parseDokterPerPage(r.URL.Query().Get("per_page"))
|
|
|
|
doctorIDs := queryValues(r, "DokterID_in", "DokterID_in[]")
|
|
doctorIDs = splitDoctorIDs(doctorIDs)
|
|
|
|
result, err := h.dokterRepository(r.Context()).ListDokter(r.Context(), repository.DokterListParams{
|
|
Search: strings.TrimSpace(r.URL.Query().Get("search")), DoctorIDs: doctorIDs,
|
|
Page: page, PerPage: perPage,
|
|
})
|
|
if err != nil {
|
|
WriteJSON(w, http.StatusInternalServerError, Response{Success: false, Message: "internal server error", Data: nil})
|
|
return
|
|
}
|
|
|
|
lastPage := (result.Total + perPage - 1) / perPage
|
|
if lastPage < 1 {
|
|
lastPage = 1
|
|
}
|
|
var from *int
|
|
if len(result.Items) > 0 {
|
|
value := (page-1)*perPage + 1
|
|
from = &value
|
|
}
|
|
var nextPageURL *string
|
|
if page < lastPage {
|
|
value := currentRequestURL(r, page+1)
|
|
nextPageURL = &value
|
|
}
|
|
|
|
WriteJSON(w, http.StatusOK, DokterPaginationResponse{
|
|
CurrentPage: page, Data: result.Items, FirstPageURL: "", From: from,
|
|
LastPage: lastPage, LastPageURL: "", Links: map[string]any{},
|
|
NextPageURL: nextPageURL, Total: result.Total, PerPage: perPage,
|
|
})
|
|
}
|
|
|
|
func parseDokterPage(raw string) int {
|
|
value, err := strconv.Atoi(raw)
|
|
if err != nil || value < 1 {
|
|
return 1
|
|
}
|
|
return value
|
|
}
|
|
|
|
func parseDokterPerPage(raw string) int {
|
|
value, err := strconv.Atoi(raw)
|
|
if err != nil || value < 1 {
|
|
return defaultDokterPerPage
|
|
}
|
|
if value > maxDokterPerPage {
|
|
return maxDokterPerPage
|
|
}
|
|
return value
|
|
}
|
|
|
|
func splitDoctorIDs(values []string) []string {
|
|
seen := make(map[string]struct{}, len(values))
|
|
result := make([]string, 0, len(values))
|
|
for _, value := range values {
|
|
for _, part := range strings.Split(value, ",") {
|
|
part = strings.TrimSpace(part)
|
|
if part == "" {
|
|
continue
|
|
}
|
|
if _, exists := seen[part]; exists {
|
|
continue
|
|
}
|
|
seen[part] = struct{}{}
|
|
result = append(result, part)
|
|
}
|
|
}
|
|
return result
|
|
}
|