changed dir structure to handle second version of the book

This commit is contained in:
2022-11-25 11:46:00 +01:00
parent b6fd7876d3
commit 5f1f5e847d
35 changed files with 7 additions and 0 deletions

13
Vanilla/public/.htaccess Normal file
View File

@@ -0,0 +1,13 @@
DirectoryIndex index.php
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI}::$0 ^(/.+)/(.*)::\2$
RewriteRule .* - [E=BASE:%1]
RewriteCond %{HTTP:Authorization} .+
RewriteRule ^ - [E=HTTP_AUTHORIZATION:%0]
RewriteCond %{ENV:REDIRECT_STATUS} =""
RewriteRule ^index\.php(?:/(.*)|$) %{ENV:BASE}/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ %{ENV:BASE}/index.php [L]
</IfModule>

View File

@@ -0,0 +1,206 @@
/*
* Copyright (c) 2022. Micha Espey <tracer@24unix.net>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
*/
function addAddress(url) {
location.href = url
}
function editAddress(id) {
if (document.getElementById('edit_button_' + id).value === 'Save') {
// save
const url = "/address/update";
fetch(url, {
method: "POST",
body: JSON.stringify({
id: id,
owner: document.getElementById('owner_' + id).value,
first: document.getElementById('first_' + id).value,
last: document.getElementById('last_' + id).value,
street: document.getElementById('street_' + id).value,
zip: document.getElementById('zip_' + id).value,
city: document.getElementById('city_' + id).value,
phone: document.getElementById('phone_' + id).value,
})
})
.then(
response => response.text()
).then(
json => {
let jsonObject = JSON.parse(json)
if (jsonObject.status === 200) {
setInfo('Data successfully saved.')
} else {
setError(jsonObject.message);
}
}
);
document.getElementById('first_' + id).disabled = true
document.getElementById('last_' + id).disabled = true
document.getElementById('street_' + id).disabled = true
document.getElementById('zip_' + id).disabled = true
document.getElementById('city_' + id).disabled = true
document.getElementById('phone_' + id).disabled = true
document.getElementById('edit_button_' + id).value = 'Edit'
} else {
//switch to edit
document.getElementById('first_' + id).disabled = false
document.getElementById('last_' + id).disabled = false
document.getElementById('street_' + id).disabled = false
document.getElementById('zip_' + id).disabled = false
document.getElementById('city_' + id).disabled = false
document.getElementById('phone_' + id).disabled = false
document.getElementById('edit_button_' + id).value = 'Save'
}
}
function deleteAddress(id) {
if (confirm('Are you sure?')) {
const url = "/address/delete";
fetch(url, {
method: "POST",
body: JSON.stringify({
id: id
})
})
.then(
response => response.text()
).then(
json => {
let jsonObject = JSON.parse(json)
if (jsonObject.status === 200) {
setInfo('Data successfully saved.')
} else {
setError(jsonObject.message);
}
}
);
let row = document.getElementById('row_' + id)
row.parentNode.removeChild(row)
}
}
function upCase(text) {
return text[0].toUpperCase() + text.substring(1);
}
function sortBy(column) {
// clear titles
const titles = ['first', 'last', 'street', 'zip', 'city', 'phone']
titles.forEach((title) =>
document.getElementById(title).innerHTML = upCase(title)
)
console.log("col", column)
console.log("curcol", currentColumn)
if (currentColumn === column) {
console.log("in switch")
// switch direction on every call on same column
if (currentSortOrder === 'asc') {
currentSortOrder = 'desc'
} else {
currentSortOrder = 'asc'
}
console.log("col", column)
} else {
currentColumn = column
}
let currentTitleElement = document.getElementById(column)
let currentTitle = currentTitleElement.innerHTML
let newTitle
if (currentSortOrder === 'asc') {
newTitle = currentTitle[0] + currentTitle.substring(1) + '&nbsp;&#11015;'
} else {
newTitle = currentTitle[0] + currentTitle.substring(1) + '&nbsp;&#11014;'
}
currentTitleElement.innerHTML = newTitle
const table = document.getElementById('address_table');
let dirty = true;
// loop until clean
while (dirty) {
// assume we are finished
dirty = false
const rows = table.rows;
for (let i = 1; i < (rows.length - 2); i++) {
let x = rows[i]
let rowXId = x.id
let rowXNumber = rowXId.match(/\d+/)
let valueX = document.getElementById(column + '_' + rowXNumber).value
let y = rows[i + 1]
let rowYId = y.id
let rowYNumber = rowYId.match(/\d+/)
let valueY = document.getElementById(column + '_' + rowYNumber).value
let sortOrder
if (currentSortOrder === 'asc') {
sortOrder = 1
} else {
sortOrder = -1
}
if (valueX.localeCompare(valueY) === sortOrder) {
x.parentNode.insertBefore(y, x);
dirty = true
}
}
}
}
function setInfo(info) {
const infoBox = document.getElementById('info_box')
infoBox.innerHTML = info
infoBox.style.display = 'block'
infoBox.classList.add('panel_float')
setTimeout(() => {
infoBox.style.display = 'none'
}, 2500)
}
function setError(error) {
const errorBox = document.getElementById('error_box')
const errorText = document.getElementById('error_text')
const infoButton = document.getElementById('info_button')
if (errorBox.style.display === 'block') {
errorBox.style.display = 'none'
return
}
if (infoButton != null) {
infoButton.disabled = true
}
errorText.innerHTML = error
errorBox.style.display = 'block'
errorBox.classList.add('panel_float')
}
function closeError() {
const errorBox = document.getElementById('error_box')
const infoButton = document.getElementById('info_button')
if (infoButton) {
infoButton.disabled = false
}
errorBox.style.display = 'none'
}
// global scope
let currentSortOrder = 'desc'
let currentColumn = 'last'
document.addEventListener('DOMContentLoaded', () => {
const table = document.getElementById('address_table') || false
if (table) {
sortBy('last')
}
})

