1
0
mirror of https://github.com/raseels-repos/golang-saas-starter-kit.git synced 2025-06-10 23:57:45 +02:00

Merge branch 'issue16/web-app-signup' of gitlab.com:geeks-accelerator/oss/saas-starter-kit into issue16/web-app-signup

This commit is contained in:
Lee Brown 2019-08-05 17:15:32 -08:00
commit 53b9424e95
12 changed files with 104 additions and 65 deletions

View File

@ -131,7 +131,6 @@ func (h *Examples) Images(ctx context.Context, w http.ResponseWriter, r *http.Re
// List of image sizes that will be used to resize the source image into. The resulting images will then be included // List of image sizes that will be used to resize the source image into. The resulting images will then be included
// as apart of the image src tag for a responsive image tag. // as apart of the image src tag for a responsive image tag.
data := map[string]interface{}{ data := map[string]interface{}{
"imgSizes": []int{100, 200, 300, 400, 500},
"imgResizeDisabled": false, "imgResizeDisabled": false,
} }

View File

@ -36,6 +36,10 @@ type User struct {
SecretKey string SecretKey string
} }
func urlUserVirtualLogin(userID string) string {
return fmt.Sprintf("/user/virtual-login/%s", userID)
}
// UserLoginRequest extends the AuthenicateRequest with the RememberMe flag. // UserLoginRequest extends the AuthenicateRequest with the RememberMe flag.
type UserLoginRequest struct { type UserLoginRequest struct {
user_auth.AuthenticateRequest user_auth.AuthenticateRequest

View File

@ -373,6 +373,7 @@ func (h *Users) View(ctx context.Context, w http.ResponseWriter, r *http.Request
} }
data["urlUsersUpdate"] = urlUsersUpdate(userID) data["urlUsersUpdate"] = urlUsersUpdate(userID)
data["urlUserVirtualLogin"] = urlUserVirtualLogin(userID)
return h.Renderer.Render(ctx, w, r, TmplLayoutBase, "users-view.gohtml", web.MIMETextHTMLCharsetUTF8, http.StatusOK, data) return h.Renderer.Render(ctx, w, r, TmplLayoutBase, "users-view.gohtml", web.MIMETextHTMLCharsetUTF8, http.StatusOK, data)
} }

View File

