This commit is contained in:
Sagi Dayan 2020-02-02 17:42:18 -05:00
parent 165e0ad97c
commit ca3976dea9
34 changed files with 1552 additions and 365 deletions

View File

@ -7,18 +7,26 @@ const Hash = use('Hash')
const Model = use('Model')
class User extends Model {
static boot () {
super.boot()
static boot() {
super
.boot()
/**
* A hook to hash the user password before saving
* it to the database.
*/
this.addHook('beforeSave', async (userInstance) => {
if (userInstance.dirty.password) {
userInstance.password = await Hash.make(userInstance.password)
}
})
/**
* A hook to hash the user password before saving
* it to the database.
*/
this.addHook('beforeSave', async (userInstance) => {
if (userInstance.dirty.password) {
userInstance.password = await Hash.make(userInstance.password)
}
})
}
publicJSON() {
const u = this.toJSON();
return {
avatar: u.avatar, email: u.email, name: u.name, isAdmin: false
}
}
/**
@ -31,7 +39,7 @@ class User extends Model {
*
* @return {Object}
*/
tokens () {
tokens() {
return this.hasMany('App/Models/Token')
}
@ -42,8 +50,6 @@ class User extends Model {
links() {
return this.hasMany('App/Models/Link')
}
}
module.exports = User

View File

@ -4,19 +4,20 @@
const Schema = use('Schema')
class UserSchema extends Schema {
up () {
up() {
this.create('users', (table) => {
table.increments()
table.string('email', 254).notNullable().unique()
table.string('name').notNullable()
table.string('password', 60).notNullable()
table.string('avatar')
table.timestamps()
})
table.increments();
table.string('email', 254).notNullable().unique();
table.string('name').notNullable();
table.string('password', 60).notNullable();
table.string('avatar');
table.boolean('is_admin').defaultTo(false).notNullable();
table.timestamps();
});
}
down () {
this.drop('users')
down() {
this.drop('users');
}
}

View File

@ -37,7 +37,8 @@
"fork-awesome": "^1.1.7",
"sqlite3": "^4.1.1",
"typescript": "^3.7.5",
"vue": "^2.6.11"
"vue": "^2.6.11",
"vue-router": "^3.1.5"
},
"devDependencies": {
"@babel/core": "^7.8.3",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,43 +0,0 @@
import Header from "./components/Header";
import {
default as SideBar,
IMenuItem
} from "../shared/components/SideBar/SideBar";
const menu: IMenuItem[] = [
{
href: '#',
text: 'Start a session',
isActive: false,
icon: 'fa fa-bookmark'
},
{
href: '#',
text: 'Create something',
isActive: true,
icon: 'fa fa-book',
},
{
href: '/logout',
text: 'Logout',
icon: 'fa fa-gears',
isActive: false
},
{
href: '/logout',
text: 'Logout',
icon: 'fa fa-sign-out',
isActive: false
}
]
export default {
name: "app",
components: {
SideBar,
Header
},
data: () => ({
appName: "Home",
menu
})
};

View File

@ -3,59 +3,63 @@
<Header :appName="appName" />
<div class="columns m-t-xs">
<div class="column is-sidebar">
<SideBar :title="appName" :menu="menu" selectedItem="Your Dashboard" :appName="appName" />
<SideBar :title="appName" :menu="menu" :appName="appName" />
</div>
<div class="section column app-content">
<!-- start shit -->
<div class="tile is-ancestor">
<div class="tile is-vertical is-8">
<div class="tile">
<div class="tile is-parent is-vertical">
<article class="tile is-child notification is-primary">
<p class="title">Vertical...</p>
<p class="subtitle">Top tile</p>
</article>
<article class="tile is-child notification is-warning">
<p class="title">...tiles</p>
<p class="subtitle">Bottom tile</p>
</article>
</div>
<div class="tile is-parent">
<article class="tile is-child notification is-info">
<p class="title">Middle tile</p>
<p class="subtitle">With an image</p>
<figure class="image is-4by3">
<img src="https://bulma.io/images/placeholders/640x480.png" />
</figure>
</article>
</div>
</div>
<div class="tile is-parent">
<article class="tile is-child notification is-danger">
<p class="title">Wide tile</p>
<p class="subtitle">Aligned with the right tile</p>
<div class="content">
<!-- Content -->
</div>
</article>
</div>
</div>
<div class="tile is-parent">
<article class="tile is-child notification is-success">
<div class="content">
<p class="title">Tall tile</p>
<p class="subtitle">With even more content</p>
<div class="content">
<!-- Content -->
</div>
</div>
</article>
</div>
<section class="section column app-content">
<div class="container">
<router-view></router-view>
</div>
<!-- end shit -->
</div>
</section>
</div>
</div>
</template>
<script lang="ts" src="./app.ts"/>
<script lang="ts">
import Header from "./components/Header.vue";
// import AppRouter from "./router/router.vue";
import {
default as SideBar,
IMenuItem
} from "../shared/components/SideBar/SideBar.vue";
const menu: IMenuItem[] = [
{
href: "/",
text: "Home",
isRouterLink: true,
icon: "fa fa-home"
},
{
href: "/applications",
text: "Applications",
isRouterLink: true,
icon: "fa fa-puzzle-piece"
},
{
href: "/settings",
isRouterLink: true,
text: "Settings",
icon: "fa fa-gears"
},
{
isRouterLink: false,
href: "/logout",
text: "Logout",
icon: "fa fa-sign-out"
}
];
export default {
name: "App",
// router: AppRouter,
components: {
SideBar,
Header
},
data() {
return {
appName: "Seepur",
menu
};
}
};
</script>

View File

@ -1,4 +0,0 @@
export default {
name: "Header",
props: ['appName']
}

View File

@ -3,10 +3,13 @@
<div class="hero-body">
<div class="container">
<h1 class="title">{{appName}}</h1>
<h2 class="subtitle">Test</h2>
</div>
</div>
</section>
</template>
<script lang="ts" src="./Header.ts">
<script lang="ts">
export default {
name: "Header",
props: ["appName"]
};
</script>

View File

@ -1,14 +1,13 @@
// import Vue from 'vue';
// import App from './app.vue';
// new Vue({
// render: h => h(App)
// }).$mount('#app')
<script>
<script lang="ts">
import Vue from "vue";
import App from "./app.vue";
new Vue({
import AppRouter from "./router/router.vue";
// Vue.use(VueRouter);
const app = new Vue({
router: AppRouter,
render: h => h(App)
}).$mount("#app");
</script>
export default app;
</script>

View File

@ -0,0 +1,37 @@
<script lang="ts">
import Vue from "vue";
import VueRouter, {
RouteConfig,
RouterOptions,
RouterMode,
NavigationGuard
} from "vue-router";
Vue.use(VueRouter);
// Views
import Home from "../views/home.vue";
import Settings from "../views/settings.vue";
import Applications from "../views/application.vue";
const routes: RouteConfig[] = [
/** Define Application Routes */
{
path: "/",
component: Home,
name: "root"
},
{
path: "/settings",
component: Settings
},
{
path: "/applications",
component: Applications
}
];
const AppRouter = new VueRouter({ routes, mode: "history" });
export default AppRouter;
</script>

View File

@ -0,0 +1,15 @@
<template>
<div class="wrapper">
<h1 class="is-1">Applications!!!</h1>
</div>
</template>
<script lang="ts">
export default {
name: "Applications",
beforeCreate: () => {
console.log("before create home vue");
}
};
</script>

View File

@ -0,0 +1,15 @@
<template>
<div class="wrapper">
<h1 class="is-1">HOME!!!</h1>
</div>
</template>
<script lang="ts">
export default {
name: "Home",
beforeCreate: () => {
console.log("before create home vue");
}
};
</script>

View File

@ -0,0 +1,32 @@
<template>
<div class="wrapper">
<h1 class="is-1">Settings {{ user.name }}!!!</h1>
</div>
</template>
<script lang="ts">
let user: {
avatar?: string;
email?: string;
name: string;
isAdmin: boolean;
} = {
name: "LOADING...",
isAdmin: false
};
export default {
name: "Settings",
beforeCreate() {},
async created() {
const response = await fetch("/users/profile/");
this.user = await response.json();
},
data() {
return {
user
};
}
};
</script>

View File

@ -1,15 +0,0 @@
import SidewayText from '../SidewayText/SidewayText';
export interface IMenuItem {
href: string;
text: string;
icon: string;
isActive: boolean;
}
export default {
components: {
SidewayText
},
name: "SideMenu",
props: ["menu", "title", "appName", "selectedItem"]
};

View File

@ -1,14 +1,31 @@
<template>
<div class="sidebar has-text-centered">
<div class="has-text-centered">
<SidewayText textSize="is-size-6" :text="appName" :bold="true" />
<router-link to="/" class>
<SidewayText textSize="is-size-6" :text="appName" :bold="true" />
</router-link>
<SidewayText class="is-size-6" :text="selectedItem" />
<!-- <div class="is-size-6 has-text-weight-bold m-l-lg m-r-md">{{appName}}</div> -->
</div>
<aside class="menu is-primary p-xxs sidebar-menu">
<ul class="menu-list">
<li v-for="item in menu" class="m-t-md m-b-md">
<a :href="item.href" :class="['button',{ 'is-active': !!item.isActive }]">
<li v-for="item in menu" class="m-t-md m-b-md" @click="onItemClicked(item)">
<router-link
active-class="is-active"
v-if="item.isRouterLink"
:to="item.href"
class="button"
exact
:title="item.text"
>
<i :class="['icon', item.icon]"></i>
</router-link>
<a
v-else
:href="item.href"
:title="item.text"
:class="['button',{ 'is-active': !!item.isActive }]"
>
<i :class="['icon', item.icon]"></i>
</a>
</li>
@ -16,4 +33,35 @@
</aside>
</div>
</template>
<script lang="ts" src="./SideBar.ts" />
<script lang="ts" >
import SidewayText from "../SidewayText/SidewayText.vue";
export interface IMenuItem {
href: string;
text: string;
icon: string;
isRouterLink: boolean;
}
export default {
components: {
SidewayText
},
beforeCreate() {},
created() {
let currentPage = this.$router.currentRoute.path.split("/")[1];
if (currentPage) currentPage[0].toUpperCase;
else currentPage = this.menu[0].text;
this.selectedItem = currentPage;
},
methods: {
onItemClicked(item: IMenuItem) {
this.selectedItem = item.text;
}
},
data: () => ({
selectedItem: ""
}),
name: "SideBar",
props: ["menu", "title", "appName"]
};
</script>

View File

@ -1,9 +0,0 @@
export interface ISidewayText {
class: string;
}
export default {
props: ["text", "bold", "textSize"],
data: () => ({
}),
};

View File

@ -13,4 +13,13 @@
</div>-->
</template>
<script lang="ts" src="./SidewayText.ts" />
<script lang="ts" >
export interface ISidewayText {
class: string;
}
export default {
name: "SidewayText",
props: ["text", "bold", "textSize"],
data: () => ({})
};
</script>

View File

@ -1,43 +0,0 @@
import Header from "./components/Header";
import {
default as SideBar,
IMenuItem
} from "../shared/components/SideBar/SideBar";
const menu: IMenuItem[] = [
{
href: '#',
text: 'Start a session',
isActive: false,
icon: 'fa fa-bookmark'
},
{
href: '#',
text: 'Create something',
isActive: true,
icon: 'fa fa-book',
},
{
href: '/logout',
text: 'Logout',
icon: 'fa fa-gears',
isActive: false
},
{
href: '/logout',
text: 'Logout',
icon: 'fa fa-sign-out',
isActive: false
}
]
export default {
name: "app",
components: {
SideBar,
Header
},
data: () => ({
appName: "Story Time",
menu
})
};

View File

@ -1,61 +0,0 @@
<template>
<div class="app">
<Header username="sagi" />
<div class="columns m-t-xs">
<div class="column is-sidebar">
<SideBar :title="appName" :menu="menu" selectedItem="Test" :appName="appName" />
</div>
<div class="section column app-content">
<!-- start shit -->
<div class="tile is-ancestor">
<div class="tile is-vertical is-8">
<div class="tile">
<div class="tile is-parent is-vertical">
<article class="tile is-child notification is-primary">
<p class="title">Vertical...</p>
<p class="subtitle">Top tile</p>
</article>
<article class="tile is-child notification is-warning">
<p class="title">...tiles</p>
<p class="subtitle">Bottom tile</p>
</article>
</div>
<div class="tile is-parent">
<article class="tile is-child notification is-info">
<p class="title">Middle tile</p>
<p class="subtitle">With an image</p>
<figure class="image is-4by3">
<img src="https://bulma.io/images/placeholders/640x480.png" />
</figure>
</article>
</div>
</div>
<div class="tile is-parent">
<article class="tile is-child notification is-danger">
<p class="title">Wide tile</p>
<p class="subtitle">Aligned with the right tile</p>
<div class="content">
<!-- Content -->
</div>
</article>
</div>
</div>
<div class="tile is-parent">
<article class="tile is-child notification is-success">
<div class="content">
<p class="title">Tall tile</p>
<p class="subtitle">With even more content</p>
<div class="content">
<!-- Content -->
</div>
</div>
</article>
</div>
</div>
<!-- end shit -->
</div>
</div>
</div>
</template>
<script lang="ts" src="./app.ts"/>

View File

@ -1,4 +0,0 @@
export default {
name: "Header",
props: ['username']
}

View File

@ -1,12 +0,0 @@
<template>
<section class="hero is-small is-primary hero-bg-landing01">
<div class="hero-body">
<div class="container">
<h1 class="title">{{username}} Story Time</h1>
<h2 class="subtitle">Test</h2>
</div>
</div>
</section>
</template>
<script lang="ts" src="./Header.ts">
</script>

View File

@ -1,16 +0,0 @@
// import Vue from 'vue';
// import App from './app.vue';
// new Vue({
// render: h => h(App)
// }).$mount('#app')
<script>
import Vue from 'vue';
import App from './app.vue';
new Vue({
render: h => h(App)
}).$mount('#app')
</script>

View File

View File

@ -5,5 +5,5 @@
<div id="app">
Loading...
</div>
{{ script('scripts/applications/home/home.bundle.js') }}
{{ script('scripts/applications/home/app.bundle.js') }}
@endsection

View File

@ -12,35 +12,36 @@ const Server = use('Server')
| match.
|
*/
const globalMiddleware = [
'Adonis/Middleware/BodyParser',
'Adonis/Middleware/Session',
'Adonis/Middleware/Shield',
'Adonis/Middleware/AuthInit',
'App/Middleware/ConvertEmptyStringsToNull',
]
const globalMiddleware =
[
'Adonis/Middleware/BodyParser',
'Adonis/Middleware/Session',
'Adonis/Middleware/Shield',
'Adonis/Middleware/AuthInit',
'App/Middleware/ConvertEmptyStringsToNull',
]
/*
|--------------------------------------------------------------------------
| Named Middleware
|--------------------------------------------------------------------------
|
| Named middleware is key/value object to conditionally add middleware on
| specific routes or group of routes.
|
| // define
| {
| auth: 'Adonis/Middleware/Auth'
| }
|
| // use
| Route.get().middleware('auth')
|
*/
const namedMiddleware = {
auth: 'Adonis/Middleware/Auth',
guest: 'Adonis/Middleware/AllowGuestOnly'
}
/*
|--------------------------------------------------------------------------
| Named Middleware
|--------------------------------------------------------------------------
|
| Named middleware is key/value object to conditionally add middleware on
| specific routes or group of routes.
|
| // define
| {
| auth: 'Adonis/Middleware/Auth'
| }
|
| // use
| Route.get().middleware('auth')
|
*/
const namedMiddleware = {
auth: 'Adonis/Middleware/Auth',
guest: 'Adonis/Middleware/AllowGuestOnly'
}
/*
|--------------------------------------------------------------------------
@ -52,12 +53,8 @@ const namedMiddleware = {
| control over request lifecycle.
|
*/
const serverMiddleware = [
'Adonis/Middleware/Static',
'Adonis/Middleware/Cors'
]
const serverMiddleware = ['Adonis/Middleware/Static', 'Adonis/Middleware/Cors']
Server
.registerGlobal(globalMiddleware)
.registerNamed(namedMiddleware)
.use(serverMiddleware)
Server.registerGlobal(globalMiddleware)
.registerNamed(namedMiddleware)
.use(serverMiddleware);

View File

@ -16,7 +16,6 @@
/** @type {typeof import('@adonisjs/framework/src/Route/Manager')} */
const Route = use('Route')
Route.get('/', 'IndexController.index').as('home');
/*
/ Auth
@ -36,3 +35,18 @@ Route
'/applications/story-time',
({view}) => view.render('applications.story-time.app'))
.middleware(['auth']);
/** Basic APIs */
Route
.get(
'/users/profile',
({request, response, auth}) => {
console.log('twergsg');
const u = auth.user.publicJSON();
response.send(u);
// return auth.user;
})
.middleware(['auth']);
Route.get('/*', 'IndexController.index').as('home');

10
start/startup_script.js Normal file
View File

@ -0,0 +1,10 @@
const User = use('App/Models/User');
export default class StartupScript {
static async run() {
// TODO: Create a new Model AppSettings (has a field for initial run) check
// if there is a app settings;
SettingItems - hasMenySettings
appCatagory -
}
}

View File

@ -5,10 +5,14 @@
"target": "es5",
"sourceMap": true,
"allowJs": true,
"lib": [
"dom",
"es2015"
],
"experimentalDecorators": true
},
"include": [
"resources/scripts/applications/story-time/app.ts"
"resources/scripts/main.ts"
],
"exclude": [
"node_modules",

101
webpack.config copy.js Normal file
View File

@ -0,0 +1,101 @@
const path = require('path');
const webpack = require('webpack');
// const HtmlWebpackPlugin = require('html-webpack-plugin');
// const CleanWebpackPlugin = require('clean-webpack-plugin');
// const CopyWebpackPlugin = require('copy-webpack-plugin');
const {VueLoaderPlugin} = require('vue-loader')
require('babel-loader');
require('ts-loader');
const resolve = relativePath => path.resolve(__dirname, '..', relativePath);
module.exports = {
mode: 'development',
entry: {
'components': './resources/scripts/components/navbar.ts',
// 'applications/story-time':
// './resources/scripts/applications/story-time/main.vue',
'applications/home': './resources/scripts/applications/home/main.vue',
},
output: {
filename: 'scripts/[name]/app.bundle.js',
path: path.resolve(__dirname, 'public'),
},
module: {
rules: [
{
// vue-loader config to load `.vue` files or single file components.
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
// https://vue-loader.vuejs.org/guide/scoped-css.html#mixing-local-and-global-styles
css: [
'vue-style-loader', {
loader: 'css-loader',
}
],
ts: [
'ts-loader',
],
js: [
'babel-loader',
],
},
cacheBusting: true,
},
},
{
test: /\.tsx?$/,
use: [
{loader: 'babel-loader'}, {
loader: 'ts-loader',
options: {
appendTsSuffixTo: [/\.ts\.vue$/],
appendTsxSuffixTo: [/\.tsx\.vue$/]
}
}
],
exclude: /node_modules/
},
{
// This is required for other javascript you are gonna write besides
// vue.
test: /\.js$/,
loader: 'babel-loader',
include: [
resolve('src'),
resolve('node_modules/webpack-dev-server/client'),
],
},
]
},
plugins: [
new webpack.NamedModulesPlugin(),
new VueLoaderPlugin(),
// Exchanges, adds, or removes modules while an application is running,
// without a full reload.
new webpack.HotModuleReplacementPlugin(),
],
resolve: {
/**
* The compiler-included build of vue which allows to use vue templates
* without pre-compiling them
*/
alias: {
'vue$': 'vue/dist/vue.esm.js',
},
extensions: ['*', '.vue', '.js', '.ts', '.json'],
},
// output: {
// filename: 'scripts/applications/[name]/[name].bundle.js',
// path: path.resolve(__dirname, 'public')
// },
watchOptions: {aggregateTimeout: 300, poll: 1000},
// webpack outputs performance related stuff in the browser.
performance: {
hints: false,
},
node: {fs: 'empty'}
}

View File

@ -11,15 +11,17 @@ const resolve = relativePath => path.resolve(__dirname, '..', relativePath);
module.exports = {
mode: 'development',
entry: {
'story-time': './resources/scripts/applications/story-time/main.vue',
'home': './resources/scripts/applications/home/main.vue',
// App2: './App2/main.js'
'components': './resources/scripts/components/navbar.ts',
// 'applications/story-time':
// './resources/scripts/applications/story-time/main.vue',
'applications/home': './resources/scripts/applications/home/main.vue',
},
output: {
filename: 'scripts/[name]/app.bundle.js',
path: path.resolve(__dirname, 'public'),
},
// output: {
// filename: '[name].js',
// // Folder where the output of webpack's result go.
// path: resolve('public'),
// },
module: {
rules: [
{
@ -45,12 +47,12 @@ module.exports = {
},
},
{
test: /\.tsx?$/,
test: /\.ts?$/,
use: [
{loader: 'babel-loader'}, {
loader: 'ts-loader',
options: {
appendTsSuffixTo: [/\.ts\.vue$/],
appendTsSuffixTo: [/\.vue$/, /\.ts$/],
appendTsxSuffixTo: [/\.tsx\.vue$/]
}
}
@ -86,10 +88,6 @@ module.exports = {
},
extensions: ['*', '.vue', '.js', '.ts', '.json'],
},
output: {
filename: 'scripts/applications/[name]/[name].bundle.js',
path: path.resolve(__dirname, 'public')
},
watchOptions: {aggregateTimeout: 300, poll: 1000},
// webpack outputs performance related stuff in the browser.
performance: {