Grouping route

This commit is contained in:
2024-10-02 15:33:41 +07:00
parent 5d7dc70f1b
commit 93c44f40cc
41 changed files with 1176 additions and 1158 deletions

View File

@ -7,38 +7,27 @@ import (
templ form(err types.Message, title string) {
@layout.Base(title){
<div class="dark flex items-center min-h-screen p-4 sm:p-6 bg-gray-900">
<div class="mx-auto w-full max-w-md space-y-8">
<header class="text-center">
<div class="space-y-2">
<h1 class="text-3xl font-bold text-white">Set Up Your Account</h1>
<p class="text-gray-500 dark:text-gray-400">Enter your information to create a new account</p>
switch err.Code {
case 0:
<div class="p-4 mb-4 text-sm text-red-800 rounded-lg bg-red-50 dark:bg-gray-800 dark:text-red-400" role="alert">
{err.Message}
</div>
case 1:
<div class="p-4 mb-4 text-sm text-green-800 rounded-lg bg-green-50 dark:bg-gray-800 dark:text-green-400" role="alert">
{err.Message}
</div>
}
<div class="bg-gray-100 flex items-center justify-center min-h-screen">
<div class="bg-white p-8 rounded-lg shadow-md w-full max-w-md">
<h1 class="text-2xl font-bold mb-6 text-center text-gray-800">Sign Up</h1>
<form action="" method="POST" class="space-y-4">
<div>
<label for="username" class="block text-sm font-medium text-gray-700">Username</label>
<input type="text" id="username" name="username" required
class="mt-1 block w-full px-3 py-2 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500">
</div>
</header>
<form class="space-y-4" method="post" action="">
<div class="space-y-2">
<label class="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 text-white" for="username">Username</label>
<input type="text" class="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:bg-gray-800 dark:text-white" id="username" name="username" required="" />
<div>
<label for="password" class="block text-sm font-medium text-gray-700">Password</label>
<input type="password" id="password" name="password" required
class="mt-1 block w-full px-3 py-2 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500">
</div>
<div class="space-y-2">
<label class="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 text-white" for="password">Password</label>
<input type="password" class="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:bg-gray-800 dark:text-white" id="password" name="password" required />
</div>
<div class="space-y-2">
<label class="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 text-white" for="confirmPassword">Confirm Password</label>
<input type="password" class="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:bg-gray-800 dark:text-white" id="confirmPassword" required />
</div>
<div class="flex justify-start mt-3 ml-4 p-1">
<div>
<label for="confirmPassword" class="block text-sm font-medium text-gray-700">Confirm Password</label>
<input type="password" id="confirmPassword" name="confirmPassword" required
class="mt-1 block w-full px-3 py-2 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500">
</div>
<div>
<div id="checkContainer" class="flex justify-start mt-1 block w-full px-3 py-2 hidden">
<ul>
<li class="flex items-center py-1">
<div id="matchSvgContainer" class="rounded-full p-1 fill-current bg-red-200 text-green-700">
@ -69,19 +58,26 @@ templ form(err types.Message, title string) {
</li>
</ul>
</div>
<button class="bg-slate-200 inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-primary text-primary-foreground hover:bg-primary/90 h-10 px-4 py-2 w-full" type="submit" id="submit" name="submit" disabled>
Sign up
</button>
<button id="submit"
type="submit"
disabled
class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 disabled:pointer-events-none disabled:opacity-50">
Sign Up
</button>
</div>
</form>
<div class="text-center text-sm text-white">
Already have an account?
<a class="underline" href="/signin" rel="ugc" hx-get="/signin" hx-swap="outerHTML" hx-push-url="true" hx-target="#content">
Sign in
</a>
<div class="mt-6 text-center">
<p class="text-sm text-gray-600">
Already have an account?
<a class="underline" href="/auth/signin" rel="ugc" hx-get="/auth/signin" hx-swap="outerHTML" hx-push-url="true"
hx-target="#content" class="font-medium text-indigo-600 hover:text-indigo-500">
Log in
</a>
</p>
</div>
</div>
<script src="/public/validatePassword.js" />
</div>
<script src="/public/validatePassword.js" />
}
}

View File

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.2.778
// templ: version: v0.2.786
package authView
//lint:file-ignore SA4006 This context is only used if a nested component is present.
@ -46,49 +46,7 @@ func form(err types.Message, title string) templ.Component {
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 1)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
switch err.Code {
case 0:
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 2)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(err.Message)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/client/auth/auth.templ`, Line: 19, Col: 38}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 3)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
case 1:
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 4)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var4 string
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(err.Message)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/client/auth/auth.templ`, Line: 23, Col: 38}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 5)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 6)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"bg-gray-100 flex items-center justify-center min-h-screen\"><div class=\"bg-white p-8 rounded-lg shadow-md w-full max-w-md\"><h1 class=\"text-2xl font-bold mb-6 text-center text-gray-800\">Sign Up</h1><form action=\"\" method=\"POST\" class=\"space-y-4\"><div><label for=\"username\" class=\"block text-sm font-medium text-gray-700\">Username</label> <input type=\"text\" id=\"username\" name=\"username\" required class=\"mt-1 block w-full px-3 py-2 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500\"></div><div><label for=\"password\" class=\"block text-sm font-medium text-gray-700\">Password</label> <input type=\"password\" id=\"password\" name=\"password\" required class=\"mt-1 block w-full px-3 py-2 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500\"></div><div><label for=\"confirmPassword\" class=\"block text-sm font-medium text-gray-700\">Confirm Password</label> <input type=\"password\" id=\"confirmPassword\" name=\"confirmPassword\" required class=\"mt-1 block w-full px-3 py-2 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500\"></div><div><div id=\"checkContainer\" class=\"flex justify-start mt-1 block w-full px-3 py-2 hidden\"><ul><li class=\"flex items-center py-1\"><div id=\"matchSvgContainer\" class=\"rounded-full p-1 fill-current bg-red-200 text-green-700\"><svg id=\"matchSvgIcon\" class=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\"><path id=\"matchGoodPath\" style=\"display: none;\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 13l4 4L19 7\"></path> <path id=\"matchBadPath\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6 18L18 6M6 6l12 12\"></path></svg></div><span id=\"matchStatusText\" class=\"font-medium text-sm ml-3 text-red-700\">Passwords do not match</span></li><li class=\"flex items-center py-1\"><div id=\"uppercaseSvgContainer\" class=\"rounded-full p-1 fill-current bg-red-200 text-green-700\"><svg id=\"uppercaseSvgIcon\" class=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\"><path id=\"uppercaseGoodPath\" style=\"display: none;\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 13l4 4L19 7\"></path> <path id=\"uppercaseBadPath\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6 18L18 6M6 6l12 12\"></path></svg></div><span id=\"uppercaseStatusText\" class=\"font-medium text-sm ml-3 text-red-700\">Password must contain at least one uppercase letter</span></li><li class=\"flex items-center py-1\"><div id=\"lengthSvgContainer\" class=\"rounded-full p-1 fill-current bg-red-200 text-green-700\"><svg id=\"lengthSvgIcon\" class=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\"><path id=\"lengthGoodPath\" style=\"display: none;\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 13l4 4L19 7\"></path> <path id=\"lengthBadPath\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6 18L18 6M6 6l12 12\"></path></svg></div><span id=\"lengthStatusText\" class=\"font-medium text-sm ml-3 text-red-700\">Password length must be at least 8 characters</span></li></ul></div><button id=\"submit\" type=\"submit\" disabled class=\"w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 disabled:pointer-events-none disabled:opacity-50\">Sign Up</button></div></form><div class=\"mt-6 text-center\"><p class=\"text-sm text-gray-600\">Already have an account? <a class=\"underline\" href=\"/auth/signin\" rel=\"ugc\" hx-get=\"/auth/signin\" hx-swap=\"outerHTML\" hx-push-url=\"true\" hx-target=\"#content\" class=\"font-medium text-indigo-600 hover:text-indigo-500\">Log in</a></p></div></div><script src=\"/public/validatePassword.js\"></script></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@ -118,9 +76,9 @@ func GoogleSetup(title string, err types.Message) templ.Component {
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var5 := templ.GetChildren(ctx)
if templ_7745c5c3_Var5 == nil {
templ_7745c5c3_Var5 = templ.NopComponent
templ_7745c5c3_Var3 := templ.GetChildren(ctx)
if templ_7745c5c3_Var3 == nil {
templ_7745c5c3_Var3 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = form(err, title).Render(ctx, templ_7745c5c3_Buffer)

View File

@ -0,0 +1,182 @@
package forgotPasswordView
import (
"github.com/fossyy/filekeeper/types"
"github.com/fossyy/filekeeper/view/client/layout"
)
templ content(title string, err types.Message) {
@layout.Base(title){
<div class="bg-gray-100 flex items-center justify-center min-h-screen">
<div class="bg-white p-8 rounded-lg shadow-md w-full max-w-md">
<h1 class="text-2xl font-bold mb-6 text-center text-gray-800">Forgot Password</h1>
<p class="text-gray-600 text-sm mb-6 text-center">Enter your email address and we'll send you instructions to reset your password.</p>
<form action="#" method="POST" class="space-y-4">
switch err.Code {
case 0:
<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative mb-4" role="alert">
<strong class="font-bold">Error!</strong>
<span class="block sm:inline"> {err.Message} </span>
</div>
}
<div>
<label for="email" class="block text-sm font-medium text-gray-700">Email</label>
<input type="email" id="email" name="email" required
class="mt-1 block w-full px-3 py-2 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500">
</div>
<div>
<button type="submit"
class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
Send Reset Instructions
</button>
</div>
</form>
<div class="mt-6 flex items-center justify-between">
<div class="text-sm">
<a href="/auth/signin" rel="ugc" hx-get="/auth/signin" hx-swap="outerHTML" hx-push-url="true" hx-target="#content" class="font-medium text-indigo-600 hover:text-indigo-500">
Return to Login
</a>
</div>
<div class="text-sm">
<a href="/auth/signup" rel="ugc" hx-get="/auth/signup" hx-swap="outerHTML" hx-push-url="true" hx-target="#content" class="font-medium text-indigo-600 hover:text-indigo-500">
Create an account
</a>
</div>
</div>
</div>
</div>
}
}
templ Main(title string, err types.Message) {
@content(title, err)
}
templ NewPasswordForm(title string, err types.Message) {
@layout.Base(title){
<div class="dark flex items-center min-h-screen p-4 sm:p-6 bg-gray-900">
<div class="mx-auto w-full max-w-md space-y-8">
<header class="text-center">
<div class="space-y-2">
<h1 class="text-3xl font-bold text-white">Forgot password</h1>
<p class="text-gray-500 dark:text-gray-400">Enter your email below to reset your password</p>
switch err.Code {
case 0:
<div class="p-4 mb-4 text-sm text-red-800 rounded-lg bg-red-50 dark:bg-gray-800 dark:text-red-400" role="alert">
{err.Message}
</div>
}
</div>
</header>
<form class="space-y-4" method="post" action="">
<div class="space-y-2">
<label class="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 text-white" for="password">Password</label>
<input type="password" class="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:bg-gray-800 dark:text-white" id="password" name="password" required />
</div>
<div class="space-y-2">
<label class="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 text-white" for="confirmPassword">Confirm Password</label>
<input type="password" class="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:bg-gray-800 dark:text-white" id="confirmPassword" required />
</div>
<div class="flex justify-start mt-3 ml-4 p-1">
<ul>
<li class="flex items-center py-1">
<div id="matchSvgContainer" class="rounded-full p-1 fill-current bg-red-200 text-green-700">
<svg id="matchSvgIcon" class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path id="matchGoodPath" style="display: none;" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
<path id="matchBadPath" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
</svg>
</div>
<span id="matchStatusText" class="font-medium text-sm ml-3 text-red-700"> Passwords do not match</span>
</li>
<li class="flex items-center py-1">
<div id="uppercaseSvgContainer" class="rounded-full p-1 fill-current bg-red-200 text-green-700">
<svg id="uppercaseSvgIcon" class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path id="uppercaseGoodPath" style="display: none;" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
<path id="uppercaseBadPath" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
</svg>
</div>
<span id="uppercaseStatusText" class="font-medium text-sm ml-3 text-red-700"> Password must contain at least one uppercase letter</span>
</li>
<li class="flex items-center py-1">
<div id="lengthSvgContainer" class="rounded-full p-1 fill-current bg-red-200 text-green-700">
<svg id="lengthSvgIcon" class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path id="lengthGoodPath" style="display: none;" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
<path id="lengthBadPath" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
</svg>
</div>
<span id="lengthStatusText" class="font-medium text-sm ml-3 text-red-700"> Password length must be at least 8 characters</span>
</li>
</ul>
</div>
<button class="bg-slate-200 inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-primary text-primary-foreground hover:bg-primary/90 h-10 px-4 py-2 w-full" type="submit" id="submit" name="submit" disabled>
Submit
</button>
</form>
</div>
</div>
<script src="/public/validatePassword.js" />
}
}
templ EmailSend(title string) {
@layout.Base(title){
<style>h1, h2, h3, h4, h5, h6 { font-family: 'Arimo', sans-serif; --font-sans: 'Arimo'; }</style>
<style>body { font-family: 'Libre Franklin', sans-serif; --font-sans: 'Libre Franklin'; }</style>
<div class="flex flex-col items-center justify-center min-h-[80vh] gap-6">
<div class="flex items-center justify-center">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="h-16 w-16 text-gray-500 dark:text-gray-400"
>
<rect width="20" height="16" x="2" y="4" rx="2"></rect>
<path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"></path>
</svg>
</div>
<div class="space-y-2 text-center">
<h1 class="text-3xl font-bold">Email Verification Sent</h1>
<p class="text-gray-500 dark:text-gray-400">
We've sent a verification email to your inbox. Please check your email and follow the instructions to change your password.
</p>
</div>
</div>
}
}
templ ChangeSuccess(title string) {
@layout.Base(title){
<style>h1, h2, h3, h4, h5, h6 { font-family: 'Arimo', sans-serif; --font-sans: 'Arimo'; }</style>
<style>body { font-family: 'Libre Franklin', sans-serif; --font-sans: 'Libre Franklin'; }</style>
<div class="flex flex-col items-center justify-center min-h-[80vh] gap-6">
<div class="bg-green-500 text-white rounded-full p-4">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="h-8 w-8"
>
<polyline points="20 6 9 17 4 12"></polyline>
</svg>
</div>
<div class="space-y-2 text-center">
<h1 class="text-3xl font-bold">Password Changed Successfully</h1>
<p class="text-gray-500 dark:text-gray-400">
Your password has been successfully updated. Feel free to continue enjoying our platform.
</p>
</div>
</div>
}
}

View File

@ -0,0 +1,281 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.2.786
package forgotPasswordView
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import (
"github.com/fossyy/filekeeper/types"
"github.com/fossyy/filekeeper/view/client/layout"
)
func content(title string, err types.Message) 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 {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"bg-gray-100 flex items-center justify-center min-h-screen\"><div class=\"bg-white p-8 rounded-lg shadow-md w-full max-w-md\"><h1 class=\"text-2xl font-bold mb-6 text-center text-gray-800\">Forgot Password</h1><p class=\"text-gray-600 text-sm mb-6 text-center\">Enter your email address and we'll send you instructions to reset your password.</p><form action=\"#\" method=\"POST\" class=\"space-y-4\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
switch err.Code {
case 0:
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative mb-4\" role=\"alert\"><strong class=\"font-bold\">Error!</strong> <span class=\"block sm:inline\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(err.Message)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/client/auth/forgotPassword/forgotPassword.templ`, Line: 19, Col: 75}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</span></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div><label for=\"email\" class=\"block text-sm font-medium text-gray-700\">Email</label> <input type=\"email\" id=\"email\" name=\"email\" required class=\"mt-1 block w-full px-3 py-2 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500\"></div><div><button type=\"submit\" class=\"w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500\">Send Reset Instructions</button></div></form><div class=\"mt-6 flex items-center justify-between\"><div class=\"text-sm\"><a href=\"/auth/signin\" rel=\"ugc\" hx-get=\"/auth/signin\" hx-swap=\"outerHTML\" hx-push-url=\"true\" hx-target=\"#content\" class=\"font-medium text-indigo-600 hover:text-indigo-500\">Return to Login</a></div><div class=\"text-sm\"><a href=\"/auth/signup\" rel=\"ugc\" hx-get=\"/auth/signup\" hx-swap=\"outerHTML\" hx-push-url=\"true\" hx-target=\"#content\" class=\"font-medium text-indigo-600 hover:text-indigo-500\">Create an account</a></div></div></div></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
templ_7745c5c3_Err = layout.Base(title).Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
func Main(title string, err types.Message) 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 {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var4 := templ.GetChildren(ctx)
if templ_7745c5c3_Var4 == nil {
templ_7745c5c3_Var4 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = content(title, err).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
func NewPasswordForm(title string, err types.Message) 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 {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var5 := templ.GetChildren(ctx)
if templ_7745c5c3_Var5 == nil {
templ_7745c5c3_Var5 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Var6 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"dark flex items-center min-h-screen p-4 sm:p-6 bg-gray-900\"><div class=\"mx-auto w-full max-w-md space-y-8\"><header class=\"text-center\"><div class=\"space-y-2\"><h1 class=\"text-3xl font-bold text-white\">Forgot password</h1><p class=\"text-gray-500 dark:text-gray-400\">Enter your email below to reset your password</p>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
switch err.Code {
case 0:
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"p-4 mb-4 text-sm text-red-800 rounded-lg bg-red-50 dark:bg-gray-800 dark:text-red-400\" role=\"alert\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var7 string
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(err.Message)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/client/auth/forgotPassword/forgotPassword.templ`, Line: 66, Col: 38}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div></header><form class=\"space-y-4\" method=\"post\" action=\"\"><div class=\"space-y-2\"><label class=\"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 text-white\" for=\"password\">Password</label> <input type=\"password\" class=\"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:bg-gray-800 dark:text-white\" id=\"password\" name=\"password\" required></div><div class=\"space-y-2\"><label class=\"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 text-white\" for=\"confirmPassword\">Confirm Password</label> <input type=\"password\" class=\"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:bg-gray-800 dark:text-white\" id=\"confirmPassword\" required></div><div class=\"flex justify-start mt-3 ml-4 p-1\"><ul><li class=\"flex items-center py-1\"><div id=\"matchSvgContainer\" class=\"rounded-full p-1 fill-current bg-red-200 text-green-700\"><svg id=\"matchSvgIcon\" class=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\"><path id=\"matchGoodPath\" style=\"display: none;\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 13l4 4L19 7\"></path> <path id=\"matchBadPath\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6 18L18 6M6 6l12 12\"></path></svg></div><span id=\"matchStatusText\" class=\"font-medium text-sm ml-3 text-red-700\">Passwords do not match</span></li><li class=\"flex items-center py-1\"><div id=\"uppercaseSvgContainer\" class=\"rounded-full p-1 fill-current bg-red-200 text-green-700\"><svg id=\"uppercaseSvgIcon\" class=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\"><path id=\"uppercaseGoodPath\" style=\"display: none;\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 13l4 4L19 7\"></path> <path id=\"uppercaseBadPath\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6 18L18 6M6 6l12 12\"></path></svg></div><span id=\"uppercaseStatusText\" class=\"font-medium text-sm ml-3 text-red-700\">Password must contain at least one uppercase letter</span></li><li class=\"flex items-center py-1\"><div id=\"lengthSvgContainer\" class=\"rounded-full p-1 fill-current bg-red-200 text-green-700\"><svg id=\"lengthSvgIcon\" class=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\"><path id=\"lengthGoodPath\" style=\"display: none;\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 13l4 4L19 7\"></path> <path id=\"lengthBadPath\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6 18L18 6M6 6l12 12\"></path></svg></div><span id=\"lengthStatusText\" class=\"font-medium text-sm ml-3 text-red-700\">Password length must be at least 8 characters</span></li></ul></div><button class=\"bg-slate-200 inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-primary text-primary-foreground hover:bg-primary/90 h-10 px-4 py-2 w-full\" type=\"submit\" id=\"submit\" name=\"submit\" disabled>Submit</button></form></div></div><script src=\"/public/validatePassword.js\"></script>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
templ_7745c5c3_Err = layout.Base(title).Render(templ.WithChildren(ctx, templ_7745c5c3_Var6), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
func EmailSend(title string) 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 {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var8 := templ.GetChildren(ctx)
if templ_7745c5c3_Var8 == nil {
templ_7745c5c3_Var8 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Var9 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<style>h1, h2, h3, h4, h5, h6 { font-family: 'Arimo', sans-serif; --font-sans: 'Arimo'; }</style> <style>body { font-family: 'Libre Franklin', sans-serif; --font-sans: 'Libre Franklin'; }</style> <div class=\"flex flex-col items-center justify-center min-h-[80vh] gap-6\"><div class=\"flex items-center justify-center\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"h-16 w-16 text-gray-500 dark:text-gray-400\"><rect width=\"20\" height=\"16\" x=\"2\" y=\"4\" rx=\"2\"></rect> <path d=\"m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7\"></path></svg></div><div class=\"space-y-2 text-center\"><h1 class=\"text-3xl font-bold\">Email Verification Sent</h1><p class=\"text-gray-500 dark:text-gray-400\">We've sent a verification email to your inbox. Please check your email and follow the instructions to change your password.</p></div></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
templ_7745c5c3_Err = layout.Base(title).Render(templ.WithChildren(ctx, templ_7745c5c3_Var9), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
func ChangeSuccess(title string) 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 {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var10 := templ.GetChildren(ctx)
if templ_7745c5c3_Var10 == nil {
templ_7745c5c3_Var10 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Var11 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<style>h1, h2, h3, h4, h5, h6 { font-family: 'Arimo', sans-serif; --font-sans: 'Arimo'; }</style> <style>body { font-family: 'Libre Franklin', sans-serif; --font-sans: 'Libre Franklin'; }</style> <div class=\"flex flex-col items-center justify-center min-h-[80vh] gap-6\"><div class=\"bg-green-500 text-white rounded-full p-4\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"h-8 w-8\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg></div><div class=\"space-y-2 text-center\"><h1 class=\"text-3xl font-bold\">Password Changed Successfully</h1><p class=\"text-gray-500 dark:text-gray-400\">Your password has been successfully updated. Feel free to continue enjoying our platform.</p></div></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
templ_7745c5c3_Err = layout.Base(title).Render(templ.WithChildren(ctx, templ_7745c5c3_Var11), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
var _ = templruntime.GeneratedTemplate

View File

@ -0,0 +1,88 @@
package signinView
import (
"github.com/fossyy/filekeeper/types"
"github.com/fossyy/filekeeper/view/client/layout"
)
templ content(err types.Message, title string) {
@layout.Base(title){
<div class="bg-gray-100 flex items-center justify-center min-h-screen">
<div class="bg-white p-8 rounded-lg shadow-md w-full max-w-md">
<h1 class="text-2xl font-bold mb-6 text-center text-gray-800">Login</h1>
switch err.Code {
case 0:
<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative mb-4" role="alert">
<strong class="font-bold">Error!</strong>
<span class="block sm:inline"> {err.Message} </span>
</div>
}
<form action="" method="POST" class="space-y-4">
<div>
<label for="email" class="block text-sm font-medium text-gray-700">Email</label>
<input type="email" id="email" name="email" required
class="mt-1 block w-full px-3 py-2 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500">
</div>
<div>
<label for="password" class="block text-sm font-medium text-gray-700">Password</label>
<input type="password" id="password" name="password" required
class="mt-1 block w-full px-3 py-2 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500">
</div>
<div class="flex items-center justify-end">
<div class="text-sm">
<a href="/auth/forgot-password" rel="ugc" hx-get="/auth/forgot-password" hx-swap="outerHTML" hx-push-url="true" hx-target="#content" class="font-medium text-indigo-600 hover:text-indigo-500">
Forgot your password?
</a>
</div>
</div>
<div>
<button type="submit"
class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
Sign in
</button>
</div>
</form>
<div class="mt-6">
<div class="relative">
<div class="absolute inset-0 flex items-center">
<div class="w-full border-t border-gray-300"></div>
</div>
<div class="relative flex justify-center text-sm">
<span class="px-2 bg-white text-gray-500">Or continue with</span>
</div>
</div>
<div class="mt-6">
<a href="/auth/google"
class="w-full flex items-center justify-center px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
<svg class="h-5 w-5 mr-2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<g transform="matrix(1, 0, 0, 1, 27.009001, -39.238998)">
<path fill="#4285F4"
d="M -3.264 51.509 C -3.264 50.719 -3.334 49.969 -3.454 49.239 L -14.754 49.239 L -14.754 53.749 L -8.284 53.749 C -8.574 55.229 -9.424 56.479 -10.684 57.329 L -10.684 60.329 L -6.824 60.329 C -4.564 58.239 -3.264 55.159 -3.264 51.509 Z" />
<path fill="#34A853"
d="M -14.754 63.239 C -11.514 63.239 -8.804 62.159 -6.824 60.329 L -10.684 57.329 C -11.764 58.049 -13.134 58.489 -14.754 58.489 C -17.884 58.489 -20.534 56.379 -21.484 53.529 L -25.464 53.529 L -25.464 56.619 C -23.494 60.539 -19.444 63.239 -14.754 63.239 Z" />
<path fill="#FBBC05"
d="M -21.484 53.529 C -21.734 52.809 -21.864 52.039 -21.864 51.239 C -21.864 50.439 -21.724 49.669 -21.484 48.949 L -21.484 45.859 L -25.464 45.859 C -26.284 47.479 -26.754 49.299 -26.754 51.239 C -26.754 53.179 -26.284 54.999 -25.464 56.619 L -21.484 53.529 Z" />
<path fill="#EA4335"
d="M -14.754 43.989 C -12.984 43.989 -11.404 44.599 -10.154 45.789 L -6.734 42.369 C -8.804 40.429 -11.514 39.239 -14.754 39.239 C -19.444 39.239 -23.494 41.939 -25.464 45.859 L -21.484 48.949 C -20.534 46.099 -17.884 43.989 -14.754 43.989 Z" />
</g>
</svg>
Sign in with Google
</a>
</div>
</div>
<div class="mt-6 text-center">
<p class="text-sm text-gray-600">
Don't have an account?
<a href="/auth/signup" rel="ugc" hx-get="/auth/signup" hx-swap="outerHTML" hx-push-url="true" hx-target="#content" class="font-medium text-indigo-600 hover:text-indigo-500">
Sign up
</a>
</p>
</div>
</div>
</div>
}
}
templ Main(title string, err types.Message) {
@content(err, title)
}

View File

@ -0,0 +1,116 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.2.786
package signinView
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import (
"github.com/fossyy/filekeeper/types"
"github.com/fossyy/filekeeper/view/client/layout"
)
func content(err types.Message, title string) 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 {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"bg-gray-100 flex items-center justify-center min-h-screen\"><div class=\"bg-white p-8 rounded-lg shadow-md w-full max-w-md\"><h1 class=\"text-2xl font-bold mb-6 text-center text-gray-800\">Login</h1>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
switch err.Code {
case 0:
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative mb-4\" role=\"alert\"><strong class=\"font-bold\">Error!</strong> <span class=\"block sm:inline\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(err.Message)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/client/auth/signin/signin.templ`, Line: 17, Col: 71}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</span></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<form action=\"\" method=\"POST\" class=\"space-y-4\"><div><label for=\"email\" class=\"block text-sm font-medium text-gray-700\">Email</label> <input type=\"email\" id=\"email\" name=\"email\" required class=\"mt-1 block w-full px-3 py-2 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500\"></div><div><label for=\"password\" class=\"block text-sm font-medium text-gray-700\">Password</label> <input type=\"password\" id=\"password\" name=\"password\" required class=\"mt-1 block w-full px-3 py-2 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500\"></div><div class=\"flex items-center justify-end\"><div class=\"text-sm\"><a href=\"/auth/forgot-password\" rel=\"ugc\" hx-get=\"/auth/forgot-password\" hx-swap=\"outerHTML\" hx-push-url=\"true\" hx-target=\"#content\" class=\"font-medium text-indigo-600 hover:text-indigo-500\">Forgot your password?</a></div></div><div><button type=\"submit\" class=\"w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500\">Sign in</button></div></form><div class=\"mt-6\"><div class=\"relative\"><div class=\"absolute inset-0 flex items-center\"><div class=\"w-full border-t border-gray-300\"></div></div><div class=\"relative flex justify-center text-sm\"><span class=\"px-2 bg-white text-gray-500\">Or continue with</span></div></div><div class=\"mt-6\"><a href=\"/auth/google\" class=\"w-full flex items-center justify-center px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500\"><svg class=\"h-5 w-5 mr-2\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\"><g transform=\"matrix(1, 0, 0, 1, 27.009001, -39.238998)\"><path fill=\"#4285F4\" d=\"M -3.264 51.509 C -3.264 50.719 -3.334 49.969 -3.454 49.239 L -14.754 49.239 L -14.754 53.749 L -8.284 53.749 C -8.574 55.229 -9.424 56.479 -10.684 57.329 L -10.684 60.329 L -6.824 60.329 C -4.564 58.239 -3.264 55.159 -3.264 51.509 Z\"></path> <path fill=\"#34A853\" d=\"M -14.754 63.239 C -11.514 63.239 -8.804 62.159 -6.824 60.329 L -10.684 57.329 C -11.764 58.049 -13.134 58.489 -14.754 58.489 C -17.884 58.489 -20.534 56.379 -21.484 53.529 L -25.464 53.529 L -25.464 56.619 C -23.494 60.539 -19.444 63.239 -14.754 63.239 Z\"></path> <path fill=\"#FBBC05\" d=\"M -21.484 53.529 C -21.734 52.809 -21.864 52.039 -21.864 51.239 C -21.864 50.439 -21.724 49.669 -21.484 48.949 L -21.484 45.859 L -25.464 45.859 C -26.284 47.479 -26.754 49.299 -26.754 51.239 C -26.754 53.179 -26.284 54.999 -25.464 56.619 L -21.484 53.529 Z\"></path> <path fill=\"#EA4335\" d=\"M -14.754 43.989 C -12.984 43.989 -11.404 44.599 -10.154 45.789 L -6.734 42.369 C -8.804 40.429 -11.514 39.239 -14.754 39.239 C -19.444 39.239 -23.494 41.939 -25.464 45.859 L -21.484 48.949 C -20.534 46.099 -17.884 43.989 -14.754 43.989 Z\"></path></g></svg> Sign in with Google</a></div></div><div class=\"mt-6 text-center\"><p class=\"text-sm text-gray-600\">Don't have an account? <a href=\"/auth/signup\" rel=\"ugc\" hx-get=\"/auth/signup\" hx-swap=\"outerHTML\" hx-push-url=\"true\" hx-target=\"#content\" class=\"font-medium text-indigo-600 hover:text-indigo-500\">Sign up</a></p></div></div></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
templ_7745c5c3_Err = layout.Base(title).Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
func Main(title string, err types.Message) 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 {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var4 := templ.GetChildren(ctx)
if templ_7745c5c3_Var4 == nil {
templ_7745c5c3_Var4 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = content(err, title).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
var _ = templruntime.GeneratedTemplate

View File

@ -0,0 +1,201 @@
package signup
import (
"github.com/fossyy/filekeeper/types"
"github.com/fossyy/filekeeper/view/client/layout"
)
templ form(err types.Message, title string) {
@layout.Base(title){
<div class="bg-gray-100 flex items-center justify-center min-h-screen">
<div class="bg-white p-8 rounded-lg shadow-md w-full max-w-md">
<h1 class="text-2xl font-bold mb-6 text-center text-gray-800">Sign Up</h1>
switch err.Code {
case 0:
<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative mb-4" role="alert">
<strong class="font-bold">Error!</strong>
<span class="block sm:inline"> {err.Message} </span>
</div>
}
<form action="" method="POST" class="space-y-4">
<div>
<label for="email" class="block text-sm font-medium text-gray-700">Email</label>
<input type="email" id="email" name="email" required
class="mt-1 block w-full px-3 py-2 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500">
</div>
<div>
<label for="username" class="block text-sm font-medium text-gray-700">Username</label>
<input type="text" id="username" name="username" required
class="mt-1 block w-full px-3 py-2 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500">
</div>
<div>
<label for="password" class="block text-sm font-medium text-gray-700">Password</label>
<input type="password" id="password" name="password" required
class="mt-1 block w-full px-3 py-2 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500">
</div>
<div>
<label for="confirmPassword" class="block text-sm font-medium text-gray-700">Confirm Password</label>
<input type="password" id="confirmPassword" name="confirmPassword" required
class="mt-1 block w-full px-3 py-2 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500">
</div>
<div>
<div id="checkContainer" class="flex justify-start mt-1 block w-full px-3 py-2 hidden">
<ul>
<li class="flex items-center py-1">
<div id="matchSvgContainer" class="rounded-full p-1 fill-current bg-red-200 text-green-700">
<svg id="matchSvgIcon" class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path id="matchGoodPath" style="display: none;" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
<path id="matchBadPath" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
</svg>
</div>
<span id="matchStatusText" class="font-medium text-sm ml-3 text-red-700"> Passwords do not match</span>
</li>
<li class="flex items-center py-1">
<div id="uppercaseSvgContainer" class="rounded-full p-1 fill-current bg-red-200 text-green-700">
<svg id="uppercaseSvgIcon" class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path id="uppercaseGoodPath" style="display: none;" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
<path id="uppercaseBadPath" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
</svg>
</div>
<span id="uppercaseStatusText" class="font-medium text-sm ml-3 text-red-700"> Password must contain at least one uppercase letter</span>
</li>
<li class="flex items-center py-1">
<div id="lengthSvgContainer" class="rounded-full p-1 fill-current bg-red-200 text-green-700">
<svg id="lengthSvgIcon" class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path id="lengthGoodPath" style="display: none;" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
<path id="lengthBadPath" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
</svg>
</div>
<span id="lengthStatusText" class="font-medium text-sm ml-3 text-red-700"> Password length must be at least 8 characters</span>
</li>
</ul>
</div>
<button id="submit"
type="submit"
disabled
class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 disabled:pointer-events-none disabled:opacity-50">
Sign Up
</button>
</div>
</form>
<div class="mt-6">
<div class="relative">
<div class="absolute inset-0 flex items-center">
<div class="w-full border-t border-gray-300"></div>
</div>
<div class="relative flex justify-center text-sm">
<span class="px-2 bg-white text-gray-500">Or continue with</span>
</div>
</div>
<div class="mt-6">
<a href="/auth/google"
class="w-full flex items-center justify-center px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
<svg class="h-5 w-5 mr-2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<g transform="matrix(1, 0, 0, 1, 27.009001, -39.238998)">
<path fill="#4285F4"
d="M -3.264 51.509 C -3.264 50.719 -3.334 49.969 -3.454 49.239 L -14.754 49.239 L -14.754 53.749 L -8.284 53.749 C -8.574 55.229 -9.424 56.479 -10.684 57.329 L -10.684 60.329 L -6.824 60.329 C -4.564 58.239 -3.264 55.159 -3.264 51.509 Z" />
<path fill="#34A853"
d="M -14.754 63.239 C -11.514 63.239 -8.804 62.159 -6.824 60.329 L -10.684 57.329 C -11.764 58.049 -13.134 58.489 -14.754 58.489 C -17.884 58.489 -20.534 56.379 -21.484 53.529 L -25.464 53.529 L -25.464 56.619 C -23.494 60.539 -19.444 63.239 -14.754 63.239 Z" />
<path fill="#FBBC05"
d="M -21.484 53.529 C -21.734 52.809 -21.864 52.039 -21.864 51.239 C -21.864 50.439 -21.724 49.669 -21.484 48.949 L -21.484 45.859 L -25.464 45.859 C -26.284 47.479 -26.754 49.299 -26.754 51.239 C -26.754 53.179 -26.284 54.999 -25.464 56.619 L -21.484 53.529 Z" />
<path fill="#EA4335"
d="M -14.754 43.989 C -12.984 43.989 -11.404 44.599 -10.154 45.789 L -6.734 42.369 C -8.804 40.429 -11.514 39.239 -14.754 39.239 C -19.444 39.239 -23.494 41.939 -25.464 45.859 L -21.484 48.949 C -20.534 46.099 -17.884 43.989 -14.754 43.989 Z" />
</g>
</svg>
Sign up with Google
</a>
</div>
</div>
<div class="mt-6 text-center">
<p class="text-sm text-gray-600">
Already have an account?
<a class="underline" href="/auth/signin" rel="ugc" hx-get="/auth/signin" hx-swap="outerHTML" hx-push-url="true"
hx-target="#content" class="font-medium text-indigo-600 hover:text-indigo-500">
Log in
</a>
</p>
</div>
</div>
<script src="/public/validatePassword.js" />
</div>
}
}
templ Main(title string, err types.Message) {
@form(err, title)
}
templ EmailSend(title string) {
@layout.Base(title){
<style>
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: 'Arimo', sans-serif;
--font-sans: 'Arimo';
}
</style>
<style>
body {
font-family: 'Libre Franklin', sans-serif;
--font-sans: 'Libre Franklin';
}
</style>
<div class="flex flex-col items-center justify-center min-h-[80vh] gap-6">
<div class="flex items-center justify-center">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="h-16 w-16 text-gray-500 dark:text-gray-400">
<rect width="20" height="16" x="2" y="4" rx="2"></rect>
<path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"></path>
</svg>
</div>
<div class="space-y-2 text-center">
<h1 class="text-3xl font-bold">Email Verification Sent</h1>
<p class="text-gray-500 dark:text-gray-400">
We've sent a verification email to your inbox. Please check your email and follow the instructions to verify your
account.
</p>
</div>
</div>
}
}
templ VerifySuccess(title string) {
@layout.Base(title){
<style>
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: 'Arimo', sans-serif;
--font-sans: 'Arimo';
}
</style>
<style>
body {
font-family: 'Libre Franklin', sans-serif;
--font-sans: 'Libre Franklin';
}
</style>
<div class="flex flex-col items-center justify-center min-h-[80vh] gap-6">
<div class="bg-green-500 text-white rounded-full p-4">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="h-8 w-8">
<polyline points="20 6 9 17 4 12"></polyline>
</svg>
</div>
<div class="space-y-2 text-center">
<h1 class="text-3xl font-bold">Account Verified</h1>
<p class="text-gray-500 dark:text-gray-400">
Your account has been successfully verified. You can now access all the features of our platform.
</p>
</div>
</div>
}
}

File diff suppressed because one or more lines are too long