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,8 +7,9 @@ const Hash = use('Hash')
const Model = use('Model') const Model = use('Model')
class User extends Model { class User extends Model {
static boot () { static boot() {
super.boot() super
.boot()
/** /**
* A hook to hash the user password before saving * A hook to hash the user password before saving
@ -21,6 +22,13 @@ class User extends Model {
}) })
} }
publicJSON() {
const u = this.toJSON();
return {
avatar: u.avatar, email: u.email, name: u.name, isAdmin: false
}
}
/** /**
* A relationship on tokens is required for auth to * A relationship on tokens is required for auth to
* work. Since features like `refreshTokens` or * work. Since features like `refreshTokens` or
@ -31,7 +39,7 @@ class User extends Model {
* *
* @return {Object} * @return {Object}
*/ */
tokens () { tokens() {
return this.hasMany('App/Models/Token') return this.hasMany('App/Models/Token')
} }
@ -42,8 +50,6 @@ class User extends Model {
links() { links() {
return this.hasMany('App/Models/Link') return this.hasMany('App/Models/Link')
} }
} }
module.exports = User module.exports = User

View file

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

View file

@ -37,7 +37,8 @@
"fork-awesome": "^1.1.7", "fork-awesome": "^1.1.7",
"sqlite3": "^4.1.1", "sqlite3": "^4.1.1",
"typescript": "^3.7.5", "typescript": "^3.7.5",
"vue": "^2.6.11" "vue": "^2.6.11",
"vue-router": "^3.1.5"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.8.3", "@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" /> <Header :appName="appName" />
<div class="columns m-t-xs"> <div class="columns m-t-xs">
<div class="column is-sidebar"> <div class="column is-sidebar">
<SideBar :title="appName" :menu="menu" selectedItem="Your Dashboard" :appName="appName" /> <SideBar :title="appName" :menu="menu" :appName="appName" />
</div> </div>
<div class="section column app-content"> <section class="section column app-content">
<!-- start shit --> <div class="container">
<div class="tile is-ancestor"> <router-view></router-view>
<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>
</section>
</div> </div>
</div> </div>
</template> </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="hero-body">
<div class="container"> <div class="container">
<h1 class="title">{{appName}}</h1> <h1 class="title">{{appName}}</h1>
<h2 class="subtitle">Test</h2>
</div> </div>
</div> </div>
</section> </section>
</template> </template>
<script lang="ts" src="./Header.ts"> <script lang="ts">
export default {
name: "Header",
props: ["appName"]
};
</script> </script>

View file

@ -1,14 +1,13 @@
// import Vue from 'vue'; <script lang="ts">
// import App from './app.vue';
// new Vue({
// render: h => h(App)
// }).$mount('#app')
<script>
import Vue from "vue"; import Vue from "vue";
import App from "./app.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) render: h => h(App)
}).$mount("#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> <template>
<div class="sidebar has-text-centered"> <div class="sidebar has-text-centered">
<div class="has-text-centered"> <div class="has-text-centered">
<router-link to="/" class>
<SidewayText textSize="is-size-6" :text="appName" :bold="true" /> <SidewayText textSize="is-size-6" :text="appName" :bold="true" />
</router-link>
<SidewayText class="is-size-6" :text="selectedItem" /> <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 class="is-size-6 has-text-weight-bold m-l-lg m-r-md">{{appName}}</div> -->
</div> </div>
<aside class="menu is-primary p-xxs sidebar-menu"> <aside class="menu is-primary p-xxs sidebar-menu">
<ul class="menu-list"> <ul class="menu-list">
<li v-for="item in menu" class="m-t-md m-b-md"> <li v-for="item in menu" class="m-t-md m-b-md" @click="onItemClicked(item)">
<a :href="item.href" :class="['button',{ 'is-active': !!item.isActive }]"> <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> <i :class="['icon', item.icon]"></i>
</a> </a>
</li> </li>
@ -16,4 +33,35 @@
</aside> </aside>
</div> </div>
</template> </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>--> </div>-->
</template> </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"> <div id="app">
Loading... Loading...
</div> </div>
{{ script('scripts/applications/home/home.bundle.js') }} {{ script('scripts/applications/home/app.bundle.js') }}
@endsection @endsection

View file

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

View file

@ -16,7 +16,6 @@
/** @type {typeof import('@adonisjs/framework/src/Route/Manager')} */ /** @type {typeof import('@adonisjs/framework/src/Route/Manager')} */
const Route = use('Route') const Route = use('Route')
Route.get('/', 'IndexController.index').as('home');
/* /*
/ Auth / Auth
@ -36,3 +35,18 @@ Route
'/applications/story-time', '/applications/story-time',
({view}) => view.render('applications.story-time.app')) ({view}) => view.render('applications.story-time.app'))
.middleware(['auth']); .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", "target": "es5",
"sourceMap": true, "sourceMap": true,
"allowJs": true, "allowJs": true,
"lib": [
"dom",
"es2015"
],
"experimentalDecorators": true "experimentalDecorators": true
}, },
"include": [ "include": [
"resources/scripts/applications/story-time/app.ts" "resources/scripts/main.ts"
], ],
"exclude": [ "exclude": [
"node_modules", "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 = { module.exports = {
mode: 'development', mode: 'development',
entry: { entry: {
'story-time': './resources/scripts/applications/story-time/main.vue', 'components': './resources/scripts/components/navbar.ts',
'home': './resources/scripts/applications/home/main.vue',
// App2: './App2/main.js'
// '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: { module: {
rules: [ rules: [
{ {
@ -45,12 +47,12 @@ module.exports = {
}, },
}, },
{ {
test: /\.tsx?$/, test: /\.ts?$/,
use: [ use: [
{loader: 'babel-loader'}, { {loader: 'babel-loader'}, {
loader: 'ts-loader', loader: 'ts-loader',
options: { options: {
appendTsSuffixTo: [/\.ts\.vue$/], appendTsSuffixTo: [/\.vue$/, /\.ts$/],
appendTsxSuffixTo: [/\.tsx\.vue$/] appendTsxSuffixTo: [/\.tsx\.vue$/]
} }
} }
@ -86,10 +88,6 @@ module.exports = {
}, },
extensions: ['*', '.vue', '.js', '.ts', '.json'], extensions: ['*', '.vue', '.js', '.ts', '.json'],
}, },
output: {
filename: 'scripts/applications/[name]/[name].bundle.js',
path: path.resolve(__dirname, 'public')
},
watchOptions: {aggregateTimeout: 300, poll: 1000}, watchOptions: {aggregateTimeout: 300, poll: 1000},
// webpack outputs performance related stuff in the browser. // webpack outputs performance related stuff in the browser.
performance: { performance: {