main.ts 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  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 { t } = useI18n();
  10. const defaultState: MainState = {
  11. isLoggedIn: null,
  12. token: '',
  13. logInError: false,
  14. userProfile: null,
  15. dashboardMiniDrawer: false,
  16. dashboardShowDrawer: true,
  17. notifications: [],
  18. videos: [],
  19. };
  20. export const useMainStore = defineStore("MainStoreId", {
  21. state: () => defaultState,
  22. getters: {
  23. readhasAdminAccess: (state) =>
  24. state.userProfile && state.userProfile.is_superuser && state.userProfile.is_active,
  25. readLoginError: (state) => state.logInError,
  26. readDashboardShowDrawer: (state) => state.dashboardShowDrawer,
  27. readDashboardMiniDrawer: (state) => state.dashboardMiniDrawer,
  28. readUserProfile: (state) => state.userProfile,
  29. readToken: (state) => state.token,
  30. readIsLoggedIn: (state) => state.isLoggedIn,
  31. readFirstNotification: (state) => state.notifications.length > 0 && state.notifications[0],
  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: "Logged in", 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: "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: "Profile successfully updated",
  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. } catch (error) {
  117. await this.removeLogIn();
  118. }
  119. } else {
  120. await this.removeLogIn();
  121. }
  122. }
  123. },
  124. async removeLogIn() {
  125. removeLocalToken();
  126. this.setToken("");
  127. this.setLoggedIn(false);
  128. },
  129. async logOut() {
  130. await this.removeLogIn();
  131. this.routeLogOut();
  132. },
  133. async userLogOut() {
  134. await this.logOut();
  135. this.addNotification({ content: "Logged out", color: "success" });
  136. },
  137. routeLogOut() {
  138. if (router.currentRoute.value.path !== "/login") {
  139. router.push("/login");
  140. }
  141. },
  142. async checkApiError(payload: unknown) {
  143. if (axios.isAxiosError(payload)) {
  144. if (payload.response?.status === 401) {
  145. await this.logOut();
  146. }
  147. }
  148. },
  149. routeLoggedIn() {
  150. if (router.currentRoute.value.path === "/login" || router.currentRoute.value.path === "/") {
  151. router.push("/main/dashboard");
  152. }
  153. },
  154. async dispatchRemoveNotification(payload: { notification: AppNotification; timeout: number },) {
  155. return new Promise((resolve, _) => {
  156. setTimeout(() => {
  157. this.removeNotification(payload.notification);
  158. resolve(true);
  159. }, payload.timeout);
  160. });
  161. },
  162. async register(payload: IUserProfileCreate) {
  163. const loadingNotification = {
  164. content: i18n.global.t("sginingUp"),
  165. showProgress: true,
  166. };
  167. try {
  168. this.addNotification(loadingNotification);
  169. const response = (
  170. await Promise.all([
  171. api.registerUser(payload),
  172. await new Promise<void>((resolve, _) => setTimeout(() => resolve(), 500)),
  173. ])
  174. )[0];
  175. this.removeNotification(loadingNotification);
  176. this.addNotification({
  177. content: i18n.global.t("successfully"),
  178. color: "success",
  179. });
  180. setTimeout(() => {
  181. router.push("/login")
  182. }, 2000)
  183. } catch (error) {
  184. await this.checkApiError(error);
  185. }
  186. },
  187. async passwordRecovery(username: string ) {
  188. const loadingNotification = {
  189. content: "Sending password recovery email",
  190. showProgress: true,
  191. };
  192. try {
  193. this.addNotification(loadingNotification);
  194. await Promise.all([
  195. api.passwordRecovery(username),
  196. await new Promise<void>((resolve, _) => setTimeout(() => resolve(), 500)),
  197. ]);
  198. this.removeNotification(loadingNotification);
  199. this.addNotification({
  200. content: "Password recovery email sent",
  201. color: "success",
  202. });
  203. await this.logOut();
  204. } catch (error) {
  205. this.removeNotification(loadingNotification);
  206. this.addNotification({ color: "error", content: "Incorrect username" });
  207. }
  208. },
  209. async resetPassword(password: string, token: string) {
  210. const loadingNotification = { content: "Resetting password", showProgress: true };
  211. try {
  212. this.addNotification(loadingNotification);
  213. await Promise.all([
  214. api.resetPassword(token, password),
  215. await new Promise<void>((resolve, _) => setTimeout(() => resolve(), 500)),
  216. ]);
  217. this.removeNotification(loadingNotification);
  218. this.addNotification( {
  219. content: "Password successfully reset",
  220. color: "success",
  221. });
  222. await this.logOut();
  223. } catch (error) {
  224. this.removeNotification(loadingNotification);
  225. this.addNotification({
  226. color: "error",
  227. content: "Error resetting password",
  228. });
  229. }
  230. },
  231. async uploadPlot(title: string, file: File) {
  232. const mainStore = useMainStore();
  233. try {
  234. const loadingNotification = { content: "sending", showProgress: true };
  235. mainStore.addNotification(loadingNotification);
  236. const response = (
  237. await Promise.all([
  238. api.uploadPlot(mainStore.token, title, file),
  239. await new Promise<void>((resolve, _) => setTimeout(() => resolve(), 500)),
  240. ])
  241. );
  242. mainStore.removeNotification(loadingNotification);
  243. mainStore.addNotification({
  244. content: "File received",
  245. color: "success",
  246. })
  247. } catch (error) {
  248. await mainStore.checkApiError(error);
  249. }
  250. },
  251. async actionGetVideos() {
  252. const mainStore = useMainStore();
  253. try {
  254. const response = await api.getVideos(mainStore.token)
  255. if (response) {
  256. this.setVideos(response.data);
  257. }
  258. } catch (error) {
  259. await mainStore.checkApiError(error);
  260. }
  261. },
  262. }
  263. });