generated from VLADIMIR/template_frontend
Compare commits
3 Commits
bb8fca352a
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 606d515ade | |||
| 4174ad304a | |||
| 862c918981 |
Vendored
-1
File diff suppressed because one or more lines are too long
Vendored
+1
File diff suppressed because one or more lines are too long
+218
-176
File diff suppressed because one or more lines are too long
Vendored
+2
-2
@@ -5,8 +5,8 @@
|
|||||||
<link rel="icon" href="/favicon.ico">
|
<link rel="icon" href="/favicon.ico">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Вечерний детектив</title>
|
<title>Вечерний детектив</title>
|
||||||
<script type="module" crossorigin src="/assets/index-B54R2K0c.js"></script>
|
<script type="module" crossorigin src="/assets/index-CNblC4ZU.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-BdDl0UCc.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-BlFsLzpe.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
|||||||
@@ -115,6 +115,47 @@ service EveningDetectiveServer {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rpc DeleteAccount(DeleteAccountReq) returns (DeleteAccountRsp) {
|
||||||
|
option (google.api.http) = {
|
||||||
|
delete: "/api/auth/delete-account"
|
||||||
|
};
|
||||||
|
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||||
|
tags : "Регистрация и вход";
|
||||||
|
summary : "Удалить учётную запись и персональные данные";
|
||||||
|
description: "Удаляет учётную запись и персональные данные текущего пользователя (ст. 21 152-ФЗ). Требует заголовок X-Password с паролем учётной записи (подтверждение владельца; пароль не передаётся в URL).";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
rpc GetTerms(GetTermsReq) returns (GetTermsRsp) {
|
||||||
|
option (google.api.http) = {
|
||||||
|
get: "/api/terms"
|
||||||
|
};
|
||||||
|
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||||
|
tags : "Документы";
|
||||||
|
summary: "Получить текст Пользовательского соглашения (оферты)";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
rpc GetPrivacy(GetPrivacyReq) returns (GetPrivacyRsp) {
|
||||||
|
option (google.api.http) = {
|
||||||
|
get: "/api/privacy"
|
||||||
|
};
|
||||||
|
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||||
|
tags : "Документы";
|
||||||
|
summary: "Получить текст Политики конфиденциальности";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
rpc GetConsent(GetConsentReq) returns (GetConsentRsp) {
|
||||||
|
option (google.api.http) = {
|
||||||
|
get: "/api/consent"
|
||||||
|
};
|
||||||
|
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||||
|
tags : "Документы";
|
||||||
|
summary: "Получить текст Согласия на обработку персональных данных";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
rpc GetUsers(GetUsersReq) returns (GetUsersRsp) {
|
rpc GetUsers(GetUsersReq) returns (GetUsersRsp) {
|
||||||
option (google.api.http) = {
|
option (google.api.http) = {
|
||||||
get: "/api/users"
|
get: "/api/users"
|
||||||
@@ -324,6 +365,27 @@ service EveningDetectiveServer {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rpc DownloadScenarioArchive(DownloadScenarioArchiveReq) returns (google.api.HttpBody) {
|
||||||
|
option (google.api.http) = {
|
||||||
|
get: "/api/scenarios/{id}/archive"
|
||||||
|
};
|
||||||
|
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||||
|
tags : "Сценарии";
|
||||||
|
summary: "Скачать сценарий архивом (со всеми материалами и картинками)";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
rpc UploadScenarioArchive(google.api.HttpBody) returns (UploadScenarioArchiveRsp) {
|
||||||
|
option (google.api.http) = {
|
||||||
|
post: "/api/scenarios/archive"
|
||||||
|
body: "*"
|
||||||
|
};
|
||||||
|
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||||
|
tags : "Сценарии";
|
||||||
|
summary: "Создать сценарий из архива";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
rpc AddGame(AddGameReq) returns (AddGameRsp) {
|
rpc AddGame(AddGameReq) returns (AddGameRsp) {
|
||||||
option (google.api.http) = {
|
option (google.api.http) = {
|
||||||
post: "/api/games"
|
post: "/api/games"
|
||||||
@@ -527,6 +589,8 @@ message EchoRsp {
|
|||||||
message SignupReq {
|
message SignupReq {
|
||||||
string username = 1;
|
string username = 1;
|
||||||
string email = 2;
|
string email = 2;
|
||||||
|
bool accept_terms = 3;
|
||||||
|
bool accept_privacy = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message SignupRsp {
|
message SignupRsp {
|
||||||
@@ -562,6 +626,39 @@ message RefreshRsp {
|
|||||||
string refreshToken = 3;
|
string refreshToken = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Пароль подтверждает, что удаляет аккаунт его владелец, а не обладатель
|
||||||
|
// украденного access-токена (ст. 21 152-ФЗ). Передаётся HTTP-заголовком
|
||||||
|
// X-Password (пробрасывается матчером в cmd/evening_detective_server/main.go),
|
||||||
|
// чтобы креденшел не попадал в URL/query-параметры и логи.
|
||||||
|
message DeleteAccountReq {}
|
||||||
|
|
||||||
|
message DeleteAccountRsp {
|
||||||
|
string error = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Документы раздаются по постоянным URL, на которые ссылается сервис при
|
||||||
|
// фиксации акцептов соглашений (user_agreements) и форма регистрации.
|
||||||
|
message GetTermsReq {}
|
||||||
|
|
||||||
|
message GetTermsRsp {
|
||||||
|
string error = 1;
|
||||||
|
string text = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetPrivacyReq {}
|
||||||
|
|
||||||
|
message GetPrivacyRsp {
|
||||||
|
string error = 1;
|
||||||
|
string text = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetConsentReq {}
|
||||||
|
|
||||||
|
message GetConsentRsp {
|
||||||
|
string error = 1;
|
||||||
|
string text = 2;
|
||||||
|
}
|
||||||
|
|
||||||
message GetUsersReq {}
|
message GetUsersReq {}
|
||||||
|
|
||||||
message GetUsersRsp {
|
message GetUsersRsp {
|
||||||
@@ -771,6 +868,15 @@ message DeleteScenarioPlaceRsp {
|
|||||||
string error = 1;
|
string error = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message DownloadScenarioArchiveReq {
|
||||||
|
int32 id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UploadScenarioArchiveRsp {
|
||||||
|
string error = 1;
|
||||||
|
int32 id = 2;
|
||||||
|
}
|
||||||
|
|
||||||
message AddGameReq {
|
message AddGameReq {
|
||||||
string name = 1;
|
string name = 1;
|
||||||
string description = 2;
|
string description = 2;
|
||||||
|
|||||||
@@ -0,0 +1,103 @@
|
|||||||
|
import { useAuthStore } from '@/stores/auth'
|
||||||
|
|
||||||
|
import { getURL } from './generated/crabs/evening_detective_server/client'
|
||||||
|
|
||||||
|
export type DownloadArchiveResult = {
|
||||||
|
blob: Blob
|
||||||
|
filename: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type UploadArchiveResult = {
|
||||||
|
id: number | null
|
||||||
|
error: string | null
|
||||||
|
}
|
||||||
|
|
||||||
|
// Клиент для бинарных операций со сценарием (ZIP-архив). Сгенерированный
|
||||||
|
// HTTP-хендлер всегда парсит ответ как JSON, поэтому для архивов используем
|
||||||
|
// сырой fetch: скачивание отдаёт байты архива, загрузка принимает их напрямую.
|
||||||
|
export function getArchiveClient() {
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
return buildArchiveClient(authStore.refreshTokenAction, authStore.getToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildArchiveClient(
|
||||||
|
refreshTokens: () => Promise<boolean>,
|
||||||
|
getToken: () => string | null,
|
||||||
|
) {
|
||||||
|
async function request(path: string, init: RequestInit): Promise<Response> {
|
||||||
|
const headers: Record<string, string> = {}
|
||||||
|
const token = getToken()
|
||||||
|
if (token) {
|
||||||
|
headers['Authorization'] = `Bearer ${token}`
|
||||||
|
}
|
||||||
|
|
||||||
|
let response = await fetch(`${getURL()}/${path}`, {
|
||||||
|
...init,
|
||||||
|
headers: { ...headers, ...(init.headers as Record<string, string>) },
|
||||||
|
})
|
||||||
|
|
||||||
|
// Токен протух — обновляем и повторяем запрос один раз.
|
||||||
|
if (response.status == 401) {
|
||||||
|
await refreshTokens()
|
||||||
|
const newToken = getToken()
|
||||||
|
if (newToken) {
|
||||||
|
headers['Authorization'] = `Bearer ${newToken}`
|
||||||
|
}
|
||||||
|
response = await fetch(`${getURL()}/${path}`, {
|
||||||
|
...init,
|
||||||
|
headers: { ...headers, ...(init.headers as Record<string, string>) },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
|
async function downloadScenarioArchive(id: number): Promise<DownloadArchiveResult> {
|
||||||
|
const response = await request(`api/scenarios/${id}/archive`, { method: 'GET' })
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(await gatewayErrorMessage(response))
|
||||||
|
}
|
||||||
|
const blob = await response.blob()
|
||||||
|
const filename =
|
||||||
|
parseContentDispositionFilename(response.headers.get('Content-Disposition')) || `scenario-${id}.zip`
|
||||||
|
return { blob, filename }
|
||||||
|
}
|
||||||
|
|
||||||
|
async function uploadScenarioArchive(file: File): Promise<UploadArchiveResult> {
|
||||||
|
const contentType = file.type || 'application/zip'
|
||||||
|
const response = await request('api/scenarios/archive', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': contentType },
|
||||||
|
body: file,
|
||||||
|
})
|
||||||
|
|
||||||
|
const data = await response.json().catch(() => null)
|
||||||
|
if (!response.ok) {
|
||||||
|
return { id: null, error: data?.message || `Ошибка сервера (${response.status})` }
|
||||||
|
}
|
||||||
|
|
||||||
|
const error = typeof data?.error === 'string' && data.error !== '' ? data.error : null
|
||||||
|
return { id: typeof data?.id === 'number' ? data.id : null, error }
|
||||||
|
}
|
||||||
|
|
||||||
|
return { downloadScenarioArchive, uploadScenarioArchive }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Извлекает имя файла из Content-Disposition: attachment; filename="name.zip"
|
||||||
|
function parseContentDispositionFilename(value: string | null): string {
|
||||||
|
if (!value) {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
const match = value.match(/filename="?([^";]+)"?/i)
|
||||||
|
const filename = match ? match[1] : ''
|
||||||
|
return filename.replace(/[\\/:*?"<>|]/g, '_')
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ошибки grpc-gateway приходят JSON-объектом {"code": ..., "message": ...}
|
||||||
|
async function gatewayErrorMessage(response: Response): Promise<string> {
|
||||||
|
const data = await response.json().catch(() => null)
|
||||||
|
if (data && typeof data.message === 'string' && data.message !== '') {
|
||||||
|
return data.message
|
||||||
|
}
|
||||||
|
return `Ошибка сервера (${response.status})`
|
||||||
|
}
|
||||||
@@ -1,11 +1,17 @@
|
|||||||
import { createEveningDetectiveServerClient, type EveningDetectiveServer } from '.'
|
import { createEveningDetectiveServerClient, type EveningDetectiveServer } from '.'
|
||||||
|
|
||||||
export function buildClient(getToken?: () => string | null): EveningDetectiveServer {
|
export type ExtraHeadersProvider = () => Record<string, string> | null | undefined
|
||||||
return createEveningDetectiveServerClient(createHttpHandler(getToken))
|
|
||||||
|
export function buildClient(
|
||||||
|
getToken?: () => string | null,
|
||||||
|
getExtraHeaders?: ExtraHeadersProvider,
|
||||||
|
): EveningDetectiveServer {
|
||||||
|
return createEveningDetectiveServerClient(createHttpHandler(getToken, getExtraHeaders))
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createHttpHandler(
|
export function createHttpHandler(
|
||||||
getToken?: () => string | null,
|
getToken?: () => string | null,
|
||||||
|
getExtraHeaders?: ExtraHeadersProvider,
|
||||||
): (request: { path: string; method: string; body: string | null }) => Promise<unknown> {
|
): (request: { path: string; method: string; body: string | null }) => Promise<unknown> {
|
||||||
return async (request: { path: string; method: string; body: string | null }) => {
|
return async (request: { path: string; method: string; body: string | null }) => {
|
||||||
const baseURL = getURL()
|
const baseURL = getURL()
|
||||||
@@ -24,6 +30,12 @@ export function createHttpHandler(
|
|||||||
headers['Authorization'] = `Bearer ${token}`
|
headers['Authorization'] = `Bearer ${token}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Добавляем дополнительные заголовки (например, X-Password для удаления аккаунта)
|
||||||
|
const extraHeaders = getExtraHeaders?.()
|
||||||
|
if (extraHeaders) {
|
||||||
|
Object.assign(headers, extraHeaders)
|
||||||
|
}
|
||||||
|
|
||||||
// Делаем запрос
|
// Делаем запрос
|
||||||
const response = await fetch(url, {
|
const response = await fetch(url, {
|
||||||
method: request.method,
|
method: request.method,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// Code generated by protoc-gen-typescript-http. DO NOT EDIT.
|
// Code generated by protoc-gen-typescript-http. DO NOT EDIT.
|
||||||
|
/* eslint-disable camelcase */
|
||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
|
|
||||||
export type PingReq = {
|
export type PingReq = {
|
||||||
@@ -19,6 +19,8 @@ export type EchoRsp = {
|
|||||||
export type SignupReq = {
|
export type SignupReq = {
|
||||||
username: string | undefined;
|
username: string | undefined;
|
||||||
email: string | undefined;
|
email: string | undefined;
|
||||||
|
acceptTerms: boolean | undefined;
|
||||||
|
acceptPrivacy: boolean | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type SignupRsp = {
|
export type SignupRsp = {
|
||||||
@@ -54,6 +56,43 @@ export type RefreshRsp = {
|
|||||||
refreshToken: string | undefined;
|
refreshToken: string | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Пароль подтверждает, что удаляет аккаунт его владелец, а не обладатель
|
||||||
|
// украденного access-токена (ст. 21 152-ФЗ). Передаётся HTTP-заголовком
|
||||||
|
// X-Password (пробрасывается матчером в cmd/evening_detective_server/main.go),
|
||||||
|
// чтобы креденшел не попадал в URL/query-параметры и логи.
|
||||||
|
export type DeleteAccountReq = {
|
||||||
|
};
|
||||||
|
|
||||||
|
export type DeleteAccountRsp = {
|
||||||
|
error: string | undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Документы раздаются по постоянным URL, на которые ссылается сервис при
|
||||||
|
// фиксации акцептов соглашений (user_agreements) и форма регистрации.
|
||||||
|
export type GetTermsReq = {
|
||||||
|
};
|
||||||
|
|
||||||
|
export type GetTermsRsp = {
|
||||||
|
error: string | undefined;
|
||||||
|
text: string | undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type GetPrivacyReq = {
|
||||||
|
};
|
||||||
|
|
||||||
|
export type GetPrivacyRsp = {
|
||||||
|
error: string | undefined;
|
||||||
|
text: string | undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type GetConsentReq = {
|
||||||
|
};
|
||||||
|
|
||||||
|
export type GetConsentRsp = {
|
||||||
|
error: string | undefined;
|
||||||
|
text: string | undefined;
|
||||||
|
};
|
||||||
|
|
||||||
export type GetUsersReq = {
|
export type GetUsersReq = {
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -273,6 +312,15 @@ export type DeleteScenarioPlaceRsp = {
|
|||||||
error: string | undefined;
|
error: string | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type DownloadScenarioArchiveReq = {
|
||||||
|
id: number | undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type UploadScenarioArchiveRsp = {
|
||||||
|
error: string | undefined;
|
||||||
|
id: number | undefined;
|
||||||
|
};
|
||||||
|
|
||||||
export type AddGameReq = {
|
export type AddGameReq = {
|
||||||
name: string | undefined;
|
name: string | undefined;
|
||||||
description: string | undefined;
|
description: string | undefined;
|
||||||
@@ -456,6 +504,10 @@ export interface EveningDetectiveServer {
|
|||||||
RefreshPassword(request: RefreshPasswordReq): Promise<RefreshPasswordRsp>;
|
RefreshPassword(request: RefreshPasswordReq): Promise<RefreshPasswordRsp>;
|
||||||
Login(request: LoginReq): Promise<LoginRsp>;
|
Login(request: LoginReq): Promise<LoginRsp>;
|
||||||
Refresh(request: RefreshReq): Promise<RefreshRsp>;
|
Refresh(request: RefreshReq): Promise<RefreshRsp>;
|
||||||
|
DeleteAccount(request: DeleteAccountReq): Promise<DeleteAccountRsp>;
|
||||||
|
GetTerms(request: GetTermsReq): Promise<GetTermsRsp>;
|
||||||
|
GetPrivacy(request: GetPrivacyReq): Promise<GetPrivacyRsp>;
|
||||||
|
GetConsent(request: GetConsentReq): Promise<GetConsentRsp>;
|
||||||
GetUsers(request: GetUsersReq): Promise<GetUsersRsp>;
|
GetUsers(request: GetUsersReq): Promise<GetUsersRsp>;
|
||||||
GetUserById(request: GetUserByIdReq): Promise<GetUserByIdRsp>;
|
GetUserById(request: GetUserByIdReq): Promise<GetUserByIdRsp>;
|
||||||
GetMe(request: GetMeReq): Promise<GetMeRsp>;
|
GetMe(request: GetMeReq): Promise<GetMeRsp>;
|
||||||
@@ -476,6 +528,8 @@ export interface EveningDetectiveServer {
|
|||||||
AddScenarioPlace(request: AddScenarioPlaceReq): Promise<AddScenarioPlaceRsp>;
|
AddScenarioPlace(request: AddScenarioPlaceReq): Promise<AddScenarioPlaceRsp>;
|
||||||
UpdateScenarioPlace(request: UpdateScenarioPlaceReq): Promise<UpdateScenarioPlaceRsp>;
|
UpdateScenarioPlace(request: UpdateScenarioPlaceReq): Promise<UpdateScenarioPlaceRsp>;
|
||||||
DeleteScenarioPlace(request: DeleteScenarioPlaceReq): Promise<DeleteScenarioPlaceRsp>;
|
DeleteScenarioPlace(request: DeleteScenarioPlaceReq): Promise<DeleteScenarioPlaceRsp>;
|
||||||
|
DownloadScenarioArchive(request: DownloadScenarioArchiveReq): Promise<googleapi_HttpBody>;
|
||||||
|
UploadScenarioArchive(request: googleapi_HttpBody): Promise<UploadScenarioArchiveRsp>;
|
||||||
AddGame(request: AddGameReq): Promise<AddGameRsp>;
|
AddGame(request: AddGameReq): Promise<AddGameRsp>;
|
||||||
GetGames(request: GetGamesReq): Promise<GetGamesRsp>;
|
GetGames(request: GetGamesReq): Promise<GetGamesRsp>;
|
||||||
GetGame(request: GetGameReq): Promise<GetGameRsp>;
|
GetGame(request: GetGameReq): Promise<GetGameRsp>;
|
||||||
@@ -507,8 +561,8 @@ export function createEveningDetectiveServerClient(
|
|||||||
handler: RequestHandler
|
handler: RequestHandler
|
||||||
): EveningDetectiveServer {
|
): EveningDetectiveServer {
|
||||||
return {
|
return {
|
||||||
Ping(request) {
|
Ping(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
const path = `api/test/ping`;
|
const path = `api/test/ping`; // eslint-disable-line quotes
|
||||||
const body = null;
|
const body = null;
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -524,8 +578,8 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "Ping",
|
method: "Ping",
|
||||||
}) as Promise<PingRsp>;
|
}) as Promise<PingRsp>;
|
||||||
},
|
},
|
||||||
Echo(request) {
|
Echo(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
const path = `api/test/echo`;
|
const path = `api/test/echo`; // eslint-disable-line quotes
|
||||||
const body = null;
|
const body = null;
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
if (request.text) {
|
if (request.text) {
|
||||||
@@ -544,8 +598,8 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "Echo",
|
method: "Echo",
|
||||||
}) as Promise<EchoRsp>;
|
}) as Promise<EchoRsp>;
|
||||||
},
|
},
|
||||||
Signup(request) {
|
Signup(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
const path = `api/auth/signup`;
|
const path = `api/auth/signup`; // eslint-disable-line quotes
|
||||||
const body = JSON.stringify(request);
|
const body = JSON.stringify(request);
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -561,8 +615,8 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "Signup",
|
method: "Signup",
|
||||||
}) as Promise<SignupRsp>;
|
}) as Promise<SignupRsp>;
|
||||||
},
|
},
|
||||||
RefreshPassword(request) {
|
RefreshPassword(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
const path = `api/auth/refresh-password`;
|
const path = `api/auth/refresh-password`; // eslint-disable-line quotes
|
||||||
const body = JSON.stringify(request);
|
const body = JSON.stringify(request);
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -578,8 +632,8 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "RefreshPassword",
|
method: "RefreshPassword",
|
||||||
}) as Promise<RefreshPasswordRsp>;
|
}) as Promise<RefreshPasswordRsp>;
|
||||||
},
|
},
|
||||||
Login(request) {
|
Login(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
const path = `api/auth/login`;
|
const path = `api/auth/login`; // eslint-disable-line quotes
|
||||||
const body = JSON.stringify(request);
|
const body = JSON.stringify(request);
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -595,8 +649,8 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "Login",
|
method: "Login",
|
||||||
}) as Promise<LoginRsp>;
|
}) as Promise<LoginRsp>;
|
||||||
},
|
},
|
||||||
Refresh(request) {
|
Refresh(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
const path = `api/auth/refresh`;
|
const path = `api/auth/refresh`; // eslint-disable-line quotes
|
||||||
const body = JSON.stringify(request);
|
const body = JSON.stringify(request);
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -612,8 +666,76 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "Refresh",
|
method: "Refresh",
|
||||||
}) as Promise<RefreshRsp>;
|
}) as Promise<RefreshRsp>;
|
||||||
},
|
},
|
||||||
GetUsers(request) {
|
DeleteAccount(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
const path = `api/users`;
|
const path = `api/auth/delete-account`; // eslint-disable-line quotes
|
||||||
|
const body = null;
|
||||||
|
const queryParams: string[] = [];
|
||||||
|
let uri = path;
|
||||||
|
if (queryParams.length > 0) {
|
||||||
|
uri += `?${queryParams.join("&")}`
|
||||||
|
}
|
||||||
|
return handler({
|
||||||
|
path: uri,
|
||||||
|
method: "DELETE",
|
||||||
|
body,
|
||||||
|
}, {
|
||||||
|
service: "EveningDetectiveServer",
|
||||||
|
method: "DeleteAccount",
|
||||||
|
}) as Promise<DeleteAccountRsp>;
|
||||||
|
},
|
||||||
|
GetTerms(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
|
const path = `api/terms`; // eslint-disable-line quotes
|
||||||
|
const body = null;
|
||||||
|
const queryParams: string[] = [];
|
||||||
|
let uri = path;
|
||||||
|
if (queryParams.length > 0) {
|
||||||
|
uri += `?${queryParams.join("&")}`
|
||||||
|
}
|
||||||
|
return handler({
|
||||||
|
path: uri,
|
||||||
|
method: "GET",
|
||||||
|
body,
|
||||||
|
}, {
|
||||||
|
service: "EveningDetectiveServer",
|
||||||
|
method: "GetTerms",
|
||||||
|
}) as Promise<GetTermsRsp>;
|
||||||
|
},
|
||||||
|
GetPrivacy(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
|
const path = `api/privacy`; // eslint-disable-line quotes
|
||||||
|
const body = null;
|
||||||
|
const queryParams: string[] = [];
|
||||||
|
let uri = path;
|
||||||
|
if (queryParams.length > 0) {
|
||||||
|
uri += `?${queryParams.join("&")}`
|
||||||
|
}
|
||||||
|
return handler({
|
||||||
|
path: uri,
|
||||||
|
method: "GET",
|
||||||
|
body,
|
||||||
|
}, {
|
||||||
|
service: "EveningDetectiveServer",
|
||||||
|
method: "GetPrivacy",
|
||||||
|
}) as Promise<GetPrivacyRsp>;
|
||||||
|
},
|
||||||
|
GetConsent(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
|
const path = `api/consent`; // eslint-disable-line quotes
|
||||||
|
const body = null;
|
||||||
|
const queryParams: string[] = [];
|
||||||
|
let uri = path;
|
||||||
|
if (queryParams.length > 0) {
|
||||||
|
uri += `?${queryParams.join("&")}`
|
||||||
|
}
|
||||||
|
return handler({
|
||||||
|
path: uri,
|
||||||
|
method: "GET",
|
||||||
|
body,
|
||||||
|
}, {
|
||||||
|
service: "EveningDetectiveServer",
|
||||||
|
method: "GetConsent",
|
||||||
|
}) as Promise<GetConsentRsp>;
|
||||||
|
},
|
||||||
|
GetUsers(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
|
const path = `api/users`; // eslint-disable-line quotes
|
||||||
const body = null;
|
const body = null;
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -629,11 +751,11 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "GetUsers",
|
method: "GetUsers",
|
||||||
}) as Promise<GetUsersRsp>;
|
}) as Promise<GetUsersRsp>;
|
||||||
},
|
},
|
||||||
GetUserById(request) {
|
GetUserById(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
if (!request.id) {
|
if (!request.id) {
|
||||||
throw new Error("missing required field request.id");
|
throw new Error("missing required field request.id");
|
||||||
}
|
}
|
||||||
const path = `api/users/${request.id}`;
|
const path = `api/users/${request.id}`; // eslint-disable-line quotes
|
||||||
const body = null;
|
const body = null;
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -649,8 +771,8 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "GetUserById",
|
method: "GetUserById",
|
||||||
}) as Promise<GetUserByIdRsp>;
|
}) as Promise<GetUserByIdRsp>;
|
||||||
},
|
},
|
||||||
GetMe(request) {
|
GetMe(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
const path = `api/users/me`;
|
const path = `api/users/me`; // eslint-disable-line quotes
|
||||||
const body = null;
|
const body = null;
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -666,11 +788,11 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "GetMe",
|
method: "GetMe",
|
||||||
}) as Promise<GetMeRsp>;
|
}) as Promise<GetMeRsp>;
|
||||||
},
|
},
|
||||||
AddUserRole(request) {
|
AddUserRole(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
if (!request.id) {
|
if (!request.id) {
|
||||||
throw new Error("missing required field request.id");
|
throw new Error("missing required field request.id");
|
||||||
}
|
}
|
||||||
const path = `api/users/${request.id}/role/add`;
|
const path = `api/users/${request.id}/role/add`; // eslint-disable-line quotes
|
||||||
const body = JSON.stringify(request);
|
const body = JSON.stringify(request);
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -686,11 +808,11 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "AddUserRole",
|
method: "AddUserRole",
|
||||||
}) as Promise<AddUserRoleRsp>;
|
}) as Promise<AddUserRoleRsp>;
|
||||||
},
|
},
|
||||||
DeleteUserRole(request) {
|
DeleteUserRole(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
if (!request.id) {
|
if (!request.id) {
|
||||||
throw new Error("missing required field request.id");
|
throw new Error("missing required field request.id");
|
||||||
}
|
}
|
||||||
const path = `api/users/${request.id}/role/delete`;
|
const path = `api/users/${request.id}/role/delete`; // eslint-disable-line quotes
|
||||||
const body = JSON.stringify(request);
|
const body = JSON.stringify(request);
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -706,8 +828,8 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "DeleteUserRole",
|
method: "DeleteUserRole",
|
||||||
}) as Promise<DeleteUserRoleRsp>;
|
}) as Promise<DeleteUserRoleRsp>;
|
||||||
},
|
},
|
||||||
GetPermissions(request) {
|
GetPermissions(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
const path = `api/ui/permissions`;
|
const path = `api/ui/permissions`; // eslint-disable-line quotes
|
||||||
const body = null;
|
const body = null;
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -723,8 +845,8 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "GetPermissions",
|
method: "GetPermissions",
|
||||||
}) as Promise<GetPermissionsRsp>;
|
}) as Promise<GetPermissionsRsp>;
|
||||||
},
|
},
|
||||||
UploadFile(request) {
|
UploadFile(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
const path = `api/files/upload`;
|
const path = `api/files/upload`; // eslint-disable-line quotes
|
||||||
const body = JSON.stringify(request);
|
const body = JSON.stringify(request);
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -740,11 +862,11 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "UploadFile",
|
method: "UploadFile",
|
||||||
}) as Promise<UploadFileRsp>;
|
}) as Promise<UploadFileRsp>;
|
||||||
},
|
},
|
||||||
DownloadFile(request) {
|
DownloadFile(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
if (!request.filename) {
|
if (!request.filename) {
|
||||||
throw new Error("missing required field request.filename");
|
throw new Error("missing required field request.filename");
|
||||||
}
|
}
|
||||||
const path = `api/files/${request.filename}`;
|
const path = `api/files/${request.filename}`; // eslint-disable-line quotes
|
||||||
const body = null;
|
const body = null;
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -760,8 +882,8 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "DownloadFile",
|
method: "DownloadFile",
|
||||||
}) as Promise<googleapi_HttpBody>;
|
}) as Promise<googleapi_HttpBody>;
|
||||||
},
|
},
|
||||||
AddScenario(request) {
|
AddScenario(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
const path = `api/scenario`;
|
const path = `api/scenario`; // eslint-disable-line quotes
|
||||||
const body = JSON.stringify(request);
|
const body = JSON.stringify(request);
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -777,8 +899,8 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "AddScenario",
|
method: "AddScenario",
|
||||||
}) as Promise<AddScenarioRsp>;
|
}) as Promise<AddScenarioRsp>;
|
||||||
},
|
},
|
||||||
GetMyScenarios(request) {
|
GetMyScenarios(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
const path = `api/my-scenarios`;
|
const path = `api/my-scenarios`; // eslint-disable-line quotes
|
||||||
const body = null;
|
const body = null;
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -794,8 +916,8 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "GetMyScenarios",
|
method: "GetMyScenarios",
|
||||||
}) as Promise<GetMyScenariosRsp>;
|
}) as Promise<GetMyScenariosRsp>;
|
||||||
},
|
},
|
||||||
GetScenariosCatalog(request) {
|
GetScenariosCatalog(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
const path = `api/catalog`;
|
const path = `api/catalog`; // eslint-disable-line quotes
|
||||||
const body = null;
|
const body = null;
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -811,11 +933,11 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "GetScenariosCatalog",
|
method: "GetScenariosCatalog",
|
||||||
}) as Promise<GetScenariosCatalogRsp>;
|
}) as Promise<GetScenariosCatalogRsp>;
|
||||||
},
|
},
|
||||||
GetFullScenario(request) {
|
GetFullScenario(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
if (!request.id) {
|
if (!request.id) {
|
||||||
throw new Error("missing required field request.id");
|
throw new Error("missing required field request.id");
|
||||||
}
|
}
|
||||||
const path = `api/scenarios/${request.id}/full`;
|
const path = `api/scenarios/${request.id}/full`; // eslint-disable-line quotes
|
||||||
const body = null;
|
const body = null;
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -831,11 +953,11 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "GetFullScenario",
|
method: "GetFullScenario",
|
||||||
}) as Promise<GetScenarioRsp>;
|
}) as Promise<GetScenarioRsp>;
|
||||||
},
|
},
|
||||||
GetScenario(request) {
|
GetScenario(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
if (!request.id) {
|
if (!request.id) {
|
||||||
throw new Error("missing required field request.id");
|
throw new Error("missing required field request.id");
|
||||||
}
|
}
|
||||||
const path = `api/scenarios/${request.id}`;
|
const path = `api/scenarios/${request.id}`; // eslint-disable-line quotes
|
||||||
const body = null;
|
const body = null;
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -851,11 +973,11 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "GetScenario",
|
method: "GetScenario",
|
||||||
}) as Promise<GetScenarioRsp>;
|
}) as Promise<GetScenarioRsp>;
|
||||||
},
|
},
|
||||||
UpdateScenario(request) {
|
UpdateScenario(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
if (!request.id) {
|
if (!request.id) {
|
||||||
throw new Error("missing required field request.id");
|
throw new Error("missing required field request.id");
|
||||||
}
|
}
|
||||||
const path = `api/scenarios/${request.id}`;
|
const path = `api/scenarios/${request.id}`; // eslint-disable-line quotes
|
||||||
const body = JSON.stringify(request);
|
const body = JSON.stringify(request);
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -871,11 +993,11 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "UpdateScenario",
|
method: "UpdateScenario",
|
||||||
}) as Promise<UpdateScenarioRsp>;
|
}) as Promise<UpdateScenarioRsp>;
|
||||||
},
|
},
|
||||||
PublicScenario(request) {
|
PublicScenario(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
if (!request.id) {
|
if (!request.id) {
|
||||||
throw new Error("missing required field request.id");
|
throw new Error("missing required field request.id");
|
||||||
}
|
}
|
||||||
const path = `api/scenarios/${request.id}/public`;
|
const path = `api/scenarios/${request.id}/public`; // eslint-disable-line quotes
|
||||||
const body = JSON.stringify(request);
|
const body = JSON.stringify(request);
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -891,11 +1013,11 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "PublicScenario",
|
method: "PublicScenario",
|
||||||
}) as Promise<PublicScenarioRsp>;
|
}) as Promise<PublicScenarioRsp>;
|
||||||
},
|
},
|
||||||
DraftScenario(request) {
|
DraftScenario(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
if (!request.id) {
|
if (!request.id) {
|
||||||
throw new Error("missing required field request.id");
|
throw new Error("missing required field request.id");
|
||||||
}
|
}
|
||||||
const path = `api/scenarios/${request.id}/draft`;
|
const path = `api/scenarios/${request.id}/draft`; // eslint-disable-line quotes
|
||||||
const body = JSON.stringify(request);
|
const body = JSON.stringify(request);
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -911,11 +1033,11 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "DraftScenario",
|
method: "DraftScenario",
|
||||||
}) as Promise<DraftScenarioRsp>;
|
}) as Promise<DraftScenarioRsp>;
|
||||||
},
|
},
|
||||||
DeleteScenario(request) {
|
DeleteScenario(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
if (!request.id) {
|
if (!request.id) {
|
||||||
throw new Error("missing required field request.id");
|
throw new Error("missing required field request.id");
|
||||||
}
|
}
|
||||||
const path = `api/scenarios/${request.id}`;
|
const path = `api/scenarios/${request.id}`; // eslint-disable-line quotes
|
||||||
const body = null;
|
const body = null;
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -931,11 +1053,11 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "DeleteScenario",
|
method: "DeleteScenario",
|
||||||
}) as Promise<DeleteScenarioRsp>;
|
}) as Promise<DeleteScenarioRsp>;
|
||||||
},
|
},
|
||||||
AddScenarioPlace(request) {
|
AddScenarioPlace(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
if (!request.id) {
|
if (!request.id) {
|
||||||
throw new Error("missing required field request.id");
|
throw new Error("missing required field request.id");
|
||||||
}
|
}
|
||||||
const path = `api/scenarios/${request.id}/places`;
|
const path = `api/scenarios/${request.id}/places`; // eslint-disable-line quotes
|
||||||
const body = JSON.stringify(request);
|
const body = JSON.stringify(request);
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -951,14 +1073,14 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "AddScenarioPlace",
|
method: "AddScenarioPlace",
|
||||||
}) as Promise<AddScenarioPlaceRsp>;
|
}) as Promise<AddScenarioPlaceRsp>;
|
||||||
},
|
},
|
||||||
UpdateScenarioPlace(request) {
|
UpdateScenarioPlace(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
if (!request.id) {
|
if (!request.id) {
|
||||||
throw new Error("missing required field request.id");
|
throw new Error("missing required field request.id");
|
||||||
}
|
}
|
||||||
if (!request.code) {
|
if (!request.code) {
|
||||||
throw new Error("missing required field request.code");
|
throw new Error("missing required field request.code");
|
||||||
}
|
}
|
||||||
const path = `api/scenarios/${request.id}/places/${request.code}`;
|
const path = `api/scenarios/${request.id}/places/${request.code}`; // eslint-disable-line quotes
|
||||||
const body = JSON.stringify(request);
|
const body = JSON.stringify(request);
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -974,14 +1096,14 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "UpdateScenarioPlace",
|
method: "UpdateScenarioPlace",
|
||||||
}) as Promise<UpdateScenarioPlaceRsp>;
|
}) as Promise<UpdateScenarioPlaceRsp>;
|
||||||
},
|
},
|
||||||
DeleteScenarioPlace(request) {
|
DeleteScenarioPlace(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
if (!request.id) {
|
if (!request.id) {
|
||||||
throw new Error("missing required field request.id");
|
throw new Error("missing required field request.id");
|
||||||
}
|
}
|
||||||
if (!request.code) {
|
if (!request.code) {
|
||||||
throw new Error("missing required field request.code");
|
throw new Error("missing required field request.code");
|
||||||
}
|
}
|
||||||
const path = `api/scenarios/${request.id}/places/${request.code}`;
|
const path = `api/scenarios/${request.id}/places/${request.code}`; // eslint-disable-line quotes
|
||||||
const body = null;
|
const body = null;
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -997,8 +1119,45 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "DeleteScenarioPlace",
|
method: "DeleteScenarioPlace",
|
||||||
}) as Promise<DeleteScenarioPlaceRsp>;
|
}) as Promise<DeleteScenarioPlaceRsp>;
|
||||||
},
|
},
|
||||||
AddGame(request) {
|
DownloadScenarioArchive(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
const path = `api/games`;
|
if (!request.id) {
|
||||||
|
throw new Error("missing required field request.id");
|
||||||
|
}
|
||||||
|
const path = `api/scenarios/${request.id}/archive`; // eslint-disable-line quotes
|
||||||
|
const body = null;
|
||||||
|
const queryParams: string[] = [];
|
||||||
|
let uri = path;
|
||||||
|
if (queryParams.length > 0) {
|
||||||
|
uri += `?${queryParams.join("&")}`
|
||||||
|
}
|
||||||
|
return handler({
|
||||||
|
path: uri,
|
||||||
|
method: "GET",
|
||||||
|
body,
|
||||||
|
}, {
|
||||||
|
service: "EveningDetectiveServer",
|
||||||
|
method: "DownloadScenarioArchive",
|
||||||
|
}) as Promise<googleapi_HttpBody>;
|
||||||
|
},
|
||||||
|
UploadScenarioArchive(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
|
const path = `api/scenarios/archive`; // eslint-disable-line quotes
|
||||||
|
const body = JSON.stringify(request);
|
||||||
|
const queryParams: string[] = [];
|
||||||
|
let uri = path;
|
||||||
|
if (queryParams.length > 0) {
|
||||||
|
uri += `?${queryParams.join("&")}`
|
||||||
|
}
|
||||||
|
return handler({
|
||||||
|
path: uri,
|
||||||
|
method: "POST",
|
||||||
|
body,
|
||||||
|
}, {
|
||||||
|
service: "EveningDetectiveServer",
|
||||||
|
method: "UploadScenarioArchive",
|
||||||
|
}) as Promise<UploadScenarioArchiveRsp>;
|
||||||
|
},
|
||||||
|
AddGame(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
|
const path = `api/games`; // eslint-disable-line quotes
|
||||||
const body = JSON.stringify(request);
|
const body = JSON.stringify(request);
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -1014,8 +1173,8 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "AddGame",
|
method: "AddGame",
|
||||||
}) as Promise<AddGameRsp>;
|
}) as Promise<AddGameRsp>;
|
||||||
},
|
},
|
||||||
GetGames(request) {
|
GetGames(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
const path = `api/games`;
|
const path = `api/games`; // eslint-disable-line quotes
|
||||||
const body = null;
|
const body = null;
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -1031,11 +1190,11 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "GetGames",
|
method: "GetGames",
|
||||||
}) as Promise<GetGamesRsp>;
|
}) as Promise<GetGamesRsp>;
|
||||||
},
|
},
|
||||||
GetGame(request) {
|
GetGame(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
if (!request.id) {
|
if (!request.id) {
|
||||||
throw new Error("missing required field request.id");
|
throw new Error("missing required field request.id");
|
||||||
}
|
}
|
||||||
const path = `api/games/${request.id}`;
|
const path = `api/games/${request.id}`; // eslint-disable-line quotes
|
||||||
const body = null;
|
const body = null;
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -1051,11 +1210,11 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "GetGame",
|
method: "GetGame",
|
||||||
}) as Promise<GetGameRsp>;
|
}) as Promise<GetGameRsp>;
|
||||||
},
|
},
|
||||||
UpdateGame(request) {
|
UpdateGame(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
if (!request.id) {
|
if (!request.id) {
|
||||||
throw new Error("missing required field request.id");
|
throw new Error("missing required field request.id");
|
||||||
}
|
}
|
||||||
const path = `api/games/${request.id}`;
|
const path = `api/games/${request.id}`; // eslint-disable-line quotes
|
||||||
const body = JSON.stringify(request);
|
const body = JSON.stringify(request);
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -1071,11 +1230,11 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "UpdateGame",
|
method: "UpdateGame",
|
||||||
}) as Promise<UpdateGameRsp>;
|
}) as Promise<UpdateGameRsp>;
|
||||||
},
|
},
|
||||||
StartGame(request) {
|
StartGame(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
if (!request.id) {
|
if (!request.id) {
|
||||||
throw new Error("missing required field request.id");
|
throw new Error("missing required field request.id");
|
||||||
}
|
}
|
||||||
const path = `api/games/${request.id}/start`;
|
const path = `api/games/${request.id}/start`; // eslint-disable-line quotes
|
||||||
const body = JSON.stringify(request);
|
const body = JSON.stringify(request);
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -1091,11 +1250,11 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "StartGame",
|
method: "StartGame",
|
||||||
}) as Promise<StartGameRsp>;
|
}) as Promise<StartGameRsp>;
|
||||||
},
|
},
|
||||||
PauseGame(request) {
|
PauseGame(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
if (!request.id) {
|
if (!request.id) {
|
||||||
throw new Error("missing required field request.id");
|
throw new Error("missing required field request.id");
|
||||||
}
|
}
|
||||||
const path = `api/games/${request.id}/pause`;
|
const path = `api/games/${request.id}/pause`; // eslint-disable-line quotes
|
||||||
const body = JSON.stringify(request);
|
const body = JSON.stringify(request);
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -1111,11 +1270,11 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "PauseGame",
|
method: "PauseGame",
|
||||||
}) as Promise<PauseGameRsp>;
|
}) as Promise<PauseGameRsp>;
|
||||||
},
|
},
|
||||||
PlayGame(request) {
|
PlayGame(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
if (!request.id) {
|
if (!request.id) {
|
||||||
throw new Error("missing required field request.id");
|
throw new Error("missing required field request.id");
|
||||||
}
|
}
|
||||||
const path = `api/games/${request.id}/play`;
|
const path = `api/games/${request.id}/play`; // eslint-disable-line quotes
|
||||||
const body = JSON.stringify(request);
|
const body = JSON.stringify(request);
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -1131,11 +1290,11 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "PlayGame",
|
method: "PlayGame",
|
||||||
}) as Promise<PlayGameRsp>;
|
}) as Promise<PlayGameRsp>;
|
||||||
},
|
},
|
||||||
FinishGame(request) {
|
FinishGame(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
if (!request.id) {
|
if (!request.id) {
|
||||||
throw new Error("missing required field request.id");
|
throw new Error("missing required field request.id");
|
||||||
}
|
}
|
||||||
const path = `api/games/${request.id}/finish`;
|
const path = `api/games/${request.id}/finish`; // eslint-disable-line quotes
|
||||||
const body = JSON.stringify(request);
|
const body = JSON.stringify(request);
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -1151,11 +1310,11 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "FinishGame",
|
method: "FinishGame",
|
||||||
}) as Promise<FinishGameRsp>;
|
}) as Promise<FinishGameRsp>;
|
||||||
},
|
},
|
||||||
ResetGame(request) {
|
ResetGame(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
if (!request.id) {
|
if (!request.id) {
|
||||||
throw new Error("missing required field request.id");
|
throw new Error("missing required field request.id");
|
||||||
}
|
}
|
||||||
const path = `api/games/${request.id}/reset`;
|
const path = `api/games/${request.id}/reset`; // eslint-disable-line quotes
|
||||||
const body = JSON.stringify(request);
|
const body = JSON.stringify(request);
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -1171,11 +1330,11 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "ResetGame",
|
method: "ResetGame",
|
||||||
}) as Promise<ResetGameRsp>;
|
}) as Promise<ResetGameRsp>;
|
||||||
},
|
},
|
||||||
DeleteGame(request) {
|
DeleteGame(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
if (!request.id) {
|
if (!request.id) {
|
||||||
throw new Error("missing required field request.id");
|
throw new Error("missing required field request.id");
|
||||||
}
|
}
|
||||||
const path = `api/games/${request.id}`;
|
const path = `api/games/${request.id}`; // eslint-disable-line quotes
|
||||||
const body = null;
|
const body = null;
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -1191,8 +1350,8 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "DeleteGame",
|
method: "DeleteGame",
|
||||||
}) as Promise<DeleteGameRsp>;
|
}) as Promise<DeleteGameRsp>;
|
||||||
},
|
},
|
||||||
AddTeam(request) {
|
AddTeam(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
const path = `api/teams`;
|
const path = `api/teams`; // eslint-disable-line quotes
|
||||||
const body = JSON.stringify(request);
|
const body = JSON.stringify(request);
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -1208,11 +1367,11 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "AddTeam",
|
method: "AddTeam",
|
||||||
}) as Promise<AddTeamRsp>;
|
}) as Promise<AddTeamRsp>;
|
||||||
},
|
},
|
||||||
UpdateTeam(request) {
|
UpdateTeam(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
if (!request.id) {
|
if (!request.id) {
|
||||||
throw new Error("missing required field request.id");
|
throw new Error("missing required field request.id");
|
||||||
}
|
}
|
||||||
const path = `api/teams/${request.id}`;
|
const path = `api/teams/${request.id}`; // eslint-disable-line quotes
|
||||||
const body = JSON.stringify(request);
|
const body = JSON.stringify(request);
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -1228,11 +1387,11 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "UpdateTeam",
|
method: "UpdateTeam",
|
||||||
}) as Promise<UpdateTeamRsp>;
|
}) as Promise<UpdateTeamRsp>;
|
||||||
},
|
},
|
||||||
DeleteTeam(request) {
|
DeleteTeam(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
if (!request.id) {
|
if (!request.id) {
|
||||||
throw new Error("missing required field request.id");
|
throw new Error("missing required field request.id");
|
||||||
}
|
}
|
||||||
const path = `api/teams/${request.id}`;
|
const path = `api/teams/${request.id}`; // eslint-disable-line quotes
|
||||||
const body = null;
|
const body = null;
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -1248,11 +1407,11 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "DeleteTeam",
|
method: "DeleteTeam",
|
||||||
}) as Promise<DeleteTeamRsp>;
|
}) as Promise<DeleteTeamRsp>;
|
||||||
},
|
},
|
||||||
GiveTeamApplications(request) {
|
GiveTeamApplications(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
if (!request.id) {
|
if (!request.id) {
|
||||||
throw new Error("missing required field request.id");
|
throw new Error("missing required field request.id");
|
||||||
}
|
}
|
||||||
const path = `api/teams/${request.id}/applications`;
|
const path = `api/teams/${request.id}/applications`; // eslint-disable-line quotes
|
||||||
const body = JSON.stringify(request);
|
const body = JSON.stringify(request);
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -1268,11 +1427,11 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "GiveTeamApplications",
|
method: "GiveTeamApplications",
|
||||||
}) as Promise<GiveTeamApplicationsRsp>;
|
}) as Promise<GiveTeamApplicationsRsp>;
|
||||||
},
|
},
|
||||||
GetTeamStory(request) {
|
GetTeamStory(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
if (!request.id) {
|
if (!request.id) {
|
||||||
throw new Error("missing required field request.id");
|
throw new Error("missing required field request.id");
|
||||||
}
|
}
|
||||||
const path = `api/teams/${request.id}/story`;
|
const path = `api/teams/${request.id}/story`; // eslint-disable-line quotes
|
||||||
const body = null;
|
const body = null;
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
if (request.password) {
|
if (request.password) {
|
||||||
@@ -1291,11 +1450,11 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "GetTeamStory",
|
method: "GetTeamStory",
|
||||||
}) as Promise<GetTeamStoryRsp>;
|
}) as Promise<GetTeamStoryRsp>;
|
||||||
},
|
},
|
||||||
AddTeamAction(request) {
|
AddTeamAction(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
if (!request.id) {
|
if (!request.id) {
|
||||||
throw new Error("missing required field request.id");
|
throw new Error("missing required field request.id");
|
||||||
}
|
}
|
||||||
const path = `api/teams/${request.id}/actions`;
|
const path = `api/teams/${request.id}/actions`; // eslint-disable-line quotes
|
||||||
const body = JSON.stringify(request);
|
const body = JSON.stringify(request);
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
@@ -1311,11 +1470,11 @@ export function createEveningDetectiveServerClient(
|
|||||||
method: "AddTeamAction",
|
method: "AddTeamAction",
|
||||||
}) as Promise<AddTeamActionRsp>;
|
}) as Promise<AddTeamActionRsp>;
|
||||||
},
|
},
|
||||||
DeleteLastTeamAction(request) {
|
DeleteLastTeamAction(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
if (!request.id) {
|
if (!request.id) {
|
||||||
throw new Error("missing required field request.id");
|
throw new Error("missing required field request.id");
|
||||||
}
|
}
|
||||||
const path = `api/teams/${request.id}/last-actions`;
|
const path = `api/teams/${request.id}/last-actions`; // eslint-disable-line quotes
|
||||||
const body = null;
|
const body = null;
|
||||||
const queryParams: string[] = [];
|
const queryParams: string[] = [];
|
||||||
let uri = path;
|
let uri = path;
|
||||||
|
|||||||
@@ -0,0 +1,173 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { NAlert, NSpin } from 'naive-ui'
|
||||||
|
import { onMounted, ref } from 'vue'
|
||||||
|
import { RouterLink } from 'vue-router'
|
||||||
|
|
||||||
|
import { getAuthClient } from '@/api/auth_client'
|
||||||
|
import HeaderText from '@/components/HeaderText.vue'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
kind: 'terms' | 'privacy' | 'consent'
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const titles: Record<string, string> = {
|
||||||
|
terms: 'Пользовательское соглашение',
|
||||||
|
privacy: 'Политика конфиденциальности',
|
||||||
|
consent: 'Согласие на обработку персональных данных',
|
||||||
|
}
|
||||||
|
|
||||||
|
const text = ref('')
|
||||||
|
const loading = ref(true)
|
||||||
|
const error = ref('')
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
const client = getAuthClient()
|
||||||
|
const fetchers = {
|
||||||
|
terms: () => client.GetTerms({}),
|
||||||
|
privacy: () => client.GetPrivacy({}),
|
||||||
|
consent: () => client.GetConsent({}),
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await fetchers[props.kind]()
|
||||||
|
if (res.error) {
|
||||||
|
error.value = res.error
|
||||||
|
} else {
|
||||||
|
text.value = res.text || ''
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
error.value = err instanceof Error ? err.message : 'Не удалось загрузить документ'
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="center-block-custom">
|
||||||
|
<div class="width700 doc-page">
|
||||||
|
<h1 class="doc-title">
|
||||||
|
<HeaderText>{{ titles[props.kind] }}</HeaderText>
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<div v-if="loading" class="doc-loading">
|
||||||
|
<n-spin size="large" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<n-alert v-else-if="error" type="error" :show-icon="false" class="doc-error">
|
||||||
|
{{ error }}
|
||||||
|
</n-alert>
|
||||||
|
|
||||||
|
<div v-else class="paper-block">
|
||||||
|
<div class="paper">
|
||||||
|
<p class="doc-text">{{ text }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="paper-shadow paper-shadow-left"></div>
|
||||||
|
<div class="paper-shadow paper-shadow-right"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="docs-links">
|
||||||
|
Смотрите также:
|
||||||
|
<RouterLink to="/user-agreement" class="docs-link">Пользовательское соглашение</RouterLink>
|
||||||
|
·
|
||||||
|
<RouterLink to="/privacy-policy" class="docs-link">Политика конфиденциальности</RouterLink>
|
||||||
|
·
|
||||||
|
<RouterLink to="/consent" class="docs-link">Согласие на обработку персональных данных</RouterLink>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.doc-page {
|
||||||
|
padding-top: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doc-title {
|
||||||
|
margin: 0 0 24px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doc-loading {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 80px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doc-error {
|
||||||
|
margin: 0 auto;
|
||||||
|
max-width: 600px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.paper-block {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.paper {
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
padding: 32px 28px;
|
||||||
|
border-radius: 3px;
|
||||||
|
background-image: url('@/assets/images/paper_white.jpg');
|
||||||
|
background-size: cover;
|
||||||
|
color: #1d1d1d;
|
||||||
|
box-shadow: 0 0 12px rgb(0 0 0 / 70%);
|
||||||
|
max-height: 60vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
scrollbar-width: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.paper::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doc-text {
|
||||||
|
font-family: 'font_old_typer';
|
||||||
|
font-size: 17px;
|
||||||
|
line-height: 1.65;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-break: break-word;
|
||||||
|
text-align: justify;
|
||||||
|
}
|
||||||
|
|
||||||
|
.paper-shadow {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border-radius: 3px;
|
||||||
|
background-image: url('@/assets/images/paper_white.jpg');
|
||||||
|
background-size: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.paper-shadow-left {
|
||||||
|
left: 0;
|
||||||
|
transform: rotate(-2.2deg);
|
||||||
|
filter: brightness(60%);
|
||||||
|
box-shadow: 0 0 10px rgb(0 0 0 / 60%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.paper-shadow-right {
|
||||||
|
right: 0;
|
||||||
|
transform: rotate(2.2deg);
|
||||||
|
filter: brightness(75%);
|
||||||
|
box-shadow: 0 0 10px rgb(0 0 0 / 60%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.docs-links {
|
||||||
|
margin-top: 28px;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 15px;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.docs-link {
|
||||||
|
color: #45aa89;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.docs-link:hover {
|
||||||
|
color: #63e2b7;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -24,7 +24,8 @@ const message = useMessage()
|
|||||||
const username = ref('')
|
const username = ref('')
|
||||||
const email = ref('')
|
const email = ref('')
|
||||||
const password = ref('')
|
const password = ref('')
|
||||||
const approval = ref(false)
|
const acceptTerms = ref(false)
|
||||||
|
const acceptPrivacy = ref(false)
|
||||||
|
|
||||||
const options = computed(() => {
|
const options = computed(() => {
|
||||||
return ['@mail.ru', '@yandex.ru', '@gmail.com'].map((suffix) => {
|
return ['@mail.ru', '@yandex.ru', '@gmail.com'].map((suffix) => {
|
||||||
@@ -48,15 +49,22 @@ async function signin() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function signup() {
|
async function signup() {
|
||||||
if (!approval.value) {
|
if (!acceptTerms.value || !acceptPrivacy.value) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const res = await authStore.signup(username.value, email.value)
|
const res = await authStore.signup(
|
||||||
|
username.value,
|
||||||
|
email.value,
|
||||||
|
acceptTerms.value,
|
||||||
|
acceptPrivacy.value,
|
||||||
|
)
|
||||||
if (!res && authStore.error != null) {
|
if (!res && authStore.error != null) {
|
||||||
message.error(authStore.error)
|
message.error(authStore.error)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
message.info('Пароль отправлен на почту')
|
message.info('Пароль отправлен на почту')
|
||||||
|
acceptTerms.value = false
|
||||||
|
acceptPrivacy.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
async function sendNewPassword() {
|
async function sendNewPassword() {
|
||||||
@@ -101,16 +109,23 @@ async function sendNewPassword() {
|
|||||||
autocomplete: 'disabled',
|
autocomplete: 'disabled',
|
||||||
}" :options="options" placeholder="detective@mail.ru" clearable />
|
}" :options="options" placeholder="detective@mail.ru" clearable />
|
||||||
<div class="form-label">
|
<div class="form-label">
|
||||||
<n-checkbox v-model:checked="approval">
|
<n-checkbox v-model:checked="acceptTerms">
|
||||||
Я согласен с
|
Я принимаю условия
|
||||||
<a href="/user-agreement" target="_blank" class="docs-link">пользовательским соглашением</a><br />
|
<a href="/user-agreement" target="_blank" class="docs-link">пользовательского соглашения</a>
|
||||||
и
|
</n-checkbox>
|
||||||
<a href="/privacy-policy" target="_blank" class="docs-link">соглашением о персональных данных</a>
|
</div>
|
||||||
|
<div class="form-label">
|
||||||
|
<n-checkbox v-model:checked="acceptPrivacy">
|
||||||
|
Я даю согласие на обработку
|
||||||
|
<a href="/privacy-policy" target="_blank" class="docs-link">персональных данных</a>
|
||||||
</n-checkbox>
|
</n-checkbox>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-button-wrapper">
|
<div class="form-button-wrapper">
|
||||||
<div class="form-label">
|
<div class="form-label">
|
||||||
<n-button @click="signup" :disabled="username.length == 0 || password.length == 0 || !approval">
|
<n-button
|
||||||
|
@click="signup"
|
||||||
|
:disabled="username.length == 0 || email.length == 0 || !acceptTerms || !acceptPrivacy"
|
||||||
|
>
|
||||||
<span v-if="!authStore.isLoading"> Регистрация </span>
|
<span v-if="!authStore.isLoading"> Регистрация </span>
|
||||||
<span v-else> Подождите... </span>
|
<span v-else> Подождите... </span>
|
||||||
</n-button>
|
</n-button>
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { NAlert } from 'naive-ui'
|
import { NAlert, NButton, NInput, NModal, useMessage } from 'naive-ui'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
|
||||||
import { getAuthClient } from '@/api/auth_client'
|
import { getAuthClient } from '@/api/auth_client'
|
||||||
import HeaderMenu from '@/components/HeaderMenu.vue'
|
import HeaderMenu from '@/components/HeaderMenu.vue'
|
||||||
import { useAuthStore } from '@/stores/auth'
|
import { useAuthStore } from '@/stores/auth'
|
||||||
|
|
||||||
const authStore = useAuthStore()
|
const authStore = useAuthStore()
|
||||||
|
const router = useRouter()
|
||||||
|
const message = useMessage()
|
||||||
const client = getAuthClient()
|
const client = getAuthClient()
|
||||||
|
|
||||||
const permissions = ref<string[]>([])
|
const permissions = ref<string[]>([])
|
||||||
@@ -208,6 +211,22 @@ function getDetectiveTip(): Tip {
|
|||||||
|
|
||||||
const tip = getDetectiveTip()
|
const tip = getDetectiveTip()
|
||||||
|
|
||||||
|
// ===== Удаление аккаунта =====
|
||||||
|
const showDeleteDialog = ref(false)
|
||||||
|
const deletePassword = ref('')
|
||||||
|
const deleteError = ref('')
|
||||||
|
|
||||||
|
async function confirmDeleteAccount() {
|
||||||
|
deleteError.value = ''
|
||||||
|
const res = await authStore.deleteAccount(deletePassword.value)
|
||||||
|
if (!res) {
|
||||||
|
deleteError.value = authStore.error || 'Не удалось удалить аккаунт'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
message.success('Аккаунт и персональные данные удалены')
|
||||||
|
showDeleteDialog.value = false
|
||||||
|
router.push('/login')
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -218,10 +237,93 @@ const tip = getDetectiveTip()
|
|||||||
</n-alert>
|
</n-alert>
|
||||||
|
|
||||||
<p>Доброго времени суток, {{ authStore.username }}.</p>
|
<p>Доброго времени суток, {{ authStore.username }}.</p>
|
||||||
|
|
||||||
|
<div class="danger-zone">
|
||||||
|
<div class="danger-zone-text">
|
||||||
|
<div class="danger-zone-title">Удаление аккаунта</div>
|
||||||
|
<div class="danger-zone-hint">
|
||||||
|
Удаление необратимо: аккаунт и все персональные данные будут стёрты (ст. 21 152-ФЗ).
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<n-button type="error" ghost @click="showDeleteDialog = true">Удалить аккаунт</n-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<n-modal
|
||||||
|
v-model:show="showDeleteDialog"
|
||||||
|
preset="card"
|
||||||
|
title="Удаление аккаунта"
|
||||||
|
class="delete-modal"
|
||||||
|
>
|
||||||
|
<p class="delete-modal-text">
|
||||||
|
Это действие необратимо. Для подтверждения удаления введите пароль от учётной записи —
|
||||||
|
он понадобится, чтобы убедиться, что аккаунт удаляет его владелец.
|
||||||
|
</p>
|
||||||
|
<n-input
|
||||||
|
v-model:value="deletePassword"
|
||||||
|
type="password"
|
||||||
|
placeholder="Пароль для подтверждения"
|
||||||
|
@keyup.enter="confirmDeleteAccount"
|
||||||
|
/>
|
||||||
|
<p v-if="deleteError" class="delete-modal-error">{{ deleteError }}</p>
|
||||||
|
<div class="delete-modal-buttons">
|
||||||
|
<n-button @click="showDeleteDialog = false">Отмена</n-button>
|
||||||
|
<n-button
|
||||||
|
type="error"
|
||||||
|
:disabled="deletePassword.length == 0"
|
||||||
|
:loading="authStore.isLoading"
|
||||||
|
@click="confirmDeleteAccount"
|
||||||
|
>
|
||||||
|
Удалить навсегда
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
</n-modal>
|
||||||
|
|
||||||
<HeaderMenu active="office" />
|
<HeaderMenu active="office" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped>
|
||||||
|
.danger-zone {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 16px;
|
||||||
|
margin-top: 40px;
|
||||||
|
padding: 20px;
|
||||||
|
background-color: #222;
|
||||||
|
border: 1px solid rgb(224 108 117 / 40%);
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.danger-zone-title {
|
||||||
|
font-size: 17px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #e06c75;
|
||||||
|
}
|
||||||
|
|
||||||
|
.danger-zone-hint {
|
||||||
|
margin-top: 6px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete-modal-text {
|
||||||
|
margin: 0 0 16px;
|
||||||
|
line-height: 1.5;
|
||||||
|
color: #bbb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete-modal-error {
|
||||||
|
margin: 12px 0 0;
|
||||||
|
color: #e06c75;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete-modal-buttons {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 12px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { NAlert, NCard, NFlex, NInput, NModal, NSpace, NTag, NText, NUpload, NUp
|
|||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
|
|
||||||
|
import { getArchiveClient } from '@/api/archive_client'
|
||||||
import { getAuthClient } from '@/api/auth_client'
|
import { getAuthClient } from '@/api/auth_client'
|
||||||
import type { Place, Scenario } from '@/api/generated/crabs/evening_detective_server'
|
import type { Place, Scenario } from '@/api/generated/crabs/evening_detective_server'
|
||||||
import HeaderMenu from '@/components/HeaderMenu.vue'
|
import HeaderMenu from '@/components/HeaderMenu.vue'
|
||||||
@@ -15,12 +16,14 @@ import { useAuthStore } from '@/stores/auth'
|
|||||||
|
|
||||||
const authStore = useAuthStore()
|
const authStore = useAuthStore()
|
||||||
const client = getAuthClient()
|
const client = getAuthClient()
|
||||||
|
const archiveClient = getArchiveClient()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const scenarioId = route.params.id
|
const scenarioId = route.params.id
|
||||||
|
|
||||||
const showSettingsModal = ref(false)
|
const showSettingsModal = ref(false)
|
||||||
const statusScenarioName = ref('')
|
const statusScenarioName = ref('')
|
||||||
const deletedScenarioName = ref('')
|
const deletedScenarioName = ref('')
|
||||||
|
const isDownloadingArchive = ref(false)
|
||||||
|
|
||||||
const message = useMessage()
|
const message = useMessage()
|
||||||
|
|
||||||
@@ -105,6 +108,27 @@ async function draftScenario(id: number) {
|
|||||||
showSettingsModal.value = false
|
showSettingsModal.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function downloadArchive() {
|
||||||
|
isDownloadingArchive.value = true
|
||||||
|
try {
|
||||||
|
const { blob, filename } = await archiveClient.downloadScenarioArchive(scenario.value.id!)
|
||||||
|
const url = URL.createObjectURL(blob)
|
||||||
|
const link = document.createElement('a')
|
||||||
|
link.href = url
|
||||||
|
link.download = filename
|
||||||
|
document.body.appendChild(link)
|
||||||
|
link.click()
|
||||||
|
link.remove()
|
||||||
|
// Отзываем URL после того как браузер начал скачивание
|
||||||
|
setTimeout(() => URL.revokeObjectURL(url), 1000)
|
||||||
|
message.success('Архив сценария скачан')
|
||||||
|
} catch (err) {
|
||||||
|
message.error(err instanceof Error ? err.message : 'Не удалось скачать архив')
|
||||||
|
} finally {
|
||||||
|
isDownloadingArchive.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function uploadFile(file: File | null, filename: string): Promise<string> {
|
async function uploadFile(file: File | null, filename: string): Promise<string> {
|
||||||
if (!file) {
|
if (!file) {
|
||||||
return ''
|
return ''
|
||||||
@@ -370,6 +394,15 @@ function getRandomComplimentForNastya() {
|
|||||||
|
|
||||||
<n-button @click="updateScenario()" ghost> Сохранить изменения </n-button>
|
<n-button @click="updateScenario()" ghost> Сохранить изменения </n-button>
|
||||||
|
|
||||||
|
<hr class="settings-hr" />
|
||||||
|
<p class="settings-header">Архив сценария</p>
|
||||||
|
<p class="settings-hint">
|
||||||
|
Скачайте сценарий ZIP-архивом (scenario.json + изображения) и импортируйте его в другом аккаунте.
|
||||||
|
</p>
|
||||||
|
<n-button :loading="isDownloadingArchive" :disabled="!scenario.id" ghost @click="downloadArchive()">
|
||||||
|
Скачать архив (.zip)
|
||||||
|
</n-button>
|
||||||
|
|
||||||
<hr class="settings-hr" />
|
<hr class="settings-hr" />
|
||||||
<p>Создать тестовую игру</p>
|
<p>Создать тестовую игру</p>
|
||||||
<n-button @click="addGame(scenario.name || '', scenario.id!)" ghost>
|
<n-button @click="addGame(scenario.name || '', scenario.id!)" ghost>
|
||||||
@@ -443,6 +476,11 @@ function getRandomComplimentForNastya() {
|
|||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.settings-hint {
|
||||||
|
color: #999;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
.settings-hr {
|
.settings-hr {
|
||||||
margin: 20px 0;
|
margin: 20px 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,18 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { Archive } from '@vicons/carbon'
|
||||||
|
import { Icon } from '@vicons/utils'
|
||||||
import { useMessage } from 'naive-ui'
|
import { useMessage } from 'naive-ui'
|
||||||
import { NButton, NCard, NFlex,NInput, NModal, NTag } from 'naive-ui'
|
import { NButton, NCard, NFlex, NInput, NModal, NTag, NText, NUpload, NUploadDragger, type UploadFileInfo } from 'naive-ui'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
|
|
||||||
|
import { getArchiveClient } from '@/api/archive_client'
|
||||||
import { getAuthClient } from '@/api/auth_client'
|
import { getAuthClient } from '@/api/auth_client'
|
||||||
import type { Scenario } from '@/api/generated/crabs/evening_detective_server'
|
import type { Scenario } from '@/api/generated/crabs/evening_detective_server'
|
||||||
import HeaderMenu from '@/components/HeaderMenu.vue'
|
import HeaderMenu from '@/components/HeaderMenu.vue'
|
||||||
|
|
||||||
const client = getAuthClient()
|
const client = getAuthClient()
|
||||||
|
const archiveClient = getArchiveClient()
|
||||||
|
|
||||||
const scenarios = ref<Scenario[]>([])
|
const scenarios = ref<Scenario[]>([])
|
||||||
|
|
||||||
@@ -19,6 +23,10 @@ const message = useMessage()
|
|||||||
const showAddScenarioModal = ref(false)
|
const showAddScenarioModal = ref(false)
|
||||||
const newScenarioName = ref('')
|
const newScenarioName = ref('')
|
||||||
|
|
||||||
|
const showImportModal = ref(false)
|
||||||
|
const importFileList = ref<UploadFileInfo[]>([])
|
||||||
|
const isImporting = ref(false)
|
||||||
|
|
||||||
async function getScenarios() {
|
async function getScenarios() {
|
||||||
scenarios.value = []
|
scenarios.value = []
|
||||||
const res = await client.GetMyScenarios({})
|
const res = await client.GetMyScenarios({})
|
||||||
@@ -38,6 +46,33 @@ async function toScenarioEditor(id: number) {
|
|||||||
router.push('/scenarios/' + id + '/editor')
|
router.push('/scenarios/' + id + '/editor')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resetImport() {
|
||||||
|
importFileList.value = []
|
||||||
|
showImportModal.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
async function importScenario() {
|
||||||
|
const file = importFileList.value[0]?.file
|
||||||
|
if (!file) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
isImporting.value = true
|
||||||
|
try {
|
||||||
|
const res = await archiveClient.uploadScenarioArchive(file)
|
||||||
|
if (res.error) {
|
||||||
|
message.error(res.error)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
message.success('Сценарий импортирован из архива')
|
||||||
|
resetImport()
|
||||||
|
await toScenarioEditor(res.id!)
|
||||||
|
} catch (err) {
|
||||||
|
message.error(err instanceof Error ? err.message : 'Не удалось импортировать архив')
|
||||||
|
} finally {
|
||||||
|
isImporting.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getScenarios()
|
getScenarios()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -51,6 +86,17 @@ getScenarios()
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="scenario-block" @click="showImportModal = true">
|
||||||
|
<div class="scenario-image-block scenario-image-plus import-icon">
|
||||||
|
<Icon>
|
||||||
|
<Archive />
|
||||||
|
</Icon>
|
||||||
|
</div>
|
||||||
|
<div class="scenario-content-block">
|
||||||
|
<p class="scenario-title">Импортировать из архива</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="scenario-block" v-for="scenario in scenarios" @click="toScenarioEditor(scenario.id!)"
|
<div class="scenario-block" v-for="scenario in scenarios" @click="toScenarioEditor(scenario.id!)"
|
||||||
v-bind:key="scenario.id">
|
v-bind:key="scenario.id">
|
||||||
<div class="scenario-image-block scenario-image" :style="{ backgroundImage: `url(${scenario.image})` }"></div>
|
<div class="scenario-image-block scenario-image" :style="{ backgroundImage: `url(${scenario.image})` }"></div>
|
||||||
@@ -86,6 +132,37 @@ getScenarios()
|
|||||||
</n-card>
|
</n-card>
|
||||||
</n-modal>
|
</n-modal>
|
||||||
|
|
||||||
|
<!-- Окно импорта сценария из архива -->
|
||||||
|
<n-modal v-model:show="showImportModal">
|
||||||
|
<n-card style="width: 600px" title="Импорт сценария из архива" :bordered="false" size="huge" role="dialog"
|
||||||
|
aria-modal="true">
|
||||||
|
<template #header-extra>
|
||||||
|
<n-button @click="resetImport()"> x </n-button>
|
||||||
|
</template>
|
||||||
|
<p class="import-hint">
|
||||||
|
Выберите ZIP-архив сценария (файл scenario.json + папка images). Архив можно получить
|
||||||
|
через «Скачать архив» в настройках сценария.
|
||||||
|
</p>
|
||||||
|
<n-upload :max="1" v-model:file-list="importFileList"
|
||||||
|
accept=".zip,application/zip,application/x-zip-compressed,application/octet-stream">
|
||||||
|
<n-upload-dragger>
|
||||||
|
<n-text style="font-size: 16px">
|
||||||
|
Щелкните или перетащите ZIP-архив в эту область
|
||||||
|
</n-text>
|
||||||
|
</n-upload-dragger>
|
||||||
|
</n-upload>
|
||||||
|
<template #footer>
|
||||||
|
<n-flex justify="end">
|
||||||
|
<n-button @click="resetImport()">Отмена</n-button>
|
||||||
|
<n-button type="primary" :loading="isImporting" :disabled="importFileList.length == 0"
|
||||||
|
@click="importScenario()">
|
||||||
|
Импортировать
|
||||||
|
</n-button>
|
||||||
|
</n-flex>
|
||||||
|
</template>
|
||||||
|
</n-card>
|
||||||
|
</n-modal>
|
||||||
|
|
||||||
<HeaderMenu active="scenarios" />
|
<HeaderMenu active="scenarios" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -126,6 +203,16 @@ getScenarios()
|
|||||||
background-color: #111;
|
background-color: #111;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.import-icon svg {
|
||||||
|
height: 100px;
|
||||||
|
width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.import-hint {
|
||||||
|
color: #aaa;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
.scenario-image {
|
.scenario-image {
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { createRouter, createWebHistory } from 'vue-router'
|
import { createRouter, createWebHistory } from 'vue-router'
|
||||||
|
|
||||||
import CatalogView from '../views/CatalogView.vue'
|
import CatalogView from '../views/CatalogView.vue'
|
||||||
|
import ConsentView from '../views/ConsentView.vue'
|
||||||
import GamesView from '../views/GamesView.vue'
|
import GamesView from '../views/GamesView.vue'
|
||||||
import GameView from '../views/GameView.vue'
|
import GameView from '../views/GameView.vue'
|
||||||
import HomeView from '../views/HomeView.vue'
|
import HomeView from '../views/HomeView.vue'
|
||||||
@@ -42,6 +43,11 @@ const router = createRouter({
|
|||||||
name: 'privacy-policy',
|
name: 'privacy-policy',
|
||||||
component: PrivacyPolicyView,
|
component: PrivacyPolicyView,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/consent',
|
||||||
|
name: 'consent',
|
||||||
|
component: ConsentView,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/games',
|
path: '/games',
|
||||||
name: 'games',
|
name: 'games',
|
||||||
|
|||||||
+33
-2
@@ -132,13 +132,18 @@ export const useAuthStore = defineStore('auth', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Регистрация
|
// Регистрация
|
||||||
async function signup(username: string, email: string) {
|
async function signup(
|
||||||
|
username: string,
|
||||||
|
email: string,
|
||||||
|
acceptTerms: boolean,
|
||||||
|
acceptPrivacy: boolean,
|
||||||
|
) {
|
||||||
isLoading.value = true
|
isLoading.value = true
|
||||||
error.value = null
|
error.value = null
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const client = buildClient(getToken)
|
const client = buildClient(getToken)
|
||||||
const response = await client.Signup({ username, email })
|
const response = await client.Signup({ username, email, acceptTerms, acceptPrivacy })
|
||||||
|
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
error.value = response.error
|
error.value = response.error
|
||||||
@@ -154,6 +159,31 @@ export const useAuthStore = defineStore('auth', () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Удаление аккаунта (подтверждение владельца паролем, ст. 21 152-ФЗ)
|
||||||
|
async function deleteAccount(password: string) {
|
||||||
|
isLoading.value = true
|
||||||
|
error.value = null
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Пароль передаётся HTTP-заголовком X-Password, а не в URL или body
|
||||||
|
const client = buildClient(getToken, () => ({ 'X-Password': password }))
|
||||||
|
const response = await client.DeleteAccount({})
|
||||||
|
|
||||||
|
if (response.error) {
|
||||||
|
error.value = response.error
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
await logout()
|
||||||
|
return true
|
||||||
|
} catch (err) {
|
||||||
|
error.value = err instanceof Error ? err.message : 'Account deletion failed'
|
||||||
|
return false
|
||||||
|
} finally {
|
||||||
|
isLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Восстановление пароля
|
// Восстановление пароля
|
||||||
async function refreshPassword(email: string) {
|
async function refreshPassword(email: string) {
|
||||||
isLoading.value = true
|
isLoading.value = true
|
||||||
@@ -216,6 +246,7 @@ export const useAuthStore = defineStore('auth', () => {
|
|||||||
getToken,
|
getToken,
|
||||||
login,
|
login,
|
||||||
signup,
|
signup,
|
||||||
|
deleteAccount,
|
||||||
refreshPassword,
|
refreshPassword,
|
||||||
logout,
|
logout,
|
||||||
fetchUser,
|
fetchUser,
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import DocsPage from '@/components/DocsPage.vue'
|
||||||
|
import HeaderMenu from '@/components/HeaderMenu.vue'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<DocsPage kind="consent" />
|
||||||
|
|
||||||
|
<HeaderMenu />
|
||||||
|
</template>
|
||||||
@@ -1,3 +1,10 @@
|
|||||||
<script setup lang="ts"></script>
|
<script setup lang="ts">
|
||||||
|
import DocsPage from '@/components/DocsPage.vue'
|
||||||
|
import HeaderMenu from '@/components/HeaderMenu.vue'
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>Соглашением о персональных данных</template>
|
<template>
|
||||||
|
<DocsPage kind="privacy" />
|
||||||
|
|
||||||
|
<HeaderMenu />
|
||||||
|
</template>
|
||||||
|
|||||||
@@ -1,3 +1,10 @@
|
|||||||
<script setup lang="ts"></script>
|
<script setup lang="ts">
|
||||||
|
import DocsPage from '@/components/DocsPage.vue'
|
||||||
|
import HeaderMenu from '@/components/HeaderMenu.vue'
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>Пользовательское соглашение</template>
|
<template>
|
||||||
|
<DocsPage kind="terms" />
|
||||||
|
|
||||||
|
<HeaderMenu />
|
||||||
|
</template>
|
||||||
|
|||||||
Reference in New Issue
Block a user