updrade with rector
This commit is contained in:
.env.gitignore.php-cs-fixer.cache.php-cs-fixer.phpsymfony.lock
assets
app.jsbootstrap.jscontrollers.json
composer.jsoncomposer.lockcontrollers
images
24unix
js
app.js
components
Author.vueNotFound.vuePagesEdit.vueProjectsList.vueSidebar.vuefooter.vuehandleLogout.vueheader.vuelogin.vuenavbar.vuepages.vueprofile.vuequotes.vue
pages
router.jsstyles
config
bundles.php
packages
api_platform.yamlassets.yaml
dev
fos_ckeditor.yamlnelmio_cors.yamlprod
reset_password.yamlsecurity.yamltest
twig.yamlroutes
migrations
Version20210530154026.phpVersion20210530161844.phpVersion20210530162315.phpVersion20210601114523.phpVersion20210609175005.phpVersion20220412144008.phpVersion20220423085724.phpVersion20220424100610.phpVersion20220425082917.php
package.jsonpublic/uploads
rector.phpsrc
Controller
Admin
BlogCrudController.phpCommentCrudController.phpDashboardController.phpPagesCrudController.phpProjectsCrudController.phpQuotesCrudController.phpSectionCrudController.phpUserCrudController.php
BlogController.phpFrontendController.phpMainController.phpPagesController.phpProjectsController.phpRegistrationController.phpResetPasswordController.phpSecurityController.phpUserController.phpEntity
EntityListener
Form
Repository
BlogRepository.phpCommentRepository.phpPagesRepository.phpProjectsRepository.phpQuotesRepository.phpResetPasswordRequestRepository.phpSectionRepository.phpUserRepository.php
Security
templates
_aside.html.twig_footer.html.twig_header.html.twig
admin
base.html.twigblog
pages
projects
security
check_email.html.twigconfirmation_email.html.twigemail.html.twiglogin.html.twigregister.html.twigrequest.html.twigreset.html.twig
user
tools/php-cs-fixer
webpack.config.jsyarn.lock@ -1,29 +1,60 @@
|
||||
// assets/js/app.js
|
||||
|
||||
const $ = require('jquery');
|
||||
require('bootstrap');
|
||||
globalThis.__VUE_OPTIONS_API__ = true;
|
||||
globalThis.__VUE_PROD_DEVTOOLS__ = true;
|
||||
|
||||
import '../styles/app.scss';
|
||||
// Matomo
|
||||
let _paq = window._paq = window._paq || [];
|
||||
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
|
||||
_paq.push(["trackPageView"]);
|
||||
_paq.push(["enableLinkTracking"]);
|
||||
(function () {
|
||||
const u = "https://analytics.24unix.net/";
|
||||
_paq.push(["setTrackerUrl", u + "matomo.php"]);
|
||||
_paq.push(["setSiteId", "1"]);
|
||||
const d = document, g = d.createElement("script"), s = d.getElementsByTagName("script")[0];
|
||||
g.async = true;
|
||||
g.src = u + "matomo.js";
|
||||
s.parentNode.insertBefore(g, s);
|
||||
})();
|
||||
// End Matomo Code
|
||||
|
||||
|
||||
import "../styles/app.scss";
|
||||
|
||||
require("fork-awesome/scss/fork-awesome.scss");
|
||||
|
||||
/*
|
||||
require('@fortawesome/fontawesome-free/css/all.min.css');
|
||||
require('@fortawesome/fontawesome-free/js/all.js');
|
||||
*/
|
||||
|
||||
// CKEditor
|
||||
//require '@'
|
||||
import '../styles/ckeditor.css';
|
||||
import "../styles/ckeditor.css"
|
||||
|
||||
|
||||
require('@fortawesome/fontawesome-free/css/all.min.css');
|
||||
require('@fortawesome/fontawesome-free/js/all.js');
|
||||
import Vue from "vue"
|
||||
import { BootstrapVue, IconsPlugin, NavbarPlugin } from "bootstrap-vue"
|
||||
import VueRouter from 'vue-router'
|
||||
|
||||
import router from '@/router'
|
||||
import MainPage from "@/pages/main"
|
||||
|
||||
Vue.use(BootstrapVue)
|
||||
Vue.use(VueRouter)
|
||||
Vue.use(IconsPlugin)
|
||||
Vue.use(NavbarPlugin)
|
||||
|
||||
Vue.config.productionTip = false;
|
||||
|
||||
|
||||
new Vue({
|
||||
router,
|
||||
render: (h) => h(MainPage)
|
||||
})
|
||||
.$mount("#app")
|
||||
|
||||
|
||||
|
||||
|
||||
window.Dropzone = require('@symfony/ux-dropzone/dist/controller');
|
||||
Dropzone.autodiscover = false;
|
||||
|
||||
/*
|
||||
initializeDropzone();
|
||||
|
||||
function initializeDropzone()
|
||||
{
|
||||
let formElement = document.querySelector('js-dropzone');
|
||||
}
|
||||
*/
|
53
assets/js/components/Author.vue
Normal file
53
assets/js/components/Author.vue
Normal file
@ -0,0 +1,53 @@
|
||||
<template>
|
||||
<div v-if="isLoading" class="circle">
|
||||
<i class="fa fa-spinner fa-spin fa-3x fa-fw"></i>
|
||||
<span class="sr-only">Loading …</span>
|
||||
</div>
|
||||
<div v-else>
|
||||
<b-link class="align-left blog-details" :to="'/profile/' + author.username">
|
||||
<img class="article-author-img rounded-circle"
|
||||
:src="'build/images/' + author.avatar"
|
||||
alt="profile"></b-link>
|
||||
<b-link :to="'/profile/' + author.username">
|
||||
{{ author.username }}
|
||||
</b-link>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
import axios from "axios";
|
||||
|
||||
export default {
|
||||
name: "Author",
|
||||
data: () => ({
|
||||
author: null,
|
||||
isLoading: true
|
||||
}),
|
||||
props: ["authorIri"],
|
||||
|
||||
mounted() {
|
||||
this.getAuthor();
|
||||
},
|
||||
methods: {
|
||||
getAuthor() {
|
||||
console.log("here" + this.authorIri);
|
||||
axios
|
||||
.get(this.authorIri)
|
||||
.then(response => {
|
||||
console.log("response");
|
||||
console.log(response);
|
||||
this.author = response.data;
|
||||
console.log(this.author);
|
||||
this.isLoading = false;
|
||||
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
console.log(this.author);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
11
assets/js/components/NotFound.vue
Normal file
11
assets/js/components/NotFound.vue
Normal file
@ -0,0 +1,11 @@
|
||||
<template>
|
||||
<div>
|
||||
404 Not Found
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "NotFound"
|
||||
}
|
||||
</script>
|
62
assets/js/components/PagesEdit.vue
Normal file
62
assets/js/components/PagesEdit.vue
Normal file
@ -0,0 +1,62 @@
|
||||
<template>
|
||||
<div v-if="!isLoading">
|
||||
<div id="edit-wrapper">
|
||||
<div class="editor mt-2">
|
||||
<VueEditor v-model="page.content"></VueEditor>
|
||||
</div>
|
||||
<b-button @click="saveContent" class="mt-3 mb-2">Save</b-button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<i class="fa fa-spinner fa-spin fa-3x fa-fw"></i>
|
||||
<span class="sr-only">Loading …</span></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import axios from "axios";
|
||||
|
||||
// Basic Use - Covers most scenarios
|
||||
import { VueEditor } from "vue2-editor";
|
||||
|
||||
|
||||
|
||||
export default {
|
||||
name: 'PagesEdit',
|
||||
components: {
|
||||
VueEditor
|
||||
},
|
||||
data: () => ({
|
||||
page: null,
|
||||
isLoading: true
|
||||
}),
|
||||
methods: {
|
||||
saveContent() {
|
||||
console.log(this.page)
|
||||
axios
|
||||
.put('/api/pages/' + this.page.id, this.page)
|
||||
.then(response => {
|
||||
console.log("resp:" + response)
|
||||
})
|
||||
}
|
||||
},
|
||||
beforeMount() {
|
||||
const slug = this.$route.params.slug
|
||||
console.log("slug: " + slug)
|
||||
|
||||
axios
|
||||
.get('/api/pages?slug=' + slug)
|
||||
.then(response => {
|
||||
this.page = response.data['hydra:member'][0]
|
||||
this.isLoading = false
|
||||
})
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.ql-container {
|
||||
height: 800px !important;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
</style>
|
89
assets/js/components/ProjectsList.vue
Normal file
89
assets/js/components/ProjectsList.vue
Normal file
@ -0,0 +1,89 @@
|
||||
<template>
|
||||
|
||||
<div v-if="isLoading" class="circle">
|
||||
<i class="fa fa-spinner fa-spin fa-3x fa-fw"></i>
|
||||
<span class="sr-only">Loading …</span>
|
||||
</div>
|
||||
<div v-else class="container-fluid">
|
||||
<div class="row">
|
||||
<h2 class="mt-2">This is an overview of my current public (and open source) projects.</h2>
|
||||
<!-- projects List -->
|
||||
<div class="col-sm-12">
|
||||
<b-col v-for="project in projects" :key="project.id">
|
||||
<div class="project-container bg-dark my-4">
|
||||
<div class="row">
|
||||
<div class="col-sm-3">
|
||||
<b-link :to="'/projects/' + project.name">
|
||||
<img v-if="project.teaserImage"
|
||||
class="blog-img"
|
||||
:src="'/uploads/projects/' + project.teaserImage"
|
||||
alt="Teaser">
|
||||
<img v-else
|
||||
class="blog-img"
|
||||
src="/build/images/24unix/24_logo_bg_96x96.png"
|
||||
alt="Teaser">
|
||||
</b-link>
|
||||
<br>
|
||||
<div>
|
||||
<b-col v-for="developer in project.developer" :key="developer">
|
||||
<author :author-iri="developer"></author>
|
||||
</b-col>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-sm-8 mt-2">
|
||||
<b-link to="project.name">
|
||||
<div class="article-title d-inline-block pl-3 align-middle">
|
||||
<h2 v-html="project.name"></h2>
|
||||
</div>
|
||||
</b-link>
|
||||
<br>
|
||||
<div class="blog-teaser mb-2 pb-2 text-xl-start">
|
||||
<span v-html="project.description"></span>
|
||||
<br>
|
||||
<br>
|
||||
started: <span v-html="project.createdAt"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</b-col>
|
||||
</div>
|
||||
<div class="text-xl-start">
|
||||
<b-link to="/add"><i class="fa fa-plus-circle"></i></b-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import axios from "axios";
|
||||
|
||||
import Author from "@/components/Author";
|
||||
|
||||
export default {
|
||||
name: "ProjectsList",
|
||||
data: () => ({
|
||||
projects: null,
|
||||
isLoading: true
|
||||
}),
|
||||
mounted() {
|
||||
this.getProjects();
|
||||
},
|
||||
components: {
|
||||
Author
|
||||
},
|
||||
methods: {
|
||||
getProjects() {
|
||||
axios
|
||||
.get("/api/projects")
|
||||
.then(response => (this.projects = response.data["hydra:member"]));
|
||||
this.isLoading = false;
|
||||
console.log(this.projects);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
27
assets/js/components/Sidebar.vue
Normal file
27
assets/js/components/Sidebar.vue
Normal file
@ -0,0 +1,27 @@
|
||||
<template>
|
||||
<b-container fluid class="col sidenav-left box text-start" id="main-menu">
|
||||
<ul>
|
||||
<li>
|
||||
<i class="fa fa-lg fa-fw fa-file-code-o" aria-hidden="true"></i> 
|
||||
<b-link to="/projects">Projects</b-link>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-lg fa-fw fa-gitea" aria-hidden="true"></i>
|
||||
<b-link href="https://git.24unix.net" target="_blank">Gitea</b-link> <i class="fa fa-external-link" aria-hidden="true"></i>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-lg fa-fw fa-nextcloud" aria-hidden="true"></i>
|
||||
<a href="//cloud.24unix.net" target="_blank">NextCloud</a> <i class="fa fa-external-link" aria-hidden="true"></i>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- <a href="//pastebin.24unix.net">pastebin.24unix.net</a>-->
|
||||
</b-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: "Sidebar"
|
||||
}
|
||||
</script>
|
||||
|
37
assets/js/components/footer.vue
Normal file
37
assets/js/components/footer.vue
Normal file
@ -0,0 +1,37 @@
|
||||
<template>
|
||||
<footer class="dark fixed-bottom"> <!-- :class="['bd-footer', 'text-muted']"> -->
|
||||
<b-container class="mt-5">
|
||||
<b-row class="justify-content-center">
|
||||
<b-col class="text-center">
|
||||
<div>powered by
|
||||
<b-link to="/" class="d-inline-block mx-auto"><img src="/build/images/Spookie/spookie_64x64.png" alt="Spookie"></b-link>
|
||||
</div>
|
||||
</b-col>
|
||||
<b-col cols="auto" md="4" class="text-left">
|
||||
<div id="legal">
|
||||
<h5 class="bd-text-purple-bright mb-1 mt-3">Legal</h5>
|
||||
<ul class="list-unstyled ml-3">
|
||||
<li><b-link to="/pages/imprint">Imprint</b-link></li>
|
||||
<li><b-link to="/pages/privacy-policy">Privacy Policy</b-link></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-container>
|
||||
</footer>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "Footer"
|
||||
}
|
||||
</script>
|
||||
|
||||
<style type="scss">
|
||||
|
||||
footer {
|
||||
color: lightgray;
|
||||
background: #0e0e10;
|
||||
}
|
||||
</style>
|
12
assets/js/components/handleLogout.vue
Normal file
12
assets/js/components/handleLogout.vue
Normal file
@ -0,0 +1,12 @@
|
||||
<template>
|
||||
<div></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'HandleLogout'
|
||||
|
||||
|
||||
}
|
||||
|
||||
</script>
|
@ -1,88 +0,0 @@
|
||||
<template>
|
||||
<header>
|
||||
<b-nav class="navbar navbar-expand-md navbar-dark fixed-top navbar-top">
|
||||
<!-- <nav class="navbar navbar-expand-md navbar-dark fixed-top navbar-top {{ is_granted('ROLE_PREVIOUS_ADMIN') ? 'bg-warning' : 'bg-dark' }}"> -->
|
||||
|
||||
<!-- <a class="navbar-brand" href=" {{ path('app_main') }} -->
|
||||
<!-- <a class="navbar-brand" href="{{ path('app_main') }}"> -->
|
||||
<!-- <img src="{{ asset('build/images/24unix/24_logo_bg_64x64.png') }}" alt="24unix.net" id="site-logo"> -->
|
||||
<!-- </a> -->
|
||||
|
||||
<button class="navbar-toggler border-0" type="button" data-toggle="collapse" data-target="#CollapsingNavbar">
|
||||
☰
|
||||
</button>
|
||||
|
||||
<div class="collapse navbar-collapse" id="CollapsingNavbar">
|
||||
<ul class="navbar-nav ms-auto">
|
||||
{% if is_granted('ROLE_PREVIOUS_ADMIN') %}
|
||||
<li class="align-bottom">
|
||||
<!-- <a class="dropdown-item" href="{{ path('app_main', { '_switch_user': '_exit'}) }}">Exit -->
|
||||
<!--Impersonation</a>-->
|
||||
</li>
|
||||
{% endif %}
|
||||
<!--
|
||||
<li>
|
||||
<form class="d-flex">
|
||||
<input class="form-control me-2 my-2" type="search" placeholder="Search" aria-label="Search">
|
||||
<button class="btn" type="submit">Search</button>
|
||||
</form>
|
||||
</li>
|
||||
-->
|
||||
{% if is_granted('IS_AUTHENTICATED_REMEMBERED') %}
|
||||
<li class="nav-item dropdown me-auto">
|
||||
<button type="button" id="navbar-dropdown" data-bs-target="#dropdown-menu"
|
||||
data-bs-toggle="dropdown"
|
||||
class="btn btn-primary dropdown-toggle ml-auto mb-2 button-login">
|
||||
<span v-if="user">
|
||||
{{ user.username }}
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<div class="dropdown-menu dropdown-menu-dark dropdown-menu-end" id="dropdown-menu"
|
||||
aria-labelledby="navbar-dropdown">
|
||||
<!-- <a class="dropdown-item" -->
|
||||
<!-- href="{{ path('app_profile_edit', { 'username': app.user.username }) }}"> -->
|
||||
<span class="fa fa-lg fa-fw fa-user" aria-hidden="true"></span>
|
||||
<!--Profile</a>-->
|
||||
<a class="dropdown-item" href="#">
|
||||
<span class="fa fa-lg fa-fw fa-wrench" aria-hidden="true"></span>
|
||||
Settings</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
{% if is_granted('ROLE_ADMIN') %}
|
||||
<!-- <a class="dropdown-item" href="{{ path('app_list_user') }}">
|
||||
<span class="fa fa-lg fa-fw fa-users" aria-hidden="true"></span>
|
||||
Users
|
||||
</a>
|
||||
<a class="dropdown-item" href="{{ path('admin') }}">
|
||||
<span class="fa fa-lg fa-fw fa-cog" aria-hidden="true"></span>
|
||||
Administration
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
{% endif %}
|
||||
|
||||
<a class="dropdown-item" href="{{ path('app_logout') }}">
|
||||
<span class="fa fa-lg fa-fw fa-sign-out" aria-hidden="true"></span>
|
||||
Logout
|
||||
</a>-->
|
||||
</div>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="nav-item">
|
||||
<!-- <a class="btn btn-primary button-login" href="{{ path('app_login') }}" role="button"
|
||||
id="buttonLogin">
|
||||
<span class="fa fa-sign-in fa-lg fa-fw" aria-hidden="true"></span>Log In
|
||||
</a>-->
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</b-nav>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Header',
|
||||
props: ['user']
|
||||
}
|
||||
</script>
|
71
assets/js/components/login.vue
Normal file
71
assets/js/components/login.vue
Normal file
@ -0,0 +1,71 @@
|
||||
<template>
|
||||
<form v-on:submit.prevent="handleSubmit">
|
||||
<div v-if="error" class="alert alert-danger">
|
||||
{{ error }}
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="exampleInputEmail1">Username</label>
|
||||
<input type="text" v-model="username" class="form-control" id="username"
|
||||
aria-describedby="emailHelp" placeholder="Enter email">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="exampleInputPassword1">Password</label>
|
||||
<input type="password" v-model="password" class="form-control"
|
||||
id="exampleInputPassword1" placeholder="Password">
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="form-check-input" id="exampleCheck1">
|
||||
<label class="form-check-label" for="exampleCheck1">I like cheese</label>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary" v-bind:class="{ disabled: isLoading }">Log in</button>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from 'axios';
|
||||
|
||||
export default {
|
||||
name: 'Login',
|
||||
data() {
|
||||
return {
|
||||
username: '',
|
||||
password: '',
|
||||
error: '',
|
||||
isLoading: false
|
||||
}
|
||||
},
|
||||
props: ['user'],
|
||||
methods: {
|
||||
handleSubmit() {
|
||||
console.log("handle submit");
|
||||
this.isLoading = true
|
||||
this.error = ''
|
||||
|
||||
axios
|
||||
.post('/login', {
|
||||
username: this.username,
|
||||
password: this.password
|
||||
})
|
||||
.then(response => {
|
||||
console.log(response.headers);
|
||||
|
||||
this.$emit('user-authenticated', response.headers.location);
|
||||
this.username = '';
|
||||
this.password = '';
|
||||
}).catch(error => {
|
||||
console.log(error.response.data);
|
||||
if (error.response.data.error) {
|
||||
this.error = error.response.data.error
|
||||
} else {
|
||||
this.error = 'Unknown error'
|
||||
}
|
||||
}).finally(() => {
|
||||
this.isLoading = false;
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
70
assets/js/components/navbar.vue
Normal file
70
assets/js/components/navbar.vue
Normal file
@ -0,0 +1,70 @@
|
||||
<template>
|
||||
<b-navbar toggleable="lg" type="dark" variant="dark" fixed="top">
|
||||
<b-navbar-brand to="/">
|
||||
<img src="/build/images/24unix/24_logo_bg_96x96.png" alt="24unix.net" id="site-logo">
|
||||
</b-navbar-brand>
|
||||
|
||||
<b-navbar-toggle target="nav-collapse"></b-navbar-toggle>
|
||||
|
||||
<b-collapse id="nav-collapse" is-nav>
|
||||
|
||||
<!--
|
||||
<b-nav-form>
|
||||
<b-form-input size="sm" class="mr-sm-2" placeholder="Search"></b-form-input>
|
||||
<b-button size="sm" class="my-2 my-sm-0" type="submit">Search</b-button>
|
||||
</b-nav-form>
|
||||
-->
|
||||
<!--
|
||||
<b-nav-item-dropdown text="Lang" right>
|
||||
<b-dropdown-item href="#">EN</b-dropdown-item>
|
||||
<b-dropdown-item href="#">ES</b-dropdown-item>
|
||||
<b-dropdown-item href="#">RU</b-dropdown-item>
|
||||
<b-dropdown-item href="#">FA</b-dropdown-item>
|
||||
</b-nav-item-dropdown>
|
||||
-->
|
||||
<b-navbar-nav class="ml-auto mr-5">
|
||||
<b-button v-if="!isLoggedIn" to="/form_login">Login</b-button>
|
||||
<b-dropdown v-else id="dropdown" :text="user.username" class="m-md-2" type="dark">
|
||||
<b-dropdown-item to="/profile">
|
||||
<span class="fa fa-lg fa-fw fa-user" aria-hidden="true"></span> Profile
|
||||
</b-dropdown-item>
|
||||
<b-dropdown-item>
|
||||
<span class="fa fa-lg fa-fw fa-wrench" aria-hidden="true"></span> Settings
|
||||
</b-dropdown-item>
|
||||
<b-dropdown-divider></b-dropdown-divider>
|
||||
<b-dropdown-item @click="logout">
|
||||
<span class="fa fa-lg fa-fw fa-sign-out" aria-hidden="true"></span> Logout
|
||||
</b-dropdown-item>
|
||||
</b-dropdown>
|
||||
</b-navbar-nav>
|
||||
</b-collapse>
|
||||
</b-navbar>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from "axios";
|
||||
|
||||
|
||||
export default {
|
||||
name: "Navbar",
|
||||
props: ["user"],
|
||||
computed: {
|
||||
isLoggedIn() {
|
||||
return !!this.user;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
logout() {
|
||||
console.log("logout");
|
||||
axios
|
||||
.get("/logout")
|
||||
.then(this.$emit("invalidate-user"));
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
|
48
assets/js/components/pages.vue
Normal file
48
assets/js/components/pages.vue
Normal file
@ -0,0 +1,48 @@
|
||||
<template>
|
||||
<div>
|
||||
|
||||
|
||||
<h2 v-if="page" v-html="page.name"></h2>
|
||||
|
||||
<div v-if="page" v-html="page.content"></div>
|
||||
<b-button :to="editTarget" variant="outline"><i class="fa fa-2x fa-fw fa-edit"></i></b-button>
|
||||
<hr>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from 'axios';
|
||||
|
||||
export default {
|
||||
name: "Pages",
|
||||
data: () => ({
|
||||
page: null
|
||||
}),
|
||||
watch: {
|
||||
$route() {
|
||||
console.log("watch called")
|
||||
this.getPagesDetails()
|
||||
}
|
||||
},
|
||||
beforeMount() {
|
||||
this.getPagesDetails()
|
||||
},
|
||||
methods: {
|
||||
getPagesDetails() {
|
||||
const slug = this.$route.params.slug
|
||||
console.log("slug: " + slug)
|
||||
|
||||
axios
|
||||
.get('/api/pages?slug=' + slug)
|
||||
.then(response => (this.page = response.data['hydra:member'][0]))
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
editTarget() {
|
||||
if (this.page) {
|
||||
return "/pages/edit/" + this.page.slug
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
12
assets/js/components/profile.vue
Normal file
12
assets/js/components/profile.vue
Normal file
@ -0,0 +1,12 @@
|
||||
<template>
|
||||
<div>
|
||||
Profile
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'Profile'
|
||||
}
|
||||
</script>
|
16
assets/js/components/quotes.vue
Normal file
16
assets/js/components/quotes.vue
Normal file
@ -0,0 +1,16 @@
|
||||
<template>
|
||||
<div class="d-flex flex-column justify-content-between mt-2 mb-2">
|
||||
<div></div>
|
||||
<div>
|
||||
<span v-html="quote"></span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'Quote',
|
||||
props: ['quote']
|
||||
}
|
||||
</script>
|
66
assets/js/pages/main.vue
Normal file
66
assets/js/pages/main.vue
Normal file
@ -0,0 +1,66 @@
|
||||
<template>
|
||||
<div>
|
||||
<nav-bar :user="user" v-on:invalidate-user="onInvalidateUser"></nav-bar>
|
||||
|
||||
<b-container fluid class="mt-5 main-content">
|
||||
<b-row>
|
||||
<div class="col-2">
|
||||
<sidebar></sidebar>
|
||||
</div>
|
||||
<div class="col-9 box">
|
||||
<router-view v-on:user-authenticated="onUserAuthenticated" :quote="quote"></router-view>
|
||||
</div>
|
||||
<div class="col mt-2">
|
||||
</div>
|
||||
</b-row>
|
||||
</b-container>
|
||||
|
||||
<footer-component></footer-component>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import axios from 'axios';
|
||||
|
||||
import NavBar from '@/components/navbar'
|
||||
import Sidebar from "@/components/Sidebar";
|
||||
import FooterComponent from '@/components/footer'
|
||||
|
||||
|
||||
export default {
|
||||
name: 'Main',
|
||||
components: {
|
||||
Sidebar,
|
||||
NavBar,
|
||||
FooterComponent
|
||||
},
|
||||
methods: {
|
||||
onUserAuthenticated(userUri) {
|
||||
console.log("authenticated")
|
||||
axios
|
||||
.get(userUri)
|
||||
.then(response => (this.user = response.data))
|
||||
this.$router.push('/')
|
||||
},
|
||||
onInvalidateUser() {
|
||||
console.log("invalidated")
|
||||
this.user = null;
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
user: null,
|
||||
quote: null
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (window.user) {
|
||||
this.user = window.user
|
||||
}
|
||||
if (window.quote) {
|
||||
this.quote = window.quote
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
44
assets/js/router.js
Normal file
44
assets/js/router.js
Normal file
@ -0,0 +1,44 @@
|
||||
import Router from 'vue-router'
|
||||
import LoginForm from '@/components/login'
|
||||
import Quotes from "@/components/quotes";
|
||||
import Pages from "@/components/pages";
|
||||
import PagesEdit from "@/components/PagesEdit";
|
||||
import ProjectsList from "@/components/ProjectsList";
|
||||
import Profile from "@/components/profile";
|
||||
import NotFound from "@/components/NotFound"
|
||||
|
||||
export default new Router({
|
||||
mode: 'history',
|
||||
routes: [
|
||||
{
|
||||
path: '/',
|
||||
name: 'Home',
|
||||
component: Quotes
|
||||
},
|
||||
{
|
||||
path: '/form_login',
|
||||
name: 'LoginForm',
|
||||
component: LoginForm,
|
||||
},
|
||||
{
|
||||
path: '/projects',
|
||||
component: ProjectsList
|
||||
},
|
||||
{
|
||||
path: '/pages/:slug',
|
||||
component: Pages
|
||||
},
|
||||
{
|
||||
path: '/pages/edit/:slug',
|
||||
component: PagesEdit
|
||||
},
|
||||
{
|
||||
path: '/profile',
|
||||
component: Profile
|
||||
},
|
||||
{
|
||||
path: '*',
|
||||
component: NotFound
|
||||
}
|
||||
]
|
||||
})
|
Reference in New Issue
Block a user