generated from jric11/baseProject
added new bootstrap css and js for login and create account
This commit is contained in:
@@ -164,29 +164,6 @@ class Base {
|
|||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
// =========================
|
|
||||||
// Return a decrypted string
|
|
||||||
// =========================
|
|
||||||
|
|
||||||
protected function decrypt($encrypted = "", $key = "") {
|
|
||||||
|
|
||||||
$key = (empty($key)) ? __CLASS__ : $key;
|
|
||||||
|
|
||||||
$decoded = base64_decode($encrypted);
|
|
||||||
$ivlen = openssl_cipher_iv_length($cipher = "AES-128-CBC");
|
|
||||||
$iv = substr($decoded, 0, $ivlen);
|
|
||||||
$hmac = substr($decoded, $ivlen, $sha2len = 32);
|
|
||||||
$raw = substr($decoded, $ivlen + $sha2len);
|
|
||||||
$decrypted = openssl_decrypt($raw, $cipher, $key, $options = OPENSSL_RAW_DATA, $iv);
|
|
||||||
$calcmac = hash_hmac("sha256", $raw, $key, $as_binary = true);
|
|
||||||
|
|
||||||
if (($hmac === false) or ($calcmac === false)) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
return (hash_equals($hmac, $calcmac)) ? $decrypted : "";
|
|
||||||
}
|
|
||||||
|
|
||||||
// ======================
|
// ======================
|
||||||
// Display a Content Page
|
// Display a Content Page
|
||||||
// ======================
|
// ======================
|
||||||
@@ -207,9 +184,6 @@ class Base {
|
|||||||
|
|
||||||
public function displayError($error_number = "", $error_message = "", $error_file = "", $error_line = "") {
|
public function displayError($error_number = "", $error_message = "", $error_file = "", $error_line = "") {
|
||||||
|
|
||||||
echo $error_message;
|
|
||||||
die();
|
|
||||||
|
|
||||||
if (error_reporting() == 0) {
|
if (error_reporting() == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -43,7 +43,7 @@ class SignIn extends Base {
|
|||||||
$XSLParms["BTN_SUBMIT"] = "main.php?action=SignIn.login&step=authenticate";
|
$XSLParms["BTN_SUBMIT"] = "main.php?action=SignIn.login&step=authenticate";
|
||||||
$XSLParms["INVALID_SIGNIN"] = "FALSE";
|
$XSLParms["INVALID_SIGNIN"] = "FALSE";
|
||||||
|
|
||||||
echo $this->applyXSL("", $this->getXSL("signIn"), $XSLParms);
|
echo $this->applyXSL("", $this->getXSL("login"), $XSLParms);
|
||||||
exit();
|
exit();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -0,0 +1,103 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// =============
|
||||||
|
// Sign In Class
|
||||||
|
// =============
|
||||||
|
|
||||||
|
class SignUp {
|
||||||
|
|
||||||
|
// ===============================
|
||||||
|
// __construct : Class Constructor
|
||||||
|
// ===============================
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==============
|
||||||
|
// Create Account
|
||||||
|
// ==============
|
||||||
|
|
||||||
|
public function createAccount() {
|
||||||
|
|
||||||
|
$step = filter_input(INPUT_POST, "step") ?: "prompt";
|
||||||
|
|
||||||
|
switch ($step) {
|
||||||
|
|
||||||
|
case "prompt":
|
||||||
|
|
||||||
|
$XSLParms["BTN_SUBMIT"] = "main.php?action=SignUp.createAccount&step=create";
|
||||||
|
|
||||||
|
echo $this->applyXSL("", $this->getXSL("createAccount"), $XSLParms);
|
||||||
|
exit();
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "create":
|
||||||
|
|
||||||
|
$user_name = trim(filter_input(INPUT_POST, "user_name") ?: "");
|
||||||
|
$user_password = filter_input(INPUT_POST, "user_password") ?: "";
|
||||||
|
|
||||||
|
$XSLParms["BTN_SUBMIT"] = "main.php?action=SignIn.login&step=authenticate";
|
||||||
|
$XSLParms["INVALID_SIGNIN"] = "TRUE";
|
||||||
|
|
||||||
|
$user = (new Users())->getUserByUserName($user_name);
|
||||||
|
|
||||||
|
if ($user->count() == 0) {
|
||||||
|
echo $this->applyXSL("", $this->getXSL("signIn"), $XSLParms);
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((string) $user->record->user_status !== 'active') {
|
||||||
|
echo $this->applyXSL("", $this->getXSL("signIn"), $XSLParms);
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
$stored_hashed_password = $user->record->user_password_hash;
|
||||||
|
|
||||||
|
if (!password_verify($user_password, $stored_hashed_password)) {
|
||||||
|
|
||||||
|
echo $this->applyXSL("", $this->getXSL("signIn"), $XSLParms);
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
session_regenerate_id(true);
|
||||||
|
|
||||||
|
$_SESSION[self::USER_AUTHENTICATED] = true;
|
||||||
|
$_SESSION[self::USER_SERIAL] = (int) $user->record->user_serial;
|
||||||
|
$_SESSION[self::USER_NAME] = (string) $user->record->user_name;
|
||||||
|
$_SESSION[self::USER_FULL_NAME] = (string) $user->record->user_full_name;
|
||||||
|
$_SESSION[self::USER_EMAIL] = (string) $user->record->user_email;
|
||||||
|
$_SESSION[self::USER_ROLE] = (string) $user->record->user_role;
|
||||||
|
|
||||||
|
$this->current_user_serial = $_SESSION[self::USER_SERIAL] ?? 0;
|
||||||
|
$this->current_user_name = $_SESSION[self::USER_NAME] ?? "";
|
||||||
|
$this->current_user_email = $_SESSION[self::USER_EMAIL] ?? "";
|
||||||
|
|
||||||
|
$system_admins = $this->getSettings()->xpath("//SystemAdministrator");
|
||||||
|
|
||||||
|
foreach ($system_admins as $admin) {
|
||||||
|
if ((string) $admin === $user_name) {
|
||||||
|
$_SESSION[self::USER_ROLE] = "System Administrator";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(new Journal())->journalEntry("{$_SESSION[self::USER_NAME]} logged in ({$_SESSION[self::USER_ROLE]}).");
|
||||||
|
|
||||||
|
(new Users())->updateLogin();
|
||||||
|
|
||||||
|
header("Location: ./");
|
||||||
|
exit();
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// User NOT Validated.
|
||||||
|
header("Location: ./");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
/* MyHuntRoster sign-in page; load after themed Bootstrap. */
|
||||||
|
body{margin:0;min-height:100vh;background:#f6f5f0;color:#26332e}.login-shell{min-height:100vh;display:grid;grid-template-columns:1.08fr 1fr}.login-story{background:#183c30;color:#f5f5e9;position:relative;overflow:hidden;display:flex;flex-direction:column;justify-content:space-between;padding:clamp(2rem,5vw,5rem)}.login-brand{display:inline-flex;gap:.75rem;align-items:center;font-size:1.35rem;font-weight:750;letter-spacing:-.04em;text-decoration:none;color:inherit}.brand-mark{width:36px;height:40px;color:#d0b182}.story-copy{position:relative;z-index:1;max-width:480px;margin:5rem 0 7rem}.eyebrow{font-size:.7rem;letter-spacing:.18em;text-transform:uppercase;font-weight:650;color:#c9b084}.story-copy h1{font-size:clamp(2.6rem,4.4vw,4.6rem);line-height:1.06;letter-spacing:-.055em;margin:1.2rem 0 1.5rem;font-weight:600}.story-copy p{font-size:1rem;line-height:1.8;color:#c5d4c9;max-width:350px}.story-footer{position:relative;z-index:1;font-size:.75rem;letter-spacing:.03em;color:#c5d4c9}.landscape{position:absolute;bottom:0;left:0;width:100%;height:45%;opacity:.6;pointer-events:none}.login-panel{display:flex;align-items:center;justify-content:center;padding:3rem 2rem;position:relative}.login-form-wrap{width:100%;max-width:390px}.panel-label{display:flex;align-items:center;gap:.5rem;color:#526c5b;font-size:.72rem;letter-spacing:.12em;font-weight:650;text-transform:uppercase;margin-bottom:2.3rem}.panel-label::before{content:"";width:7px;height:7px;background:#8a9c6c;border-radius:50%}.login-form-wrap h2{font-size:2.1rem;letter-spacing:-.045em;margin-bottom:.65rem}.login-intro{color:#657068;font-size:.94rem;line-height:1.6;margin-bottom:2rem}.form-label{font-size:.85rem;margin-bottom:.6rem}.form-control{min-height:48px;background:#fff}.password-wrap{position:relative}.password-wrap .form-control{padding-right:4.5rem}.password-toggle{position:absolute;inset:4px 4px 4px auto;border:0;background:transparent;border-radius:.5rem;color:#285548;font-size:.78rem;font-weight:650;padding:0 .8rem}.password-toggle:focus-visible{outline:2px solid #285548;outline-offset:1px}.sign-in{min-height:48px;margin-top:1.5rem}.login-help{font-size:.85rem;color:#657068;line-height:1.7;text-align:center;margin-top:1.75rem}.login-bottom{border-top:1px solid #dde3dc;padding-top:1.4rem;margin-top:2rem;text-align:center;color:#737d74;font-size:.73rem}.mobile-brand{display:none}.alert{font-size:.87rem}.forgot-row{display:flex;justify-content:space-between;align-items:baseline;gap:1rem}.forgot-row a{font-size:.78rem}.preview-note{font-size:.75rem;background:#e4eee8;border:1px solid #bfd1c6;border-radius:.5rem;padding:.7rem;margin-bottom:1rem;color:#285548}
|
||||||
|
@media(max-width:900px){.login-shell{grid-template-columns:.85fr 1fr}.login-story{padding:2rem}.story-copy h1{font-size:2.8rem}}
|
||||||
|
@media(max-width:700px){.login-shell{display:block}.login-story{display:none}.login-panel{min-height:100vh;padding:2rem 1.5rem}.mobile-brand{display:flex;color:#183c30;margin-bottom:3rem}.panel-label{margin-bottom:1.4rem}.login-form-wrap h2{font-size:1.9rem}}
|
||||||
+12065
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,17 @@
|
|||||||
|
|
||||||
|
/* MyHuntRoster custom theme. Bootstrap MIT license retained above. */
|
||||||
|
:root,[data-bs-theme="light"]{--bs-primary:#285548;--bs-primary-rgb:40,85,72;--bs-link-color:#285548;--bs-link-color-rgb:40,85,72;--bs-link-hover-color:#193c32;--bs-link-hover-color-rgb:25,60,50;--bs-body-bg:#f6f5f0;--bs-body-color:#26332e;--bs-border-color:#dde3dc;--bs-border-radius:.75rem;--bs-border-radius-lg:1rem;--bs-body-font-family:Inter,ui-sans-serif,system-ui,-apple-system,"Segoe UI",sans-serif;--bs-primary-bg-subtle:#e4eee8;--bs-primary-text-emphasis:#193c32;--bs-primary-border-subtle:#bfd1c6}
|
||||||
|
[data-bs-theme="dark"]{--bs-body-bg:#17221d;--bs-body-color:#e5ece6;--bs-secondary-bg:#223129;--bs-tertiary-bg:#293b31;--bs-border-color:#3e5144;--bs-primary:#84baa0;--bs-primary-rgb:132,186,160;--bs-link-color:#a1d4b9;--bs-link-color-rgb:161,212,185;--bs-link-hover-color:#c4ead3;--bs-link-hover-color-rgb:196,234,211;--bs-primary-bg-subtle:#203e30;--bs-primary-text-emphasis:#b2dcc3;--bs-primary-border-subtle:#4e705d}
|
||||||
|
body.hr-app{margin:0;padding:0;min-height:100vh;font-size:.9375rem}
|
||||||
|
h1,h2,h3,h4,h5,h6{font-weight:650;letter-spacing:-.025em}
|
||||||
|
.btn{border-radius:.6rem;font-weight:600;padding:.55rem .95rem}.btn-sm{padding:.35rem .7rem}
|
||||||
|
.btn-primary{--bs-btn-bg:#285548;--bs-btn-border-color:#285548;--bs-btn-hover-bg:#1c4136;--bs-btn-hover-border-color:#1c4136;--bs-btn-active-bg:#193c32;--bs-btn-active-border-color:#193c32;--bs-btn-disabled-bg:#285548;--bs-btn-disabled-border-color:#285548;--bs-btn-focus-shadow-rgb:40,85,72}
|
||||||
|
.btn-outline-primary{--bs-btn-color:var(--bs-link-color);--bs-btn-border-color:var(--bs-link-color);--bs-btn-hover-bg:#285548;--bs-btn-hover-border-color:#285548;--bs-btn-hover-color:#fff;--bs-btn-active-bg:#193c32;--bs-btn-active-border-color:#193c32;--bs-btn-active-color:#fff;--bs-btn-disabled-color:var(--bs-link-color);--bs-btn-disabled-border-color:var(--bs-link-color)}
|
||||||
|
.form-control,.form-select{border-radius:.6rem;padding:.65rem .8rem}.form-control-sm,.form-select-sm{padding:.35rem .6rem}.form-control:focus,.form-select:focus{border-color:#6b9980;box-shadow:0 0 0 .2rem rgba(40,85,72,.14)}.form-check-input:checked{background-color:#285548;border-color:#285548}.form-check-input:focus{border-color:#6b9980;box-shadow:0 0 0 .2rem rgba(40,85,72,.14)}.form-label{font-weight:600}
|
||||||
|
.card{--bs-card-bg:var(--bs-body-bg);background:var(--bs-card-bg);box-shadow:0 3px 16px rgba(18,43,29,.035);overflow:hidden}.card-header{padding:1rem 1.25rem;background:transparent}.card-body{padding:1.4rem}.table{--bs-table-bg:transparent;--bs-table-hover-bg:rgba(88,137,108,.07)}.table>:not(caption)>*>*{padding:.85rem 1rem}.table thead th{font-size:.75rem;text-transform:uppercase;letter-spacing:.06em;color:var(--bs-secondary-color);font-weight:650}.badge{padding:.45em .65em;border-radius:.4rem}.dropdown-menu{padding:.4rem!important;border-radius:.75rem;box-shadow:0 12px 40px rgba(0,0,0,.12)}.dropdown-item{padding:.55rem .75rem;border-radius:.4rem}.dropdown-item:active{background:#285548}.modal-content{box-shadow:0 20px 80px rgba(0,0,0,.15)}
|
||||||
|
.hr-sidebar{--bs-offcanvas-width:264px;background:#183c30!important;color:#e7eee8;border:0!important;padding:1.4rem 1rem;z-index:1045}.hr-brand{display:flex;align-items:center;gap:.7rem;color:#fff;text-decoration:none;font-size:1.3rem;font-weight:700;letter-spacing:-.04em;padding:.5rem .5rem 1.5rem}.hr-brand:hover{color:#fff}.hr-brand i{color:#c5a578;font-size:1.7rem}.hr-sidebar .navbar-nav{width:100%;gap:.25rem}.hr-sidebar .nav-link{color:#cbdacf;border-radius:.65rem;padding:.75rem .85rem;display:block;font-weight:550;font-size:.82rem;letter-spacing:.025em}.hr-sidebar .nav-link:hover,.hr-sidebar .nav-link:focus-visible,.hr-sidebar .nav-link.active{background:#2b5041;color:#fff}.hr-sidebar .nav-link i{margin-right:.6rem!important}.hr-sidebar .nav-link.disabled{display:none}.hr-sidebar .dropdown-menu{position:static!important;transform:none!important;margin:.3rem 0!important}.hr-sidebar-caption{font-size:.7rem;text-transform:uppercase;letter-spacing:.15em;color:#a4bdae;padding:.4rem .85rem 1rem}.hr-sidebar-foot{font-size:.75rem;color:#b3c8b9;padding:1.5rem .85rem .25rem;margin-top:auto}.hr-sidebar .offcanvas-body{display:flex;flex-direction:column;overflow-y:auto;padding:0}
|
||||||
|
.hr-workspace{min-width:0;min-height:100vh}.hr-topbar{min-height:80px;display:flex;align-items:center;justify-content:space-between;gap:1rem;padding:1rem 2rem;border-bottom:1px solid var(--bs-border-color);background:var(--bs-body-bg)}.hr-topbar .nav-link{color:var(--bs-body-color)}.hr-topbar .dropdown-menu{min-width:230px}.hr-workspace>.content{max-width:1600px;padding:2rem;margin:0 auto;min-height:65vh}.hr-workspace #footer{position:static;padding:1rem 2rem 2rem}.hr-skip{position:fixed;top:-100px;left:1rem;z-index:2000}.hr-skip:focus{top:1rem}
|
||||||
|
@media(min-width:992px){.hr-sidebar{position:fixed;inset:0 auto 0 0;width:264px;height:100vh;display:flex;flex-direction:column}.hr-sidebar .offcanvas-body{flex-grow:1}.hr-workspace{margin-left:264px}}
|
||||||
|
@media(max-width:991.98px){.hr-topbar{padding:1rem}.hr-workspace>.content{padding:1.25rem}.hr-topbar .username{font-size:.85rem}}
|
||||||
|
@media(prefers-reduced-motion:reduce){*,*::before,*::after{scroll-behavior:auto!important;transition:none!important}}
|
||||||
|
@media print{.hr-sidebar,.hr-topbar,.hr-skip{display:none!important}.hr-workspace{margin:0}.hr-workspace>.content{padding:0;max-width:none}body.hr-app{background:#fff;color:#000}}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 376 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 862 KiB |
Vendored
+4
-3
File diff suppressed because one or more lines are too long
+230
@@ -0,0 +1,230 @@
|
|||||||
|
// ========================
|
||||||
|
// Sign In / Create Account
|
||||||
|
// ========================
|
||||||
|
|
||||||
|
$(document).ready(function () {
|
||||||
|
|
||||||
|
const $login = $("#login");
|
||||||
|
const $signUp = $("form[data-create-account], #signUp");
|
||||||
|
const $resetPassword = $("#reset-password");
|
||||||
|
|
||||||
|
// Use our Bootstrap validation messages.
|
||||||
|
$login.add($signUp).add($resetPassword).attr("novalidate", "novalidate");
|
||||||
|
|
||||||
|
$(".btnSignUp").on("click", function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
window.location.href = "./?Xaction=signup";
|
||||||
|
});
|
||||||
|
|
||||||
|
// ------------------
|
||||||
|
// Validate Sign In
|
||||||
|
// ------------------
|
||||||
|
|
||||||
|
$login.on("submit", function (e) {
|
||||||
|
|
||||||
|
const $form = $(this);
|
||||||
|
const $email = $form.find("[name='user_email']");
|
||||||
|
const $password = $form.find("[name='user_password']");
|
||||||
|
|
||||||
|
clearInputErrors($form);
|
||||||
|
trimInput($email);
|
||||||
|
|
||||||
|
if (isBlank($email)) {
|
||||||
|
return rejectSubmit(e, $email, "Email address is required.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isBlank($password)) {
|
||||||
|
return rejectSubmit(e, $password, "Password is required.");
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// ------------------------
|
||||||
|
// Open Password Reset Form
|
||||||
|
// ------------------------
|
||||||
|
|
||||||
|
$(".btnForgot").on("click", function (e) {
|
||||||
|
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
if ($resetPassword.length) {
|
||||||
|
$resetPassword.trigger("submit");
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// -----------------------
|
||||||
|
// Validate Password Reset
|
||||||
|
// -----------------------
|
||||||
|
|
||||||
|
$resetPassword.on("submit", function (e) {
|
||||||
|
|
||||||
|
const $email = $login.find("[name='user_email']");
|
||||||
|
|
||||||
|
clearInputErrors($login);
|
||||||
|
trimInput($email);
|
||||||
|
|
||||||
|
if (isBlank($email)) {
|
||||||
|
return rejectSubmit(e, $email, "Enter your email address to reset your password.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$(this).find("#reset_user_email").val($email.val());
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// -----------------------
|
||||||
|
// Validate Create Account
|
||||||
|
// -----------------------
|
||||||
|
|
||||||
|
$signUp.on("submit", function (e) {
|
||||||
|
|
||||||
|
const $form = $(this);
|
||||||
|
|
||||||
|
const $firstName = $form.find("[name='user_first_name']");
|
||||||
|
const $lastName = $form.find("[name='user_last_name']");
|
||||||
|
const $email = $form.find("[name='user_email']");
|
||||||
|
const $username = $form.find("[name='user_name']");
|
||||||
|
const $password = $form.find("[name='user_password']");
|
||||||
|
const $confirmation = $form.find("[name='user_password_confirm']");
|
||||||
|
|
||||||
|
clearInputErrors($form);
|
||||||
|
|
||||||
|
[$firstName, $lastName, $email, $username].forEach(trimInput);
|
||||||
|
|
||||||
|
const requiredFields = [
|
||||||
|
[$firstName, "First name is required."],
|
||||||
|
[$lastName, "Last name is required."],
|
||||||
|
[$email, "Email address is required."],
|
||||||
|
[$username, "Username is required."],
|
||||||
|
[$password, "Password is required."],
|
||||||
|
[$confirmation, "Please confirm your password."]
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const [$input, message] of requiredFields) {
|
||||||
|
if (isBlank($input)) {
|
||||||
|
return rejectSubmit(e, $input, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($email[0].validity.typeMismatch) {
|
||||||
|
return rejectSubmit(e, $email, "Enter a valid email address.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($password.val() !== $confirmation.val()) {
|
||||||
|
return rejectSubmit(e, $confirmation, "Passwords must match.");
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// ---------------------------------
|
||||||
|
// Clear Feedback When Input Changes
|
||||||
|
// ---------------------------------
|
||||||
|
|
||||||
|
$login.add($signUp).on("input", "input", function () {
|
||||||
|
clearFieldError($(this));
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// --------------------
|
||||||
|
// Trim Text Inputs
|
||||||
|
// --------------------
|
||||||
|
|
||||||
|
function trimInput($input) {
|
||||||
|
$input.val(String($input.val() || "").trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------
|
||||||
|
// Test for Blank Value
|
||||||
|
// --------------------
|
||||||
|
|
||||||
|
function isBlank($input) {
|
||||||
|
return String($input.val() || "").trim().length === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------
|
||||||
|
// Stop Invalid Submission
|
||||||
|
// ----------------------
|
||||||
|
|
||||||
|
function rejectSubmit(event, $input, message) {
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
createInputError($input, message);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------
|
||||||
|
// Clear Form Input Errors
|
||||||
|
// ------------------------
|
||||||
|
|
||||||
|
function clearInputErrors($form) {
|
||||||
|
|
||||||
|
$form.find("input").each(function () {
|
||||||
|
clearFieldError($(this));
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------
|
||||||
|
// Clear One Input's Error
|
||||||
|
// ------------------------
|
||||||
|
|
||||||
|
function clearFieldError($input) {
|
||||||
|
|
||||||
|
const feedbackId = $input.attr("data-auth-feedback");
|
||||||
|
|
||||||
|
if (feedbackId) {
|
||||||
|
|
||||||
|
const feedback = document.getElementById(feedbackId);
|
||||||
|
|
||||||
|
if (feedback) {
|
||||||
|
feedback.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
const describedBy = ($input.attr("aria-describedby") || "").split(/\s+/).filter(id => id && id !== feedbackId);
|
||||||
|
if (describedBy.length) {
|
||||||
|
$input.attr("aria-describedby", describedBy.join(" "));
|
||||||
|
} else {
|
||||||
|
$input.removeAttr("aria-describedby");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$input.removeClass("is-invalid").removeAttr("aria-invalid data-auth-feedback");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------
|
||||||
|
// Show Input Feedback
|
||||||
|
// ---------------------
|
||||||
|
|
||||||
|
function createInputError($input, message) {
|
||||||
|
|
||||||
|
clearFieldError($input);
|
||||||
|
|
||||||
|
const feedbackId = $input.attr("id") + "-auth-error";
|
||||||
|
|
||||||
|
const $feedback = $("<div>", {id: feedbackId, class: "invalid-feedback", text: message});
|
||||||
|
|
||||||
|
// Support both plain inputs and Bootstrap input groups.
|
||||||
|
const $group = $input.closest(".input-group, .password-wrap");
|
||||||
|
|
||||||
|
if ($group.length) {
|
||||||
|
|
||||||
|
$group.addClass("has-validation");
|
||||||
|
$group.after($feedback);
|
||||||
|
$feedback.addClass("d-block");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$input.after($feedback);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const describedBy = ($input.attr("aria-describedby") || "").split(/\s+/).filter(Boolean);
|
||||||
|
|
||||||
|
describedBy.push(feedbackId);
|
||||||
|
|
||||||
|
$input.addClass("is-invalid").attr({"aria-invalid": "true", "aria-describedby": describedBy.join(" "), "data-auth-feedback": feedbackId}).trigger("focus");
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
copy.src.files=true
|
copy.src.files=true
|
||||||
copy.src.on.open=false
|
copy.src.on.open=false
|
||||||
copy.src.target=W:\\clients\\onesourceits\\huntingclubroster
|
copy.src.target=W:\\clients\\onesourceits\\huntingclubroster
|
||||||
index.file=index.php
|
index.file=main.php
|
||||||
run.as=LOCAL
|
run.as=LOCAL
|
||||||
url=http://ositsdevels/clients/onesourceits/baseProject/
|
url=http://ositsdevels/clients/onesourceits/huntingclubroster/
|
||||||
|
|||||||
+40
-43
@@ -1,12 +1,11 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
|
||||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
|
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
|
||||||
<xsl:output method="html" encoding="utf-8" indent="yes"/>
|
<xsl:output method="html" encoding="utf-8" indent="yes"/>
|
||||||
|
|
||||||
<!-- Parameters -->
|
<!-- Parameters -->
|
||||||
|
|
||||||
<xsl:param name="VERSION">1.0</xsl:param>
|
<xsl:param name="VERSION">1.0</xsl:param>
|
||||||
<xsl:param name="APPLICATION_NAME"></xsl:param>
|
<xsl:param name="APPLICATION_NAME"/>
|
||||||
<xsl:param name="NAVIGATION_AREA_WIDTH">xxl</xsl:param>
|
<xsl:param name="NAVIGATION_AREA_WIDTH">xxl</xsl:param>
|
||||||
<xsl:param name="CONTENT_AREA_WIDTH">xxl</xsl:param>
|
<xsl:param name="CONTENT_AREA_WIDTH">xxl</xsl:param>
|
||||||
|
|
||||||
@@ -14,7 +13,7 @@
|
|||||||
|
|
||||||
<xsl:template match="/">
|
<xsl:template match="/">
|
||||||
|
|
||||||
<xsl:text disable-output-escaping="yes"><!DOCTYPE html></xsl:text>
|
<xsl:text disable-output-escaping="yes"><!DOCTYPE html></xsl:text>
|
||||||
|
|
||||||
<html lang="en" data-bs-theme="{$THEME}">
|
<html lang="en" data-bs-theme="{$THEME}">
|
||||||
|
|
||||||
@@ -30,11 +29,12 @@
|
|||||||
|
|
||||||
<link rel="icon" type="image/x-icon" href="images/baseproject-logo.png"/>
|
<link rel="icon" type="image/x-icon" href="images/baseproject-logo.png"/>
|
||||||
|
|
||||||
<link href="css/themes/Sandstone/bootstrap.min.css?version={$VERSION}" rel="stylesheet" media="screen"/>
|
<link href="css/themes/MyHuntingClubRoster/bootstrap.css?version={$VERSION}" rel="stylesheet" media="screen"/>
|
||||||
<link href="css/bootstrap-icons.min.css?version={$VERSION}" rel="stylesheet" media="screen"/>
|
<link href="css/bootstrap-icons.min.css?version={$VERSION}" rel="stylesheet" media="screen"/>
|
||||||
<link href="css/base.css?version={$VERSION}" rel="stylesheet" media="screen" />
|
<link href="css/base.css?version={$VERSION}" rel="stylesheet" media="screen"/>
|
||||||
<link href="css/bootstrap-datepicker.min.css?version={$VERSION}" rel="stylesheet" media="screen" />
|
<link href="css/bootstrap-datepicker.min.css?version={$VERSION}" rel="stylesheet" media="screen"/>
|
||||||
<link href="css/bootstrap-select.min.css?version={$VERSION}" rel="stylesheet" media="screen" />
|
<link href="css/bootstrap-select.min.css?version={$VERSION}" rel="stylesheet" media="screen"/>
|
||||||
|
<link href="css/themes/MyHuntingClubRoster/huntroster-theme.css?version={$VERSION}" rel="stylesheet"/>
|
||||||
|
|
||||||
<script src="js/jquery-3.2.0.min.js?version={$VERSION}"/>
|
<script src="js/jquery-3.2.0.min.js?version={$VERSION}"/>
|
||||||
<script src="js/bootstrap.bundle.min.js?version={$VERSION}"/>
|
<script src="js/bootstrap.bundle.min.js?version={$VERSION}"/>
|
||||||
@@ -48,12 +48,9 @@
|
|||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body class="hr-app">
|
||||||
|
|
||||||
<xsl:if test="$THEME = 'Sandstone'">
|
|
||||||
<xsl:attribute name="class">bg-light bg-opacity-50</xsl:attribute>
|
|
||||||
</xsl:if>
|
|
||||||
|
|
||||||
|
<a href="#main-content" class="hr-skip btn btn-primary">Skip to content</a>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
var msie = /msie\s|trident/i.test(window.navigator.userAgent);
|
var msie = /msie\s|trident/i.test(window.navigator.userAgent);
|
||||||
if (msie) {
|
if (msie) {
|
||||||
@@ -63,22 +60,17 @@
|
|||||||
|
|
||||||
<input type="hidden" id="APPLICATION_MNEMONIC" value="{$APPLICATION_MNEMONIC}"/>
|
<input type="hidden" id="APPLICATION_MNEMONIC" value="{$APPLICATION_MNEMONIC}"/>
|
||||||
|
|
||||||
<nav class="navbar navbar-expand-lg fixed-top bg-primary navbar-dark">
|
<aside class="hr-sidebar offcanvas-lg offcanvas-start" id="hr-sidebar" tabindex="-1" aria-label="Main navigation">
|
||||||
|
<a href="./" class="hr-brand">
|
||||||
<div class="container-xxl">
|
<i class="bi bi-tree" aria-hidden="true"/>
|
||||||
|
<span>
|
||||||
<a class="navbar-brand ms-1 me-0" href="./" aria-label="Home" data-bs-toggle="tooltip" data-bs-title="Home" data-bs-custom-class="custom-tooltip" data-bs-placement="right" data-bs-offset="0,5">
|
|
||||||
<!--<i class="bi bi-cloud me-2"></i>-->
|
|
||||||
<xsl:value-of select="$APPLICATION_NAME"/>
|
<xsl:value-of select="$APPLICATION_NAME"/>
|
||||||
|
</span>
|
||||||
</a>
|
</a>
|
||||||
|
<button type="button" class="btn-close btn-close-white d-lg-none position-absolute top-0 end-0 m-3" data-bs-dismiss="offcanvas" data-bs-target="#hr-sidebar" aria-label="Close navigation"/>
|
||||||
<button type="button" class="navbar-toggler p-0" data-bs-toggle="collapse" data-bs-target="#navbar-main" aria-controls="navbar-main" aria-expanded="false" aria-label="Toggle Navigation">
|
<div class="offcanvas-body">
|
||||||
<span class="navbar-toggler-icon"></span>
|
<div class="hr-sidebar-caption">Club workspace</div>
|
||||||
</button>
|
<ul class="navbar-nav">
|
||||||
|
|
||||||
<div class="navbar-collapse collapse" id="navbar-main">
|
|
||||||
|
|
||||||
<ul class="navbar-nav mx-auto">
|
|
||||||
|
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link user-subscriptions" href="javascript:void(0);">
|
<a class="nav-link user-subscriptions" href="javascript:void(0);">
|
||||||
@@ -154,20 +146,32 @@
|
|||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<ul class="navbar-nav user-dropdown ms-0">
|
<div class="hr-sidebar-foot">MyHuntRoster · Club management</div>
|
||||||
|
</div>
|
||||||
|
</aside><!-- Content Area -->
|
||||||
|
|
||||||
|
<div class="hr-workspace">
|
||||||
|
<header class="hr-topbar">
|
||||||
|
<div class="d-flex align-items-center gap-3">
|
||||||
|
<button type="button" class="btn btn-outline-primary d-lg-none" data-bs-toggle="offcanvas" data-bs-target="#hr-sidebar" aria-controls="hr-sidebar" aria-label="Open navigation">
|
||||||
|
<i class="bi bi-list" aria-hidden="true"/>
|
||||||
|
</button>
|
||||||
|
<span class="fw-semibold">Club management</span>
|
||||||
|
</div>
|
||||||
|
<ul class="navbar-nav user-dropdown">
|
||||||
|
|
||||||
<li class="nav-item dropdown">
|
<li class="nav-item dropdown">
|
||||||
|
|
||||||
<a href="javascript:void(0);" class="nav-link ps-2 dropdown-toggle" data-bs-toggle="dropdown" role="button" aria-expanded="false">
|
<a href="javascript:void(0);" class="nav-link ps-2 dropdown-toggle" data-bs-toggle="dropdown" role="button" aria-expanded="false">
|
||||||
<span class="username me-1">
|
<span class="username me-1">
|
||||||
<span>
|
<span>
|
||||||
<i class="bi bi-person-circle me-2" aria-hidden="true"></i>
|
<i class="bi bi-person-circle me-2" aria-hidden="true"/>
|
||||||
</span>
|
</span>
|
||||||
<xsl:value-of select="$USER_FULL_NAME"/>
|
<xsl:value-of select="$USER_FULL_NAME"/>
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<div class="dropdown-menu dropdown-menu-right mt-2 pt-0 pb-0">
|
<div class="dropdown-menu dropdown-menu-end mt-2 pt-0 pb-0">
|
||||||
|
|
||||||
<!-- <a class="dropdown-item ps-2 my-account" href="javascript:void(0);">
|
<!-- <a class="dropdown-item ps-2 my-account" href="javascript:void(0);">
|
||||||
<i class="bi bi-person me-2"/>My Account</a>-->
|
<i class="bi bi-person me-2"/>My Account</a>-->
|
||||||
@@ -207,7 +211,7 @@
|
|||||||
</a>
|
</a>
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<div class="dropdown-divider mt-1 mb-1"></div>
|
<div class="dropdown-divider mt-1 mb-1"/>
|
||||||
|
|
||||||
<a class="dropdown-item ps-2 setup-users" href="javascript:void(0);">
|
<a class="dropdown-item ps-2 setup-users" href="javascript:void(0);">
|
||||||
<i class="bi bi-person-circle me-2"/>Users
|
<i class="bi bi-person-circle me-2"/>Users
|
||||||
@@ -234,21 +238,12 @@
|
|||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
</div>
|
</header>
|
||||||
|
<main class="container-xxl content" id="main-content" tabindex="-1">
|
||||||
</div>
|
|
||||||
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<!-- Content Area -->
|
|
||||||
|
|
||||||
<div class="container-xxl content">
|
|
||||||
|
|
||||||
$$$-CONTENT-$$$
|
$$$-CONTENT-$$$
|
||||||
|
|
||||||
</div>
|
</main>
|
||||||
|
|
||||||
<!-- Footer -->
|
|
||||||
|
|
||||||
<footer id="footer">
|
<footer id="footer">
|
||||||
|
|
||||||
@@ -263,6 +258,8 @@
|
|||||||
|
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
</div><!-- Footer -->
|
||||||
|
|
||||||
<!-- Spinner Modal Dialog -->
|
<!-- Spinner Modal Dialog -->
|
||||||
|
|
||||||
<div class="modal" id="spinner-dialog" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1">
|
<div class="modal" id="spinner-dialog" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1">
|
||||||
|
|||||||
@@ -0,0 +1,133 @@
|
|||||||
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
|
||||||
|
|
||||||
|
<xsl:param name="APPLICATION_NAME">MyHuntRoster</xsl:param>
|
||||||
|
<xsl:param name="PAGE_TITLE">Create your account to get started.</xsl:param>
|
||||||
|
<xsl:param name="FORM_NAME">signUp</xsl:param>
|
||||||
|
<xsl:param name="BTN_SUBMIT"></xsl:param>
|
||||||
|
<xsl:param name="REGISTER_ACTION"></xsl:param>
|
||||||
|
<xsl:param name="BTN_SIGNIN">?Xaction=signin</xsl:param>
|
||||||
|
<xsl:param name="SIGNUP_ERROR"></xsl:param>
|
||||||
|
<xsl:param name="SIGNUP_SUCCESSFUL"></xsl:param>
|
||||||
|
<xsl:param name="USER_FIRST_NAME"></xsl:param>
|
||||||
|
<xsl:param name="USER_LAST_NAME"></xsl:param>
|
||||||
|
<xsl:param name="USER_EMAIL"></xsl:param>
|
||||||
|
<xsl:param name="USER_NAME"></xsl:param>
|
||||||
|
<xsl:param name="CSRF_TOKEN"></xsl:param>
|
||||||
|
<xsl:param name="VERSION"></xsl:param>
|
||||||
|
<xsl:output method="html" encoding="UTF-8" indent="yes"/>
|
||||||
|
<xsl:template match="/">
|
||||||
|
<xsl:text disable-output-escaping="yes"><!DOCTYPE html></xsl:text>
|
||||||
|
<html lang="en" data-bs-theme="light">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||||
|
<meta name="robots" content="noindex"/>
|
||||||
|
<title>Create account · <xsl:value-of select="$APPLICATION_NAME"/></title>
|
||||||
|
<link href="css/bootstrap.css?version={$VERSION}" rel="stylesheet"/>
|
||||||
|
<link href="css/bootstrap-icons.min.css?version={$VERSION}" rel="stylesheet"/>
|
||||||
|
<link href="images/baseproject-logo.png" rel="icon" type="image/png"/>
|
||||||
|
<link rel="stylesheet" href="css/signIn.css?version={$VERSION}"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="login-shell">
|
||||||
|
<aside class="login-story" aria-label="About MyHuntRoster">
|
||||||
|
<a href="./" class="login-brand">
|
||||||
|
<svg class="brand-mark" viewBox="0 0 36 40" aria-hidden="true">
|
||||||
|
<path fill="currentColor" d="M18 1 5 18h7L2 31h13v8h6v-8h13L24 18h7Z"/>
|
||||||
|
</svg>
|
||||||
|
<span>
|
||||||
|
<xsl:value-of select="$APPLICATION_NAME"/>
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
<div class="story-copy">
|
||||||
|
<div class="eyebrow">Less paperwork. More outdoors.</div>
|
||||||
|
<h1>Your club.<br/>Your people.<br/>Your season.</h1>
|
||||||
|
<p>A simpler way to keep your hunting club connected, organized, and ready for what’s next.</p>
|
||||||
|
</div>
|
||||||
|
<svg class="landscape" viewBox="0 0 600 400" preserveAspectRatio="xMidYMax slice" aria-hidden="true">
|
||||||
|
<path fill="#254e3c" d="M0 180Q150 70 320 200T600 140V400H0Z"/>
|
||||||
|
<path fill="#102e24" d="M0 300Q200 160 380 280T600 210V400H0Z"/>
|
||||||
|
<g fill="#0d291f">
|
||||||
|
<path d="m70 145-45 100h27l-39 75h44v80h25v-80h44l-39-75h28Z"/>
|
||||||
|
<path d="m505 105-50 120h30l-44 90h50v85h28v-85h50l-44-90h30Z"/>
|
||||||
|
<path d="m400 205-32 75h18l-27 60h31v60h20v-60h31l-27-60h18Z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
<div class="story-footer">Built around the way your club works.</div>
|
||||||
|
</aside>
|
||||||
|
<main class="login-panel" id="main-content">
|
||||||
|
<div class="login-form-wrap">
|
||||||
|
<a href="./" class="login-brand mobile-brand">
|
||||||
|
<svg class="brand-mark" viewBox="0 0 36 40" aria-hidden="true">
|
||||||
|
<path fill="currentColor" d="M18 1 5 18h7L2 31h13v8h6v-8h13L24 18h7Z"/>
|
||||||
|
</svg>
|
||||||
|
<span>
|
||||||
|
<xsl:value-of select="$APPLICATION_NAME"/>
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
<div class="panel-label">Create account</div>
|
||||||
|
<h2>Your next season starts here.</h2>
|
||||||
|
<p class="login-intro">
|
||||||
|
<xsl:value-of select="$PAGE_TITLE"/>
|
||||||
|
</p>
|
||||||
|
<xsl:if test="string-length(normalize-space($SIGNUP_ERROR)) > 0">
|
||||||
|
<div class="alert alert-danger" role="alert">
|
||||||
|
<xsl:value-of select="$SIGNUP_ERROR"/>
|
||||||
|
</div>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:if test="$SIGNUP_SUCCESSFUL = 'TRUE'">
|
||||||
|
<div class="alert alert-success" role="alert">Your account request has been received. Follow the instructions provided by your club administrator to complete access.</div>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:if test="$SIGNUP_SUCCESSFUL != 'TRUE'">
|
||||||
|
<form action="{$BTN_SUBMIT}" name="{$FORM_NAME}" id="{$FORM_NAME}" method="post" data-create-account="true">
|
||||||
|
<xsl:if test="string-length(normalize-space($REGISTER_ACTION)) > 0">
|
||||||
|
<input type="hidden" name="action" value="{$REGISTER_ACTION}"/>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:if test="string-length($CSRF_TOKEN) > 0">
|
||||||
|
<input type="hidden" name="csrf_token" value="{$CSRF_TOKEN}"/>
|
||||||
|
</xsl:if>
|
||||||
|
<div class="row g-3">
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<label for="user_first_name" class="form-label">First name</label>
|
||||||
|
<input type="text" id="user_first_name" name="user_first_name" class="form-control" autocomplete="given-name" required="required" value="{$USER_FIRST_NAME}"/>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<label for="user_last_name" class="form-label">Last name</label>
|
||||||
|
<input type="text" id="user_last_name" name="user_last_name" class="form-control" autocomplete="family-name" required="required" value="{$USER_LAST_NAME}"/>
|
||||||
|
</div>
|
||||||
|
<div class="col-12">
|
||||||
|
<label for="user_email" class="form-label">Email address</label>
|
||||||
|
<input type="email" id="user_email" name="user_email" class="form-control" autocomplete="email" required="required" value="{$USER_EMAIL}" autocapitalize="none" spellcheck="false"/>
|
||||||
|
</div>
|
||||||
|
<div class="col-12">
|
||||||
|
<label for="user_name" class="form-label">Username</label>
|
||||||
|
<input type="text" id="user_name" name="user_name" class="form-control" autocomplete="username" required="required" value="{$USER_NAME}" autocapitalize="none" spellcheck="false"/>
|
||||||
|
</div>
|
||||||
|
<div class="col-12">
|
||||||
|
<label for="user_password" class="form-label">Password</label>
|
||||||
|
<input type="password" id="user_password" name="user_password" class="form-control" autocomplete="new-password" required="required"/>
|
||||||
|
</div>
|
||||||
|
<div class="col-12">
|
||||||
|
<label for="user_password_confirm" class="form-label">Confirm password</label>
|
||||||
|
<input type="password" id="user_password_confirm" name="user_password_confirm" class="form-control" autocomplete="new-password" required="required" aria-describedby="confirm-password-help"/>
|
||||||
|
<div id="confirm-password-help" class="form-text">Enter your password again.</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary w-100 mt-4 btnSignUp">Create account</button>
|
||||||
|
<p class="small text-secondary mt-3 mb-0">Your club administrator manages club membership and access.</p>
|
||||||
|
</form>
|
||||||
|
</xsl:if>
|
||||||
|
<p class="login-help">Already have an account? <a href="{$BTN_SIGNIN}">Sign in</a></p>
|
||||||
|
<div class="login-bottom">
|
||||||
|
<div class="mb-2">Unauthorized Access is Prohibited</div>
|
||||||
|
<span>OneSource IT Solutions · </span>
|
||||||
|
<xsl:value-of select="$APPLICATION_NAME"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
</xsl:template>
|
||||||
|
</xsl:stylesheet>
|
||||||
+129
@@ -0,0 +1,129 @@
|
|||||||
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
|
||||||
|
<xsl:output method="html" encoding="UTF-8" indent="yes"/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Parameters -->
|
||||||
|
<xsl:param name="APPLICATION_NAME">My Hunting Club Roster</xsl:param>
|
||||||
|
<xsl:param name="PAGE_TITLE">Sign in to your hunting club workspace.</xsl:param>
|
||||||
|
<xsl:param name="FORM_NAME">login</xsl:param>
|
||||||
|
<xsl:param name="BTN_SUBMIT"></xsl:param>
|
||||||
|
<xsl:param name="BTN_RESET_PASSWORD">./?Xaction=resetpassword</xsl:param>
|
||||||
|
<xsl:param name="INVALID_SIGNIN"></xsl:param>
|
||||||
|
<xsl:param name="RESET_PASSWORD_SUCCESSFUL"></xsl:param>
|
||||||
|
<xsl:param name="VERSION"></xsl:param>
|
||||||
|
|
||||||
|
<xsl:template match="/">
|
||||||
|
<xsl:text disable-output-escaping="yes"><!DOCTYPE html></xsl:text>
|
||||||
|
|
||||||
|
<html lang="en" data-bs-theme="light">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||||
|
<meta name="robots" content="noindex"/>
|
||||||
|
|
||||||
|
<title>Sign in · <xsl:value-of select="$APPLICATION_NAME"/></title>
|
||||||
|
|
||||||
|
<link href="css/themes/MyHuntingClubRoster/bootstrap.css?version={$VERSION}" rel="stylesheet"/>
|
||||||
|
<link href="css/bootstrap-icons.min.css?version={$VERSION}" rel="stylesheet"/>
|
||||||
|
<link href="css/signin.css" rel="stylesheet"/>
|
||||||
|
<link href="images/MyHuntRoster_Logo.png" rel="icon" type="image/png"/>
|
||||||
|
|
||||||
|
<script src="js/jquery-3.2.0.min.js?version={$VERSION}"> </script>
|
||||||
|
<script src="js/bootstrap.bundle.min.js?version={$VERSION}"> </script>
|
||||||
|
<script src="js/login.js?version={$VERSION}"></script>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="login-shell">
|
||||||
|
<aside class="login-story" aria-label="About MyHuntRoster">
|
||||||
|
<a href="./" class="login-brand">
|
||||||
|
<svg class="brand-mark" viewBox="0 0 36 40" aria-hidden="true">
|
||||||
|
<path fill="currentColor" d="M18 1 5 18h7L2 31h13v8h6v-8h13L24 18h7Z"/>
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
<div class="story-copy">
|
||||||
|
<div class="eyebrow">Less paperwork. More outdoors.</div>
|
||||||
|
<h1>Your club.<br/>Your people.<br/>Your season.</h1>
|
||||||
|
<p>A simpler way to keep your hunting club connected, organized, and ready for what’s next.</p>
|
||||||
|
</div>
|
||||||
|
<svg class="landscape" viewBox="0 0 600 400" preserveAspectRatio="xMidYMax slice" aria-hidden="true">
|
||||||
|
<path fill="#254e3c" d="M0 180Q150 70 320 200T600 140V400H0Z"/>
|
||||||
|
<path fill="#102e24" d="M0 300Q200 160 380 280T600 210V400H0Z"/>
|
||||||
|
<g fill="#0d291f">
|
||||||
|
<path d="m70 145-45 100h27l-39 75h44v80h25v-80h44l-39-75h28Z"/>
|
||||||
|
<path d="m505 105-50 120h30l-44 90h50v85h28v-85h50l-44-90h30Z"/>
|
||||||
|
<path d="m400 205-32 75h18l-27 60h31v60h20v-60h31l-27-60h18Z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
<div class="story-footer">Built around the way your club works.</div>
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
<main class="login-panel" id="main-content">
|
||||||
|
|
||||||
|
<div class="login-form-wrap">
|
||||||
|
<a href="./" class="login-brand mobile-brand">
|
||||||
|
<svg class="brand-mark" viewBox="0 0 36 40" aria-hidden="true">
|
||||||
|
<path fill="currentColor" d="M18 1 5 18h7L2 31h13v8h6v-8h13L24 18h7Z"/>
|
||||||
|
</svg>
|
||||||
|
<span>
|
||||||
|
<xsl:value-of select="$APPLICATION_NAME"/>
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
<div class="mb-4">
|
||||||
|
<img src="images/MyHuntRoster_Logo.png"
|
||||||
|
alt="{$APPLICATION_NAME}"
|
||||||
|
class="img-fluid"
|
||||||
|
style="max-width: 340px; max-height: 140px; object-fit: contain;"/>
|
||||||
|
</div>
|
||||||
|
<h2>Welcome!</h2>
|
||||||
|
<p class="login-intro">
|
||||||
|
<xsl:value-of select="$PAGE_TITLE"/>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<xsl:if test="$INVALID_SIGNIN = 'TRUE'">
|
||||||
|
<div class="alert alert-danger" role="alert">Invalid username or password.</div>
|
||||||
|
</xsl:if>
|
||||||
|
|
||||||
|
<xsl:if test="$RESET_PASSWORD_SUCCESSFUL = 'TRUE'">
|
||||||
|
<div class="alert alert-info" role="alert">If an account exists for the email address provided, you will receive an email containing a temporary password and a link to reset your password.</div>
|
||||||
|
</xsl:if>
|
||||||
|
|
||||||
|
<form action="{$BTN_SUBMIT}" name="{$FORM_NAME}" method="post" id="{$FORM_NAME}">
|
||||||
|
<input type="hidden" name="action" value="Users.login"/>
|
||||||
|
<input type="hidden" name="step" value="authenticate"/>
|
||||||
|
<div class="mb-4">
|
||||||
|
<label class="form-label" for="user_email">Email Address</label>
|
||||||
|
<input type="text" class="form-control" id="user_email" name="user_email" autocomplete="email" maxlength="128" placeholder="Enter Email Address" autofocus="autofocus"/>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label" for="user_password">Password</label>
|
||||||
|
<input id="user_password" name="user_password" type="password" class="form-control" autocomplete="current-password" maxlength="128" placeholder="Enter password"/>
|
||||||
|
</div>
|
||||||
|
<div class="d-grid gap-2 mt-4">
|
||||||
|
<button type="submit" class="btn btn-primary btnSignIn" style="min-height:48px">Sign In</button>
|
||||||
|
<button type="button" class="btn btn-warning btnSignUp" style="min-height:44px">Sign Up for New Account</button>
|
||||||
|
<button type="button" class="btn btn-outline-secondary btnForgot" style="min-height:44px">Forgot/Reset Password</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<form action="{$BTN_RESET_PASSWORD}" name="reset-password" method="post" id="reset-password">
|
||||||
|
<input type="hidden" id="reset_user_email" name="user_email"/>
|
||||||
|
</form>
|
||||||
|
<p class="login-help">Need access to your club?<br/>Contact your club administrator to get started.</p>
|
||||||
|
<div class="login-bottom">
|
||||||
|
<div class="mb-2">Unauthorized Access is Prohibited</div>
|
||||||
|
<xsl:value-of select="$APPLICATION_NAME"/>
|
||||||
|
<span> · A product of OneSource IT Solutions</span>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
</xsl:template>
|
||||||
|
</xsl:stylesheet>
|
||||||
Reference in New Issue
Block a user