Merge branch 'redesign-profile-page' into develop

This commit is contained in:
Jay Trees 2022-04-07 10:32:00 +02:00
commit db9a10b1cb
18 changed files with 2477 additions and 96 deletions

View file

@ -6,7 +6,7 @@
* @author Jay Trees <github.jay@grandel.anonaddy.me>
*/
define('VERSION', '0.4.0');
define('VERSION', '0.5.0');
define('ROOT', __DIR__);
define('DEFAULT_LOCALE', 'en_GB');

View file

@ -51,6 +51,7 @@
"popup",
"message",
"list",
"tab",
"api",
"transition"

View file

@ -1969,6 +1969,11 @@ Floated Menu / Item
border-top: 1px solid #D4D4D5;
border-right: 1px solid #D4D4D5;
}
@media only screen and (max-width: 767.98px) {
.stackable .ui.vertical.pointing.menu .item::after {
display: none;
}
}
.ui.pointing.menu .ui.dropdown .menu .item:after,
.ui.vertical.pointing.menu .ui.dropdown .menu .item:after {
display: none;

File diff suppressed because one or more lines are too long

88
semantic/dist/components/tab.css vendored Normal file
View file

@ -0,0 +1,88 @@
/*!
* # Fomantic-UI 2.8.8 - Tab
* http://github.com/fomantic/Fomantic-UI/
*
*
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
*/
/*******************************
UI Tabs
*******************************/
.ui.tab {
display: none;
}
/*******************************
States
*******************************/
/*--------------------
Active
---------------------*/
.ui.tab.active,
.ui.tab.open {
display: block;
}
/*--------------------
Loading
---------------------*/
.ui.tab.loading {
position: relative;
overflow: hidden;
display: block;
min-height: 250px;
}
.ui.tab.loading * {
position: relative !important;
left: -10000px !important;
}
.ui.tab.loading:before,
.ui.tab.loading.segment:before {
position: absolute;
content: '';
top: 50%;
left: 50%;
margin: -1.25em 0 0 -1.25em;
width: 2.5em;
height: 2.5em;
border-radius: 500rem;
border: 0.2em solid rgba(0, 0, 0, 0.1);
}
.ui.tab.loading:after,
.ui.tab.loading.segment:after {
position: absolute;
content: '';
top: 50%;
left: 50%;
margin: -1.25em 0 0 -1.25em;
width: 2.5em;
height: 2.5em;
-webkit-animation: loader 0.6s infinite linear;
animation: loader 0.6s infinite linear;
border: 0.2em solid #767676;
border-radius: 500rem;
-webkit-box-shadow: 0 0 0 1px transparent;
box-shadow: 0 0 0 1px transparent;
}
/*******************************
Tab Overrides
*******************************/
/*******************************
User Overrides
*******************************/

1001
semantic/dist/components/tab.js vendored Normal file

File diff suppressed because it is too large Load diff

9
semantic/dist/components/tab.min.css vendored Normal file
View file

@ -0,0 +1,9 @@
/*!
* # Fomantic-UI 2.8.8 - Tab
* http://github.com/fomantic/Fomantic-UI/
*
*
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
*/.ui.tab{display:none}.ui.tab.active,.ui.tab.open{display:block}.ui.tab.loading{position:relative;overflow:hidden;display:block;min-height:250px}.ui.tab.loading *{position:relative!important;left:-10000px!important}.ui.tab.loading.segment:before,.ui.tab.loading:before{position:absolute;content:'';top:50%;left:50%;margin:-1.25em 0 0 -1.25em;width:2.5em;height:2.5em;border-radius:500rem;border:.2em solid rgba(0,0,0,.1)}.ui.tab.loading.segment:after,.ui.tab.loading:after{position:absolute;content:'';top:50%;left:50%;margin:-1.25em 0 0 -1.25em;width:2.5em;height:2.5em;-webkit-animation:loader .6s infinite linear;animation:loader .6s infinite linear;border:.2em solid #767676;border-radius:500rem;-webkit-box-shadow:0 0 0 1px transparent;box-shadow:0 0 0 1px transparent}

11
semantic/dist/components/tab.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -38184,6 +38184,12 @@ Floated Menu / Item
border-right: 1px solid #D4D4D5;
}
@media only screen and (max-width: 767.98px) {
.stackable .ui.vertical.pointing.menu .item::after {
display: none;
}
}
.ui.pointing.menu .ui.dropdown .menu .item:after,
.ui.vertical.pointing.menu .ui.dropdown .menu .item:after {
display: none;
@ -40404,6 +40410,90 @@ Floated Menu / Item
/*******************************
Site Overrides
*******************************/
/*!
* # Fomantic-UI 2.8.8 - Tab
* http://github.com/fomantic/Fomantic-UI/
*
*
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
*/
/*******************************
UI Tabs
*******************************/
.ui.tab {
display: none;
}
/*******************************
States
*******************************/
/*--------------------
Active
---------------------*/
.ui.tab.active,
.ui.tab.open {
display: block;
}
/*--------------------
Loading
---------------------*/
.ui.tab.loading {
position: relative;
overflow: hidden;
display: block;
min-height: 250px;
}
.ui.tab.loading * {
position: relative !important;
left: -10000px !important;
}
.ui.tab.loading:before,
.ui.tab.loading.segment:before {
position: absolute;
content: '';
top: 50%;
left: 50%;
margin: -1.25em 0 0 -1.25em;
width: 2.5em;
height: 2.5em;
border-radius: 500rem;
border: 0.2em solid rgba(0, 0, 0, 0.1);
}
.ui.tab.loading:after,
.ui.tab.loading.segment:after {
position: absolute;
content: '';
top: 50%;
left: 50%;
margin: -1.25em 0 0 -1.25em;
width: 2.5em;
height: 2.5em;
-webkit-animation: loader 0.6s infinite linear;
animation: loader 0.6s infinite linear;
border: 0.2em solid #767676;
border-radius: 500rem;
-webkit-box-shadow: 0 0 0 1px transparent;
box-shadow: 0 0 0 1px transparent;
}
/*******************************
Tab Overrides
*******************************/
/*******************************
User Overrides
*******************************/
/*!
* # Fomantic-UI 2.8.8 - Transition
* http://github.com/fomantic/Fomantic-UI/

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1757,6 +1757,11 @@ each(@colors, {
border-top: @arrowBorder;
border-right: @arrowBorder;
}
@media only screen and (max-width: @largestMobileScreen) {
.stackable .ui.vertical.pointing.menu .item::after {
display: none;
}
}
}
.ui.pointing.menu .ui.dropdown .menu .item:after,
.ui.vertical.pointing.menu .ui.dropdown .menu .item:after {

View file

@ -1,4 +1,6 @@
$(function() {
$('.menu.profile .item').tab();
$('.ui.calendar').calendar({
type : 'date',
firstDayOfWeek : 1,

View file

@ -133,7 +133,10 @@ switch ($step) {
`last_login` DATETIME NOT NULL DEFAULT NOW(),
`power` INT NOT NULL DEFAULT 0,
`birthdate` DATE NULL DEFAULT NULL,
`locale` VARCHAR(5) NOT NULL DEFAULT "' . DEFAULT_LOCALE . '"
`locale` VARCHAR(5) NOT NULL DEFAULT "' . DEFAULT_LOCALE . '",
`name_first` VARCHAR(32) NULL DEFAULT NULL,
`name_last` VARCHAR(32) NULL DEFAULT NULL,
`name_nick` VARCHAR(32) NULL DEFAULT NULL
);');
$database->query('CREATE INDEX `idx_password` ON `users` (`password`);');

View file

@ -8,49 +8,96 @@
use wishthis\{Page, User};
if (isset($_POST['user-id'])) {
$set = array();
$page = new Page(__FILE__, __('Profile'));
$loginRequired = false;
if (isset($_POST['user-id'], $_POST['section'])) {
$set = array();
$formFieldsString = array(
array(
'column' => 'name_first',
'key' => 'user-name-first',
'label' => __('First name'),
),
array(
'column' => 'name_last',
'key' => 'user-name-last',
'label' => __('Last name'),
),
array(
'column' => 'name_nick',
'key' => 'user-name-nick',
'label' => __('Nickname'),
),
array(
'column' => 'email',
'key' => 'user-email',
'label' => __('Email'),
),
array(
'column' => 'locale',
'key' => 'user-locale',
'label' => __('Language'),
),
);
$loginRequired = false;
if (!empty($_POST['user-email'])) {
$set[] = '`email` = "' . $_POST['user-email'] . '"';
foreach ($formFieldsString as $field) {
if (!empty($_POST[$field['key']]) && $_POST[$field['key']] !== $user->{$field['column']}) {
$set[] = '`' . $field['column'] . '` = "' . $_POST[$field['key']] . '"';
$user->{$field['column']} = $_POST[$field['key']];
$page->messages[] = Page::success(
sprintf(
__('%s successfully updated!'),
'<strong>' . $field['label'] . '</strong>'
),
__('Success')
);
}
}
if (!empty($_POST['user-password']) && !empty($_POST['user-password-repeat'])) {
if (!empty($_POST['user-email']) && $_POST['user-email'] !== $user->email) {
$loginRequired = true;
}
if (isset($_POST['user-birthdate'])) {
if (empty($_POST['user-birthdate'])) {
$user->birthdate = null;
$set[] = '`birthdate` = NULL';
} else {
$user->birthdate = date('Y-m-d', strtotime($_POST['user-birthdate']));
$set[] = '`birthdate` = "' . $user->birthdate . '"';
}
}
if (
!empty($_POST['user-password'])
&& !empty($_POST['user-password-repeat'])
&& $_POST['user-password'] === $_POST['user-password-repeat']
) {
$set[] = '`password` = "' . User::generatePassword($_POST['user-password']) . '"';
$loginRequired = true;
}
if ($_POST['user-birthdate']) {
$user->birthdate = date('Y-m-d', strtotime($_POST['user-birthdate']));
$set[] = '`birthdate` = "' . $user->birthdate . '"';
} else {
$user->birthdate = null;
$set[] = '`birthdate` = NULL';
}
$set[] = '`locale` = "' . $_POST['user-locale'] . '"';
$database
->query('UPDATE `users`
SET ' . implode(',', $set) . '
WHERE `id` = ' . $_POST['user-id']);
if ($_POST['user-email'] !== $_SESSION['user']['email']) {
$loginRequired = true;
}
if ($loginRequired) {
session_destroy();
}
redirect('/?page=profile');
$page->messages[] = Page::warning(
__('It is required for you to login again.'),
__('Success')
);
}
}
$page = new Page(__FILE__, __('Profile'));
$page->header();
$page->bodyStart();
$page->navigation();
@ -60,73 +107,162 @@ $page->navigation();
<div class="ui container">
<h1 class="ui header"><?= $page->title ?></h1>
<div class="ui segment">
<form class="ui form" method="POST">
<input type="hidden" name="user-id" value="<?= $user->id ?>" />
<?= $page->messages() ?>
<div class="field">
<label><?= __('Email') ?></label>
<input type="email" name="user-email" value="<?= $user->email ?>" />
</div>
<div class="two fields">
<div class="field">
<label><?= __('Password') ?></label>
<input type="password" name="user-password" autocomplete="new-password" />
<div class="ui stackable grid">
<div class="four wide column">
<div class="ui vertical pointing fluid menu profile">
<div class="item" data-tab="personal">
<h4 class="ui header"><?= __('Personal') ?></h4>
<p><?= __('Information regarding yourself') ?></p>
</div>
<div class="field">
<label><?= __('Password (repeat)') ?></label>
<input type="password" name="user-password-repeat" autocomplete="new-password" />
<div class="item" data-tab="password">
<h4 class="ui header"><?= __('Password') ?></h4>
<p><?= __('Change your password') ?></p>
</div>
<div class="item" data-tab="preferences">
<h4 class="ui header"><?= __('Preferences') ?></h4>
<p><?= __('Improve your withthis experience') ?></p>
</div>
</div>
</div>
<div class="two fields">
<div class="field">
<label><?= __('Birthdate') ?></label>
<div class="twelve wide stretched column">
<div class="ui tab" data-tab="personal">
<div class="ui segment">
<div class="ui calendar">
<div class="ui input left icon">
<i class="calendar icon"></i>
<input type="text"
name="user-birthdate"
placeholder="<?= __('Pick a date') ?>"
value="<?= $user->birthdate ?>"
/>
<form class="ui form" method="POST">
<input type="hidden" name="user-id" value="<?= $user->id ?>" />
<input type="hidden" name="section" value="personal" />
<div class="three fields">
<div class="field">
<label><?= __('First name') ?></label>
<input type="text" name="user-name-first" value="<?= $user->name_first ?>" />
</div>
<div class="field">
<label><?= __('Last name') ?></label>
<input type="text" name="user-name-last" value="<?= $user->name_last ?>" />
</div>
<div class="field">
<label><?= __('Nickname') ?></label>
<input type="text" name="user-name-nick" value="<?= $user->name_nick ?>" />
</div>
</div>
</div>
</div>
<div class="field">
<label><?= __('Language') ?></label>
<div class="two fields">
<div class="field">
<label><?= __('Email') ?></label>
<select class="ui search dropdown" name="user-locale">
<?php if (!in_array('en', $locales)) { ?>
<option value="<?= 'en' ?>"><?= \Locale::getDisplayName('en', $user->locale) ?></option>
<?php } ?>
<input type="email" name="user-email" value="<?= $user->email ?>" />
</div>
<div class="field">
<label><?= __('Birthdate') ?></label>
<div class="ui calendar">
<div class="ui input left icon">
<i class="calendar icon"></i>
<input type="text"
name="user-birthdate"
placeholder="<?= __('Pick a date') ?>"
value="<?= $user->birthdate ?>"
/>
</div>
</div>
</div>
</div>
<div class="ui error message"></div>
<input class="ui primary button"
type="submit"
value="<?= __('Save') ?>"
title="<?= __('Save') ?>"
/>
</form>
<?php foreach ($locales as $locale) { ?>
<?php if ($locale === $user->locale) { ?>
<option value="<?= $locale ?>" selected><?= \Locale::getDisplayName($locale, $user->locale) ?></option>
<?php } else { ?>
<option value="<?= $locale ?>"><?= \Locale::getDisplayName($locale, $user->locale) ?></option>
<?php } ?>
<?php } ?>
</select>
</div>
</div>
<div class="ui error message"></div>
<div class="ui tab" data-tab="password">
<div class="ui segment">
<input class="ui primary button"
type="submit"
value="<?= __('Save') ?>"
title="<?= __('Save') ?>"
/>
</form>
<form class="ui form" method="POST">
<input type="hidden" name="user-id" value="<?= $user->id ?>" />
<input type="hidden" name="section" value="password" />
<div class="two fields">
<div class="field">
<label><?= __('Password') ?></label>
<input type="password" name="user-password" autocomplete="new-password" />
</div>
<div class="field">
<label><?= __('Password (repeat)') ?></label>
<input type="password" name="user-password-repeat" autocomplete="new-password" />
</div>
</div>
<div class="ui error message"></div>
<input class="ui primary button"
type="submit"
value="<?= __('Save') ?>"
title="<?= __('Save') ?>"
/>
</form>
</div>
</div>
<div class="ui tab" data-tab="preferences">
<div class="ui segment">
<form class="ui form" method="POST">
<input type="hidden" name="user-id" value="<?= $user->id ?>" />
<input type="hidden" name="section" value="preferences" />
<div class="two fields">
<div class="field">
<label><?= __('Language') ?></label>
<select class="ui search dropdown" name="user-locale">
<?php if (!in_array('en', $locales)) { ?>
<option value="<?= 'en' ?>"><?= \Locale::getDisplayName('en', $user->locale) ?></option>
<?php } ?>
<?php foreach ($locales as $locale) { ?>
<?php if ($locale === $user->locale) { ?>
<option value="<?= $locale ?>" selected><?= \Locale::getDisplayName($locale, $user->locale) ?></option>
<?php } else { ?>
<option value="<?= $locale ?>"><?= \Locale::getDisplayName($locale, $user->locale) ?></option>
<?php } ?>
<?php } ?>
</select>
</div>
</div>
<div class="ui error message"></div>
<input class="ui primary button"
type="submit"
value="<?= __('Save') ?>"
title="<?= __('Save') ?>"
/>
</form>
</div>
</div>
</div>
</div>
</div>
</main>

View file

@ -8,29 +8,50 @@
use wishthis\{Page, User};
$page = new Page(__FILE__, __('Update'), 100);
/**
* Update
*/
if ('POST' === $_SERVER['REQUEST_METHOD']) {
/**
* Database
*/
$versions_directory = ROOT . '/src/update';
$versions_contents = scandir($versions_directory);
$versions = array();
/** 0.5.0 *//*
if (-1 === version_compare($options->version, '0.5.0')) {
$database->query('ALTER TABLE `users`
ADD `status` VARCHAR(32) NOT NULL AFTER `url`
;');
}*/
foreach ($versions_contents as $filename) {
$filepath = $versions_directory . '/' . $filename;
$pathinfo = pathinfo($filepath);
if ('sql' === $pathinfo['extension']) {
$versions[] = array(
'version' => str_replace('-', '.', $pathinfo['filename']),
'filepath' => $filepath,
);
}
}
foreach ($versions as $version) {
if (-1 !== version_compare(VERSION, $version['version'])) {
$sql = file_get_contents($version['filepath']);
if ($sql) {
$database->query($sql);
$page->messages[] = Page::info(
sprintf(
__('Database successfully migrated to %s.'),
'v' . $version['version']
)
);
}
}
}
/** Update version */
$options->setOption('version', VERSION);
$options->setOption('updateAvailable', false);
redirect('/?page=home');
}
$page = new Page(__FILE__, __('Update'), 100);
$page->header();
$page->bodyStart();
$page->navigation();
@ -40,6 +61,8 @@ $page->navigation();
<div class="ui container">
<h1 class="ui header"><?= $page->title ?></h1>
<?= $page->messages() ?>
<div class="ui segment">
<h2 class="ui header"><?= __('Database migration') ?></h2>
<p><?= __('Thank you for updating withthis! To complete this update, some changes are required to the database structure.') ?></p>

5
src/update/0-5-0.sql Normal file
View file

@ -0,0 +1,5 @@
ALTER TABLE `users`
ADD COLUMN `name_first` VARCHAR(32) NULL DEFAULT NULL,
ADD COLUMN `name_last` VARCHAR(32) NULL DEFAULT NULL,
ADD COLUMN `name_nick` VARCHAR(32) NULL DEFAULT NULL
;