(FEAT): Profile page is wired to backend.
This required service and repo creation for the users. Logging out is not yet supported, but that is next.
This commit is contained in:
parent
a1f8fe60db
commit
6572c31ed4
@ -46,7 +46,12 @@ func GoogleCallback(ctx *gin.Context) {
|
||||
false, // TODO: True in prod
|
||||
true,
|
||||
)
|
||||
ctx.JSON(http.StatusOK, gin.H{"jwt": jwt, "googleUserInfo": googleUserInfo, "dbUser": dbUser})
|
||||
|
||||
// ctx.JSON(http.StatusOK, gin.H{"jwt": jwt, "googleUserInfo": googleUserInfo, "dbUser": dbUser})
|
||||
_ = dbUser
|
||||
_ = googleUserInfo
|
||||
|
||||
ctx.Redirect(http.StatusSeeOther, "/")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,10 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
domain "github.com/haydenhargreaves/Potion/internal/domain/server"
|
||||
layouts "github.com/haydenhargreaves/Potion/internal/templates/layouts"
|
||||
pages "github.com/haydenhargreaves/Potion/internal/templates/pages"
|
||||
)
|
||||
@ -35,8 +38,18 @@ func CreatePage(ctx *gin.Context) {
|
||||
}
|
||||
|
||||
func ProfilePage(ctx *gin.Context) {
|
||||
// If not logged in, direct to the login page
|
||||
if !domain.IsLoggedIn(ctx) {
|
||||
ctx.Redirect(http.StatusSeeOther, "/v1/web/login")
|
||||
return
|
||||
}
|
||||
|
||||
// Else, get the user data
|
||||
deps := ctx.MustGet("deps").(*domain.InjectedDependencies)
|
||||
user := deps.UserService.GetAuthenicatedUser(ctx)
|
||||
|
||||
title := "Potion - Profile"
|
||||
page := pages.ProfilePage()
|
||||
page := pages.ProfilePage(user)
|
||||
|
||||
ctx.HTML(200, "", layouts.AppLayout(title, page))
|
||||
}
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
package service
|
||||
|
||||
import domain "github.com/haydenhargreaves/Potion/internal/domain/user"
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
domain "github.com/haydenhargreaves/Potion/internal/domain/user"
|
||||
)
|
||||
|
||||
// UserService implements the domain.UserService defined in the domain module.
|
||||
type UserService struct {
|
||||
@ -15,3 +18,18 @@ var _ domain.UserService = (*UserService)(nil)
|
||||
func NewUserService(userRepository domain.UserRepository) domain.UserService {
|
||||
return &UserService{userRepository: userRepository}
|
||||
}
|
||||
|
||||
func (s *UserService) GetAuthenicatedUser(ctx *gin.Context) domain.User {
|
||||
val, ok := ctx.Get("userId")
|
||||
if !ok {
|
||||
return domain.User{}
|
||||
}
|
||||
|
||||
id := val.(int)
|
||||
user, err := s.userRepository.GetUserById(id)
|
||||
if err != nil {
|
||||
return domain.User{}
|
||||
}
|
||||
|
||||
return *user
|
||||
}
|
||||
|
||||
@ -3,4 +3,5 @@ package domain
|
||||
type UserRepository interface {
|
||||
CreateGoogleUser(googleUserInfo *GoogleUserInfo, googleRefreshToken string) (User, error)
|
||||
GetGoogleUser(googleId string) (*User, error)
|
||||
GetUserById(id int) (*User, error)
|
||||
}
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
package domain
|
||||
|
||||
import "github.com/gin-gonic/gin"
|
||||
|
||||
type UserService interface {
|
||||
GetAuthenicatedUser(ctx *gin.Context) User
|
||||
}
|
||||
|
||||
@ -105,3 +105,39 @@ func (r *UserRepository) GetGoogleUser(googleId string) (*domain.User, error) {
|
||||
|
||||
return &user, nil
|
||||
}
|
||||
|
||||
func (r *UserRepository) GetUserById(id int) (*domain.User, error) {
|
||||
tx, err := r.db.Begin()
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var user domain.User
|
||||
query := `SELECT * FROM users WHERE id = $1`
|
||||
|
||||
if err := tx.QueryRow(query, id).Scan(
|
||||
&user.Id,
|
||||
&user.GoogleId,
|
||||
&user.Name,
|
||||
&user.Email,
|
||||
&user.ImageUrl,
|
||||
&user.GoogleRefreshToken,
|
||||
&user.Created,
|
||||
); err != nil {
|
||||
// If no user was found, don't error, just return
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, nil
|
||||
}
|
||||
tx.Rollback()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := tx.Commit(); err != nil {
|
||||
tx.Rollback()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &user, nil
|
||||
|
||||
}
|
||||
|
||||
@ -1,38 +1,37 @@
|
||||
package templates
|
||||
|
||||
import "github.com/haydenhargreaves/Potion/internal/templates/components"
|
||||
import "github.com/haydenhargreaves/Potion/internal/domain/user"
|
||||
|
||||
templ userDetailsSection(name, email, url string) {
|
||||
<section class="w-full flex flex-col justify-center my-8 py-4 border-b border-gray-300">
|
||||
<div class="w-full p-4 md:p-8 flex items-center gap-x-8">
|
||||
<img class="w-24 md:w-32 border-2 border-blue-500 rounded-full shadow-blue-500 shadow select-none" src={ url }/>
|
||||
<div class="">
|
||||
<h1 class="text-md md:text-2xl font-semibold">{ name }</h1>
|
||||
<p class="text-xs md:text-sm">{ email }</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
templ userDetailsSection(user domain.User) {
|
||||
<section class="w-full flex flex-col justify-center my-8 py-4 border-b border-gray-300">
|
||||
<div class="w-full p-4 md:p-8 flex items-center gap-x-8">
|
||||
<img class="w-24 md:w-32 border-2 border-blue-500 rounded-full shadow-blue-500 shadow select-none" src={
|
||||
user.ImageUrl } />
|
||||
<div class="">
|
||||
<h1 class="text-md md:text-2xl font-semibold">{ user.Name }</h1>
|
||||
<p class="text-xs md:text-sm">{ user.Email }</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
}
|
||||
|
||||
templ logoutSection() {
|
||||
<section class="w-full flex flex-col justify-center items-center py-8 border-t border-gray-300">
|
||||
<button
|
||||
class="border border-red-500 text-red-500 w-9/10 md:w-1/3 py-2 rounded-lg hover:cursor-pointer hover:bg-red-100 duration-300"
|
||||
>
|
||||
Logout
|
||||
</button>
|
||||
</section>
|
||||
<section class="w-full flex flex-col justify-center items-center py-8 border-t border-gray-300">
|
||||
<button
|
||||
class="border border-red-500 text-red-500 w-9/10 md:w-1/3 py-2 rounded-lg hover:cursor-pointer hover:bg-red-100 duration-300">
|
||||
Logout
|
||||
</button>
|
||||
</section>
|
||||
}
|
||||
|
||||
templ ProfilePage() {
|
||||
@components.Navbar(" profile")
|
||||
<div class="w-full h-screen flex justify-center">
|
||||
<div
|
||||
class="mx-2 md:mx-0 w-full md:w-1/2 md:pt-14 border-l border-r border-gray-300 bg-white flex flex-col justify-between"
|
||||
>
|
||||
@userDetailsSection("Hayden Hargreaves", "hhargreaves2006@gmail.com",
|
||||
"https://lh3.googleusercontent.com/a/ACg8ocLeT6ltjQIkiBy1MgMJDbQxtBfMVfn8sP4e1t7d0bCJeHFdpcea=s96-c")
|
||||
@logoutSection()
|
||||
</div>
|
||||
</div>
|
||||
templ ProfilePage(user domain.User) {
|
||||
@components.Navbar(" profile")
|
||||
<div class="w-full h-screen flex justify-center">
|
||||
<div
|
||||
class="mx-2 md:mx-0 w-full md:w-1/2 md:pt-14 border-l border-r border-gray-300 bg-white flex flex-col justify-between">
|
||||
@userDetailsSection(user)
|
||||
@logoutSection()
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@ -9,8 +9,9 @@ import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import "github.com/haydenhargreaves/Potion/internal/templates/components"
|
||||
import "github.com/haydenhargreaves/Potion/internal/domain/user"
|
||||
|
||||
func userDetailsSection(name, email, url string) templ.Component {
|
||||
func userDetailsSection(user domain.User) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
@ -36,9 +37,10 @@ func userDetailsSection(name, email, url string) templ.Component {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var2 string
|
||||
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(url)
|
||||
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(
|
||||
user.ImageUrl)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/profile.templ`, Line: 8, Col: 111}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/profile.templ`, Line: 10, Col: 19}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -49,9 +51,9 @@ func userDetailsSection(name, email, url string) templ.Component {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(name)
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(user.Name)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/profile.templ`, Line: 10, Col: 56}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/profile.templ`, Line: 12, Col: 63}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -62,9 +64,9 @@ func userDetailsSection(name, email, url string) templ.Component {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(email)
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(user.Email)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/profile.templ`, Line: 11, Col: 41}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/profile.templ`, Line: 13, Col: 48}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -107,7 +109,7 @@ func logoutSection() templ.Component {
|
||||
})
|
||||
}
|
||||
|
||||
func ProfilePage() templ.Component {
|
||||
func ProfilePage(user domain.User) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
@ -136,8 +138,7 @@ func ProfilePage() templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = userDetailsSection("Hayden Hargreaves", "hhargreaves2006@gmail.com",
|
||||
"https://lh3.googleusercontent.com/a/ACg8ocLeT6ltjQIkiBy1MgMJDbQxtBfMVfn8sP4e1t7d0bCJeHFdpcea=s96-c").Render(ctx, templ_7745c5c3_Buffer)
|
||||
templ_7745c5c3_Err = userDetailsSection(user).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user