diff --git a/package.json b/package.json index 2c700035..5222f9aa 100644 --- a/package.json +++ b/package.json @@ -13,25 +13,33 @@ "lint-fix": "vue-cli-service lint --fix" }, "dependencies": { - "bootstrap": "4.6.0", + "@ckeditor/ckeditor5-build-classic": "31.1.0", + "@ckeditor/ckeditor5-editor-classic": "31.1.0", + "@ckeditor/ckeditor5-vue2": "^3.0.1", + "axios": "^1.7.7", + "bootstrap": "^4.6.0", + "bootstrap-vue": "^2.23.1", "cache-loader": "^4.1.0", "chartist": "0.11.0", "google-maps": "3.2.1", "register-service-worker": "1.7.2", "v-tooltip": "2.0.0-rc.33", "vue": "2.7.14", + "vue-ckeditor2": "^2.1.5", + "vue-loading-overlay": "^6.0.6", "vue-router": "3.0.2", - "vue2-google-maps": "0.10.7" + "vue2-google-maps": "0.10.7", + "vuex": "^3.6.2" }, "devDependencies": { "@vue/cli-plugin-babel": "3.12.1", "@vue/cli-plugin-eslint": "3.12.1", "@vue/cli-plugin-pwa": "3.12.1", "@vue/cli-service": "3.12.1", + "cross-env": "^7.0.3", "sass": "1.56.2", "sass-loader": "10.1.1", - "vue-template-compiler": "2.7.14", - "cross-env": "^7.0.3" + "vue-template-compiler": "2.7.14" }, "browserslist": [ "> 1%", diff --git a/src/layout/ContentFooter.vue b/src/layout/ContentFooter.vue index 66ceb092..e057f8d1 100644 --- a/src/layout/ContentFooter.vue +++ b/src/layout/ContentFooter.vue @@ -1,5 +1,5 @@ + + \ No newline at end of file diff --git a/src/main.js b/src/main.js index 71016a76..bae921c7 100644 --- a/src/main.js +++ b/src/main.js @@ -13,10 +13,19 @@ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. */ +import axios from "axios"; +window.axios = axios; + +window.axios.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest"; +axios.defaults.headers.common['Authorization'] = `Bearer ${localStorage.getItem("token")}`; +window.axios.defaults.withCredentials = true; + import Vue from "vue"; import VueRouter from "vue-router"; import App from "./App.vue"; +import store from './store'; + // LightBootstrap plugin import LightBootstrap from "./light-bootstrap-main"; @@ -28,8 +37,16 @@ import "./registerServiceWorker"; Vue.use(VueRouter); Vue.use(LightBootstrap); +import { BootstrapVue, IconsPlugin } from "bootstrap-vue"; +import "bootstrap/dist/css/bootstrap.css"; +import "bootstrap-vue/dist/bootstrap-vue.css"; + +Vue.use(BootstrapVue); +Vue.use(IconsPlugin); + // configure router const router = new VueRouter({ + mode: 'history', routes, // short for routes: routes linkActiveClass: "nav-item active", scrollBehavior: (to) => { @@ -41,9 +58,31 @@ const router = new VueRouter({ }, }); -/* eslint-disable no-new */ +// router.beforeEach(async (to, from, next) => { +// console.log(to, '123123') +// if (to.matched.some(record => record.meta.requiresAuth)) { +// if (!store.getters.isAuthenticated) { +// try { +// if (store.getters.isAuthenticated) { +// next(); +// } else { +// next({ name: 'Login' }); +// } +// } catch (error) { +// console.error("Error fetching user:", error); +// next({ name: 'Login' }); +// } +// } else { +// next(); +// } +// } else { +// next(); +// } +// }); + new Vue({ el: "#app", + store, render: (h) => h(App), router, }); diff --git a/src/pages/Article/ArticleAdd.vue b/src/pages/Article/ArticleAdd.vue new file mode 100644 index 00000000..a5c35fe2 --- /dev/null +++ b/src/pages/Article/ArticleAdd.vue @@ -0,0 +1,129 @@ + + + + + \ No newline at end of file diff --git a/src/pages/Article/ArticleEdit.vue b/src/pages/Article/ArticleEdit.vue new file mode 100644 index 00000000..b9f6650f --- /dev/null +++ b/src/pages/Article/ArticleEdit.vue @@ -0,0 +1,149 @@ + + + + + \ No newline at end of file diff --git a/src/pages/ArticleList.vue b/src/pages/ArticleList.vue new file mode 100644 index 00000000..7b2b3592 --- /dev/null +++ b/src/pages/ArticleList.vue @@ -0,0 +1,103 @@ + + + \ No newline at end of file diff --git a/src/pages/Category/CategoryAdd.vue b/src/pages/Category/CategoryAdd.vue new file mode 100644 index 00000000..4ee01a20 --- /dev/null +++ b/src/pages/Category/CategoryAdd.vue @@ -0,0 +1,58 @@ + + + + + \ No newline at end of file diff --git a/src/pages/Category/CategoryEdit.vue b/src/pages/Category/CategoryEdit.vue new file mode 100644 index 00000000..89e4c6bc --- /dev/null +++ b/src/pages/Category/CategoryEdit.vue @@ -0,0 +1,74 @@ + + + + + \ No newline at end of file diff --git a/src/pages/CategoryList.vue b/src/pages/CategoryList.vue new file mode 100644 index 00000000..78dab9ec --- /dev/null +++ b/src/pages/CategoryList.vue @@ -0,0 +1,89 @@ + + + + \ No newline at end of file diff --git a/src/pages/Icons.vue b/src/pages/Icons.vue deleted file mode 100644 index d9f46073..00000000 --- a/src/pages/Icons.vue +++ /dev/null @@ -1,632 +0,0 @@ - - - diff --git a/src/pages/Login.vue b/src/pages/Login.vue new file mode 100644 index 00000000..98b22a97 --- /dev/null +++ b/src/pages/Login.vue @@ -0,0 +1,62 @@ + + + diff --git a/src/pages/Maps.vue b/src/pages/Maps.vue deleted file mode 100644 index 25bed76a..00000000 --- a/src/pages/Maps.vue +++ /dev/null @@ -1,77 +0,0 @@ - - - diff --git a/src/pages/TableList.vue b/src/pages/TableList.vue deleted file mode 100644 index ebcf86d5..00000000 --- a/src/pages/TableList.vue +++ /dev/null @@ -1,115 +0,0 @@ - - - diff --git a/src/pages/Typography.vue b/src/pages/Typography.vue deleted file mode 100644 index 442a57c2..00000000 --- a/src/pages/Typography.vue +++ /dev/null @@ -1,98 +0,0 @@ - - - diff --git a/src/pages/Upgrade.vue b/src/pages/Upgrade.vue deleted file mode 100644 index cfc8b71b..00000000 --- a/src/pages/Upgrade.vue +++ /dev/null @@ -1,90 +0,0 @@ - - - diff --git a/src/pages/User/UserAdd.vue b/src/pages/User/UserAdd.vue new file mode 100644 index 00000000..96453407 --- /dev/null +++ b/src/pages/User/UserAdd.vue @@ -0,0 +1,74 @@ + + + + + \ No newline at end of file diff --git a/src/pages/User/UserEdit.vue b/src/pages/User/UserEdit.vue new file mode 100644 index 00000000..e1e8fd60 --- /dev/null +++ b/src/pages/User/UserEdit.vue @@ -0,0 +1,93 @@ + + + + + \ No newline at end of file diff --git a/src/pages/UserList.vue b/src/pages/UserList.vue new file mode 100644 index 00000000..e0442398 --- /dev/null +++ b/src/pages/UserList.vue @@ -0,0 +1,88 @@ + + + diff --git a/src/routes/routes.js b/src/routes/routes.js index e17c4054..b706641a 100644 --- a/src/routes/routes.js +++ b/src/routes/routes.js @@ -1,18 +1,42 @@ +import store from '../store/index'; + import DashboardLayout from '../layout/DashboardLayout.vue' // GeneralViews import NotFound from '../pages/NotFoundPage.vue' +import Login from '../pages/Login.vue' // Admin pages import Overview from 'src/pages/Overview.vue' import UserProfile from 'src/pages/UserProfile.vue' -import TableList from 'src/pages/TableList.vue' -import Typography from 'src/pages/Typography.vue' -import Icons from 'src/pages/Icons.vue' -import Maps from 'src/pages/Maps.vue' -import Notifications from 'src/pages/Notifications.vue' -import Upgrade from 'src/pages/Upgrade.vue' +import UserList from 'src/pages/UserList.vue' +import CategoryList from 'src/pages/CategoryList.vue' +import ArticleList from 'src/pages/ArticleList.vue' + +import UserAdd from '../pages/User/UserAdd.vue' +import UserEdit from '../pages/User/UserEdit.vue' + +import CategoryAdd from '../pages/Category/CategoryAdd.vue' +import CategoryEdit from '../pages/Category/CategoryEdit.vue' + +import ArticleEdit from '../pages/Article/ArticleEdit.vue' +import ArticleAdd from '../pages/Article/ArticleAdd.vue' + +// User +import UserLayout from '../layout/UserLayout.vue'; const routes = [ + { + path: '/', + component: UserLayout, + name: 'UserLayout', + meta: { guest: true } + }, + { + path: '/', + component: UserLayout, + name: 'UserArticle', + meta: { guest: true } + }, { path: '/', component: DashboardLayout, @@ -22,59 +46,83 @@ const routes = [ path: '/admin', component: DashboardLayout, redirect: '/admin/overview', + name: 'dashboard', children: [ + { + path: 'login', + name: 'Login', + component: Login, + meta: { guest: true } + }, { path: 'overview', name: 'Overview', - component: Overview + component: Overview, + meta: { requiresAuth: true }, }, { path: 'user', name: 'User', - component: UserProfile + component: UserProfile, + meta: { requiresAuth: true }, + }, + { + path: 'users', + name: 'UserList', + component: UserList, + meta: { requiresAuth: true }, }, { - path: 'table-list', - name: 'Table List', - component: TableList + path: 'users/edit/:id', + name: 'UsersEdit', + component: UserEdit, + meta: { requiresAuth: true }, }, { - path: 'typography', - name: 'Typography', - component: Typography + path: 'users/add', + name: 'UsersAdd', + component: UserAdd, + meta: { requiresAuth: true }, }, { - path: 'icons', - name: 'Icons', - component: Icons + path: 'articles', + name: 'ArticleList', + component: ArticleList, + meta: { requiresAuth: true }, }, { - path: 'maps', - name: 'Maps', - component: Maps + path: 'articles/edit/:id', + name: 'ArticleEdit', + component: ArticleEdit, + meta: { requiresAuth: true }, }, { - path: 'notifications', - name: 'Notifications', - component: Notifications + path: 'articles/add', + name: 'ArticleAdd', + component: ArticleAdd, + meta: { requiresAuth: true }, }, { - path: 'upgrade', - name: 'Upgrade to PRO', - component: Upgrade + path: 'categories', + name: 'CategoryList', + component: CategoryList, + meta: { requiresAuth: true }, + }, + { + path: 'categories/edit/:id', + name: 'CategoryEdit', + component: CategoryEdit, + meta: { requiresAuth: true }, + }, + { + path: 'categories/add', + name: 'CategoryAdd', + component: CategoryAdd, + meta: { requiresAuth: true }, } ] }, { path: '*', component: NotFound } ] -/** - * Asynchronously load view (Webpack Lazy loading compatible) - * The specified component must be inside the Views folder - * @param {string} name the filename (basename) of the view to load. -function view(name) { - var res= require('../components/Dashboard/Views/' + name + '.vue'); - return res; -};**/ - export default routes diff --git a/src/store/index.js b/src/store/index.js new file mode 100644 index 00000000..233c842e --- /dev/null +++ b/src/store/index.js @@ -0,0 +1,72 @@ +import Vue from "vue"; +import Vuex from "vuex"; +import axios from "axios"; + +Vue.use(Vuex); + +export default new Vuex.Store({ + state: { + user: null, + errors: {}, + }, + mutations: { + setUser(state, user) { + state.user = user; + }, + setErrors(state, errors) { + state.errors = errors; + }, + clearUser(state) { + state.user = null; + }, + clearErrors(state) { + state.errors = {}; + }, + }, + getters: { + isAuthenticated: (state) => state.user, + }, + actions: { + async getUser({ commit }) { + const token = localStorage.getItem("token"); + if (token) { + try { + const res = await axios.get("/api/user", { + headers: { Authorization: `Bearer ${token}` }, + }); + commit("setUser", res.data); + } catch (error) { + console.error("Error fetching user:", error); + } + } + }, + + async loginUser({ commit }, formData ) { + try { + const res = await axios.post(`http://127.0.0.1:8000/api/login`, formData); + if (res.status == 200) { + localStorage.setItem("token", res.data.token); + commit("setUser", res.data.user); + } + } catch (error) { + console.log("Error during authentication:", error); + } + }, + + async logout({ commit }) { + const token = localStorage.getItem("token"); + if (token) { + try { + await axios.post("http://127.0.0.1:8000/api/logout", null, { + headers: { Authorization: `Bearer ${token}` }, + }); + commit("clearUser"); + localStorage.removeItem("token"); + this.$router.push({ name: "Login" }); + } catch (error) { + console.error("Error during logout:", error); + } + } + }, + }, +});