1
0
mirror of https://github.com/raseels-repos/golang-saas-starter-kit.git synced 2025-08-08 22:36:41 +02:00

Update formatting for user pages in web app.

This commit is contained in:
Lucas Brown
2019-08-05 18:47:07 -08:00
parent 7909dc4ca4
commit b63e4eb7bd
12 changed files with 114 additions and 45 deletions

View File

@ -91,7 +91,7 @@ func (h *Projects) Index(ctx context.Context, w http.ResponseWriter, r *http.Req
subStatusIcon = "far fa-circle" subStatusIcon = "far fa-circle"
} }
v.Formatted = fmt.Sprintf("<span class='cell-font-status %s'><i class='%s'></i>%s</span>", subStatusClass, subStatusIcon, web.EnumValueTitle(v.Value)) v.Formatted = fmt.Sprintf("<span class='cell-font-status %s'><i class='%s mr-1'></i>%s</span>", subStatusClass, subStatusIcon, web.EnumValueTitle(v.Value))
case "created_at": case "created_at":
dt := web.NewTimeResponse(ctx, q.CreatedAt) dt := web.NewTimeResponse(ctx, q.CreatedAt)
v.Value = dt.Local v.Value = dt.Local

View File

@ -44,6 +44,10 @@ func urlUsersCreate() string {
return fmt.Sprintf("/users/create") return fmt.Sprintf("/users/create")
} }
func urlUsersInvite() string {
return fmt.Sprintf("/users/invite")
}
func urlUsersView(userID string) string { func urlUsersView(userID string) string {
return fmt.Sprintf("/users/%s", userID) return fmt.Sprintf("/users/%s", userID)
} }
@ -117,7 +121,7 @@ func (h *Users) Index(ctx context.Context, w http.ResponseWriter, r *http.Reques
subStatusIcon = "far fa-circle" subStatusIcon = "far fa-circle"
} }
v.Formatted = fmt.Sprintf("<span class='cell-font-status %s'><i class='%s'></i>%s</span>", subStatusClass, subStatusIcon, web.EnumValueTitle(v.Value)) v.Formatted = fmt.Sprintf("<span class='cell-font-status %s'><i class='%s mr-1'></i>%s</span>", subStatusClass, subStatusIcon, web.EnumValueTitle(v.Value))
case "created_at": case "created_at":
dt := web.NewTimeResponse(ctx, q.CreatedAt) dt := web.NewTimeResponse(ctx, q.CreatedAt)
v.Value = dt.Local v.Value = dt.Local
@ -175,6 +179,7 @@ func (h *Users) Index(ctx context.Context, w http.ResponseWriter, r *http.Reques
data := map[string]interface{}{ data := map[string]interface{}{
"datatable": dt.Response(), "datatable": dt.Response(),
"urlUsersCreate": urlUsersCreate(), "urlUsersCreate": urlUsersCreate(),
"urlUsersInvite": urlUsersInvite(),
} }
return h.Renderer.Render(ctx, w, r, TmplLayoutBase, "users-index.gohtml", web.MIMETextHTMLCharsetUTF8, http.StatusOK, data) return h.Renderer.Render(ctx, w, r, TmplLayoutBase, "users-index.gohtml", web.MIMETextHTMLCharsetUTF8, http.StatusOK, data)
@ -372,6 +377,7 @@ func (h *Users) View(ctx context.Context, w http.ResponseWriter, r *http.Request
} }
} }
data["urlUsersView"] = urlUsersView(userID)
data["urlUsersUpdate"] = urlUsersUpdate(userID) data["urlUsersUpdate"] = urlUsersUpdate(userID)
data["urlUserVirtualLogin"] = urlUserVirtualLogin(userID) data["urlUserVirtualLogin"] = urlUserVirtualLogin(userID)
@ -546,6 +552,8 @@ func (h *Users) Update(ctx context.Context, w http.ResponseWriter, r *http.Reque
data["passwordValidationDefaults"] = verr.(*weberror.Error) data["passwordValidationDefaults"] = verr.(*weberror.Error)
} }
data["urlUsersView"] = urlUsersView(userID)
return h.Renderer.Render(ctx, w, r, TmplLayoutBase, "users-update.gohtml", web.MIMETextHTMLCharsetUTF8, http.StatusOK, data) return h.Renderer.Render(ctx, w, r, TmplLayoutBase, "users-update.gohtml", web.MIMETextHTMLCharsetUTF8, http.StatusOK, data)
} }

