Refactor frontend components and enhance API integration

- Updated frontend-nuxt.mdc to specify usage of composables for API calls.
- Added new AuthCard and ConfirmModal components for improved UI consistency.
- Introduced UserAvatar component for user profile display, replacing previous Gravatar implementation.
- Implemented useFormSubmit composable for handling form submissions with loading and error states.
- Enhanced vitest.config.ts to include coverage reporting for composables and components.
- Removed deprecated useAdminApi and useAuth composables to streamline API interactions.
- Updated login and setup pages to utilize new components and composables for better user experience.
This commit is contained in:
2026-03-04 00:14:05 +03:00
parent f6375e7d0f
commit 8f769543f4
34 changed files with 878 additions and 379 deletions

View File

@@ -31,8 +31,7 @@ type meUpdateRequest struct {
// APILogin handles POST /map/api/login.
func (h *Handlers) APILogin(rw http.ResponseWriter, req *http.Request) {
if req.Method != http.MethodPost {
JSONError(rw, http.StatusMethodNotAllowed, "method not allowed", "METHOD_NOT_ALLOWED")
if !h.requireMethod(rw, req, http.MethodPost) {
return
}
ctx := req.Context()
@@ -73,8 +72,7 @@ func (h *Handlers) APILogin(rw http.ResponseWriter, req *http.Request) {
// APISetup handles GET /map/api/setup.
func (h *Handlers) APISetup(rw http.ResponseWriter, req *http.Request) {
if req.Method != http.MethodGet {
JSONError(rw, http.StatusMethodNotAllowed, "method not allowed", "METHOD_NOT_ALLOWED")
if !h.requireMethod(rw, req, http.MethodGet) {
return
}
JSON(rw, http.StatusOK, struct {
@@ -84,8 +82,7 @@ func (h *Handlers) APISetup(rw http.ResponseWriter, req *http.Request) {
// APILogout handles POST /map/api/logout.
func (h *Handlers) APILogout(rw http.ResponseWriter, req *http.Request) {
if req.Method != http.MethodPost {
JSONError(rw, http.StatusMethodNotAllowed, "method not allowed", "METHOD_NOT_ALLOWED")
if !h.requireMethod(rw, req, http.MethodPost) {
return
}
ctx := req.Context()
@@ -98,14 +95,12 @@ func (h *Handlers) APILogout(rw http.ResponseWriter, req *http.Request) {
// APIMe handles GET /map/api/me.
func (h *Handlers) APIMe(rw http.ResponseWriter, req *http.Request) {
if req.Method != http.MethodGet {
JSONError(rw, http.StatusMethodNotAllowed, "method not allowed", "METHOD_NOT_ALLOWED")
if !h.requireMethod(rw, req, http.MethodGet) {
return
}
ctx := req.Context()
s := h.Auth.GetSession(ctx, req)
s := h.requireSession(rw, req)
if s == nil {
JSONError(rw, http.StatusUnauthorized, "Unauthorized", "UNAUTHORIZED")
return
}
out := meResponse{Username: s.Username, Auths: s.Auths}
@@ -118,16 +113,14 @@ func (h *Handlers) APIMe(rw http.ResponseWriter, req *http.Request) {
// APIMeUpdate handles PATCH /map/api/me (update current user email).
func (h *Handlers) APIMeUpdate(rw http.ResponseWriter, req *http.Request) {
if req.Method != http.MethodPatch {
JSONError(rw, http.StatusMethodNotAllowed, "method not allowed", "METHOD_NOT_ALLOWED")
if !h.requireMethod(rw, req, http.MethodPatch) {
return
}
s := h.requireSession(rw, req)
if s == nil {
return
}
ctx := req.Context()
s := h.Auth.GetSession(ctx, req)
if s == nil {
JSONError(rw, http.StatusUnauthorized, "Unauthorized", "UNAUTHORIZED")
return
}
var body meUpdateRequest
if err := json.NewDecoder(req.Body).Decode(&body); err != nil {
JSONError(rw, http.StatusBadRequest, "bad request", "BAD_REQUEST")
@@ -142,16 +135,14 @@ func (h *Handlers) APIMeUpdate(rw http.ResponseWriter, req *http.Request) {
// APIMeTokens handles POST /map/api/me/tokens.
func (h *Handlers) APIMeTokens(rw http.ResponseWriter, req *http.Request) {
if req.Method != http.MethodPost {
JSONError(rw, http.StatusMethodNotAllowed, "method not allowed", "METHOD_NOT_ALLOWED")
if !h.requireMethod(rw, req, http.MethodPost) {
return
}
s := h.requireSession(rw, req)
if s == nil {
return
}
ctx := req.Context()
s := h.Auth.GetSession(ctx, req)
if s == nil {
JSONError(rw, http.StatusUnauthorized, "Unauthorized", "UNAUTHORIZED")
return
}
if !s.Auths.Has(app.AUTH_UPLOAD) {
JSONError(rw, http.StatusForbidden, "Forbidden", "FORBIDDEN")
return
@@ -166,16 +157,14 @@ func (h *Handlers) APIMeTokens(rw http.ResponseWriter, req *http.Request) {
// APIMePassword handles POST /map/api/me/password.
func (h *Handlers) APIMePassword(rw http.ResponseWriter, req *http.Request) {
if req.Method != http.MethodPost {
JSONError(rw, http.StatusMethodNotAllowed, "method not allowed", "METHOD_NOT_ALLOWED")
if !h.requireMethod(rw, req, http.MethodPost) {
return
}
s := h.requireSession(rw, req)
if s == nil {
return
}
ctx := req.Context()
s := h.Auth.GetSession(ctx, req)
if s == nil {
JSONError(rw, http.StatusUnauthorized, "Unauthorized", "UNAUTHORIZED")
return
}
var body passwordRequest
if err := json.NewDecoder(req.Body).Decode(&body); err != nil {
JSONError(rw, http.StatusBadRequest, "bad request", "BAD_REQUEST")
@@ -190,8 +179,7 @@ func (h *Handlers) APIMePassword(rw http.ResponseWriter, req *http.Request) {
// APIOAuthProviders handles GET /map/api/oauth/providers.
func (h *Handlers) APIOAuthProviders(rw http.ResponseWriter, req *http.Request) {
if req.Method != http.MethodGet {
JSONError(rw, http.StatusMethodNotAllowed, "method not allowed", "METHOD_NOT_ALLOWED")
if !h.requireMethod(rw, req, http.MethodGet) {
return
}
JSON(rw, http.StatusOK, services.OAuthProviders())
@@ -199,8 +187,7 @@ func (h *Handlers) APIOAuthProviders(rw http.ResponseWriter, req *http.Request)
// APIOAuthLogin handles GET /map/api/oauth/:provider/login.
func (h *Handlers) APIOAuthLogin(rw http.ResponseWriter, req *http.Request, provider string) {
if req.Method != http.MethodGet {
JSONError(rw, http.StatusMethodNotAllowed, "method not allowed", "METHOD_NOT_ALLOWED")
if !h.requireMethod(rw, req, http.MethodGet) {
return
}
redirect := req.URL.Query().Get("redirect")
@@ -214,8 +201,7 @@ func (h *Handlers) APIOAuthLogin(rw http.ResponseWriter, req *http.Request, prov
// APIOAuthCallback handles GET /map/api/oauth/:provider/callback.
func (h *Handlers) APIOAuthCallback(rw http.ResponseWriter, req *http.Request, provider string) {
if req.Method != http.MethodGet {
JSONError(rw, http.StatusMethodNotAllowed, "method not allowed", "METHOD_NOT_ALLOWED")
if !h.requireMethod(rw, req, http.MethodGet) {
return
}
code := req.URL.Query().Get("code")