while upgrading to symfony 6.1
This commit is contained in:
.envTODOsymfony.lock
assets
app.jsbootstrap.jscontrollers.json
composer.jsoncomposer.lockpackage.jsonpostcss.config.jscontrollers
js
App.vue
components
AppLink.vueHandleLogout.vueLoginForm.vueNotFound.vueTheAbout.vueTheFooter.vueTheNavbar.vueTheSidebar.vue
blog
minesweeper
pages
projects
quotes
tabs
users
composables
index.jsrouter
stores
styles
public
src
Controller
Security
templates
webpack.config.jsyarn.lock
12
assets/app.js
Normal file
12
assets/app.js
Normal file
@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Welcome to your app's main JavaScript file!
|
||||
*
|
||||
* We recommend including the built version of this JavaScript file
|
||||
* (and its CSS file) in your base layout (base.html.twig).
|
||||
*/
|
||||
|
||||
// any CSS you import will output into a single css file (app.css in this case)
|
||||
import './styles/app.css';
|
||||
|
||||
// start the Stimulus application
|
||||
import './bootstrap';
|
11
assets/bootstrap.js
vendored
Normal file
11
assets/bootstrap.js
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
import { startStimulusApp } from '@symfony/stimulus-bridge';
|
||||
|
||||
// Registers Stimulus controllers from controllers.json and in the controllers/ directory
|
||||
export const app = startStimulusApp(require.context(
|
||||
'@symfony/stimulus-bridge/lazy-controller-loader!./controllers',
|
||||
true,
|
||||
/\.[jt]sx?$/
|
||||
));
|
||||
|
||||
// register any custom, 3rd party controllers here
|
||||
// app.register('some_controller_name', SomeImportedController);
|
4
assets/controllers.json
Normal file
4
assets/controllers.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"controllers": [],
|
||||
"entrypoints": []
|
||||
}
|
16
assets/controllers/hello_controller.js
Normal file
16
assets/controllers/hello_controller.js
Normal file
@ -0,0 +1,16 @@
|
||||
import { Controller } from '@hotwired/stimulus';
|
||||
|
||||
/*
|
||||
* This is an example Stimulus controller!
|
||||
*
|
||||
* Any element with a data-controller="hello" attribute will cause
|
||||
* this controller to be executed. The name "hello" comes from the filename:
|
||||
* hello_controller.js -> "hello"
|
||||
*
|
||||
* Delete this file or adapt it for your use!
|
||||
*/
|
||||
export default class extends Controller {
|
||||
connect() {
|
||||
this.element.textContent = 'Hello Stimulus! Edit me in assets/controllers/hello_controller.js';
|
||||
}
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
<template>
|
||||
<v-app>
|
||||
<v-app-bar color="grey-lighten-2"/>
|
||||
<!--
|
||||
<the-navbar
|
||||
@invalidate-user="onUserInvalidate"
|
||||
/>
|
||||
-->
|
||||
<v-navigation-drawer></v-navigation-drawer>
|
||||
<v-main class="container-fluid text-center">
|
||||
<div class="col-xl-3">
|
||||
<the-sidebar/>
|
||||
</div>
|
||||
<div class="col-xl-9">
|
||||
<suspense>
|
||||
<template #default>
|
||||
<router-view
|
||||
@user-authenticated="onUserAuthenticated"
|
||||
/>
|
||||
</template>
|
||||
<template #fallback>
|
||||
<div class="loading">
|
||||
loading …
|
||||
</div>
|
||||
</template>
|
||||
</suspense>
|
||||
</div>
|
||||
<div class="col mt-2"/>
|
||||
</v-main>
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<the-footer/>
|
||||
</div>
|
||||
</div>
|
||||
</v-app>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import axios from 'axios'
|
||||
import { useRoute } from 'vue-router'
|
||||
//import RouterView from 'vue-router'
|
||||
import TheNavbar from '@/components/TheNavbar'
|
||||
import TheSidebar from '@/components/TheSidebar'
|
||||
import TheFooter from '@/components/TheFooter'
|
||||
|
||||
if (window.user) {
|
||||
const { user } = window
|
||||
}
|
||||
if (window.quote) {
|
||||
const { quote } = window
|
||||
}
|
||||
|
||||
const onUserAuthenticated = (userUri) => {
|
||||
//console.log('authenticated')
|
||||
axios
|
||||
.get(userUri)
|
||||
.then((response) => {
|
||||
this.user = response.data
|
||||
})
|
||||
this.$router.push('/')
|
||||
}
|
||||
|
||||
const onUserInvalidate = () => {
|
||||
//console.log('invalidated')
|
||||
this.user = null
|
||||
window.user = null
|
||||
}
|
||||
|
||||
</script>
|
@ -1,48 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div v-if="isExternal">
|
||||
<a :href="to">
|
||||
<span
|
||||
:class="`fa fa-lg fa-fw ${fa}`"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
|
||||
<slot/>
|
||||
</a>
|
||||
|
||||
<span
|
||||
class="fa fa-lg fa-fw fa-external-link"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</div>
|
||||
<router-link
|
||||
v-else
|
||||
:to="{ name: props.to }"
|
||||
>
|
||||
<span
|
||||
:class="`fa fa-lg fa-fw ${fa}`"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
|
||||
<slot/>
|
||||
</router-link>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { RouterLink } from 'vue-router'
|
||||
|
||||
const props = defineProps({
|
||||
to: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
fa: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
|
||||
const isExternal = computed(() => props.to.startsWith('http'))
|
||||
</script>
|
@ -1,10 +0,0 @@
|
||||
<template>
|
||||
<div></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'HandleLogout'
|
||||
}
|
||||
|
||||
</script>
|
@ -1,97 +0,0 @@
|
||||
<template>
|
||||
<div class="container box">
|
||||
<form @submit.prevent="handleSubmit">
|
||||
<div
|
||||
v-if="errorMessage"
|
||||
class="alert alert-danger mt-2"
|
||||
>
|
||||
{{ errorMessage }}
|
||||
</div>
|
||||
<div class="form-group mt-2">
|
||||
<label for="exampleInputEmail1">Username</label>
|
||||
<input
|
||||
id="username"
|
||||
v-model="username"
|
||||
type="text"
|
||||
class="form-control"
|
||||
aria-describedby="emailHelp"
|
||||
placeholder="Enter email"
|
||||
>
|
||||
</div>
|
||||
<div class="form-group mt-2">
|
||||
<label for="password">Password</label>
|
||||
<input
|
||||
id="password"
|
||||
v-model="password"
|
||||
type="password"
|
||||
class="form-control"
|
||||
placeholder="Password"
|
||||
>
|
||||
</div>
|
||||
<div class="form-check mt-2">
|
||||
<input
|
||||
id="remember-me"
|
||||
type="checkbox"
|
||||
class="form-check-input"
|
||||
>
|
||||
<label
|
||||
class="form-check-label"
|
||||
for="remember-me"
|
||||
>
|
||||
Remember Me
|
||||
</label>
|
||||
</div>
|
||||
<button
|
||||
type="submit"
|
||||
class="btn btn-primary mt-2 mb-2"
|
||||
:class="{ disabled: isLoading }"
|
||||
>
|
||||
Log in
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import axios from 'axios'
|
||||
|
||||
const username = ref('')
|
||||
const password = ref('')
|
||||
const errorMessage = ref('')
|
||||
const isLoading = ref(false)
|
||||
const emit = defineEmits(['user-authenticated'])
|
||||
|
||||
const handleSubmit = () => {
|
||||
//console.log('handle submit')
|
||||
isLoading.value = true
|
||||
|
||||
axios
|
||||
.post('/login', {
|
||||
username: username.value,
|
||||
password: password.value
|
||||
})
|
||||
.then((response) => {
|
||||
//console.log(response.headers)
|
||||
|
||||
emit('user-authenticated', response.headers.location)
|
||||
username.value = ''
|
||||
password.value = ''
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error)
|
||||
console.log(error.response.data)
|
||||
if (error.response.data.error) {
|
||||
errorMessage.value = error.response.data.error
|
||||
} else {
|
||||
errorMessage.value = 'Unknown error'
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
isLoading.value = false
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
@ -1,11 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
404 Not Found
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'NotFound'
|
||||
}
|
||||
</script>
|
@ -1,14 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
Bio:
|
||||
|
||||
Symfonycast
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'TheAbout'
|
||||
}
|
||||
</script>
|
@ -1,63 +0,0 @@
|
||||
<template>
|
||||
<footer class="dark fixed-bottom">
|
||||
<div class="container mt-5">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col text-center">
|
||||
<div>
|
||||
powered by
|
||||
<router-link
|
||||
to="/"
|
||||
class="d-inline-block mx-auto"
|
||||
>
|
||||
<img
|
||||
src="/build/images/Spookie/spookie_64x64.png"
|
||||
alt="Spookie"
|
||||
>
|
||||
</router-link>
|
||||
<div>
|
||||
<router-link
|
||||
:to="{ name: 'About'}"
|
||||
class="d-inline-block mx-auto"
|
||||
>
|
||||
About Me
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col md-4 text-left">
|
||||
<div id="legal">
|
||||
<h5 class="bd-text-purple-bright mb-1 mt-3">
|
||||
Legal
|
||||
</h5>
|
||||
<ul class="list-unstyled ml-3">
|
||||
<li>
|
||||
<router-link :to="{ name: 'Pages', params: {slug: 'imprint'}}">
|
||||
Imprint
|
||||
</router-link>
|
||||
</li>
|
||||
<li>
|
||||
<router-link to="/pages/privacy-policy">
|
||||
Privacy Policy
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'TheFooter'
|
||||
}
|
||||
</script>
|
||||
|
||||
<style type="scss">
|
||||
|
||||
footer {
|
||||
color: lightgray;
|
||||
background: #0e0e10;
|
||||
}
|
||||
</style>
|
@ -1,73 +0,0 @@
|
||||
<template>
|
||||
<nav
|
||||
class="
|
||||
grid fixed inset-x-0 top-0 flex-wrap justify-between items-center py-0 leading-6 border-b
|
||||
@border-orange-400 opacity-90 md:flex-nowrap md:justify-start md:px-24 box-border
|
||||
bg-neutral-800 text-stone-300 grid-cols-2 place-content-around"
|
||||
style="z-index: 1030;"
|
||||
>
|
||||
<div>
|
||||
<router-link
|
||||
class="py-1 mr-4 text-xl leading-7 text-white whitespace-nowrap cursor-pointer box-border
|
||||
hover:text-white focus:text-white"
|
||||
:to="{ name: 'Home' }"
|
||||
>
|
||||
<img
|
||||
src="/build/images/24unix/24_logo_bg_96x96.png"
|
||||
class="align-middle box-border"
|
||||
alt="24unix.net"
|
||||
>
|
||||
</router-link>
|
||||
</div>
|
||||
<div class="text-end">
|
||||
<router-link
|
||||
id="buttonLogin"
|
||||
class="inline-block py-1 px-3 mt-6 text-base font-normal leading-normal text-center
|
||||
text-black align-middle bg-orange-400 rounded border border-orange-400 border-solid
|
||||
cursor-pointer select-none box-border hover:border-orange-400 hover:bg-orange-400 hover:text-black
|
||||
focus:border-orange-400 focus:bg-orange-400 focus:text-black"
|
||||
:to="{ name: 'LoginForm' }"
|
||||
role="button"
|
||||
style="text-decoration: none; transition: none 0s ease 0s; list-style: outside none none;"
|
||||
>
|
||||
<span class="fa fa-sign-in fa-lg fa-fw"></span> Log In
|
||||
</router-link>
|
||||
|
||||
</div>
|
||||
|
||||
</nav>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import axios from 'axios'
|
||||
import 'vue-navigation-bar/dist/vue-navigation-bar.css'
|
||||
|
||||
const props = defineProps({
|
||||
user: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {
|
||||
username: 'tracer'
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const isLoggedIn = () => (!!this.user)
|
||||
let showDropdown = ref(false)
|
||||
const toggleDropDown = () => {
|
||||
console.log('toggle', showDropdown)
|
||||
showDropdown.value = !showDropdown.value
|
||||
}
|
||||
|
||||
/*
|
||||
const logout = () => ({
|
||||
axios
|
||||
.get('/logout')
|
||||
.then(this.$emit('invalidate-user'))
|
||||
|
||||
})
|
||||
|
||||
*/
|
||||
</script>
|
@ -1,62 +0,0 @@
|
||||
<template>
|
||||
<div
|
||||
id="main-menu"
|
||||
class="container-fluid col sidenav-left box text-start"
|
||||
>
|
||||
<ul>
|
||||
<li
|
||||
v-for="link in links"
|
||||
:key="link.url"
|
||||
>
|
||||
<AppLink
|
||||
:to="link.url"
|
||||
:fa="link.fa"
|
||||
>
|
||||
{{ link.name }}
|
||||
</AppLink>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'TheSidebar',
|
||||
data: () => ({
|
||||
links: [
|
||||
{
|
||||
name: 'Projects',
|
||||
url: 'Projects',
|
||||
fa: 'fa-file-code-o',
|
||||
},
|
||||
{
|
||||
name: 'Blog',
|
||||
url: 'Blog',
|
||||
fa: 'fa-file-text-o',
|
||||
},
|
||||
{
|
||||
name: 'Gitea',
|
||||
url: 'https://git.24unix.net',
|
||||
fa: 'fa-gitea',
|
||||
},
|
||||
{
|
||||
name: 'NextCloud',
|
||||
url: 'https://cloud.24unix.net',
|
||||
fa: 'fa-nextcloud',
|
||||
},
|
||||
{
|
||||
name: 'Pastebin',
|
||||
url: 'https://pastebin.24unix.net',
|
||||
fa: 'fa-paste',
|
||||
},
|
||||
{
|
||||
name: 'YOURLS',
|
||||
url: 'https://y.24unix.net',
|
||||
fa: 'fa-link',
|
||||
external: true
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
</script>
|
@ -1,55 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- media -->
|
||||
<div class="h-64 w-auto md:w-1/2">
|
||||
<img
|
||||
class="inset-0 h-full w-full object-cover object-center"
|
||||
src="/build/images/tracer_schmolle150x150.png"
|
||||
alt=""
|
||||
>
|
||||
</div>
|
||||
<!-- content -->
|
||||
<div class="w-full py-4 px-6 text-gray-800 flex flex-col justify-between">
|
||||
<h3 class="font-semibold text-lg leading-tight truncate">
|
||||
{{ post.title }}
|
||||
</h3>
|
||||
<p class="mt-2">
|
||||
{{ post.body.split('.')[0] }} …
|
||||
</p>
|
||||
<p class="text-sm text-gray-700 uppercase tracking-wide font-semibold mt-2">
|
||||
{{ post.createdAt.toLocaleString('de-DE') }}
|
||||
</p>
|
||||
<p v-if="blogUser">
|
||||
{{ blogUser }}
|
||||
</p>
|
||||
<p class="font-normal text-gray-700 mb-3">
|
||||
dddd
|
||||
</p>
|
||||
<router-link
|
||||
:to="{ name: 'BlogPost', params: { id: post.id } }"
|
||||
class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300
|
||||
font-medium rounded-lg text-sm px-3 py-2 text-center inline-flex items-center"
|
||||
>
|
||||
Read more
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import useResource from '@/composables/useResource'
|
||||
|
||||
const props = defineProps({
|
||||
post: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
const post = { ...props.post }
|
||||
|
||||
const { items: blogUser, fetchOne } = useResource('users')
|
||||
fetchOne(post.user)
|
||||
|
||||
console.log("blug user", post.user)
|
||||
console.log(blogUser.value)
|
||||
</script>
|
@ -1,37 +0,0 @@
|
||||
<template>
|
||||
<div class="pt-6 pb-12 bg-gray-300">
|
||||
<div
|
||||
id="card"
|
||||
class=""
|
||||
>
|
||||
<h2 class="text-center font-serif uppercase text-4xl xl:text-5xl">
|
||||
Recent Articles
|
||||
</h2>
|
||||
<!-- container for all cards -->
|
||||
<div class="container w-100 lg:w-4/5 mx-auto flex flex-col">
|
||||
<BlogCard
|
||||
v-for="post in blogPosts"
|
||||
:key="post.id"
|
||||
:post="post"
|
||||
class="
|
||||
flex flex-col md:flex-row overflow-hidden bg-white rounded-lg
|
||||
shadow-xl mt-4 w-100 mx-2"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup async>
|
||||
|
||||
import useResource from '@/composables/useResource'
|
||||
//import useUser from '@/composables/useUser'
|
||||
import BlogCard from '@/components/blog/BlogCard'
|
||||
|
||||
const {
|
||||
items: blogPosts,
|
||||
fetchAll
|
||||
} = useResource('users/1/blogPosts')
|
||||
fetchAll()
|
||||
|
||||
</script>
|
@ -1,47 +0,0 @@
|
||||
<template>
|
||||
<div
|
||||
v-if="blogPost"
|
||||
class="
|
||||
flex
|
||||
m-2
|
||||
gap-2
|
||||
items-center
|
||||
shadow-md
|
||||
w-1/4
|
||||
flex-grow
|
||||
rounded
|
||||
overflow-hidden
|
||||
"
|
||||
style="border: 1px solid #eee"
|
||||
>
|
||||
BlogIPost
|
||||
<img
|
||||
src="https://via.placeholder.com/150"
|
||||
style="background: #cccccc"
|
||||
width="150"
|
||||
height="150"
|
||||
alt="placeholder"
|
||||
>
|
||||
user {{ blogPost.userId }}:
|
||||
<div v-if="user">
|
||||
"{{ user.name }}
|
||||
</div>
|
||||
<br>
|
||||
{{ blogPost.title }}<br>
|
||||
{{ blogPost.body }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup async>
|
||||
import { useRoute } from 'vue-router'
|
||||
import useResource from '@/composables/useResource'
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
const { item: blogPost, fetchOne: fetchOneBlog } = useResource('https://jsonplaceholder.typicode.com/posts')
|
||||
await fetchOneBlog(route.params.id)
|
||||
|
||||
const { item: user, fetchOne: fetchOneUser } = useResource('https://jsonplaceholder.typicode.com/users')
|
||||
fetchOneUser(blogPost.value.userId)
|
||||
|
||||
</script>
|
@ -1,3 +0,0 @@
|
||||
<template>
|
||||
|
||||
</template>
|
@ -1,60 +0,0 @@
|
||||
<template>
|
||||
<div class="box ma7 p-5">
|
||||
<h2
|
||||
v-if="page"
|
||||
v-html="page.name"
|
||||
/>
|
||||
<div
|
||||
v-if="page"
|
||||
v-html="page.content"
|
||||
/>
|
||||
|
||||
<router-link
|
||||
:to="editTarget"
|
||||
variant="outline"
|
||||
>
|
||||
<button>
|
||||
<i class="fa fa-2x fa-fw fa-edit"/>
|
||||
</button>
|
||||
</router-link>
|
||||
<hr>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, watchEffect, computed } from 'vue'
|
||||
import axios from 'axios'
|
||||
//import h from 'highlightjs'
|
||||
//import hi from 'highlightjs-line-numbers.js'
|
||||
|
||||
//hi.highlightAll()
|
||||
//hi.initLineNumbersOnLoad()
|
||||
|
||||
const props = defineProps({
|
||||
slug: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
let page = reactive({ name: '', slug: '' })
|
||||
|
||||
const editTarget = computed(() => {
|
||||
if (page) {
|
||||
return `/pages/edit/${page.slug}`
|
||||
}
|
||||
return ''
|
||||
})
|
||||
|
||||
const getPagesDetails = async (slug) => {
|
||||
console.log('get page details')
|
||||
await axios.get(`/api/pages?slug=${slug}`)
|
||||
.then((response) => {
|
||||
page = response.data['hydra:member']
|
||||
console.log(page)
|
||||
})
|
||||
}
|
||||
|
||||
// watch fpr slug
|
||||
watchEffect(() => getPagesDetails(props.slug))
|
||||
</script>
|
@ -1,152 +0,0 @@
|
||||
<template>
|
||||
<div
|
||||
v-if="!isLoading"
|
||||
class="box p-3"
|
||||
>
|
||||
<tabs-group @tabActivated="tabActivated">
|
||||
<tab-content title="Visual Editor">
|
||||
<div class="editor mt-2">
|
||||
<QuillEditor
|
||||
ref="editor"
|
||||
theme="snow"
|
||||
:content="JSON.parse(page.content)"
|
||||
:options="editorOptions"
|
||||
:disabled="isVueEditorDisabled"
|
||||
/>
|
||||
<button
|
||||
class="btn btn-primary mt-3 mb-2"
|
||||
@click="saveContent"
|
||||
>
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
</tab-content>
|
||||
<tab-content title="Preview">
|
||||
<div class="preview mt-2 no-overflow">
|
||||
<QuillEditor
|
||||
ref="preview"
|
||||
theme="bubble"
|
||||
class="no-overflow"
|
||||
:content="JSON.parse(page.content)"
|
||||
:options="editorOptions"
|
||||
:disabled="true"
|
||||
/>
|
||||
</div>
|
||||
<!--
|
||||
<div>
|
||||
<textarea
|
||||
v-model="page.content"
|
||||
class="p-fluid pages-editor-raw"
|
||||
/>
|
||||
</div>
|
||||
-->
|
||||
</tab-content>
|
||||
<tab-content title="Delta">
|
||||
<div class="editor mt-2">
|
||||
<textarea
|
||||
ref="delta"
|
||||
v-model="page.content"
|
||||
class="p-fluid pages-editor-raw"
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
class="btn btn-primary mt-3 mb-2"
|
||||
@click="saveDelta"
|
||||
>
|
||||
Save
|
||||
</button>
|
||||
</tab-content>
|
||||
</tabs-group>
|
||||
</div>
|
||||
<div v-else>
|
||||
<i class="fa fa-spinner fa-spin fa-3x fa-fw"/>
|
||||
<span class="sr-only">Loading …</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import axios from 'axios'
|
||||
|
||||
import 'highlight.js/styles/tomorrow-night-blue.css'
|
||||
import hljs from 'highlight.js'
|
||||
|
||||
//import Quill from 'quill'
|
||||
import { Quill, QuillEditor } from '@vueup/vue-quill'
|
||||
import '@vueup/vue-quill/dist/vue-quill.snow.css'
|
||||
import '@vueup/vue-quill/dist/vue-quill.bubble.css'
|
||||
|
||||
import htmlEditButton from 'quill-html-edit-button'
|
||||
|
||||
import TabsGroup from '@/components/tabs/TabsGroup'
|
||||
import TabContent from '@/components/tabs/TabContent'
|
||||
|
||||
Quill
|
||||
// .register('modules/syntax', syntax, false)
|
||||
.register('modules/htmlEditButton', htmlEditButton)
|
||||
|
||||
hljs.configure({
|
||||
languages: ['javascript', 'php', 'swift']
|
||||
})
|
||||
|
||||
export default {
|
||||
name: 'PagesEdit',
|
||||
components: {
|
||||
QuillEditor,
|
||||
TabsGroup,
|
||||
TabContent
|
||||
},
|
||||
data: () => ({
|
||||
page: null,
|
||||
isLoading: true,
|
||||
isVueEditorDisabled: false,
|
||||
editorOptions: {
|
||||
modules: {
|
||||
htmlEditButton: {
|
||||
debug: true
|
||||
},
|
||||
syntax: {
|
||||
highlight: (text) => hljs.highlightAuto(text).value
|
||||
}
|
||||
}
|
||||
},
|
||||
theme: 'snow'
|
||||
}),
|
||||
beforeMount() {
|
||||
const { slug } = this.$route.params
|
||||
|
||||
axios
|
||||
.get(`/api/pages?slug=${slug}`)
|
||||
.then((response) => {
|
||||
[this.page] = response.data['hydra:member']
|
||||
this.isLoading = false
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
saveContent() {
|
||||
this.page.content = JSON.stringify(this.$refs.editor.getContents())
|
||||
axios
|
||||
.put(`/api/pages/${this.page.id}`, this.page)
|
||||
.then(() => {
|
||||
//this.$router.push({
|
||||
// name: 'Pages',
|
||||
// params: { slug: this.page.slug }
|
||||
//})
|
||||
})
|
||||
},
|
||||
saveDelta() {
|
||||
axios
|
||||
.put(`/api/pages/${this.page.id}`, this.page)
|
||||
.then(() => {
|
||||
//this.$router.push({
|
||||
// name: 'Pages',
|
||||
// params: { slug: this.page.slug }
|
||||
//})
|
||||
})
|
||||
},
|
||||
tabActivated(name) {
|
||||
this.isVueEditorDisabled = name === 'Raw Content'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@ -1,107 +0,0 @@
|
||||
<template>
|
||||
<div
|
||||
v-if="isLoading"
|
||||
class="circle"
|
||||
>
|
||||
<i class="fa fa-spinner fa-spin fa-3x fa-fw"/>
|
||||
<span class="sr-only">Loading …</span>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="row"
|
||||
>
|
||||
<div class="col-sm-12">
|
||||
<!-- {% if is_granted('ROLE_ADMIN') %}
|
||||
<div class="d-flex justify-content-end">
|
||||
<a :to="id"><i class="fa fa-3x fa-fw fa-edit"></i></a>
|
||||
<a :to="project.id"><i class="fa fa-3x fa-fw fa-trash"></i></a>
|
||||
</div>
|
||||
{% endif %}-->
|
||||
|
||||
<div class="show-article-container p-3 mt-4">
|
||||
<div class="show-article-title-container d-inline-block pl-3 align-middle">
|
||||
<h2>{{ project.name }}</h2>
|
||||
</div>
|
||||
<div>
|
||||
Source:
|
||||
<a
|
||||
:href="project.url"
|
||||
target="_blank"
|
||||
>
|
||||
{{ project.url }}
|
||||
</a>
|
||||
|
||||
<i
|
||||
class="fa fa-external-link"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</div>
|
||||
<div class="row mt-5">
|
||||
<div class="col-sm-12">
|
||||
<!-- eslint-disable vue/no-v-html -->
|
||||
<div
|
||||
class="article-text"
|
||||
v-html="readmeToHtml"
|
||||
/>
|
||||
<!-- eslint-enable -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import axios from 'axios'
|
||||
import { marked } from 'marked'
|
||||
import Author from '@/components/users/UserCard'
|
||||
|
||||
export default {
|
||||
Name: 'ProjectDetails',
|
||||
components: {
|
||||
Author,
|
||||
marked
|
||||
},
|
||||
data: () => ({
|
||||
project: null,
|
||||
readme: null,
|
||||
isLoading: true
|
||||
}),
|
||||
computed: {
|
||||
readmeToHtml() {
|
||||
if (!this.isLoading) {
|
||||
return marked(this.readme)
|
||||
}
|
||||
return ''
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
const { id } = this.$route.params
|
||||
console.log(id)
|
||||
axios
|
||||
.get(`/api/projects/${id}`)
|
||||
.then((projectResponse) => {
|
||||
this.project = projectResponse.data
|
||||
console.log(this.project)
|
||||
axios
|
||||
.get(`${this.project.url}/raw/branch/master/README.md`)
|
||||
.then((response) => {
|
||||
this.readme = response.data
|
||||
this.isLoading = false
|
||||
console.log(response)
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error)
|
||||
})
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error)
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
getProjects() {
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@ -1,113 +0,0 @@
|
||||
<template>
|
||||
<div
|
||||
v-if="isLoading"
|
||||
class="circle"
|
||||
>
|
||||
<i class="fa fa-spinner fa-spin fa-3x fa-fw"/>
|
||||
<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">
|
||||
<div
|
||||
v-for="project in projects"
|
||||
:key="project.id"
|
||||
>
|
||||
<div class="project-container bg-dark my-4">
|
||||
<div class="row">
|
||||
<div class="col-sm-3">
|
||||
<router-link :to="'/projects/' + project.id">
|
||||
<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"
|
||||
>
|
||||
</router-link>
|
||||
<br>
|
||||
<div>
|
||||
<div
|
||||
v-for="developer in project.developer"
|
||||
:key="developer"
|
||||
class="col"
|
||||
>
|
||||
<user-card :author-iri="developer"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-8 mt-2">
|
||||
<router-link :to="'/projects/' + project.id">
|
||||
<div class="article-title d-inline-block pl-3 align-middle">
|
||||
<h2 v-html="project.name"/>
|
||||
</div>
|
||||
</router-link>
|
||||
<br>
|
||||
<div class="blog-teaser mb-2 pb-2 text-xl-start">
|
||||
<span v-html="project.description"/>
|
||||
<br>
|
||||
<br>
|
||||
started: <span v-html="formatDate(project.createdAt)"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--
|
||||
<div class="text-xl-start">
|
||||
<router-link to="/add">
|
||||
<i class="fa fa-plus-circle"/>
|
||||
</router-link>
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import axios from 'axios'
|
||||
|
||||
import UserCard from '@/components/users/UserCard'
|
||||
|
||||
export default {
|
||||
name: 'ProjectsList',
|
||||
components: {
|
||||
UserCard,
|
||||
},
|
||||
data: () => ({
|
||||
projects: null,
|
||||
isLoading: true
|
||||
}),
|
||||
mounted() {
|
||||
this.getProjects()
|
||||
},
|
||||
methods: {
|
||||
getProjects() {
|
||||
axios
|
||||
.get('/api/projects')
|
||||
.then((response) => {
|
||||
this.projects = response.data['hydra:member']
|
||||
})
|
||||
this.isLoading = false
|
||||
console.log(this.projects)
|
||||
},
|
||||
formatDate(date) {
|
||||
return new Date(date).toLocaleDateString('de-DE')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@ -1,16 +0,0 @@
|
||||
<template>
|
||||
<div class="d-flex flex-column justify-content-between box mt-2 p-3 mb-2">
|
||||
<div></div>
|
||||
<div>
|
||||
<span v-html="quote"></span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'Quote',
|
||||
props: ['quote']
|
||||
}
|
||||
</script>
|
@ -1,34 +0,0 @@
|
||||
<template lang="html">
|
||||
<div
|
||||
v-show="title === selectedTitle"
|
||||
class="tab-content"
|
||||
>
|
||||
<slot/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { inject } from 'vue'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
setup() {
|
||||
const selectedTitle = inject('selectedTitle')
|
||||
return {
|
||||
selectedTitle
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.tab-content {
|
||||
padding: 20px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
</style>
|
@ -1,78 +0,0 @@
|
||||
<template lang="html">
|
||||
<div class="tabs">
|
||||
<ul class="tabs-header">
|
||||
<li
|
||||
v-for="title in tabTitles"
|
||||
:key="title"
|
||||
:class="{ selected: title === selectedTitle }"
|
||||
class="btn"
|
||||
@click="handleClick(title)"
|
||||
>
|
||||
{{ title }}
|
||||
</li>
|
||||
</ul>
|
||||
<slot/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, provide } from 'vue'
|
||||
|
||||
export default {
|
||||
name: 'TabsGroup',
|
||||
setup(props, { slots }) {
|
||||
const tabTitles = ref(slots.default()
|
||||
.map((tab) => tab.props.title))
|
||||
const selectedTitle = ref(tabTitles.value[0])
|
||||
|
||||
provide('selectedTitle', selectedTitle)
|
||||
return {
|
||||
selectedTitle,
|
||||
tabTitles
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleClick(title) {
|
||||
this.selectedTitle = title
|
||||
this.$emit('tabActivated', title)
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
@import "~styles/app.scss";
|
||||
.tabs {
|
||||
width: auto;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.tabs-header {
|
||||
margin-bottom: 10px;
|
||||
list-style: none;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.tabs-header li {
|
||||
width: 140px;
|
||||
text-align: center;
|
||||
padding: 10px 20px;
|
||||
margin-right: 10px;
|
||||
background-color: #2e2e2e;
|
||||
border-radius: 5px;
|
||||
color: #999999;
|
||||
cursor: pointer;
|
||||
transition: 0.4s all ease-out;
|
||||
}
|
||||
|
||||
.tabs-header li.selected {
|
||||
background-color: $primary;
|
||||
color: $jet-black;
|
||||
}
|
||||
|
||||
.tabs-header li.selected:hover {
|
||||
/*border-color: $body-color; */
|
||||
}
|
||||
|
||||
</style>
|
@ -1,87 +0,0 @@
|
||||
<template>
|
||||
<div
|
||||
v-if="isLoading"
|
||||
class="circle"
|
||||
>
|
||||
<i class="fa fa-spinner fa-spin fa-3x fa-fw"/>
|
||||
<span class="sr-only">Loading …</span>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="container box rounded bg-dark mt-5 mb-5"
|
||||
>
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
<div class="d-flex flex-column align-items-center text-center p-3 py-5">
|
||||
Profile of {{ user.username }}
|
||||
<img
|
||||
class="rounded-circle border-1 mt-5"
|
||||
src="/build/images/tracer_schmolle150x150.png"
|
||||
alt="profile image"
|
||||
>
|
||||
<span class="font-weight-bold">{{ user.username }}</span>
|
||||
<!--
|
||||
<span class="font-weight-bold">
|
||||
<a href="{{ path('app_main', { '_switch_user': app.user.username }) }}">
|
||||
switch user {{ user.username }}</span>
|
||||
-->
|
||||
<span class="text-white-50">
|
||||
<i class="fa fa-lg fa-envelope me-1"/>{{ user.email }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-5">
|
||||
<div class="p-3 py-5">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h4 class="text-right">
|
||||
User Projects …
|
||||
</h4>
|
||||
</div>
|
||||
<div class="row mt-2"/>
|
||||
|
||||
<!--
|
||||
<div class="mt-5 text-center">
|
||||
<button class="btn btn-primary profile-button" type="button">Save Profile</button>
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from 'vue'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import axios from 'axios'
|
||||
|
||||
const user = reactive(null)
|
||||
const isLoading = ref(true)
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
|
||||
// if there is no param, we go to our own profile, elso to the login
|
||||
|
||||
if (route.params.username) {
|
||||
console.log('we have the username')
|
||||
} else if (window.user) {
|
||||
console.log(window.user)
|
||||
} else {
|
||||
router.push({ name: 'LoginForm' })
|
||||
}
|
||||
|
||||
const userEndpoint = '/api/users?username=tracer'
|
||||
axios
|
||||
.get(userEndpoint)
|
||||
.then((response) => {
|
||||
//console.log(response);
|
||||
[user.value] = response.data['hydra:member']
|
||||
|
||||
//console.log(this.user)
|
||||
isLoading.value = false
|
||||
})
|
||||
.catch(() => {
|
||||
//console.log(error)
|
||||
})
|
||||
|
||||
</script>
|
@ -1,67 +0,0 @@
|
||||
<template>
|
||||
<div
|
||||
v-if="isLoading"
|
||||
class="circle"
|
||||
>
|
||||
<i class="fa fa-spinner fa-spin fa-3x fa-fw"/>
|
||||
<span class="sr-only">Loading …</span>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="mt-1 mb-1"
|
||||
>
|
||||
<router-link
|
||||
class="align-left blog-details"
|
||||
:to="'/profile/' + author.username"
|
||||
>
|
||||
<img
|
||||
class="article-author-img rounded-circle"
|
||||
:src="'build/images/' + author.avatar"
|
||||
alt="profile"
|
||||
>
|
||||
</router-link>
|
||||
<router-link :to="'/profile/' + author.username">
|
||||
{{ author.username }}
|
||||
</router-link>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import axios from 'axios'
|
||||
|
||||
export default {
|
||||
name: 'UserCard',
|
||||
props: {
|
||||
authorIri: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data: () => ({
|
||||
author: null,
|
||||
isLoading: true
|
||||
}),
|
||||
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>
|
@ -1,34 +0,0 @@
|
||||
import { ref } from 'vue'
|
||||
import axios from 'axios'
|
||||
|
||||
export default function useResource(resource) {
|
||||
|
||||
console.log('useBlog')
|
||||
axios.defaults.headers.common['app-id'] = '628cbf673800f869ed218152' // for all requests
|
||||
|
||||
const apiBaseUrl = 'https://628cc5c6a3fd714fd03914c2.mockapi.io/api/'
|
||||
const items = ref([])
|
||||
const item = ref(null)
|
||||
const fetchAll = async () => {
|
||||
await axios
|
||||
.get(apiBaseUrl + resource)
|
||||
.then((response) => {
|
||||
console.log(response.data)
|
||||
items.value = response.data
|
||||
})
|
||||
}
|
||||
const fetchOne = async (id) => {
|
||||
console.log('fetchOne', id)
|
||||
await axios
|
||||
.get(`${resource}/${id}`)
|
||||
.then((response) => {
|
||||
item.value = response.data
|
||||
})
|
||||
}
|
||||
return {
|
||||
items,
|
||||
fetchAll,
|
||||
item,
|
||||
fetchOne
|
||||
}
|
||||
}
|
@ -1,53 +1,17 @@
|
||||
// assets/js/index.js
|
||||
|
||||
import '../styles/app.scss'
|
||||
// CKEditor
|
||||
import '../styles/ckeditor.css'
|
||||
import 'fork-awesome/scss/fork-awesome.scss'
|
||||
|
||||
import { createApp } from 'vue'
|
||||
require('bootstrap')
|
||||
import 'bootswatch/dist/slate/bootstrap.min.css'
|
||||
|
||||
import { createPinia } from 'pinia'
|
||||
$(document).ready(function () {
|
||||
console.log('ready')
|
||||
$('#toggleSidebar').on('click', function () {
|
||||
$('#toggleIcon').toggleClass('fa fa-lg fa-fw fa-caret-square-o-left')
|
||||
$('#toggleIcon').toggleClass('fa fa-lg fa-fw fa-caret-square-o-right')
|
||||
$('#sidebar').toggleClass('active')
|
||||
})
|
||||
})
|
||||
|
||||
//import { QuillEditor } from '@vueup/vue-quill'
|
||||
//import '@vueup/vue-quill/dist/vue-quill.snow.css'
|
||||
//import '@vueup/vue-quill/dist/vue-quill.bubble.css'
|
||||
|
||||
import router from '@/router'
|
||||
import AppLink from '@/components/AppLink'
|
||||
import App from '@/App'
|
||||
|
||||
/* eslint-disable */
|
||||
|
||||
globalThis.__VUE_OPTIONS_API__ = true
|
||||
globalThis.__VUE_PROD_DEVTOOLS__ = true
|
||||
|
||||
// Matomo
|
||||
const _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
|
||||
const g = d.createElement('script')
|
||||
const
|
||||
s = d.getElementsByTagName('script')[0]
|
||||
g.async = true
|
||||
g.src = `${u}matomo.js`
|
||||
s.parentNode.insertBefore(g, s)
|
||||
}())
|
||||
// End Matomo Code
|
||||
/* eslint-enable */
|
||||
|
||||
//globalThis.__VUE_OPTIONS_API__ = true;
|
||||
//globalThis.__VUE_PROD_DEVTOOLS__ = true;
|
||||
|
||||
createApp(App)
|
||||
.component('AppLink', AppLink)
|
||||
// .component('QuillEditor', QuillEditor)
|
||||
.use(createPinia())
|
||||
.use(router)
|
||||
.mount('#app')
|
||||
|
@ -1,86 +0,0 @@
|
||||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
import LoginForm from '@/components/LoginForm'
|
||||
import Quotes from '@/components/quotes'
|
||||
import Pages from '@/components/pages/PagesIndex'
|
||||
import PagesEdit from '@/components/pages/edit'
|
||||
import ProjectsList from '@/components/projects'
|
||||
import ProjectsDetails from '@/components/projects/ProjectDetails'
|
||||
import BlogIndex from '@/components/blog/BlogIndex'
|
||||
import BlogPost from '@/components/blog/BlogPost'
|
||||
import ProfileView from '@/components/users/ProfileView'
|
||||
import TheAbout from '@/components/TheAbout'
|
||||
import NotFound from '@/components/NotFound'
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: '/',
|
||||
name: 'Home',
|
||||
component: Quotes
|
||||
},
|
||||
{
|
||||
path: '/about',
|
||||
name: 'About',
|
||||
component: TheAbout
|
||||
},
|
||||
{
|
||||
path: '/form_login',
|
||||
name: 'LoginForm',
|
||||
component: LoginForm
|
||||
},
|
||||
{
|
||||
path: '/projects',
|
||||
name: 'Projects',
|
||||
component: ProjectsList
|
||||
},
|
||||
{
|
||||
path: '/projects/:id',
|
||||
name: 'ProjectDetails',
|
||||
component: ProjectsDetails
|
||||
},
|
||||
{
|
||||
path: '/blog',
|
||||
name: 'Blog',
|
||||
component: BlogIndex
|
||||
},
|
||||
{
|
||||
path: '/blog/post/:id',
|
||||
name: 'BlogPost',
|
||||
component: BlogPost
|
||||
},
|
||||
{
|
||||
path: '/pages/:slug',
|
||||
name: 'Pages',
|
||||
component: Pages,
|
||||
props: true
|
||||
},
|
||||
{
|
||||
path: '/pages/edit/:slug',
|
||||
component: PagesEdit,
|
||||
meta: { requiredAuth: true }
|
||||
},
|
||||
{
|
||||
path: '/profile/:username?',
|
||||
name: 'Profile',
|
||||
component: ProfileView
|
||||
},
|
||||
{
|
||||
path: '/:pathMatch(.*)*',
|
||||
name: 'NotFound',
|
||||
component: NotFound
|
||||
}
|
||||
]
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes
|
||||
})
|
||||
|
||||
/*
|
||||
router.beforeEach((to) => {
|
||||
if (to.meta.requiredAuth && !window.user) {
|
||||
return { name: 'LoginForm' }
|
||||
}
|
||||
})
|
||||
|
||||
*/
|
||||
export default router
|
@ -1,13 +0,0 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import axios from 'axios';
|
||||
|
||||
export const useQuotesStore = defineStore('QuotesStore', {
|
||||
state: () => ({
|
||||
quotes: []
|
||||
}),
|
||||
actions: {
|
||||
async fill() {
|
||||
this.quotes = (await axios.get('api/quotes')).data;
|
||||
}
|
||||
}
|
||||
});
|
@ -1,8 +0,0 @@
|
||||
import { defineStore } from 'pinia';
|
||||
|
||||
export const useUserStore = defineStore('UsersStore', {
|
||||
state: () => {
|
||||
|
||||
},
|
||||
|
||||
});
|
@ -1,442 +0,0 @@
|
||||
/*
|
||||
jet black (tiefschwarz) - RAL 9005: #0e0e10, rgba(14, 14, 16, 1.0);
|
||||
mango: #FF8040, rgba(255, 130, 67, 1.0);
|
||||
gray: #a1a1a1, rgba(161, 161, 161, 1.0)
|
||||
*/
|
||||
|
||||
/*
|
||||
@media (prefers-color-scheme: light) {}
|
||||
@media (prefers-color-scheme: dark) {}
|
||||
*/
|
||||
|
||||
/* debug */
|
||||
* {
|
||||
//border: 1px solid gray;
|
||||
}
|
||||
|
||||
|
||||
html, body{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: black;
|
||||
background: linear-gradient(90deg, rgba(14,14,16,1) 0%, rgba(255,128,64,1) 35%, rgba(14,14,16,1) 100%);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// the ~ allows you to reference things in node_modules
|
||||
|
||||
|
||||
@import 'quill/dist/quill.core.css';
|
||||
// customize some Bootstrap variables
|
||||
|
||||
|
||||
$bs-primary: #FF8040;
|
||||
$primary: #FF8040;
|
||||
$body-bg: #0E0E10;
|
||||
$body-color: darken(white, 20);
|
||||
$border-primary: #FF8040;
|
||||
$dropdown-dark-bg: black;
|
||||
$dropdown-dark-link-color: $primary;
|
||||
$dropdown-dark-border-color: $primary;
|
||||
$jet-black: #0e0e10;
|
||||
$mango: #FF8040;
|
||||
|
||||
.btn-primary {
|
||||
border-color: $primary;
|
||||
}
|
||||
|
||||
.btn-outline-primary {
|
||||
color: $primary;
|
||||
border-color: $primary;
|
||||
}
|
||||
|
||||
.pages-editor-raw {
|
||||
width: 100%;
|
||||
height: 650px !important;
|
||||
background-color: black;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.ql-container {
|
||||
overflow-y: scroll;
|
||||
height: 650px !important;
|
||||
}
|
||||
|
||||
.no-overflow {
|
||||
overflow-y: visible !important;
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
.ql-syntax {
|
||||
background-color: #222222;
|
||||
border: 1px solid #888;
|
||||
border-left: 3px solid $primary;
|
||||
color: #666;
|
||||
page-break-inside: avoid;
|
||||
font-family: monospace;
|
||||
font-size: 15px;
|
||||
line-height: 1.6;
|
||||
margin-bottom: 1.6em;
|
||||
max-width: 100%;
|
||||
overflow: auto;
|
||||
padding: 1em 1.5em;
|
||||
display: block;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
|
||||
.ql-editor {
|
||||
counter-reset: line;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.ql-editor div:before {
|
||||
counter-increment: line;
|
||||
content: counter(line);
|
||||
display: inline-block;
|
||||
border-right: 1px solid red;
|
||||
padding: 0 .5em;
|
||||
margin-right: .5em;
|
||||
color: #888
|
||||
}
|
||||
|
||||
.ql-syntax pre:before {
|
||||
counter-increment: line;
|
||||
content: counter(line);
|
||||
display: inline-block;
|
||||
border-right: 1px solid #ddd;
|
||||
padding: 2px .5em;
|
||||
margin-right: .5em;
|
||||
color: #888
|
||||
}
|
||||
/*
|
||||
pre span.hljs-tag::before, span.hljs-attr::before {
|
||||
content: "xxx";
|
||||
display: inline-block;
|
||||
}
|
||||
*/
|
||||
|
||||
.wrapper {
|
||||
clear: both;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
|
||||
a:link {
|
||||
text-decoration: none;
|
||||
color: $mango;
|
||||
}
|
||||
a:visited {
|
||||
text-decoration: none;
|
||||
color: $mango;
|
||||
}
|
||||
a:hover {
|
||||
text-decoration: none;
|
||||
color: $mango;
|
||||
}
|
||||
a:active {
|
||||
text-decoration: none;
|
||||
color: $mango;
|
||||
}
|
||||
|
||||
|
||||
body {
|
||||
padding-top: 95px;
|
||||
padding-bottom: 155px;
|
||||
}
|
||||
|
||||
.row.content {
|
||||
height: 350px;
|
||||
}
|
||||
|
||||
.col-center {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.sidenav-left {
|
||||
padding-top: 20px;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
background-color: #f1f1f1;
|
||||
height: 100%;
|
||||
width: auto;
|
||||
margin-left: 3em !important;
|
||||
}
|
||||
|
||||
.sidenav-left ul {
|
||||
list-style-type: none;
|
||||
line-height: 2.1;
|
||||
}
|
||||
.sidenav-right {
|
||||
padding-top: 20px;
|
||||
background-color: #f1f1f1;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 767px) {
|
||||
.sidenav {
|
||||
height: auto;
|
||||
padding: 15px;
|
||||
}
|
||||
.row.content {
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.navbar {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
footer {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.navbar-top {
|
||||
border-bottom-width: 1px;
|
||||
border-bottom-color: $primary;
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.navbar-bottom {
|
||||
border-top-width: 1px;
|
||||
border-top-color: $primary;
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
height: 125px;
|
||||
opacity: 0.9;
|
||||
|
||||
}
|
||||
|
||||
.navbar-nav > li > .dropdown-menu {
|
||||
background-color: black;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
|
||||
.display-wrapper {
|
||||
text-align: left;
|
||||
width: 90%;
|
||||
margin: 0 auto 150px;
|
||||
}
|
||||
|
||||
|
||||
.button-login {
|
||||
margin-top: 25px;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
}
|
||||
|
||||
|
||||
.box {
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: $primary;
|
||||
border-radius: 10px;
|
||||
color: lightgray;
|
||||
background: black;
|
||||
align-content: center;
|
||||
margin: 15px 15px 20px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
/* BlogPosts */
|
||||
|
||||
.main-article {
|
||||
border: 2px solid #efefee;
|
||||
Background: #fff;
|
||||
border-top-left-radius: 6px;
|
||||
border-top-right-radius: 6px;
|
||||
}
|
||||
|
||||
.main-article img {
|
||||
width: 100%;
|
||||
height: 250px;
|
||||
border-top-right-radius: 5px;
|
||||
border-top-left-radius: 5px;
|
||||
border-top: 5px solid lightblue;
|
||||
}
|
||||
|
||||
.blog-container {
|
||||
border: 1px solid $primary;
|
||||
border-radius: 5px;
|
||||
margin-bottom: 25px;
|
||||
background: #0E0E10 url('../images/bg.jpeg') center;
|
||||
}
|
||||
|
||||
.main-article-link, .article-container a {
|
||||
text-decoration: none;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.main-article-link:hover {
|
||||
text-decoration: none;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.article-title {
|
||||
min-width: 300px;
|
||||
|
||||
}
|
||||
|
||||
.article-text {
|
||||
text-align: justify;
|
||||
hyphens: auto;
|
||||
}
|
||||
|
||||
|
||||
@media (max-width: 440px) {
|
||||
.article-title {
|
||||
min-width: 100px;
|
||||
max-width: 245px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.circle {
|
||||
position:fixed;
|
||||
width:500px;
|
||||
height:600px;
|
||||
margin:-300px auto auto -250px;
|
||||
top:50%;
|
||||
left:50%;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
.teaser-image {
|
||||
object-fit: contain;
|
||||
width: 800px;
|
||||
border-radius: 5px;
|
||||
margin: 7px;
|
||||
}
|
||||
|
||||
.project-container {
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
|
||||
.blog-img {
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
border-radius: 5px;
|
||||
border-width: 1px;
|
||||
border-color: $primary;
|
||||
margin: 7px;
|
||||
}
|
||||
|
||||
.article-author-img {
|
||||
height: 50px;
|
||||
border: 1px solid $primary;
|
||||
margin-left: 25px;
|
||||
}
|
||||
|
||||
.blog-details {
|
||||
font-size: .8em;
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.blog-teaser {
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
/* registration form */
|
||||
|
||||
.social_icon span {
|
||||
font-size: 60px;
|
||||
margin-left: 10px;
|
||||
color: $primary;
|
||||
}
|
||||
|
||||
.social_icon span:hover{
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.card{
|
||||
height: 370px;
|
||||
margin-top: 45px;
|
||||
margin-bottom: auto;
|
||||
width: 500px;
|
||||
background-color: #383c4a;
|
||||
border-color: $primary;
|
||||
padding: 15px;
|
||||
background-image: url('../images/bg.jpeg');
|
||||
border-bottom-left-radius: 10px !important;
|
||||
border-bottom-right-radius: 10px !important;
|
||||
}
|
||||
|
||||
|
||||
.card-header {
|
||||
position: absolute;
|
||||
color: black;
|
||||
background-color: $primary;
|
||||
width: 500px;
|
||||
height: 55px;
|
||||
border-top-left-radius: 15px !important;
|
||||
border-top-right-radius: 15px !important;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
}
|
||||
|
||||
.social_icon{
|
||||
/* position: absolute;
|
||||
right: 20px;
|
||||
top: 45px;
|
||||
*/
|
||||
}
|
||||
|
||||
.input-group-prepend span{
|
||||
width: 50px;
|
||||
background-color: $primary;
|
||||
color: black;
|
||||
border:0 !important;
|
||||
height: 40px;
|
||||
margin-bottom: 15px;
|
||||
border-radius: 10px 0 0 10px;
|
||||
}
|
||||
|
||||
|
||||
.form-control {
|
||||
height: 40px;
|
||||
background-image: url('../images/bg.jpeg') !important;
|
||||
color: white;
|
||||
border-color: $primary;
|
||||
}
|
||||
input:focus{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
.submit-button {
|
||||
color: $primary;
|
||||
background-color: black;
|
||||
width: 100px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.submit-button:hover{
|
||||
color: black;
|
||||
background-color: $primary;
|
||||
}
|
||||
|
||||
.links{
|
||||
color: white;
|
||||
}
|
||||
|
||||
.teaser-text {
|
||||
height: 180px;
|
||||
}
|
||||
|
||||
.content-text {
|
||||
height: 400px;
|
||||
}
|
||||
|
||||
.file-input {
|
||||
color: $primary;
|
||||
}
|
@ -18,74 +18,39 @@
|
||||
html, body{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: black;
|
||||
background: linear-gradient(90deg, rgba(14,14,16,1) 0%, rgba(255,128,64,1) 35%, rgba(14,14,16,1) 100%);
|
||||
//background: linear-gradient(90deg, rgba(14,14,16,1) 0%, rgba(255,128,64,1) 35%, rgba(14,14,16,1) 100%);
|
||||
background: #0e0e10;
|
||||
}
|
||||
|
||||
|
||||
// customize some Bootstrap variables
|
||||
$primary: #FF8040;
|
||||
$jet-black: #0e0e10;
|
||||
//@import "bootstrap/scss/bootstrap";
|
||||
|
||||
///
|
||||
|
||||
@import 'quill/dist/quill.core.css';
|
||||
// customize some Bootstrap variables
|
||||
// sidebar
|
||||
|
||||
|
||||
.pages-editor-raw {
|
||||
width: 100%;
|
||||
height: 650px !important;
|
||||
background-color: black;
|
||||
color: white;
|
||||
#sidebar {
|
||||
min-width: 180px;
|
||||
max-width: 180px;
|
||||
display: inline;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
float: left;
|
||||
transition: min-width 0.5s, max-width 0.5s;
|
||||
}
|
||||
|
||||
.ql-container {
|
||||
overflow-y: scroll;
|
||||
height: 650px !important;
|
||||
#sidebar.active {
|
||||
min-width: 60px;
|
||||
max-width: 60px;
|
||||
}
|
||||
|
||||
.no-overflow {
|
||||
overflow-y: visible !important;
|
||||
height: auto !important;
|
||||
#content {
|
||||
}
|
||||
|
||||
.ql-syntax {
|
||||
background-color: #222222;
|
||||
border: 1px solid #888;
|
||||
border-left: 3px solid $primary;
|
||||
color: #666;
|
||||
page-break-inside: avoid;
|
||||
font-family: monospace;
|
||||
font-size: 15px;
|
||||
line-height: 1.6;
|
||||
margin-bottom: 1.6em;
|
||||
max-width: 100%;
|
||||
overflow: auto;
|
||||
padding: 1em 1.5em;
|
||||
display: block;
|
||||
word-wrap: break-word;
|
||||
#sidebar.active .menuText {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
.ql-editor {
|
||||
counter-reset: line;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.ql-editor div:before {
|
||||
counter-increment: line;
|
||||
content: counter(line);
|
||||
display: inline-block;
|
||||
border-right: 1px solid red;
|
||||
padding: 0 .5em;
|
||||
margin-right: .5em;
|
||||
color: #888
|
||||
}
|
||||
|
||||
.ql-syntax pre:before {
|
||||
counter-increment: line;
|
||||
content: counter(line);
|
||||
display: inline-block;
|
||||
border-right: 1px solid #ddd;
|
||||
padding: 2px .5em;
|
||||
margin-right: .5em;
|
||||
color: #888
|
||||
}
|
||||
|
Reference in New Issue
Block a user