View File

@ -4,6 +4,13 @@
{{end}} {{end}}
{{define "content"}} {{define "content"}}
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/account">Account</a></li>
<li class="breadcrumb-item active" aria-current="page">Update</li>
</ol>
</nav>
<div class="d-sm-flex align-items-center justify-content-between mb-4"> <div class="d-sm-flex align-items-center justify-content-between mb-4">
<h1 class="h3 mb-0 text-gray-800">Update Account Settings</h1> <h1 class="h3 mb-0 text-gray-800">Update Account Settings</h1>
</div> </div>

View File

@ -4,6 +4,13 @@
{{end}} {{end}}
{{define "content"}} {{define "content"}}
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/account">Account</a></li>
<li class="breadcrumb-item active" aria-current="page">View</li>
</ol>
</nav>
<div class="d-sm-flex align-items-center justify-content-between mb-4"> <div class="d-sm-flex align-items-center justify-content-between mb-4">
<h1 class="h3 mb-0 text-gray-800">Account</h1> <h1 class="h3 mb-0 text-gray-800">Account</h1>
<!-- a href="/account/update" class="d-none d-sm-inline-block btn btn-sm btn-primary shadow-sm"><i class="far fa-edit fa-sm text-white-50 mr-1"></i>Edit Details</a --> <!-- a href="/account/update" class="d-none d-sm-inline-block btn btn-sm btn-primary shadow-sm"><i class="far fa-edit fa-sm text-white-50 mr-1"></i>Edit Details</a -->

View File

@ -52,7 +52,7 @@
</div> </div>
<div class="col-md-5"> <div class="col-md-5">
<p> <p>
<small>Role</small><br/> <small>Roles</small><br/>
{{ if .userAccount }} {{ if .userAccount }}
<b> <b>
{{ range $r := .userAccount.Roles }} {{ range $r := .userAccount.Roles }}

View File

@ -4,6 +4,13 @@
{{end}} {{end}}
{{define "content"}} {{define "content"}}
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/users">Users</a></li>
<li class="breadcrumb-item active" aria-current="page">Create</li>
</ol>
</nav>
<div class="d-sm-flex align-items-center justify-content-between mb-4"> <div class="d-sm-flex align-items-center justify-content-between mb-4">
<h1 class="h3 mb-0 text-gray-800">Create User</h1> <h1 class="h3 mb-0 text-gray-800">Create User</h1>
</div> </div>
@ -33,17 +40,6 @@
placeholder="enter email" name="Email" value="{{ .form.Email }}" required> placeholder="enter email" name="Email" value="{{ .form.Email }}" required>
{{template "invalid-feedback" dict "fieldName" "UserCreateRequest.Email" "validationDefaults" $.validationDefaults "validationErrors" $.validationErrors }} {{template "invalid-feedback" dict "fieldName" "UserCreateRequest.Email" "validationDefaults" $.validationDefaults "validationErrors" $.validationErrors }}
</div> </div>
<div class="form-group">
<label for="inputTimezone">Timezone</label>
<select class="form-control {{ ValidationFieldClass $.validationErrors "UserCreateRequest.Timezone" }}"
id="inputTimezone" name="Timezone">
<option value="">Not set</option>
{{ range $idx, $t := .timezones }}
<option value="{{ $t }}" {{ if CmpString $t $.form.Timezone }}selected="selected"{{ end }}>{{ $t }}</option>
{{ end }}
</select>
{{template "invalid-feedback" dict "fieldName" "UserCreateRequest.Timezone" "validationDefaults" $.validationDefaults "validationErrors" $.validationErrors }}
</div>
<div class="form-group"> <div class="form-group">
<label for="inputPassword">Password</label> <label for="inputPassword">Password</label>
<input type="password" <input type="password"

