diff --git a/database/auth.db b/database/auth.db index 26b28c4..b9667c8 100644 Binary files a/database/auth.db and b/database/auth.db differ diff --git a/database/live.db b/database/live.db index dcc54c5..d7abbac 100644 Binary files a/database/live.db and b/database/live.db differ diff --git a/public/assets/css/dragon.css b/public/assets/css/dragon.css index 45fd73d..1d2907c 100644 --- a/public/assets/css/dragon.css +++ b/public/assets/css/dragon.css @@ -1,5 +1,9 @@ @import '/assets/css/forms.css'; +:root { + font-size: 16px; +} + * { margin: 0; padding: 0; @@ -115,42 +119,155 @@ header { main { padding: 1rem; - display: grid; - grid-template-columns: 1fr 8fr 1fr; + width: 100%; + display: flex; gap: 2rem; + + #center { + flex: 1; + } } -aside#left { +aside { + min-width: 200px; + .box { background-color: rgba(0, 0, 0, 0.2); border-radius: 0.15rem; + } +} - nav > a { - display: block; - width: 100%; +aside#left nav { + & > *:not(:last-child) { + margin-bottom: 0.25rem; + } + + div.stack { + background-color: rgba(0, 0, 0, 0.2); + border-radius: 0.15rem; + + input[type="checkbox"] { + display: none; + + &:checked ~ div.list { + display: block; + } + + &:checked + label { + background-color: rgba(0, 0, 0, 0.5); + color: white; + } + } + + label { + display: flex; + align-items: center; padding: 0.5rem 1rem; border-radius: 0.15rem; text-decoration: none; color: black; transition: color, background-color 0.2s ease; + cursor: pointer; - &:hover, &.active { - color: white; + img { + height: 18px; + margin-right: 0.25rem; + } + + span.text { + display: block; + width: 100%; } &:hover { + color: white; background-color: rgba(0, 0, 0, 0.3); } - &.active { - background-color: #444c55; - color: #ffffff; - background-image: linear-gradient(rgba(255, 255, 255, 0.15), rgba(0, 0, 0, 0.1)); - border: 1px solid; - border-color: #3D444C #2F353B #2C3137; - box-shadow: 0px 1px 0px 0px rgba(255, 255, 255, 0.2) inset; + span.arrow { + position: relative; + top: 5px; } } + + div.list { + display: none; + + & > a { + display: block; + width: 100%; + padding: 0.5rem 1rem 0.5rem 1.35rem; + border-radius: 0.15rem; + text-decoration: none; + color: black; + transition: color, background-color 0.2s ease; + + &:not(:last-child)::before { + content: '├'; + display: inline-block; + margin-right: 0.25rem; + } + + &:last-child::before { + content: '└'; + display: inline-block; + position: relative; + top: 3px; + margin-right: 0.25rem; + } + + &:hover { + background-color: rgba(0, 0, 0, 0.3); + } + + &.active { + background-color: #444c55; + color: #ffffff; + background-image: linear-gradient(rgba(255, 255, 255, 0.15), rgba(0, 0, 0, 0.1)); + border: 1px solid; + border-color: #3D444C #2F353B #2C3137; + box-shadow: 0px 1px 0px 0px rgba(255, 255, 255, 0.2) inset; + } + } + } + } + + & > a { + display: block; + width: 100%; + padding: 0.5rem 1rem; + text-decoration: none; + color: black; + transition: color, background-color 0.2s ease; + background-color: rgba(0, 0, 0, 0.2); + border-radius: 0.15rem; + + &:has(img) { + display: flex; + align-items: center; + + img { + height: 18px; + margin-right: 0.25rem; + } + } + + &:hover, &.active { + color: white; + } + + &:hover { + background-color: rgba(0, 0, 0, 0.3); + } + + &.active { + background-color: #444c55; + color: #ffffff; + background-image: linear-gradient(rgba(255, 255, 255, 0.15), rgba(0, 0, 0, 0.1)); + border: 1px solid; + border-color: #3D444C #2F353B #2C3137; + box-shadow: 0px 1px 0px 0px rgba(255, 255, 255, 0.2) inset; + } } } @@ -171,19 +288,26 @@ footer { #char-bar { display: flex; align-items: center; + justify-content: space-around; padding: 0 1rem; height: 34px; color: white; gap: 1rem; background-image: url('/assets/img/bar.jpg'); - & > div { + & > div.container { display: flex; align-items: center; + gap: 1rem; - .icon { - width: 18px; - margin-right: 0.5rem; + & > div { + display: flex; + align-items: center; + + .icon { + width: 18px; + margin-right: 0.5rem; + } } } } @@ -325,6 +449,9 @@ h1:has(.badge), h2:has(.badge), h3:has(.badge), h4:has(.badge), h5:has(.badge), transition: opacity .1s ease, color .1s ease, background .1s ease, box-shadow .1s ease; border-radius: .28571429rem; box-shadow: 0 0 0 1px rgba(34, 36, 38, .22) inset, 0 0 0 0 transparent; + display: flex; + align-items: center; + justify-content: space-between; &.success { background-color: #f0f9eb; @@ -355,6 +482,13 @@ h1:has(.badge), h2:has(.badge), h3:has(.badge), h4:has(.badge), h5:has(.badge), color: #2c2c2c; border-color: #b3b3b3; } + + a[alert-close] { + text-decoration: none; + cursor: pointer; + font-size: 2rem; + color: inherit; + } } a { @@ -367,3 +501,19 @@ a { text-decoration: underline; } } + +body::-webkit-scrollbar { + width: 0.5rem; +} + +body::-webkit-scrollbar-track { + background: rgba(0, 0, 0, 0.1); +} + +body::-webkit-scrollbar-thumb { + background-color: #444c55; + background-image: linear-gradient(rgba(255, 255, 255, 0.15), rgba(0, 0, 0, 0.1)); + border: 1px solid; + border-color: #3D444C #2F353B #2C3137; + box-shadow: 0px 1px 0px 0px rgba(255, 255, 255, 0.2) inset; +} diff --git a/public/assets/css/forms.css b/public/assets/css/forms.css index 8e2754e..5b77591 100644 --- a/public/assets/css/forms.css +++ b/public/assets/css/forms.css @@ -52,9 +52,14 @@ } .character-select > .radio-block { + display: inline-block; background-color: rgba(0, 0, 0, 0.2); border-radius: 0.15rem; + &:not(:last-child) { + margin-bottom: 0.25rem; + } + & > input[type="radio"] { display: none; } @@ -81,7 +86,7 @@ & > span.selected { display: none; - margin-left: auto; + margin-left: 1rem; color: #a6e3a1; } } diff --git a/public/assets/img/icons/earth.png b/public/assets/img/icons/earth.png new file mode 100644 index 0000000..ac09f83 Binary files /dev/null and b/public/assets/img/icons/earth.png differ diff --git a/public/assets/img/icons/home.png b/public/assets/img/icons/home.png new file mode 100644 index 0000000..757d5c1 Binary files /dev/null and b/public/assets/img/icons/home.png differ diff --git a/public/assets/img/icons/map.png b/public/assets/img/icons/map.png new file mode 100644 index 0000000..36ba484 Binary files /dev/null and b/public/assets/img/icons/map.png differ diff --git a/public/assets/img/icons/settings.png b/public/assets/img/icons/settings.png new file mode 100644 index 0000000..83ce6c1 Binary files /dev/null and b/public/assets/img/icons/settings.png differ diff --git a/public/assets/img/icons/shop.png b/public/assets/img/icons/shop.png new file mode 100644 index 0000000..865433e Binary files /dev/null and b/public/assets/img/icons/shop.png differ diff --git a/public/assets/img/icons/world.png b/public/assets/img/icons/world.png new file mode 100644 index 0000000..b1e9096 Binary files /dev/null and b/public/assets/img/icons/world.png differ diff --git a/public/index.php b/public/index.php index 86cc759..2cb16a1 100644 --- a/public/index.php +++ b/public/index.php @@ -13,7 +13,8 @@ $r = []; */ router_get($r, '/', function () { if (user()) must_have_character(); - echo render('layouts/basic', ['view' => 'pages/home', 'activeTab' => nav_tabs['home']]); + $GLOBALS['active_nav_tab'] = 'home'; + echo render('layouts/basic', ['view' => 'pages/home']); }); /* @@ -34,6 +35,15 @@ router_get($r, '/character/create-first', 'char_controller_create_first_get'); router_post($r, '/character/create', 'char_controller_create_post'); router_post($r, '/character/delete', 'char_controller_delete_post'); +/* + World +*/ +router_get($r, '/world', function () { + auth_only_and_must_have_character(); + $GLOBALS['active_nav_tab'] = 'world'; + echo page('world/base'); +}); + /* Router */ @@ -42,8 +52,10 @@ stopwatch_start('router'); $l = router_lookup($r, $_SERVER['REQUEST_METHOD'], $_SERVER['REQUEST_URI']); stopwatch_stop('router'); +stopwatch_start('handler'); if ($l['code'] !== 200) router_error($l['code']); $l['handler'](...$l['params'] ?? []); +stopwatch_stop('handler'); /* Cleanup diff --git a/src/components.php b/src/components.php index 41e64e8..8c3db88 100644 --- a/src/components.php +++ b/src/components.php @@ -1,10 +1,5 @@ 0, - 'chars' => 1, -]; - /** * Render the logout button's form. */ @@ -29,13 +24,7 @@ function c_char_bar() */ function c_left_nav() { - $tab = match ($GLOBALS['active_nav_tab'] ?? '') { - 'home' => 0, - 'chars' => 1, - default => 0 - }; - - return render('components/left_nav', ['ant' => $tab]); + return render('components/left_nav'); } /** @@ -57,9 +46,10 @@ function c_char_select_box($id, $char) /** * Render an alert with a given type and message. */ -function c_alert($t, $m) +function c_alert($type, $message) { - return "
$message
"; + if (!empty($field)) + foreach ($field as $message) $html .= !empty($message) ? "$message
" : ''; return c_alert('danger', $html); } diff --git a/src/controllers/char.php b/src/controllers/char.php index b9e5e2e..a957cdf 100644 --- a/src/controllers/char.php +++ b/src/controllers/char.php @@ -48,7 +48,7 @@ function char_controller_list_post() change_user_character($char_id); - flash('alert_character_list_1', ['success', 'Switched to character ' . char('name') . '!']); + flash('alert_character_list_1', ['success', 'Switched to ' . char('name') . '!']); } // If the action is to delete a character, move to the confirmation page. diff --git a/src/helpers.php b/src/helpers.php index 06b3fa7..cda8959 100644 --- a/src/helpers.php +++ b/src/helpers.php @@ -223,3 +223,11 @@ function stopwatch_get($key) if (empty($GLOBALS['stopwatch'][$key])) return 0; return number_format($GLOBALS['stopwatch'][$key], 10); } + +/** + * Conditional Echo; if the condition is true, echo the value. If the condition is false, echo the $or value. + */ +function ce($condition, $value, $or = '') +{ + echo $condition ? $value : $or; +} diff --git a/templates/components/char_bar.php b/templates/components/char_bar.php index b826f44..2ec5199 100644 --- a/templates/components/char_bar.php +++ b/templates/components/char_bar.php @@ -1,34 +1,36 @@Page execution took = number_format((microtime(true) - START_TIME), 10) ?> seconds.
Bootstrap: = stopwatch_get('bootstrap') ?> seconds
Router: = stopwatch_get('router') ?> seconds
+Handler: = stopwatch_get('handler') ?> seconds