diff --git a/app/Http/Controllers/DashController.php b/app/Http/Controllers/DashController.php index 15af2b6..aa3d8ff 100644 --- a/app/Http/Controllers/DashController.php +++ b/app/Http/Controllers/DashController.php @@ -43,18 +43,15 @@ class DashController extends Controller ]); } - public function page($uuid) + public function page($mode, $uuid) { $status = session('handle') !== null ? true : false; - $result = []; - if ($status) { - $result = $this->pages->getPage($pageNum, 4, $pageFilter); - } - return view('back.book', [ - "status" => $status, - "result" => $result, - "currentPage" => $pageNum, - "title" => "Pages" + $page = $this->pages->getById($uuid)->first(); + return view('back.page', [ + "status" => $status, + "mode" => $mode, + "page" => $page, + "title" => 'Editing ' . $page['title'] ]); } } diff --git a/app/Repositories/PageRepository.php b/app/Repositories/PageRepository.php index dc7db39..568bfa2 100644 --- a/app/Repositories/PageRepository.php +++ b/app/Repositories/PageRepository.php @@ -32,6 +32,7 @@ class PageRepository implements PageRepositoryInterface public function getById($uuid) { + return $this->pages->where('uuid', $uuid); } public function delete($uuid) diff --git a/composer.json b/composer.json index 9fce414..8e53702 100644 --- a/composer.json +++ b/composer.json @@ -23,6 +23,7 @@ "laravel/tinker": "^2.8", "league/commonmark": "^2.4", "lodash-php/lodash-php": "^0.09.0", + "mindtwo/laravel-blade-spaceless": "^1.2", "mnapoli/front-yaml": "^2.0", "olegatro/html-sanitizer-relative": "^1.0", "symfony/yaml": "^7.0", diff --git a/composer.lock b/composer.lock index 266019f..ce47cc5 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "35ea09eaea488e5d0e0c4a22059c367c", + "content-hash": "7fbeca42f1a6ac784e32ca1e42e61d7a", "packages": [ { "name": "brick/math", @@ -2088,6 +2088,55 @@ }, "time": "2023-05-10T11:58:31+00:00" }, + { + "name": "mindtwo/laravel-blade-spaceless", + "version": "1.2.2", + "source": { + "type": "git", + "url": "https://github.com/mindtwo/laravel-blade-spaceless.git", + "reference": "0559d365f61dbe4aba6a782736b6e782ce25714d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mindtwo/laravel-blade-spaceless/zipball/0559d365f61dbe4aba6a782736b6e782ce25714d", + "reference": "0559d365f61dbe4aba6a782736b6e782ce25714d", + "shasum": "" + }, + "require": { + "illuminate/support": "6.*|^7.0|^8.0|^9.0|^10.0" + }, + "type": "package", + "extra": { + "laravel": { + "providers": [ + "mindtwo\\Spaceless\\SpacelessServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "mindtwo\\Spaceless\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "mindtwo GmbH", + "email": "info@mindtwo.de", + "homepage": "https://www.mindtwo.de/", + "role": "Developer" + } + ], + "description": "Spaceless Blade Directive", + "support": { + "issues": "https://github.com/mindtwo/laravel-blade-spaceless/issues", + "source": "https://github.com/mindtwo/laravel-blade-spaceless/tree/1.2.2" + }, + "time": "2023-04-05T15:53:59+00:00" + }, { "name": "mnapoli/front-yaml", "version": "2.0.3", diff --git a/public/assets/scripts/dash.js b/public/assets/scripts/dash.js new file mode 100644 index 0000000..bc68474 --- /dev/null +++ b/public/assets/scripts/dash.js @@ -0,0 +1,7430 @@ +function $parcel$interopDefault(a) { + return a && a.__esModule ? a.default : a; +} +var $parcel$global = +typeof globalThis !== 'undefined' + ? globalThis + : typeof self !== 'undefined' + ? self + : typeof window !== 'undefined' + ? window + : typeof global !== 'undefined' + ? global + : {}; +//** REQUEST TYPES **// +const $cbea55afea03b976$export$1470a914435ca933 = "POST"; +const $cbea55afea03b976$export$40a64a78065efa15 = "GET"; +const $cbea55afea03b976$export$d7fd7a62023314c5 = "PUT"; +const $cbea55afea03b976$export$664fc1dd454ea59a = "DELETE"; +const $cbea55afea03b976$export$e133232680a85c80 = "json"; +const $cbea55afea03b976$export$d1a86f208bdcebe5 = "x-www-form-urlencoded"; +const $cbea55afea03b976$export$353cfe44191e6ed0 = "/api/v1/status"; +const $cbea55afea03b976$export$a5dc8f3c1ec8d90e = "/api/v1/settings/site"; +const $cbea55afea03b976$export$12171301ab2e754b = "/api/v1/settings/member"; +const $cbea55afea03b976$export$bcee0afc6bcb3973 = "/api/v1/page/create"; +const $cbea55afea03b976$export$56305c0c25c10608 = "/api/v1/page/write"; +const $cbea55afea03b976$export$af6f91c104f9c4c0 = "/api/v1/page/delete"; +const $cbea55afea03b976$export$1541f55cb44e7d14 = "/api/v1/settings/sync"; +const $cbea55afea03b976$export$42d16aa2cb1126e1 = "/api/v1/settings/publish"; +const $cbea55afea03b976$export$96c65021a69fd85 = "/api/v1/settings/nav-sync"; +const $cbea55afea03b976$export$94ef9ea0ce35d9d2 = "/api/v1/settings/reindex"; +const $cbea55afea03b976$export$8d81f3b3a5b91cea = "/api/v1/mailer"; +const $cbea55afea03b976$export$7193f1fd9d4c1e50 = "/api/v1/login"; +const $cbea55afea03b976$export$5a2be2bfb8c6b601 = "getAuthStatus"; +const $cbea55afea03b976$export$cf68b0779f5f031f = "writeSettings"; +const $cbea55afea03b976$export$6ddd598aa59a7ae3 = "publishSite"; +const $cbea55afea03b976$export$f06e28eb004ce525 = "createNewPage"; +const $cbea55afea03b976$export$a01fefcc831953fa = "editPage"; +const $cbea55afea03b976$export$f9aea0c55bfa15c9 = "deletePage"; +const $cbea55afea03b976$export$835e061c7098d585 = "sendMail"; +const $cbea55afea03b976$export$99e8e9f4661c0fb8 = "reIndexPages"; +const $cbea55afea03b976$export$ff4a0df6152bf850 = "syncSite"; +const $cbea55afea03b976$export$67799ce3e3352ee1 = "syncNav"; +const $cbea55afea03b976$export$303f528a8cb6a0ec = "getSiteSettings"; +const $cbea55afea03b976$export$497a6cff1b996002 = "getMemberInfo"; +const $cbea55afea03b976$export$67f2179ab94be531 = "apiUseAuthorized"; +const $cbea55afea03b976$export$d46ee33f41c7e43d = "apiUseNotAuthorized"; +/** + * A can of methods used to edit install settings, navigation pages and content pages + */ class $cbea55afea03b976$export$2e2bcd8739ae039 { + /** + * @constructor + * @param {string} baseURL - url of site; uses local when empty + * @param {object} progressBar - element to be used to display upload progress + */ constructor(baseURL = null, progressBar = null){ + this.percentComplete = 0; //for later + this.baseURL = null; + this.progressBar = progressBar; + this.status = false; + if (baseURL) this.baseURL = baseURL; + //asks server if a session is active + this._request(this.baseURL ? this.baseURL + $cbea55afea03b976$export$353cfe44191e6ed0 : $cbea55afea03b976$export$353cfe44191e6ed0).then((response)=>{ + if (response.type === $cbea55afea03b976$export$67f2179ab94be531) this.token = response.token; + }); + } + /** + * Promise method for authenticating and starting a session\ + * **POST**`/api/v1/login` + * @param {Object[]} data - json object that contains data for set up + * @param {string} data[].handle - handle for site user + * @param {string} data[].password - password for site user + * @example + * api.login(data).then(response=>{ + * console.log("RESPONSE", response); + * }) + * @returns {object} json object that contains type and status of login request + ``` + { + "message":"Example Message of Affirmation or what you're missing!", + "type":"exampleType", + } + ``` + */ login(data) { + return new Promise((resolve, reject)=>{ + this.baseURL ? data.remote = true : data.remote = false; + this.key ? data.key = this.key : data.key = null; + this._request(this.baseURL ? this.baseURL + $cbea55afea03b976$export$7193f1fd9d4c1e50 : $cbea55afea03b976$export$7193f1fd9d4c1e50, $cbea55afea03b976$export$5a2be2bfb8c6b601, $cbea55afea03b976$export$1470a914435ca933, $cbea55afea03b976$export$e133232680a85c80, data).then((result)=>{ + resolve(result); + }).catch((err)=>{ + reject(err); + }); + }); + } + /** + * Method for saving site and navigation settings\ + * **POST**`/api/v1/settings/:task` + * @param {string} task - settings being synced `config | navigation` + * @param {object[]} data - json object that contains settings data for [site] or [nav] + * @param {string} data[].global.base_url - base url for site [site] + * @param {string} data[].global.title - site title [site] + * @param {string} data[].global.descriptions - brief site summary [site] + * @param {string} data[].global.background - url for site feature image for header [site] + * @param {boolean} data[].global.private - privacy state for site [disabled] [site] + * @param {boolean} data[].global.renderOnSave - property for publishing site when page saved [disabled] [site] + * @param {string} data[].global.theme - current theme for site [site] + * @param {boolean} data[].global.externalAPI - toggle for external API access [site] + * @param {string} data[].member.handle - current member handle [site] + * @param {string} data[].member.email - current member email [site] + * @param {string} data[].email.active - current email protocol being used [site] + * @param {string} data[].email.smtp.domain - url of smtp service being [site] + * @param {string} data[].email.smtp.email - email account of smtp service [site] + * @param {string} data[].email.smtp.password - password for email of smtp service [site] + * @param {string} data[].email.mailgun.domain - mailgun domain url [site] + * @param {string} data[].email.mailgun.key - mailgun key [site] + * + * @param {string} data[].item.title - page title [nav] + * @param {string} data[].item.slug - url safe title [nav] + * @param {string} data[].item.uuid - unique identifier [nav] + * @param {string} data[].item.path - directory path to associated markdown file [nav] + * @example + * api.sync(TASK, data).then(response=>{ + * console.log("RESPONSE", response); + * }) + * @returns {object} json object that contains type and status of sync request + ``` + * + { + "message":"Example Message of Affirmation!", + "type":"exampleType", + } + ``` + */ sync(task, data) { + return new Promise((resolve, reject)=>{ + let url = ""; + switch(task){ + case "syncSite": + url = $cbea55afea03b976$export$1541f55cb44e7d14; + break; + case "syncNav": + url = $cbea55afea03b976$export$96c65021a69fd85; + break; + } + this._request(this.baseURL ? this.baseURL + url : url, $cbea55afea03b976$export$cf68b0779f5f031f, $cbea55afea03b976$export$1470a914435ca933, $cbea55afea03b976$export$e133232680a85c80, data).then((result)=>{ + resolve(result); + }).catch((err)=>{ + reject(err); + }); + }); + } + /** + * Method for retrieving user authorizing user login + * @param {object[]} data - json object that contains task + * @param {string} data[].task - publishing task + * @example + * api.publish(TASK).then(response=>{ + * console.log("RESPONSE", response); + * }) + * @returns {object} json object that contains type and status of publis request + * ``` + { + "message":"Example Message of Affirmation!", + "type":"exampleType", + } + * ``` + */ publish(data) { + return new Promise((resolve, reject)=>{ + this._request(//API_PUBLISH_PAGES, + this.baseURL ? this.baseURL + $cbea55afea03b976$export$42d16aa2cb1126e1 : $cbea55afea03b976$export$42d16aa2cb1126e1, $cbea55afea03b976$export$6ddd598aa59a7ae3, $cbea55afea03b976$export$1470a914435ca933, $cbea55afea03b976$export$e133232680a85c80, data).then((result)=>{ + resolve(result); + }).catch((err)=>{ + reject(err); + }); + }); + } + /** + * Method for handling page creating and editing\ + * **POST**`/api/v1/page/:task` + * @param {string} task - current page action + * @param {object[]} form - form object that contains info for current page being edited/created + * @param {string} form[].id - sequence id for page, leave empty for new page + * @param {string} form[].uuid - unique identifier for page, leave empty for new page + * @param {string} form[].layout - current page layout + * @param {string} form[].current_title - saved url save title for persistence when changing title, leave empty for new page + * @param {string} form[].content - markdown body of page + * @param {string} form[].title - current title of page + * @param {string} form[].created - date page was created, leave empty for new page + * @param {string} form[].slug - url safe string of page title + * @param {string} form[].tags - comma separated list of tags + * @param {boolean} form[].menu - property that indicates page is included in site menu + * @param {boolean} form[].featured - property that indicates page is featured + * @param {boolean} form[].published - property that indicates page is public + * @param {string} form[].form_token - hidden property to authenticate form submission + * @param {input} form[].feature_image - main image for page + * @example + * api.pageActions(TASK, data).then(response=>{ + * console.log("RESPONSE", response); + * }) + * @returns {object} json object that contains type and status of page edit request + ``` + { + "message":"Example Message of Affirmation!", + "type":"exampleType", + } + ``` + */ pageActions(task, data) { + let url, event, content; + switch(task){ + case $cbea55afea03b976$export$f06e28eb004ce525: + url = $cbea55afea03b976$export$bcee0afc6bcb3973; + event = $cbea55afea03b976$export$f06e28eb004ce525; + content = $cbea55afea03b976$export$e133232680a85c80; + break; + case $cbea55afea03b976$export$a01fefcc831953fa: + url = $cbea55afea03b976$export$56305c0c25c10608; + event = $cbea55afea03b976$export$a01fefcc831953fa; + content = $cbea55afea03b976$export$e133232680a85c80; + break; + case $cbea55afea03b976$export$f9aea0c55bfa15c9: + url = $cbea55afea03b976$export$af6f91c104f9c4c0; + event = $cbea55afea03b976$export$f9aea0c55bfa15c9; + content = $cbea55afea03b976$export$e133232680a85c80; + break; + default: + break; + } + if (this.baseURL) //data.key = this.key; + data.remote = true; + else data.remote = false; + return new Promise((resolve, reject)=>{ + this._request(this.baseURL ? this.baseURL + url : url, event, $cbea55afea03b976$export$1470a914435ca933, content, data).then((result)=>{ + resolve(result); + }).catch((err)=>{ + reject(err); + }); + }); + } + /** + * Method for sending mail (if completed in settings)\ + * **POST**`/api/v1/mailer` + * @param {object[]} message - json object that contains items to be included in main site navigation + * @param {string} message[].content - message to send + * @example + * api.sendMail(message).then(response=>{ + * console.log("RESPONSE", response); + * }) + * @returns {object} json object that contains type and status of page edit request + ``` + { + "message":"Example Message of Affirmation!", + "type":"exampleType" + } + ``` + */ sendMail(message) { + return new Promise((resolve, reject)=>{ + this._request(this.baseURL ? this.baseURL + $cbea55afea03b976$export$8d81f3b3a5b91cea : $cbea55afea03b976$export$8d81f3b3a5b91cea, $cbea55afea03b976$export$835e061c7098d585, $cbea55afea03b976$export$1470a914435ca933, $cbea55afea03b976$export$e133232680a85c80, message).then((result)=>{ + resolve(result); + }).catch((err)=>{ + reject(err); + }); + }); + } + /** + * *Promise method for retrieving site and member info*\ + * **GET** `/api/v1/settings/:type` + * @param {string} type - type of info requested ['site'|'member']; + * @example + * api.getInfo("type").then(data=>{ + console.log("Info Object", data); + * }) + * @returns {object} json object that contains data for requested information + * + * *info object example* + * ``` + { + "message":"message of affirmation!", + "task":"type of info request", + "data":json-data-object, + } + * ``` + */ getInfo(type) { + let url, task; + if (type == "site") { + url = $cbea55afea03b976$export$a5dc8f3c1ec8d90e; + task = $cbea55afea03b976$export$303f528a8cb6a0ec; + } else { + url = $cbea55afea03b976$export$12171301ab2e754b; + task = $cbea55afea03b976$export$497a6cff1b996002; + } + return new Promise((resolve, reject)=>{ + this._request(this.baseURL ? this.baseURL + url : url, task).then((result)=>{ + resolve(result); + }).catch((err)=>{ + reject(err); + }); + }); + } + //-------------------------- + // private + //-------------------------- + _request(requestURL, eventType, requestType = $cbea55afea03b976$export$40a64a78065efa15, contentType = $cbea55afea03b976$export$e133232680a85c80, requestData = null) { + var self = this; + return new Promise(function(resolve, reject) { + var request = new XMLHttpRequest(); + request.upload.addEventListener("progress", (e)=>self.handleLoadProgress(e, self.progressBar)); + request.open(requestType, requestURL, true); + request.onload = ()=>{ + if (request.status == 200) { + let response = JSON.parse(request["response"]); + resolve(response); + } else { + let error = JSON.parse(request["response"]); + reject(error); + } + }; + if (requestType == $cbea55afea03b976$export$d7fd7a62023314c5 || requestType == $cbea55afea03b976$export$1470a914435ca933) { + if (eventType === $cbea55afea03b976$export$cf68b0779f5f031f || eventType === $cbea55afea03b976$export$a01fefcc831953fa || eventType === $cbea55afea03b976$export$f06e28eb004ce525 || eventType === $cbea55afea03b976$export$f9aea0c55bfa15c9 || eventType === $cbea55afea03b976$export$6ddd598aa59a7ae3 || eventType === $cbea55afea03b976$export$99e8e9f4661c0fb8) request.setRequestHeader("fipamo-access-token", self.token); + switch(contentType){ + case $cbea55afea03b976$export$e133232680a85c80: + request.setRequestHeader("Content-type", "application/" + contentType); + request.send(JSON.stringify(requestData)); + break; + case $cbea55afea03b976$export$d1a86f208bdcebe5: + request.send(requestData); + break; + } + } else { + if (eventType === $cbea55afea03b976$export$303f528a8cb6a0ec || eventType === $cbea55afea03b976$export$497a6cff1b996002) request.setRequestHeader("fipamo-access-token", self.token); + request.send(); + } + }); + } + //-------------------------- + // event handlers + //-------------------------- + handleLoadProgress(e, progressBar) { + let percent = Math.ceil(e.loaded / e.total * 100); + //if a progress bar element is present, talk to it + if (progressBar != null) progressBar.style.width = percent + "%"; + } +} + + +//** REQUEST TYPES **// +const $7e781a188206b2b3$export$1470a914435ca933 = "POST"; +const $7e781a188206b2b3$export$40a64a78065efa15 = "GET"; +const $7e781a188206b2b3$export$d7fd7a62023314c5 = "PUT"; +const $7e781a188206b2b3$export$664fc1dd454ea59a = "DELETE"; +const $7e781a188206b2b3$export$e133232680a85c80 = "json"; +const $7e781a188206b2b3$export$d1a86f208bdcebe5 = "x-www-form-urlencoded"; +const $7e781a188206b2b3$export$353cfe44191e6ed0 = "/api/v1/status"; +const $7e781a188206b2b3$export$6010ab8005eea11c = "/api/v1/init"; +const $7e781a188206b2b3$export$52ab125bf6b9623c = "/api/v1/restore"; +const $7e781a188206b2b3$export$dbda7dc2e1902943 = "/api/v1/get-secret"; +const $7e781a188206b2b3$export$6cb20b6a23a06e47 = "/api/v1/reset-password"; +const $7e781a188206b2b3$export$7d346f7b882235dd = "/api/v1/backup"; +const $7e781a188206b2b3$export$55b2e84262898562 = "/api/v1/backup/download"; +const $7e781a188206b2b3$export$32b079f7fc0b26ca = "/api/v1/backup/restore"; +const $7e781a188206b2b3$export$359fb9097c578f21 = "/api/v1/settings/add-avatar"; +const $7e781a188206b2b3$export$739eebbd7d1f81a2 = "/api/v1/settings/add-feature-background"; +const $7e781a188206b2b3$export$ee6257de8f8b01a2 = "/api/v1/page/add-entry-image"; +const $7e781a188206b2b3$export$4d4b481c07056150 = "/api/v1/files"; +const $7e781a188206b2b3$export$2fb4d35b5b0eebb2 = "blogInit"; +const $7e781a188206b2b3$export$525ebf8030c3a323 = "restoreBackup"; +const $7e781a188206b2b3$export$fc0aff5026df5452 = "createBackup"; +const $7e781a188206b2b3$export$adaa11ae547fcbcc = "retrieveSecret"; +const $7e781a188206b2b3$export$8305e7d16f23e8bc = "resetPassword"; +const $7e781a188206b2b3$export$f90c0f4ad2c7ac2b = "uploadFiles"; +const $7e781a188206b2b3$export$67f2179ab94be531 = "apiUseAuthorized"; +const $7e781a188206b2b3$export$d46ee33f41c7e43d = "apiUseNotAuthorized"; +/** + * A tub of methods for creating/restoring installs, resetting passwords and uploading images. + */ class $7e781a188206b2b3$export$2e2bcd8739ae039 { + /** + * @constructor + * @param {string} baseURL - url of site; uses local when empty + * @param {string} key - user api key + */ constructor(baseURL = null, key = null){ + this.accetableFiles = [ + "image/jpeg", + "image/gif", + "image/png", + "image/svg", + "audio/mpeg", + "video/mp4", + "application/pdf", + "text/plain", + "text/rtf" + ]; + this.percentComplete = 0; //for later + this.token = null; + this.baseURL = null; + this.key = null; + if (key) this.key = key; + if (baseURL) this.baseURL = baseURL; + //if key is valid, checks to see if a session is active and returns + this._request(this.baseURL ? this.baseURL + $7e781a188206b2b3$export$353cfe44191e6ed0 + "?key=" + this.key : $7e781a188206b2b3$export$353cfe44191e6ed0 + "?key=" + this.key).then((response)=>{ + if (response.type === $7e781a188206b2b3$export$67f2179ab94be531) this.token = response.token; + }); + } + /** + * Promise method used create new site from scratch. For local use only. + * @param {object} data - json object that contains data for set up + * @property {string} new_member_handle - handle for new user + * @property {string} new_member_email - email for new user + * @property {string} new_member_pass - password for new user + * @property {string} new_member_title - title for new user + */ create(data) { + return new Promise((resolve, reject)=>{ + this._request($7e781a188206b2b3$export$6010ab8005eea11c, null, $7e781a188206b2b3$export$2fb4d35b5b0eebb2, $7e781a188206b2b3$export$1470a914435ca933, $7e781a188206b2b3$export$e133232680a85c80, data).then((result)=>{ + resolve(result); + }).catch((err)=>{ + reject(err); + }); + }); + } + /** + * Promise method for restoring site from a previous back up. For local use only. + * @param {object} form - form object that contains restore data and files + * @property {string} restore_member_handle - handle for site user + * @property {string} restore_member_pass - password for site user + * @property {file} backup-upload - backup zip file + */ restore(form) { + return new Promise((resolve, reject)=>{ + var url, event, method, type, data; + url = $7e781a188206b2b3$export$52ab125bf6b9623c; + event = $7e781a188206b2b3$export$525ebf8030c3a323; + method = $7e781a188206b2b3$export$1470a914435ca933; + type = $7e781a188206b2b3$export$d1a86f208bdcebe5; + data = new FormData(form); + this._request(url, null, event, method, type, data).then((result)=>{ + resolve(result); + }).catch((err)=>{ + reject(err); + }); + }); + } + /** + * Promise method for creating a zip back up of current site. For local use only. + */ backup() { + return new Promise((resolve, reject)=>{ + var url, event, method, type, data; + url = $7e781a188206b2b3$export$7d346f7b882235dd; + event = $7e781a188206b2b3$export$fc0aff5026df5452; + method = $7e781a188206b2b3$export$1470a914435ca933; + type = $7e781a188206b2b3$export$e133232680a85c80; + data = { + task: "create_backup" + }; + this._request(url, null, event, method, type, data).then((result)=>{ + resolve(result); + }).catch((err)=>{ + reject(err); + }); + }); + } + /** + * Promise method for retrieving user secret key. For local use only. + * @param {object} data - json object that contains data for set up + * @property {string} email - email for site user + */ secret(data) { + return new Promise((resolve, reject)=>{ + this._request($7e781a188206b2b3$export$dbda7dc2e1902943, $7e781a188206b2b3$export$adaa11ae547fcbcc, $7e781a188206b2b3$export$1470a914435ca933, $7e781a188206b2b3$export$e133232680a85c80, data).then((result)=>{ + resolve(result); + }).catch((err)=>{ + reject(err); + }); + }); + } + /** + * Promise method for resetting password for user. For local use only. + * @param {object} data - json object that contains data for set up + * @property {string} new_password - password for user + * @property {string} new_password2 - confirm password for user + * @property {string} secret - secret key for user + */ newPass(data) { + return new Promise((resolve, reject)=>{ + this._request($7e781a188206b2b3$export$6cb20b6a23a06e47, $7e781a188206b2b3$export$8305e7d16f23e8bc, $7e781a188206b2b3$export$1470a914435ca933, $7e781a188206b2b3$export$e133232680a85c80, data).then((result)=>{ + resolve(result); + }).catch((err)=>{ + reject(err); + }); + }); + } + /** + * Promise method for uploading files [todo: change to uploading files] + * @param {string} type - type of upload + * @param {input} files - form input containing files + */ filesUpload(type, files, progress = null) { + return new Promise((resolve, reject)=>{ + let url = $7e781a188206b2b3$export$4d4b481c07056150; + if (this.baseURL) { + files.append("key", this.key); + files.append("remote", true); + } else files.append("remote", false); + this._request(url, progress, $7e781a188206b2b3$export$f90c0f4ad2c7ac2b, $7e781a188206b2b3$export$1470a914435ca933, $7e781a188206b2b3$export$d1a86f208bdcebe5, files).then((r)=>{ + resolve(r); + }).catch((err)=>{ + reject(err); + }); + }); + } + //-------------------------- + // private + //-------------------------- + _request(requestURL, progressBar = null, eventType, requestType = $7e781a188206b2b3$export$40a64a78065efa15, contentType = $7e781a188206b2b3$export$e133232680a85c80, requestData = null) { + var self = this; + return new Promise(function(resolve, reject) { + var request = new XMLHttpRequest(); + request.upload.addEventListener("progress", (e)=>self.handleLoadProgress(e, progressBar)); + request.open(requestType, requestURL, true); + request.onload = ()=>{ + if (request.status == 200) { + let response = JSON.parse(request["response"]); + resolve(response); + } else { + let error = JSON.parse(request["response"]); + reject(error); + } + }; + if (requestType == $7e781a188206b2b3$export$d7fd7a62023314c5 || requestType == $7e781a188206b2b3$export$1470a914435ca933) { + if (eventType === $7e781a188206b2b3$export$f90c0f4ad2c7ac2b) request.setRequestHeader("fipamo-access-token", self.token); + switch(contentType){ + case $7e781a188206b2b3$export$e133232680a85c80: + request.setRequestHeader("Content-type", "application/" + contentType); + request.send(JSON.stringify(requestData)); + break; + case $7e781a188206b2b3$export$d1a86f208bdcebe5: + request.send(requestData); + break; + } + } else request.send(); + }); + } + //-------------------------- + // event handlers + //-------------------------- + handleLoadProgress(e, progressBar) { + let percent = Math.ceil(e.loaded / e.total * 100); + //if a progress bar element is present, talk to it + if (progressBar != null) progressBar.style.width = percent + "%"; + } +} + + +class $f177b50aa405d296$export$2e2bcd8739ae039 { + //-------------------------- + // constructor + //-------------------------- + constructor(){} + //-------------------------- + // methods + //-------------------------- + imgLoad(url) { + "use strict"; + // Create new promise with the Promise() constructor; + // This has as its argument a function with two parameters, resolve and reject + return new Promise(function(resolve, reject) { + // Standard XHR to load an image + var request = new XMLHttpRequest(); + request.open("GET", url); + request.responseType = "blob"; + // When the request loads, check whether it was successful + request.onload = function() { + if (request.status === 200) // If successful, resolve the promise by passing back the request response + resolve(request.response); + else // If it fails, reject the promise with a error message + reject(new Error("Image didn't load successfully; error code: " + request.status + " " + request.statusText)); + }; + request.onerror = function() { + // Also deal with the case when the entire request fails to begin with + // This is probably a network error, so reject the promise with an appropriate message + reject(new Error("There was a network error.")); + }; + // Send the request + request.send(); + }); + } + loadImage(src) { + "use strict"; + let self = this; + return new Promise(function(resolve, reject) { + // Get a reference to the body element, and create a new image object + var myImage = new Image(); + myImage.crossOrigin = ""; // or "anonymous" + // Call the function with the URL we want to load, but then chain the + // promise then() method on to the end of it. This contains two callbacks + self.imgLoad(src).then(function(response) { + // The first runs when the promise resolves, with the request.reponse specified within the resolve() method. + var imageURL = window.URL.createObjectURL(response); + resolve(imageURL); + //$('background-content').setStyle('background-image', 'url('+imageURL+')') //myImage.src = imageURL; + //console.log(imageURL); + //body.appendChild(myImage); + // The second runs when the promise is rejected, and logs the Error specified with the reject() method. + }, function(Error1) { + reject(Error1); + }); + }); + } + /** + * Create a function to convert the serialize and convert the form data to JSON + * @param : $('#form_example'); + * @return a JSON Stringify + */ formDataToJSON(form) { + let object = {}; + let formData = new FormData(form); + formData.forEach((value, key)=>{ + if (!object.hasOwnProperty(key)) { + object[key] = value; + return; + } + if (!Array.isArray(object[key])) object[key] = [ + object[key] + ]; + object[key].push(value); + }); + //let json = JSON.stringify(object); + return object; + } +} + + +const $995f55a4eccd256d$export$5a2be2bfb8c6b601 = "getAuthStatus"; +const $995f55a4eccd256d$export$844339d01bfceea4 = "requestGood"; +const $995f55a4eccd256d$export$f99ec790401d28da = "requestLame"; +const $995f55a4eccd256d$export$5fb39232fef0eeff = "apiUseAuthorized"; +const $995f55a4eccd256d$export$8829e15ac416fcee = "apiUseNotAuthorized"; +const $995f55a4eccd256d$export$4bfe4aeac5ca1c9b = "imgRequestGood"; +const $995f55a4eccd256d$export$b678e0874d52df91 = "imgRequestLame"; +const $995f55a4eccd256d$export$f78d3105e9d98a5d = "settingsLoaded"; +const $995f55a4eccd256d$export$c58a4ce4b93c5925 = "postImageAdded"; +const $995f55a4eccd256d$export$26bdbac97359953d = "featureImageAdded"; +const $995f55a4eccd256d$export$a9707c9559ca4612 = "postError"; +const $995f55a4eccd256d$export$a2d54b707b6e22e1 = "postAdded"; +const $995f55a4eccd256d$export$f88aea22a746eab = "postUpdated"; +const $995f55a4eccd256d$export$92d3c9e452b188cc = "postImageAdded"; +const $995f55a4eccd256d$export$9ab81161d8ad3297 = "pagesRendered"; +const $995f55a4eccd256d$export$a447f8a3982d1ca8 = "pagesNotRendered"; +const $995f55a4eccd256d$export$b47ada4663816e48 = "tagPagesRendered"; +const $995f55a4eccd256d$export$14f1954724290577 = "tagPagesNotRendered"; +const $995f55a4eccd256d$export$5dd76fd38bbe7841 = "settingsUpdated"; +const $995f55a4eccd256d$export$5082b4f0403769e9 = "settingsNotUpdated"; +const $995f55a4eccd256d$export$bd3b33ec4de8bf3 = "menuAddItem"; +const $995f55a4eccd256d$export$dbd640577c4e5d0d = "menuDeleteItem"; +const $995f55a4eccd256d$export$d4fd546d3456ff85 = "menuUpdated"; +const $995f55a4eccd256d$export$9b65f586914397ef = "avatarUploaded"; +const $995f55a4eccd256d$export$c3b6b85989e4a0a8 = "siteBackgroundUploaded"; +const $995f55a4eccd256d$export$c51d011f6ede1aa5 = "uploadProgress"; +const $995f55a4eccd256d$export$e0e6bcdbaa787779 = "writingItDown"; +const $995f55a4eccd256d$export$ac8c24f9b72727c3 = "writingNewEntry"; +const $995f55a4eccd256d$export$8ae3e28253adc030 = "erasingPage"; +const $995f55a4eccd256d$export$16cc4df8146e89ab = "savingSettings"; +const $995f55a4eccd256d$export$524c7f283d44a2c3 = "createBackup"; +const $995f55a4eccd256d$export$ef2d8441bb01121d = "downloadBackup"; +const $995f55a4eccd256d$export$8020812a0ef5b01d = "downloadBackup"; +const $995f55a4eccd256d$export$bd723636cbbfa9dd = "uploadProfileImages"; +const $995f55a4eccd256d$export$a5f1510cea1ffff9 = "renderPages"; +const $995f55a4eccd256d$export$94ef9ea0ce35d9d2 = "reindexPages"; +const $995f55a4eccd256d$export$6010ab8005eea11c = "blogInit"; +const $995f55a4eccd256d$export$57f3dcd64790c65 = "blogInitGood"; +const $995f55a4eccd256d$export$74a5c30fa9753d80 = "blogInitLame"; +const $995f55a4eccd256d$export$dbda7dc2e1902943 = "retrieveSecret"; +const $995f55a4eccd256d$export$6cb20b6a23a06e47 = "resetPassword"; +const $995f55a4eccd256d$export$eeb056b4f9e6ce71 = "sendMail"; +class $995f55a4eccd256d$var$DataEvent { +} +var $995f55a4eccd256d$export$2e2bcd8739ae039 = new $995f55a4eccd256d$var$DataEvent(); + + +//TOOLS + + + +class $224e88b348829f3a$var$StringUtils { + //-------------------------- + // constructor + //-------------------------- + constructor(){} + //-------------------------- + // methods + //-------------------------- + cleanString(string) { + var clean = string.replace(/(^\-+|[^a-zA-Z0-9\/_| -]+|\-+$)/g, "").toLowerCase().replace(/[\/_| -]+/g, "-"); + return clean; + } + decodeHTML(string, quote_style) { + var optTemp = 0, i = 0, noquotes = false; + if (typeof quote_style === "undefined") quote_style = 2; + string = string.toString().replace(/</g, "<").replace(/>/g, ">"); + var OPTS = { + ENT_NOQUOTES: 0, + ENT_HTML_QUOTE_SINGLE: 1, + ENT_HTML_QUOTE_DOUBLE: 2, + ENT_COMPAT: 2, + ENT_QUOTES: 3, + ENT_IGNORE: 4 + }; + if (quote_style === 0) noquotes = true; + if (typeof quote_style !== "number") { + // Allow for a single string or an array of string flags + quote_style = [].concat(quote_style); + for(i = 0; i < quote_style.length; i++){ + // Resolve string input to bitwise e.g. 'PATHINFO_EXTENSION' becomes 4 + if (OPTS[quote_style[i]] === 0) noquotes = true; + else if (OPTS[quote_style[i]]) optTemp = optTemp | OPTS[quote_style[i]]; + } + quote_style = optTemp; + } + if (quote_style & OPTS.ENT_HTML_QUOTE_SINGLE) string = string.replace(/�*39;/g, "'"); // PHP doesn't currently escape if more than one 0, but it should + if (!noquotes) string = string.replace(/"/g, '"'); + // Put this in last place to avoid escape being double-decoded + string = string.replace(/&/g, "&"); + return string; + } +} +var $224e88b348829f3a$export$2e2bcd8739ae039 = $224e88b348829f3a$var$StringUtils; + + +class $de01a7e5b1773530$export$2e2bcd8739ae039 { + //-------------------------- + // constructor + //-------------------------- + constructor(){} + //-------------------------- + // methods + //-------------------------- + collectInfo(files) { + return new Promise((resolve, reject)=>{ + let pageInfo = []; + let pageRef = document.querySelector('[role="file-manager"]'); + //process html content for storage + let txt = document.createElement("textarea"); + txt.innerHTML = document.getElementById("highlight-content").innerHTML; + let html = txt.value; + html = html.replace(/<\/?span[^>]*>/g, ""); //removes prism styling + html = html.replace(/<\/?br[^>]*>/g, "\n"); //convert back to encoded line break for storage + //build data object + pageInfo = { + id: pageRef.getAttribute("data-index"), + uuid: pageRef.getAttribute("data-uuid"), + layout: document.getElementById("page-templates").value, + current_title: pageRef.getAttribute("data-slug"), + content: html, + title: document.getElementById("post-title-text").value, + created: document.getElementById("post-date").getAttribute("data-raw"), + slug: new (0, $224e88b348829f3a$export$2e2bcd8739ae039)().cleanString(document.getElementById("post-title-text").value), + tags: document.getElementById("post-tags").value, + menu: document.getElementById("option-menu-pin").getAttribute("data-active"), + featured: document.getElementById("option-feature").getAttribute("data-active"), + published: document.getElementById("option-published").getAttribute("data-active"), + form_token: document.getElementById("form_token").value, + imageList: files.images, + fileList: files.files + }; + resolve(pageInfo); + }); + } +} + + +const $0d6abf40542266b3$export$e0c06b1ddd9992cc = "editorDelete"; +const $0d6abf40542266b3$export$80082ca64f03d0e9 = "editorUploadImage"; +const $0d6abf40542266b3$export$1844db352cf5aef3 = "editorSave"; +const $0d6abf40542266b3$export$14580fc61246740 = "editorUpdate"; +class $0d6abf40542266b3$var$EditorEvent { +} +var $0d6abf40542266b3$export$2e2bcd8739ae039 = new $0d6abf40542266b3$var$EditorEvent(); + + + +class $68b475f2a0292491$var$EventEmitter { + //-------------------------- + // constructor + //-------------------------- + constructor(){ + this.listeners = new Map(); + } + //-------------------------- + // methods + //-------------------------- + addListener(label, callback) { + this.listeners.has(label) || this.listeners.set(label, []); + this.listeners.get(label).push(callback); + } + removeListener(label, callback) { + var isFunction = function(obj) { + return typeof obj == "function" || false; + }; + var listeners = this.listeners.get(label), index; + if (listeners && listeners.length) { + index = listeners.reduce((i, listener, index)=>{ + return isFunction(listener) && listener === callback ? i = index : i; + }, -1); + if (index > -1) { + listeners.splice(index, 1); + this.listeners.set(label, listeners); + return true; + } + } + return false; + } + emitEvent(label, ...args) { + var listeners = this.listeners.get(label); + if (listeners && listeners.length) { + listeners.forEach((listener)=>{ + listener(...args); + }); + return true; + } + return false; + } +} +var $68b475f2a0292491$export$2e2bcd8739ae039 = $68b475f2a0292491$var$EventEmitter; + + + +var $4b862aa2466a294d$exports = {}; +/// +var $4b862aa2466a294d$var$_self = typeof window !== "undefined" ? window // if in browser + : typeof WorkerGlobalScope !== "undefined" && self instanceof WorkerGlobalScope ? self // if in worker + : {} // if in node js +; +/** + * Prism: Lightweight, robust, elegant syntax highlighting + * + * @license MIT + * @author Lea Verou + * @namespace + * @public + */ var $4b862aa2466a294d$var$Prism = function(_self) { + // Private helper vars + var lang = /(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i; + var uniqueId = 0; + // The grammar object for plaintext + var plainTextGrammar = {}; + var _ = { + /** + * By default, Prism will attempt to highlight all code elements (by calling {@link Prism.highlightAll}) on the + * current page after the page finished loading. This might be a problem if e.g. you wanted to asynchronously load + * additional languages or plugins yourself. + * + * By setting this value to `true`, Prism will not automatically highlight all code elements on the page. + * + * You obviously have to change this value before the automatic highlighting started. To do this, you can add an + * empty Prism object into the global scope before loading the Prism script like this: + * + * ```js + * window.Prism = window.Prism || {}; + * Prism.manual = true; + * // add a new diff --git a/resources/views/includes/editor.blade.php b/resources/views/includes/editor.blade.php new file mode 100644 index 0000000..cb671e5 --- /dev/null +++ b/resources/views/includes/editor.blade.php @@ -0,0 +1,38 @@ +
+ + + + + + + + + @if($mode == "edit") + + + @else + + @endif +
diff --git a/resources/views/includes/options.blade.php b/resources/views/includes/options.blade.php new file mode 100644 index 0000000..d93f1bc --- /dev/null +++ b/resources/views/includes/options.blade.php @@ -0,0 +1,49 @@ + +@php + +if($page['menu']) +{ + $menu = 'true'; +}else{ + $menu = 'false'; +} + +if($page['featured']) +{ + $featured = 'true'; +}else{ + $featured = 'false'; +} + +if($page['published']) +{ + $published = 'true'; +}else{ + $published = 'false'; +} + +@endphp + +
+ + + + + + diff --git a/routes/web.php b/routes/web.php index e077743..e9d3031 100644 --- a/routes/web.php +++ b/routes/web.php @@ -28,6 +28,6 @@ Route::post("/login", [AuthController::class, 'enter']); Route::group(['prefix' => 'dashboard'], function () { Route::get("/", [DashController::class, 'start']); Route::get("/pages/{pageFilter?}/{pageNum?}", [DashController::class, 'book']); - Route::get("/page/{uuid}", [DashController::class, 'page']); + Route::get("/page/{mode}/{uuid}", [DashController::class, 'page']); Route::get("/logout", [AuthController::class, 'exit']); });