before suspend

This commit is contained in:
tracer 2022-05-23 16:25:55 +02:00
parent 8fab301419
commit aec0b4356a
24 changed files with 1291 additions and 1067 deletions

View File

@ -11,7 +11,8 @@
}, },
"env": { "env": {
"es6": true, "es6": true,
"browser": true "browser": true,
"vue/setup-compiler-macros": true
}, },
"rules": { "rules": {
"semi": [ "semi": [
@ -23,11 +24,22 @@
"error", "error",
"tab" "tab"
], ],
"vue/html-closing-bracket-spacing": ["error", { "vue/html-closing-bracket-spacing": [
"startTag": "never", "error",
"endTag": "never", {
"selfClosingTag": "never" "startTag": "never",
}], "endTag": "never",
"selfClosingTag": "never"
}
],
"vue/component-api-style": [
"error",
[
"script-setup",
"composition"
]
// "script-setup", "composition", "composition-vue2", or "options"
],
"indent": [ "indent": [
"error", "error",
"tab" "tab"

8
TODO Normal file
View File

@ -0,0 +1,8 @@
- use quill vue
- add linenumbering
- add yntax highlighning
- pinia
- harden Api-Platform
- learn tailwind

View File

@ -2,20 +2,18 @@
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<nav-bar <the-navbar
:user="user" @invalidate-user="onUserInvalidate"
@invalidate-user="onInvalidateUser"
/> />
</div> </div>
</div> </div>
<div class="row mt-5 main-content"> <div class="row mt-5 main-content">
<div class="col-xl-3"> <div class="col-xl-3">
<sidebar/> <the-sidebar/>
</div> </div>
<div class="col-xl-9"> <div class="col-xl-9">
<router-view <router-view
:quote="quote"
@user-authenticated="onUserAuthenticated" @user-authenticated="onUserAuthenticated"
/> />
</div> </div>
@ -24,58 +22,41 @@
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<footer-component/> <the-footer/>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script setup>
import axios from 'axios' 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'
import routerView from 'vue-router' if (window.user) {
import NavBar from '@/components/TheNavbar' const { user } = window
import Sidebar from '@/components/TheSidebar'
import FooterComponent from '@/components/TheFooter'
export default {
name: 'App',
components: {
routerView,
Sidebar,
NavBar,
FooterComponent
},
data() {
return {
user: null,
quote: null
}
},
mounted() {
if (window.user) {
this.user = window.user
console.log(this.user)
}
if (window.quote) {
this.quote = window.quote
}
},
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
window.user = null
}
}
} }
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> </script>

View File

@ -17,7 +17,7 @@
</div> </div>
<router-link <router-link
v-else v-else
v-bind="$props" :to="{ name: props.to }"
> >
<span <span
:class="`fa fa-lg fa-fw ${fa}`" :class="`fa fa-lg fa-fw ${fa}`"
@ -29,21 +29,20 @@
</div> </div>
</template> </template>
<script> <script setup>
import { computed } from 'vue'
import { RouterLink } from 'vue-router' import { RouterLink } from 'vue-router'
export default { const props = defineProps({
props: { to: {
...RouterLink.props, type: String,
fa: { required: true
type: String,
default: ''
}
}, },
computed: { fa: {
isExternal() { type: String,
return typeof this.to === 'string' && this.to.startsWith('http') default: ''
}
} }
} })
const isExternal = computed(() => props.to.startsWith('http'))
</script> </script>

View File

@ -2,10 +2,10 @@
<div class="container box"> <div class="container box">
<form @submit.prevent="handleSubmit"> <form @submit.prevent="handleSubmit">
<div <div
v-if="error" v-if="errorMessage"
class="alert alert-danger" class="alert alert-danger mt-2"
> >
{{ error }} {{ errorMessage }}
</div> </div>
<div class="form-group mt-2"> <div class="form-group mt-2">
<label for="exampleInputEmail1">Username</label> <label for="exampleInputEmail1">Username</label>
@ -52,57 +52,44 @@
</div> </div>
</template> </template>
<script> <script setup>
import { ref, defineEmits } from 'vue'
import axios from 'axios' import axios from 'axios'
export default { const username = ref('')
name: 'LoginForm', const password = ref('')
/* const errorMessage = ref('')
props: { const isLoading = ref(false)
user: { const emit = defineEmits(['user-authenticated'])
Type: Object
}
},
*/
data() {
return {
username: '',
password: '',
error: '',
isLoading: false
}
},
methods: {
handleSubmit() {
console.log('handle submit')
this.isLoading = true
this.error = ''
axios const handleSubmit = () => {
.post('/login', { //console.log('handle submit')
username: this.username, isLoading.value = true
password: this.password
})
.then((response) => {
console.log(response.headers)
this.$emit('user-authenticated', response.headers.location) axios
this.username = '' .post('/login', {
this.password = '' username: username.value,
}) password: password.value
.catch((error) => { })
console.log(error.response.data) .then((response) => {
if (error.response.data.error) { //console.log(response.headers)
this.error = error.response.data.error
} else { emit('user-authenticated', response.headers.location)
this.error = 'Unknown error' username.value = ''
} password.value = ''
}) })
.finally(() => { .catch((error) => {
this.isLoading = false 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> </script>

View File

@ -0,0 +1,14 @@
<template>
<div>
Bio:
Symfonycast
</div>
</template>
<script>
export default {
name: 'TheAbout'
}
</script>

View File

@ -14,6 +14,14 @@
alt="Spookie" alt="Spookie"
> >
</router-link> </router-link>
<div>
<router-link
:to="{ name: 'About'}"
class="d-inline-block mx-auto"
>
About Me
</router-link>
</div>
</div> </div>
</div> </div>
<div class="col md-4 text-left"> <div class="col md-4 text-left">

View File

@ -116,37 +116,30 @@
</nav> </nav>
</template> </template>
<script> <script setup>
import axios from 'axios' import axios from 'axios'
import 'vue-navigation-bar/dist/vue-navigation-bar.css' import 'vue-navigation-bar/dist/vue-navigation-bar.css'
export default { const props = defineProps({
name: 'TheNavbar', user: {
components: {}, type: Object,
props: { default() {
user: { return {
type: Object, username: 'tracer'
default: null }
} }
},
data: () => ({}),
computed: {
isLoggedIn() {
return !!this.user
}
},
methods: {
logout() {
console.log('logout')
axios
.get('/logout')
.then(this.$emit('invalidate-user'))
}
} }
} })
</script>
<style> const isLoggedIn = () => (!!this.user)
</style>
/*
const logout = () => ({
axios
.get('/logout')
.then(this.$emit('invalidate-user'))
})
*/
</script>

View File

@ -30,6 +30,11 @@ export default {
url: 'Projects', url: 'Projects',
fa: 'fa-file-code-o', fa: 'fa-file-code-o',
}, },
{
name: 'Blog',
url: 'Blog',
fa: 'fa-file-text-o',
},
{ {
name: 'Gitea', name: 'Gitea',
url: 'https://git.24unix.net', url: 'https://git.24unix.net',

View File

@ -0,0 +1,38 @@
<template>
<div
class="
flex
m-2
gap-2
items-center
shadow-md
w-1/4
flex-grow
rounded
overflow-hidden
"
style="border: 1px solid #eee"
>
<img
src="https://via.placeholder.com/150"
style="background: #cccccc"
width="150"
height="150"
alt="placeholder"
>
<router-link :to="{ name: 'BlogPost', params: { id: post.id } }">
{{ post.title }}<br>
User: {{ post.userId }}
</router-link>
</div>
</template>
<script setup>
console.log('BlogCard')
const props = defineProps({
post: {
type: Object,
required: true
}
})
const post = { ...props.post }
</script>

View File

@ -0,0 +1,34 @@
<template>
<div
class="
flex
m-2
gap-2
items-center
shadow-md
w-1/4
flex-grow
rounded
overflow-hidden
"
style="border: 1px solid #eee"
>
BlogIndex
<BlogCard
v-for="post in blogPosts"
:key="post.id"
:post="post"
/>
</div>
</template>
<script setup>
import useResource from '@/composables/useResource'
//import useUser from '@/composables/useUser'
import BlogCard from '@/components/blog/BlogCard'
const { items: blogPosts, fetchAll } = useResource('https://jsonplaceholder.typicode.com/posts')
fetchAll()
</script>

View File

@ -0,0 +1,51 @@
<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>
import { watch } from 'vue'
import { useRoute } from 'vue-router'
import useResource from '@/composables/useResource'
const route = useRoute()
const { item: blogPost, fetchOne: fetchOneBlog } = useResource('https://jsonplaceholder.typicode.com/posts')
fetchOneBlog(route.params.id)
const { item: user, fetchOne: fetchOneUser } = useResource('https://jsonplaceholder.typicode.com/users')
watch(
() => ({ ...blogPost.value }),
() => fetchOneUser(blogPost.value.userId)
)
</script>

View File

@ -0,0 +1,60 @@
<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>

View File

@ -6,28 +6,57 @@
<tabs-group @tabActivated="tabActivated"> <tabs-group @tabActivated="tabActivated">
<tab-content title="Visual Editor"> <tab-content title="Visual Editor">
<div class="editor mt-2"> <div class="editor mt-2">
<VueEditor <QuillEditor
v-model="page.content" ref="editor"
:editor-options="editorOptions" theme="snow"
:content="JSON.parse(page.content)"
:options="editorOptions"
:disabled="isVueEditorDisabled" :disabled="isVueEditorDisabled"
/> />
<button
class="btn btn-primary mt-3 mb-2"
@click="saveContent"
>
Save
</button>
</div> </div>
</tab-content> </tab-content>
<tab-content title="Raw 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> <div>
<textarea <textarea
v-model="page.content" v-model="page.content"
class="p-fluid pages-editor-raw" class="p-fluid pages-editor-raw"
/> />
</div> </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> </tab-content>
</tabs-group> </tabs-group>
<button
class="btn btn-primary mt-3 mb-2"
@click="saveContent"
>
Save
</button>
</div> </div>
<div v-else> <div v-else>
<i class="fa fa-spinner fa-spin fa-3x fa-fw"/> <i class="fa fa-spinner fa-spin fa-3x fa-fw"/>
@ -39,20 +68,31 @@
import axios from 'axios' import axios from 'axios'
// Basic Use - Covers most scenarios import 'highlight.js/styles/tomorrow-night-blue.css'
// https://github.com/davidroyer/vue2-editor => docs apply for version 3, too import hljs from 'highlight.js'
import { VueEditor } from 'vue3-editor'
import hljs from 'highlightjs' //import Quill from 'quill'
import 'highlightjs/styles/dracula.css' 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 TabsGroup from '@/components/tabs/TabsGroup'
import TabContent from '@/components/tabs/TabContent' import TabContent from '@/components/tabs/TabContent'
Quill
// .register('modules/syntax', syntax, false)
.register('modules/htmlEditButton', htmlEditButton)
hljs.configure({
languages: ['javascript', 'php', 'swift']
})
export default { export default {
name: 'PagesEdit', name: 'PagesEdit',
components: { components: {
VueEditor, QuillEditor,
TabsGroup, TabsGroup,
TabContent TabContent
}, },
@ -62,12 +102,15 @@ export default {
isVueEditorDisabled: false, isVueEditorDisabled: false,
editorOptions: { editorOptions: {
modules: { modules: {
htmlEditButton: {
debug: true
},
syntax: { syntax: {
highlight: (text) => hljs.highlightAuto(text).value highlight: (text) => hljs.highlightAuto(text).value
} }
}, }
theme: 'snow' },
} theme: 'snow'
}), }),
beforeMount() { beforeMount() {
const { slug } = this.$route.params const { slug } = this.$route.params
@ -81,13 +124,24 @@ export default {
}, },
methods: { methods: {
saveContent() { saveContent() {
this.page.content = JSON.stringify(this.$refs.editor.getContents())
axios axios
.put(`/api/pages/${this.page.id}`, this.page) .put(`/api/pages/${this.page.id}`, this.page)
.then(() => { .then(() => {
this.$router.push({ //this.$router.push({
name: 'Pages', // name: 'Pages',
params: { slug: this.page.slug } // 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) { tabActivated(name) {

View File

@ -1,69 +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>
import axios from 'axios'
//import h from 'highlightjs'
//import hi from 'highlightjs-line-numbers.js'
//hi.highlightAll()
//hi.initLineNumbersOnLoad()
export default {
name: 'PagesDisplay',
props: {
slug: {
type: String,
required: true
}
},
data: () => ({
page: null
}),
computed: {
editTarget() {
if (this.page) {
return `/pages/edit/${this.page.slug}`
}
return ''
}
},
beforeMount() {
this.getPagesDetails()
this.$watch(
() => this.slug,
() => {
this.getPagesDetails()
}
)
},
methods: {
async getPagesDetails() {
await axios.get(`/api/pages?slug=${this.slug}`)
.then((response) => {
[this.page] = response.data['hydra:member']
})
}
}
}
</script>

View File

@ -5,6 +5,7 @@
v-for="title in tabTitles" v-for="title in tabTitles"
:key="title" :key="title"
:class="{ selected: title === selectedTitle }" :class="{ selected: title === selectedTitle }"
class="btn"
@click="handleClick(title)" @click="handleClick(title)"
> >
{{ title }} {{ title }}
@ -39,7 +40,9 @@ export default {
} }
</script> </script>
<style> <style lang="scss">
@import "~styles/app.scss";
.tabs { .tabs {
width: auto; width: auto;
margin: 0 auto; margin: 0 auto;
@ -56,15 +59,20 @@ export default {
text-align: center; text-align: center;
padding: 10px 20px; padding: 10px 20px;
margin-right: 10px; margin-right: 10px;
background-color: #ddd; background-color: #2e2e2e;
border-radius: 5px; border-radius: 5px;
color: black; color: #999999;
cursor: pointer; cursor: pointer;
transition: 0.4s all ease-out; transition: 0.4s all ease-out;
} }
.tabs-header li.selected { .tabs-header li.selected {
background-color: #0984e3; background-color: $primary;
color: white; color: $jet-black;
} }
.tabs-header li.selected:hover {
border-color: $body-color;
}
</style> </style>

View File

@ -50,36 +50,38 @@
</div> </div>
</template> </template>
<script> <script setup>
import { ref, reactive } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import axios from 'axios' import axios from 'axios'
export default { const user = reactive(null)
name: 'ProfileView', const isLoading = ref(true)
data: () => ({ const router = useRouter()
user: null, const route = useRoute()
isLoading: true
}),
computed: {
getUserEndpoint() {
if (this.$route.params.username) {
return `/api/users?username=${this.$route.params.username}`
}
return '/api/users?username=tracer'
}
},
mounted() {
axios
.get(this.getUserEndpoint)
.then((response) => {
console.log(response);
[this.user] = response.data['hydra:member']
console.log(this.user) // if there is no param, we go to our own profile, elso to the login
this.isLoading = false
}) if (route.params.username) {
.catch((error) => { console.log('we have the username')
console.log(error) } 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> </script>

View File

@ -0,0 +1,29 @@
import { ref } from 'vue'
import axios from 'axios'
export default function useResource(resource) {
console.log('useBlog')
const items = ref([])
const item = ref(null)
const fetchAll = async () => {
await axios
.get(resource)
.then((response) => {
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
}
}

View File

@ -11,10 +11,11 @@ import 'bootstrap/dist/js/bootstrap'
import { createPinia } from 'pinia' import { createPinia } from 'pinia'
import VueHighLightJS from 'vue3-highlightjs' //import { QuillEditor } from '@vueup/vue-quill'
import 'vue3-highlightjs/styles/dracula.css' //import '@vueup/vue-quill/dist/vue-quill.snow.css'
//import '@vueup/vue-quill/dist/vue-quill.bubble.css'
import Router from '@/router' import router from '@/router'
import AppLink from '@/components/AppLink' import AppLink from '@/components/AppLink'
import App from '@/App' import App from '@/App'
@ -48,7 +49,7 @@ _paq.push(['enableLinkTracking']);
createApp(App) createApp(App)
.component('AppLink', AppLink) .component('AppLink', AppLink)
// .component('QuillEditor', QuillEditor)
.use(createPinia()) .use(createPinia())
.use(VueHighLightJS) .use(router)
.use(Router)
.mount('#app') .mount('#app')

View File

@ -1,11 +1,14 @@
import { createRouter, createWebHistory } from 'vue-router' import { createRouter, createWebHistory } from 'vue-router'
import LoginForm from '@/components/LoginForm' import LoginForm from '@/components/LoginForm'
import Quotes from '@/components/quotes' import Quotes from '@/components/quotes'
import Pages from '@/components/pages' import Pages from '@/components/pages/PagesIndex'
import PagesEdit from '@/components/pages/edit' import PagesEdit from '@/components/pages/edit'
import ProjectsList from '@/components/projects' import ProjectsList from '@/components/projects'
import ProjectsDetails from '@/components/projects/ProjectDetails' 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 ProfileView from '@/components/users/ProfileView'
import TheAbout from '@/components/TheAbout'
import NotFound from '@/components/NotFound' import NotFound from '@/components/NotFound'
const routes = [ const routes = [
@ -14,6 +17,11 @@ const routes = [
name: 'Home', name: 'Home',
component: Quotes component: Quotes
}, },
{
path: '/about',
name: 'About',
component: TheAbout
},
{ {
path: '/form_login', path: '/form_login',
name: 'LoginForm', name: 'LoginForm',
@ -29,6 +37,16 @@ const routes = [
name: 'ProjectDetails', name: 'ProjectDetails',
component: ProjectsDetails component: ProjectsDetails
}, },
{
path: '/blog',
name: 'Blog',
component: BlogIndex
},
{
path: '/blog/post/:id',
name: 'BlogPost',
component: BlogPost
},
{ {
path: '/pages/:slug', path: '/pages/:slug',
name: 'Pages', name: 'Pages',
@ -57,10 +75,12 @@ const router = createRouter({
routes routes
}) })
/* eslint-disable */ /*
router.beforeEach((to) => { router.beforeEach((to) => {
if (to.meta.requiredAuth && !window.user) { if (to.meta.requiredAuth && !window.user) {
return { name: 'LoginForm' } return { name: 'LoginForm' }
} }
}) })
*/
export default router export default router

View File

@ -68,6 +68,11 @@ $mango: #FF8040;
height: 650px !important; height: 650px !important;
} }
.no-overflow {
overflow-y: visible !important;
height: auto !important;
}
.ql-syntax { .ql-syntax {
background-color: #222222; background-color: #222222;
border: 1px solid #888; border: 1px solid #888;
@ -85,11 +90,37 @@ $mango: #FF8040;
word-wrap: break-word; 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 { pre span.hljs-tag::before, span.hljs-attr::before {
content: "xxx"; content: "xxx";
display: inline-block; display: inline-block;
} }
*/
.wrapper { .wrapper {
clear: both; clear: both;

View File

@ -26,28 +26,26 @@
}, },
"dependencies": { "dependencies": {
"@fortawesome/fontawesome-free": "^6.1.1", "@fortawesome/fontawesome-free": "^6.1.1",
"@vueup/vue-quill": "^1.0.0-beta.8",
"axios": "^0.27.1", "axios": "^0.27.1",
"bootsdark": "^1.0.16", "bootsdark": "^1.0.16",
"bootstrap": "^5.1.3", "bootstrap": "^5.1.3",
"ckeditor": "^4.12.1", "eslint": "^8.15.0",
"ckeditor4": "^4.18.0",
"eslint": "^8.14.0",
"eslint-config-airbnb-base": "^15.0.0", "eslint-config-airbnb-base": "^15.0.0",
"eslint-plugin-import": "^2.26.0", "eslint-plugin-import": "^2.26.0",
"eslint-plugin-vue": "^8.7.1", "eslint-plugin-vue": "^8.7.1",
"fork-awesome": "^1.2.0", "fork-awesome": "^1.2.0",
"highlightjs": "^9.16.2", "highlight.js": "^11.5.1",
"highlightjs-line-numbers.js": "^2.8.0",
"husky": "^7.0.4", "husky": "^7.0.4",
"less": "^4.1.2", "less": "^4.1.2",
"marked": "^4.0.15", "marked": "^4.0.15",
"pinia": "^2.0.14", "pinia": "^2.0.14",
"popper.js": "^1.16.1", "popper.js": "^1.16.1",
"primevue": "^3.12.6", "primevue": "^3.12.6",
"quill": "^1.3.7",
"quill-html-edit-button": "^2.2.12",
"vue": "3", "vue": "3",
"vue-navigation-bar": "^5.0.0", "vue-navigation-bar": "^5.0.0",
"vue-router": "4", "vue-router": "4"
"vue3-editor": "^0.1.1",
"vue3-highlightjs": "^1.0.5"
} }
} }

View File

@ -35,7 +35,7 @@ Encore
styles: path.resolve(__dirname, 'assets', 'styles') styles: path.resolve(__dirname, 'assets', 'styles')
}) })
.enableSassLoader() .enableSassLoader()
.enableVueLoader() .enableVueLoader(() => {}, { runtimeCompilerBuild: false })
.enableTypeScriptLoader() .enableTypeScriptLoader()
.autoProvidejQuery() .autoProvidejQuery()

1512
yarn.lock

File diff suppressed because it is too large Load Diff