@ -814,7 +814,7 @@ func main() {
tmplFuncs["S3ImgThumbSrcSmall"] = func(ctx context.Context, p string) template.HTMLAttr { tmplFuncs["S3ImgThumbSrcSmall"] = func(ctx context.Context, p string) template.HTMLAttr {
return imgSrcAttr(ctx, p, []int{320}, false) return imgSrcAttr(ctx, p, []int{320}, false)
} }
tmplFuncs["S3ImgSrc"] = func(ctx context.Context, p string, sizes []int) template.HTMLAttr { tmplFuncs["S3ImgSrc"] = func(ctx context.Context, p string, sizes ...int) template.HTMLAttr {
return imgSrcAttr(ctx, p, sizes, true) return imgSrcAttr(ctx, p, sizes, true)
} }
tmplFuncs["S3ImgUrl"] = func(ctx context.Context, p string, size int) string { tmplFuncs["S3ImgUrl"] = func(ctx context.Context, p string, size int) string {

View File

@ -109,3 +109,12 @@ div.dataTable_card a.paginate_button.current {
.alert p:last-child { .alert p:last-child {
margin-bottom: 0; margin-bottom: 0;
} }
.topbar.navbar-light .navbar-nav.unauthenicated .nav-item .nav-link {
color: #4e73df;
}
.topbar.navbar-light .navbar-nav.unauthenicated .nav-item .nav-link:hover {
color: #1cc88a;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 MiB

View File

@ -4,7 +4,9 @@
{{end}} {{end}}
{{define "content"}} {{define "content"}}
<h3>Inline Validation Example</h3>
<h3 class="mt-5">Inline Validation Example</h3>
<p>Any field error that is not displayed inline will still be displayed as apart of the the validation at the top of the page.</p> <p>Any field error that is not displayed inline will still be displayed as apart of the the validation at the top of the page.</p>
<form class="user" method="post" novalidate> <form class="user" method="post" novalidate>
<div class="form-group"> <div class="form-group">
@ -12,7 +14,7 @@
{{template "invalid-feedback" dict "validationDefaults" $.validationDefaults "validationErrors" $.validationErrors "fieldName" "Email" }} {{template "invalid-feedback" dict "validationDefaults" $.validationDefaults "validationErrors" $.validationErrors "fieldName" "Email" }}
</div> </div>
<button class="btn btn-primary btn-user btn-block"> <button class="btn btn-purple btn-user ">
Submit Form Submit Form
</button> </button>
<hr> <hr>

View File

@ -23,56 +23,66 @@
<p>This SaaS Starter Kit includes functions to resize images automatically and render the src of an image tag with an array of source URLs. The functions are custom functions that are rendered with the GO templates.</p> <p>This SaaS Starter Kit includes functions to resize images automatically and render the src of an image tag with an array of source URLs. The functions are custom functions that are rendered with the GO templates.</p>
<pre class="mb-4">&#x7B;&#x7B; FUNCTION_NAME $._ctx "RELATIVE_PATH_TO_IMAGE_HERE" &#x7D;&#x7D;</pre> <pre class="mb-4">&#x7B;&#x7B; FUNCTION_NAME $._ctx "RELATIVE_PATH_TO_IMAGE_HERE" &#x7D;&#x7D;</pre>
<h5>S3ImgSrcLarge</h5> <p>The <em>thumb</em> version of each function does not include the original as part of the array of images. This thumb version of the funciton is used then the original is a very large file at it is not needed to be displayed as the largest option.</p>
<p>Generates an array of three images from the source file with widths of 320, 480 and 800.</p>
<img {{ S3ImgSrcLarge $._ctx "/images/example-image-resize-galaxy-3000x1600.png" }}/><br/>
<p class="mb-0 mt-2">HTML:</p><pre>&lt;img &#x7B;&#x7B; S3ImgSrcLarge $._ctx "/images/example-image-resize-galaxy-3000x1600.png" &#x7D;&#x7D;&gt;</pre> <h5 class="mt-5">S3ImgSrcLarge</h5>
<p class="mb-0">Result:</p><pre>&lt;img {{ S3ImgSrcLarge $._ctx "/images/example-image-resize-galaxy-3000x1600.png" }}&gt;</pre></p> <p>Generates three resized images from the original with widths of 320, 480 and 800. Then creates an array with four options: the three resized along with the original. Then sets the array as the value of the srcset in an img tag.</p>
<p class="mb-0 mt-2">Example HTML:</p><pre>&lt;img &#x7B;&#x7B; S3ImgSrcLarge $._ctx "/images/example-image-resize-galaxy-3000x1000.png" &#x7D;&#x7D;&gt;</pre>
<p class="mb-0">Result:</p><pre>&lt;img {{ S3ImgSrcLarge $._ctx "/images/example-image-resize-galaxy-3000x1000.png" }}&gt;</pre></p>
<img {{ S3ImgSrcLarge $._ctx "/images/example-image-resize-galaxy-3000x1000.png" }}/><br/>
<h3>S3ImgThumbSrcLarge</h3> <h5 class="mt-5">S3ImgThumbSrcLarge</h5>
<p>320, 480, 800</p> <p>Generates three resized images from the original with widths of 320, 480 and 800. Then creates an array of only the three resized image. Then sets the array as the value of the srcset in an img tag.</p>
<img {{ S3ImgThumbSrcLarge $._ctx "/images/example-image-resize-galaxy-3000x1600.png" }}/><br/> <p class="mb-0 mt-2">Example GO HTML:</p><pre>&lt;img &#x7B;&#x7B; S3ImgThumbSrcLarge $._ctx "/images/example-image-resize-galaxy-3000x1000.png" &#x7D;&#x7D;&gt;</pre>
HTML: <pre>&lt;img &#x7B;&#x7B; S3ImgThumbSrcLarge $._ctx "/images/example-image-resize-galaxy-3000x1600.png" &#x7D;&#x7D;&gt;</pre> <p class="mb-0">Result:</p><pre>&lt;img {{ S3ImgThumbSrcLarge $._ctx "/images/example-image-resize-galaxy-3000x1000.png" }}&gt;</pre>
Result: <pre>&lt;img {{ S3ImgThumbSrcLarge $._ctx "/images/example-image-resize-galaxy-3000x1600.png" }}&gt;</pre> <img {{ S3ImgThumbSrcLarge $._ctx "/images/example-image-resize-galaxy-3000x1000.png" }}/><br/>
<h3>S3ImgSrcMedium</h3> <h5 class="mt-5">S3ImgSrcMedium</h5>
<p>320, 640</p> <p>Generates resized images from the original with widths of 320 and 480. Then creates an array with three options: the two resized along with the original. Then sets the array as the value of the srcset in an img tag.</p>
<img {{ S3ImgSrcMedium $._ctx "/images/example-image-resize-galaxy-3000x1600.png" }}/><br/> <p class="mb-0 mt-2">Example GO HTML:</p><pre>&lt;img &#x7B;&#x7B; S3ImgSrcMedium $._ctx "/images/example-image-resize-galaxy-3000x1000.png" &#x7D;&#x7D;&gt;</pre>
HTML: <pre>&lt;img &#x7B;&#x7B; S3ImgSrcMedium $._ctx "/images/example-image-resize-galaxy-3000x1600.png" &#x7D;&#x7D;&gt;</pre> <p class="mb-0">Result:</p><pre>&lt;img {{ S3ImgSrcMedium $._ctx "/images/example-image-resize-galaxy-3000x1000.png" }}&gt;</pre>
Result: <pre>&lt;img {{ S3ImgSrcMedium $._ctx "/images/example-image-resize-galaxy-3000x1600.png" }}&gt;</pre> <img {{ S3ImgSrcMedium $._ctx "/images/example-image-resize-galaxy-3000x1000.png" }}/><br/>
<h3>S3ImgThumbSrcMedium</h3> <h5 class="mt-5">S3ImgThumbSrcMedium</h5>
<p>320, 640</p> <p>Generates two resized images from the original with widths of 320 and 480. Then creates an array of only the two resized image. Then sets the array as the value of the srcset in an img tag.</p>
<img {{ S3ImgThumbSrcMedium $._ctx "/images/example-image-resize-galaxy-3000x1600.png" }}/><br/> <p class="mb-0 mt-2">Example GO HTML:</p><pre>&lt;img &#x7B;&#x7B; S3ImgThumbSrcMedium $._ctx "/images/example-image-resize-galaxy-3000x1000.png" &#x7D;&#x7D;&gt;</pre>
HTML: <pre>&lt;img &#x7B;&#x7B; S3ImgThumbSrcMedium $._ctx "/images/example-image-resize-galaxy-3000x1600.png" &#x7D;&#x7D;&gt;</pre> <p class="mb-0">Result:</p><pre>&lt;img {{ S3ImgThumbSrcMedium $._ctx "/images/example-image-resize-galaxy-3000x1000.png" }}&gt;</pre>
Result: <pre>&lt;img {{ S3ImgThumbSrcMedium $._ctx "/images/example-image-resize-galaxy-3000x1600.png" }}&gt;</pre> <img {{ S3ImgThumbSrcMedium $._ctx "/images/example-image-resize-galaxy-3000x1000.png" }}/><br/>
<h3>S3ImgSrcSmall</h3> <h5 class="mt-5">S3ImgSrcSmall</h5>
<p>320</p> <p>Generates one resized image from the original with width of 320. Then creates an array with two options: the one resized along with the original. Then sets the array as the value of the srcset in an img tag.</p>
<img {{ S3ImgSrcSmall $._ctx "/images/example-image-resize-galaxy-3000x1600.png" }}/><br/> <p class="mb-0 mt-2">Example GO HTML:</p><pre>&lt;img &#x7B;&#x7B; S3ImgSrcSmall $._ctx "/images/example-image-resize-galaxy-3000x1000.png" &#x7D;&#x7D;&gt;</pre>
HTML: <pre>&lt;img &#x7B;&#x7B; S3ImgSrcSmall $._ctx "/images/example-image-resize-galaxy-3000x1600.png" &#x7D;&#x7D;&gt;</pre> <p class="mb-0">Result:</p><pre>&lt;img {{ S3ImgSrcSmall $._ctx "/images/example-image-resize-galaxy-3000x1000.png" }}&gt;</pre>
Result: <pre>&lt;img {{ S3ImgSrcSmall $._ctx "/images/example-image-resize-galaxy-3000x1600.png" }}&gt;</pre> <img {{ S3ImgSrcSmall $._ctx "/images/example-image-resize-galaxy-3000x1000.png" }}/><br/>
<h3>S3ImgThumbSrcSmall</h3> <h5 class="mt-5">S3ImgThumbSrcSmall</h5>
<p>320</p> <p>Generates one resized image from the original with widths of 320. Then creates an array of only the one resized image. Then sets the array as the value of the srcset in an img tag.</p>
<img {{ S3ImgThumbSrcSmall $._ctx "/images/example-image-resize-galaxy-3000x1600.png" }}/><br/> <p class="mb-0 mt-2">Example GO HTML:</p><pre>&lt;img &#x7B;&#x7B; S3ImgThumbSrcSmall $._ctx "/images/example-image-resize-galaxy-3000x1000.png" &#x7D;&#x7D;&gt;</pre>
HTML: <pre>&lt;img &#x7B;&#x7B; S3ImgThumbSrcSmall $._ctx "/images/example-image-resize-galaxy-3000x1600.png" &#x7D;&#x7D;&gt;</pre> <p class="mb-0">Result:</p><pre>&lt;img {{ S3ImgThumbSrcSmall $._ctx "/images/example-image-resize-galaxy-3000x1000.png" }}&gt;</pre>
Result: <pre>&lt;img {{ S3ImgThumbSrcSmall $._ctx "/images/example-image-resize-galaxy-3000x1600.png" }}&gt;</pre> <img {{ S3ImgThumbSrcSmall $._ctx "/images/example-image-resize-galaxy-3000x1000.png" }}/><br/>
<h5 class="mt-5">S3ImgSrc</h5>
<p>Generates an array of two images from the source file with widths of 320, 480, and then sets the array as the value of the srcset in an img tag.</p>
<p class="mb-0 mt-2">Example GO HTML:</p><pre>&lt;img &#x7B;&#x7B; S3ImgSrc $._ctx "/images/example-image-resize-galaxy-3000x1000.png" 100 200 300 400 500 &#x7D;&#x7D; &gt;</pre>
<p class="mb-0">Result:</p><pre>&lt;img {{ S3ImgSrc $._ctx "/images/example-image-resize-galaxy-3000x1000.png" 100 200 300 400 500 }} &gt;</pre>
<img id="imgVerifyResizeEnabled" {{ S3ImgSrc $._ctx "/images/example-image-resize-galaxy-3000x1000.png" 100 200 300 400 500 }}/><br/>
<h5 class="mt-5">S3ImgUrl <small>with Specific Width</small></h5>
<p>Generates a resized image from the source file with specific width and retuns the URL. The example below has the width set to 200 pixels wide.</p>
<p class="mb-0 mt-2">Example GO HTML:</p><pre>&lt;img src="&#x7B;&#x7B; S3ImgUrl $._ctx "/images/example-image-resize-galaxy-3000x1000.png" 200 &#x7D;&#x7D;" &gt;</pre>
<p class="mb-0">Result:</p><pre>&lt;img src="{{ S3ImgUrl $._ctx "/images/example-image-resize-galaxy-3000x1000.png" 200 }}" &gt;</pre>
<img src="{{ S3ImgUrl $._ctx "/images/example-image-resize-galaxy-3000x1000.png" 200 }}" /><br/>
<h5 class="mt-5">S3Url</h5>
<p>If you do not want the image to be resized, you can use the S3Url function. This function returns the URL of the file on S3. However, when environment is not production, function returns the local relative path.</p>
<p class="mb-0 mt-2">Example GO HTML:</p><pre>&lt;img src="&#x7B;&#x7B; S3Url "/images/example-image-resize-galaxy-3000x1000.png" &#x7D;&#x7D;" &gt;</pre>
<p class="mb-0">Result:</p><pre>&lt;img src="{{ S3Url "/images/example-image-resize-galaxy-3000x1000.png" }}" &gt;</pre>
<img src="{{ S3Url "/images/example-image-resize-galaxy-3000x1000.png" }}" style="width: 100%;" /><br/>
<h3>S3ImgSrc</h3>
<p>returns Src array</p>
<img id="imgVerifyResizeEnabled" {{ S3ImgSrc $._ctx "/images/example-image-resize-galaxy-3000x1600.png" $.imgSizes }}/><br/>
HTML: <pre>&lt;img &#x7B;&#x7B; S3ImgSrc $._ctx "/images/example-image-resize-galaxy-3000x1600.png" $.imgSizes &#x7D;&#x7D; &gt;</pre>
Result: <pre>&lt;img {{ S3ImgSrc $._ctx "/images/example-image-resize-galaxy-3000x1600.png" $.imgSizes }} &gt;</pre>
<h3>S3ImgUrl</h3>
<p>Returns URL for file on S3</p>
<img src="{{ S3ImgUrl $._ctx "/images/example-image-resize-galaxy-3000x1600.png" 200 }}" /><br/>
HTML: <pre>&lt;img src="&#x7B;&#x7B; S3ImgUrl $._ctx "/images/example-image-resize-galaxy-3000x1600.png" 200 &#x7D;&#x7D;" &gt;</pre>
Result: <pre>&lt;img src="{{ S3ImgUrl $._ctx "/images/example-image-resize-galaxy-3000x1600.png" 200 }}" &gt;</pre>
{{ end }} {{ end }}

View File

@ -22,34 +22,32 @@
<div class="text-center"> <div class="text-center">
<h1 class="h4 text-gray-900 mb-2">Reset Your Password</h1> <h1 class="h4 text-gray-900 mb-2">Reset Your Password</h1>
<p class="mb-4">.....</p> <p class="mb-4">Enter your new password below.</p>
</div> </div>
{{ template "validation-error" . }} {{ template "validation-error" . }}
<form class="user" method="post" novalidate> <form class="user" method="post" novalidate>
<div class="form-group row"> <div class="form-group ">
<div class="col-sm-6 mb-3 mb-sm-0"> <input type="password"
<input type="password" class="form-control form-control-user {{ ValidationFieldClass $.validationErrors "Password" }}" name="Password" value="{{ $.form.Password }}" placeholder="Password" required> class="form-control form-control-user {{ ValidationFieldClass $.validationErrors "Password" }}"
{{template "invalid-feedback" dict "validationDefaults" $.validationDefaults "validationErrors" $.validationErrors "fieldName" "Password" }} name="Password" value="{{ $.form.Password }}" placeholder="New Password" required>
</div> {{template "invalid-feedback" dict "fieldName" "Password" "validationDefaults" $.validationDefaults "validationErrors" $.validationErrors }}
<div class="col-sm-6"> </div>
<input type="password" class="form-control form-control-user {{ ValidationFieldClass $.validationErrors "PasswordConfirm" }}" name="PasswordConfirm" value="{{ $.form.PasswordConfirm }}" placeholder="Repeat Password" required> <div class="form-group ">
{{template "invalid-feedback" dict "validationDefaults" $.validationDefaults "validationErrors" $.validationErrors "fieldName" "PasswordConfirm" }} <input type="password"
</div> class="form-control form-control-user {{ ValidationFieldClass $.validationErrors "PasswordConfirm" }}"
name="PasswordConfirm" value="{{ $.form.PasswordConfirm }}" placeholder="Repeat New Password" required>
{{template "invalid-feedback" dict "fieldName" "PasswordConfirm" "validationDefaults" $.validationDefaults "validationErrors" $.validationErrors }}
</div> </div>
<button class="btn btn-primary btn-user btn-block"> <button class="btn btn-primary btn-user btn-block">
Reset Password Reset Password
</button> </button>
<hr>
</form> </form>
<hr> <hr>
<div class="text-center"> <div class="text-center">
<a class="small" href="/user/login">Already have an account? Login!</a> <a class="small" href="/user/login">Already have an account? Login!</a>
</div> </div>
<div class="text-center">
<a class="small" href="/signup">Create an Account!</a>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -26,6 +26,10 @@
{{ $ctxUser := ContextUser $._Ctx }} {{ $ctxUser := ContextUser $._Ctx }}
{{ if $ctxUser }} {{ if $ctxUser }}
{{ if ne .user.ID $ctxUser.ID }} {{ if ne .user.ID $ctxUser.ID }}
<a href="{{ .urlUserVirtualLogin }}" class="dropdown-item">Virtual Login</a>
<form method="post"><input type="hidden" name="action" value="archive" /><input type="submit" value="Archive User" class="dropdown-item"></form> <form method="post"><input type="hidden" name="action" value="archive" /><input type="submit" value="Archive User" class="dropdown-item"></form>
{{ end }} {{ end }}
{{ end }} {{ end }}

View File

@ -178,12 +178,12 @@
Account Settings Account Settings
</a> </a>
<a class="dropdown-item" href="/users"> <a class="dropdown-item" href="/users">
<i class="fas fa-cogs fa-sm fa-fw mr-2 text-gray-400"></i> <i class="fas fa-users fa-sm fa-fw mr-2 text-gray-400"></i>
Manage Users Manage Users
</a> </a>
<a class="dropdown-item" href="/users/invite"> <a class="dropdown-item" href="/users/invite">
<i class="fas fa-cogs fa-sm fa-fw mr-2 text-gray-400"></i> <i class="fas fa-user-plus fa-sm fa-fw mr-2 text-gray-400"></i>
Invite User Invite Users
</a> </a>
{{ else }} {{ else }}
<a class="dropdown-item" href="/user/account"> <a class="dropdown-item" href="/user/account">
@ -193,7 +193,7 @@
{{ end }} {{ end }}
<a class="dropdown-item" href="/support" target="_blank"> <a class="dropdown-item" href="/support" target="_blank">
<i class="fas fa-cogs fa-sm fa-fw mr-2 text-gray-400"></i> <i class="fas fa-hand-holding-heart fa-sm fa-fw mr-2 text-gray-400"></i>
Support Support
</a> </a>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
@ -207,7 +207,7 @@
{{ if ContextIsVirtualSession $._Ctx }} {{ if ContextIsVirtualSession $._Ctx }}
<a class="dropdown-item" href="/user/virtual-logout"> <a class="dropdown-item" href="/user/virtual-logout">
<i class="far fa-sign-out fa-sm fa-fw mr-2 text-gray-400"></i> <i class="fas fa-undo-alt fa-sm fa-fw mr-2 text-gray-400"></i>
Switch Back Switch Back
</a> </a>
{{ end }} {{ end }}
@ -221,7 +221,19 @@
</ul> </ul>
{{ else }} {{ else }}
<button onclick="window.location='/user/login'; return false;">Login</button>
<ul class="navbar-nav ml-auto unauthenicated">
<li class="nav-item">
<a class="nav-link" href="/signup">Create Account</a>
</li>
<div class="topbar-divider d-none d-sm-block"></div>
<li class="nav-item">
<a class="nav-link" href="/user/login"><i class="fas fa-unlock-alt mr-1"></i>Login</a>
</li>
</ul>
{{ end }} {{ end }}
</nav> </nav>
<!-- End of Topbar --> <!-- End of Topbar -->