Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@
"test": "vitest",
"lint": "eslint \"**/*.{vue,ts}\"",
"lint:fix": "eslint \"**/*.{vue,ts}\" --fix",
"lint:deadcode": "knip --exclude binaries,dependencies,unlisted",
"lint:circular": "dpdm --exit-code circular:1 --no-tree --no-warning --progress false --transform './src/main.ts'",
"prettier": "prettier . --check",
"prettier:write": "prettier . --write",
"stylelint": "stylelint \"**/*.{vue,css}\"",
"stylelint:fix": "stylelint \"**/*.{vue,css}\" --fix",
"format": "pnpm run lint:fix && pnpm run prettier:write && pnpm run stylelint:fix",
"format": "vue-tsc && pnpm run lint:fix && pnpm run prettier:write && pnpm run stylelint:fix",
"check": "vue-tsc && pnpm run lint && pnpm run prettier && pnpm run stylelint"
},
"dependencies": {
Expand All @@ -41,11 +43,13 @@
"@typescript-eslint/parser": "^8.15.0",
"@vitejs/plugin-vue": "^5.2.0",
"@vue/eslint-config-typescript": "^14.1.3",
"dpdm": "^3.14.0",
"eslint": "^9.15.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-vue": "^9.31.0",
"globals": "^15.12.0",
"knip": "^5.45.0",
"openapi-typescript": "^7.4.3",
"postcss": "^8.4.49",
"postcss-html": "^1.7.0",
Expand All @@ -55,6 +59,7 @@
"stylelint-config-recommended-vue": "^1.5.0",
"stylelint-config-standard": "^36.0.1",
"typescript": "5.6.3",
"typescript-eslint": "^8.26.0",
"vite": "^5.4.11",
"vite-plugin-eslint": "^1.8.1",
"vite-plugin-pwa": "^0.21.0",
Expand Down
790 changes: 734 additions & 56 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import IrdomToastList from './components/IrdomToastList.vue';
import { useToolbar } from './store/toolbar';
import IrdomToolbar from './components/IrdomToolbar.vue';
import CalendarDropdown from './views/timetable/CalendarDropdown.vue';
import apiClient from '@/api/';
import { apiClient } from '@/api/';

const profileStore = useProfileStore();
const toolbar = useToolbar();
Expand Down
34 changes: 34 additions & 0 deletions src/api/client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { createClient } from '@profcomff/api-uilib';
import { type Middleware } from 'openapi-fetch';
import { ApiError, ErrorInfo } from './types';

export function recordError(url: string, status: number, error: ApiError | undefined) {
if (error) {
const errorInfo: ErrorInfo = {
url,
status,
message: error.message,
};
apiClient.POST('/marketing/v1/action', {
body: {
action: 'error',
additional_data: JSON.stringify(errorInfo),
},
});
}
}

const errorMiddleware: Middleware = {
async onResponse({ response }) {
const data = await response.clone();
if (!response.ok) {
const error = await data.json();
recordError(response.url, response.status, await error);
return undefined;
}
return response;
},
};

export const apiClient = createClient(import.meta.env.VITE_API_URL);
apiClient.use(errorMiddleware);
2 changes: 1 addition & 1 deletion src/api/controllers/TimetableApi.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { stringifyDate, getDateWithDayOffset } from './../../utils/date';
import { useTimetableStore } from './../../store/timetable';
import apiClient from '@/api/';
import { apiClient } from '../client';

interface GetLecturersParams {
query?: string;
Expand Down
2 changes: 1 addition & 1 deletion src/api/controllers/UserdataApi.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { apply, checkToken, showErrorToast } from './auth/decorators';
import { UserdataUpdateUser } from '@/models';
import apiClient from '@/api/';
import { apiClient } from '../client';

export class UserdataApi {
static getUser = apply(
Expand Down
2 changes: 1 addition & 1 deletion src/api/controllers/auth/AuthApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { LocalStorage, LocalStorageItem } from '@/models/LocalStorage';
import { UNKNOWN_DEVICE } from '@/models';

import router from '@/router';
import apiClient from '@/api/';
import { apiClient } from '../../client';

export enum UserInfo {
Groups = 'groups',
Expand Down
6 changes: 3 additions & 3 deletions src/api/controllers/auth/decorators.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import apiClient from '@/api/';
import { ApiError } from '@/api';
import { apiClient } from '../../client';
import { ToastType } from '@/models';
import router from '@/router';
import { useProfileStore } from '@/store/profile';
import { useToastStore } from '@/store/toast';
import { apiError } from '@/utils/errorHandler';

export type Func<R = any, FuncArgs extends any[] = any[]> = (...args: FuncArgs) => R;
type Decorator<F extends Func = Func, DecoratorArgs extends any[] = any[]> = Func<
Expand Down Expand Up @@ -44,7 +44,7 @@ export function showErrorToast<F extends Func>(
const response = await method(...args);
return response;
} catch (err) {
const error = err as apiError;
const error = err as ApiError;
if (error) {
toastStore.push({
title: error.ru ?? error.message,
Expand Down
23 changes: 3 additions & 20 deletions src/api/index.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,3 @@
export * from './controllers';
import { recordError } from '@/utils/errorHandler';
import { createClient } from '@profcomff/api-uilib';
import { type Middleware } from 'openapi-fetch';

const errorMiddleware: Middleware = {
async onResponse({ response }) {
const data = await response.clone();
if (!response.ok) {
const error = await data.json();
recordError(response.url, response.status, await error);
return undefined;
}
return response;
},
};

const apiClient = createClient(import.meta.env.VITE_API_URL);
apiClient.use(errorMiddleware);
export default apiClient;
export { apiClient } from './client';
export * from './types';
export * from './controllers';
11 changes: 11 additions & 0 deletions src/api/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export type ApiError = {
status: string;
message: string;
ru: string;
};

export interface ErrorInfo {
url: string;
status: number;
message: string;
}
2 changes: 1 addition & 1 deletion src/components/IrdomAuthButton.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script setup lang="ts">
import { onMounted, ref } from 'vue';
import { AuthMethodLink, AuthMethodName } from '@/models';
import apiClient from '@/api/';
import { apiClient } from '@/api/';

export interface AuthButton {
name: string;
Expand Down
2 changes: 1 addition & 1 deletion src/components/IrdomToolbar.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script setup lang="ts">
import { useRoute, useRouter } from 'vue-router';
import { useProfileStore } from '@/store/profile';
import apiClient from '@/api/';
import { apiClient } from '@/api/';

export interface ToolbarMenuItem {
name: string;
Expand Down
2 changes: 1 addition & 1 deletion src/router/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useToastStore } from '@/store/toast';
import { AuthApi } from '@/api';
import { UNKNOWN_DEVICE, LoginError } from '@/models';

import apiClient from '@/api/';
import { apiClient } from '@/api/';
import { isAuthMethod } from '@/utils/authMethodName';

export const authRoutes: RouteRecordRaw[] = [
Expand Down
2 changes: 1 addition & 1 deletion src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';
import { timetableRoutes, timetableHandler } from './timetable';
import AppsView from '@/views/apps/AppsView.vue';
import { useProfileStore } from '@/store/profile';
import apiClient from '@/api/';
import { apiClient } from '@/api/';

const routes: RouteRecordRaw[] = [
{
Expand Down
2 changes: 1 addition & 1 deletion src/router/profile.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import apiClient from '@/api';
import { apiClient } from '@/api';
import { RouteRecordRaw } from 'vue-router';

export const profileRoutes: RouteRecordRaw[] = [
Expand Down
2 changes: 1 addition & 1 deletion src/store/profile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { scopename } from './../models/ScopeName';
import { LocalStorage, LocalStorageItem } from '@/models/LocalStorage';
import { defineStore } from 'pinia';
import { computed, ref } from 'vue';
import apiClient from '@/api/';
import { apiClient } from '@/api/';

export const useProfileStore = defineStore('profile', () => {
const id = ref<number | null>(null);
Expand Down
29 changes: 0 additions & 29 deletions src/utils/errorHandler.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/views/admin/achievement/AchievementListView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import IrdomLayout from '@/components/IrdomLayout.vue';
import { scopename } from '@/models/ScopeName';
import { useToolbar } from '@/store/toolbar';

import apiClient from '@/api/';
import { apiClient } from '@/api/';

const toolbar = useToolbar();

Expand Down
2 changes: 1 addition & 1 deletion src/views/admin/achievement/AchievementRecieversView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { scopename } from '@/models/ScopeName';
import { useToolbar } from '@/store/toolbar';
import { getPictureUrl } from '@/utils/achievement';

import apiClient from '@/api/';
import { apiClient } from '@/api/';

const route = useRoute();
const toolbar = useToolbar();
Expand Down
2 changes: 1 addition & 1 deletion src/views/admin/achievement/AchievementRow.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script setup lang="ts">
import { AchievementGet } from '@/models';
import apiClient from '@/api/';
import { apiClient } from '@/api/';
import { ref, watch } from 'vue';
import { useRouter } from 'vue-router';
import { getPictureUrl } from '@/utils/achievement';
Expand Down
2 changes: 1 addition & 1 deletion src/views/admin/group/AdminGroupView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import ScopesTable from '../ScopesTable.vue';
import { onMounted, computed } from 'vue';
import { useRoute } from 'vue-router';
import { AuthApi } from '@/api';
import apiClient from '@/api/';
import { apiClient } from '@/api/';
import AccessRestricted from '@/components/AccessRestricted.vue';
import IrdomLayout from '@/components/IrdomLayout.vue';
import { scopename } from '@/models/ScopeName';
Expand Down
2 changes: 1 addition & 1 deletion src/views/admin/groups/AdminGroupsView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { useToolbar } from '@/store/toolbar';
import { useProfileStore } from '@/store/profile';
import { scopename } from '@/models/ScopeName';

import apiClient from '@/api/';
import { apiClient } from '@/api/';

const authStore = useAuthStore();
const toolbar = useToolbar();
Expand Down
2 changes: 1 addition & 1 deletion src/views/admin/groups/GroupTreeNode.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup lang="ts">
import apiClient from '@/api/';
import { apiClient } from '@/api/';
import { scopename } from '@/models/ScopeName';
import { StoreGroup, useAuthStore } from '@/store/auth';
import { useProfileStore } from '@/store/profile';
Expand Down
2 changes: 1 addition & 1 deletion src/views/admin/scopes/AdminScopesView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import AccessRestricted from '@/components/AccessRestricted.vue';
import { useAuthStore } from '@/store/auth';
import { useProfileStore } from '@/store/profile';
import { useToolbar } from '@/store/toolbar';
import apiClient from '@/api/';
import { apiClient } from '@/api/';

const authStore = useAuthStore();
const profileStore = useProfileStore();
Expand Down
2 changes: 1 addition & 1 deletion src/views/apps/ApplicationFrame.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useProfileStore } from '@/store/profile';
import FullscreenLoader from '@/components/FullscreenLoader.vue';
import { AuthApi } from '@/api/controllers/auth/AuthApi';
import { ServiceData } from '@/models';
import apiClient from '@/api/';
import { apiClient } from '@/api/';
import { msInHour } from '@/utils/time';
import { useAppsStore } from '@/store/apps';

Expand Down
2 changes: 1 addition & 1 deletion src/views/apps/AsyncContent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useProfileStore } from '@/store/profile';
import { useToastStore } from '@/store/toast';
import { RouterLink } from 'vue-router';

import apiClient from '@/api/';
import { apiClient } from '@/api/';

const appsStore = useAppsStore();
const profileStore = useProfileStore();
Expand Down
2 changes: 1 addition & 1 deletion src/views/auth/OauthRegisterView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import IrdomLayout from '@/components/IrdomLayout.vue';
import { useToolbar } from '@/store/toolbar';
import { useProfileStore } from '@/store/profile';
import { AuthMethodLink } from '@/models';
import apiClient from '@/api/';
import { apiClient } from '@/api/';

const router = useRouter();
const toolbar = useToolbar();
Expand Down
2 changes: 1 addition & 1 deletion src/views/profile/ProfileDeleteView.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script setup lang="ts">
import IrdomLayout from '@/components/IrdomLayout.vue';
import apiClient from '@/api';
import { apiClient } from '@/api';
import { useToastStore } from '@/store/toast';
import { useToolbar } from '@/store/toolbar';
import { useProfileStore } from '@/store/profile';
Expand Down
10 changes: 7 additions & 3 deletions src/views/profile/ProfileView.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script setup lang="ts">
import { onMounted, ref } from 'vue';
import Placeholder from '@/assets/profile_image_placeholder.webp';
import apiClient, { AuthApi, UserdataApi } from '@/api';
import { apiClient, AuthApi, UserdataApi } from '@/api';
import { useRouter, useRoute } from 'vue-router';
import { UserdataArray, UserdataCategoryName, UserdataParams } from '@/models';
import AchievementsSlider from './achievement/AchievementsSlider.vue';
Expand Down Expand Up @@ -191,7 +191,9 @@ onMounted(async () => {
color: var(--m-3-sys-light-outline, #79747e);
font-size: 14px;
font-weight: 900;
line-height: 16px; /* 114.286% */
line-height: 16px;

/* 114.286% */
letter-spacing: 0.5px;
margin-top: 11px;

Expand Down Expand Up @@ -239,7 +241,9 @@ onMounted(async () => {
color: #000;
font-size: 20px;
font-weight: 600;
line-height: 16px; /* 80% */
line-height: 16px;

/* 80% */
letter-spacing: 0.5px;
}
</style>
2 changes: 1 addition & 1 deletion src/views/profile/achievement/AchievementsSlider.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { onMounted, ref, Ref } from 'vue';
import { getPictureUrl } from '@/utils/achievement';
import AchievementElement from './AchievementsElement.vue';
import FullscreenLoader from '@/components/FullscreenLoader.vue';
import apiClient from '@/api/';
import { apiClient } from '@/api/';

const props = defineProps<{ userId: number }>();
const achievements: Ref<AchievementGet[]> = ref([]);
Expand Down
2 changes: 1 addition & 1 deletion src/views/profile/sessions/AsyncContent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import UAParser from 'ua-parser-js';

import { SessionInfo, Session } from '@/models';

import apiClient from '@/api/';
import { apiClient } from '@/api/';

import Apple from '@/assets/logo/Apple.svg';
import Desktop from '@/assets/logo/Desktop.svg';
Expand Down
2 changes: 1 addition & 1 deletion src/views/timetable/init/AsyncGroupsList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { StudyGroup } from '@/models';
import { computed } from 'vue';
import GroupsListItem from './GroupsListItem.vue';
import apiClient from '@/api/';
import { apiClient } from '@/api/';

const props = withDefaults(defineProps<{ query?: string }>(), {
query: '',
Expand Down
Loading