Update UI result
This commit is contained in:
parent
228f6a78c9
commit
104cd987e9
@ -1,7 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
APP_NAME="meti-frontend"
|
APP_NAME="meti-backend"
|
||||||
PORT="3000"
|
PORT="4000"
|
||||||
|
|
||||||
echo "🔄 Pulling latest code..."
|
echo "🔄 Pulling latest code..."
|
||||||
git pull
|
git pull
|
||||||
@ -15,7 +15,9 @@ docker rm $APP_NAME 2>/dev/null
|
|||||||
|
|
||||||
echo "🚀 Running new container..."
|
echo "🚀 Running new container..."
|
||||||
docker run -d --name $APP_NAME \
|
docker run -d --name $APP_NAME \
|
||||||
-p 4002:$PORT \
|
-p 4001:$PORT \
|
||||||
|
-v "$(pwd)/infra":/infra:ro \
|
||||||
|
-v "$(pwd)/templates":/templates:ro \
|
||||||
$APP_NAME:latest
|
$APP_NAME:latest
|
||||||
|
|
||||||
echo "✅ Deployment complete."
|
echo "✅ Deployment complete."
|
||||||
|
|||||||
@ -24,17 +24,17 @@ type UpdateVoteEventRequest struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type VoteEventResponse struct {
|
type VoteEventResponse struct {
|
||||||
ID uuid.UUID `json:"id"`
|
ID uuid.UUID `json:"id"`
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
StartDate time.Time `json:"start_date"`
|
StartDate time.Time `json:"start_date"`
|
||||||
EndDate time.Time `json:"end_date"`
|
EndDate time.Time `json:"end_date"`
|
||||||
IsActive bool `json:"is_active"`
|
IsActive bool `json:"is_active"`
|
||||||
ResultsOpen bool `json:"results_open"`
|
ResultsOpen bool `json:"results_open"`
|
||||||
IsVotingOpen bool `json:"is_voting_open"`
|
IsVotingOpen bool `json:"is_voting_open"`
|
||||||
CreatedAt time.Time `json:"created_at"`
|
CreatedAt time.Time `json:"created_at"`
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
Candidates []CandidateResponse `json:"candidates,omitempty"`
|
Candidates []CandidateResponse `json:"candidates,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ListVoteEventsRequest struct {
|
type ListVoteEventsRequest struct {
|
||||||
@ -90,7 +90,29 @@ type CandidateWithVotesResponse struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type CheckVoteStatusResponse struct {
|
type CheckVoteStatusResponse struct {
|
||||||
HasVoted bool `json:"has_voted"`
|
HasVoted bool `json:"has_voted"`
|
||||||
VotedAt *time.Time `json:"voted_at,omitempty"`
|
VotedAt *time.Time `json:"voted_at,omitempty"`
|
||||||
CandidateID *uuid.UUID `json:"candidate_id,omitempty"`
|
CandidateID *uuid.UUID `json:"candidate_id,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type VoteEventDetailsResponse struct {
|
||||||
|
VoteEvent VoteEventResponse `json:"vote_event"`
|
||||||
|
TotalParticipants int64 `json:"total_participants"`
|
||||||
|
TotalVoted int64 `json:"total_voted"`
|
||||||
|
TotalNotVoted int64 `json:"total_not_voted"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserVoteInfo struct {
|
||||||
|
UserID uuid.UUID `json:"user_id"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
FullName string `json:"full_name"`
|
||||||
|
VotedAt time.Time `json:"voted_at"`
|
||||||
|
CandidateID uuid.UUID `json:"candidate_id"`
|
||||||
|
CandidateName string `json:"candidate_name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserBasicInfo struct {
|
||||||
|
UserID uuid.UUID `json:"user_id"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
FullName string `json:"full_name"`
|
||||||
|
}
|
||||||
|
|||||||
@ -26,6 +26,7 @@ type VoteEventService interface {
|
|||||||
SubmitVote(ctx context.Context, userID uuid.UUID, req *contract.SubmitVoteRequest) (*contract.VoteResponse, error)
|
SubmitVote(ctx context.Context, userID uuid.UUID, req *contract.SubmitVoteRequest) (*contract.VoteResponse, error)
|
||||||
GetVoteResults(ctx context.Context, eventID uuid.UUID) (*contract.VoteResultsResponse, error)
|
GetVoteResults(ctx context.Context, eventID uuid.UUID) (*contract.VoteResultsResponse, error)
|
||||||
CheckVoteStatus(ctx context.Context, userID, eventID uuid.UUID) (*contract.CheckVoteStatusResponse, error)
|
CheckVoteStatus(ctx context.Context, userID, eventID uuid.UUID) (*contract.CheckVoteStatusResponse, error)
|
||||||
|
GetVoteEventDetails(ctx context.Context, eventID uuid.UUID) (*contract.VoteEventDetailsResponse, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type VoteEventHandler struct {
|
type VoteEventHandler struct {
|
||||||
@ -305,6 +306,26 @@ func (h *VoteEventHandler) sendErrorResponse(c *gin.Context, message string, sta
|
|||||||
c.JSON(statusCode, errorResponse)
|
c.JSON(statusCode, errorResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *VoteEventHandler) GetVoteEventDetails(c *gin.Context) {
|
||||||
|
eventIDStr := c.Param("id")
|
||||||
|
eventID, err := uuid.Parse(eventIDStr)
|
||||||
|
if err != nil {
|
||||||
|
logger.FromContext(c).WithError(err).Error("VoteEventHandler::GetVoteEventDetails -> Invalid event ID")
|
||||||
|
h.sendValidationErrorResponse(c, "Invalid event ID", constants.MalformedFieldErrorCode)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
details, err := h.voteEventService.GetVoteEventDetails(c.Request.Context(), eventID)
|
||||||
|
if err != nil {
|
||||||
|
logger.FromContext(c).WithError(err).Error("VoteEventHandler::GetVoteEventDetails -> Failed to get vote event details")
|
||||||
|
h.sendErrorResponse(c, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.FromContext(c).Infof("VoteEventHandler::GetVoteEventDetails -> Successfully retrieved vote event details")
|
||||||
|
c.JSON(http.StatusOK, contract.BuildSuccessResponse(details))
|
||||||
|
}
|
||||||
|
|
||||||
func (h *VoteEventHandler) sendValidationErrorResponse(c *gin.Context, message string, errorCode string) {
|
func (h *VoteEventHandler) sendValidationErrorResponse(c *gin.Context, message string, errorCode string) {
|
||||||
statusCode := constants.HttpErrorMap[errorCode]
|
statusCode := constants.HttpErrorMap[errorCode]
|
||||||
if statusCode == 0 {
|
if statusCode == 0 {
|
||||||
|
|||||||
@ -120,3 +120,21 @@ func (r *VoteEventRepositoryImpl) GetVoteResults(ctx context.Context, eventID uu
|
|||||||
|
|
||||||
return resultMap, nil
|
return resultMap, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *VoteEventRepositoryImpl) GetVotedCount(ctx context.Context, eventID uuid.UUID) (int64, error) {
|
||||||
|
var count int64
|
||||||
|
err := r.db.WithContext(ctx).
|
||||||
|
Model(&entities.Vote{}).
|
||||||
|
Where("vote_event_id = ?", eventID).
|
||||||
|
Count(&count).Error
|
||||||
|
return count, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *VoteEventRepositoryImpl) GetTotalActiveUsersCount(ctx context.Context) (int64, error) {
|
||||||
|
var count int64
|
||||||
|
err := r.db.WithContext(ctx).
|
||||||
|
Model(&entities.User{}).
|
||||||
|
Where("is_active = ?", true).
|
||||||
|
Count(&count).Error
|
||||||
|
return count, err
|
||||||
|
}
|
||||||
@ -93,4 +93,5 @@ type VoteEventHandler interface {
|
|||||||
GetVoteResults(c *gin.Context)
|
GetVoteResults(c *gin.Context)
|
||||||
CheckVoteStatus(c *gin.Context)
|
CheckVoteStatus(c *gin.Context)
|
||||||
GetCandidates(c *gin.Context)
|
GetCandidates(c *gin.Context)
|
||||||
|
GetVoteEventDetails(c *gin.Context)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -174,6 +174,7 @@ func (r *Router) addAppRoutes(rg *gin.Engine) {
|
|||||||
voteEvents.GET("/:id/candidates", r.voteEventHandler.GetCandidates)
|
voteEvents.GET("/:id/candidates", r.voteEventHandler.GetCandidates)
|
||||||
voteEvents.GET("/:id/results", r.voteEventHandler.GetVoteResults)
|
voteEvents.GET("/:id/results", r.voteEventHandler.GetVoteResults)
|
||||||
voteEvents.GET("/:id/vote-status", r.voteEventHandler.CheckVoteStatus)
|
voteEvents.GET("/:id/vote-status", r.voteEventHandler.CheckVoteStatus)
|
||||||
|
voteEvents.GET("/:id/details", r.voteEventHandler.GetVoteEventDetails)
|
||||||
}
|
}
|
||||||
|
|
||||||
candidates := v1.Group("/candidates")
|
candidates := v1.Group("/candidates")
|
||||||
|
|||||||
@ -23,6 +23,8 @@ type VoteEventRepository interface {
|
|||||||
SubmitVote(ctx context.Context, vote *entities.Vote) error
|
SubmitVote(ctx context.Context, vote *entities.Vote) error
|
||||||
HasUserVoted(ctx context.Context, userID, eventID uuid.UUID) (bool, error)
|
HasUserVoted(ctx context.Context, userID, eventID uuid.UUID) (bool, error)
|
||||||
GetVoteResults(ctx context.Context, eventID uuid.UUID) (map[uuid.UUID]int64, error)
|
GetVoteResults(ctx context.Context, eventID uuid.UUID) (map[uuid.UUID]int64, error)
|
||||||
|
GetVotedCount(ctx context.Context, eventID uuid.UUID) (int64, error)
|
||||||
|
GetTotalActiveUsersCount(ctx context.Context) (int64, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type VoteEventServiceImpl struct {
|
type VoteEventServiceImpl struct {
|
||||||
@ -256,3 +258,29 @@ func (s *VoteEventServiceImpl) CheckVoteStatus(ctx context.Context, userID, even
|
|||||||
|
|
||||||
return response, nil
|
return response, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *VoteEventServiceImpl) GetVoteEventDetails(ctx context.Context, eventID uuid.UUID) (*contract.VoteEventDetailsResponse, error) {
|
||||||
|
voteEvent, err := s.voteEventRepo.GetByID(ctx, eventID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
totalParticipants, err := s.voteEventRepo.GetTotalActiveUsersCount(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
totalVoted, err := s.voteEventRepo.GetVotedCount(ctx, eventID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
totalNotVoted := totalParticipants - totalVoted
|
||||||
|
|
||||||
|
return &contract.VoteEventDetailsResponse{
|
||||||
|
VoteEvent: *transformer.VoteEventToContract(voteEvent),
|
||||||
|
TotalParticipants: totalParticipants,
|
||||||
|
TotalVoted: totalVoted,
|
||||||
|
TotalNotVoted: totalNotVoted,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user