add user profile stats
This commit is contained in:
parent
a2d4dfb282
commit
b31bc76a24
@ -39,7 +39,7 @@ func (server *Server) getRoutes() {
|
|||||||
router.Use(cors.New(cors.Config{
|
router.Use(cors.New(cors.Config{
|
||||||
AllowOrigins: []string{"http://localhost:5173"},
|
AllowOrigins: []string{"http://localhost:5173"},
|
||||||
AllowCredentials: true,
|
AllowCredentials: true,
|
||||||
AllowHeaders: []string{"Content-Type", "Content-Length", "Accept-Encoding", "X-CSRF-Token", "Authorization", "accept", "origin", "Cache-Control", "X-Requested-With"},
|
AllowHeaders: []string{"Content-Type", "Content-Length", "Accept-Encoding", "Authorization", "accept", "origin", "Cache-Control", "X-Requested-With", "X-XSRF-TOKEN"},
|
||||||
AllowMethods: []string{"POST", "PUT", "GET", "DELETE", "PATCH"},
|
AllowMethods: []string{"POST", "PUT", "GET", "DELETE", "PATCH"},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
@ -68,6 +68,7 @@ func (server *Server) getRoutes() {
|
|||||||
authRoutes := router.Use(authMiddleware(server.TokenMaker))
|
authRoutes := router.Use(authMiddleware(server.TokenMaker))
|
||||||
authRoutes.POST("/review/location", server.createReview)
|
authRoutes.POST("/review/location", server.createReview)
|
||||||
authRoutes.GET("/user/review/location/:location_id", server.getUserReviewByLocation)
|
authRoutes.GET("/user/review/location/:location_id", server.getUserReviewByLocation)
|
||||||
|
authRoutes.GET("/user/profile", server.getUserStats)
|
||||||
|
|
||||||
server.Router = router
|
server.Router = router
|
||||||
}
|
}
|
||||||
|
37
api/user.go
37
api/user.go
@ -2,11 +2,13 @@ package api
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
db "git.nochill.in/nochill/hiling_go/db/sqlc"
|
db "git.nochill.in/nochill/hiling_go/db/sqlc"
|
||||||
"git.nochill.in/nochill/hiling_go/util"
|
"git.nochill.in/nochill/hiling_go/util"
|
||||||
|
"git.nochill.in/nochill/hiling_go/util/token"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/lib/pq"
|
"github.com/lib/pq"
|
||||||
)
|
)
|
||||||
@ -124,6 +126,41 @@ func (server *Server) createUser(ctx *gin.Context) {
|
|||||||
ctx.JSON(http.StatusOK, res)
|
ctx.JSON(http.StatusOK, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (server *Server) getUserStats(ctx *gin.Context) {
|
||||||
|
var scoreDistribution []map[string]int8
|
||||||
|
authPayload := ctx.MustGet(authorizationPayloadKey).(*token.Payload)
|
||||||
|
|
||||||
|
userStats, err := server.Store.GetUserStats(ctx, int32(authPayload.UserID))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
ctx.JSON(http.StatusInternalServerError, ErrorResponse(err, "Something went wrong while try to get user stats"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.Unmarshal(userStats.ScoresDistribution, &scoreDistribution)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
ctx.JSON(http.StatusInternalServerError, ErrorResponse(err, "Something went wrong whilet try to parse score distribution"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var userReviews []map[string]any
|
||||||
|
if userStats.Reviews != nil {
|
||||||
|
err = json.Unmarshal(userStats.Reviews, &userReviews)
|
||||||
|
if err != nil {
|
||||||
|
ctx.JSON(http.StatusInternalServerError, ErrorResponse(err, "Something wrong while try to parse user reviwes stats"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
userReviews = make([]map[string]any, 0)
|
||||||
|
}
|
||||||
|
ctx.JSON(http.StatusOK, gin.H{
|
||||||
|
"reviews": userReviews,
|
||||||
|
"scores_distribution": scoreDistribution,
|
||||||
|
"user_stats": userStats,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (server *Server) login(ctx *gin.Context) {
|
func (server *Server) login(ctx *gin.Context) {
|
||||||
var req createUserRequest
|
var req createUserRequest
|
||||||
|
|
||||||
|
@ -362,6 +362,21 @@ func (mr *MockStoreMockRecorder) GetUserReviewByLocation(arg0, arg1 interface{})
|
|||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUserReviewByLocation", reflect.TypeOf((*MockStore)(nil).GetUserReviewByLocation), arg0, arg1)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUserReviewByLocation", reflect.TypeOf((*MockStore)(nil).GetUserReviewByLocation), arg0, arg1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetUserStats mocks base method.
|
||||||
|
func (m *MockStore) GetUserStats(arg0 context.Context, arg1 int32) (db.GetUserStatsRow, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "GetUserStats", arg0, arg1)
|
||||||
|
ret0, _ := ret[0].(db.GetUserStatsRow)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUserStats indicates an expected call of GetUserStats.
|
||||||
|
func (mr *MockStoreMockRecorder) GetUserStats(arg0, arg1 interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUserStats", reflect.TypeOf((*MockStore)(nil).GetUserStats), arg0, arg1)
|
||||||
|
}
|
||||||
|
|
||||||
// RemoveFollowUser mocks base method.
|
// RemoveFollowUser mocks base method.
|
||||||
func (m *MockStore) RemoveFollowUser(arg0 context.Context, arg1 db.RemoveFollowUserParams) error {
|
func (m *MockStore) RemoveFollowUser(arg0 context.Context, arg1 db.RemoveFollowUserParams) error {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
|
@ -14,6 +14,7 @@ type Store interface {
|
|||||||
GetImagesByLocation(ctx context.Context, arg GetImagesByLocationParams) ([]GetImagesByLocationRow, error)
|
GetImagesByLocation(ctx context.Context, arg GetImagesByLocationParams) ([]GetImagesByLocationRow, error)
|
||||||
GetLocation(ctx context.Context, location_id int32) (GetLocationRow, error)
|
GetLocation(ctx context.Context, location_id int32) (GetLocationRow, error)
|
||||||
GetUser(ctx context.Context, username string) (GetUserRow, error)
|
GetUser(ctx context.Context, username string) (GetUserRow, error)
|
||||||
|
GetUserStats(ctx context.Context, user_id int32) (GetUserStatsRow, error)
|
||||||
CreateReview(ctx context.Context, arg CreateReviewParams) (Review, error)
|
CreateReview(ctx context.Context, arg CreateReviewParams) (Review, error)
|
||||||
GetListLocationReviews(ctx context.Context, arg GetListLocationReviewsParams) ([]GetListLocationReviewsRow, error)
|
GetListLocationReviews(ctx context.Context, arg GetListLocationReviewsParams) ([]GetListLocationReviewsRow, error)
|
||||||
CreateLocation(ctx context.Context, arg CreateLocationParams) (int32, error)
|
CreateLocation(ctx context.Context, arg CreateLocationParams) (int32, error)
|
||||||
|
@ -3,11 +3,13 @@ package db
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/sqlc-dev/pqtype"
|
"github.com/sqlc-dev/pqtype"
|
||||||
)
|
)
|
||||||
|
|
||||||
const getUser = `-- name: GetUser :one
|
const getUserQ = `-- name: GetUser :one
|
||||||
SELECT
|
SELECT
|
||||||
id,
|
id,
|
||||||
COALESCE(email, '') as email,
|
COALESCE(email, '') as email,
|
||||||
@ -43,7 +45,7 @@ type GetUserRow struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) GetUser(ctx context.Context, username string) (GetUserRow, error) {
|
func (q *Queries) GetUser(ctx context.Context, username string) (GetUserRow, error) {
|
||||||
row := q.db.QueryRowContext(ctx, getUser, username)
|
row := q.db.QueryRowContext(ctx, getUserQ, username)
|
||||||
var i GetUserRow
|
var i GetUserRow
|
||||||
err := row.Scan(
|
err := row.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
@ -62,3 +64,74 @@ func (q *Queries) GetUser(ctx context.Context, username string) (GetUserRow, err
|
|||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getUserStatsQ = `
|
||||||
|
SELECT
|
||||||
|
json_agg(ur.*) AS reviews,
|
||||||
|
( SELECT COUNT(id) FROM user_follow u WHERE u.followee_id = $1) as followers,
|
||||||
|
( SELECT COUNT(id) FROM reviews r WHERE r.submitted_by = $1 ) as score_count,
|
||||||
|
( SELECT
|
||||||
|
json_agg(r1.*) AS scores_distribution
|
||||||
|
FROM
|
||||||
|
(
|
||||||
|
SELECT
|
||||||
|
*
|
||||||
|
FROM
|
||||||
|
( SELECT COUNT(id) as "0" FROM reviews r WHERE r.score >= 0 AND r.score <= 9 AND r.submitted_by = $1) as score0,
|
||||||
|
( SELECT COUNT(id) as "1" FROM reviews r WHERE r.score >= 10 AND r.score <= 19 AND r.submitted_by = $1) as score1,
|
||||||
|
( SELECT COUNT(id) as "2" FROM reviews r WHERE r.score >= 20 AND r.score <= 29 AND r.submitted_by = $1) as score2,
|
||||||
|
( SELECT COUNT(id) as "3" FROM reviews r WHERE r.score >= 30 AND r.score <= 39 AND r.submitted_by = $1) as score3,
|
||||||
|
( SELECT COUNT(id) as "4" FROM reviews r WHERE r.score >= 40 AND r.score <= 49 AND r.submitted_by = $1) as score4,
|
||||||
|
( SELECT COUNT(id) as "5" FROM reviews r WHERE r.score >= 50 AND r.score <= 59 AND r.submitted_by = $1) as score5,
|
||||||
|
( SELECT COUNT(id) as "6" FROM reviews r WHERE r.score >= 60 AND r.score <= 69 AND r.submitted_by = $1) as score6,
|
||||||
|
( SELECT COUNT(id) as "7" FROM reviews r WHERE r.score >= 70 AND r.score <= 79 AND r.submitted_by = $1) as score7,
|
||||||
|
( SELECT COUNT(id) as "8" FROM reviews r WHERE r.score >= 80 AND r.score <= 89 AND r.submitted_by = $1) as score8,
|
||||||
|
( SELECT COUNT(id) as "9" FROM reviews r WHERE r.score >= 90 AND r.score <= 99 AND r.submitted_by = $1) as score9,
|
||||||
|
( SELECT COUNT(id) as "99" FROM reviews r WHERE r.score = 100 AND r.submitted_by = $1) as score10
|
||||||
|
) r1
|
||||||
|
)
|
||||||
|
FROM (
|
||||||
|
SELECT
|
||||||
|
reviews.id,
|
||||||
|
reviews.comments,
|
||||||
|
score,
|
||||||
|
l.name,
|
||||||
|
p.province_name,
|
||||||
|
COALESCE(l.thumbnail, '') as thumbnail
|
||||||
|
FROM
|
||||||
|
reviews
|
||||||
|
JOIN locations l on reviews.location_id = l.id
|
||||||
|
JOIN regencies r on l.regency_id = r.id
|
||||||
|
JOIN provinces p on r.province_id = p.id
|
||||||
|
WHERE reviews.submitted_by = $1
|
||||||
|
ORDER BY score ASC
|
||||||
|
LIMIT 10
|
||||||
|
) ur
|
||||||
|
`
|
||||||
|
|
||||||
|
type GetUserStatsRow struct {
|
||||||
|
Reviews []byte `json:"-"`
|
||||||
|
Followers int32 `json:"followers"`
|
||||||
|
ScoreCount int32 `json:"score_count"`
|
||||||
|
ScoresDistribution []byte `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) GetUserStats(ctx context.Context, user_id int32) (GetUserStatsRow, error) {
|
||||||
|
var i GetUserStatsRow
|
||||||
|
row := q.db.QueryRowContext(ctx, getUserStatsQ, user_id)
|
||||||
|
|
||||||
|
err := row.Scan(
|
||||||
|
&i.Reviews,
|
||||||
|
&i.Followers,
|
||||||
|
&i.ScoreCount,
|
||||||
|
&i.ScoresDistribution,
|
||||||
|
)
|
||||||
|
|
||||||
|
var r []map[string]any
|
||||||
|
|
||||||
|
err = json.Unmarshal(i.ScoresDistribution, &r)
|
||||||
|
fmt.Println(r)
|
||||||
|
|
||||||
|
return i, err
|
||||||
|
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user