@ -1,13 +1,8 @@ | |||
composer.phar | |||
/vendor/ | |||
node_modules | |||
.env | |||
*.log | |||
rysnc_exclude | |||
/storage/database | |||
/storage/files | |||
storage/database/* | |||
!storage/database/.gitkeep | |||
storage/cache/* | |||
!storage/cache/.gitkeep | |||
!/storage/database/.gitkeep | |||
!/storage/files/.gitkeep |
@ -1,28 +0,0 @@ | |||
<?php | |||
namespace App\Flight; | |||
use Flight; | |||
/** | |||
* abstract FlightAbstract get instance of flight engine | |||
* | |||
* | |||
* @author Björn Hase | |||
* @license http://opensource.org/licenses/MIT The MIT License | |||
* | |||
*/ | |||
abstract class FlightAbstract | |||
{ | |||
/** object of flight */ | |||
protected $app; | |||
/** | |||
* getting object of flight | |||
* | |||
*/ | |||
public function __construct() | |||
{ | |||
$this->app = Flight::app(); | |||
} | |||
} |
@ -1,42 +0,0 @@ | |||
<?php | |||
/** | |||
* fake function for blade @inject | |||
* | |||
* @param string $class | |||
* @return object | |||
*/ | |||
function app($class) | |||
{ | |||
return new $class(); | |||
} | |||
/** | |||
* function similar to blade asset | |||
* | |||
* @param $path | |||
* @return string | |||
* | |||
*/ | |||
function asset($path, $prefix = '/public') | |||
{ | |||
// get flight | |||
$app = Flight::app(); | |||
// getting basePath | |||
$basePath = $app->get('basePath'); | |||
// path to mix-manifest | |||
$file = $app->get('basePath').'mix-manifest.json'; | |||
if (file_exists($file)) { | |||
$manifest = file_get_contents($file); | |||
$files = json_decode($manifest, true); | |||
if (isset($files[$prefix.$path])) { | |||
$path = str_replace($prefix, '', $files[$prefix.$path]); | |||
} | |||
} | |||
return $path; | |||
} |
@ -1,39 +0,0 @@ | |||
<?php | |||
namespace App\Http; | |||
use Rakit\Validation\Validator; | |||
use App\Flight\FlightAbstract; | |||
use App\Models\Bucket; | |||
use Carbon\Carbon; | |||
/** | |||
* | |||
* | |||
* | |||
* | |||
* @author Björn Hase | |||
* @link https://gitea.tentakelfabrik.de/mITSM/feedback GitHub Repository | |||
* | |||
* | |||
*/ | |||
class Bucket extends FlightAbstract | |||
{ | |||
public function viewAction($id) | |||
{ | |||
$this->app->render('bucket', [ | |||
'id' => $id | |||
]); | |||
} | |||
public function indexAction($id, $visibilty, $page) | |||
{ | |||
$bucketStore = new Bucket(); | |||
$publicBuckets = $bucketStore->findBy(); | |||
$this->app->json([ | |||
'publicBuckets' => $publicBuckets | |||
]); | |||
} | |||
} |
@ -1,29 +0,0 @@ | |||
<?php | |||
namespace App\Http; | |||
use Rakit\Validation\Validator; | |||
use App\Flight\FlightAbstract; | |||
use App\Models\Bucket; | |||
use Carbon\Carbon; | |||
/** | |||
* | |||
* | |||
* | |||
* | |||
* @author Björn Hase | |||
* @link https://gitea.tentakelfabrik.de/mITSM/feedback GitHub Repository | |||
* | |||
* | |||
*/ | |||
class Home extends FlightAbstract | |||
{ | |||
public function indexAction() | |||
{ | |||
$this->app->render('home', [ | |||
]); | |||
} | |||
} |
@ -1,58 +0,0 @@ | |||
<?php | |||
namespace App\Http; | |||
use Rakit\Validation\Validator; | |||
use App\Flight\FlightAbstract; | |||
use App\Models\Bucket; | |||
use Carbon\Carbon; | |||
/** | |||
* | |||
* | |||
* | |||
* | |||
* @author Björn Hase | |||
* @link https://gitea.tentakelfabrik.de/mITSM/feedback GitHub Repository | |||
* | |||
* | |||
*/ | |||
class Note extends FlightAbstract | |||
{ | |||
/** | |||
* | |||
* @param integer $id | |||
* | |||
*/ | |||
public function viewAction($id) | |||
{ | |||
$this->app->render('bucket', [ | |||
'id' => $id | |||
]); | |||
} | |||
public function indexAction($bucketId) | |||
{ | |||
$noteStore = new Note(); | |||
$notes = $noteStore->findBy(); | |||
$this->app->json([ | |||
'data' => $notes, | |||
'page' => $page | |||
]); | |||
} | |||
public function createAction($bucketId) | |||
{ | |||
$result = [ | |||
'success' => false | |||
]; | |||
$noteStore = new Note(); | |||
$this->app->json([ | |||
'data' => $notes, | |||
]); | |||
} | |||
} |
@ -1,26 +0,0 @@ | |||
<?php | |||
namespace App\Models; | |||
/** | |||
* Store for Courses | |||
* | |||
* | |||
* @author Björn Hase | |||
* @link https://gitea.tentakelfabrik.de/mITSM/feedback GitHub Repository | |||
* | |||
*/ | |||
class Bucket extends ModelAbstract | |||
{ | |||
// name of store | |||
protected $name = 'buckets'; | |||
public function findByVisiblity($visiblity) | |||
{ | |||
return $this->store->findBy( | |||
[ 'visiblity' => $visiblity ], | |||
[ 'created_at' => 'ASC' ], | |||
100 | |||
); | |||
} | |||
} |
@ -1,46 +0,0 @@ | |||
<?php | |||
namespace App\Models; | |||
use SleekDB\Store; | |||
use SleekDB\Query; | |||
/** | |||
* Abstract Class for Stores | |||
* | |||
* | |||
* @author Björn Hase | |||
* @link https://gitea.tentakelfabrik.de/mITSM/feedback GitHub Repository | |||
* | |||
*/ | |||
class ModelAbstract | |||
{ | |||
// store of model | |||
public $store; | |||
// name of store | |||
protected $name; | |||
// configuration of store | |||
protected $configuration = [ | |||
'auto_cache' => true, | |||
'cache_lifetime' => null, | |||
'timeout' => 120, | |||
'primary_key' => '_id', | |||
'search' => [ | |||
'min_length' => 2, | |||
'mode' => 'or', | |||
'score_key' => 'scoreKey', | |||
'algorithm' => Query::SEARCH_ALGORITHM['hits'] | |||
] | |||
]; | |||
/** | |||
* | |||
* | |||
*/ | |||
public function __construct() | |||
{ | |||
$this->store = new Store($this->name, __DIR__.'/../../storage/database', $this->configuration); | |||
} | |||
} |
@ -1,17 +0,0 @@ | |||
<?php | |||
namespace App\Models; | |||
/** | |||
* Store for Tags | |||
* | |||
* | |||
* @author Björn Hase | |||
* @link https://gitea.tentakelfabrik.de/mITSM/feedback GitHub Repository | |||
* | |||
*/ | |||
class Tag extends ModelAbstract | |||
{ | |||
// name of store | |||
protected $name = 'tags'; | |||
} |
@ -1,17 +0,0 @@ | |||
<?php | |||
namespace App\Models; | |||
/** | |||
* Store for Users | |||
* | |||
* | |||
* @author Björn Hase | |||
* @link https://gitea.tentakelfabrik.de/mITSM/feedback GitHub Repository | |||
* | |||
*/ | |||
class User extends ModelAbstract | |||
{ | |||
// name of store | |||
protected $name = 'users'; | |||
} |
@ -1,31 +0,0 @@ | |||
<?php | |||
// adding functions | |||
require_once(__DIR__.'/Flight/Functions.php'); | |||
// adding env | |||
$env = Dotenv\Dotenv::createImmutable(__DIR__.'/..'); | |||
$env->load(); | |||
// display all errors if debug is true | |||
if (getenv('DEBUG') === true) { | |||
error_reporting(E_ALL); | |||
ini_set('display_errors', 1); | |||
} | |||
// create app | |||
$app = Flight::app(); | |||
// setting view path | |||
$app->set('flight.views.path', __DIR__.'/../resources/views'); | |||
// adding blade for templates | |||
Flight::register('view', 'Jenssegers\Blade\Blade', [ $app->get('flight.views.path'), __DIR__.'/../storage/cache']); | |||
Flight::map('render', function($view, $data) { | |||
echo Flight::view()->make($view, $data); | |||
}); | |||
// setting path | |||
$app->set('basePath', __DIR__.'/../'); | |||
$app->set('publicPath', __DIR__.'/../public'); | |||
$app->set('storagePath', __DIR__.'/../storage'); |
@ -1,16 +0,0 @@ | |||
{ | |||
"require": { | |||
"mikecao/flight": "^1.3", | |||
"rakibtg/sleekdb": "^2.11", | |||
"vlucas/phpdotenv": "^5.3", | |||
"jenssegers/blade": "^1.4", | |||
"rakit/validation": "^1.4", | |||
"nesbot/carbon": "^2.49", | |||
"microweber/screen": "^1.0" | |||
}, | |||
"autoload": { | |||
"psr-4": { | |||
"App\\": "app/" | |||
} | |||
} | |||
} |
@ -0,0 +1,5 @@ | |||
{ | |||
"/public/js/index.js": "/public/js/index.js", | |||
"/public/js/critical.js": "/public/js/critical.js", | |||
"/public/css/index.css": "/public/css/index.css" | |||
} |
@ -0,0 +1,19 @@ | |||
{ | |||
"private": true, | |||
"scripts": { | |||
"test": "echo \"Error: no test specified\" && exit 1" | |||
}, | |||
"author": "me@herr-hase.wtf", | |||
"license": "GPL", | |||
"dependencies": { | |||
"turbolinks": "^5.2.0" | |||
}, | |||
"devDependencies": { | |||
"@riotjs/webpack-loader": "^5.0.0", | |||
"cross-env": "^7.0.3", | |||
"laravel-mix": "^6.0.25", | |||
"resolve-url-loader": "^4.0.0", | |||
"sass": "^1.35.1", | |||
"sass-loader": "^12.1.0" | |||
} | |||
} |
@ -0,0 +1,5 @@ | |||
.turbolinks-progress-bar { | |||
width: 5px; | |||
height: 100%; | |||
background-color: blue; | |||
} |
@ -1,18 +0,0 @@ | |||
<?php | |||
require __DIR__.'/../vendor/autoload.php'; | |||
require __DIR__.'/../app/bootstrap.php'; | |||
$app->route('GET /', array(new App\Http\Home, 'homeAction')); | |||
$app->route('GET /bucket/@id:[0-9]', array(new App\Http\Bucket, 'viewAction')); | |||
$app->route('GET /bucket/@id:[0-9]', array(new App\Http\Bucket, 'indexAction')); | |||
$app->route('POST /bucket', array(new App\Http\Bucket, 'createAction')); | |||
$app->route('PUT /bucket/@id:[0-9]', array(new App\Http\Bucket, 'updateAction')); | |||
$app->route('DELETE /bucket/@id:[0-9]', array(new App\Http\Bucket, 'destroyAction')); | |||
$app->route('POST /note', array(new App\Http\Note, 'createAction')); | |||
$app->route('PUT /note/@id:[0-9]', array(new App\Http\Note, 'updateAction')); | |||
$app->route('DELETE /note/@id:[0-9]', array(new App\Http\Note, 'destroyAction')); | |||
$app->start(); |
@ -0,0 +1,166 @@ | |||
/******/ (() => { // webpackBootstrap | |||
/******/ var __webpack_modules__ = ({ | |||
/***/ "./resources/js/index.js": | |||
/*!*******************************!*\ | |||
!*** ./resources/js/index.js ***! | |||
\*******************************/ | |||
/***/ (() => { | |||
/***/ }), | |||
/***/ "./resources/scss/index.scss": | |||
/*!***********************************!*\ | |||
!*** ./resources/scss/index.scss ***! | |||
\***********************************/ | |||
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { | |||
"use strict"; | |||
__webpack_require__.r(__webpack_exports__); | |||
// extracted by mini-css-extract-plugin | |||
/***/ }) | |||
/******/ }); | |||
/************************************************************************/ | |||
/******/ // The module cache | |||
/******/ var __webpack_module_cache__ = {}; | |||
/******/ | |||
/******/ // The require function | |||
/******/ function __webpack_require__(moduleId) { | |||
/******/ // Check if module is in cache | |||
/******/ var cachedModule = __webpack_module_cache__[moduleId]; | |||
/******/ if (cachedModule !== undefined) { | |||
/******/ return cachedModule.exports; | |||
/******/ } | |||
/******/ // Create a new module (and put it into the cache) | |||
/******/ var module = __webpack_module_cache__[moduleId] = { | |||
/******/ // no module.id needed | |||
/******/ // no module.loaded needed | |||
/******/ exports: {} | |||
/******/ }; | |||
/******/ | |||
/******/ // Execute the module function | |||
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); | |||
/******/ | |||
/******/ // Return the exports of the module | |||
/******/ return module.exports; | |||
/******/ } | |||
/******/ | |||
/******/ // expose the modules object (__webpack_modules__) | |||
/******/ __webpack_require__.m = __webpack_modules__; | |||
/******/ | |||
/************************************************************************/ | |||
/******/ /* webpack/runtime/chunk loaded */ | |||
/******/ (() => { | |||
/******/ var deferred = []; | |||
/******/ __webpack_require__.O = (result, chunkIds, fn, priority) => { | |||
/******/ if(chunkIds) { | |||
/******/ priority = priority || 0; | |||
/******/ for(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1]; | |||
/******/ deferred[i] = [chunkIds, fn, priority]; | |||
/******/ return; | |||
/******/ } | |||
/******/ var notFulfilled = Infinity; | |||
/******/ for (var i = 0; i < deferred.length; i++) { | |||
/******/ var [chunkIds, fn, priority] = deferred[i]; | |||
/******/ var fulfilled = true; | |||
/******/ for (var j = 0; j < chunkIds.length; j++) { | |||
/******/ if ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) { | |||
/******/ chunkIds.splice(j--, 1); | |||
/******/ } else { | |||
/******/ fulfilled = false; | |||
/******/ if(priority < notFulfilled) notFulfilled = priority; | |||
/******/ } | |||
/******/ } | |||
/******/ if(fulfilled) { | |||
/******/ deferred.splice(i--, 1) | |||
/******/ result = fn(); | |||
/******/ } | |||
/******/ } | |||
/******/ return result; | |||
/******/ }; | |||
/******/ })(); | |||
/******/ | |||
/******/ /* webpack/runtime/hasOwnProperty shorthand */ | |||
/******/ (() => { | |||
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) | |||
/******/ })(); | |||
/******/ | |||
/******/ /* webpack/runtime/make namespace object */ | |||
/******/ (() => { | |||
/******/ // define __esModule on exports | |||
/******/ __webpack_require__.r = (exports) => { | |||
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { | |||
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); | |||
/******/ } | |||
/******/ Object.defineProperty(exports, '__esModule', { value: true }); | |||
/******/ }; | |||
/******/ })(); | |||
/******/ | |||
/******/ /* webpack/runtime/jsonp chunk loading */ | |||
/******/ (() => { | |||
/******/ // no baseURI | |||
/******/ | |||
/******/ // object to store loaded and loading chunks | |||
/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched | |||
/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded | |||
/******/ var installedChunks = { | |||
/******/ "/public/js/index": 0, | |||
/******/ "public/css/index": 0 | |||
/******/ }; | |||
/******/ | |||
/******/ // no chunk on demand loading | |||
/******/ | |||
/******/ // no prefetching | |||
/******/ | |||
/******/ // no preloaded | |||
/******/ | |||
/******/ // no HMR | |||
/******/ | |||
/******/ // no HMR manifest | |||
/******/ | |||
/******/ __webpack_require__.O.j = (chunkId) => (installedChunks[chunkId] === 0); | |||
/******/ | |||
/******/ // install a JSONP callback for chunk loading | |||
/******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => { | |||
/******/ var [chunkIds, moreModules, runtime] = data; | |||
/******/ // add "moreModules" to the modules object, | |||
/******/ // then flag all "chunkIds" as loaded and fire callback | |||
/******/ var moduleId, chunkId, i = 0; | |||
/******/ for(moduleId in moreModules) { | |||
/******/ if(__webpack_require__.o(moreModules, moduleId)) { | |||
/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; | |||
/******/ } | |||
/******/ } | |||
/******/ if(runtime) var result = runtime(__webpack_require__); | |||
/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); | |||
/******/ for(;i < chunkIds.length; i++) { | |||
/******/ chunkId = chunkIds[i]; | |||
/******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) { | |||
/******/ installedChunks[chunkId][0](); | |||
/******/ } | |||
/******/ installedChunks[chunkIds[i]] = 0; | |||
/******/ } | |||
/******/ return __webpack_require__.O(result); | |||
/******/ } | |||
/******/ | |||
/******/ var chunkLoadingGlobal = self["webpackChunk"] = self["webpackChunk"] || []; | |||
/******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0)); | |||
/******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal)); | |||
/******/ })(); | |||
/******/ | |||
/************************************************************************/ | |||
/******/ | |||
/******/ // startup | |||
/******/ // Load entry module and return exports | |||
/******/ // This entry module depends on other loaded chunks and execution need to be delayed | |||
/******/ __webpack_require__.O(undefined, ["public/css/index"], () => (__webpack_require__("./resources/js/index.js"))) | |||
/******/ var __webpack_exports__ = __webpack_require__.O(undefined, ["public/css/index"], () => (__webpack_require__("./resources/scss/index.scss"))) | |||
/******/ __webpack_exports__ = __webpack_require__.O(__webpack_exports__); | |||
/******/ | |||
/******/ })() | |||
; |
@ -0,0 +1,4 @@ | |||
const Turbolinks = require('turbolinks') | |||
Turbolinks.start() | |||
Turbolinks.setProgressBarDelay(500) |
@ -0,0 +1,5 @@ | |||
.turbolinks-progress-bar { | |||
width: 5px; | |||
height: 100%; | |||
background-color: blue; | |||
} |
@ -0,0 +1,55 @@ | |||
<% layout('./../layout.html') %> | |||
<div class="container"> | |||
<div class="grid"> | |||
<div class="col-12"> | |||
<h2> | |||
Create Bucket | |||
</h2> | |||
</div> | |||
<div class="col-12"> | |||
<form action="/bucket/store" method="POST" novalidate> | |||
<div class="field"> | |||
<label class="field__label"> | |||
title* | |||
<input class="field__text" name="title" type="text" /> | |||
</label> | |||
</div> | |||
<div class="field"> | |||
<label class="field__label"> | |||
description* | |||
<input class="field__text" name="description" type="text" /> | |||
</label> | |||
</div> | |||
<div class="field"> | |||
<label class="field__label"> | |||
type* | |||
<% it.types.forEach(function(type) { %> | |||
<input class="field__choice" name="type" type="radio" value="<%= type.value %>" /> | |||
<span class="field__help"> | |||
<%= type %> | |||
</span> | |||
<% }) %> | |||
</label> | |||
</div> | |||
<div class="field"> | |||
<label class="field__label"> | |||
visiblity* | |||
<% it.visiblities.forEach(function(visiblity) { %> | |||
<input class="field__choice" name="visiblity" type="radio" value="<%= visiblity.value %>" /> | |||
<span> | |||
<%= visiblity %> | |||
</span> | |||
<% }) %> | |||
</label> | |||
</div> | |||
<div class=""> | |||
<button class="button"> | |||
Create | |||
</button> | |||
</div> | |||
</form> | |||
</div> | |||
</div> | |||
</div> |
@ -0,0 +1,12 @@ | |||
<% layout('./../layout.html') %> | |||
<div class="container"> | |||
<div class="grid"> | |||
<div class="col-12"> | |||
<h1><%= it.bucket.title %></h1> | |||
<span> | |||
<%= it.bucket.description %> | |||
</span> | |||
</div> | |||
</div> | |||
</div> |
@ -0,0 +1 @@ | |||
404 |
@ -0,0 +1 @@ | |||
ldjlsjfl |
@ -1,24 +0,0 @@ | |||
@extends('layout') | |||
@section('main') | |||
<div class="container"> | |||
<h2> | |||
Buckets | |||
<button class="button"> | |||
Create | |||
</button> | |||
</h2> | |||
<h3> | |||
</h3> | |||
<app-buckets></app-buckets> | |||
</div> | |||
@push('scripts') | |||
<script type="text/javascript" src="js/buckets.js"></script> | |||
<script type="text/javascript" defer> | |||
riot.mount('buckets', {!! json_encode([ 'buckets' => $buckets ]) !!}); | |||
</script> | |||
@endpush | |||
@endsection |
@ -0,0 +1,22 @@ | |||
<% layout('./layout.html') %> | |||
<div class="container"> | |||
<div class="grid"> | |||
<div class="col-12"> | |||
<h2> | |||
Buckets | |||
<a class="button" href="/bucket/create"> | |||
Create | |||
</a> | |||
</h2> | |||
</div> | |||
<h3> | |||
Your Buckets | |||
</h3> | |||
<app-buckets visiblity="private"></app-buckets> | |||
<h3> | |||
Other Buckets | |||
</h3> | |||
<app-buckets visiblity="public,community"></app-buckets> | |||
</div> | |||
</div> |
@ -1,55 +0,0 @@ | |||
<!DOCTYPE html> | |||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}"> | |||
<head> | |||
<meta charset="utf-8"> | |||
<meta name="viewport" content="width=device-width, initial-scale=1"> | |||
<title>Nano Buckets</title> | |||
@yield('head') | |||
<link rel="stylesheet" href="css/app.css" /> | |||
</head> | |||
<body> | |||
<header class="app-header"> | |||
<div class="container is-fluid pt-2 pb-2"> | |||
<nav class="navbar" role="navigation" aria-label="main navigation"> | |||
<div class="navbar-brand"> | |||
<a class="navbar-item" href="/"> | |||
<img class="app-header__logo" src="/logo.svg" alt="Urban Filehub" /> | |||
<span class="app-header__title ml-2"> | |||
Filehub<strong>.Freifunk Minden</strong> | |||
</span> | |||
</a> | |||
</div> | |||
<div class="navbar-menu"> | |||
<div class="navbar-start"> | |||
<a class="navbar-item"> | |||
Dashboard | |||
</a> | |||
</div> | |||
</div> | |||
</nav> | |||
</div> | |||
</header> | |||
<section class="section"> | |||
<div class="container is-fluid mt-3 mb-4"> | |||
<urban-accordion> | |||
<div title="Send me a Link"> | |||
<urban-login-email></urban-login-email> | |||
</div> | |||
<div title="Login with Password"> | |||
<urban-login-password></urban-login-password> | |||
</div> | |||
</urban-accordion> | |||
</div> | |||
</section> | |||
<main> | |||
@yield('main') | |||
</main> | |||
<script type="text/javascript" src="js/app.js"></script> | |||
@stack('scripts') | |||
</body> | |||
</html> |
@ -0,0 +1,31 @@ | |||
<!DOCTYPE html> | |||
<html lang="en"> | |||
<head> | |||
<meta charset="utf-8"> | |||
<meta name="viewport" content="width=device-width, initial-scale=1"> | |||
<title>Nano Buckets</title> | |||
<link rel="stylesheet" href="/css/index.css" /> | |||
<script type="text/javascript" src="/js/critical.js" defer></script> | |||
</head> | |||
<body> | |||
<header class="app-header"> | |||
<div class="container"> | |||
<nav class="navbar" role="navigation" aria-label="main navigation"> | |||
</nav> | |||
</div> | |||
</header> | |||
<section class="app-section"> | |||
<div class=""> | |||
</div> | |||
</section> | |||
<main> | |||
<%~ it.body %> | |||
</main> | |||
</body> | |||
</html> |
@ -0,0 +1,43 @@ | |||
import 'https://deno.land/x/dotenv@v2.0.0/load.ts' | |||
import { | |||
opine, | |||
serveStatic, | |||
json, | |||
urlencoded | |||
} from 'https://deno.land/x/opine@1.5.3/mod.ts' | |||
import { dirname, join, createError } from "https://deno.land/x/opine@1.5.3/deps.ts"; | |||
import { renderFile } from 'https://deno.land/x/eta@v1.12.2/mod.ts' | |||
// getting routes | |||
import index from './src/http/index.ts' | |||
import bucket from './src/http/bucket.ts' | |||
import bucketApi from './src/http/api/bucket.ts' | |||
const app = opine() | |||
const __dirname = dirname(import.meta.url) | |||
// | |||
app.use(json()); // for parsing application/json | |||
app.use(urlencoded()); // for parsing application/x-www-form-urlencoded | |||
// adding static files | |||
app.use(serveStatic(join(__dirname, 'public'))) | |||
// adding eta as view engine | |||
app.engine('.html', renderFile) | |||
app.set('views', join(__dirname, 'resources/views')) | |||
app.set('view engine', 'html') | |||
// adding http classes for routes | |||
app.use('/', index) | |||
app.use('/bucket', bucket) | |||
app.use('/api/bucket', bucketApi) | |||
app.use((request, response, next) => { | |||
response.setStatus(404) | |||
response.render('errors/404') | |||
}) | |||
// let it rain | |||
app.listen(Number(Deno.env.get('SERVER_PORT'))) | |||
console.log('running on ' + Deno.env.get('SERVER_PORT')) | |||
@ -0,0 +1,18 @@ | |||
import Enum from 'https://deno.land/x/enum@v3.0.4/index.js' | |||
// visibilties are a template for the roles | |||
export const visibilties = new Enum([ | |||
'PUBLIC', | |||
'COMMUNITY', | |||
'PRIVATE' | |||
], { freeze: true, name: 'visibilties' }) | |||
// types define the structure of a bucket | |||
// kanban: columns with title | |||
// masonry: wall with columns and each note can have different hight | |||
// blog: all notes will be organized in one column | |||
export const types = new Enum([ | |||
'KANBAN', | |||
'MASONRY', | |||
'BLOG' | |||
], { freeze: true, name: 'types' }) |
@ -0,0 +1,49 @@ | |||
import { Router } from 'https://deno.land/x/opine@1.5.3/mod.ts' | |||
const router = Router() | |||
/** | |||
* | |||
* | |||
* @param request | |||
* @param response | |||
* @return | |||
*/ | |||
router.get('/:uuid', function(request, response) { | |||
}) | |||
/** | |||
* | |||
* | |||
* @param request | |||
* @param response | |||
* @return | |||
*/ | |||
router.post('/', function(request, response, next) { | |||
}) | |||
/** | |||
* | |||
* | |||
* @param request | |||
* @param response | |||
* @return | |||
*/ | |||
router.put('/:uuid', function(request, response, next) { | |||
}) | |||
/** | |||
* | |||
* | |||
* @param request | |||
* @param response | |||
* @return | |||
*/ | |||
router.delete('/:uuid', function(request, response, next) { | |||
}) | |||
export default router |
@ -0,0 +1,46 @@ | |||
import { Router } from 'https://deno.land/x/opine@1.5.3/mod.ts' | |||
const router = Router() | |||
/** | |||
* | |||
* | |||
* @param request | |||
* @param response | |||
* @return | |||
*/ | |||
router.post('/:bucket_id', function(request, response) | |||
{ | |||
const [ valid, errors ] = await validate(body, { | |||
title: [ maxLength(255) ], | |||
content: [ maxLength(10922) ], | |||
tags: [ ], | |||
url: isUrl | |||
}) | |||
}) | |||
/** | |||
* | |||
* | |||
* @param request | |||
* @param response | |||
* @return | |||
*/ | |||
router.put('/:bucket_id/:id', function(request, response, next) | |||
{ | |||
}) | |||
/** | |||
* | |||
* | |||
* @param request | |||
* @param response | |||
* @return | |||
*/ | |||
router.delete('/:bucket_id/:id', function(request, response, next) | |||
{ | |||
}) | |||
export default router |
@ -0,0 +1,102 @@ | |||
import { Router } from 'https://deno.land/x/opine@1.5.3/mod.ts' | |||
import { v4 } from "https://deno.land/std@0.99.0/uuid/mod.ts"; | |||
import { validate, required, isIn, maxLength } from 'https://deno.land/x/validasaur@v0.15.0/mod.ts' | |||
import { Database } from 'https://deno.land/x/aloedb@0.9.0/mod.ts' | |||
import { escapeHtml } from "https://deno.land/x/escape@1.3.0/mod.ts" | |||
import { BucketSchema } from './../stores/bucket.ts' | |||
import { visibilties, types } from './../enums/bucket.ts' | |||
const router = Router() | |||
/** | |||
* render template for form | |||
* | |||
* @param request | |||
* @param response | |||
* @return | |||
*/ | |||
router.get('/create', function(request, response, next) | |||
{ | |||
response.render('bucket/form', { | |||
visiblities: visibilties.enums, | |||
types: types.enums | |||
}) | |||
}) | |||
/** | |||
* render template for form | |||
* | |||
* @param request | |||
* @param response | |||
* @return | |||
*/ | |||
router.post('/store', async function(request, response, next) | |||
{ | |||
const body = request.body | |||
let typeValues = <any>[] | |||
let visiblityValues = <any>[] | |||
types.enums.forEach(function(type) { | |||
typeValues.push(String(type.value)) | |||
}) | |||
visibilties.enums.forEach(function(visiblity) { | |||
visiblityValues.push(String(visiblity.value)) | |||
}) | |||
// escape before validate | |||
if (body.title) { | |||
body.title = escapeHtml(body.title) | |||
} | |||
if (body.description) { | |||
body.description = escapeHtml(body.description) | |||
} | |||
const [ valid, errors ] = await validate(body, { | |||
title: [ required, maxLength(255) ], | |||
description: [ required, maxLength(255) ], | |||
type: [ required, isIn(typeValues) ], | |||
visiblity: [ required, isIn(visiblityValues)] | |||
}); | |||
if (valid) { | |||
const db = new Database<BucketSchema>('./storage/database/buckets.json') | |||
body._id = v4.generate() | |||
const bucket = await db.insertOne(body) | |||
response.redirect('/bucket/' + bucket._id) | |||
} else { | |||
response.redirect('/bucket/create') | |||
} | |||
}) | |||
/** | |||
* render template for form | |||
* | |||
* @param request | |||
* @param response | |||
* @return | |||
*/ | |||
router.get('/:id', async function(request, response, next) | |||
{ | |||
if (!v4.validate(request.params.id)) { | |||
response.setStatus(404) | |||
} | |||
const db = new Database<BucketSchema>('./storage/database/buckets.json') | |||
const bucket = await db.findOne({ '_id': request.params.id }) | |||
if (!bucket) { | |||
response.setStatus(404) | |||
} | |||
response.render('bucket/single', { | |||
bucket: bucket | |||
}) | |||
}) | |||
export default router |
@ -0,0 +1,16 @@ | |||
import { Router } from 'https://deno.land/x/opine@1.5.3/mod.ts' | |||
const router = Router() | |||
/** | |||
* render template for form | |||
* | |||
* @param request | |||
* @param response | |||
* @return | |||
*/ | |||
router.get('/', function(request, response, next) { | |||
response.render('index') | |||
}) | |||
export default router |
@ -0,0 +1,43 @@ | |||
import { Drash } from 'https://deno.land/x/drash@v1.4.4/mod.ts' | |||
import { v4 } from 'https://deno.land/std@0.99.0/uuid/mod.ts' | |||
import { Bucket as BucketSchema } from './src/schemas/bucket.ts' | |||
import Schema, { Type, string, number, array } from 'https://denoporter.sirjosh.workers.dev/v1/deno.land/x/computed_types/src/index.ts' | |||
/** | |||
* | |||
* | |||
*/ | |||
export class BucketResource extends Drash.Http.Resource | |||
{ | |||
// route | |||
static paths = ['/bucket/[:id?]'] | |||
/** | |||
* [GET description] | |||
* @param id [description] | |||
* @return [description] | |||
*/ | |||
public GET(id) | |||
{ | |||
const db = new Database<BucketSchema>() | |||
const buckets = await db.findOne({ | |||
'_id': id | |||
}) | |||
this.response.body = bucket | |||
return this.response | |||
} | |||
/** | |||
* | |||
* | |||
*/ | |||
public POST() | |||
{ | |||
const db = new Database<BucketSchema>() | |||
this.response.body = bucket | |||
return this.response | |||
} | |||
} |
@ -0,0 +1,24 @@ | |||
import { Drash } from 'https://deno.land/x/drash@v1.4.4/mod.ts' | |||
import { v4 } from 'https://deno.land/std@0.99.0/uuid/mod.ts' | |||
import { Bucket as BucketSchema } from './src/schemas/bucket.ts' | |||
/** | |||
* | |||
* | |||
*/ | |||
export class BucketResource extends Drash.Http.Resource | |||
{ | |||
// route | |||
static paths = ['/buckets'] | |||
// | |||
public GET() | |||
{ | |||
const db = new Database<BucketSchema>() | |||
const buckets = await db.findMany() | |||
this.response.body = buckets | |||
return this.response | |||
} | |||
} |
@ -0,0 +1,18 @@ | |||
import { Drash } from 'https://deno.land/x/drash@v1.4.4/mod.ts' | |||
/** | |||
* | |||
* | |||
*/ | |||
export class IndexResource extends Drash.Http.Resource | |||
{ | |||
// route | |||
static paths = ['/'] | |||
// | |||
public GET() | |||
{ | |||
this.response.body = 'Hallo' | |||
return this.response | |||
} | |||
} |
@ -0,0 +1,14 @@ | |||
import { Database } from 'https://deno.land/x/aloedb/mod.ts'; | |||
class BaseStore | |||
{ | |||
construct() | |||
{ | |||
this.db = new Database<('./storage/database/' + this.name + '.json') | |||
} | |||
uuid() | |||
{ | |||
} | |||
} |
@ -0,0 +1,10 @@ | |||
export interface BucketSchema { | |||
_id: string; | |||
title: string; | |||
description: string; | |||
owner: string; | |||
configuration: string[]; | |||
visiblity: string; | |||
created_at: string; | |||
updated_at: string; | |||
} |
@ -0,0 +1,8 @@ | |||
export interface Note { | |||
_id: string; | |||
title: string; | |||
type: string; | |||
content: string; | |||
attachment: array; | |||
tags: string[]; | |||
} |
@ -0,0 +1,4 @@ | |||
interface Tag { | |||
_bucket_id: string; | |||
name: string; | |||
} |
@ -0,0 +1,6 @@ | |||
interface Bucket { | |||
_id: string; | |||
username: string; | |||
password: string; | |||
displayname: string; | |||
} |
@ -0,0 +1,13 @@ | |||
import { validate, required, isNumber } from 'https://deno.land/x/validasaur@0.15.0/mod.ts' | |||
// create shema for validation | |||
const BucketSchema = Schema({ | |||
title: string.trim().normalize(), | |||
description: string.trim().normalize().optional(), | |||
type: Schema.either('a', 'b', 'c'), | |||
visiblity: Schema.either('a', 'b', 'c') | |||
}) | |||
// create type and get validator from schema | |||
export type bucketType = Type<typeof BucketSchema> | |||
export const bucketValidator = BucketSchema.destruct() |
@ -0,0 +1,15 @@ | |||
import Schema, { Type, string, number, array } from 'https://denoporter.sirjosh.workers.dev/v1/deno.land/x/computed_types/src/index.ts' | |||
// create shema for validation | |||
const NoteSchema = Schema({ | |||
title: string.trim().normalize(), | |||
description: string.trim().normalize().optional(), | |||
type: Schema.either('a', 'b', 'c'), | |||
visiblity: Schema.either('a', 'b', 'c') | |||
}) | |||
// create type and get validator from schema | |||
type Note = Type<typeof NoteSchema> | |||
const validator = NoteSchema.destruct() | |||
export default validator |
@ -0,0 +1,14 @@ | |||
import Schema, { Type, string, number, array } from 'https://denoporter.sirjosh.workers.dev/v1/deno.land/x/computed_types/src/index.ts' | |||
// create shema for validation | |||
const UserSchema = Schema({ | |||
username: string.trim().normalize(), | |||
password: string.normalize(), | |||
email: Schema.email() | |||
}) | |||
// create type and get validator from schema | |||
type User = Type<typeof UserSchema> | |||
const validator = UserSchema.destruct() | |||
export default validator |
@ -0,0 +1,23 @@ | |||
const mix = require('laravel-mix') | |||
/* | |||
|-------------------------------------------------------------------------- | |||
| Mix Asset Management | |||
|-------------------------------------------------------------------------- | |||
| | |||
| Mix provides a clean, fluent API for defining some Webpack build steps | |||
| for your Laravel application. By default, we are compiling the Sass | |||
| file for the application as well as bundling up all the JS files. | |||
| | |||
*/ | |||
mix.options({ | |||
terser: { | |||
extractComments: false | |||
} | |||
}) | |||
mix | |||
.js('resources/js/index.js', 'public/js') | |||
.js('resources/js/critical.js', 'public/js') | |||
.sass('resources/scss/index.scss', 'public/css') |