summaryrefslogtreecommitdiff
path: root/web
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--web/_controller/_index.php23
-rw-r--r--web/_controller/apps/error.php20
-rw-r--r--web/_controller/apps/home.php (renamed from web/routes/home/controller.php)45
-rw-r--r--web/_controller/modal.php26
-rw-r--r--web/_controller/template.php22
-rw-r--r--web/_model/apps/error.php (renamed from web/routes/error/model.php)8
-rw-r--r--web/_model/apps/home.php (renamed from web/routes/home/model.php)11
-rw-r--r--web/_model/cache.php37
-rw-r--r--web/_model/format.php45
-rw-r--r--web/_model/main.php84
-rw-r--r--web/_model/request.php40
-rw-r--r--web/config/aesthetic.php (renamed from web/core/aesthetic.php)5
-rw-r--r--web/config/routes.php7
-rw-r--r--web/core/_controller.php49
-rw-r--r--web/core/_model.php44
-rw-r--r--web/core/controller.php55
-rw-r--r--web/core/database.php1
-rw-r--r--web/core/loader.php79
-rw-r--r--web/core/main.php123
-rw-r--r--web/core/model.php29
-rw-r--r--web/core/router.php192
-rw-r--r--web/helper/error.php9
-rw-r--r--web/helper/lang.php77
-rw-r--r--web/index.php116
-rw-r--r--web/lang/en_US/api_lang.php26
-rw-r--r--web/lang/en_US/apps/home.php9
-rw-r--r--web/lang/en_US/common_lang.php10
-rw-r--r--web/lang/en_US/error_lang.php2
-rw-r--r--web/lang/en_US/routes/home.php14
-rw-r--r--web/public/css/common.css57
-rw-r--r--web/public/js/lib.js66
-rw-r--r--web/public/js/routes/home.js (renamed from web/core/helper.php)0
-rw-r--r--web/public/js/shared/modal.js (renamed from web/public/js/modal.js)0
-rw-r--r--web/public/js/shared/post.js (renamed from web/public/js/post.js)2
-rw-r--r--web/routes/error/controller.php20
-rw-r--r--web/routes/error/views/error.php4
-rw-r--r--web/views/apps/error/main.php6
-rw-r--r--web/views/apps/home/main.php (renamed from web/routes/home/views/main.php)5
-rw-r--r--web/views/footer.php2
-rw-r--r--web/views/header.php14
-rw-r--r--web/views/modal/new_post.php (renamed from web/views/modal/new-post.php)24
-rw-r--r--web/views/template/comment.php2
-rw-r--r--web/views/template/error.php (renamed from web/core/error.php)0
-rw-r--r--web/views/template/modal.php2
-rw-r--r--web/views/template/pfp.php2
-rw-r--r--web/views/template/post.php2
-rw-r--r--web/views/template/toast.php19
47 files changed, 953 insertions, 482 deletions
diff --git a/web/_controller/_index.php b/web/_controller/_index.php
new file mode 100644
index 0000000..fdf9440
--- /dev/null
+++ b/web/_controller/_index.php
@@ -0,0 +1,23 @@
+<?php /* Copyright (c) 2024 Freya Murphy */
+class _index_controller extends Controller {
+
+ // the home model
+ private $home_model;
+
+ // the request model
+ private $request_model;
+
+ // the caceh model
+ private $cache_model;
+
+ public function index(): void {
+ if ($this->main->session) {
+ $this->redirect('/home');
+ } else {
+ $this->redirect('/login');
+ }
+ }
+
+}
+
+?>
diff --git a/web/_controller/apps/error.php b/web/_controller/apps/error.php
new file mode 100644
index 0000000..5ce9ec4
--- /dev/null
+++ b/web/_controller/apps/error.php
@@ -0,0 +1,20 @@
+<?php /* Copyright (c) 2024 Freya Murphy */
+class Error_controller extends Controller {
+
+ private $error_model;
+
+ function __construct($load) {
+ parent::__construct($load);
+ $this->error_model = $this->load->model('apps/error');
+ }
+
+ public function index() {
+ parent::index();
+ $data = $this->error_model->get_data();
+ $this->view('header', $data);
+ $this->view('apps/error/main', $data);
+ }
+
+}
+
+?>
diff --git a/web/routes/home/controller.php b/web/_controller/apps/home.php
index 775e43a..25c8c4e 100644
--- a/web/routes/home/controller.php
+++ b/web/_controller/apps/home.php
@@ -1,22 +1,31 @@
<?php /* Copyright (c) 2024 Freya Murphy */
-class HomeController extends Controller {
+class Home_controller extends Controller {
- private $model;
+ // the home model
+ private $home_model;
- function __construct($model) {
- parent::__construct();
- $this->model = $model;
+ // the request model
+ private $request_model;
+
+ // the caceh model
+ private $cache_model;
+
+ function __construct($load) {
+ parent::__construct($load);
+ $this->home_model = $this->load->model('apps/home');
+ $this->request_model = $this->load->model('request');
+ $this->cache_model = $this->load->model('cache');
}
- public function index() {
+ public function index(): void {
parent::index();
- $data = $this->model->get_data();
+ $data = $this->home_model->get_data();
$this->view('header', $data);
- $this->app_view('main', $data);
+ $this->view('apps/home/main', $data);
}
- public function posts() {
- $page = $this->main->get_num('page', 0);
+ public function posts(): void {
+ $page = $this->request_model->get_int('page', 0);
$page_size = 20;
$offset = $page * $page_size;
@@ -30,7 +39,7 @@ class HomeController extends Controller {
$query = $query->select('p.*, FALSE as liked');
}
- $query = $query->from('admin.post p');
+ $query = $query->from('api.post p');
if ($user) {
$query = $query->join('admin.like l', 'p.id = l.post_id')
@@ -42,7 +51,7 @@ class HomeController extends Controller {
->offset($offset)
->rows();
- $users = $this->main->get_users($posts);
+ $users = $this->cache_model->get_users($posts);
foreach ($posts as $post) {
$data = array();
@@ -52,9 +61,9 @@ class HomeController extends Controller {
}
}
- public function comments() {
- $page = $this->main->get_num('page', 0);
- $id = $this->main->get_num('id');
+ public function comments(): void {
+ $page = $this->request_model->get_int('page', 0);
+ $id = $this->request_model->get_int('id');
$page_size = 20;
$offset = $page * $page_size;
@@ -65,7 +74,7 @@ class HomeController extends Controller {
->offset($offset)
->rows();
- $users = $this->main->get_users($comments);
+ $users = $this->cache_model->get_users($comments);
foreach ($comments as $comment) {
$data = array();
@@ -75,10 +84,6 @@ class HomeController extends Controller {
}
}
- public function new_post_modal() {
- $this->modal(lang('new_post_modal_title'), 'new-post');
- }
-
}
?>
diff --git a/web/_controller/modal.php b/web/_controller/modal.php
new file mode 100644
index 0000000..9ae4ca8
--- /dev/null
+++ b/web/_controller/modal.php
@@ -0,0 +1,26 @@
+<?php /* Copyright (c) 2024 Freya Murphy */
+class Modal_controller extends Controller {
+
+
+ function __construct($load) {
+ parent::__construct($load);
+ }
+
+ /**
+ * @param string $name
+ * @param array $data
+ */
+ private function modal($name, $data = array()): void {
+ $title = lang($name . '_modal_title');
+ $data['title'] = $title;
+ $data['content'] = $name;
+ $this->view('template/modal', $data);
+ }
+
+ public function new_post(): void {
+ $this->modal('new_post');
+ }
+}
+
+?>
+
diff --git a/web/_controller/template.php b/web/_controller/template.php
new file mode 100644
index 0000000..7a8cdf8
--- /dev/null
+++ b/web/_controller/template.php
@@ -0,0 +1,22 @@
+<?php /* Copyright (c) 2024 Freya Murphy */
+class Template_controller extends Controller {
+
+ // the request model
+ private $request_model;
+
+ function __construct($load) {
+ parent::__construct($load);
+ $this->request_model = $this->load->model('request');
+ }
+
+ public function toast(): void {
+ $data = array(
+ 'msg' => $this->request_model->get_str('msg', FALSE),
+ 'detail' => $this->request_model->get_str('detail', FALSE),
+ 'hint' => $this->request_model->get_str('hint', FALSE)
+ );
+ $this->view('template/toast', $data);
+ }
+
+}
+
diff --git a/web/routes/error/model.php b/web/_model/apps/error.php
index a30fccc..ad72b28 100644
--- a/web/routes/error/model.php
+++ b/web/_model/apps/error.php
@@ -1,5 +1,9 @@
<?php /* Copyright (c) 2024 Freya Murphy */
-class ErrorModel extends Model {
+class Error_model extends Model {
+
+ function __construct($load) {
+ parent::__construct($load);
+ }
private function get_msg(&$data) {
if (!array_key_exists('code', $_GET)) {
@@ -22,7 +26,7 @@ class ErrorModel extends Model {
}
}
- public function get_data() {
+ public function get_data(): array {
$data = parent::get_data();
$this->get_msg($data);
return $data;
diff --git a/web/routes/home/model.php b/web/_model/apps/home.php
index 44a8549..82fbf26 100644
--- a/web/routes/home/model.php
+++ b/web/_model/apps/home.php
@@ -1,7 +1,11 @@
<?php /* Copyright (c) 2024 Freya Murphy */
-class HomeModel extends Model {
+class Home_model extends Model {
- private function get_posts() {
+ function __construct($load) {
+ parent::__construct($load);
+ }
+
+ private function get_posts(): array {
return $this->db
->select('*')
->from('admin.post')
@@ -9,11 +13,10 @@ class HomeModel extends Model {
->rows();
}
- public function get_data() {
+ public function get_data(): array {
$data = parent::get_data();
$data['title'] = lang('title');
$data['posts'] = $this->get_posts();
return $data;
}
}
-?>
diff --git a/web/_model/cache.php b/web/_model/cache.php
new file mode 100644
index 0000000..6cf9924
--- /dev/null
+++ b/web/_model/cache.php
@@ -0,0 +1,37 @@
+<?php /* Copyright (c) 2024 Freya Murphy */
+class Cache_model extends Model {
+
+ // the user cache
+ private $users;
+
+ function __construct($load) {
+ parent::__construct($load);
+ $this->users = array();
+ }
+
+ /**
+ * Gets a array of users
+ */
+ public function get_users($objs) {
+ $ids = array();
+ foreach ($objs as $obj) {
+ $id = $obj['user_id'];
+ if (!array_key_exists($id, $this->users)) {
+ array_push($ids, intval($id));
+ }
+ }
+ if (!empty($ids)) {
+ $result = $this->main->db
+ ->select('*')
+ ->from('api.user')
+ ->where_in('id', $ids)
+ ->rows();
+ foreach ($result as $user) {
+ $id = $user['id'];
+ $this->users[$id] = $user;
+ }
+ }
+ return $this->users;
+ }
+
+}
diff --git a/web/_model/format.php b/web/_model/format.php
new file mode 100644
index 0000000..d8c7480
--- /dev/null
+++ b/web/_model/format.php
@@ -0,0 +1,45 @@
+<?php /* Copyright (c) 2024 Freya Murphy */
+class Format_model extends Modal {
+
+ function __construct($load) {
+ parent::__construct($load);
+ }
+
+ /**
+ * Formats a users's name
+ * @param array $user - the $user
+ * @returns the user's formatted display name
+ */
+ public function name($user) {
+ $name = '';
+ if ($user['first_name']) {
+ $name .= $user['first_name'];
+ }
+ if ($user['middle_name']) {
+ if ($name != '') {
+ $name .= ' ';
+ }
+ $name .= $user['middle_name'];
+ }
+ if ($user['last_name']) {
+ if ($name != '') {
+ $name .= ' ';
+ }
+ $name .= $user['last_name'];
+ }
+ if ($name == '') {
+ $name = '@' . $user['username'];
+ }
+ return $name;
+ }
+
+ /**
+ * Formats a date
+ * @param string $date - the data in RFC3999 format
+ * @returns the formatted date
+ */
+ public function date($date) {
+ return $date;
+ }
+
+}
diff --git a/web/_model/main.php b/web/_model/main.php
new file mode 100644
index 0000000..f72a2f3
--- /dev/null
+++ b/web/_model/main.php
@@ -0,0 +1,84 @@
+<?php /* Copyright (c) 2024 Freya Murphy */
+class Main_model {
+
+ // the website database
+ public $db;
+
+ // the current user session (can be NULL)
+ public $session;
+
+ // current loaded users
+ private $users;
+
+ // stores the current request info
+ public $info;
+
+ /**
+ * Loads the main model
+ * @param Loader $load - the main loader object
+ */
+ function __construct($load) {
+ /// load the database helper
+ $this->db = new DatabaseHelper();
+ /// load the current session
+ if (array_key_exists('jwt', $_SESSION)) {
+ $this->get_session($_SESSION['jwt']);
+ } else {
+ $this->session = NULL;
+ };
+ /// init other vars
+ $this->users = array();
+ }
+
+ /**
+ * Loads current session
+ * @param string $jwt - the user provided JWT
+ */
+ private function get_session($jwt) {
+ $query = $this->db
+ ->select("_api.verify_jwt('" . $jwt . "') AS user_id;");
+ $result = $query->row();
+ $user_id = $result['user_id'];
+ if ($user_id) {
+ $this->session = array(
+ 'id' => $user_id,
+ 'jwt' => $jwt
+ );
+ }
+ }
+
+ /**
+ * Loads a css html link
+ * @param string $path - the path to the css file
+ */
+ public function link_css($path) {
+ return '<link rel="stylesheet" href="/public/' . $path . '">';
+ }
+
+ /**
+ * Loads a js html link
+ * @param string $path - the path to the js file
+ */
+ public function link_js($path) {
+ return '<script src="/public/'. $path . '"></script>';
+ }
+
+ /**
+ * Gets the current user
+ */
+ public function user() {
+ if ($this->session) {
+ return $this->db
+ ->select('*')
+ ->from('api.user')
+ ->where('id')
+ ->eq($this->session['id'])
+ ->row();
+ } else {
+ return NULL;
+ }
+ }
+
+}
+
+?>
diff --git a/web/_model/request.php b/web/_model/request.php
new file mode 100644
index 0000000..4cce07a
--- /dev/null
+++ b/web/_model/request.php
@@ -0,0 +1,40 @@
+<?php /* Copyright (c) 2024 Freya Murphy */
+class Request_model extends Model {
+
+ function __construct($load) {
+ parent::__construct($load);
+ }
+
+ /**
+ * Loads a string from the GET request
+ * @param string $key - the name for the query param
+ * @param string $default - the default value if not exists
+ */
+ public function get_str($key, $default = NULL): string | NULL {
+ if (!array_key_exists($key, $_GET)) {
+ return $default;
+ } else {
+ return $_GET[$key];
+ }
+ }
+
+ /**
+ * Loads a number from the GET request
+ * @param string $key - the name for the query param
+ * @param int $default - the default value if not exists
+ */
+ public function get_int($key, $default = NULL): int | NULL {
+ if (!array_key_exists($key, $_GET)) {
+ return $default;
+ } else {
+ $val = $_GET[$key];
+ $val = intval($val);
+ if ($val < 0) {
+ return 0;
+ } else {
+ return $val;
+ }
+ }
+ }
+
+}
diff --git a/web/core/aesthetic.php b/web/config/aesthetic.php
index 1180ad1..ed79653 100644
--- a/web/core/aesthetic.php
+++ b/web/config/aesthetic.php
@@ -9,7 +9,7 @@ class Aesthetic {
'js' => [
'js/jquery-3.7.1.min.js',
'js/lib.js',
- 'js/modal.js',
+ 'js/shared/modal.js',
],
'css' => [
'css/common.css'
@@ -22,7 +22,8 @@ class Aesthetic {
),
'home' => array(
'js' => [
- 'js/post.js',
+ 'js/shared/post.js',
+ 'js/routes/home.js',
],
'css' => [
'css/home.css',
diff --git a/web/config/routes.php b/web/config/routes.php
new file mode 100644
index 0000000..78df332
--- /dev/null
+++ b/web/config/routes.php
@@ -0,0 +1,7 @@
+<?php /* Copyright (c) 2024 Freya Murphy */
+
+$routes = array();
+$routes['home'] = 'apps/home';
+$routes['error'] = 'apps/error';
+
+$routes[''] = '_index';
diff --git a/web/core/_controller.php b/web/core/_controller.php
new file mode 100644
index 0000000..8a467d6
--- /dev/null
+++ b/web/core/_controller.php
@@ -0,0 +1,49 @@
+<?php /* Copyright (c) 2024 Freya Murphy */
+abstract class Controller {
+
+ // the main model
+ public $main;
+
+ // the loader
+ public $load;
+
+ // the database
+ public $db;
+
+ /**
+ * Creates a constructor
+ * @param Loader $load - the website loaded object
+ */
+ function __construct($load) {
+ $this->load = $load;
+ $this->main = $this->load->model('main');
+ $this->db = $this->main->db;
+
+ $info = $this->main->info;
+ $lang = $info['lang'];
+ $this->load->lang($lang);
+ $app = $info['app'];
+ if ($app) {
+ $this->load->app_lang($lang, $app);
+ }
+ }
+
+ public function index() {}
+
+ public function redirect($link) {
+ header('Location: '. $link, true, 301);
+ die();
+ }
+
+ protected function view($__name, $data = array()) {
+ $__root = $GLOBALS['webroot'];
+ $__path = $__root . '/views/' . $__name . '.php';
+ if (is_file($__path)) {
+ extract($data);
+ require($__path);
+ return;
+ }
+ }
+
+}
+?>
diff --git a/web/core/_model.php b/web/core/_model.php
new file mode 100644
index 0000000..936fab4
--- /dev/null
+++ b/web/core/_model.php
@@ -0,0 +1,44 @@
+<?php /* Copyright (c) 2024 Freya Murphy */
+abstract class Model {
+ // the main model
+ // shared by all controllers and models
+ public $main;
+ public $load;
+
+ // the database
+ public $db;
+
+ private $config;
+
+ /**
+ * Creates a model
+ * @param Loader $load - the main loader object
+ */
+ function __construct($load) {
+ $this->load = $load;
+ $this->main = $this->load->model('main');
+ $this->db = $this->main->db;
+ $this->config = new Aesthetic();
+ }
+
+ /**
+ * @returns the base model data
+ */
+ public function get_data(): array {
+ $data = array();
+ $data['self'] = $this->main->user();
+
+ $info = $this->main->info;
+ $app = $info['app'];
+
+ if ($app) {
+ $files = $this->config->get_files($app);
+ $data = array_merge($data, $files);
+ } else {
+ $files = $this->config->get_files();
+ $data = array_merge($data, $files);
+ }
+
+ return $data;
+ }
+}
diff --git a/web/core/controller.php b/web/core/controller.php
deleted file mode 100644
index 946b460..0000000
--- a/web/core/controller.php
+++ /dev/null
@@ -1,55 +0,0 @@
-<?php /* Copyright (c) 2024 Freya Murphy */
-abstract class Controller {
-
- // the main model
- public $main;
-
- // the loader
- public $load;
-
- // the database
- public $db;
-
- function __construct() {
- $this->main = $GLOBALS['__vars']['main'];
- $this->load = $GLOBALS['__vars']['load'];
- $this->db = $this->main->db;
-
- $info = $this->main->info;
- $lang_code = $info['lang'];
- $route_name = $info['route'];
- $this->load->lang($lang_code);
- $this->load->route_lang($lang_code, $route_name);
- }
-
- public function index() {}
-
- protected function view($__name, $data = array()) {
- $__root = $GLOBALS['webroot'];
- $__path = $__root . '/views/' . $__name . '.php';
- if (is_file($__path)) {
- extract($data);
- require($__path);
- return;
- }
- }
-
- protected function app_view($__name, $data = array()) {
- $__root = $GLOBALS['webroot'];
- $__route = $this->main->info['route'];
- $__path = $__root . '/routes/' . $__route . '/views/' . $__name . '.php';
- if (is_file($__path)) {
- extract($data);
- require($__path);
- return;
- }
- }
-
- protected function modal($title, $content, $data = array()) {
- $data['title'] = $title;
- $data['content'] = $content;
- $this->view('template/modal', $data);
- }
-
-}
-?>
diff --git a/web/core/database.php b/web/core/database.php
index b3a597b..4b44e86 100644
--- a/web/core/database.php
+++ b/web/core/database.php
@@ -170,4 +170,3 @@ class DatabaseHelper {
}
}
-?>
diff --git a/web/core/loader.php b/web/core/loader.php
index 4d4526c..2091533 100644
--- a/web/core/loader.php
+++ b/web/core/loader.php
@@ -1,16 +1,79 @@
<?php /* Copyright (c) 2024 Freya Murphy */
class Loader {
+ // keep track of what has been loaded
+ private $loaded;
+
+ function __construct() {
+ $this->loaded = array();
+ }
+
+ /**
+ * Loads a $type of object from a $dir with a given $name
+ * @param string $name - the name of the object to load
+ * @param string $dir - the directory theese objects are stored in
+ * @param string $type - the type of the object
+ */
+ private function load_type($name, $dir, $type): object|NULL {
+ $path = $dir . '/' . $name . '.php';
+ if (array_key_exists($path, $this->loaded)) {
+ return $this->loaded[$path];
+ }
+
+ if (!file_exists($path)) {
+ return NULL;
+ }
+
+ $parts = explode('/', $name);
+ $part = end($parts);
+ $class = ucfirst($part) . '_' . $type;
+ require($path);
+
+ $ref = NULL;
+ try {
+ $ref = new ReflectionClass($class);
+ } catch (Exception $_e) {}
+
+ if ($ref === NULL) {
+ return NULL;
+ }
+
+ $obj = $ref->newInstance($this);
+ $this->loaded[$path] = $obj;
+
+ return $obj;
+ }
+
+ /**
+ * Loads a model
+ * @param string $name - the name of the model to load
+ */
+ public function model($name): object|NULL {
+ $root = $GLOBALS['webroot'];
+ $dir = $root . '/_model';
+ return $this->load_type($name, $dir, 'model');
+ }
+
+ /**
+ * Loads a controller
+ * @param string $name - the name of the controller to load
+ */
+ public function controller($name): Controller|NULL {
+ $root = $GLOBALS['webroot'];
+ $dir = $root . '/_controller';
+ return $this->load_type($name, $dir, 'controller');
+ }
+
/**
* Loads the given common lang
- * @param lang_code - the language code
+ * @param string $lang_code 0 the language code
*/
- public function lang($lang_code) {
+ public function lang($lang_code): void {
$dir = $GLOBALS['webroot'] . '/lang/' . $lang_code . '/';
$lang = $GLOBALS['lang'];
if ($handle = opendir($dir)) {
while (false !== ($entry = readdir($handle))) {
- if ($entry === '.' || $entry === '..' || $entry === 'routes') {
+ if ($entry === '.' || $entry === '..' || $entry === 'apps') {
continue;
}
$path = $dir . $entry;
@@ -21,12 +84,12 @@ class Loader {
}
/**
- * Loads a given route specific lang
- * @param lang_coed - the language code
- * #param name - the name of the route
+ * Loads a given app specific lang
+ * @param string $lang_code - the language code
+ * @param string $name - the name of the app
*/
- public function route_lang($lang_code, $name) {
- $dir = $GLOBALS['webroot'] . '/lang/' . $lang_code . '/routes/';
+ public function app_lang($lang_code, $name): void {
+ $dir = $GLOBALS['webroot'] . '/lang/' . $lang_code . '/apps/';
$file = $dir . $name . '.php';
if (file_exists($file)) {
$lang = $GLOBALS['lang'];
diff --git a/web/core/main.php b/web/core/main.php
deleted file mode 100644
index c3c65dd..0000000
--- a/web/core/main.php
+++ /dev/null
@@ -1,123 +0,0 @@
-<?php /* Copyright (c) 2024 Freya Murphy */
-class MainModel {
-
- // loaded route infomation
- public $info;
- public $db;
- public $user_id;
-
- private $users;
-
- function __construct() {
- $this->info = NULL;
- $this->db = new DatabaseHelper();
- $this->users = array();
- $_SESSION['jwt'] = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoicmVzdF91c2VyIiwidXNlcl9pZCI6MSwiZXhwIjoxNzExODUxMDUzfQ.FUcFO44SWV--YtVOy7NftTF8OeeOYGZDaDHigygQxsY';
- if (array_key_exists('jwt', $_SESSION)) {
- $this->get_session($_SESSION['jwt']);
- } else {
- $this->user_id = NULL;
- };
- }
-
- private function get_session($jwt) {
- $query = $this->db
- ->select("_api.verify_jwt('" . $jwt . "') AS user_id;");
- $result = $query->row();
- $user_id = $result['user_id'];
- if ($user_id) {
- $this->user_id = $user_id;
- }
- }
-
- public function link_css($path) {
- return '<link rel="stylesheet" href="/public/' . $path . '">';
- }
-
- public function link_js($path) {
- return '<script src="/public/'. $path . '"></script>';
- }
-
- public function user() {
- if ($this->user_id) {
- return $this->db
- ->select('*')
- ->from('api.user')
- ->where('id')
- ->eq($this->user_id)
- ->row();
- } else {
- return NULL;
- }
- }
-
- public function get_num($key, $default = NULL) {
- if (!array_key_exists($key, $_GET)) {
- if ($default !== NULL) {
- return $default;
- } else {
- error_page(400, lang('error_400'));
- }
- } else {
- $val = $_GET[$key];
- $val = intval($val);
- if ($val < 0) {
- return 0;
- } else {
- return $val;
- }
- }
- }
-
- public function get_users($objs) {
- $ids = array();
- foreach ($objs as $obj) {
- $id = $obj['user_id'];
- if (!array_key_exists($id, $this->users)) {
- array_push($ids, intval($id));
- }
- }
- if (!empty($ids)) {
- $result = $this->db
- ->select('*')
- ->from('api.user')
- ->where_in('id', $ids)
- ->rows();
- foreach ($result as $user) {
- $id = $user['id'];
- $this->users[$id] = $user;
- }
- }
- return $this->users;
- }
-
- public function display_name($user) {
- $name = '';
- if ($user['first_name']) {
- $name .= $user['first_name'];
- }
- if ($user['middle_name']) {
- if ($name != '') {
- $name .= ' ';
- }
- $name .= $user['middle_name'];
- }
- if ($user['last_name']) {
- if ($name != '') {
- $name .= ' ';
- }
- $name .= $user['last_name'];
- }
- if ($name == '') {
- $name = '@' . $user['username'];
- }
- return $name;
- }
-
- public function display_date($date) {
- return $date;
- }
-
-}
-
-?>
diff --git a/web/core/model.php b/web/core/model.php
deleted file mode 100644
index 039b138..0000000
--- a/web/core/model.php
+++ /dev/null
@@ -1,29 +0,0 @@
-<?php /* Copyright (c) 2024 Freya Murphy */
-abstract class Model {
- // the main model
- // shared by all controllers and models
- public $main;
- public $load;
-
- // the database
- public $db;
-
- private $config;
-
- function __construct() {
- $this->main = $GLOBALS['__vars']['main'];
- $this->load = $GLOBALS['__vars']['load'];
- $this->db = $this->main->db;
- $this->config = new Aesthetic();
- }
-
- public function get_data() {
- $data = array();
- $route = $this->main->info['route'];
- $files = $this->config->get_files($route);
- $data = array_merge($data, $files);
- $data['self'] = $this->main->user();
- return $data;
- }
-}
-?>
diff --git a/web/core/router.php b/web/core/router.php
index 6ee28a9..72c7674 100644
--- a/web/core/router.php
+++ b/web/core/router.php
@@ -1,127 +1,147 @@
<?php /* Copyright (c) 2024 Freya Murphy */
class Router {
- private $main;
+ // the loader
private $load;
- private $routes;
-
- function load_route($route) {
- $name = $route['name'];
- $controller_cls = $route['controller'];
- $model_cls = $route['model'];
-
- $root = $GLOBALS['webroot'];
- $dir = $root . '/routes/' . $name;
- require($dir . '/model.php');
- require($dir . '/controller.php');
-
- $model_ref = new ReflectionClass($model_cls);
- $model = $model_ref->newInstance();
- $controller_ref = new ReflectionClass($controller_cls);
- $controller = $controller_ref->newInstance($model);
+ // the main model
+ private $main;
- return $controller;
+ /**
+ * Creates a router
+ * @param Loader $load - the main laoder object
+ */
+ function __construct($load) {
+ $this->load = $load;
+ $this->main = $this->load->model('main');
}
- function __construct($main, $load) {
+ /**
+ * @param string $path - the current request path
+ * Gets the current route
+ * @return array<string,mixed>
+ */
+ private function get_req_route($path): array {
+ // trim the path
+ $path = trim($path);
+ // remove first '/'
+ $path = substr($path, 1);
+ // get path parts
+ $parts = explode('/', $path);
- $routes = array(
- 'home' => array(
- 'slugs' => ['', 'home'],
- 'model' => 'HomeModel',
- 'controller' => 'HomeController',
- ),
- );
+ $len = count($parts);
- $this->routes = array();
- foreach ($routes as $name => $route) {
- foreach ($route['slugs'] as $slug) {
- $this->routes[$slug] = $route;
- $this->routes[$slug]['name'] = $name;
- }
+ // get route info
+ $route = array();
+ // e.g. /
+ if ($path === '') {
+ $route = array(
+ 'route' => '',
+ 'slug' => 'index',
+ );
+ // e.g. /home /login
+ } else if ($len === 1) {
+ $route = array(
+ 'route' => $parts[0],
+ 'slug' => 'index',
+ );
+ // e.g. /home/posts
+ } else {
+ $route = array (
+ 'route' => implode('/', array_slice($parts, 0, -1)),
+ 'slug' => end($parts)
+ );
+ };
+
+ $route['app'] = $route['route'];
+ $routes = $GLOBALS['routes'];
+ if (array_key_exists($route['route'], $routes)) {
+ $route['route'] = $routes[$route['route']];
}
- $this->main = $main;
- $this->load = $load;
+ return $route;
}
- function get_info() {
- $uri = parse_url($_SERVER['REQUEST_URI']);
+ /**
+ * Gets the curret request info
+ * @return array<string,mixed>
+ */
+ private function get_req(): array {
$method = $_SERVER['REQUEST_METHOD'];
- $parts = explode('/', $uri['path']);
-
- $slug = sizeof($parts) > 1 ? $parts[1] : '';
- $path = sizeof($parts) > 2 ? $parts[2] : 'index';
- if (sizeof($parts) > 3) {
- return NULL;
- }
-
- return array(
- 'method' => $method,
- 'uri' => $uri,
+ $uri = parse_url($_SERVER['REQUEST_URI']);
+ $path = $uri['path'];
- 'slug' => $slug,
- 'path' => $path
+ return array_merge(
+ array(
+ 'uri' => $uri,
+ 'method' => $method,
+ 'lang' => $this->get_lang(),
+ ),
+ $this->get_req_route($path),
);
}
- function handle_error($code) {
- $route = array(
- 'name' => 'error',
- 'model' => 'ErrorModel',
- 'controller' => 'ErrorController'
- );
- $this->main->info = array(
- 'slug' => 'error',
- 'lang' => 'en_US',
- 'route' => 'error'
- );
- $controller = $this->load_route($route);
- $_GET['code'] = $code;
- http_response_code($code);
- $controller->index();
+ /**
+ * Gets the current language
+ * @return string
+ */
+ private function get_lang(): string {
+ return 'en_US';
}
- public function handle_request() {
- $request = $this->get_info();
-
- if ($request === NULL) {
- $this->handle_error(404);
- return;
+ /**
+ * Handles a router error code
+ * @param int $code - the http error code
+ * @param bool $recursed
+ */
+ private function handle_error($code, $recursed): void {
+ if ($recursed) {
+ die($code . ' (recursed)');
}
- $slug = $request['slug'];
- if (!array_key_exists($slug, $this->routes)) {
- $this->handle_error(404);
- return;
- }
+ $this->main->info['slug'] = 'index';
+ $this->main->info['app'] = 'error';
+ $this->main->info['route'] = 'apps/error';
+ $req = $this->main->info;
+ $_GET['code'] = $code;
- $route = $this->routes[$slug];
- $this->main->info = array(
- 'lang' => 'en_US',
- 'slug' => $slug,
- 'route' => $route['name'],
- );
+ $this->handle_req($req, TRUE);
+ }
- $controller = $this->load_route($route);
+ /**
+ * @param array $req
+ * @param bool $recursed
+ */
+ private function handle_req($req, $recursed = FALSE): void {
+ $controller = $this->load->controller($req['route']);
- $path = $request['path'];
- $ref = NULL;
+ if ($controller === NULL) {
+ $this->handle_error(404, $recursed);
+ return;
+ }
+ $ref = NULL;
try {
- $ref = new ReflectionMethod($controller, $path);
+ $ref = new ReflectionMethod($controller, $req['slug']);
} catch (Exception $_e) {}
if ($ref === NULL || !$ref->isPublic()) {
- $this->handle_error(404);
+ $this->handle_error(404, $recursed);
return;
}
$ref->invoke($controller);
+ }
+ /**
+ * Handels the incomming reuqest
+ */
+ public function handle_request(): void {
+ $req = $this->get_req();
+ $this->main->info = $req;
+ $this->handle_req($req);
}
}
diff --git a/web/helper/error.php b/web/helper/error.php
new file mode 100644
index 0000000..6fcaddd
--- /dev/null
+++ b/web/helper/error.php
@@ -0,0 +1,9 @@
+<?php /* Copyright (c) 2024 Freya Murphy */
+
+function error_page($code, $msg) {
+ $root = $GLOBALS['webroot'];
+ error_reporting(E_ERROR | E_PARSE);
+ http_response_code($code);
+ require($root . '/views/template/error.php');
+ die();
+}
diff --git a/web/helper/lang.php b/web/helper/lang.php
new file mode 100644
index 0000000..96944da
--- /dev/null
+++ b/web/helper/lang.php
@@ -0,0 +1,77 @@
+<?php /* Copyright (c) 2024 Freya Murphy */
+$lang = array();
+
+function lang($key, $default = NULL, $sub = NULL) {
+ $lang = $GLOBALS['lang'];
+ if(array_key_exists($key, $lang)) {
+ if ($sub) {
+ return sprintf($lang[$key], ...$sub);
+ } else {
+ return $lang[$key];
+ }
+ } else if ($default !== NULL) {
+ return $default;
+ } else {
+ return $key;
+ }
+}
+
+function ilang($key,
+ $class = NULL,
+ $id = NULL,
+ $href = NULL,
+ $click = NULL,
+ $attrs = array(),
+ $sub = NULL,
+ $button = FALSE,
+) {
+ $text = lang($key . "_text", FALSE, sub: $sub);
+ $tip = lang($key . "_tip", FALSE);
+ $icon = lang($key . "_icon", FALSE);
+ $content = lang($key . "_content", FALSE);
+
+ if ($click || $button) {
+ echo '<button ';
+ } else {
+ echo '<a ';
+ }
+ if ($tip) {
+ echo 'title="' . $tip . '" ';
+ echo 'aria-label="' . $tip . '" ';
+ }
+ if ($class) {
+ echo 'class="' . $class . '" ';
+ }
+ if ($id) {
+ echo 'id="' . $id . '" ';
+ }
+ if ($click) {
+ echo 'onclick="' . $click . '" ';
+ }
+ if ($href) {
+ echo 'href="' . $href . '" ';
+ }
+ foreach ($attrs as $key => $attr) {
+ echo $key . '="' . $attr . '" ';
+ }
+ echo '> ';
+ if ($icon) {
+ echo '<i class="' . $icon . '">';
+ if ($content) {
+ echo $content;
+ }
+ echo '</i>';
+ }
+ if ($text) {
+ echo '<span';
+ if ($icon) {
+ echo ' class="ml-sm"';
+ }
+ echo '>' . $text . '</span>';
+ }
+ if ($click) {
+ echo '</button>';
+ } else {
+ echo '</a>';
+ }
+}
diff --git a/web/index.php b/web/index.php
index 1032b7f..9c2d239 100644
--- a/web/index.php
+++ b/web/index.php
@@ -2,114 +2,26 @@
session_start();
-$lang = array();
-$__vars = array();
$webroot = dirname(__FILE__);
-function error_page($code, $msg) {
- $root = $GLOBALS['webroot'];
- error_reporting(E_ERROR | E_PARSE);
- http_response_code($code);
- require($root . '/core/error.php');
- die();
-}
+// load all the helper files
+require($webroot . '/helper/error.php');
+require($webroot . '/helper/lang.php');
-function lang($key, $default = NULL, $sub = NULL) {
- $lang = $GLOBALS['lang'];
- if(array_key_exists($key, $lang)) {
- if ($sub) {
- return sprintf($lang[$key], ...$sub);
- } else {
- return $lang[$key];
- }
- } else if ($default !== NULL) {
- return $default;
- } else {
- return $key;
- }
-}
+// load all the config files
+require($webroot . '/config/aesthetic.php');
+require($webroot . '/config/routes.php');
-function ilang($key,
- $class = NULL,
- $id = NULL,
- $href = NULL,
- $click = NULL,
- $attrs = array(),
- $sub = NULL,
- $button = FALSE,
-) {
- $text = lang($key . "_text", FALSE, sub: $sub);
- $tip = lang($key . "_tip", FALSE);
- $icon = lang($key . "_icon", FALSE);
- $content = lang($key . "_content", FALSE);
-
- if ($click || $button) {
- echo '<button ';
- } else {
- echo '<a ';
- }
- if ($tip) {
- echo 'title="' . $tip . '" ';
- echo 'aria-label="' . $tip . '" ';
- }
- if ($class) {
- echo 'class="' . $class . '" ';
- }
- if ($id) {
- echo 'id="' . $id . '" ';
- }
- if ($click) {
- echo 'onclick="' . $click . '" ';
- }
- if ($href) {
- echo 'href="' . $href . '" ';
- }
- foreach ($attrs as $key => $attr) {
- echo $key . '="' . $attr . '" ';
- }
- echo '> ';
- if ($icon) {
- echo '<i class="' . $icon . '">';
- if ($content) {
- echo $content;
- }
- echo '</i>';
- }
- if ($text) {
- echo '<span';
- if ($icon) {
- echo ' class="ml-sm"';
- }
- echo '>' . $text . '</span>';
- }
- if ($click) {
- echo '</button>';
- } else {
- echo '</a>';
- }
-}
+// load all core files
+require($webroot . '/core/_controller.php');
+require($webroot . '/core/_model.php');
+require($webroot . '/core/database.php');
+require($webroot . '/core/loader.php');
+require($webroot . '/core/router.php');
function __init() {
-
- $root = $GLOBALS['webroot'];
-
- // load all core files
- require($root . '/core/database.php');
- require($root . '/core/aesthetic.php');
- require($root . '/core/controller.php');
- require($root . '/core/model.php');
- require($root . '/core/loader.php');
- require($root . '/core/main.php');
- require($root . '/core/router.php');
-
- $main = new MainModel();
$load = new Loader();
- $router = new Router($main, $load);
-
- $GLOBALS['__vars']['main'] = $main;
- $GLOBALS['__vars']['load'] = $load;
- $GLOBALS['__vars']['router'] = $router;
-
+ $router = new Router($load);
$router->handle_request();
};
@@ -118,5 +30,3 @@ if (!file_exists('/status/ready')) {
}
__init();
-
-?>
diff --git a/web/lang/en_US/api_lang.php b/web/lang/en_US/api_lang.php
new file mode 100644
index 0000000..129147c
--- /dev/null
+++ b/web/lang/en_US/api_lang.php
@@ -0,0 +1,26 @@
+<?php /* Copyright (c) 2024 Freya Murphy */
+
+// user column
+$lang['api_column_username'] = 'username';
+$lang['api_column_first_name'] = 'first name';
+$lang['api_column_last_name'] = 'last name';
+$lang['api_column_middle_name'] = 'middle name';
+$lang['api_column_email'] = 'email';
+$lang['api_column_gender'] = 'gender';
+$lang['api_column_join_date'] = 'join date';
+$lang['api_column_birth_date'] = 'birth date';
+$lang['api_column_profile_avatar'] = 'avatar image';
+$lang['api_column_profile_banner'] = 'banner image';
+$lang['api_column_profile_bio'] = 'profile bio';
+
+// post column
+$lang['api_column_content'] = 'post content';
+
+// error messages
+$lang['api_denied'] = 'Action was denied';
+$lang['api_null_value'] = '%s cannot be empty';
+$lang['api_unique_value'] = '%s is not available (not unique)';
+$lang['api_min_value'] = '%s length cannot be less than %s';
+$lang['api_max_value'] = '%s length cannot exceed %s';
+
+?>
diff --git a/web/lang/en_US/apps/home.php b/web/lang/en_US/apps/home.php
new file mode 100644
index 0000000..a30eb88
--- /dev/null
+++ b/web/lang/en_US/apps/home.php
@@ -0,0 +1,9 @@
+<?php
+
+$lang['title'] = 'Home';
+
+// actions
+$lang['action_load_posts_text'] = 'Load more posts';
+$lang['action_load_posts_tip'] = 'Load more posts';
+
+?>
diff --git a/web/lang/en_US/common_lang.php b/web/lang/en_US/common_lang.php
index 3ce2fdb..7e214b5 100644
--- a/web/lang/en_US/common_lang.php
+++ b/web/lang/en_US/common_lang.php
@@ -1,4 +1,4 @@
-<?php
+<?php /* Copyright (c) 2024 Freya Murphy */
// Navigation Bar Lang
$lang['action_home_text'] = 'Home';
@@ -29,6 +29,10 @@ $lang['action_load_comments_tip'] = 'Load more comments';
// General
$lang['action_submit_text'] = 'Submit';
$lang['action_submit_tip'] = 'Submit';
+$lang['action_close_text'] = '';
+$lang['action_close_tip'] = 'Close';
+$lang['action_close_icon'] = 'mi mi-sm';
+$lang['action_close_content'] = 'close';
// Modals
$lang['action_modal_close_text'] = '';
@@ -36,6 +40,10 @@ $lang['action_modal_close_tip'] = 'Close modal.';
$lang['action_modal_close_icon'] = 'mi mi-sm';
$lang['action_modal_close_content'] = 'close';
+$lang['new_post_modal_title'] = 'Author New Post';
+$lang['action_new_post_text'] = 'What\'s on your mind, %s';
+$lang['action_new_post_tip'] = 'Author a new post.';
+
// Words
$lang['now'] = 'Now';
diff --git a/web/lang/en_US/error_lang.php b/web/lang/en_US/error_lang.php
index 42ade65..afecaa1 100644
--- a/web/lang/en_US/error_lang.php
+++ b/web/lang/en_US/error_lang.php
@@ -1,4 +1,4 @@
-<?php
+<?php /* Copyright (c) 2024 Freya Murphy */
$lang['error_400'] = 'Bad request';
$lang['error_404'] = 'Resource not found';
diff --git a/web/lang/en_US/routes/home.php b/web/lang/en_US/routes/home.php
deleted file mode 100644
index 051eff2..0000000
--- a/web/lang/en_US/routes/home.php
+++ /dev/null
@@ -1,14 +0,0 @@
-<?php
-
-$lang['title'] = 'Home';
-
-// actions
-$lang['action_new_post_text'] = 'What\'s on your mind, %s';
-$lang['action_new_post_tip'] = 'Author a new post.';
-$lang['action_load_posts_text'] = 'Load more posts';
-$lang['action_load_posts_tip'] = 'Load more posts';
-
-// modals
-$lang['new_post_modal_title'] = 'Author New Post';
-
-?>
diff --git a/web/public/css/common.css b/web/public/css/common.css
index 05f429f..84aabfc 100644
--- a/web/public/css/common.css
+++ b/web/public/css/common.css
@@ -52,6 +52,8 @@ body {
}
header {
+ top: 0;
+ position: sticky;
height: 3.5rem;
background-color: var(--primary);
display: flex;
@@ -145,6 +147,10 @@ input:focus {
align-items: center;
}
+.nav {
+ position: sticky;
+}
+
.nav-right {
flex: 1;
justify-content: flex-end;
@@ -333,6 +339,30 @@ input:focus {
border-radius: .5rem;
display: flex;
flex-direction: column;
+ animation: fadeIn .1s, slideInModal .1s linear;
+}
+
+@keyframes slideInModal {
+ 0% {
+ animation-timing-function: ease-in;
+ transform: translate(-50%, -60%);
+ }
+}
+
+@keyframes slideIn {
+ 0% {
+ animation-timing-function: ease-out;
+ transform: translate(0, -50%);
+ }
+}
+
+@keyframes fadeIn {
+ 0% {
+ opacity: 0;
+ }
+ 100% {
+ opacity: 1;
+ }
}
.modal>form {
@@ -402,3 +432,30 @@ button[type="submit"]:hover {
background-color: var(--logo);
}
+#toast-container {
+ position: fixed;
+ top: 4rem;
+ left: 100%;
+ transform: translateX(-110%);
+ margin-top: 1rem;
+ z-index: 10000;
+}
+
+.toast {
+ padding: .75rem;
+ margin: .5rem;
+ border-radius: .5rem;
+ min-width: 15rem;
+ font-family: sfpro;
+ animation: fadeIn .1s, slideIn .25s linear;
+ display: flex;
+ justify-content: space-between;
+}
+
+.toast.error {
+ background-color: var(--error);
+}
+
+.toast.success {
+ background-color: var(--success);
+}
diff --git a/web/public/js/lib.js b/web/public/js/lib.js
index d822b02..7647208 100644
--- a/web/public/js/lib.js
+++ b/web/public/js/lib.js
@@ -1,4 +1,8 @@
+///
+/// document ready functions
+///
+
let ready = false;
$(function() {
@@ -15,9 +19,14 @@ var r$ = function(callback) {
}
}
+///
+/// dom observer
+/// checks for elements on the DOM now and added later
+///
+
function observe(containerSelector, elementSelector, callback) {
- r$(() => {
+ r$(() => {
$(containerSelector + ' ' + elementSelector).each(function (_, e) {
let me = $(e);
callback(me);
@@ -37,9 +46,64 @@ function observe(containerSelector, elementSelector, callback) {
};
var target = $(containerSelector)[0];
+
+ if (!target) {
+ console.warn('[observe] didnt find container: ', containerSelector);
+ return;
+ }
+
var config = { childList: true, subtree: true };
var MutationObserver = window.MutationObserver;
var observer = new MutationObserver(onMutationsObserved);
observer.observe(target, config);
});
}
+
+///
+/// ajax setup
+///
+
+let ajaxHeaders = {};
+ajaxHeaders['Content-Type'] = 'application/json';
+if (jwtStr) {
+ ajaxHeaders['Authorization'] = 'Bearer ' + jwtStr
+}
+
+$.ajaxSetup({
+ headers: ajaxHeaders
+})
+
+///
+/// ajax error handle
+///
+
+var errorToast = (xhr) => {
+ let data = xhr.responseJSON;
+ let msg = data.message;
+ let detail = data.details;
+ let hint = data.hint;
+
+ let query = '?msg=' + msg;
+ if (detail) {
+ query += '&detail=' + detail;
+ }
+ if (hint) {
+ query += '&hint=' + hint;
+ }
+ let url = '/template/toast' + query;
+ $.get(url, function (data) {
+ $('#toast-container').prepend(data);
+ })
+}
+
+observe('#toast-container', '.action-close-toast', function(el) {
+ el.on('click', function() {
+ el.parent().remove();
+ });
+
+ setTimeout(function() {
+ el.parent().remove();
+ }, 5000);
+});
+
+
diff --git a/web/core/helper.php b/web/public/js/routes/home.js
index e69de29..e69de29 100644
--- a/web/core/helper.php
+++ b/web/public/js/routes/home.js
diff --git a/web/public/js/modal.js b/web/public/js/shared/modal.js
index 792cd85..792cd85 100644
--- a/web/public/js/modal.js
+++ b/web/public/js/shared/modal.js
diff --git a/web/public/js/post.js b/web/public/js/shared/post.js
index 736fa2b..afbeaf0 100644
--- a/web/public/js/post.js
+++ b/web/public/js/shared/post.js
@@ -1,4 +1,4 @@
-observe('.post', '.action-load-comments', function(me) {
+observe('#main-content', '.action-load-comments', function(me) {
me.on('click', function() {
let page = me.attr('page');
if (!page) {
diff --git a/web/routes/error/controller.php b/web/routes/error/controller.php
deleted file mode 100644
index 3cb2345..0000000
--- a/web/routes/error/controller.php
+++ /dev/null
@@ -1,20 +0,0 @@
-<?php /* Copyright (c) 2024 Freya Murphy */
-class ErrorController extends Controller {
-
- private $model;
-
- function __construct($model) {
- parent::__construct();
- $this->model = $model;
- }
-
- public function index() {
- parent::index();
- $data = $this->model->get_data();
- $this->view('header', $data);
- $this->app_view('error', $data);
- }
-
-}
-
-?>
diff --git a/web/routes/error/views/error.php b/web/routes/error/views/error.php
deleted file mode 100644
index 3b926bc..0000000
--- a/web/routes/error/views/error.php
+++ /dev/null
@@ -1,4 +0,0 @@
-<div id="error">
- <h1><?=$title?></h1>
- <span><?=$msg?></span>
-</div>
diff --git a/web/views/apps/error/main.php b/web/views/apps/error/main.php
new file mode 100644
index 0000000..81051bd
--- /dev/null
+++ b/web/views/apps/error/main.php
@@ -0,0 +1,6 @@
+<?php /* Copyright (c) 2024 Freya Murphy */ ?>
+<?php /* vi: syntax=php */ ?>
+<div id="error">
+ <h1><?=$title?></h1>
+ <span><?=$msg?></span>
+</div>
diff --git a/web/routes/home/views/main.php b/web/views/apps/home/main.php
index bf0087b..b1c1efc 100644
--- a/web/routes/home/views/main.php
+++ b/web/views/apps/home/main.php
@@ -1,4 +1,5 @@
-<?php // vi: syntax=php ?>
+<?php /* Copyright (c) 2024 Freya Murphy */ ?>
+<?php /* vi: syntax=php */ ?>
<div id="main-content">
<?php if ($self): ?>
<div id="new-post" class="card">
@@ -15,7 +16,7 @@
</div>
<script>
$('#action-new-post').on('click', function() {
- $.get( "/home/new_post_modal", function (data) {
+ $.get( "/modal/new_post", function (data) {
$(document.body).append(data);
});
})
diff --git a/web/views/footer.php b/web/views/footer.php
index 6cbe21b..1266b9a 100644
--- a/web/views/footer.php
+++ b/web/views/footer.php
@@ -1,2 +1,4 @@
+<?php /* Copyright (c) 2024 Freya Murphy */ ?>
+<?php /* vi: syntax=php */ ?>
<body>
</html>
diff --git a/web/views/header.php b/web/views/header.php
index 183f4f4..891e27e 100644
--- a/web/views/header.php
+++ b/web/views/header.php
@@ -1,10 +1,18 @@
-<?php // vi: syntax=php ?>
+<?php /* Copyright (c) 2024 Freya Murphy */ ?>
+<?php /* vi: syntax=php */ ?>
<?php
$self = $this->main->user();
?>
<!DOCTYPE html>
<html>
<head>
+ <script>
+ <?php if ($this->main->session): ?>
+ var jwtStr = <?=json_encode($this->main->session['jwt'])?>;
+ <?php else: ?>
+ var jwtStr = null;
+ <?php endif; ?>
+ </script>
<?php
foreach ($js_files as $js) {
echo $this->main->link_js($js);
@@ -71,4 +79,6 @@
menu.toggleClass('visible');
});
</script>
- </header>
+ </header>
+ <div id="toast-container">
+ </div>
diff --git a/web/views/modal/new-post.php b/web/views/modal/new_post.php
index 7215862..82243fb 100644
--- a/web/views/modal/new-post.php
+++ b/web/views/modal/new_post.php
@@ -1,7 +1,9 @@
+<?php /* Copyright (c) 2024 Freya Murphy */ ?>
+<?php /* vi: syntax=php */ ?>
<?php
$user = $this->main->user();
?>
-<form>
+<form id="new-post-form">
<div class="modal-content new-post-modal">
<div class="row">
<?php $this->view('template/pfp', array('user' => $user))?>
@@ -12,8 +14,8 @@
</div>
<textarea
type="text"
- name="text"
- id="text"
+ name="content"
+ id="new-post-content"
placeholder="<?=lang('action_new_post_text', sub: [$user['first_name']])?>"
></textarea>
</div>
@@ -26,3 +28,19 @@
)?>
</div>
</form>
+<script>
+ $('#new-post-form').submit(function(e) {
+ e.preventDefault();
+ let content = $('#new-post-content').val();
+
+ $.ajax({
+ url: '/api/post',
+ method: 'POST',
+ data: JSON.stringify({ content }),
+ success: function(data) {
+ window.location.reload();
+ },
+ error: errorToast
+ });
+ });
+</script>
diff --git a/web/views/template/comment.php b/web/views/template/comment.php
index ef7a081..943f232 100644
--- a/web/views/template/comment.php
+++ b/web/views/template/comment.php
@@ -1,3 +1,5 @@
+<?php /* Copyright (c) 2024 Freya Murphy */ ?>
+<?php /* vi: syntax=php */ ?>
<div class="comment row mt">
<?php $this->view('template/pfp', array('user' => $user))?>
<div class="ml col sub-card">
diff --git a/web/core/error.php b/web/views/template/error.php
index 2e02cb1..2e02cb1 100644
--- a/web/core/error.php
+++ b/web/views/template/error.php
diff --git a/web/views/template/modal.php b/web/views/template/modal.php
index 4f47400..e3ce6fe 100644
--- a/web/views/template/modal.php
+++ b/web/views/template/modal.php
@@ -1,3 +1,5 @@
+<?php /* Copyright (c) 2024 Freya Murphy */ ?>
+<?php /* vi: syntax=php */ ?>
<div class="modal-container">
<div class="modal">
<div class="modal-header row">
diff --git a/web/views/template/pfp.php b/web/views/template/pfp.php
index 842fc92..aec7318 100644
--- a/web/views/template/pfp.php
+++ b/web/views/template/pfp.php
@@ -1,3 +1,5 @@
+<?php /* Copyright (c) 2024 Freya Murphy */ ?>
+<?php /* vi: syntax=php */ ?>
<?php
$class = isset($class) ? $class : '';
?>
diff --git a/web/views/template/post.php b/web/views/template/post.php
index d9c7c92..40a3c1d 100644
--- a/web/views/template/post.php
+++ b/web/views/template/post.php
@@ -1,3 +1,5 @@
+<?php /* Copyright (c) 2024 Freya Murphy */ ?>
+<?php /* vi: syntax=php */ ?>
<div class="post card">
<div class="row">
<?php $this->view('template/pfp', array('user' => $user))?>
diff --git a/web/views/template/toast.php b/web/views/template/toast.php
new file mode 100644
index 0000000..1f74602
--- /dev/null
+++ b/web/views/template/toast.php
@@ -0,0 +1,19 @@
+<?php /* Copyright (c) 2024 Freya Murphy */ ?>
+<?php /* vi: syntax=php */ ?>
+<?php
+ $params = array();
+
+ if ($detail) {
+ array_push($params, lang('api_column_' . $detail));
+ }
+
+ if ($hint) {
+ array_push($params, $hint);
+ }
+
+ $msg = lang($msg, sub: $params);
+?>
+<div class="toast error">
+ <?=ucfirst($msg)?>
+ <?=ilang('action_close', class: 'action-close-toast')?>
+</div>