main.ts 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. import axios from "axios"
  2. import { defineStore } from "pinia";
  3. import { api } from "@/api"
  4. import router from "@/router"
  5. import { getLocalToken, removeLocalToken, saveLocalToken } from "@/utils";
  6. import type { AppNotification } from '@/interfaces';
  7. import type { IUserProfile, IUserProfileCreate, IUserProfileUpdate, MainState, Video } from '@/interfaces';
  8. import i18n from '@/plugins/i18n'
  9. const defaultState: MainState = {
  10. isLoggedIn: null,
  11. token: '',
  12. logInError: false,
  13. userProfile: null,
  14. dashboardMiniDrawer: false,
  15. dashboardShowDrawer: true,
  16. notifications: [],
  17. videos: [],
  18. };
  19. export const useMainStore = defineStore("MainStoreId", {
  20. state: () => defaultState,
  21. getters: {
  22. readhasAdminAccess: (state) =>
  23. state.userProfile && state.userProfile.is_superuser && state.userProfile.is_active,
  24. readLoginError: (state) => state.logInError,
  25. readDashboardShowDrawer: (state) => state.dashboardShowDrawer,
  26. readDashboardMiniDrawer: (state) => state.dashboardMiniDrawer,
  27. readUserProfile: (state) => state.userProfile,
  28. readToken: (state) => state.token,
  29. readIsLoggedIn: (state) => state.isLoggedIn,
  30. readFirstNotification: (state) => state.notifications.length > 0 && state.notifications[0],
  31. readVideos: (state) => state.videos,
  32. },
  33. actions: {
  34. // setters
  35. setToken(payload: string) { this.token = payload; },
  36. setLoggedIn(payload: boolean) { this.isLoggedIn = payload; },
  37. setLogInError(payload: boolean) { this.logInError = payload; },
  38. setUserProfile(payload: IUserProfile) { this.userProfile = payload },
  39. setDashboardMiniDrawer(payload: boolean) { this.dashboardMiniDrawer = payload; },
  40. setDashboardShowDrawer(payload: boolean) { this.dashboardShowDrawer = payload; },
  41. setVideos(payload: Video[]) { this.videos = payload },
  42. addNotification(payload: AppNotification) { this.notifications.push(payload); },
  43. removeNotification(payload: AppNotification) {
  44. if (payload) {
  45. this.notifications = this.notifications.filter(
  46. (notification) => notification !== payload,
  47. );
  48. }
  49. },
  50. // actions
  51. async logIn(username: string, password: string) {
  52. try {
  53. const response = await api.logInGetToken(username, password);
  54. const token: string = response.data.access_token;
  55. if (token) {
  56. saveLocalToken(token);
  57. this.setToken(token);
  58. this.setLoggedIn(true);
  59. this.setLogInError(false);
  60. await this.getUserProfile();
  61. await this.routeLoggedIn();
  62. this.addNotification({ content: i18n.global.t("loggedIn"), color: "success" });
  63. } else {
  64. await this.logOut();
  65. }
  66. } catch (err) {
  67. this.setLogInError(true);
  68. await this.logOut();
  69. }
  70. },
  71. async getUserProfile() {
  72. try {
  73. const response = await api.getMe(this.token);
  74. if (response.data) {
  75. this.setUserProfile(response.data)
  76. }
  77. } catch (error) {
  78. await this.checkApiError(error);
  79. }
  80. },
  81. async updateUserProfile(payload: IUserProfileUpdate) {
  82. try {
  83. const loadingNotification = { content: i18n.global.t("saving"), showProgress: true };
  84. await this.addNotification(loadingNotification);
  85. const response = (
  86. await Promise.all([
  87. api.updateMe(this.token, payload),
  88. await new Promise<void>((resolve, _) => setTimeout(() => resolve(), 500)),
  89. ])
  90. )[0];
  91. this.setUserProfile(response.data);
  92. this.removeNotification(loadingNotification);
  93. this.addNotification({
  94. content: i18n.global.t("profileUpdated"),
  95. color: "success",
  96. });
  97. } catch (error) {
  98. await this.checkApiError(error);
  99. }
  100. },
  101. async checkLoggedIn() {
  102. if (!this.isLoggedIn) {
  103. let token = this.token;
  104. if (!token) {
  105. const localToken = getLocalToken();
  106. if (localToken) {
  107. this.setToken(localToken);
  108. token = localToken;
  109. }
  110. }
  111. if (token) {
  112. try {
  113. const response = await api.getMe(token);
  114. this.setLoggedIn(true);
  115. this.setUserProfile(response.data);
  116. router.push("/main/dashboard");
  117. } catch (error) {
  118. await this.removeLogIn();
  119. }
  120. } else {
  121. await this.removeLogIn();
  122. }
  123. }
  124. },
  125. async removeLogIn() {
  126. removeLocalToken();
  127. this.setToken("");
  128. this.setLoggedIn(false);
  129. },
  130. async logOut() {
  131. await this.removeLogIn();
  132. this.routeLogOut();
  133. },
  134. async userLogOut() {
  135. await this.logOut();
  136. this.addNotification({ content: "Logged out", color: "success" });
  137. },
  138. routeLogOut() {
  139. if (router.currentRoute.value.path !== "/login") {
  140. router.push("/login");
  141. }
  142. },
  143. async checkApiError(payload: unknown) {
  144. if (axios.isAxiosError(payload)) {
  145. if (payload.response?.status === 401) {
  146. await this.logOut();
  147. }
  148. }
  149. },
  150. routeLoggedIn() {
  151. if (router.currentRoute.value.path === "/login" || router.currentRoute.value.path === "/") {
  152. router.push("/main/dashboard");
  153. }
  154. },
  155. async dispatchRemoveNotification(payload: { notification: AppNotification; timeout: number },) {
  156. return new Promise((resolve, _) => {
  157. setTimeout(() => {
  158. this.removeNotification(payload.notification);
  159. resolve(true);
  160. }, payload.timeout);
  161. });
  162. },
  163. async register(payload: IUserProfileCreate) {
  164. const loadingNotification = {
  165. content: i18n.global.t("signingUp"),
  166. showProgress: true,
  167. };
  168. try {
  169. this.addNotification(loadingNotification);
  170. const response = (
  171. await Promise.all([
  172. api.registerUser(payload),
  173. await new Promise<void>((resolve, _) => setTimeout(() => resolve(), 500)),
  174. ])
  175. )[0];
  176. this.removeNotification(loadingNotification);
  177. this.addNotification({
  178. content: i18n.global.t("registerSuccess"),
  179. color: "success",
  180. });
  181. setTimeout(() => {
  182. router.push("/login")
  183. }, 2000)
  184. } catch (error) {
  185. await this.checkApiError(error);
  186. }
  187. },
  188. async passwordRecovery(username: string) {
  189. const loadingNotification = {
  190. content: i18n.global.t("sendingEmail"),
  191. showProgress: true,
  192. };
  193. try {
  194. this.addNotification(loadingNotification);
  195. await Promise.all([
  196. api.passwordRecovery(username),
  197. await new Promise<void>((resolve, _) => setTimeout(() => resolve(), 500)),
  198. ]);
  199. this.removeNotification(loadingNotification);
  200. this.addNotification({
  201. content: i18n.global.t("passwordMailSent"),
  202. color: "success",
  203. });
  204. await this.logOut();
  205. } catch (error) {
  206. this.removeNotification(loadingNotification);
  207. this.addNotification({ color: "error", content: i18n.global.t("incorrectUsername") });
  208. }
  209. },
  210. async resetPassword(password: string, token: string) {
  211. const loadingNotification = { content: "Resetting password", showProgress: true };
  212. try {
  213. this.addNotification(loadingNotification);
  214. await Promise.all([
  215. api.resetPassword(token, password),
  216. await new Promise<void>((resolve, _) => setTimeout(() => resolve(), 500)),
  217. ]);
  218. this.removeNotification(loadingNotification);
  219. this.addNotification({
  220. content: "Password successfully reset",
  221. color: "success",
  222. });
  223. await this.logOut();
  224. } catch (error) {
  225. this.removeNotification(loadingNotification);
  226. this.addNotification({
  227. color: "error",
  228. content: "Error resetting password",
  229. });
  230. }
  231. },
  232. async uploadPlot(title: string, file: File) {
  233. const mainStore = useMainStore();
  234. try {
  235. const loadingNotification = { content: i18n.global.t("sending"), showProgress: true };
  236. mainStore.addNotification(loadingNotification);
  237. const response = (
  238. await Promise.all([
  239. api.uploadPlot(mainStore.token, title, file),
  240. await new Promise<void>((resolve, _) => setTimeout(() => resolve(), 0)),
  241. ])
  242. );
  243. mainStore.removeNotification(loadingNotification);
  244. mainStore.addNotification({
  245. content: i18n.global.t("fileReceived"),
  246. color: "success",
  247. })
  248. this.actionGetVideos();
  249. } catch (error) {
  250. await mainStore.checkApiError(error);
  251. }
  252. },
  253. async actionGetVideos() {
  254. const mainStore = useMainStore();
  255. try {
  256. const response = await api.getVideos(mainStore.token)
  257. if (response) {
  258. this.setVideos(response.data);
  259. }
  260. } catch (error) {
  261. await mainStore.checkApiError(error);
  262. }
  263. },
  264. }
  265. });