This commit is contained in:
Joey Kimsey
2025-01-01 22:17:38 -05:00
parent ccc134d1b2
commit 1ef85c6c2c
65 changed files with 1200 additions and 215 deletions

View File

@ -18,6 +18,8 @@ use TheTempusProject\Hermes\Functions\Redirect;
use TheTempusProject\Bedrock\Functions\Session;
use TheTempusProject\Bedrock\Classes\Config;
use TheTempusProject\Models\Token;
use TheTempusProject\Canary\Bin\Canary as Debug;
use TheTempusProject\Houdini\Classes\Views;
class ApiController extends Controller {
protected static $canAccessApplicationApi = false;
@ -26,16 +28,15 @@ class ApiController extends Controller {
protected static $authToken;
public function __construct( $secure = true ) {
header('Content-Type: application/json; charset=utf-8');
parent::__construct();
$this->verifyApiRequest();
if ( $secure && ! $this->canUseApi() ) {
Session::flash( 'error', 'You do not have permission to view this page.' );
return Redirect::home();
}
Template::setTemplate( 'api' );
Template::noFollow();
Template::noIndex();
Template::addHeader( 'Content-Type: application/json; charset=utf-8' );
Template::setTemplate( 'api' );
$res = $this->verifyApiRequest();
if ( $secure && ! $this->canUseApi() ) {
exit( $res );
}
}
protected function canUseApi() {
@ -72,16 +73,16 @@ class ApiController extends Controller {
} else {
$secret = $this->getSecretToken();
if ( empty( $secret ) ) {
return;
return Views::simpleView( 'api.response', ['response' => json_encode( [ 'error' => 'invalid secret' ], true )]);
}
$token = $tokens->findBySecret( $secret );
}
if ( empty( $token ) ) {
return;
return Views::simpleView( 'api.response', ['response' => json_encode( [ 'error' => 'invalid token' ], true )]);
}
self::$authToken = $token;
if ( $token->expiresAt <= time() && empty( $secret ) ) {
return;
return Views::simpleView( 'api.response', ['response' => json_encode( [ 'error' => 'token expired' ], true )]);
}
if ( $token->expiresAt <= time() ) {
self::$canAccessAuthenticationApi = true;

View File

@ -114,6 +114,7 @@ class Forms extends Check {
self::addHandler( 'install', __CLASS__, 'install' );
self::addHandler( 'adminCreateToken', __CLASS__, 'adminCreateToken' );
self::addHandler( 'apiLogin', __CLASS__, 'apiLogin' );
self::addHandler( 'updatePreference', __CLASS__, 'updatePreference' );
self::addHandler( 'installStart', __CLASS__, 'install', [ 'start' ] );
self::addHandler( 'installAgreement', __CLASS__, 'install', [ 'agreement' ] );
self::addHandler( 'installCheck', __CLASS__, 'install', [ 'check' ] );
@ -650,4 +651,16 @@ class Forms extends Check {
}
return true;
}
public static function updatePreference() {
if ( !Input::exists( 'prefName' ) ) {
self::addUserError( 'You must specify a name' );
return false;
}
if ( !Input::exists( 'prefValue' ) ) {
self::addUserError( 'You must specify a value' );
return false;
}
return true;
}
}

View File

@ -201,6 +201,8 @@ class Preferences {
$tempPrefsArray = $this->normalizePreferenceArray( $name, $details );
if ( isset( $populated[ $name ] ) ) {
$tempPrefsArray['value'] = $populated[$name];
} else {
$tempPrefsArray['value'] = $tempPrefsArray['default'];
}
// $form .= Forms::getFormFieldHtml( $name, $tempPrefsArray['pretty'], $tempPrefsArray['type'], $tempPrefsArray['default'], $tempPrefsArray['options'] );
if ( $tempPrefsArray['type'] == 'checkbox' ) {

View File

@ -27,15 +27,14 @@ class Login extends ApiController {
parent::__construct( false );
self::$tokens = new Token;
self::$user = new User;
// Template::addHeader( 'Access-Control-Allow-Origin: *' );
// Template::addHeader( 'Content-Type: application/json; charset=utf-8' );
Template::addHeader( 'Access-Control-Allow-Origin: *' );
Template::addHeader( 'Content-Type: application/json; charset=utf-8' );
}
public function index() {
header('Access-Control-Allow-Origin: *');
if ( !Forms::check( 'apiLogin' ) ) {
if ( ! Forms::check( 'apiLogin' ) ) {
$responseType = 'error';
$response = 'malformed input1';
$response = 'malformed input';
return Views::view( 'api.response', ['response' => json_encode( [ $responseType => $response ], true )]);
}
$user = self::$user->authorize( Input::post( 'username' ), Input::post( 'password' ) );
@ -45,7 +44,7 @@ class Login extends ApiController {
return Views::view( 'api.response', ['response' => json_encode( [ $responseType => $response ], true )]);
}
$responseType = 'token';
$token = self::$tokens->findOrCreateUserToken( $user->ID );
$token = self::$tokens->findOrCreateUserToken( $user->ID, true );
return Views::view( 'api.response', ['response' => json_encode( [ $responseType => $token ], true )]);
}
}

View File

@ -36,12 +36,12 @@ class Usercp extends Controller {
Redirect::home();
}
Template::noIndex();
$menu = Views::simpleView( 'nav.usercp', App::$userCPlinks );
Navigation::activePageSelect( $menu, null, true, true );
}
public function email() {
self::$title = 'Email Settings';
$menu = Views::simpleView( 'nav.usercp', App::$userCPlinks );
Navigation::activePageSelect( $menu, null, true, true );
if ( App::$activeUser->confirmed != '1' ) {
return Issues::add( 'notice', 'You need to confirm your email address before you can make modifications. If you would like to resend that confirmation link, please <a href="/register/resend">click here</a>', true );
}
@ -68,11 +68,15 @@ class Usercp extends Controller {
public function index() {
self::$title = 'User Control Panel';
$menu = Views::simpleView( 'nav.usercp', App::$userCPlinks );
Navigation::activePageSelect( $menu, null, true, true );
Views::view( 'profile', App::$activeUser );
}
public function password() {
self::$title = 'Password Settings';
$menu = Views::simpleView( 'nav.usercp', App::$userCPlinks );
Navigation::activePageSelect( $menu, null, true, true );
if ( !Input::exists() ) {
return Views::view( 'user_cp.password_change' );
}
@ -94,6 +98,8 @@ class Usercp extends Controller {
public function settings() {
self::$title = 'Preferences';
$menu = Views::simpleView( 'nav.usercp', App::$userCPlinks );
Navigation::activePageSelect( $menu, null, true, true );
$prefs = new Preferences;
$fields = App::$activePrefs;
if ( Input::exists( 'submit' ) ) {
@ -109,4 +115,39 @@ class Usercp extends Controller {
Components::set( 'PREFERENCES_FORM', $prefs->getFormHtml( $fields ) );
Views::view( 'user_cp.settings', App::$activeUser );
}
public function updatePref() {
Template::setTemplate( 'api' );
if ( ! App::$isLoggedIn ) {
return Views::view( 'api.response', ['response' => json_encode( [ 'error' => 'Not Logged In' ], true )]);
}
if ( ! Forms::check( 'updatePreference' ) ) {
return Views::view( 'api.response', ['response' => json_encode( [ 'error' => Check::userErrors() ], true )]);
}
$name = Input::post( 'prefName' );
$value = Input::post('prefValue' );
if ( 'false' === $value ) {
$value = false;
} elseif ( 'true' === $value ) {
$value = true;
}
if ( empty( Preferences::get( $name ) ) ) {
return Views::view( 'api.response', ['response' => json_encode( [ 'error' => 'Unknown Preference' ], true )]);
}
$prefs = new Preferences;
$fields1 = $prefs->convertFormToArray( true, false );
$fields2 = [];
$fields3 = $fields1;
if ( isset( $fields1[ $name ] ) ) {
$fields2[ $name ] = $value;
$fields3[ $name ] = $value;
}
$result = self::$user->updatePrefs( $fields3, App::$activeUser->ID );
return Views::view( 'api.response', ['response' => json_encode( $result, true )]);
}
}

View File

@ -119,35 +119,46 @@ document.addEventListener('DOMContentLoaded', function () {
if ( enableButton ) {
enableButton.addEventListener('click', function () {
if (darkModeStylesheet.disabled) {
darkModeStylesheet.disabled = false;
localStorage.setItem('darkMode', 'enabled');
enableButton.innerText = 'Disable Now';
} else {
darkModeStylesheet.disabled = true;
localStorage.setItem('darkMode', 'disabled');
enableButton.innerText = 'Enable Now';
}
if (darkModeStylesheet.disabled) {
darkModeStylesheet.disabled = false;
localStorage.setItem('darkMode', 'enabled');
enableButton.innerText = 'Disable Now';
} else {
darkModeStylesheet.disabled = true;
localStorage.setItem('darkMode', 'disabled');
enableButton.innerText = 'Enable Now';
}
});
}
toggleButton.addEventListener('click', function () {
if (darkModeStylesheet.disabled) {
darkModeStylesheet.disabled = false;
localStorage.setItem('darkMode', 'enabled');
} else {
darkModeStylesheet.disabled = true;
localStorage.setItem('darkMode', 'disabled');
}
document.querySelectorAll('.table-striped').forEach((table) => {
if (localStorage.getItem('darkMode') === 'enabled') {
table.classList.add('table-dark');
table.classList.remove('table-light');
if (darkModeStylesheet.disabled) {
toggleDarkModePref( true );
darkModeStylesheet.disabled = false;
localStorage.setItem('darkMode', 'enabled');
} else {
table.classList.add('table-light');
table.classList.remove('table-dark');
toggleDarkModePref( false );
darkModeStylesheet.disabled = true;
localStorage.setItem('darkMode', 'disabled');
}
document.querySelectorAll('.table-striped').forEach((table) => {
if (localStorage.getItem('darkMode') === 'enabled') {
table.classList.add('table-dark');
table.classList.remove('table-light');
} else {
table.classList.add('table-light');
table.classList.remove('table-dark');
}
});
});
});
function toggleDarkModePref( value ) {
var fields = {};
fields.prefName = 'darkMode';
fields.prefValue = value;
$.post( '/usercp/updatePref', fields ).done(function(response) {
// alert('Timer updated successfully!');
});
}
});

View File

@ -94,10 +94,15 @@ class Token extends DatabaseModel {
return false;
}
public function findOrCreateUserToken( $user_id ) {
public function findOrCreateUserToken( $user_id, $refresh = false ) {
$test = $this->findUserToken( $user_id );
if ( ! empty( $test ) ) {
return $test->token;
if ( ! empty( $refresh ) ) {
$token = $this->refresh( $test->ID, 'user' );
} else {
$token = $test->token;
}
return $token;
}
$expiration = Config::getValue( 'api/UserAccessTokenExpiration' );

View File

@ -121,6 +121,11 @@ class User extends DatabaseModel {
'50',
],
],
'darkMode' => [
'pretty' => 'Enable Dark-Mode viewing',
'type' => 'checkbox',
'default' => 'false',
],
];
protected static $avatars;
protected static $preferences;

View File

@ -5,7 +5,7 @@
<div class="card-body">
<ol class="list-unstyled">
{LOOP}
<li><a href="{ROOT_URL}blog/post/{ID}">{title}</a></li>
<li><a href="{ROOT_URL}blog/post/{ID}" class="text-decoration-none atb-green">{title}</a></li>
{/LOOP}
{ALT}
<li>No Posts to show</li>
@ -13,6 +13,6 @@
</ol>
</div>
<div class="card-footer">
<a href="{ROOT_URL}blog">View All</a>
<a href="{ROOT_URL}blog" class="text-decoration-none atb-green">View All</a>
</div>
</div>

View File

@ -2,7 +2,7 @@
<h4 class="fst-italic">Archives</h4>
<ul class="list-unstyled mb-0">
{LOOP}
<li>({count}) <a href="{ROOT_URL}blog/month/{month}/{year}">{monthText} {year}</a></li>
<li>({count}) <a href="{ROOT_URL}blog/month/{month}/{year}" class="text-decoration-none atb-green">{monthText} {year}</a></li>
{/LOOP}
{ALT}
<li>None To Show</li>

View File

@ -22,13 +22,12 @@ class BookmarkFolders extends ApiController {
protected static $folders;
public function __construct() {
header('Access-Control-Allow-Origin: *');
parent::__construct();
self::$folders = new Folders;
}
public function create() {
header('Access-Control-Allow-Origin: *');
$user = self::$authToken->createdBy;
$payload = @file_get_contents('php://input');
@ -54,7 +53,6 @@ class BookmarkFolders extends ApiController {
}
public function list( $id = '' ) {
header('Access-Control-Allow-Origin: *');
$user = self::$authToken->createdBy;
$folders = self::$folders->bySpecificUser( $user );

View File

@ -1,9 +1,10 @@
<?php
/**
* app/controllers/extensions.php
* app/plugins/bookmarks/controllers/extensions.php
*
* This is the extensions controller.
*
* @package TP Bookmarks
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com
@ -15,10 +16,17 @@ use TheTempusProject\Classes\Controller;
use TheTempusProject\Houdini\Classes\Views;
use TheTempusProject\Houdini\Classes\Issues;
use TheTempusProject\TheTempusProject as App;
use TheTempusProject\Hermes\Functions\Route as Routes;
use TheTempusProject\Models\Token;
use TheTempusProject\Houdini\Classes\Components;
use TheTempusProject\Models\Folders;
use TheTempusProject\Houdini\Classes\Template;
use TheTempusProject\Bedrock\Functions\Input;
class Extensions extends Controller {
public function index() {
self::$title = 'Browser Extensions';
self::$pageDescription = 'Our extensions cover all major browsers with the notable exception of Safari. Chrome, Opera, Brave, Firefox, and Edge are all represented; giving users a simple way to add bookmarks and folders from any page.';
if ( App::$isLoggedIn ) {
Issues::add( 'success', 'We also have a simple solution to using the app from your mobile devices <a href="/extensions/mobile">here</a>.' );
}
@ -27,39 +35,114 @@ class Extensions extends Controller {
public function mobile() {
self::$title = 'Mobile Bookmarklet';
self::$pageDescription = 'When you find yourself on the go, sometimes an extension isn\'t an option. For those times, we have the mobile bookmarklet to allow you to add bookmarks from your mobile devices.';
if ( ! App::$isLoggedIn ) {
return Issues::add( 'error', 'Unfortunately you will need to sign in to generate the bookmarklet unique to your account.' );
Issues::add( 'notice', 'Since the bookmarklet is tied directly to your account, you will need to <a href="/home/login">log in</a> to generate the code for your account.' );
return Views::view( 'bookmarks.extensions.bookmarkletExplainer' );
}
if ( Input::exists('privacy') ) {
$privacy = 'const privacy = "' . Input::post('privacy') . '";';
} else {
$privacy = 'const privacy = prompt("Enter privacy level (e.g., public/private):");';
}
Components::set( 'BK_JS_PRIVACY', $privacy );
if ( Input::exists('includeDescription') ) {
$description = 'const notes = prompt("Enter a description (optional):");';
} else {
$description = '';
}
Components::set( 'BK_JS_NOTES', $description );
if ( Input::exists('includeColor') ) {
$color = 'const color = "'.Input::post('color').'";';
} else {
$color = '';
}
Components::set( 'BK_JS_COLOR', $color );
if ( Input::exists('includeFolder') ) {
$folder = 'const folder = "'.Input::post('folder_id').'";';
} else {
$folder = '';
}
Components::set( 'BK_JS_FOLDER', $folder );
$this->setFolderSelect(Input::post('folder'));
$tokens = new Token;
$apiKey = $tokens->findOrCreateUserToken( App::$activeUser->ID, true );
$apiUrl = Routes::getAddress() . 'api/bookmarks/create';
Components::set( 'BK_API_KEY', $apiKey );
Components::set( 'BK_API_URL', $apiUrl );
Views::view( 'bookmarks.extensions.bookmarklet' );
}
public function chrome() {
self::$title = 'Chrome Extension';
self::$pageDescription = 'Our Chrome extension allows you to quickly add new bookmarks or folders right from your browser\'s toolbar.';
Views::view( 'bookmarks.extensions.chrome' );
}
public function firefox() {
self::$title = 'Firefox Extension';
self::$pageDescription = 'Our Firefox extension allows you to quickly add new bookmarks or folders right from your browser\'s toolbar.';
Views::view( 'bookmarks.extensions.firefox' );
}
public function opera() {
self::$title = 'Opera Extension';
self::$pageDescription = 'Our Opera extension allows you to quickly add new bookmarks or folders right from your browser\'s toolbar.';
Views::view( 'bookmarks.extensions.opera' );
}
public function edge() {
self::$title = 'Edge Extension';
self::$pageDescription = 'Our Edge extension allows you to quickly add new bookmarks or folders right from your browser\'s toolbar.';
Views::view( 'bookmarks.extensions.edge' );
}
public function brave() {
self::$title = 'Brave Extension';
self::$pageDescription = 'Our Brave extension allows you to quickly add new bookmarks or folders right from your browser\'s toolbar.';
Views::view( 'bookmarks.extensions.brave' );
}
public function safari() {
self::$title = 'Safari Extension';
self::$pageDescription = 'Our Safari extension allows you to quickly add new bookmarks or folders right from your browser\'s toolbar.';
Views::view( 'bookmarks.extensions.safari' );
}
private function setFolderSelect( $folderID = null ) {
$folders = new Folders;
$options = $folders->simpleByUser();
$out = '';
$out .= '<select name="folder_id" id="folder_id" class="form-control">';
if ( isset( $options[0] ) ) {
$assocOptions = [];
foreach ( $options as $key => $value ) {
$assocOptions[$value] = $value;
}
$options = $assocOptions;
}
if ( ! empty( $options ) ) {
foreach ( $options as $fieldname => $value ) {
if ( $value == $folderID ) {
$selected = ' selected';
} else {
$selected = '';
}
$out .= '<option value="' . $value . '"' . $selected . '>' . $fieldname . '</option>';
}
} else {
$out .= '<option value="0" selected>No Folder</option>';
}
$out .= '</select>';
$folderSelect = Template::parse( $out );
Components::set( 'folderSelect', $folderSelect );
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

View File

@ -0,0 +1,35 @@
javascript:(function() {
const apiKey = localStorage.getItem('notAnAuthToken');
const apiUrl = localStorage.getItem('api_url');
const name = prompt("Enter a name for the bookmark:");
const notes = prompt("Enter any notes (optional):");
const color = prompt("Enter a color (optional):");
const privacy = prompt("Enter privacy level (e.g., public/private):");
const folder = prompt("Enter a folder (optional):");
const url = window.location.href;
if (!name) {
alert("Name is required.");
return;
}
fetch(apiUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${apiKey}`
},
body: JSON.stringify({ name, url, notes, color, privacy, folder })
})
.then(response => {
if (response.ok) {
alert("Bookmark saved successfully!");
} else {
alert("Failed to save bookmark. Please check your API key.");
}
})
.catch(error => {
console.error(error);
alert("An unknown error occurred while saving the bookmark.");
});
})();

View File

@ -20,12 +20,19 @@ document.addEventListener('DOMContentLoaded', () => {
toggleVisibility('dashShareButtonSwitch', 'btn-share');
// Retrieve the list of collapsed folderCard IDs from local storage
const collapsedFolders = JSON.parse(localStorage.getItem( 'collapsedFolders' )) || [];
const onDashboard = document.getElementById("dash_id");
let collapsedFolders;
if ( onDashboard ) {
collapsedFolders = JSON.parse(localStorage.getItem( 'collapsedDashFolders' + onDashboard.value )) || [];
} else {
collapsedFolders = JSON.parse(localStorage.getItem( 'collapsedFolders' )) || [];
}
// Collapse the elements stored in local storage when the page loads
collapsedFolders.forEach((folderId) => {
const collapseElement = document.querySelector(`#Collapse${folderId}`);
if (collapseElement) {
if ( collapseElement ) {
collapseElement.classList.remove('show');
}
});
@ -40,19 +47,31 @@ document.addEventListener('DOMContentLoaded', () => {
// Listen for collapse and expand events
collapseElement.addEventListener('hidden.bs.collapse', () => {
let storageName;
// Add the folderCard ID to local storage when collapsed
if (!collapsedFolders.includes(folderCardId)) {
collapsedFolders.push(folderCardId);
localStorage.setItem( 'collapsedFolders' , JSON.stringify(collapsedFolders));
if ( onDashboard ) {
storageName = 'collapsedDashFolders' + onDashboard.value;
} else {
storageName = 'collapsedFolders';
}
localStorage.setItem( storageName , JSON.stringify(collapsedFolders));
}
});
collapseElement.addEventListener('shown.bs.collapse', () => {
let storageName;
// Remove the folderCard ID from local storage when expanded
const index = collapsedFolders.indexOf(folderCardId);
if (index > -1) {
collapsedFolders.splice(index, 1);
localStorage.setItem( 'collapsedFolders' , JSON.stringify(collapsedFolders));
if ( onDashboard ) {
storageName = 'collapsedDashFolders' + onDashboard.value;
} else {
storageName = 'collapsedFolders';
}
localStorage.setItem( storageName , JSON.stringify(collapsedFolders));
}
});
});
@ -180,10 +199,11 @@ function updateDashLinkOrder() {
}
function loadDashLinkOrder() {
const onDashboard = document.getElementById("dash_id");
const storedOrder = localStorage.getItem("manageFolderOrder"); // Get the saved order
const bookmarkSort = document.getElementById("bookmarkSort");
if (!storedOrder || !bookmarkSort) return; // Exit if no saved order or no container
if ( onDashboard || !storedOrder || !bookmarkSort ) return; // Exit if no saved order or no container
const orderArray = storedOrder.split(","); // Convert the saved order into an array
const bookmarkCards = Array.from(document.querySelectorAll("#bookmarkSort .bookmark-card"));

View File

@ -21,14 +21,14 @@
<div class="mb-3 row">
<label for="title" class="col-lg-5 col-form-label text-end">Description:</label>
<label for="description" class="col-lg-5 col-form-label text-end">Description:</label>
<div class="col-lg-3">
<textarea class="form-control" name="description" maxlength="2000" rows="10" cols="50" id="description"></textarea>
</div>
</div>
{folderSelect}
<div class="mb-3 row">
<label for="title" class="col-lg-5 col-form-label text-end">Privacy</label>
<label for="privacy" class="col-lg-5 col-form-label text-end">Privacy</label>
<div class="col-lg-3">
<select id="privacy" name="privacy" class="form-control">
<option value="private">Private</option>
@ -37,7 +37,7 @@
</div>
</div>
<div class="mb-3 row">
<label for="title" class="col-lg-5 col-form-label text-end">Color</label>
<label for="color" class="col-lg-5 col-form-label text-end">Color</label>
<div class="col-lg-3" id="colorContainer">
{colorSelect}
</div>

View File

@ -5,6 +5,7 @@
<form method="post">
<fieldset>
<input type="hidden" name="token" value="{TOKEN}">
<input type="hidden" name="dash_id" id="dash_id" value="{ID}">
<input type="hidden" name="link_order" value="{link_order}" id="dashLinkOrder">
<div class="row g-3" id="bookmarkSort">
{folderPanels}

View File

@ -8,31 +8,75 @@
Since you can't use extensions on mobile, you can log in from your mobile device and visit this page.
</p>
<p>
Below is a code snippet that you can copy, then create a new bookmark on your mobile device as you would normally.
Before saving the bookmark, change the name to something simple like "ATB Bookmarker" and paste thiis code as the url.
Below is a code snippet that you can copy. Copy the code, then create a new bookmark on your mobile device as you would normally.
Before saving the bookmark, change the name to something simple like "ATB Bookmarker" and paste this code as the url.
</p>
<p>
Once you have the bookmarklet saved, you can simply go to your mobile bookmarks while on a page and this snippet will grab the info you need and add it to you account.
</p>
</div>
<div class="context-second-bg p-4 border m-4">
<form method="post">
<fieldset>
<!-- Privacy -->
<div class="d-flex align-items-center border p-2 rounded mb-3 context-main-bg">
<div class="me-3 fw-bold">Default privacy:</div>
<div class="">
<select id="privacy" name="privacy" class="form-control">
<option value="private">Private</option>
<option value="public">Public</option>
</select>
</div>
</div>
<!-- Description -->
<div class="d-flex align-items-center border p-2 rounded mb-3 context-main-bg">
<div class="me-3 fw-bold">Ask for Description:</div>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="includeDescription" name="includeDescription"{editModeSwitch_IS_CHECKED}>
<label class="form-check-label" for="includeDescription"></label>
</div>
</div>
<!-- Color -->
<div class="d-flex align-items-center border p-2 rounded mb-3 context-main-bg">
<div class="me-3 fw-bold">Include a default color:</div>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="includeColor" name="includeColor"{editModeSwitch_IS_CHECKED}>
<label class="form-check-label" for="includeColor"></label>
</div>
<div class="">
{colorSelect}
</div>
</div>
<!-- Folder -->
<div class="d-flex align-items-center border p-2 rounded mb-3 context-main-bg">
<div class="me-3 fw-bold">Include a default folder:</div>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="includeFolder" name="includeFolder"{editModeSwitch_IS_CHECKED}>
<label class="form-check-label" for="includeFolder"></label>
</div>
<div class="">
{folderSelect}
</div>
</div>
</fieldset>
<div class="card-footer d-flex justify-content-center align-items-center context-main-bg">
<button type="submit" name="submit" value="submit" class="btn btn-md atb-green-outline my-2">Refresh Code</button>
</div>
</form>
</div>
<div class="">
<div class="context-second-bg p-4">
<pre lang="javascript">
javascript:(function() {
const apiKey = localStorage.getItem('notAnAuthToken');
const apiUrl = localStorage.getItem('api_url');
const name = prompt("Enter a name for the bookmark:");
const notes = prompt("Enter any notes (optional):");
const color = prompt("Enter a color (optional):");
const privacy = prompt("Enter privacy level (e.g., public/private):");
const folder = prompt("Enter a folder (optional):");
const apiKey = "{BK_API_KEY}";
const apiUrl = "{BK_API_URL}";
const url = window.location.href;
if (!apiKey) {
alert("You must sign in to obtain an auth token.");
return;
}
const name = prompt("Enter a name for the bookmark:");
{BK_JS_NOTES}
{BK_JS_COLOR}
{BK_JS_PRIVACY}
{BK_JS_FOLDER}
if (!name) {
alert("Name is required.");
return;

View File

@ -0,0 +1,19 @@
<div class="col-10 offset-md-1 context-main-bg p-4 my-5">
<legend class="text-center">Mobile Bookmarklet</legend>
<hr>
<div class="col-8 offset-2 ">
<div class="h5">
<p>
You can quickly and easily add bookmarks to your AllTheBookmarks account from any mobile device.
Since you can't use extensions on mobile, you can log in from your mobile device and visit this page.
</p>
<p>
Once logged in, there will be a code snippet that you can copy. Copy the code, then create a new bookmark on your mobile device as you would normally.
Before saving the bookmark, change the name to something simple like "ATB Bookmarker" and paste this code as the url.
</p>
<p>
Once you have the bookmarklet saved, you can simply go to your mobile bookmarks while on a page and this snippet will grab the info you need and add it to you account.
</p>
</div>
</div>
</div>

View File

@ -0,0 +1,48 @@
<section class="container my-5">
<div class="card shadow-sm">
<div class="card-body context-main-bg">
<h2 class="card-title text-center mb-4">How to Export bookmarks in Edge</h2>
{tutorialCrumbs}
<hr>
<p class="card-text">
Exporting your bookmarks is lightning fast and simple inside of Edge.
</p>
<h5 class="mt-4">Step 1: open the main application menu </h5>
<p class="card-text">
Simply left-click these three dots on the right side of your main toolbar.
</p>
<div class="text-center">
<img src="/app/plugins/bookmarks/images/edge/settings.png" class="img-fluid rounded mb-4" alt="Right-clicking on the extension icon">
</div>
<h5>Step 2: Open the Bookmark Menu</h5>
<p class="card-text">
In the list, select <strong>Favorites</strong> and another menu should appear.
</p>
<div class="text-center">
<img src="/app/plugins/bookmarks/images/edge/favorites.png" class="img-fluid rounded mb-4" alt="Extension settings page">
</div>
<h5>Step 3: Open the Favorites Options</h5>
<p class="card-text">
In this menu, on the top right click the three dots for a final dropdown.
</p>
<div class="text-center">
<img src="/app/plugins/bookmarks/images/edge/bookmark-options.png" class="img-fluid rounded mb-4" alt="Extension settings page">
</div>
<h5>Step 4: Export your bookmarks</h5>
<p class="card-text">
From this list, select <strong>Export favorites</strong> and you should be taken to the import page.
</p>
<div class="text-center">
<img src="/app/plugins/bookmarks/images/edge/export.png" class="img-fluid rounded mb-4" alt="Extension settings page">
</div>
<p class="card-text">
Finally, save the <strong>.html</strong> file somewhere easy to access when you use the <a href="/bookmarks/import" class="text-decoration-none atb-green">imports</a> feature.
</p>
</div>
</div>
</section>

View File

@ -0,0 +1,64 @@
<section class="container my-5">
<div class="card shadow-sm">
<div class="card-body context-main-bg">
<h2 class="card-title text-center mb-4">How to Import bookmarks in Edge</h2>
{tutorialCrumbs}
<hr>
<p class="card-text">
Importing your bookmarks from AllTheBookmarks is lightning fast and simple inside of Edge.
</p>
<h5 class="mt-4">Step 1: open the main application menu </h5>
<p class="card-text">
Simply left-click these three dots on the right side of your main toolbar.
</p>
<div class="text-center">
<img src="/app/plugins/bookmarks/images/edge/settings.png" class="img-fluid rounded mb-4" alt="Right-clicking on the extension icon">
</div>
<h5>Step 2: Open the Bookmark Menu</h5>
<p class="card-text">
In the list, select <strong>Favorites</strong> and another menu should appear.
</p>
<div class="text-center">
<img src="/app/plugins/bookmarks/images/edge/favorites.png" class="img-fluid rounded mb-4" alt="Extension settings page">
</div>
<h5>Step 3: Open the Favorites Options</h5>
<p class="card-text">
In this menu, on the top right click the three dots for a final dropdown.
</p>
<div class="text-center">
<img src="/app/plugins/bookmarks/images/edge/bookmark-options.png" class="img-fluid rounded mb-4" alt="Extension settings page">
</div>
<h5>Step 4: Open the Import Page</h5>
<p class="card-text">
From this list, select <strong>Import favorites</strong> and you should be taken to the import page.
</p>
<div class="text-center">
<img src="/app/plugins/bookmarks/images/edge/import.png" class="img-fluid rounded mb-4" alt="Extension settings page">
</div>
<h5>Step 5: Open the Importer</h5>
<p class="card-text">
On this page, under the title <strong>Import from other browsers</strong> click the button labeled <strong>Choose what to import</strong>.
</p>
<div class="text-center">
<img src="/app/plugins/bookmarks/images/edge/import-menu.png" class="img-fluid rounded mb-4" alt="Extension settings page">
</div>
<h5>Step 6: Begin Importing</h5>
<p class="card-text">
Under <strong>Import from</strong> make sure to select <strong>Favorites or bookmarks HTML file</strong>.
</p>
<div class="text-center">
<img src="/app/plugins/bookmarks/images/edge/import-select.png" class="img-fluid rounded mb-4" alt="Extension settings page">
</div>
<p class="card-text">
Finally, select the <strong>.html</strong> file you saved when using the <a href="/bookmarks/export" class="text-decoration-none atb-green">exports</a> feature.
</p>
</div>
</div>
</section>

View File

@ -0,0 +1,36 @@
<section class="container my-5">
<div class="card shadow-sm">
<div class="card-body context-main-bg">
<h2 class="card-title text-center mb-4">How to pin the extension to your toolbar in Edge</h2>
{tutorialCrumbs}
<hr>
<div class="alert alert-success w-100 text-center" role="alert">
If you have not already installed the AllTheBookmarks Edge extension, you can find it in the
<a href="#" class="text-decoration-none text-primary" target="_blank">Microsoft Store</a>.
</div>
<p class="card-text">
Once installed, you can add the extension to your Edge toolbar with just a few easy steps.
</p>
<h5 class="mt-4">Step 1: Find the extensions icon on your toolbar.</h5>
<p class="card-text">
It should look like this:
</p>
<div class="text-center">
<img src="/app/plugins/bookmarks/images/edge/extensions-icon.png" class="img-fluid rounded mb-4" alt="Right-clicking on the extension icon">
</div>
<h5>Step 2: Left click this icon and a list of your currently installed extensions should show.</h5>
<p class="card-text">
Next to AllTheBookmarks, on the right you should see an eye icon, click this.
</p>
<div class="text-center">
<img src="/app/plugins/bookmarks/images/edge/pin.png" class="img-fluid rounded mb-4" alt="Extension settings page">
</div>
<p class="card-text">
Once pinned, you should see the AllTheBookmarks icon on the toolbar.
</p>
<div class="text-center">
<img src="/app/plugins/bookmarks/images/edge/pinned.png" class="img-fluid rounded mb-4" alt="Extension settings page">
</div>
</div>
</div>
</section>

View File

@ -0,0 +1,37 @@
<section class="container my-5">
<div class="card shadow-sm">
<div class="card-body context-main-bg">
<h2 class="card-title text-center mb-4">How to Access Extension Settings in Edge</h2>
{tutorialCrumbs}
<hr>
<div class="alert alert-success w-100 text-center" role="alert">
If you have not already installed the AllTheBookmarks Edge extension, you can find it in the
<a href="#" class="text-decoration-none text-primary" target="_blank">Microsoft Store</a>.
</div>
<p class="card-text">
With Edge, accessing the extension settings couldn't be easier.
</p>
<h5 class="mt-4">Step 1: Locate the Extension Icon</h5>
<p class="card-text">
Simply locate the AllTheBookmarks icon on your toolbar and right-click the icon.
</p>
<div class="text-center">
<img src="/app/plugins/bookmarks/images/edge/options.png" class="img-fluid rounded mb-4" alt="Right-clicking on the extension icon">
</div>
<h5>Step 2: Open the Options</h5>
<p class="card-text">
From the dropdown menu that appears, select <strong>Extension Options</strong>. You should be greeted by a settings page very similar to the one below.
</p>
<div class="text-center">
<img src="/app/plugins/bookmarks/images/edge/settings-page.png" class="img-fluid rounded mb-4" alt="Extension settings page">
</div>
<p class="card-text">
(If you need help pinning the extension to your toolbar for easy access, we have a separate
<a href="/tutorials/edge/pin" class="text-decoration-none atb-green">tutorial</a> for that.)
</p>
</div>
</div>
</section>

View File

@ -5,7 +5,7 @@
{tutorialCrumbs}
<hr>
<p class="card-text">
Exporting your bookmarks is lightning fast and simple inside of firefox.
Exporting your bookmarks is lightning fast and simple inside of Firefox.
</p>
<h5 class="mt-4">Step 1: open the main application menu </h5>
@ -32,7 +32,7 @@
<img src="/app/plugins/bookmarks/images/firefox/manage-bookmarks.png" class="img-fluid rounded mb-4" alt="Extension settings page">
</div>
<h5>Step 3: Open the Import Menu</h5>
<h5>Step 4: Open the Export Menu</h5>
<p class="card-text">
On this page, near the top left, you should see a button that says <strong>Import and Backup</strong>. Click this button and another menu should appear.
</p>

View File

@ -20,7 +20,7 @@
</div>
<h5>Step 2: Left click this icon and a list of your currently installed extensions should show.</h5>
<p class="card-text">
Next to AllTheBookmarks, on the right you should see a pin icon, click this.
Next to AllTheBookmarks, on the right you should see a settings icon, click this then select <strong>Pin to Toolbar</strong>
</p>
<div class="text-center">
<img src="/app/plugins/bookmarks/images/firefox/pin.png" class="img-fluid rounded mb-4" alt="Extension settings page">

View File

@ -9,22 +9,40 @@
<a href="/firefox" class="text-decoration-none text-primary" target="_blank">Firefox Store</a>.
</div>
<p class="card-text">
With Firefox, accessing the extension settings couldn't be easier.
With Firefox, accessing the extension settings is a breeze.
</p>
<h5 class="mt-4">Step 1: Locate the Extension Icon</h5>
<p class="card-text">
Simply locate the AllTheBookmarks icon on your toolbar and right-click the icon.
</p>
<div class="text-center">
<img src="/app/plugins/bookmarks/images/firefox/options.png" class="img-fluid rounded mb-4" alt="Right-clicking on the extension icon">
<img src="/app/plugins/bookmarks/images/firefox/icon.png" class="img-fluid rounded mb-4" alt="Right-clicking on the extension icon">
</div>
<h5>Step 2: Open the Options</h5>
<h5>Step 2: Open the Add-on manage page</h5>
<p class="card-text">
From the dropdown menu that appears, select <strong>Options</strong>. You should be greeted by a settings page very similar to the one below.
From the dropdown menu that appears, select <strong>Manage Extension</strong>.
</p>
<div class="text-center">
<img src="/app/plugins/bookmarks/images/firefox/manage.png" class="img-fluid rounded mb-4" alt="Extension settings page">
</div>
<h5>Step 3: Open the extension setting page</h5>
<p class="card-text">
The extension management page should appear similar to this. In the top right, click these three dots and select <strong>Options</strong>.
</p>
<div class="text-center">
<img src="/app/plugins/bookmarks/images/firefox/manage-select.png" class="img-fluid rounded mb-4" alt="Extension settings page">
</div>
<p class="card-text">
You should be greeted by a settings page very similar to the one below.
</p>
<div class="text-center">
<img src="/app/plugins/bookmarks/images/firefox/settings-page.png" class="img-fluid rounded mb-4" alt="Extension settings page">
</div>
<p class="card-text">
(If you need help pinning the extension to your toolbar for easy access, we have a separate
<a href="/tutorials/firefox/pin" class="text-decoration-none atb-green">tutorial</a> for that.)

View File

@ -0,0 +1,40 @@
<section class="container my-5">
<div class="card shadow-sm">
<div class="card-body context-main-bg">
<h2 class="card-title text-center mb-4">How to Export bookmarks in Opera</h2>
{tutorialCrumbs}
<hr>
<p class="card-text">
Exporting your bookmarks is lightning fast and simple inside of Opera.
</p>
<h5 class="mt-4">Step 1: open the main application menu </h5>
<p class="card-text">
Simply left-click these three dots in the bottom left of the browser window.
</p>
<div class="text-center">
<img src="/app/plugins/bookmarks/images/opera/sidebar.png" class="img-fluid rounded mb-4" alt="Right-clicking on the extension icon">
</div>
<h5>Step 2: Open the Bookmark Menu</h5>
<p class="card-text">
In the list, click the icon next to <strong>Bookmarks</strong> and another window should open.
</p>
<div class="text-center">
<img src="/app/plugins/bookmarks/images/opera/bookmarks.png" class="img-fluid rounded mb-4" alt="Extension settings page">
</div>
<h5>Step 4: Export your bookmarks</h5>
<p class="card-text">
In the bottom right of the page, click <strong>Import / Export</strong> and select <strong>Export Bookmarks</strong>.
</p>
<div class="text-center">
<img src="/app/plugins/bookmarks/images/opera/export.png" class="img-fluid rounded mb-4" alt="Extension settings page">
</div>
<p class="card-text">
Finally, save the <strong>.html</strong> file somewhere easy to access when you use the <a href="/bookmarks/import" class="text-decoration-none atb-green">imports</a> feature.
</p>
</div>
</div>
</section>

View File

@ -0,0 +1,48 @@
<section class="container my-5">
<div class="card shadow-sm">
<div class="card-body context-main-bg">
<h2 class="card-title text-center mb-4">How to Import bookmarks in Opera</h2>
{tutorialCrumbs}
<hr>
<p class="card-text">
Importing your bookmarks from AllTheBookmarks is lightning fast and simple inside of Opera.
</p>
<h5 class="mt-4">Step 1: open the main application menu </h5>
<p class="card-text">
Simply left-click these three dots in the bottom left of the browser window.
</p>
<div class="text-center">
<img src="/app/plugins/bookmarks/images/opera/sidebar.png" class="img-fluid rounded mb-4" alt="Right-clicking on the extension icon">
</div>
<h5>Step 2: Open the Bookmark Menu</h5>
<p class="card-text">
In the list, click the icon next to <strong>Bookmarks</strong> and another window should open.
</p>
<div class="text-center">
<img src="/app/plugins/bookmarks/images/opera/bookmarks.png" class="img-fluid rounded mb-4" alt="Extension settings page">
</div>
<h5>Step 3: Open the Import Page</h5>
<p class="card-text">
In the bottom right of the page, click <strong>Import / Export</strong> and select <strong>Import Bookmarks</strong> and you should be taken to the import page.
</p>
<div class="text-center">
<img src="/app/plugins/bookmarks/images/opera/import.png" class="img-fluid rounded mb-4" alt="Extension settings page">
</div>
<h5>Step 4: Begin Importing</h5>
<p class="card-text">
In this menu, click the dropdown and make sure to select <strong>Bookmarks HTML file</strong>.
</p>
<div class="text-center">
<img src="/app/plugins/bookmarks/images/opera/import-select.png" class="img-fluid rounded mb-4" alt="Extension settings page">
</div>
<p class="card-text">
Finally, select the <strong>.html</strong> file you saved when using the <a href="/bookmarks/export" class="text-decoration-none atb-green">exports</a> feature.
</p>
</div>
</div>
</section>

View File

@ -0,0 +1,46 @@
<section class="container my-5">
<div class="card shadow-sm">
<div class="card-body context-main-bg">
<h2 class="card-title text-center mb-4">How to pin the extension to your toolbar in Opera</h2>
{tutorialCrumbs}
<hr>
<div class="alert alert-success w-100 text-center" role="alert">
If you have not already installed the AllTheBookmarks Opera extension, you can find it in the
<a href="#" class="text-decoration-none text-primary" target="_blank">Opera Store</a>.
</div>
<p class="card-text">
Once installed, you can add the extension to your Opera toolbar with just a few easy steps.
</p>
<h5 class="mt-4">Step 1: Find the extensions icon on your toolbar.</h5>
<p class="card-text">
It should look like this:
</p>
<div class="text-center">
<img src="/app/plugins/bookmarks/images/opera/extensions.png" class="img-fluid rounded mb-4" alt="Right-clicking on the extension icon">
</div>
<h5 class="mt-4">Step 0: Reveal the extensions toolbar. ( This step may not be required for all users ).</h5>
<p class="card-text">
If you find that you are having trouble locating the extensions icon, double check that the additional toolbar is expanded.
</p>
<div class="text-center">
<img src="/app/plugins/bookmarks/images/opera/toolbar.png" class="img-fluid rounded mb-4" alt="Right-clicking on the extension icon">
</div>
<h5>Step 2: Left click this icon and a list of your currently installed extensions should show.</h5>
<p class="card-text">
Next to AllTheBookmarks, on the right you should see an eye icon, click this.
</p>
<div class="text-center">
<img src="/app/plugins/bookmarks/images/opera/pin.png" class="img-fluid rounded mb-4" alt="Extension settings page">
</div>
<p class="card-text">
Once pinned, you should see the AllTheBookmarks icon on the toolbar.
</p>
<div class="text-center">
<img src="/app/plugins/bookmarks/images/opera/pinned.png" class="img-fluid rounded mb-4" alt="Extension settings page">
</div>
</div>
</div>
</section>

View File

@ -0,0 +1,37 @@
<section class="container my-5">
<div class="card shadow-sm">
<div class="card-body context-main-bg">
<h2 class="card-title text-center mb-4">How to Access Extension Settings in Opera</h2>
{tutorialCrumbs}
<hr>
<div class="alert alert-success w-100 text-center" role="alert">
If you have not already installed the AllTheBookmarks Opera extension, you can find it in the
<a href="#" class="text-decoration-none text-primary" target="_blank">Opera Store</a>.
</div>
<p class="card-text">
With Opera, accessing the extension settings couldn't be easier.
</p>
<h5 class="mt-4">Step 1: Locate the Extension Icon</h5>
<p class="card-text">
Simply locate the AllTheBookmarks icon on your toolbar and right-click the icon.
</p>
<div class="text-center">
<img src="/app/plugins/bookmarks/images/opera/options.png" class="img-fluid rounded mb-4" alt="Right-clicking on the extension icon">
</div>
<h5>Step 2: Open the Options</h5>
<p class="card-text">
From the dropdown menu that appears, select <strong>Options</strong>. You should be greeted by a settings page very similar to the one below.
</p>
<div class="text-center">
<img src="/app/plugins/bookmarks/images/opera/settings-page.png" class="img-fluid rounded mb-4" alt="Extension settings page">
</div>
<p class="card-text">
(If you need help pinning the extension to your toolbar for easy access, we have a separate
<a href="/tutorials/opera/pin" class="text-decoration-none atb-green">tutorial</a> for that.)
</p>
</div>
</div>
</section>

View File

@ -8,7 +8,7 @@
id="comment"
placeholder="Write your comment here..."></textarea>
</div>
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary mb-3">Comment</button>
<button name="submit" value="submit" type="submit" class="btn btn-lg atb-green-bg mb-3">Comment</button>
<input type="hidden" name="token" value="{TOKEN}">
<input type="hidden" name="contentId" value="{CONTENT_ID}">
</form>

View File

@ -28,7 +28,7 @@
</li>
{/LOOP}
{ALT}
<li class="list-group-item">
<li class="list-group-item context-second-bg context-main mb-2">
<div class="text-center">
<p class="mb-0">Be the first to comment.</p>
</div>

View File

@ -33,7 +33,7 @@ class Reviews extends Controller {
public function __construct() {
self::$title = 'Reviews - {SITENAME}';
self::$pageDescription = 'On this page you can submit a reviews for a product.';
self::$pageDescription = 'This page allows you to add a new product review or update your existing reviews.';
if ( ! App::$isLoggedIn ) {
Session::flash( 'notice', 'You must be logged in to review products.' );
@ -48,18 +48,21 @@ class Reviews extends Controller {
}
public function index() {
$reviews = Views::simpleView( 'reviews.list', self::$reviews->byUser() );
Components::set( 'reviews', $reviews );
Views::view( 'reviews.list' );
Views::view( 'reviews.list', self::$reviews->byUser() );
}
public function review( $slug = null ) {
$category = self::$categories->findBySlug( $slug );
if ( ! $category ) {
$categories = self::$categories->simpleUnreviewed();
if ( empty( $categories ) ) {
Session::flash( 'notice', 'There are no additional products to review at this time.' );
Redirect::to( 'reviews/index' );
}
$selectedCategory = '0';
$reviewCategorySelect = HoudiniForms::getSelectHtml(
'review_category_id',
self::$categories->simple(),
$categories,
$selectedCategory,
);
Components::set( 'reviewCategorySelect', $reviewCategorySelect );
@ -78,12 +81,76 @@ class Reviews extends Controller {
return Views::view( 'reviews.create' );
}
$result = self::$reviews->create( Input::post('title'), Input::post('rating'), Input::post('review'), Input::post('review_category_id') );
if ( true === $result ) {
if ( ! empty( $result ) ) {
Session::flash( 'success', 'Your review has been received.' );
Redirect::to( 'home/index' );
Redirect::to( 'reviews/index' );
} else {
Issues::add( 'error', 'There was an unresolved error while submitting your review.' );
return Views::view( 'reviews.create' );
}
}
public function view( $id = null ) {
$review = $this->confirmOwner( $id );
Views::view( 'reviews.view', $review );
}
public function edit( $id = null ) {
$review = $this->confirmOwner( $id );
if ( ! Input::exists( 'submit' ) ) {
return Views::view( 'reviews.edit', $review );
}
if ( ! Forms::check( 'reviewEditPublic' ) ) {
Issues::add( 'error', [ 'There was an error with your request.' => Check::userErrors() ] );
return Views::view( 'reviews.edit', $review );
}
$result = self::$reviews->update(
$id,
Input::post('title'),
Input::post('rating'),
Input::post('review')
);
if ( $result ) {
Session::flash( 'success', 'Your review has been updated.' );
return Redirect::to( 'reviews/index' );
}
Issues::add( 'error', [ 'There was an error with your request.' => Check::userErrors() ] );
Views::view( 'reviews.edit', $review );
}
public function delete( $id = null ) {
$this->confirmOwner( $id );
if ( self::$reviews->delete( $id ) ) {
Session::flash( 'success', 'Review deleted' );
} else {
Session::flash( 'error', 'There was an error with your request.' );
}
return Redirect::to( 'reviews/index' );
}
private function confirmOwner( $id ) {
if ( ! App::$isLoggedIn ) {
Session::flash( 'error', 'You must be logged in to review products.' );
return Redirect::home();
}
if ( !Check::id( $id ) ) {
Session::flash( 'error', 'Unknown Review' );
return Redirect::to( 'reviews/index' );
}
$review = self::$reviews->findById( $id );
if ( empty( $review ) ) {
Session::flash( 'error', 'Unknown Review' );
return Redirect::to( 'reviews/index' );
}
if ( App::$activeUser->ID != $review->createdBy ) {
Session::flash( 'error', 'Unknown Review' );
return Redirect::to( 'reviews/index' );
}
return $review;
}
}

View File

@ -25,6 +25,7 @@ class ReviewForms extends Forms {
self::addHandler( 'editReview', __CLASS__, 'editReview' );
self::addHandler( 'categoryCreate', __CLASS__, 'categoryCreate' );
self::addHandler( 'categoryEdit', __CLASS__, 'categoryEdit' );
self::addHandler( 'reviewEditPublic', __CLASS__, 'reviewEditPublic' );
}
/**
@ -88,6 +89,21 @@ class ReviewForms extends Forms {
}
return true;
}
public static function reviewEditPublic() {
if ( ! Input::exists( 'review' ) ) {
Check::addUserError( 'You must provide a review.' );
return false;
}
if ( ! Input::exists( 'title' ) ) {
Check::addUserError( 'You must provide a title.' );
return false;
}
if ( ! Input::exists( 'rating' ) ) {
Check::addUserError( 'You must provide a rating.' );
return false;
}
return true;
}
}
new ReviewForms;

View File

@ -62,21 +62,19 @@ class Review extends DatabaseModel {
return self::$db->lastId();
}
public function update( $id, $title, $rating, $review, $review_category_id = '0' ) {
public function update( $id, $title, $rating, $review, $review_category_id = null ) {
if ( ! $this->plugin->checkEnabled() ) {
Debug::info( 'Reviews are disabled in the config.' );
return false;
}
if ( !Check::dataTitle( $slug ) ) {
Debug::info( 'Review Categories: illegal title.' );
return false;
}
$fields = [
'title' => $title,
'rating' => $rating,
'review' => $review,
'review_category_id' => $review_category_id,
'review' => $review
];
if ( ! empty( $review_category_id ) ) {
$fields['review_category_id'] = $review_category_id;
}
if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
new CustomException( 'reviewUpdate' );
Debug::error( "Review: $id not updated: $fields" );
@ -133,6 +131,23 @@ class Review extends DatabaseModel {
return $this->filter( $reviews->results() );
}
public function reviewedCategoriesByUser() {
$whereClause = ['createdBy', '=', App::$activeUser->ID];
$reviews = self::$db->action( 'SELECT ID,review_category_id', $this->tableName, $whereClause );
if ( !$reviews->count() ) {
Debug::info( 'No Reviews found.' );
return false;
}
$categoryIds = [];
foreach ($reviews->results() as $key => $result) {
if ( ! in_array( $result->review_category_id, $categoryIds ) ) {
$categoryIds[] = $result->review_category_id;
}
}
return $categoryIds;
}
public function byCategory( $id, $limit = null ) {
$whereClause = [ 'review_category_id', '=', $id ];
if ( empty( $limit ) ) {

View File

@ -17,6 +17,7 @@ use TheTempusProject\Bedrock\Functions\Check;
use TheTempusProject\Canary\Bin\Canary as Debug;
use TheTempusProject\Classes\DatabaseModel;
use TheTempusProject\Plugins\Reviews as Plugin;
use TheTempusProject\Models\Review;
use TheTempusProject\TheTempusProject as App;
use TheTempusProject\Canary\Classes\CustomException;
@ -109,4 +110,29 @@ class ReviewCategory extends DatabaseModel {
}
return $out;
}
public function simpleUnreviewed() {
$categories = self::$db->get( $this->tableName, '*' );
if ( !$categories->count() ) {
Debug::warn( 'Could not find any categories' );
return false;
}
$categories = $categories->results();
$review = new Review;
$reviews = $review->reviewedCategoriesByUser();
$out = [];
foreach ( $categories as &$category ) {
if ( ! empty( $reviews) && in_array( $category->ID, $reviews ) ) {
continue;
}
$out[ $category->name ] = $category->ID;
}
return $out;
}
}

View File

@ -1,35 +1,42 @@
<div class="container col-md-4 col-lg-4">
<div class="row">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">Review Category</h3>
</div>
<div class="panel-body">
<div class="row">
<div class="">
<table class="table table-user-primary">
<div class="container py-4">
<div class="row justify-content-center">
<div class="col-md-8">
{ADMIN_BREADCRUMBS}
<div class="card shadow">
<!-- Card Header -->
<div class="card-header text-center bg-dark text-white">
<h3 class="card-title mb-0">Review Category: {name}</h3>
</div>
<!-- Card Body -->
<div class="card-body">
<div class="row align-items-center">
<!-- Details -->
<table class="table table-borderless">
<tbody>
<tr>
<td align="left" width="200"><b>Name</b></td>
<td align="right">{name}</td>
<th scope="row">Name:</th>
<td>{name}</td>
</tr>
<tr>
<td><b>Slug</b></td>
<td align="right">{slug}</td>
<th scope="row">Slug:</th>
<td>{slug}</td>
</tr>
<tr>
<td><b>Created</b></td>
<td align="right">{DTC}{createdAt}{/DTC}</td>
<th scope="row">Created:</th>
<td>{DTC}{createdAt}{/DTC}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="panel-footer">
<a href="{ROOT_URL}admin/reviews/categoryEdit/{ID}" class="btn btn-md btn-warning" role="button"><i class="fa fa-fw fa-pencil"></i></a>
<a href="{ROOT_URL}admin/reviews/categoryDelete/{ID}" class="btn btn-md btn-danger" role="button"><i class="fa fa-fw fa-trash"></i></a>
<!-- Admin Controls -->
<div class="card-footer text-center">
<a href="{ROOT_URL}admin/reviews/categoryEdit/{ID}" class="btn btn-md btn-warning" role="button"><i class="fa fa-fw fa-pencil"></i></a>
<a href="{ROOT_URL}admin/reviews/categoryDelete/{ID}" class="btn btn-md btn-danger" role="button"><i class="fa fa-fw fa-trash"></i></a>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@ -1,22 +1,35 @@
<legend>Create Review Category</legend>
<form action="" method="post" class="form-horizontal">
<input type="hidden" name="token" value="{TOKEN}">
<div class="form-group">
<label for="name" class="col-lg-3 control-label">Name</label>
<div class="col-lg-3">
<input type="text" class="form-control" name="name" id="name">
</div>
</div>
<div class="form-group">
<label for="slug" class="col-lg-3 control-label">Slug (the public link for reviews would be {ROOT_URL}reviews/YOUR_SLUG_HERE)</label>
<div class="col-lg-3">
<input type="text" class="form-control" name="slug" id="slug">
</div>
</div>
<div class="form-group">
<label for="submit" class="col-lg-3 control-label"></label>
<div class="col-lg-3">
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block ">Submit</button>
</div>
</div>
</form>
<div class="context-main-bg context-main p-3">
<legend class="text-center">Add Review Category</legend>
<hr>
{ADMIN_BREADCRUMBS}
<form method="post">
<fieldset>
<!-- Name -->
<div class="mb-3 row">
<label for="name" class="col-lg-6 col-form-label text-end">Name:</label>
<div class="col-lg-2">
<input type="text" class="form-control" name="name" id="name" required>
</div>
</div>
<!-- Slug -->
<div class="mb-3 row">
<label for="slug" class="col-lg-6 col-form-label text-end">Slug:</label>
<div class="col-lg-2">
<input type="text" class="form-control" name="slug" id="slug" aria-describedby="slugHelp" required>
<small id="slugHelp" class="form-text text-muted">
Public links would be {ROOT_URL}reviews/YOUR_SLUG_HERE
</small>
</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">Create</button>
</div>
</fieldset>
</form>
</div>

View File

@ -1,22 +1,35 @@
<legend>Edit Review Category</legend>
<form action="" method="post" class="form-horizontal">
<input type="hidden" name="token" value="{TOKEN}">
<div class="form-group">
<label for="name" class="col-lg-3 control-label">Name</label>
<div class="col-lg-3">
<input type="text" class="form-control" name="name" id="name" value="{name}">
</div>
</div>
<div class="form-group">
<label for="slug" class="col-lg-3 control-label">Slug (the public link for reviews would be {ROOT_URL}reviews/YOUR_SLUG_HERE)</label>
<div class="col-lg-3">
<input type="text" class="form-control" name="slug" id="slug" value="{slug}">
</div>
</div>
<div class="form-group">
<label for="submit" class="col-lg-3 control-label"></label>
<div class="col-lg-3">
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block ">Submit</button>
</div>
</div>
</form>
<div class="context-main-bg context-main p-3">
<legend class="text-center">Edit Review Category</legend>
<hr>
{ADMIN_BREADCRUMBS}
<form method="post">
<fieldset>
<!-- Name -->
<div class="mb-3 row">
<label for="name" class="col-lg-6 col-form-label text-end">Name:</label>
<div class="col-lg-2">
<input type="text" class="form-control" name="name" id="name" value="{name}" required>
</div>
</div>
<!-- Slug -->
<div class="mb-3 row">
<label for="slug" class="col-lg-6 col-form-label text-end">Slug:</label>
<div class="col-lg-2">
<input type="text" class="form-control" name="slug" id="slug" aria-describedby="slugHelp" value="{slug}" required>
<small id="slugHelp" class="form-text text-muted">
Public links would be {ROOT_URL}reviews/YOUR_SLUG_HERE
</small>
</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">Create</button>
</div>
</fieldset>
</form>
</div>

View File

@ -1,28 +1,33 @@
<div class="container col-md-4 col-lg-4">
<div class="row">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">Review</h3>
</div>
<div class="panel-body">
<div class="row">
<div class="">
<table class="table table-user-primary">
<div class="container py-4">
<div class="row justify-content-center">
<div class="col-md-8">
{ADMIN_BREADCRUMBS}
<div class="card shadow">
<!-- Card Header -->
<div class="card-header text-center bg-dark text-white">
<h3 class="card-title mb-0">Review: {title}</h3>
</div>
<!-- Card Body -->
<div class="card-body">
<div class="row align-items-center">
<!-- Details -->
<table class="table table-borderless">
<tbody>
<tr>
<td align="left" width="200"><b>Title</b></td>
<td align="right">{title}</td>
<th scope="row">Title:</th>
<td>{title}</td>
</tr>
<tr>
<td><b>Rating</b></td>
<td align="right">{rating}</td>
<th scope="row">Rating:</th>
<td>{rating}</td>
</tr>
<tr>
<td><b>Created</b></td>
<td align="right">{DTC}{createdAt}{/DTC}</td>
<th scope="row">Created:</th>
<td>{DTC}{createdAt}{/DTC}</td>
</tr>
<tr>
<td align="center" colspan="2"><b>Review</b></td>
<th scope="row" colspan="2">Review:</th>
</tr>
<tr>
<td colspan="2">{review}</td>
@ -31,12 +36,14 @@
</table>
</div>
</div>
</div>
<div class="panel-footer">
<a href="{ROOT_URL}admin/reviews/reviewApprove/{ID}" class="btn btn-sm btn-success" role="button"><i class="fa fa-fw fa-info-circle"></i></a>
<a href="{ROOT_URL}admin/reviews/reviewHide/{ID}" class="btn btn-sm btn-info" role="button"><i class="fa fa-fw fa-eye-closed"></i></a>
<a href="{ROOT_URL}admin/reviews/reviewDelete/{ID}" class="btn btn-sm btn-danger" role="button"><i class="fa fa-fw fa-trash"></i></a>
<!-- Admin Controls -->
<div class="card-footer text-center">
<a href="{ROOT_URL}admin/reviews/reviewApprove/{ID}" class="btn btn-sm btn-success" role="button"><i class="fa fa-fw fa-info-circle"></i></a>
<a href="{ROOT_URL}admin/reviews/reviewHide/{ID}" class="btn btn-sm btn-info" role="button"><i class="fa fa-fw fa-eye-closed"></i></a>
<a href="{ROOT_URL}admin/reviews/reviewDelete/{ID}" class="btn btn-sm btn-danger" role="button"><i class="fa fa-fw fa-trash"></i></a>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,49 @@
<div class="container py-4">
<div class="row justify-content-center">
<div class="col-md-8">
{ADMIN_BREADCRUMBS}
<div class="card shadow">
<!-- Card Header -->
<div class="card-header text-center bg-dark text-white">
<h3 class="card-title mb-0">Review: {title}</h3>
</div>
<!-- Card Body -->
<div class="card-body">
<div class="row align-items-center">
<!-- Details -->
<table class="table table-borderless">
<tbody>
<tr>
<th scope="row">Title:</th>
<td>{title}</td>
</tr>
<tr>
<th scope="row">Rating:</th>
<td>{rating}</td>
</tr>
<tr>
<th scope="row">Created:</th>
<td>{DTC}{createdAt}{/DTC}</td>
</tr>
<tr>
<th scope="row" colspan="2">Review:</th>
</tr>
<tr>
<td colspan="2">{review}</td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- Admin Controls -->
<div class="card-footer text-center">
<a href="{ROOT_URL}admin/reviews/reviewApprove/{ID}" class="btn btn-sm btn-success" role="button"><i class="fa fa-fw fa-info-circle"></i></a>
<a href="{ROOT_URL}admin/reviews/reviewHide/{ID}" class="btn btn-sm btn-info" role="button"><i class="fa fa-fw fa-eye-closed"></i></a>
<a href="{ROOT_URL}admin/reviews/reviewDelete/{ID}" class="btn btn-sm btn-danger" role="button"><i class="fa fa-fw fa-trash"></i></a>
</div>
</div>
</div>
</div>
</div>

View File

@ -1,16 +1,18 @@
<div class="container mt-5">
<h2>Write a Review</h2>
<div class="col-8 mx-auto p-4 rounded shadow-sm mb-5 context-main-bg mt-4 container">
<h2 class="text-center mb-4">Share a Review</h2>
<hr>
<p>We thank you for for taking the time to review our products. We do not edit or modify reviews in any way. You, as the customer have the ability to modify your own reviews.</p>
<p>We read each and every review. You and the admin team both have the ability to comment on reviews privately. Neither your reviews or comments will be publicly shared without your permission.</p>
<form id="review-form" method="post">
<div class="form-group">
<label for="review_category_id">Review Category:</label>
<!-- Review Category -->
<div class="mb-3">
<label for="review_category_id" class="form-label">Review Category:</label>
{reviewCategorySelect}
</div>
<div class="form-group">
<label for="title">Title your review:</label>
<input type="text" class="form-control" id="title" name="title" required>
</div>
<div class="form-group">
<label>Rating:</label>
<!-- Rating -->
<div class="mb-3">
<label for="star-rating" class="form-label">Rating:</label>
<div class="star-rating">
<span class="fa fa-star" data-rating="1"></span>
<span class="fa fa-star" data-rating="2"></span>
@ -20,10 +22,31 @@
<input type="hidden" name="rating" class="rating-value" value="0">
</div>
</div>
<div class="form-group">
<label for="review">Your Review:</label>
<textarea class="form-control" id="review" name="review" rows="5" required></textarea>
<!-- Review Title -->
<div class="mb-3">
<label for="title" class="form-label">Review Title:</label>
<input type="text" class="form-control" id="title" name="title" aria-describedby="titleHelp" required>
<small id="titleHelp" class="form-text text-muted">
No need to overthink it, something as simple as "My Review" is fine.
</small>
</div>
<!-- Review -->
<div class="mb-3">
<label for="review" class="form-label">Your Review:</label>
<textarea class="form-control" name="review" id="review" rows="5" maxlength="2000" aria-describedby="reviewHelp" required></textarea>
<small id="reviewHelp" class="form-text text-muted">
(max: 2000 characters)
</small>
</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 atb-green-bg">Submit</button>
</div>
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block ">Submit</button>
</form>
</div>

View File

@ -0,0 +1,44 @@
<div class="col-8 mx-auto p-4 rounded shadow-sm mb-5 context-main-bg mt-4 container">
<h2 class="text-center mb-4">Edit Your Review</h2>
<hr>
<form id="review-form" method="post">
<!-- Review Title -->
<div class="mb-3">
<label for="title" class="form-label">Review Title:</label>
<input type="text" class="form-control" id="title" name="title" aria-describedby="titleHelp" value="{title}" required>
<small id="titleHelp" class="form-text text-muted">
No need to overthink it, something as simple as "My Review" is fine.
</small>
</div>
<!-- Rating -->
<div class="mb-3">
<label for="star-rating" class="form-label">Rating:</label>
<div class="star-rating">
<span class="fa fa-star" data-rating="1"></span>
<span class="fa fa-star" data-rating="2"></span>
<span class="fa fa-star" data-rating="3"></span>
<span class="fa fa-star" data-rating="4"></span>
<span class="fa fa-star" data-rating="5"></span>
<input type="hidden" name="rating" class="rating-value" value="{rating}">
</div>
</div>
<!-- Review -->
<div class="mb-3">
<label for="review" class="form-label">Your Review:</label>
<textarea class="form-control" name="review" id="review" rows="5" maxlength="2000" aria-describedby="reviewHelp" required>{review}</textarea>
<small id="reviewHelp" class="form-text text-muted">
(max: 2000 characters)
</small>
</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 atb-green-bg">Submit</button>
</div>
</form>
</div>

View File

@ -1,4 +1,4 @@
<div class="col-8 mx-auto p-4 rounded shadow-sm mb-5 context-main-bg mt-4 context-main">
<div class="col-8 mx-auto p-4 rounded shadow-sm mb-5 context-main-bg mt-4 context-main text-center">
<legend>Reviews</legend>
<hr>
<p>
@ -7,12 +7,11 @@
<p>
On this page you can find <strong>your</strong> reviews to see any responses or make edits.
</p>
<table class="table context-main">
<table class="table context-main text-center">
<thead>
<tr>
<th style="width: 60%">Title</th>
<th style="width: 10%">Rating</th>
<th style="width: 10%"></th>
<th style="width: 20%">Rating</th>
<th style="width: 10%"></th>
<th style="width: 10%"></th>
</tr>
@ -20,19 +19,20 @@
<tbody>
{LOOP}
<tr>
<td><a href="{ROOT_URL}admin/reviews/reviewView/{ID}" class="btn btn-sm btn-primary" role="button">{title}</a></td>
<td align="center">{rating}</td>
<td><a href="{ROOT_URL}admin/reviews/reviewEdit/{ID}" class="btn btn-sm btn-info" role="button"><i class="fa fa-fw fa-pencil"></i></a></td>
<td><a href="{ROOT_URL}admin/reviews/reviewDelete/{ID}" class="btn btn-sm btn-danger" role="button"><i class="fa fa-fw fa-trash"></i></a></td>
<td><a href="{ROOT_URL}reviews/view/{ID}" class="text-decoration-none atb-green" role="button">{title}</a></td>
<td>{rating}</td>
<td><a href="{ROOT_URL}reviews/edit/{ID}" class="btn btn-sm btn-warning" role="button"><i class="fa fa-fw fa-pencil"></i></a></td>
<td><a href="{ROOT_URL}reviews/delete/{ID}" class="btn btn-sm btn-danger" role="button"><i class="fa fa-fw fa-trash"></i></a></td>
</tr>
{/LOOP}
{ALT}
<tr>
<td align="center" colspan="6">
<td colspan="4">
No results to show.
</td>
</tr>
{/ALT}
</tbody>
</table>
<a href="{ROOT_URL}reviews/review" class="btn btn-md atb-green-bg" role="button">Add Review</a>
</div>

View File

@ -0,0 +1,47 @@
<div class="container py-4">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card shadow">
<!-- Card Header -->
<div class="card-header text-center bg-dark text-white">
<h3 class="card-title mb-0">Review: {title}</h3>
</div>
<!-- Card Body -->
<div class="card-body">
<div class="row align-items-center">
<!-- Details -->
<table class="table table-borderless">
<tbody>
<tr>
<th scope="row">Title:</th>
<td>{title}</td>
</tr>
<tr>
<th scope="row">Rating:</th>
<td>{rating}</td>
</tr>
<tr>
<th scope="row">Created:</th>
<td>{DTC}{createdAt}{/DTC}</td>
</tr>
<tr>
<th scope="row" colspan="2">Review:</th>
</tr>
<tr>
<td colspan="2">{review}</td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- Admin Controls -->
<div class="card-footer text-center">
<a href="{ROOT_URL}reviews/edit/{ID}" class="btn btn-sm btn-warning" role="button"><i class="fa fa-fw fa-pencil"></i></a>
<a href="{ROOT_URL}reviews/delete/{ID}" class="btn btn-sm btn-danger" role="button"><i class="fa fa-fw fa-trash"></i></a>
</div>
</div>
</div>
</div>
</div>

View File

@ -41,7 +41,7 @@
<!-- Submit Button -->
<div class="text-center">
<button type="submit" name="submit" value="submit" class="btn btn-primary btn-lg">Create</button>
<button type="submit" name="submit" value="submit" class="btn btn-primary btn-lg">Save</button>
</div>
</fieldset>
</form>

View File

@ -41,8 +41,6 @@ class DefaultLoader extends Loader {
Components::set( 'JQUERY_CDN', self::JQUERY_CDN );
Components::set( 'FONT_AWESOME_URL', self::FONT_AWESOME_URL );
}
$this->addCss( '<link rel="stylesheet" href="{ROOT_URL}app/css/main.css">' );
$this->addCss( '<link rel="stylesheet" href="{ROOT_URL}app/css/main-dark.css" id="dark-mode-stylesheet" disabled>' );
$this->addJs( '<script language="JavaScript" crossorigin="anonymous" type="text/javascript" src="{ROOT_URL}app/js/main.js"></script>' );
Components::setIfNull( 'LOGO', Config::getValue( 'main/logo' ) ?? TP_DEFAULT_LOGO );
Components::setIfNull( 'COPY', Views::simpleView( 'footer.copy') );
@ -55,12 +53,21 @@ class DefaultLoader extends Loader {
* Top-Nav
*/
if ( App::$isLoggedIn ) {
if ( ! empty( App::$activePrefs['darkMode'] ) ) {
$this->addCss( '<link rel="stylesheet" href="{ROOT_URL}app/css/main.css">' );
$this->addCss( '<link rel="stylesheet" href="{ROOT_URL}app/css/main-dark.css" id="dark-mode-stylesheet">' );
} else {
$this->addCss( '<link rel="stylesheet" href="{ROOT_URL}app/css/main.css">' );
$this->addCss( '<link rel="stylesheet" href="{ROOT_URL}app/css/main-dark.css" id="dark-mode-stylesheet" disabled>' );
}
Components::set( 'topNavRightDropdown', Template::parse( App::$topNavRightDropdown ) );
Components::set( 'STATUS', Views::simpleView( 'nav.statusLoggedIn' ) );
Components::set( 'USERNAME', \ucfirst( App::$activeUser->username ) );
Components::set( 'AVATAR', App::$activeUser->avatar );
} else {
Components::set( 'STATUS', Views::simpleView( 'nav.statusLoggedOut' ) );
$this->addCss( '<link rel="stylesheet" href="{ROOT_URL}app/css/main.css">' );
$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( 'topNavLeft', Views::simpleView( 'nav.main', Navigation::getMenuLinks( App::MAIN_MENU_NAME ) ) );

View File

@ -46,7 +46,7 @@
<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">Terms of Service</a>
I have read and agree to the <a href="/home/terms" class="text-decoration-none atb-green">Terms of Service</a>
</label>
</div>
<div class="terms mt-2 mx-auto">
@ -59,7 +59,7 @@
<!-- Submit Button -->
<div class="text-center">
<button type="submit" name="submit" value="submit" class="btn btn-primary btn-lg">Sign up</button>
<button type="submit" name="submit" value="submit" class="btn atb-green-bg btn-lg">Sign up</button>
</div>
</fieldset>
</form>