Compare commits

...

4 Commits
4.0.4 ... 4.1

Author SHA1 Message Date
e52ae78ed0 composer bump 2025-02-02 18:44:53 -05:00
5e621883ff Various changes
mobile-friendly ui updates
admin user-edit bugfix
file cleanup
added searchFields
add blog search
remove unused code
add maintenance mode config
2025-02-02 02:16:43 -05:00
b5996dc7db remove unused code 2025-02-02 01:55:15 -05:00
bc33b4cac4 cleanup and added admin images control 2025-02-02 01:55:15 -05:00
130 changed files with 1325 additions and 1558 deletions

View File

@ -18,7 +18,7 @@ I am working very hard to ensure the system is safe and reliable enough for me t
## Find Us ## Find Us
* [DockerHub](https://hub.docker.com/repositories/thetempusproject) * [DockerHub](https://hub.docker.com/repositories/thetempusproject)
* [Packagist](https://packagist.org/users/joeyk4816/packages/) * [Packagist](https://packagist.org/packages/thetempusproject/)
* [GitLab](https://git.thetempusproject.com/the-tempus-project/thetempusproject) * [GitLab](https://git.thetempusproject.com/the-tempus-project/thetempusproject)
## Summary ## Summary

View File

@ -268,13 +268,13 @@ class Preferences {
} }
$html .= '<div class="mb-3 row">'; $html .= '<div class="mb-3 row">';
$html .= '<label for="' . $fieldname . '" class="col-lg-6 col-form-label text-end">' . $fieldTitle . '</label>'; $html .= '<label for="' . $fieldname . '" class="col-lg-6 col-form-label text-start text-lg-end">' . $fieldTitle . '</label>';
$html .= '<div class="col-lg-6">'; $html .= '<div class="col-lg-6">';
$html .= $fieldHtml; $html .= $fieldHtml;
$html .= '</div>'; $html .= '</div>';
if ( 'file' === $type ) { if ( 'file' === $type ) {
$html .= '<div class="mb-3 row">'; $html .= '<div class="mb-3 row">';
$html .= '<h4 class="col-lg-6 col-form-label text-end">Current Image</h4>'; $html .= '<h4 class="col-lg-6 col-form-label text-start text-lg-end">Current Image</h4>';
$html .= '<div class="col-lg-6">'; $html .= '<div class="col-lg-6">';
$html .= '<img alt="User Avatar" src="{ROOT_URL}' . $defaultValue . '" class="img-circle img-fluid p-2 avatar-125">'; $html .= '<img alt="User Avatar" src="{ROOT_URL}' . $defaultValue . '" class="img-circle img-fluid p-2 avatar-125">';
$html .= '</div>'; $html .= '</div>';

View File

@ -32,8 +32,6 @@ class Groups extends AdminController {
self::$title = 'Admin - Groups'; self::$title = 'Admin - Groups';
self::$group = new Group; self::$group = new Group;
self::$permissions = new Permissions; self::$permissions = new Permissions;
$view = Navigation::activePageSelect( 'nav.admin', '/admin/groups' );
Components::set( 'ADMINNAV', $view );
} }
public function create( $data = null ) { public function create( $data = null ) {

View File

@ -22,6 +22,7 @@ use TheTempusProject\Plugins\Comments as CommentPlugin;
use TheTempusProject\Plugins\Blog as BlogPlugin; use TheTempusProject\Plugins\Blog as BlogPlugin;
use TheTempusProject\Plugins\Contact as ContactPlugin; use TheTempusProject\Plugins\Contact as ContactPlugin;
use TheTempusProject\Canary\Bin\Canary as Debug; use TheTempusProject\Canary\Bin\Canary as Debug;
use TheTempusProject\Bedrock\Functions\Input;
class Home extends AdminController { class Home extends AdminController {
public static $user; public static $user;

View File

@ -0,0 +1,114 @@
<?php
/**
* app/controllers/admin/tokens.php
*
* This is the admin app/user tokens controller.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Controllers\Admin;
use TheTempusProject\Classes\Forms as TTPForms;
use TheTempusProject\Houdini\Classes\Views;
use TheTempusProject\Houdini\Classes\Issues;
use TheTempusProject\Houdini\Classes\Navigation;
use TheTempusProject\Houdini\Classes\Components;
use TheTempusProject\Houdini\Classes\Forms;
use TheTempusProject\Classes\AdminController;
use TheTempusProject\Models\Token;
use TheTempusProject\Bedrock\Functions\Input;
use TheTempusProject\Bedrock\Functions\Check;
use TheTempusProject\Hermes\Functions\Redirect;
use TheTempusProject\Bedrock\Functions\Session;
class Images extends AdminController {
public function __construct() {
parent::__construct();
self::$title = 'Admin - Images';
}
public function create() {
if ( Input::exists( 'submit' ) ) {
if ( !TTPForms::check( 'addImage' ) ) {
Issues::add( 'error', [ 'There was an error with your image.' => Check::userErrors() ] );
}
if ( Input::exists( 'folder' ) ) {
$folder = Input::post('folder');
} else {
// IMAGE_DIRECTORY
$folder = UPLOAD_DIRECTORY . App::$activeUser->username . DIRECTORY_SEPARATOR . 'images' . DIRECTORY_SEPARATOR;
}
$upload = Upload::image( 'upload', $folder );
if ( $upload ) {
$route = str_replace( APP_ROOT_DIRECTORY, '', $folder );
$out = $route . Upload::last();
} else {
Debug::error( 'There was an error with your upload.');
Issues::add( 'error', [ 'There was an error with your upload.' => Check::userErrors() ] );
}
// if ( self::$token->create(
// Input::post( 'name' ),
// Input::post( 'notes' ),
// Input::post( 'token_type' )
// ) ) {
// Session::flash( 'success', 'Token Created' );
// Redirect::to( 'admin/images' );
// }
}
Views::view( 'admin.images.create' );
}
public function delete( $id = null ) {
if ( self::$token->delete( [ $id ] ) ) {
Session::flash( 'success', 'Token deleted.' );
}
Redirect::to( 'admin/images' );
}
public function edit( $id = null ) {
$token = self::$token->findById( $id );
if ( Input::exists( 'submit' ) ) {
if ( !TTPForms::check( 'adminEditToken' ) ) {
Issues::add( 'error', [ 'There was an error with your token.' => Check::userErrors() ] );
} else {
if ( self::$token->update(
$id,
Input::post( 'name' ),
Input::post( 'notes' ),
Input::post( 'token_type' )
) ) {
Session::flash( 'success', 'Token Updated' );
Redirect::to( 'admin/images' );
}
}
}
Forms::selectOption( $token->token_type );
return Views::view( 'admin.images.edit', $token );
}
public function index() {
return Views::view( 'admin.images.list', self::$token->listPaginated() );
}
public function view( $id = null ) {
return Views::view( 'admin.images.view', self::$token->findById( $id ) );
}
}

View File

@ -30,8 +30,6 @@ class Plugins extends AdminController {
self::$title = 'Admin - Installed Plugins'; self::$title = 'Admin - Installed Plugins';
$this->installer = new Installer; $this->installer = new Installer;
$this->plugins = $this->installer->getAvailablePlugins(); $this->plugins = $this->installer->getAvailablePlugins();
$view = Navigation::activePageSelect( 'nav.admin', '/admin/plugins' );
Components::set( 'ADMINNAV', $view );
} }
public function index() { public function index() {

View File

@ -31,8 +31,6 @@ class Routes extends AdminController {
parent::__construct(); parent::__construct();
self::$title = 'Admin - Redirects'; self::$title = 'Admin - Redirects';
self::$routes = new RoutesClass; self::$routes = new RoutesClass;
$view = Navigation::activePageSelect( 'nav.admin', '/admin/routes' );
Components::set( 'ADMINNAV', $view );
} }
public function create() { public function create() {

View File

@ -31,8 +31,6 @@ class Tokens extends AdminController {
parent::__construct(); parent::__construct();
self::$title = 'Admin - Tokens'; self::$title = 'Admin - Tokens';
self::$token = new Token; self::$token = new Token;
$view = Navigation::activePageSelect( 'nav.admin', '/admin/tokens' );
Components::set( 'ADMINNAV', $view );
} }
public function create() { public function create() {

View File

@ -27,6 +27,7 @@ use TheTempusProject\Models\User;
use TheTempusProject\Models\Group; use TheTempusProject\Models\Group;
use TheTempusProject\TheTempusProject as App; use TheTempusProject\TheTempusProject as App;
use TheTempusProject\Houdini\Classes\Template; use TheTempusProject\Houdini\Classes\Template;
use TheTempusProject\Bedrock\Functions\Upload;
class Users extends AdminController { class Users extends AdminController {
public static $user; public static $user;
@ -37,8 +38,6 @@ class Users extends AdminController {
self::$title = 'Admin - Users'; self::$title = 'Admin - Users';
self::$user = new User; self::$user = new User;
self::$group = new Group; self::$group = new Group;
$view = Navigation::activePageSelect( 'nav.admin', '/admin/users' );
Components::set( 'ADMINNAV', $view );
} }
public function create() { public function create() {
@ -114,6 +113,25 @@ class Users extends AdminController {
'email' => Input::post( 'email' ), 'email' => Input::post( 'email' ),
'userGroup' => Input::post( 'groupSelect' ), 'userGroup' => Input::post( 'groupSelect' ),
]; ];
if ( Input::exists( 'avatar' ) ) {
$folder = UPLOAD_DIRECTORY . $userData->username . DIRECTORY_SEPARATOR . 'images' . DIRECTORY_SEPARATOR;
$upload = Upload::image( 'avatar', $folder );
if ( $upload ) {
$route = str_replace( APP_ROOT_DIRECTORY, '', $folder );
$prefs = [];
$prefs['avatar'] = $route . Upload::last();
self::$user->updatePrefs( $prefs, $userData->ID );
} else {
Issues::add( 'error', [ 'There was an error with your avatar.' => Check::userErrors() ] );
}
}
if ( Input::exists( 'password' ) ) {
$fields['password'] = Hash::make( Input::post( 'password' ) );
}
if ( Input::exists( 'confirmed' ) ) { if ( Input::exists( 'confirmed' ) ) {
$fields['confirmed'] = 1; $fields['confirmed'] = 1;
} else { } else {
@ -121,6 +139,7 @@ class Users extends AdminController {
$fields['confirmationCode'] = Code::genConfirmation(); $fields['confirmationCode'] = Code::genConfirmation();
} }
} }
if ( self::$user->update( $userData->ID, $fields ) ) { if ( self::$user->update( $userData->ID, $fields ) ) {
Issues::add( 'success', 'User Updated.' ); Issues::add( 'success', 'User Updated.' );
return $this->index(); return $this->index();

View File

@ -1,35 +0,0 @@
<?php
/**
* app/controllers/alpha.php
*
* This is the friends and family alpha controller.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Controllers;
use TheTempusProject\Classes\Controller;
use TheTempusProject\Houdini\Classes\Views;
class Alpha extends Controller {
public function index() {
self::$title = 'Friends and Family Alpha';
self::$pageDescription = 'The Tempus Project friends and family alpha has begun. Please join me and take part in bringing a dream to reality.';
Views::view( 'alpha.index' );
}
public function crashcourse() {
self::$title = 'Friends and Family Crash-Course';
self::$pageDescription = 'The Tempus Project runs not only this site, but it can be used and deployed for any number of sites. This crash course is intended to give you all the knowledge you will need to start building your own applications powered by The Tempus Project.';
Views::view( 'alpha.crashcourse' );
}
public function certification() {
self::$title = 'Friends and Family Certification';
self::$pageDescription = 'The Tempus Project runs not only this site, but it can be used and deployed for any number of sites. This certification course is intended to give experienced users all the information they will need to start building your own applications powered by The Tempus Project.';
Views::view( 'alpha.certification' );
}
}

View File

@ -38,15 +38,15 @@ class Home extends Controller {
return Issues::add( 'notice', 'You are already logged in. Please <a href="' . Routes::getAddress() . 'home/logout">click here</a> to log out.' ); return Issues::add( 'notice', 'You are already logged in. Please <a href="' . Routes::getAddress() . 'home/logout">click here</a> to log out.' );
} }
if ( !Input::exists() ) { if ( !Input::exists() ) {
return Views::view( 'login' ); return Views::view( 'auth.login' );
} }
if ( !Forms::check( 'login' ) ) { if ( !Forms::check( 'login' ) ) {
Issues::add( 'error', [ 'There was an error with your login.' => Check::userErrors() ] ); Issues::add( 'error', [ 'There was an error with your login.' => Check::userErrors() ] );
return Views::view( 'login' ); return Views::view( 'auth.login' );
} }
if ( !self::$user->logIn( Input::post( 'username' ), Input::post( 'password' ), Input::post( 'remember' ) ) ) { if ( !self::$user->logIn( Input::post( 'username' ), Input::post( 'password' ), Input::post( 'remember' ) ) ) {
Issues::add( 'error', 'Username or password was incorrect.' ); Issues::add( 'error', 'Username or password was incorrect.' );
return Views::view( 'login' ); return Views::view( 'auth.login' );
} }
Session::flash( 'success', 'You have been logged in.' ); Session::flash( 'success', 'You have been logged in.' );
if ( Input::exists( 'rurl' ) ) { if ( Input::exists( 'rurl' ) ) {
@ -79,13 +79,13 @@ class Home extends Controller {
} }
self::$title = $user->username . '\'s Profile - {SITENAME}'; self::$title = $user->username . '\'s Profile - {SITENAME}';
self::$pageDescription = 'User Profile for ' . $user->username . ' - {SITENAME}'; self::$pageDescription = 'User Profile for ' . $user->username . ' - {SITENAME}';
Views::view( 'profile', $user ); Views::view( 'profilePage', $user );
} }
public function terms() { public function terms() {
self::$title = 'Terms and Conditions - {SITENAME}'; self::$title = 'Terms and Conditions - {SITENAME}';
self::$pageDescription = '{SITENAME} Terms and Conditions of use. Please use {SITENAME} safely.'; self::$pageDescription = '{SITENAME} Terms and Conditions of use. Please use {SITENAME} safely.';
Components::set( 'TERMS', Views::simpleView( 'terms' ) ); Components::set( 'TERMS', Views::simpleView( 'auth.terms' ) );
Views::view( 'termsPage' ); Views::view( 'termsPage' );
} }
@ -98,8 +98,7 @@ class Home extends Controller {
public function privacy() { public function privacy() {
self::$title = 'Privacy Policy - {SITENAME}'; self::$title = 'Privacy Policy - {SITENAME}';
self::$pageDescription = 'At {SITENAME} you privacy is very important to us. On this page you can find a detailed outline of all the information we collect and how its used.'; self::$pageDescription = 'At {SITENAME} you privacy is very important to us. On this page you can find a detailed outline of all the information we collect and how its used.';
Components::set( 'PRIVACY', Views::simpleView( 'privacy' ) ); Views::view( 'privacy' );
Views::raw( '<div class="col-lg-8 mx-auto">{PRIVACY}</div>' );
} }
public function faq() { public function faq() {

View File

@ -1,3 +0,0 @@
<?php
// the idea is that this will be info pages for the plugin various/info
?>

View File

@ -31,14 +31,14 @@ class Register extends Controller {
Template::noIndex(); Template::noIndex();
self::$title = 'Confirm Email'; self::$title = 'Confirm Email';
if ( !isset( $code ) && !Input::exists( 'confirmationCode' ) ) { if ( !isset( $code ) && !Input::exists( 'confirmationCode' ) ) {
return Views::view( 'confirmation' ); return Views::view( 'auth.confirmation' );
} }
if ( Forms::check( 'emailConfirmation' ) ) { if ( Forms::check( 'emailConfirmation' ) ) {
$code = Input::post( 'confirmationCode' ); $code = Input::post( 'confirmationCode' );
} }
if ( !self::$user->confirm( $code ) ) { if ( !self::$user->confirm( $code ) ) {
Issues::add( 'error', 'There was an error confirming your account, please try again.' ); Issues::add( 'error', 'There was an error confirming your account, please try again.' );
return Views::view( 'confirmation' ); return Views::view( 'auth.confirmation' );
} }
Session::flash( 'success', 'You have successfully confirmed your email address.' ); Session::flash( 'success', 'You have successfully confirmed your email address.' );
Redirect::to( 'home/index' ); Redirect::to( 'home/index' );
@ -52,16 +52,16 @@ class Register extends Controller {
return Issues::add( 'notice', 'The site administrator has disable the ability to register a new account.' ); return Issues::add( 'notice', 'The site administrator has disable the ability to register a new account.' );
} }
Components::set( 'TERMS', Views::simpleView( 'terms' ) ); Components::set( 'TERMS', Views::simpleView( 'auth.terms' ) );
if ( App::$isLoggedIn ) { if ( App::$isLoggedIn ) {
return Issues::add( 'notice', 'You are currently logged in.' ); return Issues::add( 'notice', 'You are currently logged in.' );
} }
if ( !Input::exists() ) { if ( !Input::exists() ) {
return Views::view( 'register' ); return Views::view( 'auth.register' );
} }
if ( !Forms::check( 'register' ) ) { if ( !Forms::check( 'register' ) ) {
Issues::add( 'error', [ 'There was an error with your registration.' => Check::userErrors() ] ); Issues::add( 'error', [ 'There was an error with your registration.' => Check::userErrors() ] );
return Views::view( 'register' ); return Views::view( 'auth.register' );
} }
self::$user->create( [ self::$user->create( [
'username' => Input::post( 'username' ), 'username' => Input::post( 'username' ),
@ -80,7 +80,7 @@ class Register extends Controller {
self::$title = 'Recover Account - {SITENAME}'; self::$title = 'Recover Account - {SITENAME}';
Template::noIndex(); Template::noIndex();
if ( !Input::exists() ) { if ( !Input::exists() ) {
return Views::view( 'forgot' ); return Views::view( 'auth.forgot' );
} }
if ( Check::email( Input::post( 'entry' ) ) && self::$user->findByEmail( Input::post( 'entry' ) ) ) { if ( Check::email( Input::post( 'entry' ) ) && self::$user->findByEmail( Input::post( 'entry' ) ) ) {
$userData = self::$user->data(); $userData = self::$user->data();
@ -96,7 +96,7 @@ class Register extends Controller {
Redirect::to( 'home/login' ); Redirect::to( 'home/login' );
} }
Issues::add( 'error', 'User not found.' ); Issues::add( 'error', 'User not found.' );
Views::view( 'forgot' ); Views::view( 'auth.forgot' );
} }
public function resend() { public function resend() {
@ -109,7 +109,7 @@ class Register extends Controller {
return Issues::add( 'notice', 'Your account has already been confirmed.' ); return Issues::add( 'notice', 'Your account has already been confirmed.' );
} }
if ( !Forms::check( 'confirmationResend' ) ) { if ( !Forms::check( 'confirmationResend' ) ) {
return Views::view( 'confirmation_resend' ); return Views::view( 'auth.confirmation_resend' );
} }
Email::send( App::$activeUser->email, 'confirmation', App::$activeUser->confirmationCode, [ 'template' => true ] ); Email::send( App::$activeUser->email, 'confirmation', App::$activeUser->confirmationCode, [ 'template' => true ] );
Session::flash( 'success', 'Your confirmation email has been sent to the email for your account.' ); Session::flash( 'success', 'Your confirmation email has been sent to the email for your account.' );
@ -121,7 +121,7 @@ class Register extends Controller {
Template::noIndex(); Template::noIndex();
if ( !isset( $code ) && !Input::exists( 'resetCode' ) ) { if ( !isset( $code ) && !Input::exists( 'resetCode' ) ) {
Issues::add( 'info', 'Please provide a reset code.' ); Issues::add( 'info', 'Please provide a reset code.' );
return Views::view( 'password_reset_code' ); return Views::view( 'auth.password_reset_code' );
} }
if ( Input::exists( 'resetCode' ) ) { if ( Input::exists( 'resetCode' ) ) {
if ( Forms::check( 'passwordResetCode' ) ) { if ( Forms::check( 'passwordResetCode' ) ) {
@ -130,15 +130,15 @@ class Register extends Controller {
} }
if ( ! self::$user->checkCode( $code ) ) { if ( ! self::$user->checkCode( $code ) ) {
Issues::add( 'error', 'There was an error with your reset code. Please try again.' ); Issues::add( 'error', 'There was an error with your reset code. Please try again.' );
return Views::view( 'password_reset_code' ); return Views::view( 'auth.password_reset_code' );
} }
Components::set( 'resetCode', $code ); Components::set( 'resetCode', $code );
if ( ! Input::exists('password') ) { if ( ! Input::exists('password') ) {
return Views::view( 'password_reset' ); return Views::view( 'auth.password_reset' );
} }
if ( ! Forms::check( 'passwordReset' ) ) { if ( ! Forms::check( 'passwordReset' ) ) {
Issues::add( 'error', [ 'There was an error with your request.' => Check::userErrors() ] ); Issues::add( 'error', [ 'There was an error with your request.' => Check::userErrors() ] );
return Views::view( 'password_reset' ); return Views::view( 'auth.password_reset' );
} }
self::$user->changePassword( $code, Input::post( 'password' ) ); self::$user->changePassword( $code, Input::post( 'password' ) );
Email::send( self::$user->data()->email, 'passwordChange', null, [ 'template' => true ] ); Email::send( self::$user->data()->email, 'passwordChange', null, [ 'template' => true ] );

View File

@ -70,7 +70,7 @@ class Usercp extends Controller {
self::$title = 'User Control Panel'; self::$title = 'User Control Panel';
$menu = Views::simpleView( 'nav.usercp', App::$userCPlinks ); $menu = Views::simpleView( 'nav.usercp', App::$userCPlinks );
Navigation::activePageSelect( $menu, null, true, true ); Navigation::activePageSelect( $menu, null, true, true );
Views::view( 'profile', App::$activeUser ); Views::view( 'user_cp.profile', App::$activeUser );
} }
public function password() { public function password() {
@ -104,6 +104,10 @@ class Usercp extends Controller {
$userPrefs = App::$activePrefs; $userPrefs = App::$activePrefs;
if ( Input::exists( 'submit' ) ) { if ( Input::exists( 'submit' ) ) {
$fields = $prefs->convertFormToArray( true, false ); $fields = $prefs->convertFormToArray( true, false );
// @TODO now i may need to rework the form checker to work with this....
// if (!Forms::check('userPrefs')) {
// Issues::add( 'error', [ 'There was an error with your request.' => Check::userErrors() ] );
// }
self::$user->updatePrefs( $fields, App::$activeUser->ID ); self::$user->updatePrefs( $fields, App::$activeUser->ID );
Issues::add( 'success', 'Your preferences have been updated.' ); Issues::add( 'success', 'Your preferences have been updated.' );
// if the image upload fails, need to fall back on original // if the image upload fails, need to fall back on original

View File

@ -9,36 +9,42 @@
* @license https://opensource.org/licenses/MIT [MIT LICENSE] * @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/ */
.context-main { .context-main-border {
color: #fff; border-color: #f5f5f5!important;
}
.context-second {
color: #1e1e1e;
} }
.context-main-bg { .context-main-bg {
background-color: #2c2c2c; background-color: #2c2c2c;
} }
.context-second-bg { .context-second-bg {
background-color: #1e1e1e; background-color: #383838;
} }
.context-third-bg { .context-third-bg {
background-color: #3a3a3a; background-color: #3a3a3a;
} }
.context-other-bg {
background-color: #1e1e1e;
}
.context-main {
color: #fff;
}
.bg-default { .bg-default {
background-color: #2c2c2c; background-color: #2c2c2c;
} }
hr { hr {
color: #f5f5f5; color: #f5f5f5;
} }
.bg-none,.bg-warning { .bg-none,.bg-warning {
color: #000 !important; color: #000 !important;
} }
.context-other {
color: #000;
}
.accordion-button:not(.collapsed) { .accordion-button:not(.collapsed) {
color: #f5f5f5; color: #f5f5f5;
background-color: var(--bs-accordion-dark-active-bg); background-color: var(--bs-accordion-dark-active-bg);
@ -68,12 +74,6 @@ body {
.install-terms strong { .install-terms strong {
color: #ffffff; color: #ffffff;
} }
.context-main {
color: #ffffff;
}
.context-other {
color: #ffffff;
}
/** /**
* Terms Page * Terms Page

View File

@ -9,10 +9,28 @@
* @license https://opensource.org/licenses/MIT [MIT LICENSE] * @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/ */
.context-other-bg { .context-main-border {
background-color: #eaeaea; border-color: #1e1e1e!important;
} }
.context-main-bg {
background-color: #f7f7f7;
/* background-color: #b1b; */
}
.context-second-bg {
background-color: #eaeaea;
/* background-color: #b1b; */
}
.context-third-bg {
background-color: #ccc;
/* background-color: #b1b; */
}
.context-main {
color: #000;
}
.nav-link.active { .nav-link.active {
font-weight: bold; /* Make the text bold */ font-weight: bold; /* Make the text bold */
} }
@ -21,10 +39,6 @@ hr {
color: #000; color: #000;
} }
.context-main-bg {
background-color: #f7f7f7;
}
/* Base styles for the switch container */ /* Base styles for the switch container */
.material-switch { .material-switch {
position: relative; position: relative;
@ -77,20 +91,6 @@ hr {
transform: translateX(25px); /* Adjust based on switch width */ transform: translateX(25px); /* Adjust based on switch width */
} }
.context-main {
color: #000;
}
.context-other {
color: #fff;
}
html { html {
font-family: 'Open Sans', sans-serif; font-family: 'Open Sans', sans-serif;
position: relative; position: relative;
@ -319,3 +319,4 @@ body {
/* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */ /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
background: linear-gradient(to right, #2c2c2c, #1e1e1e, #1e1e1e); background: linear-gradient(to right, #2c2c2c, #1e1e1e, #1e1e1e);
} }

View File

@ -1,218 +0,0 @@
/**
* app/css/wysiwyg.css
*
* This file is for the wysiwyg editor's css.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
body {
margin: 0;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
font-family: 'Helvetica Neue', 'Helvetica', arial, sans-serif;
}
/* WYSIWYG Editor */
.wp-webdeasy-comment-editor {
width: 40rem;
min-height: 18rem;
box-shadow: 0 0 4px 1px rgba(0, 0, 0, 0.3);
border-top: 6px solid #4a4a4a;
border-radius: 3px;
margin: 2rem 0;
.toolbar {
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2);
.line {
display: flex;
border-bottom: 1px solid #e2e2e2;
&:last-child {
border-bottom: none;
}
.box {
display: flex;
border-left: 1px solid #e2e2e2;
.editor-btn {
display: block;
display: flex;
align-items: center;
justify-content: center;
position: relative;
transition: .2s ease all;
&:hover, &.active {
background-color: #e1e1e1;
cursor: pointer;
}
&.icon img {
width: 15px;
padding: 9px;
box-sizing: content-box;
}
&.icon.smaller img {
width: 16px;
}
&.has-submenu {
width: 20px;
padding: 0 10px;
&::after {
content: '';
width: 6px;
height: 6px;
position: absolute;
background-image: url(https://img.icons8.com/ios-glyphs/30/000000/chevron-down.png);
background-repeat: no-repeat;
background-size: cover;
background-position: center;
right: 4px;
}
.submenu {
display: none;
position: absolute;
top: 34px;
left: -1px;
z-index: 10;
background-color: #FFF;
border: 1px solid #b5b5b5;
border-top: none;
.btn {
width: 39px;
}
&:hover {
display: block;
}
}
&:hover .submenu {
display: block;
}
}
}
}
}
}
.content-area {
padding: 15px 12px;
line-height: 1.5;
.visuell-view {
outline: none;
min-height: 12rem;
p {
margin: 12px 0;
}
}
.html-view {
outline: none;
display: none;
width: 100%;
height: 200px;
border: none;
resize: none;
}
}
}
/* Modal */
.modal {
z-index: 40;
display: none;
.modal-wrapper {
background-color: #FFF;
padding: 1rem;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 20rem;
min-height: 10rem;
z-index: 41;
.close {
position: absolute;
top: 1rem;
right: 1rem;
cursor: pointer;
}
.modal-content {
flex-direction: column;
h3 {
margin-top: 0;
}
input {
margin: 1rem 0;
padding: .5rem;
}
input[type="text"] {
width: calc(100% - 1rem);
}
.row {
label {
margin-left: .5rem;
}
}
button {
background-color: #D2434F;
border: 0;
color: #FFF;
padding: .5rem 1.2rem;
cursor: pointer;
}
}
}
.modal-bg {
position: fixed;
background-color: rgba(0, 0, 0, .3);
width: 100vw;
height: 100vh;
top: 0;
left: 0;
}
}
/* Codepen Footer */
footer {
position: fixed;
bottom: 0;
display: flex;
p {
margin: 0.5rem 1rem;
font-size: 12px;
}
a {
text-decoration: none;
font-weight: bold;
color: #000;
}
}

View File

@ -1,233 +0,0 @@
/**
* app/js/wysiwyg.js
*
* This is css used in the debuging console.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
// define vars
const editor = document.getElementsByClassName('wp-webdeasy-comment-editor')[0];
const toolbar = editor.getElementsByClassName('toolbar')[0];
const buttons = toolbar.querySelectorAll('.editor-btn:not(.has-submenu)');
const contentArea = editor.getElementsByClassName('content-area')[0];
const visuellView = contentArea.getElementsByClassName('visuell-view')[0];
const htmlView = contentArea.getElementsByClassName('html-view')[0];
const modal = document.getElementsByClassName('modal')[0];
// add active tag event
document.addEventListener('selectionchange', selectionChange);
// add paste event
visuellView.addEventListener('paste', pasteEvent);
// add paragraph tag on new line
contentArea.addEventListener('keypress', addParagraphTag);
// add toolbar button actions
for(let i = 0; i < buttons.length; i++) {
let button = buttons[i];
button.addEventListener('click', function(e) {
let action = this.dataset.action;
switch(action) {
case 'toggle-view':
execCodeAction(this, editor);
break;
case 'createLink':
execLinkAction();
break;
default:
execDefaultAction(action);
}
});
}
/**
* This function toggles between visual and html view
*/
function execCodeAction(button, editor) {
if(button.classList.contains('active')) { // show visuell view
visuellView.innerHTML = htmlView.value;
htmlView.style.display = 'none';
visuellView.style.display = 'block';
button.classList.remove('active');
} else { // show html view
htmlView.innerText = visuellView.innerHTML;
visuellView.style.display = 'none';
htmlView.style.display = 'block';
button.classList.add('active');
}
}
/**
* This function adds a link to the current selection
*/
function execLinkAction() {
modal.style.display = 'block';
let selection = saveSelection();
let submit = modal.querySelectorAll('button.done')[0];
let close = modal.querySelectorAll('.close')[0];
// done button active => add link
submit.addEventListener('click', function(e) {
e.preventDefault();
let newTabCheckbox = modal.querySelectorAll('#new-tab')[0];
let linkInput = modal.querySelectorAll('#linkValue')[0];
let linkValue = linkInput.value;
let newTab = newTabCheckbox.checked;
restoreSelection(selection);
if(window.getSelection().toString()) {
let a = document.createElement('a');
a.href = linkValue;
if(newTab) a.target = '_blank';
window.getSelection().getRangeAt(0).surroundContents(a);
}
modal.style.display = 'none';
linkInput.value = '';
// deregister modal events
submit.removeEventListener('click', arguments.callee);
close.removeEventListener('click', arguments.callee);
});
// close modal on X click
close.addEventListener('click', function(e) {
e.preventDefault();
let linkInput = modal.querySelectorAll('#linkValue')[0];
modal.style.display = 'none';
linkInput.value = '';
// deregister modal events
submit.removeEventListener('click', arguments.callee);
close.removeEventListener('click', arguments.callee);
});
}
/**
* This function executes all 'normal' actions
*/
function execDefaultAction(action) {
document.execCommand(action, false);
}
/**
* Saves the current selection
*/
function saveSelection() {
if(window.getSelection) {
sel = window.getSelection();
if(sel.getRangeAt && sel.rangeCount) {
let ranges = [];
for(var i = 0, len = sel.rangeCount; i < len; ++i) {
ranges.push(sel.getRangeAt(i));
}
return ranges;
}
} else if (document.selection && document.selection.createRange) {
return document.selection.createRange();
}
return null;
}
/**
* Loads a saved selection
*/
function restoreSelection(savedSel) {
if(savedSel) {
if(window.getSelection) {
sel = window.getSelection();
sel.removeAllRanges();
for(var i = 0, len = savedSel.length; i < len; ++i) {
sel.addRange(savedSel[i]);
}
} else if(document.selection && savedSel.select) {
savedSel.select();
}
}
}
/**
* Sets the current selected format buttons active/inactive
*/
function selectionChange(e) {
for(let i = 0; i < buttons.length; i++) {
let button = buttons[i];
// don't remove active class on code toggle button
if(button.dataset.action === 'toggle-view') continue;
button.classList.remove('active');
}
if(!childOf(window.getSelection().anchorNode.parentNode, editor)) return false;
parentTagActive(window.getSelection().anchorNode.parentNode);
}
/**
* Checks if the passed child has the passed parent
*/
function childOf(child, parent) {
return parent.contains(child);
}
/**
* Sets the tag active that is responsible for the current element
*/
function parentTagActive(elem) {
if(!elem ||!elem.classList || elem.classList.contains('visuell-view')) return false;
let toolbarButton;
// active by tag names
let tagName = elem.tagName.toLowerCase();
toolbarButton = document.querySelectorAll(`.toolbar .editor-btn[data-tag-name="${tagName}"]`)[0];
if(toolbarButton) {
toolbarButton.classList.add('active');
}
// active by text-align
let textAlign = elem.style.textAlign;
toolbarButton = document.querySelectorAll(`.toolbar .editor-btn[data-style="textAlign:${textAlign}"]`)[0];
if(toolbarButton) {
toolbarButton.classList.add('active');
}
return parentTagActive(elem.parentNode);
}
/**
* Handles the paste event and removes all HTML tags
*/
function pasteEvent(e) {
e.preventDefault();
let text = (e.originalEvent || e).clipboardData.getData('text/plain');
document.execCommand('insertHTML', false, text);
}
/**
* This functions adds a paragraph tag when the enter key is pressed
*/
function addParagraphTag(evt) {
if (evt.keyCode == '13') {
// don't add a p tag on list item
if(window.getSelection().anchorNode.parentNode.tagName === 'LI') return;
document.execCommand('formatBlock', false, 'p');
}
}

View File

@ -38,6 +38,9 @@ class Group extends DatabaseModel {
[ 'name', 'varchar', '32' ], [ 'name', 'varchar', '32' ],
[ 'permissions', 'text', '' ], [ 'permissions', 'text', '' ],
]; ];
public $searchFields = [
'name',
];
public $permissionMatrix = [ public $permissionMatrix = [
'adminAccess' => [ 'adminAccess' => [
'pretty' => 'Access Administrator Areas', 'pretty' => 'Access Administrator Areas',

View File

@ -46,6 +46,9 @@ class Log extends DatabaseModel {
[ 'source', 'varchar', '64' ], [ 'source', 'varchar', '64' ],
[ 'action', 'text', '' ], [ 'action', 'text', '' ],
]; ];
public $searchFields = [
'source',
];
/** /**
* The model constructor. * The model constructor.

View File

@ -24,6 +24,9 @@ class Routes extends DatabaseModel {
[ 'original_url', 'varchar', '32' ], [ 'original_url', 'varchar', '32' ],
[ 'forwarded_url', 'text', '' ], [ 'forwarded_url', 'text', '' ],
]; ];
public $searchFields = [
'nickname',
];
public $resourceMatrix = [ public $resourceMatrix = [
[ [
'original_url' => 'fb', 'original_url' => 'fb',

View File

@ -36,6 +36,9 @@ class Sessions extends DatabaseModel {
[ 'username', 'varchar', '20' ], [ 'username', 'varchar', '20' ],
[ 'token', 'varchar', '120' ], [ 'token', 'varchar', '120' ],
]; ];
public $searchFields = [
'username',
];
public static $activeSession = false; public static $activeSession = false;
/** /**

View File

@ -31,6 +31,10 @@ class Token extends DatabaseModel {
[ 'createdBy', 'int', '10' ], [ 'createdBy', 'int', '10' ],
[ 'expiresAt', 'int', '10' ], [ 'expiresAt', 'int', '10' ],
]; ];
public $searchFields = [
'name',
'token',
];
public $permissionMatrix = [ public $permissionMatrix = [
'addAppToken' => [ 'addAppToken' => [
'pretty' => 'Add Application Tokens', 'pretty' => 'Add Application Tokens',

View File

@ -44,6 +44,9 @@ class User extends DatabaseModel {
[ 'confirmationCode', 'varchar', '80' ], [ 'confirmationCode', 'varchar', '80' ],
[ 'prefs', 'text', '' ], [ 'prefs', 'text', '' ],
]; ];
public $searchFields = [
'username',
];
public $permissionMatrix = [ public $permissionMatrix = [
'uploadImages' => [ 'uploadImages' => [
'pretty' => 'Upload images (such as avatars)', 'pretty' => 'Upload images (such as avatars)',
@ -428,7 +431,7 @@ class User extends DatabaseModel {
if ( ! empty( $filter ) ) { if ( ! empty( $filter ) ) {
switch ( $filter ) { switch ( $filter ) {
case 'newsletter': case 'newsletter':
$data = self::$db->search( $this->tableName, 'prefs', 'newsletter":"true' ); $data = self::$db->searchColumn( $this->tableName, 'prefs', 'newsletter":"true' );
break; break;
default: default:
$data = self::$db->get( $this->tableName, '*' ); $data = self::$db->get( $this->tableName, '*' );
@ -546,6 +549,7 @@ class User extends DatabaseModel {
$instance->prefs = json_decode( $instance->prefs, true ); $instance->prefs = json_decode( $instance->prefs, true );
$instance->gender = $instance->prefs['gender']; $instance->gender = $instance->prefs['gender'];
$instance->avatar = $instance->prefs['avatar']; $instance->avatar = $instance->prefs['avatar'];
$instance->usernamePretty = \ucfirst( $instance->username );
$out[] = $instance; $out[] = $instance;
if ( !empty( $end ) ) { if ( !empty( $end ) ) {
$out = $out[0]; $out = $out[0];
@ -659,7 +663,7 @@ class User extends DatabaseModel {
} }
if ( !self::$db->update( $this->tableName, $id, $fields ) ) { if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
new CustomException( 'userUpdate' ); new CustomException( 'userUpdate' );
Debug::error( "User: $id not updated: $fields" ); Debug::error( "User: $id not updated: " . var_export( $fields, true ) );
return false; return false;
} }
return true; return true;

View File

@ -29,8 +29,6 @@ class Blog extends AdminController {
parent::__construct(); parent::__construct();
self::$posts = new Posts; self::$posts = new Posts;
self::$title = 'Admin - Blog'; self::$title = 'Admin - Blog';
$view = Navigation::activePageSelect( 'nav.admin', '/admin/blog' );
Components::set( 'ADMINNAV', $view );
} }
public function index( $data = null ) { public function index( $data = null ) {

View File

@ -171,4 +171,16 @@ class Blog extends Controller {
self::$pageDescription = '{SITENAME} blog posts easily and conveniently sorted by years.'; self::$pageDescription = '{SITENAME} blog posts easily and conveniently sorted by years.';
Views::view( 'blog.list', self::$posts->byYear( $year ) ); Views::view( 'blog.list', self::$posts->byYear( $year ) );
} }
public function search() {
$results = [];
if ( Input::exists( 'submit' ) ) {
$dbResults = self::$posts->search( Input::post('searchTerm') );
if ( ! empty( $dbResults ) ) {
$results = $dbResults;
}
}
Components::set( 'searchResults', Views::simpleView( 'blog.list', $results ) );
Views::view( 'blog.searchResults' );
}
} }

View File

@ -24,6 +24,11 @@ use TheTempusProject\Models\Comments;
class Posts extends DatabaseModel { class Posts extends DatabaseModel {
public $tableName = 'posts'; public $tableName = 'posts';
public $searchFields = [
'title',
'slug',
'content',
];
public static $comments = false; public static $comments = false;
public $databaseMatrix = [ public $databaseMatrix = [

View File

@ -37,6 +37,7 @@ class Blog extends Plugin {
'posts' => [ 'posts' => [
[ [
'title' => 'Welcome', 'title' => 'Welcome',
'slug' => 'welcome',
'content' => '<p>This is just a simple message to say thank you for installing The Tempus Project. If you have any questions you can find everything through our website <a href="https://TheTempusProject.com">here</a>.</p>', 'content' => '<p>This is just a simple message to say thank you for installing The Tempus Project. If you have any questions you can find everything through our website <a href="https://TheTempusProject.com">here</a>.</p>',
'author' => 1, 'author' => 1,
'created' => '{time}', 'created' => '{time}',

View File

@ -26,9 +26,10 @@ class BlogLoader extends DefaultLoader {
*/ */
public function __construct() { public function __construct() {
$posts = new Posts; $posts = new Posts;
Components::set('SIDEBAR', Views::simpleView('blog.sidebar', $posts->recent(5))); Components::set('SIDEBAR', Views::simpleView('blog.widgets.recent', $posts->recent(5)));
Components::set('SIDEBAR2', Views::simpleView('blog.sidebar2', $posts->archive())); Components::set('SIDEBAR2', Views::simpleView('blog.widgets.archive', $posts->archive()));
Components::set('SIDEBARABOUT', Views::simpleView('blog.about')); Components::set('SIDEBARABOUT', Views::simpleView('blog.widgets.about'));
Components::set('SIDEBARSEARCH', Views::simpleView('blog.widgets.search'));
Components::set('BLOGFEATURES', ''); Components::set('BLOGFEATURES', '');
Navigation::setCrumbComponent( 'BLOG_BREADCRUMBS', Input::get( 'url' ) ); Navigation::setCrumbComponent( 'BLOG_BREADCRUMBS', Input::get( 'url' ) );
Components::set( 'BLOG_TEMPLATE_URL', Template::parse( '{ROOT_URL}app/plugins/comments/' ) ); Components::set( 'BLOG_TEMPLATE_URL', Template::parse( '{ROOT_URL}app/plugins/comments/' ) );

View File

@ -41,24 +41,42 @@
<!-- Navigation --> <!-- Navigation -->
<header class="p-3 text-bg-dark"> <header class="p-3 text-bg-dark">
<div class="container"> <div class="container">
<div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start"> <div class="d-flex align-items-center position-relative">
<img src="{ROOT_URL}{LOGO}" class="bi me-2" width="40" height="32" role="img" aria-label="{SITENAME} Logo"> <!-- Navbar Toggler (Left) -->
<a href="/" class="d-flex align-items-center mb-2 mb-lg-0 text-white text-decoration-none">
{SITENAME} <!-- Centered Logo (Now inside normal document flow) -->
<a href="/" class="d-flex align-items-center text-white text-decoration-none d-md-none mx-auto">
<img src="{ROOT_URL}{LOGO}" width="40" height="32" alt="{SITENAME} Logo" class="bi">
</a> </a>
<!-- Logo (Normal Position for Large Screens) -->
<a href="/" class="d-flex align-items-center text-white text-decoration-none d-none d-md-flex">
<img src="{ROOT_URL}{LOGO}" width="40" height="32" alt="{SITENAME} Logo" class="bi">
</a>
<div class="navbar-expand-md flex-grow-1">
<div class="collapse navbar-collapse d-md-flex" id="mainMenu">
<!-- Centered Navigation -->
<div class="d-none d-md-block d-flex justify-content-center w-100 position-absolute start-50 translate-middle-x">
{topNavLeft} {topNavLeft}
<div class="text-end d-flex align-items-center"> </div>
<div class="d-flex justify-content-center flex-grow-1 d-md-none">
{topNavLeft}
</div>
<!-- Right-Side Content (Push to End) -->
<div class="d-flex flex-row justify-content-center align-items-center mt-3 mt-md-0 ms-md-auto">
{topNavRight} {topNavRight}
</div> </div>
</div> <!-- End Collapse -->
</div> <!-- End Navbar Expand -->
<button class="me-3 d-md-none btn btn-md btn-outline-light" type="button" data-bs-toggle="collapse" data-bs-target="#mainMenu" aria-controls="mainMenu" aria-expanded="false" aria-label="Toggle navigation">
<i class="fa fa-bars"></i>
</button>
</div> </div>
</div> </div>
</header> </header>
<div class="d-flex flex-column min-vh-100"> <div class="d-flex flex-column min-vh-100">
<div class="flex-container flex-grow-1"> <div class="flex-container flex-grow-1">
{ISSUES} {ISSUES}
@ -79,24 +97,27 @@
<div class="pt-4"> <div class="pt-4">
<div class="container"> <div class="container">
<h3 class="pb-4 mb-4 fst-italic border-bottom"> <h3 class="pb-4 mb-4 fst-italic border-bottom context-main-border">
{SITENAME} Blog {SITENAME} Blog
</h3> </h3>
<div class="row g-5"> <div class="d-md-flex g-5">
<!-- Main Content --> <!-- Main Content -->
<div class="col-md-8"> <div class="col-12 col-md-8">
{CONTENT} {CONTENT}
</div> </div>
<!-- Sidebar Content --> <!-- Sidebar Content -->
<div class="col-md-4"> <div class="col-12 col-md-4">
<div class="position-sticky" style="top: 2rem;"> <div class="position-sticky" style="top: 2rem;">
<div class="p-4"> <div class="ps-md-2 ps-lg-5">
{SIDEBARABOUT} {SIDEBARABOUT}
</div> </div>
<div class="p-4"> <div class="ps-md-2 ps-lg-5">
{SIDEBARSEARCH}
</div>
<div class="ps-md-2 ps-lg-5">
{SIDEBAR} {SIDEBAR}
</div> </div>
<div class="p-4"> <div class="ps-md-2 ps-lg-5">
{SIDEBAR2} {SIDEBAR2}
</div> </div>
</div> </div>

View File

@ -1,6 +0,0 @@
<div class="p-4 mb-3 rounded context-main-bg">
<h4 class="fst-italic">About</h4>
<p class="mb-0">
The blog is mostly here to serve ass a simple way to link to long-form content on the site. There won't be any breaking news or tell-all stories here. Just good ole fashioned boring crap no one wants to read.
</p>
</div>

View File

@ -2,7 +2,7 @@
<legend class="text-center">Add Blog Post</legend> <legend class="text-center">Add Blog Post</legend>
<hr> <hr>
{ADMIN_BREADCRUMBS} {ADMIN_BREADCRUMBS}
<form action="" method="post"> <form method="post">
<fieldset> <fieldset>
<!-- Title --> <!-- Title -->
<div class="mb-3 row"> <div class="mb-3 row">

View File

@ -2,7 +2,7 @@
<legend class="text-center">Edit Blog Post</legend> <legend class="text-center">Edit Blog Post</legend>
<hr> <hr>
{ADMIN_BREADCRUMBS} {ADMIN_BREADCRUMBS}
<form action="" method="post"> <form method="post">
<fieldset> <fieldset>
<!-- Title --> <!-- Title -->
<div class="mb-3 row"> <div class="mb-3 row">

View File

@ -7,7 +7,7 @@
</div><!-- /.blog-post --> </div><!-- /.blog-post -->
</div><!-- /.blog-main --> </div><!-- /.blog-main -->
</div><!-- /.row --> </div><!-- /.row -->
<form action="" method="post" class="form-horizontal" enctype="multipart/form-data"> <form method="post" enctype="multipart/form-data">
<legend>New Blog Post</legend> <legend>New Blog Post</legend>
<div class="form-group"> <div class="form-group">
<label for="title" class="col-lg-3 control-label">Title</label> <label for="title" class="col-lg-3 control-label">Title</label>

View File

@ -1,5 +1,5 @@
{LOOP} {LOOP}
<article class="blog-post"> <article class="blog-post context-main-bg p-2">
<h2 class="blog-post-title mb-1">{title}</h2> <h2 class="blog-post-title mb-1">{title}</h2>
<p class="blog-post-meta">{DTC date}{created}{/DTC} by <a href="{ROOT_URL}home/profile/{authorName}" class="text-decoration-none">{authorName}</a></p> <p class="blog-post-meta">{DTC date}{created}{/DTC} by <a href="{ROOT_URL}home/profile/{authorName}" class="text-decoration-none">{authorName}</a></p>
<div class="well"> <div class="well">
@ -9,7 +9,7 @@
<hr> <hr>
{/LOOP} {/LOOP}
{ALT} {ALT}
<article class="blog-post"> <div class="text-center">
<p class="blog-post-meta">No Posts Found.</p> <p class="h5">No Posts Found</p>
</article> </div>
{/ALT} {/ALT}

View File

@ -1,6 +1,6 @@
<div class="row"> <div class="row">
<div class="col-lg-12 col-sm-12 blog-main"> <div class="col-lg-12 col-sm-12 blog-main context-main-bg p-1 p-md-2 mb-2 rounded">
<div class="blog-post"> <div class="blog-post mb-5 pb-5">
<h2 class="blog-post-title">{title}</h2> <h2 class="blog-post-title">{title}</h2>
<hr> <hr>
<p class="blog-post-meta">{DTC date}{created}{/DTC} by <a href="{ROOT_URL}home/profile/{authorName}" class="text-decoration-none">{authorName}</a></p> <p class="blog-post-meta">{DTC date}{created}{/DTC} by <a href="{ROOT_URL}home/profile/{authorName}" class="text-decoration-none">{authorName}</a></p>

View File

@ -1,15 +0,0 @@
<div class="card">
<div class="card-header bg-info">
<h3 class="card-title">Recent Posts</h3>
</div>
<ul class="list-group">
{LOOP}
<li class="list-group-item">
<a href="{ROOT_URL}blog/post/{ID}">{title}</a>
</li>
{/LOOP}
{ALT}
<li class="list-group-item">No Posts to show</li>
{/ALT}
</ul>
</div>

View File

@ -0,0 +1,3 @@
<legend class="text-center my-2">Search Results</legend>
<hr>
{searchResults}

View File

@ -1,18 +0,0 @@
<div class="card context-main-bg">
<div class="card-header">
<h3 class="card-title">Recent Posts</h3>
</div>
<div class="card-body">
<ol class="list-unstyled">
{LOOP}
<li><a href="{ROOT_URL}blog/post/{ID}" class="text-decoration-none">{title}</a></li>
{/LOOP}
{ALT}
<li>No Posts to show</li>
{/ALT}
</ol>
</div>
<div class="card-footer">
<a href="{ROOT_URL}blog" class="text-decoration-none">View All</a>
</div>
</div>

View File

@ -1,15 +0,0 @@
<div class="card context-main-bg">
<div class="card-header">
<h3 class="card-title">Archives</h3>
</div>
<div class="card-body">
<ol class="list-unstyled">
{LOOP}
<li>({count}) <a href="{ROOT_URL}blog/month/{month}/{year}" class="text-decoration-none">{monthText} {year}</a></li>
{/LOOP}
{ALT}
<li>None To Show</li>
{/ALT}
</ol>
</div>
</div>

View File

@ -0,0 +1,11 @@
<div class="pb-2 pb-lg-3">
<div class="card rounded context-main-bg">
<div class="card-body">
<h4 class="fst-italic">About</h4>
<p class="mb-0">
The blog is mostly here to serve ass a simple way to link to long-form content on the site.
There won't be any breaking news or tell-all stories here. Just good ole fashioned boring crap no one wants to read.
</p>
</div>
</div>
</div>

View File

@ -0,0 +1,17 @@
<div class="pb-2 pb-lg-3">
<div class="card rounded context-main-bg">
<div class="card-header">
<h3 class="card-title">Archives</h3>
</div>
<div class="card-body context-second-bg">
<ol class="list-unstyled">
{LOOP}
<li>({count}) <a href="{ROOT_URL}blog/month/{month}/{year}" class="text-decoration-none">{monthText} {year}</a></li>
{/LOOP}
{ALT}
<li>None To Show</li>
{/ALT}
</ol>
</div>
</div>
</div>

View File

@ -0,0 +1,20 @@
<div class="pb-2 pb-lg-3">
<div class="card rounded context-main-bg">
<div class="card-header">
<h3 class="card-title">Recent Posts</h3>
</div>
<div class="card-body context-second-bg">
<ol class="list-unstyled">
{LOOP}
<li><a href="{ROOT_URL}blog/post/{ID}" class="text-decoration-none">{title}</a></li>
{/LOOP}
{ALT}
<li>No Posts to show</li>
{/ALT}
</ol>
</div>
<div class="card-footer">
<a href="{ROOT_URL}blog" class="text-decoration-none">View All</a>
</div>
</div>
</div>

View File

@ -0,0 +1,18 @@
<div class="pb-2 pb-lg-3">
<div class="card rounded context-main-bg">
<div class="card-body">
<form method="post" action="/blog/search">
<fieldset>
<!-- Hidden Token -->
<input type="hidden" name="token" value="{TOKEN}">
<!-- Search -->
<div class="input-group">
<input type="text" class="form-control" aria-label="Search Terms" name="searchTerm" id="searchTerm">
<button type="submit" class="btn btn-secondary bg-primary" name="submit" value="submit">Search</button>
</div>
</fieldset>
</form>
</div>
</div>
</div>

View File

@ -51,7 +51,7 @@ class Bugreport extends Plugin {
]; ];
public $contact_footer_links = [ public $contact_footer_links = [
[ [
'text' => 'Bug Report', 'text' => 'Report a Bug',
'url' => '{ROOT_URL}bugreport', 'url' => '{ROOT_URL}bugreport',
'filter' => 'loggedin', 'filter' => 'loggedin',
], ],

View File

@ -1,15 +1,20 @@
<div class="col-8 mx-auto p-4 rounded shadow-sm mb-5 context-main-bg mt-4 container"> <div class="m-2 m-lg-4">
<h2 class="text-center mb-4">Bug Report</h2> <div class="col-12 mx-5 col-sm-10 col-lg-8 mx-auto p-4 rounded shadow-sm context-main-bg">
<h2 class="text-center mb-4">Report a Bug</h2>
<hr> <hr>
<p>Thank you for visiting our bug reporting page. We value our users' input highly and in an effort to better serve your needs, please fill out the form below to help us address this issue.</p> <p class="text-center text-sm-start">
<p>We read each and every bug report submitted, and by submitting this form you allow us to send you a follow-up email.</p> Thank you for visiting our bug reporting page. We value our users' input highly and in an effort to better serve your needs, please fill out the form below to help us address this issue.
<form action="" method="post"> </p>
<p class="text-center text-sm-start">
We read each and every bug report submitted, and by submitting this form you allow us to send you a follow-up email.
</p>
<form method="post">
<!-- Page URL --> <!-- Page URL -->
<div class="mb-3"> <div class="mb-3">
<label for="url" class="form-label">Page you were trying to reach:</label> <label for="url" class="form-label">Page you were trying to reach:</label>
<input type="url" name="url" id="url" class="form-control" aria-describedby="urlHelp" required> <input type="url" name="url" id="url" class="form-control" aria-describedby="urlHelp" required>
<small id="urlHelp" class="form-text text-muted"> <small id="urlHelp" class="form-text text-muted">
What is the URL of the page you actually received the error on? (The URL is the website address. Example: {ROOT_URL}home) This is the URL of the page you actually received the error.
</small> </small>
</div> </div>
@ -18,7 +23,7 @@
<label for="ourl" class="form-label">Page you were on:</label> <label for="ourl" class="form-label">Page you were on:</label>
<input type="url" name="ourl" id="ourl" class="form-control" aria-describedby="ourlHelp"> <input type="url" name="ourl" id="ourl" class="form-control" aria-describedby="ourlHelp">
<small id="ourlHelp" class="form-text text-muted"> <small id="ourlHelp" class="form-text text-muted">
What is the URL of the page you were on before you received the error? (The URL is the website address. Example: {ROOT_URL}home/newhome) This is the URL of the page you were on before you received the error.
</small> </small>
</div> </div>
@ -37,8 +42,11 @@
<!-- Description --> <!-- Description -->
<div class="mb-3"> <div class="mb-3">
<label for="entry" class="form-label">Describe the problem/error as best as you can: (max: 2000 characters)</label> <label for="entry" class="form-label">Describe the error you received: </label>
<textarea class="form-control" name="entry" id="entry" rows="6" maxlength="2000" required></textarea> <textarea class="form-control" name="entry" id="entry" rows="6" maxlength="2000" aria-describedby="descHelp" required></textarea>
<small id="descHelp" class="form-text text-muted">
(max: 2000 characters)
</small>
</div> </div>
<!-- Hidden Token --> <!-- Hidden Token -->
@ -50,3 +58,4 @@
</div> </div>
</form> </form>
</div> </div>
</div>

View File

@ -3,7 +3,7 @@
<legend class="text-center">Edit Comment</legend> <legend class="text-center">Edit Comment</legend>
<hr> <hr>
{ADMIN_BREADCRUMBS} {ADMIN_BREADCRUMBS}
<form action="" method="post" class="container py-4"> <form method="post" class="container py-4">
<fieldset> <fieldset>
<div class="mb-3 row"> <div class="mb-3 row">
<label for="comment" class="col-lg-5 col-form-label text-end">Comment:</label> <label for="comment" class="col-lg-5 col-form-label text-end">Comment:</label>

View File

@ -1,4 +1,4 @@
<form action="" method="post" class="text-center mx-auto mt-4" style="max-width: 600px;"> <form method="post" class="text-center mx-auto mt-4" style="max-width: 600px;">
<div class="mb-3"> <div class="mb-3">
<textarea <textarea
class="form-control" class="form-control"

View File

@ -1,14 +1,14 @@
<div class="card"> <div class="card">
<div class="card-header d-flex align-items-center justify-content-between context-second-bg context-main"> <div class="card-header d-flex align-items-center justify-content-between context-main-bg context-main">
<h3 class="card-title mb-0"> <h3 class="card-title mb-0">
<i class="fa fa-fw fa-comment"></i> Comments <i class="fa fa-fw fa-comment"></i> Comments
</h3> </h3>
<span class="badge bg-primary">{count}</span> <span class="badge bg-primary">{count}</span>
</div> </div>
<div class="card-body context-main-bg context-main"> <div class="card-body context-second-bg">
<ul class="list-group list-group-flush"> <ul class="list-group list-group-flush">
{LOOP} {LOOP}
<li class="list-group-item context-second-bg context-main mb-2"> <li class="list-group-item context-main-bg context-main mb-2">
<div class="d-flex align-items-start"> <div class="d-flex align-items-start">
<div class="me-3"> <div class="me-3">
<img src="{ROOT_URL}{avatar}" class="rounded-circle" alt="User Avatar" style="width: 50px; height: 50px;"> <img src="{ROOT_URL}{avatar}" class="rounded-circle" alt="User Avatar" style="width: 50px; height: 50px;">
@ -28,7 +28,7 @@
</li> </li>
{/LOOP} {/LOOP}
{ALT} {ALT}
<li class="list-group-item context-second-bg context-main mb-2"> <li class="list-group-item context-main-bg mb-2">
<div class="text-center"> <div class="text-center">
<p class="mb-0">Be the first to comment.</p> <p class="mb-0">Be the first to comment.</p>
</div> </div>

View File

@ -27,8 +27,6 @@ class Contact extends AdminController {
parent::__construct(); parent::__construct();
self::$title = 'Admin - Contact'; self::$title = 'Admin - Contact';
self::$contact = new ContactModel; self::$contact = new ContactModel;
$view = Navigation::activePageSelect( 'nav.admin', '/admin/contact' );
Components::set( 'ADMINNAV', $view );
} }
public function view( $id = null ) { public function view( $id = null ) {

View File

@ -1,17 +1,18 @@
<div class="context-main-bg container py-4 my-4"> <div class="m-2 m-lg-4">
<div class="context-main-bg container py-2 my-2 py-lg-4 my-lg-4">
<h2 class="text-center mb-4">Contact Us</h2> <h2 class="text-center mb-4">Contact Us</h2>
<div class="col-lg-6 offset-md-3"> <div class="col-12 col-lg-6 offset-lg-3">
<p> <p class="text-center text-lg-start">
Here at <strong>{SITENAME}</strong>, we highly value your feedback. We constantly strive to provide our users with the highest level of quality in everything we do. Here at <strong>{SITENAME}</strong>, we highly value your feedback. We constantly strive to provide our users with the highest level of quality in everything we do.
</p> </p>
<p> <p class="text-center text-lg-start">
If you would like to provide any suggestions or comments on our service, we ask that you please fill out the quick form below and let us know what's on your mind. If you would like to provide any suggestions or comments on our service, we ask that you please fill out the quick form below and let us know what's on your mind.
</p> </p>
</div> </div>
<form action="" method="post"> <form method="post">
<!-- Name --> <!-- Name -->
<div class="mb-3 row"> <div class="mb-3 row">
<label for="name" class="col-lg-3 col-form-label text-end">Name:</label> <label for="name" class="col-lg-3 col-form-label text-lg-end">Name:</label>
<div class="col-lg-6"> <div class="col-lg-6">
<input type="text" class="form-control" name="name" id="name" required> <input type="text" class="form-control" name="name" id="name" required>
</div> </div>
@ -19,7 +20,7 @@
<!-- Email (Optional) --> <!-- Email (Optional) -->
<div class="mb-3 row"> <div class="mb-3 row">
<label for="contactEmail" class="col-lg-3 col-form-label text-end">E-mail: (optional)</label> <label for="contactEmail" class="col-lg-3 col-form-label text-lg-end">E-mail: (optional)</label>
<div class="col-lg-6"> <div class="col-lg-6">
<input type="email" class="form-control" name="contactEmail" id="contactEmail"> <input type="email" class="form-control" name="contactEmail" id="contactEmail">
</div> </div>
@ -27,7 +28,7 @@
<!-- Feedback --> <!-- Feedback -->
<div class="mb-3 row"> <div class="mb-3 row">
<label for="entry" class="col-lg-3 col-form-label text-end">Feedback:</label> <label for="entry" class="col-lg-3 col-form-label text-lg-end">Feedback:</label>
<div class="col-lg-6"> <div class="col-lg-6">
<textarea class="form-control" name="entry" id="entry" rows="6" maxlength="2000" required></textarea> <textarea class="form-control" name="entry" id="entry" rows="6" maxlength="2000" required></textarea>
<small class="form-text text-muted">Max: 2000 characters</small> <small class="form-text text-muted">Max: 2000 characters</small>
@ -43,3 +44,4 @@
</div> </div>
</form> </form>
</div> </div>
</div>

View File

@ -259,7 +259,9 @@ class Message extends DatabaseModel {
} }
$messageOut['fromAvatar'] = self::$user->getAvatar( $message->userFrom ); $messageOut['fromAvatar'] = self::$user->getAvatar( $message->userFrom );
$messageOut['userTo'] = self::$user->getUsername( $message->userTo ); $messageOut['userTo'] = self::$user->getUsername( $message->userTo );
$messageOut['userToPretty'] = \ucfirst( $messageOut['userTo'] );
$messageOut['userFrom'] = self::$user->getUsername( $message->userFrom ); $messageOut['userFrom'] = self::$user->getUsername( $message->userFrom );
$messageOut['userFromPretty'] = \ucfirst( $messageOut['userFrom'] );
$out[] = (object) $messageOut; $out[] = (object) $messageOut;
if ( !empty( $end ) ) { if ( !empty( $end ) ) {
$out = $out[0]; $out = $out[0];

View File

@ -1,8 +1,21 @@
<div class="container py-4"> <div class="m-2 m-lg-4">
<div class="col-12 mx-5 col-sm-10 col-lg-8 mx-auto p-4 rounded shadow-sm context-main-bg">
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a href="{ROOT_URL}messages" class="text-decoration-none">
Messages
</a>
</li>
<li class="breadcrumb-item active" aria-current="page">
Create
</li>
</ol>
</nav>
<div class="row justify-content-center"> <div class="row justify-content-center">
<div class="col-md-4"> <div class="col-md-6 col-lg-6">
<form action="" method="post" class="needs-validation"> <form method="post" class="needs-validation">
<legend class="mb-4">New Message</legend> <legend class="mb-3">New Message</legend>
<fieldset> <fieldset>
<!-- To User Field --> <!-- To User Field -->
<div class="mb-3 row"> <div class="mb-3 row">
@ -44,6 +57,7 @@
</div> </div>
</fieldset> </fieldset>
<input type="hidden" name="token" value="{TOKEN}"> <input type="hidden" name="token" value="{TOKEN}">
<div class="text-center text-md-start">
<button <button
type="submit" type="submit"
name="submit" name="submit"
@ -51,7 +65,9 @@
class="btn btn-primary btn-lg"> class="btn btn-primary btn-lg">
Send Send
</button> </button>
</div>
</form> </form>
</div> </div>
</div> </div>
</div> </div>
</div>

View File

@ -1,14 +1,14 @@
<h2>Inbox</h2> <h2>Inbox</h2>
<form action="{ROOT_URL}messages/delete" method="post"> <form action="{ROOT_URL}messages/delete" method="post">
<table class="table table-striped"> <table class="table table-striped text-center">
<thead> <thead>
<tr> <tr>
<th style="width: 20%">From</th> <th style="width: 15%">From</th>
<th style="width: 25%">Subject</th> <th style="width: 40%">Subject</th>
<th style="width: 15%">Last Reply</th> <th style="width: 20%">Last Reply</th>
<th style="width: 20%"></th>
<th style="width: 10%"></th> <th style="width: 10%"></th>
<th style="width: 10%"> <th style="width: 10%"></th>
<th style="width: 5%">
<INPUT type="checkbox" onchange="checkAll(this)" name="check.t" value="T_[]"/> <INPUT type="checkbox" onchange="checkAll(this)" name="check.t" value="T_[]"/>
</th> </th>
</tr> </tr>
@ -16,11 +16,11 @@
<tbody> <tbody>
{LOOP} {LOOP}
<tr {unreadBadge}> <tr {unreadBadge}>
<td><a href="{ROOT_URL}home/profile/{userFrom}">{userFrom}</a></td> <td><a href="{ROOT_URL}home/profile/{userFrom}" class="text-decoration-none">{userFromPretty}</a></td>
<td><a href="{ROOT_URL}messages/view/{ID}">{subject}</a></td> <td><a href="{ROOT_URL}messages/view/{ID}" class="text-decoration-none">{subject}</a></td>
<td>{DTC}{lastReply}{/DTC}</td> <td>{DTC date}{lastReply}{/DTC}</td>
<td><a href="{ROOT_URL}messages/read/{ID}">Mark as read</a></td> <td><a href="{ROOT_URL}messages/read/{ID}" class="btn btn-sm btn-info"><i class="fa-solid fa-envelope-open"></i></a></td>
<td><a href="{ROOT_URL}messages/delete/{ID}">Delete</a></td> <td><a href="{ROOT_URL}messages/delete/{ID}" class="btn btn-sm btn-danger"><i class="fa fa-fw fa-trash"></i></a></td>
<td> <td>
<input type="checkbox" value="{ID}" name="T_[]"> <input type="checkbox" value="{ID}" name="T_[]">
</td> </td>
@ -35,5 +35,6 @@
{/ALT} {/ALT}
</tbody> </tbody>
</table> </table>
<button name="submit" value="submit" type="submit" class="btn btn-sm btn-danger">Delete</button> <a href="{ROOT_URL}messages/create" class="btn btn-sm btn-primary">New message</a> <button name="submit" value="submit" type="submit" class="btn btn-sm btn-danger"><i class="fa fa-fw fa-trash"></i></button>
<a href="{ROOT_URL}messages/create" class="btn btn-sm btn-primary">New message</a>
</form> </form>

View File

@ -1,4 +1,5 @@
<div class="context-main context-main-bg col-10 offset-1 my-3 p-3"> <div class="m-2 m-lg-4">
<div class="col-12 col-sm-10 col-lg-8 mx-auto p-md-2 p-lg-4 rounded shadow-sm context-main-bg context-main">
<div class="my-3 p-3"> <div class="my-3 p-3">
{message_inbox} {message_inbox}
</div> </div>
@ -6,3 +7,4 @@
{message_outbox} {message_outbox}
</div> </div>
</div> </div>
</div>

View File

@ -1,43 +0,0 @@
<div class="container">
<div class="row">
<div class="col-sm-12 col-md-6 col-lg-6 col-sm-offset-0 col-md-offset-3 col-lg-offset-3 top-pad" >
<div class="card panel-primary">
{LOOP}
{SINGLE}
<div class="card-header">
<h3 class="card-title">{subject}</h3>
</div>
{/SINGLE}
<div class="card-body">
<div class="row">
<div class="col-md-3 col-lg-3 " align="center">
<a href="{ROOT_URL}home/profile/{userFrom}">{userFrom}</a><br>
<img alt="User Pic" src="{ROOT_URL}{fromAvatar}" class="img-circle img-responsive">
</div>
<div class=" col-md-9 col-lg-9 ">
<table class="table table-user-information">
<tbody>
<td>{message}</td>
</tbody>
</table>
</div>
</div>
</div>
<div class="card-footer">
{ADMIN}
{ID}
<span class="float-right">
{DTC}{sent}{/DTC}
</span>
{/ADMIN}
</div>
{/LOOP}
</div>
<form action="{ROOT_URL}messages/reply" method="post">
<input type="hidden" name="token" value="{TOKEN}">
<input type="hidden" name="messageID" value="{PID}">
<button name="submit" value="reply" type="submit" class="btn btn-sm btn-primary">Reply</button>
</form>
</div>
</div>
</div>

View File

@ -1,29 +1,45 @@
<div class="context-main context-main-bg col-8 offset-2 my-3 p-3"> <div class="m-2 m-lg-4">
<div class="col-sm-12 col-md-6 col-lg-6 col-sm-offset-0 col-md-offset-3 col-lg-offset-3 top-pad" > <div class="col-12 mx-5 col-sm-10 col-lg-8 mx-auto p-4 rounded shadow-sm context-main-bg context-main">
<div class="card panel-primary"> <nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a href="{ROOT_URL}messages" class="text-decoration-none">
Messages
</a>
</li>
<li class="breadcrumb-item active" aria-current="page">
View
</li>
</ol>
</nav>
<div class="card panel-primary col-lg-8 mx-auto text-center">
{LOOP} {LOOP}
{SINGLE} {SINGLE}
<div class="card-header context-main-bg"> <div class="card-header context-second-bg">
<h5 class="card-title context-main">{subject}</h5> <p class="card-title context-main text-center h3">{subject}</p>
</div> </div>
{/SINGLE} {/SINGLE}
<div class="card-body context-second-bg"> <div class="card-body context-other-bg">
<div class="row"> <div class="row">
<div class="col-md-3 col-lg-3 text-center"> <div class="col-4 col-lg-3 text-center">
<a href="{ROOT_URL}home/profile/{userFrom}">{userFrom}</a><br> <a href="{ROOT_URL}home/profile/{userFrom}" class="text-decoration-none">{userFromPretty}</a><br>
<img alt="User Pic" src="{ROOT_URL}{fromAvatar}" class="img-circle img-fluid"> <img alt="User Pic" src="{ROOT_URL}{fromAvatar}" class="img-circle img-fluid mt-2">
</div> </div>
<div class=" col-md-9 col-lg-9 context-main"> <div class="col-8 col-lg-9 text-start">
{message} {message}
</div> </div>
</div> </div>
</div> </div>
<div class="card-footer context-main-bg"> <div class="card-footer context-second-bg">
{ADMIN} {ADMIN}
<div class="d-flex justify-content-between">
<div class="">
{ID} {ID}
<span class="float-right"> </div>
<div class="">
{DTC}{sent}{/DTC} {DTC}{sent}{/DTC}
</span> </div>
</div>
{/ADMIN} {/ADMIN}
</div> </div>
{/LOOP} {/LOOP}

View File

@ -1,4 +1,4 @@
<div class="dropdown nav-item mx-2"> <div class="dropdown nav-item mx-2 my-2 my-lg-0">
<a <a
href="#" href="#"
class="d-flex align-items-center text-white text-decoration-none dropdown-toggle" class="d-flex align-items-center text-white text-decoration-none dropdown-toggle"

View File

@ -1,6 +1,6 @@
<h2>Outbox</h2> <h2>Outbox</h2>
<form action="{ROOT_URL}messages/delete" method="post"> <form action="{ROOT_URL}messages/delete" method="post">
<table class="table table-striped"> <table class="table table-striped text-center">
<thead> <thead>
<tr> <tr>
<th style="width: 20%">To</th> <th style="width: 20%">To</th>
@ -15,10 +15,10 @@
<tbody> <tbody>
{LOOP} {LOOP}
<tr> <tr>
<td><a href="{ROOT_URL}home/profile/{userTo}">{userTo}</a></td> <td><a href="{ROOT_URL}home/profile/{userTo}" class="text-decoration-none">{userToPretty}</a></td>
<td><a href="{ROOT_URL}messages/view/{ID}">{subject}</a></td> <td><a href="{ROOT_URL}messages/view/{ID}" class="text-decoration-none">{subject}</a></td>
<td>{DTC date}{sent}{/DTC}</td> <td>{DTC date}{sent}{/DTC}</td>
<td><a href="{ROOT_URL}messages/delete/{ID}">Delete</a></td> <td><a href="{ROOT_URL}messages/delete/{ID}" class="btn btn-sm btn-danger"><i class="fa fa-fw fa-trash"></i></a></td>
<td> <td>
<input type="checkbox" value="{ID}" name="F_[]"> <input type="checkbox" value="{ID}" name="F_[]">
</td> </td>
@ -33,5 +33,5 @@
{/ALT} {/ALT}
</tbody> </tbody>
</table> </table>
<button name="submit" value="submit" type="submit" class="btn btn-sm btn-danger">Delete</button> <button name="submit" value="submit" type="submit" class="btn btn-sm btn-danger"><i class="fa fa-fw fa-trash"></i></button>
</form> </form>

View File

@ -1,5 +1,5 @@
<div class="context-main context-main-bg col-8 offset-2 my-3 p-3"> <div class="context-main context-main-bg col-8 offset-2 my-3 p-3">
<form action="" method="post" class="form-horizontal"> <form method="post">
<legend class="text-center">Reply</legend> <legend class="text-center">Reply</legend>
<fieldset> <fieldset>
<div class="form-group"> <div class="form-group">

View File

@ -2,8 +2,7 @@
<legend class="text-center">Send Notification</legend> <legend class="text-center">Send Notification</legend>
<hr> <hr>
{ADMIN_BREADCRUMBS} {ADMIN_BREADCRUMBS}
<form method="post" enctype="multipart/form-data">
<form action="" method="post" enctype="multipart/form-data">
<fieldset> <fieldset>
<!-- Group --> <!-- Group -->
<div class="mb-3 row"> <div class="mb-3 row">

View File

@ -1,4 +1,6 @@
<div class="col-8 mx-auto p-4 rounded shadow-sm context-main-bg my-4">
<div class="m-2 m-lg-4">
<div class="col-12 mx-5 col-sm-10 col-lg-8 mx-auto p-4 rounded shadow-sm context-main-bg">
<div class="row justify-content-center"> <div class="row justify-content-center">
<div class="col-md-8"> <div class="col-md-8">
<legend class="text-center">Notifications</legend> <legend class="text-center">Notifications</legend>
@ -26,7 +28,7 @@
{/LOOP} {/LOOP}
{ALT} {ALT}
<tr> <tr>
<td colspan="7" class=" context-main"> <td colspan="3" class="text-center context-main">
No Notifications No Notifications
</td> </td>
</tr> </tr>
@ -36,3 +38,4 @@
</div> </div>
</div> </div>
</div> </div>
</div>

View File

@ -1,5 +1,5 @@
<!-- Notifications Dropdown --> <!-- Notifications Dropdown -->
<div class="dropdown nav-item mx-2"> <div class="dropdown nav-item mx-2 my-2 my-lg-0">
<a <a
href="#" href="#"
class="d-flex align-items-center text-white text-decoration-none dropdown-toggle" class="d-flex align-items-center text-white text-decoration-none dropdown-toggle"

View File

@ -2,7 +2,7 @@
<legend class="text-center">Add Subscriber</legend> <legend class="text-center">Add Subscriber</legend>
<hr> <hr>
{ADMIN_BREADCRUMBS} {ADMIN_BREADCRUMBS}
<form action="" method="post"> <form method="post">
<fieldset> <fieldset>
<!-- Subject --> <!-- Subject -->
<div class="mb-3 row"> <div class="mb-3 row">

View File

@ -1,7 +1,7 @@
<div class="col-md-5 offset-md-1 mb-3 text-center"> <div class="col-12 col-sm-6 col-md-3 offset-0 offset-lg-2 mb-3 text-center">
<h5 class="">Subscribe</h5> <h5 class="">Subscribe</h5>
<div class="d-flex flex-column flex-sm-row gap-2 justify-content-center mx-auto"> <div class="d-flex flex-column w-75 w-sm-100 gap-2 justify-content-center mx-auto">
<form action="{ROOT_URL}subscribe/home" method="post" class="form-horizontal"> <form action="{ROOT_URL}subscribe/home" method="post">
<label for="email" class="visually-hidden">Email address</label> <label for="email" class="visually-hidden">Email address</label>
<input name="email" id="email" type="email" class="form-control my-2" placeholder="Email address" autocomplete="email"> <input name="email" id="email" type="email" class="form-control my-2" placeholder="Email address" autocomplete="email">
<input type="hidden" name="token" value="{TOKEN}"> <input type="hidden" name="token" value="{TOKEN}">

View File

@ -1,4 +1,4 @@
<form action="{ROOT_URL}subscribe/home" method="post" class="form-horizontal"> <form action="{ROOT_URL}subscribe/home" method="post">
<input type="email" placeholder="Email" id="email" name="email" autocomplete="email"> <input type="email" placeholder="Email" id="email" name="email" autocomplete="email">
<input type="hidden" name="token" value="{TOKEN}"> <input type="hidden" name="token" value="{TOKEN}">
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block">Submit</button><br> <button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block">Submit</button><br>

View File

@ -1,4 +1,4 @@
<form action="{ROOT_URL}home/unsubscribe" method="post" class="form-horizontal"> <form action="{ROOT_URL}home/unsubscribe" method="post">
<input type="email" placeholder="Email" id="email" name="email"> <input type="email" placeholder="Email" id="email" name="email">
<input type="hidden" name="token" value="{TOKEN}"> <input type="hidden" name="token" value="{TOKEN}">
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block">Submit</button><br> <button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block">Submit</button><br>

View File

@ -44,6 +44,11 @@ class AdminLoader extends DefaultLoader {
$menu = Views::simpleView( 'nav.admin', $links ); $menu = Views::simpleView( 'nav.admin', $links );
$activeMenu = Navigation::activePageSelect( $menu, Input::get( 'url' ), false, true ); $activeMenu = Navigation::activePageSelect( $menu, Input::get( 'url' ), false, true );
Components::set( 'ADMIN_LINKS', $activeMenu ); Components::set( 'ADMIN_LINKS', $activeMenu );
$menu = Views::simpleView( 'nav.adminTop', Navigation::getMenuLinks( App::MAIN_MENU_NAME ) );
$activeMenu = Navigation::activePageSelect( $menu, Input::get( 'url' ), false, true );
Components::set( 'topNavLeft', $activeMenu );
Navigation::setCrumbComponent( 'ADMIN_BREADCRUMBS', Input::get( 'url' ) ); Navigation::setCrumbComponent( 'ADMIN_BREADCRUMBS', Input::get( 'url' ) );
} }
} }

View File

@ -45,7 +45,7 @@
<!-- Center Element --> <!-- Center Element -->
<div class="flex-grow-1 d-flex flex-column"> <div class="flex-grow-1 d-flex flex-column">
<!-- Top Navigation Bar --> <!-- Top Navigation Bar -->
<div class="p-3 text-bg-dark"> <div class="p-2 text-bg-dark">
<div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start"> <div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start">
{topNavLeft} {topNavLeft}
</div> </div>

View File

@ -73,9 +73,11 @@ class DefaultLoader extends Loader {
$this->addCss( '<link rel="stylesheet" href="{ROOT_URL}app/css/main-dark.css" id="dark-mode-stylesheet" disabled>' ); $this->addCss( '<link rel="stylesheet" href="{ROOT_URL}app/css/main-dark.css" id="dark-mode-stylesheet" disabled>' );
} }
Components::set( 'topNavRight', Template::parse( App::$topNavRight . '{STATUS}' ) ); Components::set( 'topNavRight', Template::parse( App::$topNavRight . '{STATUS}' ) );
$menu = Views::simpleView( 'nav.main', Navigation::getMenuLinks( App::MAIN_MENU_NAME ) ); $menu = Views::simpleView( 'nav.main', Navigation::getMenuLinks( App::MAIN_MENU_NAME ) );
$activeMenu = Navigation::activePageSelect( $menu, Input::get( 'url' ), false, true ); $activeMenu = Navigation::activePageSelect( $menu, Input::get( 'url' ), false, true );
Components::set( 'topNavLeft', $activeMenu ); Components::set( 'topNavLeft', $activeMenu );
Components::set( 'colorSelect', Views::simpleView( 'forms.colorSelect' ) ); Components::set( 'colorSelect', Views::simpleView( 'forms.colorSelect' ) );
Components::set( 'iconSelect', Views::simpleView( 'forms.iconSelect' ) ); Components::set( 'iconSelect', Views::simpleView( 'forms.iconSelect' ) );
Navigation::setCrumbComponent( 'BREADCRUMB', Input::get( 'url' ) ); Navigation::setCrumbComponent( 'BREADCRUMB', Input::get( 'url' ) );

View File

@ -41,18 +41,43 @@
<!-- Navigation --> <!-- Navigation -->
<header class="p-3 text-bg-dark"> <header class="p-3 text-bg-dark">
<div class="container"> <div class="container">
<div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start"> <div class="d-flex align-items-center position-relative">
<img src="{ROOT_URL}{LOGO}" class="bi me-2" width="40" height="32" alt="{SITENAME} Logo" aria-label="{SITENAME} Logo"> <!-- Navbar Toggler (Left) -->
<a href="/" class="d-flex align-items-center mb-2 mb-lg-0 text-white text-decoration-none">
{SITENAME} <!-- Centered Logo (Now inside normal document flow) -->
<a href="/" class="align-items-center text-white text-decoration-none d-flex d-md-none">
<img src="{ROOT_URL}{LOGO}" width="40" height="32" alt="{SITENAME} Logo" class="bi">
</a> </a>
<!-- Logo (Normal Position for Large Screens) -->
<a href="/" class="align-items-center text-white text-decoration-none d-none d-md-flex">
<img src="{ROOT_URL}{LOGO}" width="40" height="32" alt="{SITENAME} Logo" class="bi">
</a>
<div class="navbar-expand-md flex-grow-1">
<div class="collapse navbar-collapse d-md-flex" id="mainMenu">
<!-- Centered Navigation -->
<div class="d-none d-md-block d-flex justify-content-center position-absolute start-50 translate-middle-x">
{topNavLeft} {topNavLeft}
<div class="text-end d-flex align-items-center"> </div>
<div class="d-flex justify-content-center flex-grow-1 d-md-none">
{topNavLeft}
</div>
<!-- Right-Side Content (Push to End) -->
<div class="d-flex flex-row justify-content-center align-items-center mt-3 mt-md-0 ms-md-auto">
{topNavRight} {topNavRight}
</div> </div>
</div> <!-- End Collapse -->
</div> <!-- End Navbar Expand -->
<button class="me-3 d-md-none btn btn-md btn-outline-light" type="button" data-bs-toggle="collapse" data-bs-target="#mainMenu" aria-controls="mainMenu" aria-expanded="false" aria-label="Toggle navigation">
<i class="fa fa-bars"></i>
</button>
</div> </div>
</div> </div>
</header> </header>
<div class="d-flex flex-column min-vh-100"> <div class="d-flex flex-column min-vh-100">
<div class="flex-container flex-grow-1"> <div class="flex-container flex-grow-1">
<!-- Issues --> <!-- Issues -->

View File

@ -1,16 +1,27 @@
<div class="col-8 mx-auto p-4 rounded shadow-sm context-main-bg my-4"> <div class="m-2 m-lg-4">
<div class="col-12 mx-5 col-sm-10 col-lg-8 mx-auto p-4 rounded shadow-sm context-main-bg">
<h2 class="text-center mb-4">About {SITENAME}</h2> <h2 class="text-center mb-4">About {SITENAME}</h2>
<p class="lead"> <p class="lead text-center text-lg-start">
{SITENAME} was built out of a need to create and manage my own web applications. {SITENAME} was built out of a need to create and manage web applications.
At the time, I had used wordpress but I didn't want or even need any of the blog functionality.
No matter what plugins you add, no matter how you customize layout, wordpress is still a blog at its core.
There is nothing inherently wrong with a blog, but when you start from a blog, everything is a post, or a plugin.
Under the hood, wordpress is going to run how wordpress wants, as a web interface for accessing text records.
</p> </p>
<p class="text-muted"> <p class="text-center text-lg-start">
The Tempus Project was always intended to be a web application, not a blog.
</p>
<p class="text-muted text-center text-lg-start">
Right now, this entire system was built and managed by myself. As stated, I have used my own version of this for years, but translating it to a publicly available product is not a 1-to-1 job. There may be bugs or issues encountered while you use the product. I can't guarantee a fix for every need in every case immediately, but I do actively keep track of bugs and work hard to ensure everyone has a great experience using the app. Right now, this entire system was built and managed by myself. As stated, I have used my own version of this for years, but translating it to a publicly available product is not a 1-to-1 job. There may be bugs or issues encountered while you use the product. I can't guarantee a fix for every need in every case immediately, but I do actively keep track of bugs and work hard to ensure everyone has a great experience using the app.
</p> </p>
<p> <p class="text-center text-lg-start">
If you encounter any bugs, feel free to report them <a href="/bugreport" class="text-decoration-none">here</a>. Likewise, there are forms for feedback, reviews, suggestions, and a general contact form. Thanks for taking the time to check out the product! If you encounter any bugs, feel free to report them <a href="/bugreport" class="text-decoration-none">here</a>. Likewise, there are forms for feedback, reviews, suggestions, and a general contact form. Thanks for taking the time to check out the product!
</p> </p>
<div class="text-center mt-4 pb-4"> <div class="text-center mt-4 pb-4">
{loggedin}<a href="/bugreport" class="btn btn-primary btn-lg px-5">Report a Bug</a>{/loggedin} {loggedin}
<a href="/contact" class="btn btn-outline-secondary btn-lg px-5 ms-3">Contact Us</a> <a href="/bugreport" class="btn btn-primary px-3 btn-lg m-2">Report a Bug</a>
{/loggedin}
<a href="/contact" class="btn btn-outline-primary px-3 m-2 btn-lg">Contact Us</a>
</div>
</div> </div>
</div> </div>

View File

@ -7,7 +7,7 @@
Please be very careful with this feature. This form allows you to send an email (formatted within the default site email template) to registered emails from various sources including newsletter subscribers, call to action subscribers, and all registered user accounts. Please be very careful with this feature. This form allows you to send an email (formatted within the default site email template) to registered emails from various sources including newsletter subscribers, call to action subscribers, and all registered user accounts.
</p> </p>
</div> </div>
<form action="" method="post"> <form method="post">
<fieldset> <fieldset>
<!-- Subject --> <!-- Subject -->
<div class="mb-3 row"> <div class="mb-3 row">

View File

@ -2,7 +2,7 @@
<legend class="text-center">Settings</legend> <legend class="text-center">Settings</legend>
<hr> <hr>
{ADMIN_BREADCRUMBS} {ADMIN_BREADCRUMBS}
<form action="" method="post" class="form-horizontal" enctype="multipart/form-data"> <form method="post" enctype="multipart/form-data">
<fieldset> <fieldset>
{configForm} {configForm}

View File

@ -3,7 +3,7 @@
<legend class="text-center">Create Token</legend> <legend class="text-center">Create Token</legend>
<hr> <hr>
{ADMIN_BREADCRUMBS} {ADMIN_BREADCRUMBS}
<form action="" method="post" class="container py-4"> <form method="post" class="container py-4">
<fieldset> <fieldset>
<div class="mb-3 row"> <div class="mb-3 row">
<label for="name" class="col-lg-5 col-form-label text-end">Name</label> <label for="name" class="col-lg-5 col-form-label text-end">Name</label>

View File

@ -3,7 +3,7 @@
<legend class="text-center">Edit Token</legend> <legend class="text-center">Edit Token</legend>
<hr> <hr>
{ADMIN_BREADCRUMBS} {ADMIN_BREADCRUMBS}
<form action="" method="post" class="container py-4"> <form method="post" class="container py-4">
<fieldset> <fieldset>
<div class="mb-3 row"> <div class="mb-3 row">
<label for="name" class="col-lg-5 col-form-label text-end">Name</label> <label for="name" class="col-lg-5 col-form-label text-end">Name</label>

View File

@ -34,7 +34,7 @@
<div class="mb-3 row"> <div class="mb-3 row">
<label for="password" class="col-lg-6 col-form-label text-end">Password:</label> <label for="password" class="col-lg-6 col-form-label text-end">Password:</label>
<div class="col-lg-2"> <div class="col-lg-2">
<input type="password" class="form-control" name="password" id="password" value="" required> <input type="password" class="form-control" name="password" id="password" value="">
</div> </div>
</div> </div>
@ -42,7 +42,7 @@
<div class="mb-3 row"> <div class="mb-3 row">
<label for="password2" class="col-lg-6 col-form-label text-end">Re-Enter Password:</label> <label for="password2" class="col-lg-6 col-form-label text-end">Re-Enter Password:</label>
<div class="col-lg-2"> <div class="col-lg-2">
<input type="password" class="form-control" name="password2" id="password2" value="" required> <input type="password" class="form-control" name="password2" id="password2" value="">
</div> </div>
</div> </div>

View File

@ -20,7 +20,7 @@
{LOOP} {LOOP}
<tr> <tr>
<td align="center">{ID}</td> <td align="center">{ID}</td>
<td><a href='{ROOT_URL}admin/users/view/{ID}' class="text-decoration-none">{username}</a></td> <td><a href='{ROOT_URL}admin/users/view/{ID}' class="text-decoration-none">{usernamePretty}</a></td>
<td>{DTC date}{registered}{/DTC}</td> <td>{DTC date}{registered}{/DTC}</td>
<td><a href="{ROOT_URL}admin/users/edit/{ID}" class="btn btn-sm btn-warning"><i class="fa fa-fw fa-pencil"></i></a></td> <td><a href="{ROOT_URL}admin/users/edit/{ID}" class="btn btn-sm btn-warning"><i class="fa fa-fw fa-pencil"></i></a></td>
<td><a href="{ROOT_URL}admin/users/delete/{ID}" class="btn btn-sm btn-danger"><i class="fa fa-fw fa-trash"></i></a></td> <td><a href="{ROOT_URL}admin/users/delete/{ID}" class="btn btn-sm btn-danger"><i class="fa fa-fw fa-trash"></i></a></td>

View File

@ -5,7 +5,7 @@
<div class="card shadow"> <div class="card shadow">
<!-- Card Header --> <!-- Card Header -->
<div class="card-header text-center bg-dark text-white"> <div class="card-header text-center bg-dark text-white">
<h3 class="card-title mb-0">{username}</h3> <h3 class="card-title mb-0">{usernamePretty}</h3>
</div> </div>
<!-- Card Body --> <!-- Card Body -->
@ -27,7 +27,7 @@
</tr> </tr>
<tr> <tr>
<th scope="row">Group:</th> <th scope="row">Group:</th>
<td><a href="{ROOT_URL}admin/groups/view/{userGroup}">{groupName}</a></td> <td><a href="{ROOT_URL}admin/groups/view/{userGroup}" class="text-decoration-none">{groupName}</a></td>
</tr> </tr>
{/ADMIN} {/ADMIN}
<tr> <tr>
@ -45,7 +45,7 @@
{ADMIN} {ADMIN}
<tr> <tr>
<th scope="row">Email:</th> <th scope="row">Email:</th>
<td><a href="mailto:{email}">{email}</a></td> <td><a href="mailto:{email}" class="text-decoration-none">{email}</a></td>
</tr> </tr>
<tr> <tr>
<th scope="row">User ID:</th> <th scope="row">User ID:</th>

View File

@ -1,30 +0,0 @@
<div class="container">
<div class="row">
<div class="col-lg-9 col-md-9 col-sm-12 col-centered">
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12">
<h2>Welcome to The Tempus-Project Friends and Family Alpha.</h2>
<hr>
<p>This project is now entering its third official version and nearly its tenth year of development. What a long journey it has been to get here.</p>
<p>With that being said, I won't waste your time with a journey down memory road. If you have been sent this page, clearly I trust you, or one of our mutual friends is an asshole. Both equally possible... The main purpose of inviting you was to ask for your help.</p>
<h2>What I need</h2>
<p>With any application, there are bugs. The best developers I have had the pleasure of working with make mundane every day mistakes just like everyone else. This obviously includes myself. With any project you spend years working on, you will develop blind spots, or places where even if something was broken, you would skip right past it and never notice.</p>
<p>I would like your help in identifying these such blind spots.</p>
<h2>What you can do to help.</h2>
<p>Currently there is a bug-report form at the bottom, usable by anyone with a registered account. I have also built an administrator system that allows me to track progress of these bugs and ensure they get fixed. In addition to tracking bugs, there is a public suggestions system and a publicly viewable to-do list.</p>
<p>I will need some users to help test very specific things like permissions for various groups. I will need some trusted users to act as administrators and test features. I will also just need some people to use and interact with the site to ensure they aren't encountering any bugs.</p>
<p>There are a ton of things you can do to help!</p>
<ul>
<li>Report any bugs!!! ( there is a bug-report link at the bottom of every page )</li>
<li>Register an account</li>
<li>Subscribe to the mailing list</li>
<li>Browse blog posts</li>
<li>Make suggestions for improvements or new features</li>
<li>Leave comments on the blog and other features.</li>
<li>Keep an eye out for email or messages requesting specific help.</li>
</ul>
</div>
</div>
</div>
</div>
</div>

View File

@ -3,7 +3,7 @@
<h1 class="mb-4">Email Confirmation</h1> <h1 class="mb-4">Email Confirmation</h1>
<hr> <hr>
<p>Please enter the confirmation code you received in your email.</p> <p>Please enter the confirmation code you received in your email.</p>
<form action="" method="post" class=""> <form method="post">
<fieldset> <fieldset>
<div data-mdb-input-init class="form-outline mb-4 col-2 offset-5"> <div data-mdb-input-init class="form-outline mb-4 col-2 offset-5">
<input class="form-control" type="text" name="confirmationCode" id="confirmationCode" placeholder="Confirmation Code"> <input class="form-control" type="text" name="confirmationCode" id="confirmationCode" placeholder="Confirmation Code">

View File

@ -2,7 +2,7 @@
<h1 class="mb-4">Re-Send Confirmation</h1> <h1 class="mb-4">Re-Send Confirmation</h1>
<hr> <hr>
<p>Please click the resend button to resend your email confirmation. Don't forget to check the spam folder!</p> <p>Please click the resend button to resend your email confirmation. Don't forget to check the spam folder!</p>
<form action="" method="post" class=""> <form method="post">
<input type="hidden" name="resendConfirmation" value="true"> <input type="hidden" name="resendConfirmation" value="true">
<input type="hidden" name="token" value="{TOKEN}"> <input type="hidden" name="token" value="{TOKEN}">
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block">Resend Confirmation</button><br> <button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block">Resend Confirmation</button><br>

View File

@ -1,5 +1,5 @@
<div class="col-8 mx-auto p-4 rounded shadow-sm mb-5 context-main-bg mt-4 text-center"> <div class="col-8 mx-auto p-4 rounded shadow-sm mb-5 context-main-bg mt-4 text-center">
<form action="" method="post"> <form method="post">
<legend class=" my-2">Lost and Found</legend> <legend class=" my-2">Lost and Found</legend>
<p class="col-8 offset-2">You can begin the process of recovering your account here. Provide your username, or email address and instructions for ressetting your password will be mailed to you shortly.</p> <p class="col-8 offset-2">You can begin the process of recovering your account here. Provide your username, or email address and instructions for ressetting your password will be mailed to you shortly.</p>
<fieldset> <fieldset>

View File

@ -2,7 +2,7 @@
<h1 class="mb-4">Change Password</h1> <h1 class="mb-4">Change Password</h1>
<hr> <hr>
<p>Please enter the confirmation code you received in your email.</p> <p>Please enter the confirmation code you received in your email.</p>
<form action="" method="post" class=""> <form method="post">
<fieldset> <fieldset>
<div data-mdb-input-init class="form-outline mb-4 col-2 offset-5"> <div data-mdb-input-init class="form-outline mb-4 col-2 offset-5">
<input class="form-control" type="password" name="password" id="password" placeholder="New Password"> <input class="form-control" type="password" name="password" id="password" placeholder="New Password">

View File

@ -2,7 +2,7 @@
<h1 class="mb-4">Change Password</h1> <h1 class="mb-4">Change Password</h1>
<hr> <hr>
<p>Please enter the code you received in your email. If you did not receive the code, please check your spam filter or <a href="{ROOT_URL}">click here</a> to request a new reset code.</p> <p>Please enter the code you received in your email. If you did not receive the code, please check your spam filter or <a href="{ROOT_URL}">click here</a> to request a new reset code.</p>
<form action="" method="post" class=""> <form method="post">
<fieldset> <fieldset>
<div data-mdb-input-init class="form-outline mb-4 col-2 offset-5"> <div data-mdb-input-init class="form-outline mb-4 col-2 offset-5">
<input class="form-control" type="text" name="resetCode" id="resetCode" placeholder="Password Reset Code"> <input class="form-control" type="text" name="resetCode" id="resetCode" placeholder="Password Reset Code">

View File

@ -0,0 +1,76 @@
<div class="container py-4 context-main-bg my-2 my-lg-4 mx-2 mx-sm-auto">
<h2 class="text-center mb-4">Create an Account</h2>
<form method="post">
<fieldset>
<!-- Username -->
<div class="mb-3 row">
<label for="username" class="col-lg-6 col-form-label text-lg-end">Username:</label>
<div class="col-lg-2">
<input type="text" class="form-control" name="username" id="username" required>
</div>
</div>
<!-- Email -->
<div class="mb-3 row">
<label for="email" class="col-lg-6 col-form-label text-lg-end">Email:</label>
<div class="col-lg-2">
<input type="email" class="form-control" name="email" id="email" required>
</div>
</div>
<!-- Re-enter Email -->
<div class="mb-3 row">
<label for="email2" class="col-lg-6 col-form-label text-lg-end">Re-Enter Email:</label>
<div class="col-lg-2">
<input type="email" class="form-control" name="email2" id="email2" required>
</div>
</div>
<!-- Password -->
<div class="mb-3 row">
<label for="password" class="col-lg-6 col-form-label text-lg-end">Password:</label>
<div class="col-lg-2">
<input type="password" class="form-control" name="password" id="password" required>
</div>
</div>
<!-- Re-enter Password -->
<div class="mb-3 row">
<label for="password2" class="col-lg-6 col-form-label text-lg-end">Re-Enter Password:</label>
<div class="col-lg-2">
<input type="password" class="form-control" name="password2" id="password2" required>
</div>
</div>
<!-- Terms of Service -->
<div class="mb-3 text-center">
<div class="">
<input type="checkbox" class="form-check-input" name="terms" id="terms" value="1" required>
<label for="terms" class="form-check-label">
I have read and agree to the <a href="/home/terms" class="text-primary text-decoration-none">Terms of Service</a>
</label>
</div>
<div class="terms mt-2 mx-auto">
{TERMS}
</div>
</div>
<!-- Hidden Token -->
<input type="hidden" name="token" value="{TOKEN}">
<!-- Submit Button -->
<div class="text-center">
<button type="submit" name="submit" value="submit" class="btn btn-primary btn-lg">Sign up</button>
</div>
</fieldset>
</form>
</div>

View File

View File

@ -1,5 +0,0 @@
<div class="copy">
<div class="col-lg-12 col-md-12 col-sm-12 text-center">
<p class="text-muted">Powered by <a href="https://thetempusproject.com">The Tempus Project</a>.</p>
</div>
</div>

View File

@ -1,16 +0,0 @@
<link rel="stylesheet" href="{ROOT_URL}app/css/debug.css" crossorigin="anonymous">
<div id="debug-wrapper">
<div id="debug-header">
<p><b>Debug Log:</b></p>
<button id="debug-copy" name="debug-copy">Copy</button>
</div>
<div id="debug-log">
{DEBUGGING_LOG}
</div>
</div>
<script language="JavaScript" type="text/javascript">
$("#debug-copy").on("click", function(){
copyAll("debug-log");
console.log('copied');
});
</script>

View File

@ -1,9 +0,0 @@
<link rel="stylesheet" href="{ROOT_URL}app/css/debug.css" crossorigin="anonymous">
<div id="wrapper">
<div id="menu">
<p class="welcome"><b>Debug Dump:</b></p>
</div>
<div>
<pre>{DUMP}</pre>
</div>
</div>

View File

@ -1,4 +1,4 @@
<div class="col-6 col-md-2 mb-3 text-center"> <div class="col-12 col-sm-6 col-md-3 col-lg-2 mb-3 text-center">
<h5>More Info</h5> <h5>More Info</h5>
<ul class="nav flex-column"> <ul class="nav flex-column">
{LOOP} {LOOP}

View File

@ -1,11 +1,23 @@
<div class="container border-top border-white mt-auto"> <div class="container mt-auto">
<footer class="pt-4"> <footer class="pt-4">
<!-- Footer Toggle Button (Visible on Small Screens) -->
<div class="text-center border-top context-main-border">
<button class="d-md-none my-3 btn btn-lg context-main context-main-border" type="button" data-bs-toggle="collapse" data-bs-target="#footerMenu" aria-controls="footerMenu" aria-expanded="false" aria-label="Toggle footer navigation">
<i class="fa fa-bars"></i>
</button>
</div>
<!-- Collapsible Footer Content -->
<div class="collapse d-md-block my-4" id="footerMenu">
<div class="row"> <div class="row">
{FOOTER_LEFT} {FOOTER_LEFT}
{FOOTER_CENTER} {FOOTER_CENTER}
{FOOTER_RIGHT} {FOOTER_RIGHT}
</div> </div>
<div class="d-flex flex-column flex-sm-row justify-content-between py-3 mt-2 border-top border-white"> </div>
<!-- Copy & Social (Always Visible) -->
<div class="d-flex flex-column flex-md-row justify-content-md-between py-3 border-top context-main-border">
{COPY} {COPY}
{SOCIAL} {SOCIAL}
</div> </div>

View File

@ -1 +1,3 @@
<span>© 2025 {SITENAME}, Powered by <a href="https://thetempusproject.com" class="text-decoration-none">The Tempus Project</a>.</span> <div class="d-flex justify-content-center justify-content-md-start text-center text-md-start">
<span>© 2025 {SITENAME}, Powered by <a href="https://thetempusproject.com" class="text-decoration-none">The Tempus Project</a></span>
</div>

View File

@ -1,4 +1,4 @@
<div class="col-6 col-md-2 mb-3 text-center"> <div class="col-12 col-sm-6 col-md-3 col-lg-2 mb-3 text-center">
<h5>Contact Us</h5> <h5>Contact Us</h5>
<ul class="nav flex-column"> <ul class="nav flex-column">
{LOOP} {LOOP}

View File

@ -1,4 +1,4 @@
<div class="col-6 col-md-2 mb-3 text-center"> <div class="col-12 col-sm-6 col-md-3 col-lg-2 mb-3 text-center">
<h5>Dark Mode</h5> <h5>Dark Mode</h5>
<div class="material-switch px-4 mt-2"> <div class="material-switch px-4 mt-2">
<input name="dark-mode-toggle" type="checkbox" id="dark-mode-toggle" class="form-check-input"> <input name="dark-mode-toggle" type="checkbox" id="dark-mode-toggle" class="form-check-input">

View File

@ -1,3 +1,4 @@
<div class="d-flex justify-content-center justify-content-md-end mt-3 mt-md-0">
<ul class="list-unstyled d-flex mb-0"> <ul class="list-unstyled d-flex mb-0">
<li class="ms-3"> <li class="ms-3">
<a class="context-main" href="{ROOT_URL}fb"> <a class="context-main" href="{ROOT_URL}fb">
@ -25,3 +26,4 @@
</a> </a>
</li> </li>
</ul> </ul>
</div>

Some files were not shown because too many files have changed in this diff Show More