View File

@ -1,10 +1,20 @@
{{define "title"}}Users{{end}} {{define "title"}}Users{{end}}
{{define "content"}} {{define "content"}}
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/users">Users</a></li>
<li class="breadcrumb-item active" aria-current="page">Index</li>
</ol>
</nav>
<div class="d-sm-flex align-items-center justify-content-between mb-4"> <div class="d-sm-flex align-items-center justify-content-between mb-4">
<h1 class="h3 mb-0 text-gray-800">Users</h1> <h1 class="h3 mb-0 text-gray-800">Users</h1>
{{ if HasRole $._Ctx "admin" }} {{ if HasRole $._Ctx "admin" }}
<a href="{{ .urlUsersCreate }}" class="d-none d-sm-inline-block btn btn-sm btn-primary shadow-sm"><i class="fas fa-user-plus fa-sm text-white-50 mr-1"></i>Create User</a> <div>
<a href="{{ .urlUsersCreate }}" class="d-none d-sm-inline-block btn btn-sm btn-primary shadow-sm mr-2"><i class="fas fa-user-plus fa-sm text-white-50 mr-1"></i>Create User</a>
<a href="{{ .urlUsersInvite }}" class="d-none d-sm-inline-block btn btn-sm btn-primary shadow-sm"><i class="fas fa-restroom fa-sm text-white-50 mr-1"></i>Invite Users</a>
</div>
{{ end }} {{ end }}
</div> </div>

View File

@ -1,16 +1,44 @@
{{define "title"}}Invite Users{{end}} {{define "title"}}Invite Users{{end}}
{{define "content"}} {{define "content"}}
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/users">Users</a></li>
<li class="breadcrumb-item active" aria-current="page">Invite</li>
</ol>
</nav>
<div class="d-sm-flex align-items-center justify-content-between mb-4">
<h1 class="h3 mb-0 text-gray-800">Invite Users</h1>
</div>
<form method="POST"> <form method="POST">
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
<div class="card"> <div class="card">
<div class="card-body"> <div class="card-body">
<div class="form-group"> <div class="form-group">
<label for="inputEmail">Email for Invite 1</label> <label for="selectRoles">Roles <small>- Select at least one role for invited user(s).</small></label>
<input type="text" class="form-control invite-user-email" placeholder="enter email" name="Emails" value=""> <select class="form-control {{ ValidationFieldClass $.validationErrors "Roles" }}"
id="selectRoles" name="Roles" multiple="multiple">
{{ range $t := .roles }}
<option value="{{ $t.Value }}" {{ if $t.Selected }}selected="selected"{{ end }}>{{ $t.Title }}</option>
{{ end }}
</select>
{{template "invalid-feedback" dict "validationDefaults" $.validationDefaults "validationErrors" $.validationErrors "fieldName" "Roles" }}
</div> </div>
<div id="email-form-groups">
<div class="form-group">
<label for="inputEmail">Email for Invite 1</label>
<input type="text" class="form-control invite-user-email" placeholder="enter email" name="Emails" value="">
</div>
</div>
<p class="mt-2 mb-0"><a href="javascript:void(0)" class="btn btn-outline-primary btn-sm" id="inviteUser1"><i class="fas fa-user-plus mr-1"></i>Add another invitation</a></p>
</div> </div>
</div> </div>
</div> </div>
@ -32,9 +60,8 @@
</div> </div>
</div> </div>
<div class="spacer-30"></div>
<div class="row"> <div class="row mt-4">
<div class="col"> <div class="col">
<input id="btnSubmit" type="submit" value="Invite Users" class="btn btn-primary"/> <input id="btnSubmit" type="submit" value="Invite Users" class="btn btn-primary"/>
</div> </div>
@ -46,7 +73,7 @@
<script> <script>
function addAnotherEmail(el) { function addAnotherEmail(el) {
if ($(el).val() == '') { if ($(el).val() == '') {
return; //return;
} }
cnt = 0; cnt = 0;
@ -61,24 +88,21 @@
newHtml = newHtml + '<label for="inputEmail">Email for Invite '+cnt+'</label>'; newHtml = newHtml + '<label for="inputEmail">Email for Invite '+cnt+'</label>';
newHtml = newHtml + '<input type="text" class="form-control invite-user-email" placeholder="enter email" name="Emails" value="">'; newHtml = newHtml + '<input type="text" class="form-control invite-user-email" placeholder="enter email" name="Emails" value="">';
newHtml = newHtml + '</div>'; newHtml = newHtml + '</div>';
$(el).closest('div.card-body').append(newHtml); $('#email-form-groups').append(newHtml);
$(el).unbind( "blur" );
$('#'+newId).on("blur", function() {
addAnotherEmail($(this));
});
} }
$(document).ready(function(){ $(document).ready(function(){
$("#inviteUser1").on("blur", function() { $("#inviteUser1").click( function() {
addAnotherEmail($(this)); addAnotherEmail($(this));
}); });
$("#inputRole").on("change", function() { $("#inputRole").on("change", function() {
if ($(this).val() == 'admin') { if ($(this).val() == 'admin') {
$('#userProcedures').hide(); //$('#userProjects').hide();
} else { } else {
$('#userProcedures').show(); //$('#userProjects').show();
} }
}).change(); }).change();
}); });

