mirror of
https://github.com/prurigro/hypothetical.git
synced 2024-11-09 11:16:39 -05:00
Create a equal-featured vue variant of the public portion of the site
This commit is contained in:
parent
f9f3cfc5b7
commit
795e8335c2
44 changed files with 720 additions and 168 deletions
|
@ -67,6 +67,7 @@ class RegisterController extends Controller
|
||||||
'name' => $data['name'],
|
'name' => $data['name'],
|
||||||
'email' => $data['email'],
|
'email' => $data['email'],
|
||||||
'password' => bcrypt($data['password']),
|
'password' => bcrypt($data['password']),
|
||||||
|
'api_token' => str_random(60)
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ class User extends Authenticatable
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'name', 'email', 'password',
|
'name', 'email', 'password', 'api_token'
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -24,6 +24,6 @@ class User extends Authenticatable
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $hidden = [
|
protected $hidden = [
|
||||||
'password', 'remember_token',
|
'password', 'remember_token', 'api_token'
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class AddApiTokenToUsersTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('users', function(Blueprint $table) {
|
||||||
|
$table->string('api_token', 60)->unique();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('users', function(Blueprint $table) {
|
||||||
|
$table->dropColumn('api_token');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
124
gulpfile.js
vendored
124
gulpfile.js
vendored
|
@ -1,25 +1,39 @@
|
||||||
// include packages
|
// Core packages
|
||||||
const gulp = require("gulp"),
|
const gulp = require("gulp"),
|
||||||
gutil = require("gulp-util"),
|
gutil = require("gulp-util"),
|
||||||
plumber = require("gulp-plumber"),
|
plumber = require("gulp-plumber"),
|
||||||
concat = require("gulp-concat"),
|
concat = require("gulp-concat");
|
||||||
sass = require("gulp-sass"),
|
|
||||||
|
// Sass packages
|
||||||
|
const sass = require("gulp-sass"),
|
||||||
sassGlob = require("gulp-sass-glob"),
|
sassGlob = require("gulp-sass-glob"),
|
||||||
postCSS = require("gulp-postcss"),
|
postCSS = require("gulp-postcss"),
|
||||||
autoprefixer = require("autoprefixer"),
|
autoprefixer = require("autoprefixer");
|
||||||
babel = require("gulp-babel"),
|
|
||||||
|
// Javascript packages
|
||||||
|
const babel = require("gulp-babel"),
|
||||||
stripDebug = require("gulp-strip-debug"),
|
stripDebug = require("gulp-strip-debug"),
|
||||||
uglify = require("gulp-uglify");
|
uglify = require("gulp-uglify");
|
||||||
|
|
||||||
// determine if gulp has been run with --production
|
// Vue packages
|
||||||
const prod = gutil.env.production;
|
const browserify = require("browserify"),
|
||||||
|
vueify = require("vueify"),
|
||||||
|
source = require("vinyl-source-stream"),
|
||||||
|
buffer = require("vinyl-buffer");
|
||||||
|
|
||||||
// declare plugin settings
|
// Determine if gulp has been run with --production
|
||||||
const sassOutputStyle = prod ? "compressed" : "nested",
|
const isProduction = gutil.env.production;
|
||||||
sassIncludePaths = [ "bower_components" ],
|
|
||||||
autoprefixerSettings = { remove: false, cascade: false, browsers: [ "last 6 versions" ] };
|
|
||||||
|
|
||||||
// javascript files for the public site
|
// Declare plugin settings
|
||||||
|
const sassOutputStyle = isProduction ? "compressed" : "nested",
|
||||||
|
sassPaths = [ "bower_components", "node_modules" ],
|
||||||
|
autoprefixerSettings = { remove: false, cascade: false, browsers: [ "last 6 versions" ] },
|
||||||
|
vuePaths = [ "./bower_components", "./node_modules", "./resources/components", "./resources/assets/js" ];
|
||||||
|
|
||||||
|
// Vue file for the public site
|
||||||
|
const vuePublic = "resources/assets/js/app-vue.js";
|
||||||
|
|
||||||
|
// Javascript files for the public site
|
||||||
const jsPublic = [
|
const jsPublic = [
|
||||||
"resources/assets/js/site-vars.js",
|
"resources/assets/js/site-vars.js",
|
||||||
"resources/assets/js/contact.js",
|
"resources/assets/js/contact.js",
|
||||||
|
@ -27,7 +41,7 @@ const jsPublic = [
|
||||||
"resources/assets/js/app.js"
|
"resources/assets/js/app.js"
|
||||||
];
|
];
|
||||||
|
|
||||||
// javascript libraries for the public site
|
// Javascript libraries for the public site
|
||||||
const jsPublicLibs = [
|
const jsPublicLibs = [
|
||||||
"bower_components/jquery/dist/jquery.js",
|
"bower_components/jquery/dist/jquery.js",
|
||||||
"bower_components/bootstrap-sass/assets/javascripts/bootstrap.js",
|
"bower_components/bootstrap-sass/assets/javascripts/bootstrap.js",
|
||||||
|
@ -35,12 +49,12 @@ const jsPublicLibs = [
|
||||||
"node_modules/what-input/dist/what-input.js"
|
"node_modules/what-input/dist/what-input.js"
|
||||||
];
|
];
|
||||||
|
|
||||||
// javascript files for the dashboard
|
// Javascript files for the dashboard
|
||||||
const jsDashboard = [
|
const jsDashboard = [
|
||||||
"resources/assets/js/dashboard.js"
|
"resources/assets/js/dashboard.js"
|
||||||
];
|
];
|
||||||
|
|
||||||
// javascript libraries for the dashboard
|
// Javascript libraries for the dashboard
|
||||||
const jsDashboardLibs = [
|
const jsDashboardLibs = [
|
||||||
"bower_components/jquery/dist/jquery.js",
|
"bower_components/jquery/dist/jquery.js",
|
||||||
"bower_components/bootstrap-sass/assets/javascripts/bootstrap.js",
|
"bower_components/bootstrap-sass/assets/javascripts/bootstrap.js",
|
||||||
|
@ -50,102 +64,128 @@ const jsDashboardLibs = [
|
||||||
"bower_components/simplemde/dist/simplemde.min.js"
|
"bower_components/simplemde/dist/simplemde.min.js"
|
||||||
];
|
];
|
||||||
|
|
||||||
// paths to folders containing fonts that should be copied to public/fonts/
|
// Paths to folders containing fonts that should be copied to public/fonts/
|
||||||
const fontPaths = [
|
const fontPaths = [
|
||||||
"resources/assets/fonts/**",
|
"resources/assets/fonts/**",
|
||||||
"bower_components/bootstrap-sass/assets/fonts/**/*",
|
"bower_components/bootstrap-sass/assets/fonts/**/*",
|
||||||
"bower_components/fontawesome/fonts/**"
|
"bower_components/fontawesome/fonts/**"
|
||||||
];
|
];
|
||||||
|
|
||||||
// function to handle gulp-plumber errors
|
// Handle errors
|
||||||
function plumberError(err) {
|
function handleError(err) {
|
||||||
console.log(err);
|
gutil.log(err);
|
||||||
this.emit("end");
|
this.emit("end");
|
||||||
}
|
}
|
||||||
|
|
||||||
// function to handle the processing of sass files
|
// Process sass
|
||||||
function processSass(filename) {
|
function processSass(filename) {
|
||||||
return gulp.src("resources/assets/sass/" + filename + ".scss")
|
return gulp.src("resources/assets/sass/" + filename + ".scss")
|
||||||
.pipe(plumber(plumberError))
|
.pipe(plumber(handleError))
|
||||||
.pipe(sassGlob())
|
.pipe(sassGlob())
|
||||||
.pipe(sass({ outputStyle: sassOutputStyle, includePaths: sassIncludePaths }))
|
.pipe(sass({ outputStyle: sassOutputStyle, includePaths: sassPaths }))
|
||||||
.pipe(postCSS([ autoprefixer(autoprefixerSettings) ]))
|
.pipe(postCSS([ autoprefixer(autoprefixerSettings) ]))
|
||||||
.pipe(concat(filename + ".css"))
|
.pipe(concat(filename + ".css"))
|
||||||
.pipe(gulp.dest("public/css/"));
|
.pipe(gulp.dest("public/css/"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// function to handle the processing of javascript files
|
// Process vue
|
||||||
function processJavaScript(ouputFilename, inputFiles, es6) {
|
function processVue(ouputFilename, inputFile) {
|
||||||
const javascript = gulp.src(inputFiles)
|
const javascript = browserify({
|
||||||
.pipe(plumber(plumberError))
|
entries: [ inputFile ],
|
||||||
.pipe(concat(ouputFilename + ".js"));
|
paths: vuePaths
|
||||||
|
}).transform("babelify")
|
||||||
|
.transform(vueify)
|
||||||
|
.bundle()
|
||||||
|
.on("error", handleError)
|
||||||
|
.pipe(source(ouputFilename + ".js"))
|
||||||
|
.pipe(buffer());
|
||||||
|
|
||||||
if (es6) { javascript.pipe(babel()); }
|
if (isProduction) { javascript.pipe(stripDebug()).pipe(uglify().on("error", handleError)); }
|
||||||
if (prod) { javascript.pipe(stripDebug()).pipe(uglify()); }
|
|
||||||
return javascript.pipe(gulp.dest("public/js/"));
|
return javascript.pipe(gulp.dest("public/js/"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// gulp task for public styles
|
// Process javascript
|
||||||
|
function processJavaScript(ouputFilename, inputFiles, es6) {
|
||||||
|
const javascript = gulp.src(inputFiles)
|
||||||
|
.pipe(plumber(handleError))
|
||||||
|
.pipe(concat(ouputFilename + ".js"));
|
||||||
|
|
||||||
|
if (es6) { javascript.pipe(babel()); }
|
||||||
|
if (isProduction) { javascript.pipe(stripDebug()).pipe(uglify()); }
|
||||||
|
return javascript.pipe(gulp.dest("public/js/"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Task for public styles
|
||||||
gulp.task("sass-public", function() {
|
gulp.task("sass-public", function() {
|
||||||
return processSass("app");
|
return processSass("app");
|
||||||
});
|
});
|
||||||
|
|
||||||
// gulp task for dashboard styles
|
// Task for dashboard styles
|
||||||
gulp.task("sass-dashboard", function() {
|
gulp.task("sass-dashboard", function() {
|
||||||
return processSass("dashboard");
|
return processSass("dashboard");
|
||||||
});
|
});
|
||||||
|
|
||||||
// gulp task for public javascript
|
// Task for public vue
|
||||||
|
gulp.task("js-public-vue", function() {
|
||||||
|
return processVue("app-vue", vuePublic);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Task for public javascript
|
||||||
gulp.task("js-public", function() {
|
gulp.task("js-public", function() {
|
||||||
return processJavaScript("app", jsPublic, true);
|
return processJavaScript("app", jsPublic, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
// gulp task for public javascript libraries
|
// Task for public javascript libraries
|
||||||
gulp.task("js-public-libs", function() {
|
gulp.task("js-public-libs", function() {
|
||||||
return processJavaScript("lib", jsPublicLibs, false);
|
return processJavaScript("lib", jsPublicLibs, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
// gulp task for dashboard javascript
|
// Task for dashboard javascript
|
||||||
gulp.task("js-dashboard", function() {
|
gulp.task("js-dashboard", function() {
|
||||||
return processJavaScript("dashboard", jsDashboard, true);
|
return processJavaScript("dashboard", jsDashboard, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
// gulp task for dashboard javascript libraries
|
// Task for dashboard javascript libraries
|
||||||
gulp.task("js-dashboard-libs", function() {
|
gulp.task("js-dashboard-libs", function() {
|
||||||
return processJavaScript("lib-dashboard", jsDashboardLibs, false);
|
return processJavaScript("lib-dashboard", jsDashboardLibs, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
// gulp task to copy fonts
|
// Task to copy fonts
|
||||||
gulp.task("fonts", function() {
|
gulp.task("fonts", function() {
|
||||||
return gulp.src(fontPaths)
|
return gulp.src(fontPaths)
|
||||||
.pipe(plumber(plumberError))
|
.pipe(plumber(handleError))
|
||||||
.pipe(gulp.dest("public/fonts/"));
|
.pipe(gulp.dest("public/fonts/"));
|
||||||
});
|
});
|
||||||
|
|
||||||
// gulp watch task
|
// Task to run tasks when their respective files are changed
|
||||||
gulp.task("watch", function() {
|
gulp.task("watch", function() {
|
||||||
const gLiveReload = require("gulp-livereload");
|
const livereload = require("gulp-livereload");
|
||||||
|
|
||||||
const liveReloadUpdate = function(files, wait) {
|
const liveReloadUpdate = function(files, wait) {
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
gLiveReload.changed(files);
|
livereload.changed(files);
|
||||||
}, wait || 1);
|
}, wait || 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
gLiveReload.listen();
|
livereload.listen();
|
||||||
gulp.watch(jsPublic, [ "js-public" ]).on("change", liveReloadUpdate);
|
gulp.watch(jsPublic, [ "js-public" ]).on("change", liveReloadUpdate);
|
||||||
gulp.watch(jsDashboard, [ "js-dashboard" ]).on("change", liveReloadUpdate);
|
gulp.watch(jsDashboard, [ "js-dashboard" ]).on("change", liveReloadUpdate);
|
||||||
gulp.watch([ "app/**/*.php", "routes/**/*.php", "resources/views/**/*.blade.php" ]).on("change", liveReloadUpdate);
|
gulp.watch([ "app/**/*.php", "routes/**/*.php", "resources/views/**/*.blade.php" ]).on("change", liveReloadUpdate);
|
||||||
|
|
||||||
|
gulp.watch([ vuePublic, "resources/assets/js/mixins/**/*.js", "resources/components/**/*.vue" ], [ "js-public-vue" ]).on("change", function(files) {
|
||||||
|
liveReloadUpdate(files, 3000);
|
||||||
|
});
|
||||||
|
|
||||||
gulp.watch("resources/assets/sass/**/*.scss", [ "sass-public", "sass-dashboard" ]).on("change", function(files) {
|
gulp.watch("resources/assets/sass/**/*.scss", [ "sass-public", "sass-dashboard" ]).on("change", function(files) {
|
||||||
liveReloadUpdate(files, 1000);
|
liveReloadUpdate(files, 1000);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// gulp default task
|
// Task to run non-development tasks
|
||||||
gulp.task("default", [
|
gulp.task("default", [
|
||||||
"sass-public",
|
"sass-public",
|
||||||
"sass-dashboard",
|
"sass-dashboard",
|
||||||
|
"js-public-vue",
|
||||||
"js-public",
|
"js-public",
|
||||||
"js-public-libs",
|
"js-public-libs",
|
||||||
"js-dashboard",
|
"js-dashboard",
|
||||||
|
|
13
package.json
13
package.json
|
@ -10,7 +10,11 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"autoprefixer": "^7.1.6",
|
"autoprefixer": "^7.1.6",
|
||||||
"babel-core": "^6.26.0",
|
"babel-core": "^6.26.0",
|
||||||
|
"babel-plugin-transform-runtime": "^6.23.0",
|
||||||
"babel-preset-env": "^1.6.1",
|
"babel-preset-env": "^1.6.1",
|
||||||
|
"babelify": "^8.0.0",
|
||||||
|
"browserify": "^14.5.0",
|
||||||
|
"es6-promise": "^4.1.1",
|
||||||
"gsap": "^1.20.3",
|
"gsap": "^1.20.3",
|
||||||
"gulp": "^3.9.1",
|
"gulp": "^3.9.1",
|
||||||
"gulp-babel": "^7.0.0",
|
"gulp-babel": "^7.0.0",
|
||||||
|
@ -22,6 +26,15 @@
|
||||||
"gulp-strip-debug": "^1.1.0",
|
"gulp-strip-debug": "^1.1.0",
|
||||||
"gulp-uglify": "^3.0.0",
|
"gulp-uglify": "^3.0.0",
|
||||||
"gulp-util": "^3.0.8",
|
"gulp-util": "^3.0.8",
|
||||||
|
"vinyl-buffer": "^1.0.0",
|
||||||
|
"vinyl-source-stream": "^1.1.0",
|
||||||
|
"vue": "^2.5.8",
|
||||||
|
"vue-resource": "^1.3.4",
|
||||||
|
"vue-router": "^3.0.1",
|
||||||
|
"vue-template-compiler": "^2.5.8",
|
||||||
|
"vueify": "^9.4.1",
|
||||||
|
"vuex": "^3.0.1",
|
||||||
|
"vuex-router-sync": "^5.0.0",
|
||||||
"what-input": "^5.0.3"
|
"what-input": "^5.0.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
120
resources/assets/js/app-vue.js
vendored
Normal file
120
resources/assets/js/app-vue.js
vendored
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
// Determine whether to use vue.js in debug or production mode
|
||||||
|
const Vue = env.debug ? require("vue/dist/vue.js") : require("vue/dist/vue.min.js");
|
||||||
|
|
||||||
|
// Import plugins
|
||||||
|
import VueRouter from "vue-router";
|
||||||
|
import VueResource from "vue-resource";
|
||||||
|
import Vuex from "vuex";
|
||||||
|
import { sync } from "vuex-router-sync";
|
||||||
|
|
||||||
|
// Load plugins
|
||||||
|
Vue.use(VueRouter);
|
||||||
|
Vue.use(VueResource);
|
||||||
|
Vue.use(Vuex);
|
||||||
|
|
||||||
|
// CSRF prevention header
|
||||||
|
Vue.http.headers.common["X-CSRF-TOKEN"] = env.csrfToken;
|
||||||
|
|
||||||
|
// Import page components
|
||||||
|
import HomePage from "pages/home.vue";
|
||||||
|
import ContactPage from "pages/contact.vue";
|
||||||
|
import Error404Page from "pages/error404.vue";
|
||||||
|
|
||||||
|
// Import section components
|
||||||
|
import NavSection from "sections/nav.vue";
|
||||||
|
import FooterSection from "sections/footer.vue";
|
||||||
|
|
||||||
|
// Name the nav and footer components so they can be used globally
|
||||||
|
Vue.component("nav-component", NavSection);
|
||||||
|
Vue.component("footer-component", FooterSection);
|
||||||
|
|
||||||
|
// Create a router instance
|
||||||
|
const router = new VueRouter({
|
||||||
|
mode: "history",
|
||||||
|
linkActiveClass: "active",
|
||||||
|
root: "/",
|
||||||
|
routes: [
|
||||||
|
{ path: "/", component: HomePage },
|
||||||
|
{ path: "/contact", component: ContactPage },
|
||||||
|
{ path: "/*", component: Error404Page }
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create a vuex store instance
|
||||||
|
const store = new Vuex.Store({
|
||||||
|
state: {
|
||||||
|
appName: env.appName,
|
||||||
|
firstLoad: true,
|
||||||
|
lastPath: ""
|
||||||
|
},
|
||||||
|
|
||||||
|
getters: {
|
||||||
|
getAppName: state => {
|
||||||
|
return state.appName;
|
||||||
|
},
|
||||||
|
|
||||||
|
getFirstLoad: state => {
|
||||||
|
return state.firstLoad;
|
||||||
|
},
|
||||||
|
|
||||||
|
getLastPath: state => {
|
||||||
|
return state.lastPath;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mutations: {
|
||||||
|
setFirstLoad(state, value) {
|
||||||
|
state.firstLoad = value;
|
||||||
|
},
|
||||||
|
|
||||||
|
setLastPath(state, value) {
|
||||||
|
state.lastPath = value;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Sync vue-router-sync with vuex store
|
||||||
|
sync(store, router);
|
||||||
|
|
||||||
|
// Functionality to run before page load and change
|
||||||
|
router.beforeEach((to, from, next) => {
|
||||||
|
if (to.path !== store.getters.getLastPath) {
|
||||||
|
if (store.getters.getFirstLoad) {
|
||||||
|
next();
|
||||||
|
} else {
|
||||||
|
// Fade the page out and scroll when moving from one page to another
|
||||||
|
TweenMax.to("#router-view", 0.25, {
|
||||||
|
opacity: 0,
|
||||||
|
onComplete: () => {
|
||||||
|
$("html, body").scrollTop(0);
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Functionality to run on page load and change
|
||||||
|
router.afterEach((to, from) => {
|
||||||
|
if (to.path !== store.getters.getLastPath) {
|
||||||
|
store.commit("setLastPath", to.path);
|
||||||
|
|
||||||
|
if (store.getters.getFirstLoad) {
|
||||||
|
// Set Page.firstLoad to false so we know the initial load has completed
|
||||||
|
store.commit("setFirstLoad", false);
|
||||||
|
} else {
|
||||||
|
Vue.nextTick(() => {
|
||||||
|
TweenMax.to("#router-view", 0.25, { opacity: 1 });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const App = new Vue({
|
||||||
|
router,
|
||||||
|
store
|
||||||
|
}).$mount("#page-content");
|
78
resources/assets/js/mixins/base-page.js
vendored
Normal file
78
resources/assets/js/mixins/base-page.js
vendored
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
metaTitle: "",
|
||||||
|
metaDescription: "",
|
||||||
|
metaKeywords: "",
|
||||||
|
|
||||||
|
metaTags: {
|
||||||
|
"title": [ "name", "title" ],
|
||||||
|
"description": [ "name", "description" ],
|
||||||
|
"keywords": [ "name", "keywords" ],
|
||||||
|
"dc:title": [ "name", "title" ],
|
||||||
|
"dc:description": [ "name", "description" ],
|
||||||
|
"og:title": [ "property", "title" ],
|
||||||
|
"og:description": [ "property", "description" ],
|
||||||
|
"og:url": [ "property", "url" ],
|
||||||
|
"twitter:title": [ "name", "title" ],
|
||||||
|
"twitter:description": [ "name", "description" ]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
pageTitle() {
|
||||||
|
return this.metaTitle === "" ? env.appName : `${this.metaTitle} | ${env.appName}`;
|
||||||
|
},
|
||||||
|
|
||||||
|
pageDescription() {
|
||||||
|
return this.metaDescription === "" ? env.appDesc : this.metaDescription;
|
||||||
|
},
|
||||||
|
|
||||||
|
fullPath() {
|
||||||
|
return document.location.origin + this.$route.path;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
updateMetaTag(name, attribute, content) {
|
||||||
|
const $tag = $("meta[" + name + "=" + attribute.replace(/:/, "\\:") + "]");
|
||||||
|
|
||||||
|
if ($tag.length) {
|
||||||
|
$tag.attr("content", content);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
updateMetaData() {
|
||||||
|
let metaContent;
|
||||||
|
|
||||||
|
document.title = this.pageTitle;
|
||||||
|
$("link[rel=canonical]").attr("href", this.fullPath);
|
||||||
|
|
||||||
|
Object.keys(this.metaTags).forEach((name) => {
|
||||||
|
switch (this.metaTags[name][1]) {
|
||||||
|
case "title":
|
||||||
|
metaContent = this.pageTitle;
|
||||||
|
break;
|
||||||
|
case "description":
|
||||||
|
metaContent = this.pageDescription;
|
||||||
|
break;
|
||||||
|
case "keywords":
|
||||||
|
metaContent = this.metaKeywords;
|
||||||
|
break;
|
||||||
|
case "url":
|
||||||
|
metaContent = this.fullPath;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
metaContent = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
this.updateMetaTag(this.metaTags[name][0], name, metaContent);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
this.updateMetaData();
|
||||||
|
}
|
||||||
|
};
|
6
resources/assets/sass/app.scss
vendored
6
resources/assets/sass/app.scss
vendored
|
@ -6,7 +6,7 @@
|
||||||
@import "bootstrap-sass/assets/stylesheets/_bootstrap.scss";
|
@import "bootstrap-sass/assets/stylesheets/_bootstrap.scss";
|
||||||
|
|
||||||
// Supplementary
|
// Supplementary
|
||||||
@import "elements/**/*.scss";
|
@import "sections/**/*.scss";
|
||||||
@import "pages/**/*.scss";
|
@import "pages/**/*.scss";
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -38,13 +38,13 @@ body {
|
||||||
@media (max-width: $grid-float-breakpoint-max) { padding-top: $nav-height-mobile; }
|
@media (max-width: $grid-float-breakpoint-max) { padding-top: $nav-height-mobile; }
|
||||||
}
|
}
|
||||||
|
|
||||||
#page-container {
|
.page-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
padding-top: $nav-height;
|
padding-top: $nav-height;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
#main-content {
|
.main-content {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
88
resources/assets/sass/pages/_contact.scss
vendored
88
resources/assets/sass/pages/_contact.scss
vendored
|
@ -1,53 +1,51 @@
|
||||||
.page-contact {
|
.contact-page-component {
|
||||||
#contact-form {
|
$trans-speed: 100ms;
|
||||||
$trans-speed: 100ms;
|
margin-top: 35px;
|
||||||
margin-top: 35px;
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
input, textarea {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
|
width: 100%;
|
||||||
|
padding: 5px 10px;
|
||||||
|
border: 2px solid fade-out($c-text, 0.75);
|
||||||
|
background-color: rgba(255, 255, 255, 0.8);
|
||||||
|
font-size: 14px;
|
||||||
|
transition: border $trans-speed;
|
||||||
|
&:focus { border: 2px solid fade-out($c-base, 0.4); }
|
||||||
|
&.error { border: 2px solid $c-error; }
|
||||||
|
}
|
||||||
|
|
||||||
input, textarea {
|
textarea {
|
||||||
margin-bottom: 20px;
|
resize: none;
|
||||||
width: 100%;
|
height: 150px;
|
||||||
padding: 5px 10px;
|
}
|
||||||
border: 2px solid fade-out($c-text, 0.75);
|
|
||||||
background-color: rgba(255, 255, 255, 0.8);
|
|
||||||
font-size: 14px;
|
|
||||||
transition: border $trans-speed;
|
|
||||||
&:focus { border: 2px solid fade-out($c-base, 0.4); }
|
|
||||||
&.error { border: 2px solid $c-error; }
|
|
||||||
}
|
|
||||||
|
|
||||||
textarea {
|
.submit {
|
||||||
resize: none;
|
background-color: lighten($c-base, 5%);
|
||||||
height: 150px;
|
color: $c-text-light;
|
||||||
}
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
transition: background-color $trans-speed;
|
||||||
|
&:hover { background-color: $c-base; }
|
||||||
|
&.disabled { background-color: $c-base; }
|
||||||
|
}
|
||||||
|
|
||||||
.submit {
|
.notification {
|
||||||
background-color: lighten($c-base, 5%);
|
margin: 0px auto 15px auto;
|
||||||
color: $c-text-light;
|
padding: 5px 10px;
|
||||||
|
background-color: lighten($c-error, 15%);
|
||||||
|
color: $c-text-light;
|
||||||
|
font-size: 14px;
|
||||||
|
text-align: center;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity $trans-speed;
|
||||||
|
span { font-weight: bold; }
|
||||||
|
&.visible { opacity: 1; }
|
||||||
|
|
||||||
|
&.success {
|
||||||
|
background-color: transparent;
|
||||||
|
color: $c-text;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
text-align: center;
|
|
||||||
transition: background-color $trans-speed;
|
|
||||||
&:hover { background-color: $c-base; }
|
|
||||||
&.disabled { background-color: $c-base; }
|
|
||||||
}
|
|
||||||
|
|
||||||
.notification {
|
|
||||||
margin: 0px auto 15px auto;
|
|
||||||
padding: 5px 10px;
|
|
||||||
background-color: lighten($c-error, 15%);
|
|
||||||
color: $c-text-light;
|
|
||||||
font-size: 14px;
|
|
||||||
text-align: center;
|
|
||||||
opacity: 0;
|
|
||||||
transition: opacity $trans-speed;
|
|
||||||
span { font-weight: bold; }
|
|
||||||
&.visible { opacity: 1; }
|
|
||||||
|
|
||||||
&.success {
|
|
||||||
background-color: transparent;
|
|
||||||
color: $c-text;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,8 @@
|
||||||
footer {
|
.footer-section-component {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
background-color: $c-base;
|
background-color: $c-base;
|
||||||
color: $c-text-light;
|
color: $c-text-light;
|
||||||
line-height: 32px;
|
line-height: 32px;
|
||||||
|
|
||||||
&.sticky-footer {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
.navbar {
|
.nav-section-component {
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
margin-bottom: 0px;
|
margin-bottom: 0px;
|
||||||
height: $nav-height;
|
height: $nav-height;
|
|
@ -1,4 +1,4 @@
|
||||||
#subscription-form {
|
.subscription-form-section-component {
|
||||||
$trans-speed: 100ms;
|
$trans-speed: 100ms;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50%;
|
top: 50%;
|
100
resources/components/pages/contact.vue
Normal file
100
resources/components/pages/contact.vue
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
<template>
|
||||||
|
<div class="contact-page-component">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-12 col-md-8 col-md-offset-2">
|
||||||
|
<h1>Contact</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-12 col-md-8 col-md-offset-2">
|
||||||
|
<div id="contact-form">
|
||||||
|
<form action="#" method="POST" accept-charset="UTF-8" @submit.prevent="submit">
|
||||||
|
<input type="text" v-model="form.name" name="name" placeholder="Name" />
|
||||||
|
<input type="text" v-model="form.email" name="email" placeholder="Email" />
|
||||||
|
<textarea name="message" v-model="form.message" placeholder="Message"></textarea>
|
||||||
|
|
||||||
|
<input
|
||||||
|
class="submit"
|
||||||
|
:class="{ disabled: submitSuccess }"
|
||||||
|
type="submit"
|
||||||
|
name="submit"
|
||||||
|
value="Submit"
|
||||||
|
/>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="notification"
|
||||||
|
:class="{ success: submitSuccess, visible: errorCount > 0 && submitSuccess }">
|
||||||
|
|
||||||
|
<template v-if="submitSuccess">
|
||||||
|
Thanks for your message!
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-else>
|
||||||
|
<strong>Error:</strong> There were problems with the <span>{{ errorCount }}</span> fields highlighted above
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import BasePageMixin from "mixins/base-page.js";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
mixins: [
|
||||||
|
BasePageMixin
|
||||||
|
],
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
metaTitle: "Contact",
|
||||||
|
metaDescription: "Contact Us",
|
||||||
|
metaKeywords: "contact",
|
||||||
|
submitting: false,
|
||||||
|
errorCount: 0,
|
||||||
|
submitSuccess: false,
|
||||||
|
|
||||||
|
form: {
|
||||||
|
name: "",
|
||||||
|
email: "",
|
||||||
|
message: ""
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
submit() {
|
||||||
|
if (!this.submitting) {
|
||||||
|
this.submitting = true;
|
||||||
|
$(this.$el).find(":input.error").removeClass("error");
|
||||||
|
|
||||||
|
this.$http.post("/api/contact-submit" + env.apiToken, JSON.stringify(this.form)).then((response) => {
|
||||||
|
// Success
|
||||||
|
$(this.$el).find(":input").attr("disabled", true);
|
||||||
|
this.submitSuccess = true;
|
||||||
|
this.submitting = false;
|
||||||
|
}, (response) => {
|
||||||
|
// Error
|
||||||
|
let errors = 0;
|
||||||
|
|
||||||
|
for (let errorName in response.body.errors) {
|
||||||
|
if ($(this.$el).find(`[name='${errorName}']`).length) {
|
||||||
|
$(this.$el).find(`[name='${errorName}']`).addClass("error");
|
||||||
|
errors++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.errorCount = errors;
|
||||||
|
this.submitting = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
22
resources/components/pages/error404.vue
Normal file
22
resources/components/pages/error404.vue
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
<template>
|
||||||
|
<div class="error-page-component">
|
||||||
|
Page Not Found
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import BasePageMixin from "mixins/base-page.js";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
mixins: [
|
||||||
|
BasePageMixin
|
||||||
|
],
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
metaTitle: "Page Not Found",
|
||||||
|
metaDescription: "The requested page cannot be found"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
26
resources/components/pages/home.vue
Normal file
26
resources/components/pages/home.vue
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
<template>
|
||||||
|
<div class="home-page-component">
|
||||||
|
<subscription-form />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import BasePageMixin from "mixins/base-page.js";
|
||||||
|
import SubscriptionFormSection from "sections/subscription-form.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
mixins: [
|
||||||
|
BasePageMixin
|
||||||
|
],
|
||||||
|
|
||||||
|
components: {
|
||||||
|
"subscription-form": SubscriptionFormSection
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
metaKeywords: "home"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
5
resources/components/sections/footer.vue
Normal file
5
resources/components/sections/footer.vue
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<template>
|
||||||
|
<footer class="footer-section-component">
|
||||||
|
© {{ new Date().getFullYear() }} {{ $store.getters.getAppName }}
|
||||||
|
</footer>
|
||||||
|
</template>
|
23
resources/components/sections/nav.vue
Normal file
23
resources/components/sections/nav.vue
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
<template>
|
||||||
|
<nav class="nav-section-component navbar navbar-default navbar-fixed-top">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="navbar-header">
|
||||||
|
<button type="button" id="navbar-toggle" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-collapse" aria-expanded="false" aria-controls="navbar">
|
||||||
|
<span class="sr-only">Toggle Navigation</span>
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<router-link class="navbar-logo" to="/"></router-link>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="navbar-collapse" class="navbar-collapse collapse">
|
||||||
|
<ul class="nav navbar-nav navbar-right">
|
||||||
|
<li class="navlink"><router-link to="/" title="Home">Home</router-link></li>
|
||||||
|
<li class="navlink"><router-link to="/contact" title="Contact">Contact</router-link></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</template>
|
62
resources/components/sections/subscription-form.vue
Normal file
62
resources/components/sections/subscription-form.vue
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
<template>
|
||||||
|
<div class="subscription-form-section-component">
|
||||||
|
<form action="#" method="POST" accept-charset="UTF-8" @submit.prevent="submit">
|
||||||
|
<div class="notification" :class="[ notifyStatus, { visible: notifyStatus !== '' } ]">{{ notifyText }}</div>
|
||||||
|
<input type="text" v-model="form.email" name="email" placeholder="Email" />
|
||||||
|
<input type="text" v-model="form.name" name="name" placeholder="Name" />
|
||||||
|
<input type="submit" name="submit" value="Subscribe" />
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
submitting: false,
|
||||||
|
notifyStatus: "",
|
||||||
|
notifyText: "",
|
||||||
|
|
||||||
|
form: {
|
||||||
|
email: "",
|
||||||
|
name: ""
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
submit() {
|
||||||
|
if (!this.submitting) {
|
||||||
|
this.submitting = true;
|
||||||
|
this.notifyStatus = "";
|
||||||
|
$(this.$el).find(":input.error").removeClass("error");
|
||||||
|
|
||||||
|
this.$http.post("/api/subscription-submit" + env.apiToken, JSON.stringify(this.form)).then((response) => {
|
||||||
|
// Success
|
||||||
|
$(this.$el).find(":input").fadeOut(150);
|
||||||
|
this.notifyText = "Thanks for subscribing!";
|
||||||
|
this.notifyStatus = "success";
|
||||||
|
this.submitting = false;
|
||||||
|
}, (response) => {
|
||||||
|
// Error
|
||||||
|
let errors = 0;
|
||||||
|
|
||||||
|
for (let errorName in response.body.errors) {
|
||||||
|
if ($(this.$el).find(`[name='${errorName}']`).length) {
|
||||||
|
$(this.$el).find(`[name='${errorName}']`).addClass("error");
|
||||||
|
errors++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errors === 0) {
|
||||||
|
this.notifyText = "An error occurred. Are you already subscribed?";
|
||||||
|
this.notifyStatus = "error";
|
||||||
|
}
|
||||||
|
|
||||||
|
this.submitting = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -1,6 +1,6 @@
|
||||||
@extends('layouts.dashboard')
|
@extends('templates.dashboard')
|
||||||
|
|
||||||
@section('content')
|
@section('page-content')
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-8 col-md-offset-2">
|
<div class="col-md-8 col-md-offset-2">
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
@extends('layouts.dashboard')
|
@extends('templates.dashboard')
|
||||||
|
|
||||||
@section('content')
|
@section('page-content')
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-8 col-md-offset-2">
|
<div class="col-md-8 col-md-offset-2">
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
@extends('layouts.dashboard')
|
@extends('templates.dashboard')
|
||||||
|
|
||||||
@section('content')
|
@section('page-content')
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-8 col-md-offset-2">
|
<div class="col-md-8 col-md-offset-2">
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
@extends('layouts.dashboard')
|
@extends('templates.dashboard')
|
||||||
|
|
||||||
@section('content')
|
@section('page-content')
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-8 col-md-offset-2">
|
<div class="col-md-8 col-md-offset-2">
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
@extends('layouts.dashboard')
|
@extends('templates.dashboard')
|
||||||
|
|
||||||
@section('content')
|
@section('page-content')
|
||||||
<div class="container spark-screen">
|
<div class="container spark-screen">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xs-12">
|
<div class="col-xs-12">
|
||||||
|
|
|
@ -2,5 +2,5 @@
|
||||||
|
|
||||||
@section('dashboard-body')
|
@section('dashboard-body')
|
||||||
@set('menu_class', 'list-group-item')
|
@set('menu_class', 'list-group-item')
|
||||||
<ul class="list-group linked-list">@include('dashboard.elements.menu')</ul>
|
<ul class="list-group linked-list">@include('dashboard.sections.menu')</ul>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
@endif
|
@endif
|
||||||
@else
|
@else
|
||||||
@set('menu_class', 'nav-item')
|
@set('menu_class', 'nav-item')
|
||||||
@include('dashboard.elements.menu')
|
@include('dashboard.sections.menu')
|
||||||
|
|
||||||
<li class="dropdown">
|
<li class="dropdown">
|
||||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
|
|
@ -1 +0,0 @@
|
||||||
<footer>© {{ date('Y') }} {{ env('APP_NAME') }}</footer>
|
|
|
@ -1,7 +0,0 @@
|
||||||
<form id="subscription-form" action="#" method="POST" accept-charset="UTF-8">
|
|
||||||
<div class="notification"></div>
|
|
||||||
<input type="hidden" name="_token" value="{{ csrf_token() }}" />
|
|
||||||
<input type="text" name="email" placeholder="Email" />
|
|
||||||
<input type="text" name="name" placeholder="Name" />
|
|
||||||
<input type="submit" name="submit" value="Subscribe" />
|
|
||||||
</form>
|
|
9
resources/views/elements/variables.blade.php
Normal file
9
resources/views/elements/variables.blade.php
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<script type="text/javascript">
|
||||||
|
var env = {
|
||||||
|
appName: "{{ env('APP_NAME') }}",
|
||||||
|
appDesc: "{{ env('APP_DESC') }}",
|
||||||
|
apiToken: "{{ Auth::check() ? '?api_token=' . Auth::user()->api_token : '' }}",
|
||||||
|
csrfToken: "{{ csrf_token() }}",
|
||||||
|
debug: {{ Config::get('app.debug') ? 'true' : 'false' }}
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -1,4 +1,4 @@
|
||||||
@extends('layouts.error')
|
@extends('templates.error')
|
||||||
|
|
||||||
@section('error-title')
|
@section('error-title')
|
||||||
Page Not Found
|
Page Not Found
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
@extends('layouts.error')
|
@extends('templates.error')
|
||||||
|
|
||||||
@section('error-title')
|
@section('error-title')
|
||||||
Be Right Back
|
Be Right Back
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
@extends('layouts.error')
|
@extends('templates.error')
|
||||||
|
|
||||||
@section('error-title')
|
@section('error-title')
|
||||||
No Such Record
|
No Such Record
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
@extends('layouts.public', [ 'title' => 'Contact' ])
|
@extends('templates.public', [ 'title' => 'Contact' ])
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<div class="container">
|
<div class="contact-page-component">
|
||||||
<div class="row">
|
<div class="container">
|
||||||
<div class="col-xs-12 col-md-8 col-md-offset-2">
|
<div class="row">
|
||||||
<h1>Contact</h1>
|
<div class="col-xs-12 col-md-8 col-md-offset-2">
|
||||||
|
<h1>Contact</h1>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xs-12 col-md-8 col-md-offset-2">
|
<div class="col-xs-12 col-md-8 col-md-offset-2">
|
||||||
<div id="contact-form">
|
|
||||||
<form action="#" method="POST" accept-charset="UTF-8">
|
<form action="#" method="POST" accept-charset="UTF-8">
|
||||||
<input type="hidden" name="_token" value="{{ csrf_token() }}" />
|
<input type="hidden" name="_token" value="{{ csrf_token() }}" />
|
||||||
<input type="text" name="name" placeholder="Name" />
|
<input type="text" name="name" placeholder="Name" />
|
7
resources/views/pages/index.blade.php
Normal file
7
resources/views/pages/index.blade.php
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
@extends('templates.public')
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="home-page-component">
|
||||||
|
@include('sections.subscription-form')
|
||||||
|
</div>
|
||||||
|
@endsection
|
3
resources/views/sections/footer.blade.php
Normal file
3
resources/views/sections/footer.blade.php
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<footer class="footer-section-component">
|
||||||
|
© {{ date('Y') }} {{ env('APP_NAME') }}
|
||||||
|
</footer>
|
|
@ -1,4 +1,4 @@
|
||||||
<nav class="navbar navbar-default navbar-fixed-top">
|
<nav class="nav-section-component navbar navbar-default navbar-fixed-top">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div class="navbar-header">
|
<div class="navbar-header">
|
||||||
<button type="button" id="navbar-toggle" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-collapse" aria-expanded="false" aria-controls="navbar">
|
<button type="button" id="navbar-toggle" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-collapse" aria-expanded="false" aria-controls="navbar">
|
9
resources/views/sections/subscription-form.blade.php
Normal file
9
resources/views/sections/subscription-form.blade.php
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<div class="subscription-form-section-component">
|
||||||
|
<form id="subscription-form" action="#" method="POST" accept-charset="UTF-8">
|
||||||
|
<div class="notification"></div>
|
||||||
|
<input type="hidden" name="_token" value="{{ csrf_token() }}" />
|
||||||
|
<input type="text" name="email" placeholder="Email" />
|
||||||
|
<input type="text" name="name" placeholder="Name" />
|
||||||
|
<input type="submit" name="submit" value="Subscribe" />
|
||||||
|
</form>
|
||||||
|
</div>
|
|
@ -41,21 +41,13 @@
|
||||||
@endif
|
@endif
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
@if(preg_match('/^dashboard/', Request::path()))
|
<body class="{{ $device_mobile ? 'mobile-browser' : 'desktop-browser' }}">
|
||||||
@set('body_class', preg_replace([ '/\/(new|[0-9][0-9]*)$/', '/\//' ], [ '', '-' ], Request::path()))
|
|
||||||
@else
|
|
||||||
@set('body_class', Request::path() == '/' ? 'index' : preg_replace('/\/.*/', '', Request::path()))
|
|
||||||
@endif
|
|
||||||
|
|
||||||
<body class="page-{{ $body_class }} {{ $device_mobile ? 'mobile-browser' : 'desktop-browser' }}">
|
|
||||||
@yield('page-top')
|
@yield('page-top')
|
||||||
|
|
||||||
<div id="page-container">
|
<div id="page-content">
|
||||||
<div id="main-content">
|
@yield('page-content')
|
||||||
@yield('content')
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@yield('page-bottom')
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@yield('page-bottom')
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -1,4 +1,4 @@
|
||||||
@extends('layouts.base', [ 'title' => 'Dashboard' ])
|
@extends('templates.base', [ 'title' => 'Dashboard' ])
|
||||||
|
|
||||||
@section('page-includes')
|
@section('page-includes')
|
||||||
<script src="/js/lib-dashboard.js?version={{ env('CACHE_BUST') }}"></script>
|
<script src="/js/lib-dashboard.js?version={{ env('CACHE_BUST') }}"></script>
|
||||||
|
@ -7,5 +7,5 @@
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@section('page-top')
|
@section('page-top')
|
||||||
@include('dashboard.elements.nav')
|
@include('dashboard.sections.nav')
|
||||||
@endsection
|
@endsection
|
23
resources/views/templates/public-vue.blade.php
Normal file
23
resources/views/templates/public-vue.blade.php
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
@extends('templates.base')
|
||||||
|
|
||||||
|
@section('page-includes')
|
||||||
|
<script src="/js/lib.js?version={{ env('CACHE_BUST') }}"></script>
|
||||||
|
<link rel="stylesheet" href="/css/app.css?version={{ env('CACHE_BUST') }}" />
|
||||||
|
@include('elements.variables')
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('page-content')
|
||||||
|
<nav-component></nav-component>
|
||||||
|
|
||||||
|
<div class="page-container">
|
||||||
|
<div id="router-view" class="main-content">
|
||||||
|
<router-view></router-view>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer-component></footer-component>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('page-bottom')
|
||||||
|
<script src="/js/app-vue.js?version={{ env('CACHE_BUST') }}"></script>
|
||||||
|
@endsection
|
|
@ -1,4 +1,4 @@
|
||||||
@extends('layouts.base')
|
@extends('templates.base')
|
||||||
|
|
||||||
@section('page-includes')
|
@section('page-includes')
|
||||||
<script src="/js/lib.js?version={{ env('CACHE_BUST') }}"></script>
|
<script src="/js/lib.js?version={{ env('CACHE_BUST') }}"></script>
|
||||||
|
@ -6,10 +6,14 @@
|
||||||
<link rel="stylesheet" href="/css/app.css?version={{ env('CACHE_BUST') }}" />
|
<link rel="stylesheet" href="/css/app.css?version={{ env('CACHE_BUST') }}" />
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@section('page-top')
|
@section('page-content')
|
||||||
@include('elements.nav')
|
@include('sections.nav')
|
||||||
@endsection
|
|
||||||
|
|
||||||
@section('page-bottom')
|
<div class="page-container">
|
||||||
@include('elements.footer')
|
<div class="main-content">
|
||||||
|
@yield('content')
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@include('sections.footer')
|
||||||
|
</div>
|
||||||
@endsection
|
@endsection
|
|
@ -1,5 +0,0 @@
|
||||||
@extends('layouts.public', [ 'title' => 'Home' ])
|
|
||||||
|
|
||||||
@section('content')
|
|
||||||
@include('elements.subscription-form')
|
|
||||||
@endsection
|
|
|
@ -19,19 +19,23 @@ use App\Utilities\Language;
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Route::get('/', function() {
|
|
||||||
return view('website.index');
|
|
||||||
});
|
|
||||||
|
|
||||||
Route::get('/contact', function() {
|
|
||||||
return view('website.contact');
|
|
||||||
});
|
|
||||||
|
|
||||||
Route::get('/language/{lang}', function($lang) {
|
Route::get('/language/{lang}', function($lang) {
|
||||||
Language::setSessionLanguage($lang);
|
Language::setSessionLanguage($lang);
|
||||||
return redirect()->back();
|
return redirect()->back();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Route::get('/', function() {
|
||||||
|
// return view('pages.index');
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// Route::get('/contact', function() {
|
||||||
|
// return view('pages.contact');
|
||||||
|
// });
|
||||||
|
|
||||||
|
Route::get('/{vue?}', function() {
|
||||||
|
return view('templates.public-vue');
|
||||||
|
})->where('vue', '[\/\w\.-]*');
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Authentication Routes
|
| Authentication Routes
|
||||||
|
|
Loading…
Reference in a new issue