Skip to content

Commit a90c4cd

Browse files
committed
added a few tests
1 parent 700dc2e commit a90c4cd

File tree

7 files changed

+373
-1
lines changed

7 files changed

+373
-1
lines changed

bootstrap.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@
7070
*/
7171
$response = new Zend\Diactoros\Response();
7272
$response = $response
73-
->withHeader('Content-Type', 'text/html')
73+
// ->withHeader('Content-Type', 'text/html')
7474
->withAddedHeader('X-Phreak-KEY', $config->system['site_key'])
7575
->withHeader('Cache-Control', 'private, max-age=3600, must-revalidate');
7676
$request = Zend\Diactoros\ServerRequestFactory::fromGlobals();

modules/admin/controllers/Dashboard.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,10 @@ public function getDashboard() {
2222
$this->template->display('layout.tpl');
2323
}
2424

25+
public function getVue() {
26+
$this->template->setTemplateDir(ROOT_DIR.'/modules/admin/views/');
27+
$this->template->left_delimiter = "{!";
28+
$this->template->right_delimiter = "!}";
29+
$this->template->display('vue.tpl');
30+
}
2531
}

modules/admin/views/vue.tpl

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
<html lang="en">
2+
<head>
3+
<meta charset="utf-8">
4+
<meta http-equiv="x-ua-compatible" content="ie=edge">
5+
<title>Vue.js CRUD application</title>
6+
<meta name="description" content="">
7+
<meta name="viewport" content="width=device-width, initial-scale=1">
8+
<link rel="stylesheet" media="all" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" />
9+
10+
<style>
11+
.logo {
12+
width: 75px;
13+
float: left;
14+
margin-right: 15px;
15+
}
16+
17+
.form-group {
18+
max-width: 500px;
19+
}
20+
21+
.actions {
22+
padding: 10px 0;
23+
}
24+
25+
.glyphicon-euro {
26+
font-size: 12px;
27+
}
28+
</style>
29+
</head>
30+
<body>
31+
32+
<div class="container">
33+
<header class="page-header">
34+
<div class="branding">
35+
<img src="https://vuejs.org/images/logo.png" alt="Logo" title="Home page" class="logo"/>
36+
<h1>Vue.js 2 CRUD application</h1>
37+
</div>
38+
</header>
39+
<main id="app">
40+
<router-view></router-view>
41+
</main>
42+
</div>
43+
44+
<template id="product-list">
45+
<div>
46+
<div class="actions">
47+
<router-link class="btn btn-default" v-bind:to="{path: '/add-product'}">
48+
<span class="glyphicon glyphicon-plus"></span>
49+
Add product
50+
</router-link>
51+
</div>
52+
<div class="filters row">
53+
<div class="form-group col-sm-3">
54+
<label for="search-element">Product name</label>
55+
<input v-model="searchKey" class="form-control" id="search-element" requred/>
56+
</div>
57+
</div>
58+
<table class="table">
59+
<thead>
60+
<tr>
61+
<th>Name</th>
62+
<th>Description</th>
63+
<th>Price</th>
64+
<th class="col-sm-2">Actions</th>
65+
</tr>
66+
</thead>
67+
<tbody>
68+
<tr v-for="product in filteredProducts">
69+
<td>
70+
<router-link v-bind:to="{name: 'product', params: {product_id: product.id}}">{{ product.name }}</router-link>
71+
</td>
72+
<td>{{ product.description }}</td>
73+
<td>
74+
{{ product.price }}
75+
<span class="glyphicon glyphicon-euro" aria-hidden="true"></span>
76+
</td>
77+
<td>
78+
<router-link class="btn btn-warning btn-xs" v-bind:to="{name: 'product-edit', params: {product_id: product.id}}">Edit</router-link>
79+
<router-link class="btn btn-danger btn-xs" v-bind:to="{name: 'product-delete', params: {product_id: product.id}}">Delete</router-link>
80+
</td>
81+
</tr>
82+
</tbody>
83+
</table>
84+
</div>
85+
</template>
86+
87+
<template id="add-product">
88+
<div>
89+
<h2>Add new product</h2>
90+
<form v-on:submit="createProduct">
91+
<div class="form-group">
92+
<label for="add-name">Name</label>
93+
<input class="form-control" id="add-name" v-model="product.name" required/>
94+
</div>
95+
<div class="form-group">
96+
<label for="add-description">Description</label>
97+
<textarea class="form-control" id="add-description" rows="10" v-model="product.description"></textarea>
98+
</div>
99+
<div class="form-group">
100+
<label for="add-price">Price, <span class="glyphicon glyphicon-euro"></span></label>
101+
<input type="number" class="form-control" id="add-price" v-model="product.price"/>
102+
</div>
103+
<button type="submit" class="btn btn-primary">Create</button>
104+
<router-link class="btn btn-default" v-bind:to="'/'">Cancel</router-link>
105+
</form>
106+
</div>
107+
</template>
108+
109+
<template id="product">
110+
<div>
111+
<h2>{{ product.name }}</h2>
112+
<b>Description: </b>
113+
<div>{{ product.description }}</div>
114+
<b>Price:</b>
115+
<div>{{ product.price }}<span class="glyphicon glyphicon-euro"></span></div>
116+
<br/>
117+
<span class="glyphicon glyphicon-arrow-left" aria-hidden="true"></span>
118+
<router-link v-bind:to="'/'">Back to product list</router-link>
119+
</div>
120+
</template>
121+
122+
<template id="product-edit">
123+
<div>
124+
<h2>Edit product</h2>
125+
<form v-on:submit="updateProduct">
126+
<div class="form-group">
127+
<label for="edit-name">Name</label>
128+
<input class="form-control" id="edit-name" v-model="product.name" required/>
129+
</div>
130+
<div class="form-group">
131+
<label for="edit-description">Description</label>
132+
<textarea class="form-control" id="edit-description" rows="3" v-model="product.description"></textarea>
133+
</div>
134+
<div class="form-group">
135+
<label for="edit-price">Price, <span class="glyphicon glyphicon-euro"></span></label>
136+
<input type="number" class="form-control" id="edit-price" v-model="product.price"/>
137+
</div>
138+
<button type="submit" class="btn btn-primary">Save</button>
139+
<router-link class="btn btn-default" v-bind:to="'/'">Cancel</router-link>
140+
</form>
141+
</div>
142+
</template>
143+
144+
<template id="product-delete">
145+
<div>
146+
<h2>Delete product {{ product.name }}</h2>
147+
<form v-on:submit="deleteProduct">
148+
<p>The action cannot be undone.</p>
149+
<button type="submit" class="btn btn-danger">Delete</button>
150+
<router-link class="btn btn-default" v-bind:to="'/'">Cancel</router-link>
151+
</form>
152+
</div>
153+
</template>
154+
155+
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.js"></script>
156+
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/2.2.1/vue-router.js"></script>
157+
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
158+
<script src="{!BASE_URL!}/assets/js/vueapp.js"></script>
159+
160+
</body>
161+
</html>

