Commit cd757087 authored by Dhevan's avatar Dhevan

nyicil auth

parent 9f88d3f2
...@@ -9,12 +9,14 @@ ...@@ -9,12 +9,14 @@
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"@popperjs/core": "2.11.8", "@popperjs/core": "2.11.8",
"axios": "^1.6.7",
"bootstrap": "5.3.3", "bootstrap": "5.3.3",
"chart.js": "4.4.1", "chart.js": "4.4.1",
"core-js": "3.36.0", "core-js": "3.36.0",
"dropzone": "6.0.0-beta.2", "dropzone": "6.0.0-beta.2",
"pinia": "^2.1.7", "pinia": "^2.1.7",
"quill": "1.3.7", "quill": "1.3.7",
"sweetalert2": "^11.10.6",
"vue": "^3.4.15", "vue": "^3.4.15",
"vue-count-to": "1.0.13", "vue-count-to": "1.0.13",
"vue-flatpickr-component": "11.0.4", "vue-flatpickr-component": "11.0.4",
...@@ -1231,8 +1233,7 @@ ...@@ -1231,8 +1233,7 @@
"node_modules/asynckit": { "node_modules/asynckit": {
"version": "0.4.0", "version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
"dev": true
}, },
"node_modules/at-least-node": { "node_modules/at-least-node": {
"version": "1.0.0", "version": "1.0.0",
...@@ -1262,7 +1263,6 @@ ...@@ -1262,7 +1263,6 @@
"version": "1.6.7", "version": "1.6.7",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz",
"integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==",
"dev": true,
"dependencies": { "dependencies": {
"follow-redirects": "^1.15.4", "follow-redirects": "^1.15.4",
"form-data": "^4.0.0", "form-data": "^4.0.0",
...@@ -1273,7 +1273,6 @@ ...@@ -1273,7 +1273,6 @@
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"dev": true,
"dependencies": { "dependencies": {
"asynckit": "^0.4.0", "asynckit": "^0.4.0",
"combined-stream": "^1.0.8", "combined-stream": "^1.0.8",
...@@ -1286,8 +1285,7 @@ ...@@ -1286,8 +1285,7 @@
"node_modules/axios/node_modules/proxy-from-env": { "node_modules/axios/node_modules/proxy-from-env": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
"dev": true
}, },
"node_modules/balanced-match": { "node_modules/balanced-match": {
"version": "1.0.2", "version": "1.0.2",
...@@ -1664,7 +1662,6 @@ ...@@ -1664,7 +1662,6 @@
"version": "1.0.8", "version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"dev": true,
"dependencies": { "dependencies": {
"delayed-stream": "~1.0.0" "delayed-stream": "~1.0.0"
}, },
...@@ -1931,7 +1928,6 @@ ...@@ -1931,7 +1928,6 @@
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"dev": true,
"engines": { "engines": {
"node": ">=0.4.0" "node": ">=0.4.0"
} }
...@@ -2262,7 +2258,6 @@ ...@@ -2262,7 +2258,6 @@
"version": "1.15.5", "version": "1.15.5",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz",
"integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==",
"dev": true,
"funding": [ "funding": [
{ {
"type": "individual", "type": "individual",
...@@ -3238,7 +3233,6 @@ ...@@ -3238,7 +3233,6 @@
"version": "1.52.0", "version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"dev": true,
"engines": { "engines": {
"node": ">= 0.6" "node": ">= 0.6"
} }
...@@ -3247,7 +3241,6 @@ ...@@ -3247,7 +3241,6 @@
"version": "2.1.35", "version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"dev": true,
"dependencies": { "dependencies": {
"mime-db": "1.52.0" "mime-db": "1.52.0"
}, },
...@@ -4367,6 +4360,15 @@ ...@@ -4367,6 +4360,15 @@
"url": "https://github.com/chalk/supports-color?sponsor=1" "url": "https://github.com/chalk/supports-color?sponsor=1"
} }
}, },
"node_modules/sweetalert2": {
"version": "11.10.6",
"resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.10.6.tgz",
"integrity": "sha512-CINZPLZXZRSZqSOE7H7j1F7X8e8O1kLOiXPmtJn1DYxvXsKBr3d16d90+IcwTTs7dJww20h8r8QIxIwsLGX+6A==",
"funding": {
"type": "individual",
"url": "https://github.com/sponsors/limonte"
}
},
"node_modules/symbol-tree": { "node_modules/symbol-tree": {
"version": "3.2.4", "version": "3.2.4",
"resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
......
...@@ -13,12 +13,14 @@ ...@@ -13,12 +13,14 @@
}, },
"dependencies": { "dependencies": {
"@popperjs/core": "2.11.8", "@popperjs/core": "2.11.8",
"axios": "^1.6.7",
"bootstrap": "5.3.3", "bootstrap": "5.3.3",
"chart.js": "4.4.1", "chart.js": "4.4.1",
"core-js": "3.36.0", "core-js": "3.36.0",
"dropzone": "6.0.0-beta.2", "dropzone": "6.0.0-beta.2",
"pinia": "^2.1.7", "pinia": "^2.1.7",
"quill": "1.3.7", "quill": "1.3.7",
"sweetalert2": "^11.10.6",
"vue": "^3.4.15", "vue": "^3.4.15",
"vue-count-to": "1.0.13", "vue-count-to": "1.0.13",
"vue-flatpickr-component": "11.0.4", "vue-flatpickr-component": "11.0.4",
......
...@@ -14,23 +14,23 @@ Coded by www.creative-tim.com ...@@ -14,23 +14,23 @@ Coded by www.creative-tim.com
--> -->
<script setup> <script setup>
import { computed } from "vue"; import { computed } from "vue";
import { useStore } from "vuex";
import Sidenav from "./components/Sidenav"; import Sidenav from "./components/Sidenav";
import Configurator from "@/components/Configurator.vue"; import Configurator from "@/components/Configurator.vue";
import Navbar from "@/components/Navbars/Navbar.vue"; import Navbar from "@/components/Navbars/Navbar.vue";
import AppFooter from "@/components/Footer.vue"; import AppFooter from "@/components/Footer.vue";
import { useMenuStore } from "./store/menu";
const store = useStore(); const store = useMenuStore();
const isNavFixed = computed(() => store.state.isNavFixed); const isNavFixed = computed(() => store.isNavFixed);
const darkMode = computed(() => store.state.darkMode); const darkMode = computed(() => store.darkMode);
const isAbsolute = computed(() => store.state.isAbsolute); const isAbsolute = computed(() => store.isAbsolute);
const showSidenav = computed(() => store.state.showSidenav); const showSidenav = computed(() => store.showSidenav);
const layout = computed(() => store.state.layout); const layout = computed(() => store.layout);
const showNavbar = computed(() => store.state.showNavbar); const showNavbar = computed(() => store.showNavbar);
const showFooter = computed(() => store.state.showFooter); const showFooter = computed(() => store.showFooter);
const showConfig = computed(() => store.state.showConfig); const showConfig = computed(() => store.showConfig);
const hideConfigButton = computed(() => store.state.hideConfigButton); const hideConfigButton = computed(() => store.hideConfigButton);
const toggleConfigurator = () => store.commit("toggleConfigurator"); const toggleConfigurator = () => store.toggleConfigurator;
const navClasses = computed(() => { const navClasses = computed(() => {
return { return {
......
import axios from "axios";
const baseUrl = "http://localhost:4002/api";
const request = axios.create({
baseURL: baseUrl,
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
});
const errorHandler = (error) => {
if (!error.response) {
// store.dispatch("alert/showMessage", {
// type: "error",
// message: "Tidak bisa terkoneksi dengan API",
// });
throw new Error("Failed to connect API");
}
if (error.response.status == 422) {
throw error;
}
const errorMessage = error.response.data.error;
// if (error.response.status === 401) {
// localStorage.removeItem('token')
// localStorage.removeItem('user')
// window.location = '/auth'
// }
// const alertMessage =
// error.response.data.code === "VALIDATION_ERROR"
// ? error.response.data.data[0].msg
// : errorMessage;
// store.dispatch("alert/showMessage", {
// type: "error",
// message: alertMessage,
// });
throw new Error(errorMessage);
};
const successHandler = (response) => {
return response;
};
const requestHandler = (request) => {
if (localStorage.getItem("token") != null) {
request.headers.Authorization = `Bearer ${localStorage.getItem("token")}`;
}
return request;
};
request.interceptors.request.use((request) => requestHandler(request));
request.interceptors.response.use(
(response) => successHandler(response),
(error) => errorHandler(error)
);
export default request;
import RestClient from "./restClient.js";
export class UserApi {
static async login(username, password) {
const response = await RestClient.post("/user/login", {
username,
password,
});
return response.data;
}
static async me() {
const response = await RestClient.get("/user/me");
return response.data;
}
}
<script setup> <script setup>
import { computed } from "vue"; import { computed } from "vue";
import { useStore } from "vuex"; import { useMenuStore } from "@/store/menu";
const store = useStore(); const store = useMenuStore();
const isRTL = computed(() => store.state.isRTL); const isRTL = computed(() => store.isRTL);
const isNavFixed = computed(() => store.state.isNavFixed); const isNavFixed = computed(() => store.isNavFixed);
defineProps({ defineProps({
currentPage: { currentPage: {
......
<script setup> <script setup>
import { computed } from "vue"; import { computed } from "vue";
import { useStore } from "vuex"; import { useMenuStore } from "@/store/menu";
import ArgonAvatar from "@/components/ArgonAvatar.vue"; import ArgonAvatar from "@/components/ArgonAvatar.vue";
import img1 from "../../assets/img/logos/mastercard.png"; import img1 from "../../assets/img/logos/mastercard.png";
const store = useStore(); const store = useMenuStore();
const isRTL = computed(() => store.state.isRTL); const isRTL = computed(() => store.isRTL);
defineProps({ defineProps({
card: { card: {
type: Object, type: Object,
......
<script setup> <script setup>
import { computed } from "vue"; import { computed } from "vue";
import { useStore } from "vuex"; import { useMenuStore } from "@/store/menu";
import { activateDarkMode, deactivateDarkMode } from "@/assets/js/dark-mode"; import { activateDarkMode, deactivateDarkMode } from "@/assets/js/dark-mode";
const store = useStore(); const store = useMenuStore();
// state // state
const isRTL = computed(() => store.state.isRTL); const isRTL = computed(() => store.isRTL);
const isNavFixed = computed(() => store.state.isNavFixed); const isNavFixed = computed(() => store.isNavFixed);
const sidebarType = computed(() => store.state.sidebarType); const sidebarType = computed(() => store.sidebarType);
const toggleConfigurator = () => store.commit("toggleConfigurator"); const toggleConfigurator = () => store.toggleConfigurator();
// mutations // mutations
const navbarFixed = () => store.commit("navbarFixed"); const navbarFixed = () => store.navbarFixed;
const setSidebarType = (type) => store.commit("sidebarType", type); const setSidebarType = (type) => store.sidebarType(type);
const sidebarColor = (color = "success") => { const sidebarColor = (color = "success") => {
document.querySelector("#sidenav-main").setAttribute("data-color", color); document.querySelector("#sidenav-main").setAttribute("data-color", color);
}; };
const darkMode = () => { const darkMode = () => {
if (store.state.darkMode) { if (store.darkMode) {
store.state.darkMode = false; store.darkMode = false;
setSidebarType("bg-white"); setSidebarType("bg-white");
deactivateDarkMode(); deactivateDarkMode();
return; return;
} else { } else {
store.state.darkMode = true; store.darkMode = true;
setSidebarType("bg-default"); setSidebarType("bg-default");
activateDarkMode(); activateDarkMode();
} }
...@@ -156,7 +156,7 @@ const darkMode = () => { ...@@ -156,7 +156,7 @@ const darkMode = () => {
<input <input
class="form-check-input mt-1 ms-auto" class="form-check-input mt-1 ms-auto"
type="checkbox" type="checkbox"
:checked="store.state.darkMode" :checked="store.darkMode"
@click="darkMode" @click="darkMode"
/> />
</div> </div>
......
<script setup> <script setup>
import { useStore } from "vuex"; import { useMenuStore } from "@/store/menu";
const store = useStore(); const store = useMenuStore();
</script> </script>
<template> <template>
<footer class="py-3 footer"> <footer class="py-3 footer">
...@@ -9,7 +9,7 @@ const store = useStore(); ...@@ -9,7 +9,7 @@ const store = useStore();
<div class="mb-4 col-lg-6 mb-lg-0"> <div class="mb-4 col-lg-6 mb-lg-0">
<div <div
class="text-sm text-center copyright text-muted" class="text-sm text-center copyright text-muted"
:class="store.state.isRTL ? 'text-lg-end' : 'text-lg-start'" :class="store.isRTL ? 'text-lg-end' : 'text-lg-start'"
> >
© ©
{{ new Date().getFullYear() }}, made with {{ new Date().getFullYear() }}, made with
......
<script setup> <script setup>
import { computed, ref } from "vue"; import { computed, ref } from "vue";
import { useStore } from "vuex"; import { useMenuStore } from "@/store/menu";
import { useRoute } from "vue-router"; import { useRoute } from "vue-router";
import Breadcrumbs from "../Breadcrumbs.vue"; import Breadcrumbs from "../Breadcrumbs.vue";
const showMenu = ref(false); const showMenu = ref(false);
const store = useStore(); const store = useMenuStore();
const isRTL = computed(() => store.state.isRTL); const isRTL = computed(() => store.isRTL);
const route = useRoute(); const route = useRoute();
...@@ -18,8 +18,8 @@ const currentDirectory = computed(() => { ...@@ -18,8 +18,8 @@ const currentDirectory = computed(() => {
return dir.charAt(0).toUpperCase() + dir.slice(1); return dir.charAt(0).toUpperCase() + dir.slice(1);
}); });
const minimizeSidebar = () => store.commit("sidebarMinimize"); const minimizeSidebar = () => store.sidebarMinimize();
const toggleConfigurator = () => store.commit("toggleConfigurator"); const toggleConfigurator = () => store.toggleConfigurator();
const closeMenu = () => { const closeMenu = () => {
setTimeout(() => { setTimeout(() => {
...@@ -62,20 +62,8 @@ const closeMenu = () => { ...@@ -62,20 +62,8 @@ const closeMenu = () => {
</div> </div>
</div> </div>
<ul class="navbar-nav justify-content-end"> <ul class="navbar-nav justify-content-end">
<li class="nav-item d-flex align-items-center">
<router-link
:to="{ name: 'Signin' }"
class="px-0 nav-link font-weight-bold text-white"
target="_blank"
>
<i class="fa fa-user" :class="isRTL ? 'ms-sm-2' : 'me-sm-2'"></i>
<span v-if="isRTL" class="d-sm-inline d-none">يسجل دخول</span>
<span v-else class="d-sm-inline d-none">Sign In</span>
</router-link>
</li>
<li class="nav-item d-xl-none ps-3 d-flex align-items-center"> <li class="nav-item d-xl-none ps-3 d-flex align-items-center">
<a <a
href="#"
@click="minimizeSidebar" @click="minimizeSidebar"
class="p-0 nav-link text-white" class="p-0 nav-link text-white"
id="iconNavbarSidenav" id="iconNavbarSidenav"
......
<script setup> <script setup>
import { computed } from "vue"; import { computed } from "vue";
import { useStore } from "vuex"; import { useMenuStore } from "@/store/menu";
const store = useStore(); const store = useMenuStore();
const isRTL = computed(() => store.state.isRTL); const isRTL = computed(() => store.isRTL);
const layout = computed(() => store.state.layout); const layout = computed(() => store.layout);
defineProps({ defineProps({
card: { card: {
type: Object, type: Object,
......
<script setup> <script setup>
import { computed } from "vue"; import { computed } from "vue";
import { useStore } from "vuex"; import { useMenuStore } from "@/store/menu";
const store = useStore(); const store = useMenuStore();
const isRTL = computed(() => store.state.isRTL); const isRTL = computed(() => store.isRTL);
const sidebarMinimize = () => store.commit("sidebarMinimize"); const sidebarMinimize = () => store.sidebarMinimize();
const minimizeSidebar = () => { const minimizeSidebar = () => {
if (window.innerWidth < 1200) { if (window.innerWidth < 1200) {
......
<script setup> <script setup>
import { computed } from "vue"; import { computed } from "vue";
import { useRoute } from "vue-router"; import { useRoute } from "vue-router";
import { useStore } from "vuex"; import { useMenuStore } from "@/store/menu";
import SidenavItem from "./SidenavItem.vue"; import SidenavItem from "./SidenavItem.vue";
import SidenavParent from "./SidenavParent.vue"; import SidenavParent from "./SidenavParent.vue";
import SidenavCard from "./SidenavCard.vue";
const store = useStore(); const store = useMenuStore();
const isRTL = computed(() => store.state.isRTL); const isRTL = computed(() => store.isRTL);
const getRoute = () => { const getRoute = () => {
const route = useRoute(); const route = useRoute();
...@@ -24,8 +23,19 @@ const getRoute = () => { ...@@ -24,8 +23,19 @@ const getRoute = () => {
<ul class="navbar-nav"> <ul class="navbar-nav">
<li class="nav-item"> <li class="nav-item">
<sidenav-item <sidenav-item
to="/dashboard-default" to="/profile"
:class="getRoute() === 'dashboard-default' ? 'active' : ''" :class="getRoute() === 'profile' ? 'active' : ''"
:navText="isRTL ? 'حساب تعريفي' : 'Profile'"
>
<template v-slot:icon>
<i class="ni ni-user text-dark text-sm opacity-10"></i>
</template>
</sidenav-item>
</li>
<li class="nav-item">
<sidenav-item
to="/dashboard"
:class="getRoute() === 'dashboard' ? 'active' : ''"
:navText="isRTL ? 'لوحة القيادة' : 'Dashboard'" :navText="isRTL ? 'لوحة القيادة' : 'Dashboard'"
> >
<template v-slot:icon> <template v-slot:icon>
...@@ -41,9 +51,7 @@ const getRoute = () => { ...@@ -41,9 +51,7 @@ const getRoute = () => {
:navText="isRTL ? 'الجداول' : 'Tables'" :navText="isRTL ? 'الجداول' : 'Tables'"
> >
<template v-slot:icon> <template v-slot:icon>
<i <i class="ni ni-laptop text-warning text-sm opacity-10"></i>
class="ni ni-laptop text-warning text-sm opacity-10"
></i>
</template> </template>
</sidenav-item> </sidenav-item>
</li> </li>
...@@ -59,61 +67,6 @@ const getRoute = () => { ...@@ -59,61 +67,6 @@ const getRoute = () => {
</template> </template>
</sidenav-item> </sidenav-item>
</li> </li>
<li class="mt-3 nav-item">
<h6
v-if="isRTL"
class="text-xs ps-4 text-uppercase font-weight-bolder opacity-6"
:class="isRTL ? 'me-4' : 'ms-2'"
>
صفحات المرافق
</h6>
<h6
v-else
class="text-xs ps-4 text-uppercase font-weight-bolder opacity-6"
:class="isRTL ? 'me-4' : 'ms-2'"
>
ACCOUNT PAGES
</h6>
</li>
<li class="nav-item">
<sidenav-item
to="/profile"
:class="getRoute() === 'profile' ? 'active' : ''"
:navText="isRTL ? 'حساب تعريفي' : 'Profile'"
>
<template v-slot:icon>
<i class="ni ni-user text-dark text-sm opacity-10"></i>
</template>
</sidenav-item>
</li>
<li class="nav-item">
<sidenav-item
to="/signin"
:class="getRoute() === 'signin' ? 'active' : ''"
:navText="isRTL ? 'تسجيل الدخول' : 'Sign In'"
>
<template v-slot:icon>
<i class="ni ni-user text-danger text-sm opacity-10"></i>
</template>
</sidenav-item>
</li>
<li class="nav-item">
<sidenav-parent
identifier="submenu"
:class="getRoute() === 'signup' ? 'active' : ''"
:navText="isRTL ? 'اشتراك' : 'Sign Up'"
>
<template v-slot:icon>
<i class="ni ni-window-expand-bottom-right text-info text-sm opacity-10"></i>
</template>
</sidenav-parent>
</li>
</ul> </ul>
</div> </div>
</template> </template>
...@@ -2,12 +2,12 @@ ...@@ -2,12 +2,12 @@
import SidenavItem from "./SidenavItem.vue"; import SidenavItem from "./SidenavItem.vue";
import { computed } from "vue"; import { computed } from "vue";
import { useStore } from "vuex"; import { useMenuStore } from "@/store/menu";
import { useRoute } from "vue-router"; import { useRoute } from "vue-router";
const store = useStore(); const store = useMenuStore();
const isRTL = computed(() => store.state.isRTL); const isRTL = computed(() => store.isRTL);
const sidebarMinimize = () => store.commit("sidebarMinimize"); const sidebarMinimize = () => store.sidebarMinimize();
const minimizeSidebar = () => { const minimizeSidebar = () => {
if (window.innerWidth < 1200) { if (window.innerWidth < 1200) {
......
<script setup> <script setup>
import { computed } from "vue"; import { computed } from "vue";
import { useStore } from "vuex"; import { useMenuStore } from "@/store/menu";
import SidenavList from "./SidenavList.vue"; import SidenavList from "./SidenavList.vue";
import logo from "@/assets/img/logo-ct-dark.png"; import logo from "@/assets/img/logo-ct-dark.png";
import logoWhite from "@/assets/img/logo-ct.png"; import logoWhite from "@/assets/img/logo-ct.png";
const store = useStore(); const store = useMenuStore();
const isRTL = computed(() => store.state.isRTL); const isRTL = computed(() => store.isRTL);
const layout = computed(() => store.state.layout); const layout = computed(() => store.layout);
const sidebarType = computed(() => store.state.sidebarType); const sidebarType = computed(() => store.sidebarType);
const darkMode = computed(() => store.state.darkMode); const darkMode = computed(() => store.darkMode);
</script> </script>
<template> <template>
<div <div
......
import { createApp } from "vue"; import { createApp } from "vue";
import { createPinia } from "pinia";
import App from "./App.vue"; import App from "./App.vue";
import store from "./store";
import router from "./router"; import router from "./router";
import tools from "./plugins/tools";
import "./assets/css/nucleo-icons.css"; import "./assets/css/nucleo-icons.css";
import "./assets/css/nucleo-svg.css"; import "./assets/css/nucleo-svg.css";
import ArgonDashboard from "./argon-dashboard"; import ArgonDashboard from "./argon-dashboard";
const appInstance = createApp(App); const pinia = createPinia();
appInstance.use(store); const app = createApp(App);
appInstance.use(router);
appInstance.use(ArgonDashboard); app.use(pinia);
appInstance.mount("#app"); app.use(router);
app.use(tools);
app.use(ArgonDashboard);
app.mount("#app");
import axios from 'axios'
import API from '../api/index'
export default {
install: (app) => {
const baseUrl: string = 'http://localhost:4002'
const request = axios.create({
baseURL: baseUrl,
headers: {
'Content-Type': 'application/json',
Accept: 'application/json'
}
})
const errorHandler = (error) => {
if (!error.response) {
// store.dispatch("alert/showMessage", {
// type: "error",
// message: "Tidak bisa terkoneksi dengan API",
// });
throw new Error('Failed to connect API')
}
if (error.response.status == 422) {
throw error
}
const errorMessage = error.response.data.error
// if (error.response.status === 401) {
// localStorage.removeItem('token')
// localStorage.removeItem('user')
// window.location = '/auth'
// }
// const alertMessage =
// error.response.data.code === "VALIDATION_ERROR"
// ? error.response.data.data[0].msg
// : errorMessage;
// store.dispatch("alert/showMessage", {
// type: "error",
// message: alertMessage,
// });
throw new Error(errorMessage)
}
const successHandler = (response) => {
return response
}
const requestHandler = (request) => {
if (localStorage.getItem('token') != null) {
request.headers.Authorization = `Bearer ${localStorage.getItem('token')}`
}
return request
}
request.interceptors.request.use((request) => requestHandler(request))
request.interceptors.response.use(
(response) => successHandler(response),
(error) => errorHandler(error)
)
app.config.globalProperties.$api = new API(request)
app.provide('api', new API(request))
}
}
import Swal from "sweetalert2";
export default {
install: (app) => {
// Swal
const showLoading = () => {
Swal.fire({
allowOutsideClick: false,
didOpen: () => {
Swal.showLoading();
},
});
};
const hideLoading = () => {
Swal.close();
};
app.provide("tools", {
Swal,
showLoading,
hideLoading,
});
},
};
...@@ -2,18 +2,17 @@ import { createRouter, createWebHashHistory } from "vue-router"; ...@@ -2,18 +2,17 @@ import { createRouter, createWebHashHistory } from "vue-router";
import Dashboard from "../views/Dashboard.vue"; import Dashboard from "../views/Dashboard.vue";
import Tables from "../views/Tables.vue"; import Tables from "../views/Tables.vue";
import Billing from "../views/Billing.vue"; import Billing from "../views/Billing.vue";
import Profile from "../views/Profile.vue"; import { userRoutes } from "./user.js";
import Signup from "../views/Signup.vue";
import Signin from "../views/Signin.vue";
const routes = [ const routes = [
...userRoutes,
{ {
path: "/", path: "/",
name: "/", name: "/",
redirect: "/dashboard-default", redirect: "/dashboard",
}, },
{ {
path: "/dashboard-default", path: "/dashboard",
name: "Dashboard", name: "Dashboard",
component: Dashboard, component: Dashboard,
}, },
...@@ -27,21 +26,6 @@ const routes = [ ...@@ -27,21 +26,6 @@ const routes = [
name: "Billing", name: "Billing",
component: Billing, component: Billing,
}, },
{
path: "/profile",
name: "Profile",
component: Profile,
},
{
path: "/signin",
name: "Signin",
component: Signin,
},
{
path: "/signup",
name: "Signup",
component: Signup,
},
]; ];
const router = createRouter({ const router = createRouter({
......
import UserLogin from "./../views/user/UserLogin.vue";
import UserSignup from "./../views/user/UserSignup.vue";
import UserProfile from "./../views/user/UserProfile.vue";
export const userRoutes = [
{
path: "/user/login",
name: "user-login",
component: UserLogin,
},
{
path: "/user/register",
name: "user-register",
component: UserSignup,
},
{
path: "/profile",
name: "user-profile",
component: UserProfile,
},
];
// store/auth.ts
import { UserApi } from "@/api/user";
import { defineStore } from "pinia";
import router from "@/router";
export const useAuthStore = defineStore({
id: "auth",
state: () => ({
/* Initialize state from local storage to enable user to stay logged in */
user: localStorage.getItem("token")
? JSON.parse(localStorage.getItem("user"))
: null,
savedToken: localStorage.getItem("token")
? localStorage.getItem("token")
: null,
role: localStorage.getItem("token")
? JSON.parse(localStorage.getItem("role"))
: null,
}),
getters: {
token: (state) => state.savedToken,
},
actions: {
async login(email, password) {
try {
// Getting Access Token And Save It
const responseLogin = await UserApi.login(email, password);
const {
result: { access_token },
} = responseLogin;
this.savedToken = access_token;
localStorage.setItem("access_token", this.savedToken);
// Getting User Data
const responseUser = await UserApi.me();
const user = responseUser.result;
this.user = user;
localStorage.setItem("user", JSON.stringify(this.user));
router.replace("/dashboard");
} catch (error) {
// TODO: handle invalid credentials
localStorage.removeItem("token");
localStorage.removeItem("user");
throw error;
}
},
async fetchUserData() {
const responseUser = await UserApi.me();
const user = responseUser.result;
this.user = user;
localStorage.setItem("user", JSON.stringify(this.user));
this.role = role;
localStorage.setItem("role", JSON.stringify(this.role));
return this.user;
},
logout() {
this.user = null;
this.savedToken = null;
localStorage.removeItem("user");
localStorage.removeItem("token");
router.replace("/user/login");
},
removeUser() {
this.user = null;
localStorage.removeItem("user");
},
},
});
import { createStore } from "vuex"; import { defineStore } from "pinia";
export default createStore({ export const useMenuStore = defineStore("menu", {
state: { state: () => ({
hideConfigButton: false, hideConfigButton: false,
isPinned: false, isPinned: false,
showConfig: false, showConfig: false,
...@@ -17,37 +17,35 @@ export default createStore({ ...@@ -17,37 +17,35 @@ export default createStore({
showFooter: true, showFooter: true,
showMain: true, showMain: true,
layout: "default", layout: "default",
}, }),
mutations: { actions: {
toggleConfigurator(state) { toggleConfigurator() {
state.showConfig = !state.showConfig; this.showConfig = !this.showConfig;
}, },
sidebarMinimize(state) { sidebarMinimize() {
let sidenav_show = document.querySelector("#app"); let sidenav_show = document.querySelector("#app");
if (state.isPinned) { if (this.isPinned) {
sidenav_show.classList.add("g-sidenav-hidden"); sidenav_show.classList.add("g-sidenav-hidden");
sidenav_show.classList.remove("g-sidenav-pinned"); sidenav_show.classList.remove("g-sidenav-pinned");
state.isPinned = false; this.isPinned = false;
} else { } else {
sidenav_show.classList.add("g-sidenav-pinned"); sidenav_show.classList.add("g-sidenav-pinned");
sidenav_show.classList.remove("g-sidenav-hidden"); sidenav_show.classList.remove("g-sidenav-hidden");
state.isPinned = true; this.isPinned = true;
} }
}, },
sidebarType(state, payload) { setSidebarType(payload) {
state.sidebarType = payload; this.sidebarType = payload;
}, },
navbarFixed(state) { navbarFixed() {
if (state.isNavFixed === false) { if (this.isNavFixed === false) {
state.isNavFixed = true; this.isNavFixed = true;
} else { } else {
state.isNavFixed = false; this.isNavFixed = false;
} }
}, },
}, toggleSidebarColor(payload) {
actions: { this.sidebarType = payload;
toggleSidebarColor({ commit }, payload) {
commit("sidebarType", payload);
}, },
}, },
getters: {}, getters: {},
......
<script setup> <script setup>
import { computed } from "vue"; import { computed } from "vue";
import { useStore } from "vuex"; import { useMenuStore } from "@/store/menu";
const store = useStore(); const store = useMenuStore();
const isRTL = computed(() => store.state.isRTL); const isRTL = computed(() => store.isRTL);
defineProps({ defineProps({
title: { title: {
......
<script setup> <script setup>
import { onBeforeUnmount, onBeforeMount } from "vue"; import { onBeforeUnmount, onBeforeMount, inject, ref } from "vue";
import { useStore } from "vuex"; import { useMenuStore } from "@/store/menu";
// import Navbar from "@/examples/PageLayout/Navbar.vue";
import ArgonInput from "@/components/ArgonInput.vue"; import ArgonInput from "@/components/ArgonInput.vue";
import ArgonSwitch from "@/components/ArgonSwitch.vue"; import ArgonSwitch from "@/components/ArgonSwitch.vue";
import ArgonButton from "@/components/ArgonButton.vue"; import ArgonButton from "@/components/ArgonButton.vue";
import { UserApi } from "@/api/user";
import { useAuthStore } from "@/store/auth";
const store = useMenuStore();
const tools = inject("tools");
const body = document.getElementsByTagName("body")[0]; const body = document.getElementsByTagName("body")[0];
const store = useStore(); const login = async () => {
tools.showLoading();
const authStore = useAuthStore();
await authStore.login("developer@gmail.com", "kecilsemuatanpaspasi");
console.log(response);
tools.hideLoading();
};
onBeforeMount(() => { onBeforeMount(() => {
store.state.hideConfigButton = true; store.hideConfigButton = true;
store.state.showNavbar = false; store.showNavbar = false;
store.state.showSidenav = false; store.showSidenav = false;
store.state.showFooter = false; store.showFooter = false;
body.classList.remove("bg-gray-100"); body.classList.remove("bg-gray-100");
}); });
onBeforeUnmount(() => { onBeforeUnmount(() => {
store.state.hideConfigButton = false; store.hideConfigButton = false;
store.state.showNavbar = true; store.showNavbar = true;
store.state.showSidenav = true; store.showSidenav = true;
store.state.showFooter = true; store.showFooter = true;
body.classList.add("bg-gray-100"); body.classList.add("bg-gray-100");
}); });
</script> </script>
<template> <template>
<div class="container top-0 position-sticky z-index-sticky">
<div class="row">
<div class="col-12">
<!-- <navbar
isBlur="blur border-radius-lg my-3 py-2 start-0 end-0 mx-4 shadow"
v-bind:darkMode="true"
isBtn="bg-gradient-success"
/> -->
</div>
</div>
</div>
<main class="mt-0 main-content"> <main class="mt-0 main-content">
<section> <section>
<div class="page-header min-vh-100"> <div class="page-header min-vh-100">
...@@ -68,30 +68,29 @@ onBeforeUnmount(() => { ...@@ -68,30 +68,29 @@ onBeforeUnmount(() => {
size="lg" size="lg"
/> />
</div> </div>
<argon-switch id="rememberMe" name="remember-me"
>Remember me</argon-switch
>
<div class="text-center"> <div class="text-center">
<argon-button <argon-button
@click="login"
class="mt-4" class="mt-4"
variant="gradient" variant="gradient"
color="success" color="success"
fullWidth fullWidth
size="lg" size="lg"
>Sign in</argon-button
> >
Sign in
</argon-button>
</div> </div>
</form> </form>
</div> </div>
<div class="px-1 pt-0 text-center card-footer px-lg-2"> <div class="px-1 pt-0 text-center card-footer px-lg-2">
<p class="mx-auto mb-4 text-sm"> <p class="mx-auto mb-4 text-sm">
Don't have an account? Don't have an account?
<a <router-link
href="javascript:;" :to="{ name: 'user-register' }"
class="text-success text-gradient font-weight-bold" class="text-success text-gradient font-weight-bold"
>Sign up</a
> >
Sign up
</router-link>
</p> </p>
</div> </div>
</div> </div>
...@@ -102,7 +101,7 @@ onBeforeUnmount(() => { ...@@ -102,7 +101,7 @@ onBeforeUnmount(() => {
<div <div
class="position-relative bg-gradient-primary h-100 m-3 px-7 border-radius-lg d-flex flex-column justify-content-center overflow-hidden" class="position-relative bg-gradient-primary h-100 m-3 px-7 border-radius-lg d-flex flex-column justify-content-center overflow-hidden"
style=" style="
background-image: url(&quot;https://raw.githubusercontent.com/creativetimofficial/public-assets/master/argon-dashboard-pro/assets/img/signin-ill.jpg&quot;); background-image: url('https://raw.githubusercontent.com/creativetimofficial/public-assets/master/argon-dashboard-pro/assets/img/signin-ill.jpg');
background-size: cover; background-size: cover;
" "
> >
......
<script setup> <script setup>
import { onBeforeMount, onMounted, onBeforeUnmount } from "vue"; import { onBeforeMount, onMounted, onBeforeUnmount } from "vue";
import { useStore } from "vuex"; import { useMenuStore } from "@/store/menu";
import setNavPills from "@/assets/js/nav-pills.js"; import setNavPills from "@/assets/js/nav-pills.js";
import setTooltip from "@/assets/js/tooltip.js"; import setTooltip from "@/assets/js/tooltip.js";
import ProfileCard from "./components/ProfileCard.vue"; import ProfileCard from "./../components/ProfileCard.vue";
import ArgonInput from "@/components/ArgonInput.vue"; import ArgonInput from "@/components/ArgonInput.vue";
import ArgonButton from "@/components/ArgonButton.vue"; import ArgonButton from "@/components/ArgonButton.vue";
const body = document.getElementsByTagName("body")[0]; const body = document.getElementsByTagName("body")[0];
const store = useStore(); const store = useMenuStore();
onMounted(() => { onMounted(() => {
store.state.isAbsolute = true; store.isAbsolute = true;
setNavPills(); setNavPills();
setTooltip(); setTooltip();
}); });
onBeforeMount(() => { onBeforeMount(() => {
store.state.imageLayout = "profile-overview"; store.imageLayout = "profile-overview";
store.state.showNavbar = false; store.showNavbar = false;
store.state.showFooter = true; store.showFooter = true;
store.state.hideConfigButton = true; store.hideConfigButton = true;
body.classList.add("profile-overview"); body.classList.add("profile-overview");
}); });
onBeforeUnmount(() => { onBeforeUnmount(() => {
store.state.isAbsolute = false; store.isAbsolute = false;
store.state.imageLayout = "default"; store.imageLayout = "default";
store.state.showNavbar = true; store.showNavbar = true;
store.state.showFooter = true; store.showFooter = true;
store.state.hideConfigButton = false; store.hideConfigButton = false;
body.classList.remove("profile-overview"); body.classList.remove("profile-overview");
}); });
</script> </script>
......
<script setup> <script setup>
import { onBeforeUnmount, onBeforeMount } from "vue"; import { onBeforeUnmount, onBeforeMount } from "vue";
import { useStore } from "vuex"; import { useMenuStore } from "@/store/menu";
// import Navbar from "@/examples/PageLayout/Navbar.vue";
// import AppFooter from "@/examples/PageLayout/Footer.vue";
import ArgonInput from "@/components/ArgonInput.vue"; import ArgonInput from "@/components/ArgonInput.vue";
import ArgonCheckbox from "@/components/ArgonCheckbox.vue"; import ArgonCheckbox from "@/components/ArgonCheckbox.vue";
import ArgonButton from "@/components/ArgonButton.vue"; import ArgonButton from "@/components/ArgonButton.vue";
const body = document.getElementsByTagName("body")[0]; const body = document.getElementsByTagName("body")[0];
const store = useStore(); const store = useMenuStore();
onBeforeMount(() => { onBeforeMount(() => {
store.state.hideConfigButton = true; store.hideConfigButton = true;
store.state.showNavbar = false; store.showNavbar = false;
store.state.showSidenav = false; store.showSidenav = false;
store.state.showFooter = false; store.showFooter = false;
body.classList.remove("bg-gray-100"); body.classList.remove("bg-gray-100");
}); });
onBeforeUnmount(() => { onBeforeUnmount(() => {
store.state.hideConfigButton = false; store.hideConfigButton = false;
store.state.showNavbar = true; store.showNavbar = true;
store.state.showSidenav = true; store.showSidenav = true;
store.state.showFooter = true; store.showFooter = true;
body.classList.add("bg-gray-100"); body.classList.add("bg-gray-100");
}); });
</script> </script>
...@@ -37,7 +34,7 @@ onBeforeUnmount(() => { ...@@ -37,7 +34,7 @@ onBeforeUnmount(() => {
<div <div
class="page-header align-items-start min-vh-50 pt-5 pb-11 m-3 border-radius-lg" class="page-header align-items-start min-vh-50 pt-5 pb-11 m-3 border-radius-lg"
style=" style="
background-image: url(&quot;https://raw.githubusercontent.com/creativetimofficial/public-assets/master/argon-dashboard-pro/assets/img/signup-cover.jpg&quot;); background-image: url('https://raw.githubusercontent.com/creativetimofficial/public-assets/master/argon-dashboard-pro/assets/img/signup-cover.jpg');
background-position: top; background-position: top;
" "
> >
...@@ -208,9 +205,12 @@ onBeforeUnmount(() => { ...@@ -208,9 +205,12 @@ onBeforeUnmount(() => {
</div> </div>
<p class="text-sm mt-3 mb-0"> <p class="text-sm mt-3 mb-0">
Already have an account? Already have an account?
<a href="javascript:;" class="text-dark font-weight-bolder" <router-link
>Sign in</a :to="{ name: 'user-login' }"
class="text-dark font-weight-bolder"
> >
Sign in
</router-link>
</p> </p>
</form> </form>
</div> </div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment