diff --git a/src/App.vue b/src/App.vue index bc96cad..27cfe53 100644 --- a/src/App.vue +++ b/src/App.vue @@ -5,16 +5,34 @@ - - + + + + + diff --git a/src/components/UpdateCard.vue b/src/components/UpdateCard.vue new file mode 100644 index 0000000..7100069 --- /dev/null +++ b/src/components/UpdateCard.vue @@ -0,0 +1,67 @@ + + + + + + diff --git a/src/router.ts b/src/router.ts index ecb9b42..c82ecc7 100644 --- a/src/router.ts +++ b/src/router.ts @@ -1,32 +1,22 @@ -import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'; - -const routes: Array = [ - { - path: '/', - name: 'ManagerView', - component: () => import('./views/ManagerView.vue'), - }, - { - path: '/login', - name: 'LoginView', - component: () => import('./views/LoginView.vue'), - }, -]; - -const router = createRouter({ - history: createWebHistory(), - routes, -}); - -router.beforeEach((to, from, next) => { - const token = window.localStorage.getItem('auth-token'); - - if (!token && to.path != '/login') return next({ path: '/login' }); - - if (token && to.path == '/login') return next({ path: '/' }); - // else if (to.path == '/login') return next({ path: '/' }); - - return next(); -}); - -export default router; +import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'; + +const routes: Array = [ + { + path: '/', + name: 'ManagerView', + component: () => import('./views/ManagerView.vue'), + }, + { + path: '/login', + name: 'LoginView', + component: () => import('./views/LoginView.vue'), + }, +]; + +const router = createRouter({ + history: createWebHistory(), + routes, +}); + + +export default router; diff --git a/src/store.ts b/src/store.ts index 0497e57..89e392a 100644 --- a/src/store.ts +++ b/src/store.ts @@ -1,28 +1,31 @@ -import { defineStore } from 'pinia'; -import { Availability, ChangeProp, HeaderTypes, IStore } from './types/types'; -import { getAvailabilityValue } from './types/typeUitls'; - -export const useStore = defineStore('store', { - state: () => - ({ - dataState: 'LOADING', - unsavedChanges: false, - stationList: [], - backupList: [], - stationsToRemove: [], - searchedSceneryName: '', - changeList: [], - newStationsCount: 0, - routesModalVisible: true, - currentStation: null, - selectedStationName: '', - token: null, - user: null, - isAuthorized: false, - notifyDiscord: true, - alertMessage: '', - confirmMessage: '', - - changesResponse: [], - } as IStore), -}); +import { defineStore } from 'pinia'; +import { AuthState, Availability, ChangeProp, HeaderTypes, IStore } from './types/types'; +import { getAvailabilityValue } from './types/typeUitls'; + +export const useStore = defineStore('store', { + state: () => + ({ + dataState: 'LOADING', + authState: AuthState.LOADING, + + unsavedChanges: false, + stationList: [], + backupList: [], + stationsToRemove: [], + searchedSceneryName: '', + changeList: [], + newStationsCount: 0, + routesModalVisible: true, + currentStation: null, + selectedStationName: '', + token: null, + user: null, + isAuthorized: false, + notifyDiscord: true, + + alertMessage: '', + confirmMessage: '', + + changesResponse: [], + } as IStore), +}); diff --git a/src/types/types.ts b/src/types/types.ts index f051354..c9ce655 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -1,85 +1,103 @@ -export type Availability = 'default' | 'unavailable' | 'nonPublic' | 'abandoned' | 'nonDefault'; -export type ChangeProp = - | 'name' - | 'url' - | 'lines' - | 'project' - | 'reqLevel' - | 'signalType' - | 'controlType' - | 'SUP' - | 'routes' - | 'checkpoints' - | 'authors' - | 'availability'; - -export enum HeaderTypes { - name = 'Nazwa', - url = 'URL', - lines = 'Linie', - project = 'Projekt', - reqLevel = 'Wym. poziom', - signalType = 'Sygnalizacja', - controlType = 'Sterowanie', - SUP = 'SUP', - authors = 'Autorzy', - routes = 'Szlaki', - checkpoints = 'Posterunki', - availability = 'Dostępność', - toRemove = 'Usuń', -} - -export enum AvailabilityTypes { - 'default' = 'w paczce', - 'nonDefault' = 'poza paczką', - 'nonPublic' = 'niepubliczna', - 'abandoned' = 'wycofana', - 'unavailable' = 'niedostępna', -} - -export interface SceneryRowItem { - id: string; - name: string; - url: string; - lines: string; - project: string | null; - reqLevel: number; - signalType: string; - controlType: string; - SUP: boolean; - routes: string; - checkpoints: string; - authors: string; - availability: Availability; -} - -export type ChangeItem = { - [key in ChangeProp]?: string | number | boolean | null; -} & { - id: string; - name: string; - - toRemove?: boolean; -}; - -export interface IStore { - dataState: string; - unsavedChanges: boolean; - stationList: SceneryRowItem[]; - backupList: SceneryRowItem[]; - stationsToRemove: string[]; - searchedSceneryName: string; - changeList: ChangeItem[]; - newStationsCount: number; - routesModalVisible: boolean; - currentStation: SceneryRowItem | null; - selectedStationName: string; - token: string | null; - user: { name: string; id: string } | null; - isAuthorized: boolean; - notifyDiscord: boolean; - alertMessage: string; - confirmMessage: string; - - changesResponse: string[]; -} +export type Availability = 'default' | 'unavailable' | 'nonPublic' | 'abandoned' | 'nonDefault'; +export type ChangeProp = + | 'name' + | 'url' + | 'lines' + | 'project' + | 'reqLevel' + | 'signalType' + | 'controlType' + | 'SUP' + | 'routes' + | 'checkpoints' + | 'authors' + | 'availability'; + +export enum HeaderTypes { + name = 'Nazwa', + url = 'URL', + lines = 'Linie', + project = 'Projekt', + reqLevel = 'Wym. poziom', + signalType = 'Sygnalizacja', + controlType = 'Sterowanie', + SUP = 'SUP', + authors = 'Autorzy', + routes = 'Szlaki', + checkpoints = 'Posterunki', + availability = 'Dostępność', + toRemove = 'Usuń', +} + +export enum AvailabilityTypes { + 'default' = 'w paczce', + 'nonDefault' = 'poza paczką', + 'nonPublic' = 'niepubliczna', + 'abandoned' = 'wycofana', + 'unavailable' = 'niedostępna', +} + +export interface SceneryRowItem { + id: string; + name: string; + url: string; + lines: string; + project: string | null; + reqLevel: number; + signalType: string; + controlType: string; + SUP: boolean; + routes: string; + checkpoints: string; + authors: string; + availability: Availability; +} + +export type ChangeItem = { + [key in ChangeProp]?: string | number | boolean | null; +} & { + id: string; + name: string; + + toRemove?: boolean; +}; + +export enum AuthState { + 'LOADING' = 0, + 'AUTHORIZED' = 1, + 'UNAUTHORIZED' = 2, +} + +export interface IStore { + dataState: string; + authState: AuthState; + + unsavedChanges: boolean; + stationList: SceneryRowItem[]; + backupList: SceneryRowItem[]; + stationsToRemove: string[]; + searchedSceneryName: string; + changeList: ChangeItem[]; + newStationsCount: number; + routesModalVisible: boolean; + currentStation: SceneryRowItem | null; + selectedStationName: string; + token: string | null; + user: { name: string; id: string } | null; + isAuthorized: boolean; + notifyDiscord: boolean; + alertMessage: string; + confirmMessage: string; + + changesResponse: string[]; +} + +export interface ILoginResponse { + token: string; + user: IUser; +} + +export interface IUser { + name: string; + id: string; +} diff --git a/src/views/LoginView.vue b/src/views/LoginView.vue index 0b24b3e..60bda5a 100644 --- a/src/views/LoginView.vue +++ b/src/views/LoginView.vue @@ -1,5 +1,5 @@ @@ -24,13 +24,12 @@ import axios from 'axios'; import { defineComponent } from 'vue'; import dataMixin from '../mixins/dataMixin'; import { useStore } from '../store'; +import { AuthState, ILoginResponse } from '../types/types'; -interface LoginResponse { - token: string; - user: { - name: string; - id: string; - }; +enum LoginState { + INITIALIZED = 0, + LOADING = 1, + LOADED = 2, } export default defineComponent({ @@ -40,18 +39,20 @@ export default defineComponent({ return { name: '', password: '', + loginState: LoginState.INITIALIZED, + LoginState, store: useStore(), + AuthState, }; }, methods: { async signIn(e: Event) { e.preventDefault(); - - console.log(import.meta.env.VITE_API_URL); + this.loginState = LoginState.LOADING; try { - const data: LoginResponse = ( + const data: ILoginResponse = ( await axios.post( `${this.API_URL}/auth/login`, { username: this.name, password: this.password }, @@ -63,7 +64,9 @@ export default defineComponent({ ) ).data; - this.store.isAuthorized = true; + this.store.authState = AuthState.AUTHORIZED; + this.loginState = LoginState.LOADED; + this.store.token = data.token; this.store.user = data.user; @@ -73,6 +76,9 @@ export default defineComponent({ this.loadData(); this.$router.push('/'); } catch (e: any) { + this.store.authState = AuthState.UNAUTHORIZED; + this.loginState = LoginState.LOADED; + if (!e.response || e.response.status === undefined) { this.store.alertMessage = 'Wystąpił błąd podczas łączenia z serwerem!'; return; diff --git a/src/views/ManagerView.vue b/src/views/ManagerView.vue index e9081af..55bec49 100644 --- a/src/views/ManagerView.vue +++ b/src/views/ManagerView.vue @@ -1,247 +1,250 @@ - - - - - + + + + +