View File

@ -4,6 +4,14 @@
{{end}} {{end}}
{{define "content"}} {{define "content"}}
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/users">Users</a></li>
<li class="breadcrumb-item"><a href="{{ .urlUsersView }}">{{ .user.Name }}</a></li>
<li class="breadcrumb-item active" aria-current="page">Update</li>
</ol>
</nav>
<div class="d-sm-flex align-items-center justify-content-between mb-4"> <div class="d-sm-flex align-items-center justify-content-between mb-4">
<h1 class="h3 mb-0 text-gray-800">Update User</h1> <h1 class="h3 mb-0 text-gray-800">Update User</h1>
</div> </div>
@ -39,6 +47,16 @@
placeholder="enter email" name="Email" value="{{ .form.Email }}" required> placeholder="enter email" name="Email" value="{{ .form.Email }}" required>
{{template "invalid-feedback" dict "fieldName" "UserUpdateRequest.Email" "validationDefaults" $.userValidationDefaults "validationErrors" $.validationErrors }} {{template "invalid-feedback" dict "fieldName" "UserUpdateRequest.Email" "validationDefaults" $.userValidationDefaults "validationErrors" $.validationErrors }}
</div> </div>
<div class="form-group">
<label for="inputTimezone">Timezone</label>
<select class="form-control {{ ValidationFieldClass $.validationErrors "UserUpdateRequest.Timezone" }}" name="Timezone">
<option value="">Not set</option>
{{ range $idx, $t := .timezones }}
<option value="{{ $t }}" {{ if CmpString $t $.form.Timezone }}selected="selected"{{ end }}>{{ $t }}</option>
{{ end }}
</select>
{{template "invalid-feedback" dict "fieldName" "UserUpdateRequest.Timezone" "validationDefaults" $.validationDefaults "validationErrors" $.validationErrors }}
</div>
<div class="form-group"> <div class="form-group">
<label for="inputRoles">Roles</label> <label for="inputRoles">Roles</label>
<span class="help-block "><small>- Select at least one role.</small></span> <span class="help-block "><small>- Select at least one role.</small></span>
@ -55,16 +73,6 @@
{{ end }} {{ end }}
{{template "invalid-feedback" dict "fieldName" "Roles" "validationDefaults" $.validationDefaults "validationErrors" $.validationErrors }} {{template "invalid-feedback" dict "fieldName" "Roles" "validationDefaults" $.validationDefaults "validationErrors" $.validationErrors }}
</div> </div>
<div class="form-group">
<label for="inputTimezone">Timezone</label>
<select class="form-control {{ ValidationFieldClass $.validationErrors "UserUpdateRequest.Timezone" }}" name="Timezone">
<option value="">Not set</option>
{{ range $idx, $t := .timezones }}
<option value="{{ $t }}" {{ if CmpString $t $.form.Timezone }}selected="selected"{{ end }}>{{ $t }}</option>
{{ end }}
</select>
{{template "invalid-feedback" dict "fieldName" "UserUpdateRequest.Timezone" "validationDefaults" $.validationDefaults "validationErrors" $.validationErrors }}
</div>
</div> </div>
</div> </div>
<div class="row"> <div class="row">

