add login/register/reset/logout views

This commit is contained in:
2025-01-05 23:54:50 +01:00
parent 273918f542
commit 48491d0786
7 changed files with 271 additions and 25 deletions

View File

@@ -48,7 +48,6 @@ func (uc *UserController) Register(c *gin.Context) {
return
}
//respond
c.JSON(http.StatusOK, gin.H{})
}
@@ -102,22 +101,86 @@ func (uc *UserController) Validate(c *gin.Context) {
}
func (rc *UserController) LoginView(c *gin.Context) {
rooms, _ := repositories.Rooms.GetAll()
//if already logged in
_, exists := c.Get("user")
if exists {
c.HTML(http.StatusOK, "index.html", CreateSessionData(c, gin.H{}))
return
}
data := gin.H{
"title": "Room Page",
"rooms": rooms,
"error": "",
}
c.HTML(http.StatusOK, "login.html", CreateSessionData(c, data))
}
func (rc *UserController) LoginHandler(c *gin.Context) {
email := c.PostForm("email")
password := c.PostForm("password")
tokenString, err := services.Users.Login(email, password)
if err != nil {
data := gin.H{
"error": "Login Failed. Wrong Email or Password!",
}
c.HTML(http.StatusOK, "login.html", data)
return
}
//set this so that CreateSessionData works
//otherwise header would not be generated correctly
user, _ := repositories.Users.GetByEmail(email)
c.Set("user", user)
// send it back
//c.SetSameSite(http.SameSiteLaxMode)
c.SetCookie("Authorization", tokenString, 3600 * 24, "", "", false, true)
c.HTML(http.StatusPermanentRedirect, "index.html", CreateSessionData(c, gin.H{}))
}
func CreateSessionData(c *gin.Context, extra any) gin.H {
_, exists := c.Get("user")
return gin.H{
"test": "HEllo World",
"loggedIn": exists,
"data": extra,
}
}
func (rc *UserController) RegisterHandler(c *gin.Context) {
name := c.PostForm("name")
email := c.PostForm("email")
password := c.PostForm("password")
_, err := services.Users.Register(name, email, password)
if err != nil {
data := gin.H{
"error": "Registering Failed.",
"success": "",
}
c.HTML(http.StatusOK, "register.html", data)
return
}
data := gin.H{
"error": "",
"success": "You successfully registered. Try logging in.",
}
c.HTML(http.StatusOK, "register.html", data)
}
func (rc *UserController) RegisterView(c *gin.Context) {
rooms, _ := repositories.Rooms.GetAll()
data := gin.H{
"title": "Room Page",
"rooms": rooms,
"error": "",
"success": "",
}
c.HTML(http.StatusOK, "register.html", data)
@@ -134,7 +197,7 @@ func (rc *UserController) ResetView(c *gin.Context) {
c.HTML(http.StatusOK, "passwordreset.html", data)
}
func (rc *UserController) MainView(c *gin.Context) {
func (rc *UserController) ResetHandler(c *gin.Context) {
rooms, _ := repositories.Rooms.GetAll()
data := gin.H{
@@ -142,6 +205,20 @@ func (rc *UserController) MainView(c *gin.Context) {
"rooms": rooms,
}
c.HTML(http.StatusOK, "passwordreset.html", data)
}
func (rc *UserController) MainView(c *gin.Context) {
data := CreateSessionData(c, gin.H{
"title": "Room Page",
})
fmt.Println(data)
c.HTML(http.StatusOK, "index.html", data)
}
func (rc *UserController) Logout(c *gin.Context) {
c.SetCookie("Authorization", "", -1, "", "", false, true)
c.HTML(http.StatusOK, "index.html", gin.H{})
}

View File

@@ -71,12 +71,17 @@ func main() {
apiRoutes.GET("/users/validate", authValidator.OptionalAuth, userController.Validate)
}
viewRoutes := server.Group("/")
viewRoutes := server.Group("/", authValidator.OptionalAuth)
{
viewRoutes.GET("/", userController.MainView)
//write middleware that redirects to homescreen on register/login/reset for logged in users
viewRoutes.GET("/login", userController.LoginView)
viewRoutes.GET("/logout", userController.Logout)
viewRoutes.GET("/register", userController.RegisterView)
viewRoutes.GET("/passwordreset", userController.ResetView)
viewRoutes.POST("/login", userController.LoginHandler)
viewRoutes.POST("/register", userController.RegisterHandler)
viewRoutes.POST("/passwordreset", userController.ResetHandler)
}

View File

@@ -1,6 +1,52 @@
<!DOCTYPE html>
<html>
<head>
<title> {{ .title }}</title>
</head>
<body>
<html lang="en">
<head>
<title>FreiRaum</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="/static/output.css" rel="stylesheet">
</head>
<body>
<nav class="bg-gray-800">
<div class="mx-auto max-w-7xl px-4 sm:px-8 lg:px-8">
<div class="relative flex h-16 items-center justify-between">
<div class="flex flex-1 items-center">
<div class="flex shrink-0">
<img class="h-8 w-auto" src="https://tailwindui.com/plus/img/logos/mark.svg?color=indigo&shade=500" alt="Your Company">
</div>
<!--
{{ if .loggedIn }}
<div class="hidden sm:ml-6 sm:block">
<div class="flex space-x-4">
<a href="#" class="block rounded-md px-3 py-2 text-base font-medium text-gray-300 hover:bg-gray-700 hover:text-white">Logged In</a>
</div>
</div>
{{ end }}
-->
</div>
{{ if .loggedIn }}
<div class="absolute inset-y-0 right-0 flex items-center pr-2 sm:static sm:inset-auto sm:ml-6 sm:pr-0 px-4 sm:px-8">
<a href="settings" class="rounded-md bg-gray-900 m-2 px-3 py-2 text-sm font-medium text-gray-300 hover:bg-gray-700 hover:text-white">Settings</a>
<a href="logout" class="rounded-md bg-gray-900 m-2 px-3 py-2 text-sm font-medium text-red-300 hover:bg-gray-700 hover:text-white">Logout</a>
</div>
{{ else }}
<div class="absolute inset-y-0 right-0 flex items-center pr-2 sm:static sm:inset-auto sm:ml-6 sm:pr-0 px-4 sm:px-8">
<a href="login" class="rounded-md bg-gray-900 m-2 px-3 py-2 text-sm font-medium text-gray-300 hover:bg-gray-700 hover:text-white">Login</a>
<a href="register" class="rounded-md bg-gray-900 m-2 px-3 py-2 text-sm font-medium text-gray-300 hover:bg-gray-700 hover:text-white">Register</a>
</div>
{{ end }}
</div>
</div>
<!-- Mobile menu, show/hide based on menu state. -->
<!--
{{ if .loggedIn }}
<div class="sm:hidden" id="mobile-menu">
<div class="space-y-1 px-2 pb-3 pt-2">
<a href="#" class="block rounded-md px-3 py-2 text-base font-medium text-gray-300 hover:bg-gray-700 hover:text-white">Logged In</a>
</div>
</div>
{{ end }}
-->
</nav>

View File

@@ -1,8 +1,3 @@
{{ template "header.html" }}
{{ template "header.html" . }}
{{ range .videos }}
{{ .Title }}
{{ .Description }}
{{ end }}
{{ template "footer.html" }}
{{ template "footer.html" . }}

44
views/login.html Normal file
View File

@@ -0,0 +1,44 @@
{{ template "header.html" . }}
<div class="flex min-h-full flex-col justify-center px-6 py-12 lg:px-8">
<div class="sm:mx-auto sm:w-full sm:max-w-sm">
<img class="mx-auto h-10 w-auto" src="https://tailwindui.com/plus/img/logos/mark.svg?color=indigo&shade=600" alt="Your Company">
<h2 class="mt-10 text-center text-2xl/9 font-bold tracking-tight text-gray-900">Login to your account</h2>
</div>
<div class="mt-10 sm:mx-auto sm:w-full sm:max-w-sm">
<form class="space-y-6" action="/login" method="POST">
<div>
<label for="email" class="block text-sm/6 font-medium text-gray-900">Email address</label>
<div class="mt-2">
<input type="email" name="email" id="email" autocomplete="email" required class="block w-full rounded-md bg-white px-3 py-1.5 text-base text-gray-900 outline outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline focus:outline-2 focus:-outline-offset-2 focus:outline-indigo-600 sm:text-sm/6">
</div>
</div>
<div>
<div class="flex items-center justify-between">
<label for="password" class="block text-sm/6 font-medium text-gray-900">Password</label>
<div class="text-sm">
<a href="passwordreset" class="font-semibold text-indigo-600 hover:text-indigo-500">Forgot password?</a>
</div>
</div>
<div class="mt-2">
<input type="password" name="password" id="password" autocomplete="current-password" required class="block w-full rounded-md bg-white px-3 py-1.5 text-base text-gray-900 outline outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline focus:outline-2 focus:-outline-offset-2 focus:outline-indigo-600 sm:text-sm/6">
</div>
</div>
<p class="mt-10 text-center text-sm/6 text-red-500">
{{ .error }}
</p>
<div>
<button type="submit" class="flex w-full justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm/6 font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">Login</button>
</div>
</form>
</div>
</div>
{{ template "footer.html" . }}

28
views/passwordreset.html Normal file
View File

@@ -0,0 +1,28 @@
{{ template "header.html" }}
<div class="flex min-h-full flex-col justify-center px-6 py-12 lg:px-8">
<div class="sm:mx-auto sm:w-full sm:max-w-sm">
<img class="mx-auto h-10 w-auto" src="https://tailwindui.com/plus/img/logos/mark.svg?color=indigo&shade=600" alt="Your Company">
<h2 class="mt-10 text-center text-2xl/9 font-bold tracking-tight text-gray-900">Reset your password</h2>
</div>
<div class="mt-10 sm:mx-auto sm:w-full sm:max-w-sm">
<form class="space-y-6" action="#" method="POST">
<div>
<label for="email" class="block text-sm/6 font-medium text-gray-900">Email address</label>
<div class="mt-2">
<input type="email" name="email" id="email" autocomplete="email" required class="block w-full rounded-md bg-white px-3 py-1.5 text-base text-gray-900 outline outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline focus:outline-2 focus:-outline-offset-2 focus:outline-indigo-600 sm:text-sm/6">
</div>
</div>
<div>
<button type="submit" class="flex w-full justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm/6 font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">Request reset</button>
</div>
</form>
<p class="mt-10 text-center text-sm/6 text-gray-500">
We will send you an E-Mail with a new password.
</p>
</div>
</div>
{{ template "footer.html" }}

51
views/register.html Normal file
View File

@@ -0,0 +1,51 @@
{{ template "header.html" . }}
<div class="flex min-h-full flex-col justify-center px-6 py-12 lg:px-8">
<div class="sm:mx-auto sm:w-full sm:max-w-sm">
<img class="mx-auto h-10 w-auto" src="https://tailwindui.com/plus/img/logos/mark.svg?color=indigo&shade=600" alt="Your Company">
<h2 class="mt-10 text-center text-2xl/9 font-bold tracking-tight text-gray-900">Register your account</h2>
</div>
<div class="mt-10 sm:mx-auto sm:w-full sm:max-w-sm">
<form class="space-y-6" action="#" method="POST">
<div>
<label for="name" class="block text-sm/6 font-medium text-gray-900">Username</label>
<div class="mt-2">
<input type="text" name="name" id="name" required class="block w-full rounded-md bg-white px-3 py-1.5 text-base text-gray-900 outline outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline focus:outline-2 focus:-outline-offset-2 focus:outline-indigo-600 sm:text-sm/6">
</div>
</div>
<div>
<label for="email" class="block text-sm/6 font-medium text-gray-900">Email address</label>
<div class="mt-2">
<input type="email" name="email" id="email" autocomplete="email" required class="block w-full rounded-md bg-white px-3 py-1.5 text-base text-gray-900 outline outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline focus:outline-2 focus:-outline-offset-2 focus:outline-indigo-600 sm:text-sm/6">
</div>
</div>
<div>
<div class="flex items-center justify-between">
<label for="password" class="block text-sm/6 font-medium text-gray-900">Password</label>
</div>
<div class="mt-2">
<input type="password" name="password" id="password" autocomplete="current-password" required class="block w-full rounded-md bg-white px-3 py-1.5 text-base text-gray-900 outline outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline focus:outline-2 focus:-outline-offset-2 focus:outline-indigo-600 sm:text-sm/6">
</div>
</div>
<p class="mt-10 text-center text-sm/6 text-red-500">
{{ .error }}
</p>
<p class="mt-10 text-center text-sm/6 text-green-500">
{{ .success }}
</p>
<div>
<button type="submit" class="flex w-full justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm/6 font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">Register</button>
</div>
</form>
</div>
</div>
{{ template "footer.html" . }}