View File

@@ -0,0 +1,127 @@
body {
background: #1f1f1f;
color: #cdcdcd;
}
/* unvisited link */
a:link {
color: #ff8844;
text-decoration: none;
}
/* visited link */
a:visited {
color: #ff8844;
text-decoration: none;
}
/* mouse over link */
a:hover {
color: #ff8844;
text-decoration: none;
}
/* selected link */
a:active {
color: #ff8844;
text-decoration: none;
font-weight: bold;
}
table, th, td {
border: 1px solid;
}
label {
display: block;
padding: 1ex;
}
.panel_float {
position: fixed;
overflow: hidden;
z-index: 2400;
opacity: 0.70;
margin: auto;
top: 110px !important;
-webkit-transition: all 0.5s ease-in-out;
-moz-transition: all 0.5s ease-in-out;
-ms-transition: all 0.5s ease-in-out;
-o-transition: all 0.5s ease-in-out;
transition: all 0.5s ease-in-out;
}
#info_box {
background-color: #3fc52a;
border: solid #cdcdcd;
border-radius: 5px;
color: #1f1f1f;
display: none;
padding: 10px;
font-weight: bold;
position: absolute;
z-index: 10;
width: 50%;
margin-left: 200px;
margin-right: 200px;
}
.info_button {
border-radius: 5px;
border: solid #cdcdcd;
color: #1f1f1f;
padding: 8px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px;
background-color: #3fc52a;
transition-duration: 0.4s;
cursor: pointer;
}
#error_box {
background-color: #e06844;
border: solid #cdcdcd;
border-radius: 5px;
color: #1f1f1f;
display: none;
padding: 10px;
font-weight: bold;
position: absolute;
z-index: 10;
width: 50%;
margin-left: 200px;
margin-right: 200px;
}
.error_button {
border-radius: 5px;
border: solid #cdcdcd;
color: #1f1f1f;
padding: 8px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px;
background-color: #e06844;
transition-duration: 0.4s;
cursor: pointer;
}
.close_button {
margin-left: 15px;
color: white;
font-weight: bold;
float: right;
font-size: 22px;
line-height: 20px;
cursor: pointer;
transition: 0.3s;
}
.close_button:hover {
color: black;
}

80
Vanilla/public/index.php Normal file
View File

@@ -0,0 +1,80 @@
<?php
/*
* Copyright (c) 2022. Micha Espey <tracer@24unix.net>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
*/
ini_set(option: 'display_errors', value: 1);
ini_set(option: 'display_startup_errors', value: 1);
// no one sane should ignore deprecations
error_reporting(error_level: E_ALL);
// just during dev
opcache_reset();
session_start();
require dirname(path: __DIR__) . '/src/bootstrap.php';
use App\Controller\AddressBookAdminController;
use App\Controller\AddressBookController;
use App\Controller\SecurityController;
use App\Service\Container;
use App\Service\Router;
$container = new Container();
$router = $container->get(className: Router::class);
$security = $container->get(className: SecurityController::class);
$addressBook = $container->get(className: AddressBookController::class);
$addressBookAdmin = $container->get(className: AddressBookAdminController::class);
$router->addRoute(name: 'app_login', route: '/login', callback: function () use ($security) {
$security->login();
});
$router->addRoute(name: 'app_logout', route: '/logout', callback: function () use ($security) {
$security->logout();
});
$router->addRoute(name: 'app_main', route: '/', callback: function () use ($addressBook) {
$addressBook->main();
});
$router->addRoute(name: 'app_admin', route: '/admin', callback: function () use ($addressBookAdmin) {
$addressBookAdmin->admin();
});
$router->addRoute(name: 'app_admin_users', route: '/admin/users', callback: function () use ($addressBookAdmin) {
$addressBookAdmin->adminUser();
});
$router->addRoute(name: 'app_admin_users_edit', route: '/admin/users/{nick}', callback: function (array $parameters) use ($addressBookAdmin) {
$addressBookAdmin->adminUserEdit(parameters: $parameters);
});
$router->addRoute(name: 'app_admin_users_add', route: '/admin/users/add', callback: function () use ($addressBookAdmin) {
$addressBookAdmin->adminUserAdd();
});
$router->addRoute(name: 'app_admin_users_delete', route: '/admin/users/delete/{nick}', callback: function (array $parameters) use ($addressBookAdmin) {
$addressBookAdmin->adminUserDelete(parameters: $parameters);
});
$router->addRoute(name: 'address_add', route: '/address/add', callback: function () use ($addressBook) {
$addressBook->addAddress();
});
$router->addRoute(name: 'address_add', route: '/address/update', callback: function () use ($addressBook) {
$addressBook->updateAddress();
});
$router->addRoute(name: 'address_add', route: '/address/delete', callback: function () use ($addressBook) {
$addressBook->deleteAddress();
});
$router->handleRouting();