View File

@ -3,6 +3,15 @@
{{end}} {{end}}
{{define "content"}} {{define "content"}}
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/users">Users</a></li>
<li class="breadcrumb-item"><a href="{{ .urlUsersView }}">{{ .user.Name }}</a></li>
<li class="breadcrumb-item active" aria-current="page">View</li>
</ol>
</nav>
<div class="d-sm-flex align-items-center justify-content-between mb-4"> <div class="d-sm-flex align-items-center justify-content-between mb-4">
<h1 class="h3 mb-0 text-gray-800">{{ .user.Name }}</h1> <h1 class="h3 mb-0 text-gray-800">{{ .user.Name }}</h1>
{{ if HasRole $._Ctx "admin" }} {{ if HasRole $._Ctx "admin" }}
@ -64,7 +73,7 @@
</div> </div>
<div class="col-md-5"> <div class="col-md-5">
<p> <p>
<small>Role</small><br/> <small>Roles</small><br/>
{{ if .userAccount }} {{ if .userAccount }}
<b> <b>
{{ range $r := .userAccount.Roles }}{{ if $r.Selected }} {{ range $r := .userAccount.Roles }}{{ if $r.Selected }}

View File

@ -38,11 +38,12 @@
</a> </a>
<div id="navSectionProjects" class="collapse" data-parent="#accordionSidebar"> <div id="navSectionProjects" class="collapse" data-parent="#accordionSidebar">
<div class="bg-white py-2 collapse-inner rounded"> <div class="bg-white py-2 collapse-inner rounded">
<a class="collapse-item" href="/projects">Projects</a> <a class="collapse-item" href="/projects">Manage Projects</a>
</div> </div>
</div> </div>
</li> </li>
{{ if HasRole $._Ctx "admin" }}
<!-- Nav Item - Utilities Collapse Menu --> <!-- Nav Item - Utilities Collapse Menu -->
<li class="nav-item"> <li class="nav-item">
<a class="nav-link collapsed" href="#" data-toggle="collapse" data-target="#navSectionUsers" aria-expanded="true" aria-controls="navSectionUsers"> <a class="nav-link collapsed" href="#" data-toggle="collapse" data-target="#navSectionUsers" aria-expanded="true" aria-controls="navSectionUsers">
@ -51,10 +52,13 @@
</a> </a>
<div id="navSectionUsers" class="collapse" data-parent="#accordionSidebar"> <div id="navSectionUsers" class="collapse" data-parent="#accordionSidebar">
<div class="bg-white py-2 collapse-inner rounded"> <div class="bg-white py-2 collapse-inner rounded">
<a class="collapse-item" href="/users">Users</a> <a class="collapse-item" href="/users">Manage Users</a>
<a class="collapse-item" href="/users/invite">Invite Users</a>
</div> </div>
</div> </div>
</li> </li>
{{end}}
{{ end }} {{ end }}
<!-- Divider --> <!-- Divider -->

View File

@ -181,10 +181,6 @@
<i class="fas fa-users 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">
<i class="fas fa-user-plus fa-sm fa-fw mr-2 text-gray-400"></i>
Invite Users
</a>
{{ else }} {{ else }}
<a class="dropdown-item" href="/user/account"> <a class="dropdown-item" href="/user/account">
<i class="fas fa-cogs fa-sm fa-fw mr-2 text-gray-400"></i> <i class="fas fa-cogs fa-sm fa-fw mr-2 text-gray-400"></i>