diff --git a/xroom-dashboard/src/assets/main.css b/xroom-dashboard/src/assets/main.css new file mode 100644 index 0000000..e6c28a9 --- /dev/null +++ b/xroom-dashboard/src/assets/main.css @@ -0,0 +1,44 @@ +/* main.css */ +@import url("https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css"); + +:root { + --white: rgba(255, 255, 255, 1); + --black: rgba(16, 16, 16, 1); + --accentcolor-accentcolor-600: rgba(230, 230, 230, 1); + --neutralcolorneutralcolor-25: rgba(198, 204, 213, 1); + --neutralcolorneutralcolor-300: rgba(141, 153, 171, 1); + --neutralcolorneutralcolor-600: rgba(102, 115, 135, 1); + --neutralcolorneutralcolor-500: rgba(113, 128, 150, 1); + --neutralcolorneutralcolor-800: rgba(79, 90, 105, 1); + --neutralcolorneutralcolor-900: rgba(68, 77, 90, 1); + --neutralcolorneutralcolor-400: rgba(127, 141, 161, 1); + --neutralcolorneutralcolor-50: rgba(184, 192, 203, 1); + --successcolor-successcolor-500: rgba(72, 187, 120, 1); + --brand-colorbrand-color-400: rgba(97, 121, 237, 1); + --neutralcolorneutralcolor-1000: rgba(45, 51, 60, 1); + --successcolor-successcolor-300: rgba(109, 201, 147, 1); + --brand-colorbrand-color-800: rgba(32, 48, 128, 1); +} + +* { + -webkit-font-smoothing: antialiased; + box-sizing: border-box; +} + +html, +body { + margin: 0px; + height: 100%; + background-color: #101010; + font-family: "IRANSansXFaNum-Medium", Helvetica; +} + +/* a blue color as a generic focus style */ +button:focus-visible { + outline: 2px solid #4a90e2 !important; + outline: -webkit-focus-ring-color auto 5px !important; +} + +a { + text-decoration: none; +} \ No newline at end of file diff --git a/xroom-dashboard/src/axios.js b/xroom-dashboard/src/axios.js new file mode 100644 index 0000000..2f0c375 --- /dev/null +++ b/xroom-dashboard/src/axios.js @@ -0,0 +1,16 @@ +// src/axios.js +import axios from 'axios'; + +const instance = axios.create({ + baseURL: 'http://194.62.43.230:8000', +}); + +instance.interceptors.request.use(config => { + const token = localStorage.getItem('token'); + if (token) { + config.headers.Authorization = `token ${token}`; + } + return config; +}); + +export default instance; diff --git a/xroom-dashboard/src/components.rar b/xroom-dashboard/src/components.rar new file mode 100644 index 0000000..1144298 Binary files /dev/null and b/xroom-dashboard/src/components.rar differ diff --git a/xroom-dashboard/src/components/DashboardPage.vue b/xroom-dashboard/src/components/DashboardPage.vue index a3e14c1..5cb12b3 100644 --- a/xroom-dashboard/src/components/DashboardPage.vue +++ b/xroom-dashboard/src/components/DashboardPage.vue @@ -1,150 +1,575 @@ + - - - - - \ No newline at end of file + + + + + + + \ No newline at end of file diff --git a/xroom-dashboard/src/components/SidebarMenu.vue b/xroom-dashboard/src/components/SidebarMenu.vue index 4c24d65..fc447b6 100644 --- a/xroom-dashboard/src/components/SidebarMenu.vue +++ b/xroom-dashboard/src/components/SidebarMenu.vue @@ -1,94 +1,270 @@ + - - - - - \ No newline at end of file +} + + + \ No newline at end of file diff --git a/xroom-dashboard/src/main.js b/xroom-dashboard/src/main.js index 4ac17c1..49aabb8 100644 --- a/xroom-dashboard/src/main.js +++ b/xroom-dashboard/src/main.js @@ -1,6 +1,7 @@ import { createApp } from 'vue' import App from './App.vue' import router from './router' +import '@/assets/main.css' createApp(App) .use(router) // Make sure you use the router here diff --git a/xroom-dashboard/src/components/LoginPage.vue b/xroom-dashboard/src/pages/LoginPage.vue similarity index 83% rename from xroom-dashboard/src/components/LoginPage.vue rename to xroom-dashboard/src/pages/LoginPage.vue index 601f962..6654e00 100644 --- a/xroom-dashboard/src/components/LoginPage.vue +++ b/xroom-dashboard/src/pages/LoginPage.vue @@ -55,24 +55,26 @@ export default { }, methods: { async handleSubmit() { - // Prepare the data to match API format - const signupData = { - first_name: this.form.firstName, - last_name: this.form.lastName, - mobile_number: this.form.mobileNumber, - password: this.form.password, - }; + const loginData = { + mobile_number: this.form.mobileNumber, + password: this.form.password, + }; + + try { + const response = await axios.post('http://194.62.43.230:8000/login', loginData); + const token = response.data.token; + const user = response.data.user; + + localStorage.setItem('token', token); + localStorage.setItem('user', JSON.stringify(user)); + + this.$router.push('/dashboard'); + } catch (error) { + console.error('Login error:', error); + alert('خطا در ورود. لطفا دوباره تلاش کنید.'); + } +}, - try { - const response = await axios.post('http://194.62.43.230:8000/login', signupData); - console.log('Signup success:', response.data); - // Redirect to login page upon successful signup - this.$router.push('/dashboard'); - } catch (error) { - console.error('Signup error:', error); - // Handle error, show alert or error message - } - }, }, }; diff --git a/xroom-dashboard/src/components/SignupPage.vue b/xroom-dashboard/src/pages/SignupPage.vue similarity index 100% rename from xroom-dashboard/src/components/SignupPage.vue rename to xroom-dashboard/src/pages/SignupPage.vue diff --git a/xroom-dashboard/src/pages/dashboard/files.vue b/xroom-dashboard/src/pages/dashboard/files.vue new file mode 100644 index 0000000..cc70368 --- /dev/null +++ b/xroom-dashboard/src/pages/dashboard/files.vue @@ -0,0 +1,341 @@ + + + + + + \ No newline at end of file diff --git a/xroom-dashboard/src/pages/dashboard/index.vue b/xroom-dashboard/src/pages/dashboard/index.vue new file mode 100644 index 0000000..b35a535 --- /dev/null +++ b/xroom-dashboard/src/pages/dashboard/index.vue @@ -0,0 +1,575 @@ + + + + + + \ No newline at end of file diff --git a/xroom-dashboard/src/router/index.js b/xroom-dashboard/src/router/index.js index 8552811..16a439c 100644 --- a/xroom-dashboard/src/router/index.js +++ b/xroom-dashboard/src/router/index.js @@ -1,8 +1,9 @@ import { createRouter, createWebHistory } from 'vue-router' -import SignupPage from '../components/SignupPage.vue' // Renamed -import LoginPage from '../components/LoginPage.vue' // Renamed -import DashboardPage from '../components/DashboardPage.vue' -import FilesPage from '@/components/FilesPage.vue'; // import the new page +import SignupPage from '../pages/SignupPage.vue' // Renamed +import LoginPage from '../pages/LoginPage.vue' // Renamed +import DashboardPage from '../pages/dashboard/index.vue' +import FilesPage from '@/pages/dashboard/files.vue'; // import the new page +import axios from '@/axios'; const routes = [ { @@ -20,7 +21,7 @@ const routes = [ name: 'DashboardPage', // Renamed component: DashboardPage },{ - path: '/files', + path: '/dashboard/files', name: 'files', component: FilesPage, // link the files page } @@ -31,4 +32,32 @@ const router = createRouter({ routes }) + +router.beforeEach(async (to, from, next) => { + const token = localStorage.getItem('token'); + + // No token, redirect to login if trying to access dashboard + if (to.path === '/dashboard' && !token) { + return next('/login'); + } + + if (token) { + try { + await axios.get('/getInfo'); + if (to.path === '/login') { + return next('/dashboard'); + } + return next(); + } catch (err) { + // Invalid token, redirect to login + localStorage.removeItem('token'); + localStorage.removeItem('user'); + return next('/login'); + } + } + + next(); +}); + + export default router