modules/api/controllers/Manage.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
namespace Modules\Api\Controllers;
3+
4+
class Manage {
5+
6+
public function __construct()
7+
{
8+
header('Content-Type: application/json');
9+
header('Accept: application/json');
10+
}
11+
12+
public function postUpdate ()
13+
{
14+
echo 'success!';
15+
}
16+
17+
}

modules/api/routes.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
// Filters
3+
$router->filter('authadmin', ['Modules\Admin\Models\Auth','checkSession']);
4+
5+
// ADMIN SECTION
6+
$router->group([
7+
'prefix'=>'api',
8+
'before'=>'authadmin'
9+
],
10+
function ($router) {
11+
$router->controller('/', 'Modules\Api\Controllers\Manage');
12+
});

public/assets/js/tooSimple.js

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
2$imple (too Simple) JS Framework
3+
-
4+
selectors, html content changer, css style changer, events, hide, show, toggle
5+
*/
6+
7+
const $$ = function $$(selector, context = document) {
8+
const elements = Array.from(context.querySelectorAll(selector))
9+
10+
return {
11+
elements,
12+
13+
html(newHtml) {
14+
this.elements.forEach(element => {
15+
element.innerHTML = newHtml
16+
})
17+
return this
18+
},
19+
20+
css(newCss) {
21+
this.elements.forEach(element => {
22+
Object.assign(element.style, newCss)
23+
})
24+
return this
25+
},
26+
27+
on(event, handler, options) {
28+
this.elements.forEach(element => {
29+
element.addEventListener(event, handler, options)
30+
})
31+
return this
32+
},
33+
34+
hide() {
35+
this.elements.forEach(element => {
36+
Object.assign(element.style, { display: 'none' })
37+
})
38+
return this
39+
},
40+
41+
show() {
42+
this.elements.forEach(element => {
43+
Object.assign(element.style, { display: 'block' })
44+
})
45+
return this
46+
},
47+
48+
toggle() {
49+
this.elements.forEach(element => {
50+
if (element.style.display === 'none') {
51+
Object.assign(element.style, { display: 'block' })
52+
} else {
53+
Object.assign(element.style, { display: 'none' })
54+
}
55+
})
56+
return this
57+
}
58+
59+
// etc.
60+
}
61+
}

public/assets/js/vueapp.js

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
var products = [
2+
{ id: 1, name: 'Angular', description: 'Superheroic JavaScript MVW Framework.', price: 100 },
3+
{ id: 2, name: 'Ember', description: 'A framework for creating ambitious web applications.', price: 100 },
4+
{ id: 3, name: 'React', description: 'A JavaScript Library for building user interfaces.', price: 100 }
5+
];
6+
7+
function findProduct(productId) {
8+
return products[findProductKey(productId)];
9+
};
10+
11+
function findProductKey(productId) {
12+
for (var key = 0; key < products.length; key++) {
13+
if (products[key].id == productId) {
14+
return key;
15+
}
16+
}
17+
};
18+
19+
var List = Vue.extend({
20+
template: '#product-list',
21+
data: function() {
22+
return { products: products, searchKey: '' };
23+
},
24+
computed: {
25+
filteredProducts: function() {
26+
return this.products.filter(function(product) {
27+
return this.searchKey == '' || product.name.toLowerCase().indexOf(this.searchKey.toLowerCase()) !== -1;
28+
}, this);
29+
}
30+
}
31+
});
32+
33+
var Product = Vue.extend({
34+
template: '#product',
35+
data: function() {
36+
return { product: findProduct(this.$route.params.product_id) };
37+
}
38+
});
39+
40+
var ProductEdit = Vue.extend({
41+
template: '#product-edit',
42+
data: function() {
43+
return { product: findProduct(this.$route.params.product_id) };
44+
},
45+
methods: {
46+
updateProduct: function() {
47+
var product = this.product;
48+
products[findProductKey(product.id)] = {
49+
id: product.id,
50+
name: product.name,
51+
description: product.description,
52+
price: product.price
53+
};
54+
this.$http.post('/phreak/api/update', product, {
55+
emulateJSON: true
56+
}).then(response => {
57+
this.someData = response.body;
58+
}, response => {
59+
console.log(response.status + ' ' + response.statusText);
60+
});
61+
router.push('/');
62+
}
63+
}
64+
});
65+
66+
var ProductDelete = Vue.extend({
67+
template: '#product-delete',
68+
data: function() {
69+
return { product: findProduct(this.$route.params.product_id) };
70+
},
71+
methods: {
72+
deleteProduct: function() {
73+
products.splice(findProductKey(this.$route.params.product_id), 1);
74+
this.$http.post('/api/delete', product, {
75+
emulateJSON: true
76+
});
77+
router.push('/');
78+
}
79+
}
80+
});
81+
82+
var AddProduct = Vue.extend({
83+
template: '#add-product',
84+
data: function() {
85+
return { product: { name: '', description: '', price: '' } }
86+
},
87+
methods: {
88+
createProduct: function() {
89+
var product = this.product;
90+
products.push({
91+
id: Math.random().toString().split('.')[1],
92+
name: product.name,
93+
description: product.description,
94+
price: product.price
95+
});
96+
this.$http.post('/api/add', product, {
97+
emulateJSON: true
98+
});
99+
router.push('/');
100+
}
101+
}
102+
});
103+
104+
var router = new VueRouter({
105+
routes: [
106+
{ path: '/', component: List },
107+
{ path: '/product/:product_id', component: Product, name: 'product' },
108+
{ path: '/add-product', component: AddProduct },
109+
{ path: '/product/:product_id/edit', component: ProductEdit, name: 'product-edit' },
110+
{ path: '/product/:product_id/delete', component: ProductDelete, name: 'product-delete' }
111+
]
112+
});
113+
app = new Vue({
114+
router: router
115+
}).$mount('#app');

0 commit comments

Comments
 (0)