diff options
Diffstat (limited to 'backend/handlers/user.go')
| -rw-r--r-- | backend/handlers/user.go | 84 |
1 files changed, 73 insertions, 11 deletions
diff --git a/backend/handlers/user.go b/backend/handlers/user.go index c985471..a9174a2 100644 --- a/backend/handlers/user.go +++ b/backend/handlers/user.go | |||
| @@ -4,6 +4,7 @@ import ( | |||
| 4 | "net/http" | 4 | "net/http" |
| 5 | "os" | 5 | "os" |
| 6 | "regexp" | 6 | "regexp" |
| 7 | "strconv" | ||
| 7 | "time" | 8 | "time" |
| 8 | 9 | ||
| 9 | "github.com/gin-gonic/gin" | 10 | "github.com/gin-gonic/gin" |
| @@ -12,15 +13,16 @@ import ( | |||
| 12 | ) | 13 | ) |
| 13 | 14 | ||
| 14 | type ProfileResponse struct { | 15 | type ProfileResponse struct { |
| 15 | Profile bool `json:"profile"` | 16 | Profile bool `json:"profile"` |
| 16 | SteamID string `json:"steam_id"` | 17 | SteamID string `json:"steam_id"` |
| 17 | UserName string `json:"user_name"` | 18 | UserName string `json:"user_name"` |
| 18 | AvatarLink string `json:"avatar_link"` | 19 | AvatarLink string `json:"avatar_link"` |
| 19 | CountryCode string `json:"country_code"` | 20 | CountryCode string `json:"country_code"` |
| 20 | Titles []models.Title `json:"titles"` | 21 | Titles []models.Title `json:"titles"` |
| 21 | Links models.Links `json:"links"` | 22 | Links models.Links `json:"links"` |
| 22 | Rankings ProfileRankings `json:"rankings"` | 23 | Rankings ProfileRankings `json:"rankings"` |
| 23 | Records []ProfileRecords `json:"records"` | 24 | Records []ProfileRecords `json:"records"` |
| 25 | Pagination models.Pagination `json:"pagination"` | ||
| 24 | } | 26 | } |
| 25 | 27 | ||
| 26 | type ProfileRankings struct { | 28 | type ProfileRankings struct { |
| @@ -73,10 +75,18 @@ func Profile(c *gin.Context) { | |||
| 73 | c.JSON(http.StatusOK, models.ErrorResponse("User not logged in.")) | 75 | c.JSON(http.StatusOK, models.ErrorResponse("User not logged in.")) |
| 74 | return | 76 | return |
| 75 | } | 77 | } |
| 78 | page, err := strconv.Atoi(c.DefaultQuery("page", "1")) | ||
| 79 | if err != nil || page < 1 { | ||
| 80 | page = 1 | ||
| 81 | } | ||
| 82 | pageSize, err := strconv.Atoi(c.DefaultQuery("pageSize", "20")) | ||
| 83 | if err != nil || pageSize < 1 { | ||
| 84 | pageSize = 20 | ||
| 85 | } | ||
| 76 | // Get user links | 86 | // Get user links |
| 77 | links := models.Links{} | 87 | links := models.Links{} |
| 78 | sql := `SELECT u.p2sr, u.steam, u.youtube, u.twitch FROM users u WHERE u.steam_id = $1` | 88 | sql := `SELECT u.p2sr, u.steam, u.youtube, u.twitch FROM users u WHERE u.steam_id = $1` |
| 79 | err := database.DB.QueryRow(sql, user.(models.User).SteamID).Scan(&links.P2SR, &links.Steam, &links.YouTube, &links.Twitch) | 89 | err = database.DB.QueryRow(sql, user.(models.User).SteamID).Scan(&links.P2SR, &links.Steam, &links.YouTube, &links.Twitch) |
| 80 | if err != nil { | 90 | if err != nil { |
| 81 | c.JSON(http.StatusOK, models.ErrorResponse(err.Error())) | 91 | c.JSON(http.StatusOK, models.ErrorResponse(err.Error())) |
| 82 | return | 92 | return |
| @@ -291,6 +301,8 @@ func Profile(c *gin.Context) { | |||
| 291 | } | 301 | } |
| 292 | } | 302 | } |
| 293 | records := []ProfileRecords{} | 303 | records := []ProfileRecords{} |
| 304 | totalRecords := 0 | ||
| 305 | totalPages := 0 | ||
| 294 | // Get singleplayer records | 306 | // Get singleplayer records |
| 295 | sql = `SELECT sp.id, m.game_id, m.chapter_id, sp.map_id, m."name", (SELECT mr.score_count FROM map_routes mr WHERE mr.map_id = sp.map_id ORDER BY mr.score_count ASC LIMIT 1) AS wr_count, sp.score_count, sp.score_time, sp.demo_id, sp.record_date | 307 | sql = `SELECT sp.id, m.game_id, m.chapter_id, sp.map_id, m."name", (SELECT mr.score_count FROM map_routes mr WHERE mr.map_id = sp.map_id ORDER BY mr.score_count ASC LIMIT 1) AS wr_count, sp.score_count, sp.score_time, sp.demo_id, sp.record_date |
| 296 | FROM records_sp sp INNER JOIN maps m ON sp.map_id = m.id WHERE sp.user_id = $1 AND sp.is_deleted = false ORDER BY sp.map_id, sp.score_count, sp.score_time` | 308 | FROM records_sp sp INNER JOIN maps m ON sp.map_id = m.id WHERE sp.user_id = $1 AND sp.is_deleted = false ORDER BY sp.map_id, sp.score_count, sp.score_time` |
| @@ -393,6 +405,20 @@ func Profile(c *gin.Context) { | |||
| 393 | placementIndex++ | 405 | placementIndex++ |
| 394 | records[len(records)-1].Scores = append(records[len(records)-1].Scores, score) | 406 | records[len(records)-1].Scores = append(records[len(records)-1].Scores, score) |
| 395 | } | 407 | } |
| 408 | totalRecords = len(records) | ||
| 409 | if totalRecords != 0 { | ||
| 410 | totalPages = (totalRecords + pageSize - 1) / pageSize | ||
| 411 | if page > totalPages { | ||
| 412 | c.JSON(http.StatusOK, models.ErrorResponse("Invalid page number.")) | ||
| 413 | return | ||
| 414 | } | ||
| 415 | startIndex := (page - 1) * pageSize | ||
| 416 | endIndex := startIndex + pageSize | ||
| 417 | if endIndex > totalRecords { | ||
| 418 | endIndex = totalRecords | ||
| 419 | } | ||
| 420 | records = records[startIndex:endIndex] | ||
| 421 | } | ||
| 396 | c.JSON(http.StatusOK, models.Response{ | 422 | c.JSON(http.StatusOK, models.Response{ |
| 397 | Success: true, | 423 | Success: true, |
| 398 | Message: "Successfully retrieved user scores.", | 424 | Message: "Successfully retrieved user scores.", |
| @@ -406,6 +432,12 @@ func Profile(c *gin.Context) { | |||
| 406 | Links: links, | 432 | Links: links, |
| 407 | Rankings: rankings, | 433 | Rankings: rankings, |
| 408 | Records: records, | 434 | Records: records, |
| 435 | Pagination: models.Pagination{ | ||
| 436 | TotalRecords: totalRecords, | ||
| 437 | TotalPages: totalPages, | ||
| 438 | CurrentPage: page, | ||
| 439 | PageSize: pageSize, | ||
| 440 | }, | ||
| 409 | }, | 441 | }, |
| 410 | }) | 442 | }) |
| 411 | } | 443 | } |
| @@ -427,11 +459,19 @@ func FetchUser(c *gin.Context) { | |||
| 427 | c.JSON(http.StatusOK, models.ErrorResponse("User not found.")) | 459 | c.JSON(http.StatusOK, models.ErrorResponse("User not found.")) |
| 428 | return | 460 | return |
| 429 | } | 461 | } |
| 462 | page, err := strconv.Atoi(c.DefaultQuery("page", "1")) | ||
| 463 | if err != nil || page < 1 { | ||
| 464 | page = 1 | ||
| 465 | } | ||
| 466 | pageSize, err := strconv.Atoi(c.DefaultQuery("pageSize", "20")) | ||
| 467 | if err != nil || pageSize < 1 { | ||
| 468 | pageSize = 20 | ||
| 469 | } | ||
| 430 | // Check if user exists | 470 | // Check if user exists |
| 431 | var user models.User | 471 | var user models.User |
| 432 | links := models.Links{} | 472 | links := models.Links{} |
| 433 | sql := `SELECT u.steam_id, u.user_name, u.avatar_link, u.country_code, u.created_at, u.updated_at, u.p2sr, u.steam, u.youtube, u.twitch FROM users u WHERE u.steam_id = $1` | 473 | sql := `SELECT u.steam_id, u.user_name, u.avatar_link, u.country_code, u.created_at, u.updated_at, u.p2sr, u.steam, u.youtube, u.twitch FROM users u WHERE u.steam_id = $1` |
| 434 | err := database.DB.QueryRow(sql, id).Scan(&user.SteamID, &user.UserName, &user.AvatarLink, &user.CountryCode, &user.CreatedAt, &user.UpdatedAt, &links.P2SR, &links.Steam, &links.YouTube, &links.Twitch) | 474 | err = database.DB.QueryRow(sql, id).Scan(&user.SteamID, &user.UserName, &user.AvatarLink, &user.CountryCode, &user.CreatedAt, &user.UpdatedAt, &links.P2SR, &links.Steam, &links.YouTube, &links.Twitch) |
| 435 | if err != nil { | 475 | if err != nil { |
| 436 | c.JSON(http.StatusOK, models.ErrorResponse(err.Error())) | 476 | c.JSON(http.StatusOK, models.ErrorResponse(err.Error())) |
| 437 | return | 477 | return |
| @@ -663,6 +703,8 @@ func FetchUser(c *gin.Context) { | |||
| 663 | } | 703 | } |
| 664 | } | 704 | } |
| 665 | records := []ProfileRecords{} | 705 | records := []ProfileRecords{} |
| 706 | totalRecords := 0 | ||
| 707 | totalPages := 0 | ||
| 666 | // Get singleplayer records | 708 | // Get singleplayer records |
| 667 | sql = `SELECT sp.id, m.game_id, m.chapter_id, sp.map_id, m."name", (SELECT mr.score_count FROM map_routes mr WHERE mr.map_id = sp.map_id ORDER BY mr.score_count ASC LIMIT 1) AS wr_count, sp.score_count, sp.score_time, sp.demo_id, sp.record_date | 709 | sql = `SELECT sp.id, m.game_id, m.chapter_id, sp.map_id, m."name", (SELECT mr.score_count FROM map_routes mr WHERE mr.map_id = sp.map_id ORDER BY mr.score_count ASC LIMIT 1) AS wr_count, sp.score_count, sp.score_time, sp.demo_id, sp.record_date |
| 668 | FROM records_sp sp INNER JOIN maps m ON sp.map_id = m.id WHERE sp.user_id = $1 AND sp.is_deleted = false ORDER BY sp.map_id, sp.score_count, sp.score_time` | 710 | FROM records_sp sp INNER JOIN maps m ON sp.map_id = m.id WHERE sp.user_id = $1 AND sp.is_deleted = false ORDER BY sp.map_id, sp.score_count, sp.score_time` |
| @@ -765,6 +807,20 @@ func FetchUser(c *gin.Context) { | |||
| 765 | placementIndex++ | 807 | placementIndex++ |
| 766 | records[len(records)-1].Scores = append(records[len(records)-1].Scores, score) | 808 | records[len(records)-1].Scores = append(records[len(records)-1].Scores, score) |
| 767 | } | 809 | } |
| 810 | totalRecords = len(records) | ||
| 811 | if totalRecords != 0 { | ||
| 812 | totalPages = (totalRecords + pageSize - 1) / pageSize | ||
| 813 | if page > totalPages { | ||
| 814 | c.JSON(http.StatusOK, models.ErrorResponse("Invalid page number.")) | ||
| 815 | return | ||
| 816 | } | ||
| 817 | startIndex := (page - 1) * pageSize | ||
| 818 | endIndex := startIndex + pageSize | ||
| 819 | if endIndex > totalRecords { | ||
| 820 | endIndex = totalRecords | ||
| 821 | } | ||
| 822 | records = records[startIndex:endIndex] | ||
| 823 | } | ||
| 768 | c.JSON(http.StatusOK, models.Response{ | 824 | c.JSON(http.StatusOK, models.Response{ |
| 769 | Success: true, | 825 | Success: true, |
| 770 | Message: "Successfully retrieved user scores.", | 826 | Message: "Successfully retrieved user scores.", |
| @@ -778,6 +834,12 @@ func FetchUser(c *gin.Context) { | |||
| 778 | Links: links, | 834 | Links: links, |
| 779 | Rankings: rankings, | 835 | Rankings: rankings, |
| 780 | Records: records, | 836 | Records: records, |
| 837 | Pagination: models.Pagination{ | ||
| 838 | TotalRecords: totalRecords, | ||
| 839 | TotalPages: totalPages, | ||
| 840 | CurrentPage: page, | ||
| 841 | PageSize: pageSize, | ||
| 842 | }, | ||
| 781 | }, | 843 | }, |
| 782 | }) | 844 | }) |
| 783 | } | 845 | } |