run prettier on whole project
This commit is contained in:
parent
0baf300f4e
commit
6c2e44ca66
@ -1,40 +1,30 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
root: true,
|
root: true,
|
||||||
env: { browser: true, es2020: true },
|
env: { browser: true, es2020: true },
|
||||||
extends: [
|
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended", "plugin:react-hooks/recommended"],
|
||||||
"eslint:recommended",
|
ignorePatterns: ["dist", ".eslintrc.cjs"],
|
||||||
"plugin:@typescript-eslint/recommended",
|
parser: "@typescript-eslint/parser",
|
||||||
"plugin:react-hooks/recommended",
|
plugins: ["react-refresh"],
|
||||||
],
|
rules: {
|
||||||
ignorePatterns: ["dist", ".eslintrc.cjs"],
|
"react-refresh/only-export-components": ["warn", { allowConstantExport: true }],
|
||||||
parser: "@typescript-eslint/parser",
|
"@typescript-eslint/ban-ts-comment": "off",
|
||||||
plugins: ["react-refresh"],
|
"@typescript-eslint/no-empty-function": "off",
|
||||||
rules: {
|
"@typescript-eslint/no-empty-interface": "off",
|
||||||
"react-refresh/only-export-components": [
|
"@typescript-eslint/no-explicit-any": "off",
|
||||||
"warn",
|
"@typescript-eslint/no-floating-promises": "off",
|
||||||
{ allowConstantExport: true },
|
"@typescript-eslint/no-inferrable-types": "off",
|
||||||
],
|
"@typescript-eslint/no-misused-promises": "off",
|
||||||
"@typescript-eslint/ban-ts-comment": "off",
|
"@typescript-eslint/no-non-null-assertion": "off",
|
||||||
"@typescript-eslint/no-empty-function": "off",
|
"@typescript-eslint/no-unsafe-argument": "off",
|
||||||
"@typescript-eslint/no-empty-interface": "off",
|
"@typescript-eslint/no-unsafe-assignment": "off",
|
||||||
"@typescript-eslint/no-explicit-any": "off",
|
"@typescript-eslint/no-unsafe-call": "off",
|
||||||
"@typescript-eslint/no-floating-promises": "off",
|
"@typescript-eslint/no-unsafe-member-access": "off",
|
||||||
"@typescript-eslint/no-inferrable-types": "off",
|
"@typescript-eslint/no-unused-vars": ["warn", { vars: "all", args: "none" }],
|
||||||
"@typescript-eslint/no-misused-promises": "off",
|
"@typescript-eslint/restrict-template-expressions": "off",
|
||||||
"@typescript-eslint/no-non-null-assertion": "off",
|
"no-debugger": "off",
|
||||||
"@typescript-eslint/no-unsafe-argument": "off",
|
"no-empty-function": "off",
|
||||||
"@typescript-eslint/no-unsafe-assignment": "off",
|
"no-empty-pattern": "off",
|
||||||
"@typescript-eslint/no-unsafe-call": "off",
|
"no-empty": "off",
|
||||||
"@typescript-eslint/no-unsafe-member-access": "off",
|
"prefer-const": "warn",
|
||||||
"@typescript-eslint/no-unused-vars": [
|
},
|
||||||
"warn",
|
|
||||||
{ "vars": "all", "args": "none" }
|
|
||||||
],
|
|
||||||
"@typescript-eslint/restrict-template-expressions": "off",
|
|
||||||
"no-debugger": "off",
|
|
||||||
"no-empty-function": "off",
|
|
||||||
"no-empty-pattern": "off",
|
|
||||||
"no-empty": "off",
|
|
||||||
"prefer-const": "warn",
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
31
README.md
31
README.md
@ -1,47 +1,68 @@
|
|||||||
## Правила
|
## Правила
|
||||||
|
|
||||||
- Запрещено использовать vh/vw css-юниты и их производные
|
- Запрещено использовать vh/vw css-юниты и их производные
|
||||||
|
|
||||||
## Виджет
|
## Виджет
|
||||||
|
|
||||||
### Сборка
|
### Сборка
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
yarn build:widget
|
yarn build:widget
|
||||||
```
|
```
|
||||||
|
|
||||||
### Использование
|
### Использование
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import widget from "https://hbpn.link/export/pub.js";
|
import widget from "https://hbpn.link/export/pub.js";
|
||||||
|
|
||||||
widget.create({
|
widget.create({
|
||||||
selector: "widget-container",
|
selector: "widget-container",
|
||||||
quizId: "...",
|
quizId: "...",
|
||||||
})
|
});
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
## Npm-пакет
|
## Npm-пакет
|
||||||
|
|
||||||
### Перед использованием и публикацией
|
### Перед использованием и публикацией
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm config set //penahub.gitlab.yandexcloud.net/api/v4/packages/npm/:_authToken=INSTANCE_TOKEN
|
npm config set //penahub.gitlab.yandexcloud.net/api/v4/packages/npm/:_authToken=INSTANCE_TOKEN
|
||||||
npm config set //penahub.gitlab.yandexcloud.net/api/v4/projects/43/packages/npm/:_authToken=PROJECT_TOKEN
|
npm config set //penahub.gitlab.yandexcloud.net/api/v4/projects/43/packages/npm/:_authToken=PROJECT_TOKEN
|
||||||
```
|
```
|
||||||
|
|
||||||
### Публикация
|
### Публикация
|
||||||
|
|
||||||
1. Инкрементировать версию в package.json
|
1. Инкрементировать версию в package.json
|
||||||
2.
|
2.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
yarn publish
|
yarn publish
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Нажать enter при запросе версии
|
3. Нажать enter при запросе версии
|
||||||
|
|
||||||
### Установка
|
### Установка
|
||||||
|
|
||||||
Добавить в корень проекта файл .yarnrc с содержимым
|
Добавить в корень проекта файл .yarnrc с содержимым
|
||||||
|
|
||||||
```
|
```
|
||||||
"@frontend:registry" "https://penahub.gitlab.yandexcloud.net/api/v4/packages/npm/"
|
"@frontend:registry" "https://penahub.gitlab.yandexcloud.net/api/v4/packages/npm/"
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
yarn add @frontend/squzanswerer
|
yarn add @frontend/squzanswerer
|
||||||
```
|
```
|
||||||
|
|
||||||
Peer dependencies:
|
Peer dependencies:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
yarn add @emoji-mart/data @emoji-mart/react @emotion/react @emotion/styled @mui/icons-material @mui/material @mui/x-date-pickers axios emoji-mart immer moment nanoid notistack react-dom react-error-boundary react-router-dom react swr use-debounce zustand
|
yarn add @emoji-mart/data @emoji-mart/react @emotion/react @emotion/styled @mui/icons-material @mui/material @mui/x-date-pickers axios emoji-mart immer moment nanoid notistack react-dom react-error-boundary react-router-dom react swr use-debounce zustand
|
||||||
```
|
```
|
||||||
|
|
||||||
### Использование
|
### Использование
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
import { QuizView } from "@frontend/squzanswerer";
|
import { QuizView } from "@frontend/squzanswerer";
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { defineConfig } from "cypress";
|
import { defineConfig } from "cypress";
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
e2e: {
|
e2e: {
|
||||||
baseUrl: 'http://localhost:3000',
|
baseUrl: "http://localhost:3000",
|
||||||
viewportWidth: 1440,
|
viewportWidth: 1440,
|
||||||
viewportHeight: 900,
|
viewportHeight: 900,
|
||||||
supportFile: false,
|
supportFile: false,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -5,4 +5,3 @@ services:
|
|||||||
image: $CI_REGISTRY_IMAGE/main:$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID
|
image: $CI_REGISTRY_IMAGE/main:$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID
|
||||||
hostname: respondent
|
hostname: respondent
|
||||||
tty: true
|
tty: true
|
||||||
|
|
||||||
|
@ -5,4 +5,3 @@ services:
|
|||||||
image: $CI_REGISTRY_IMAGE/staging:$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID
|
image: $CI_REGISTRY_IMAGE/staging:$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID
|
||||||
hostname: respondent
|
hostname: respondent
|
||||||
tty: true
|
tty: true
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { GetQuizDataResponse, parseQuizData } from "@model/api/getQuizData";
|
import { GetQuizDataResponse, parseQuizData } from "@model/api/getQuizData";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import MobileDetect from 'mobile-detect';
|
import MobileDetect from "mobile-detect";
|
||||||
import device from "current-device";
|
import device from "current-device";
|
||||||
|
|
||||||
import type { AxiosError } from "axios";
|
import type { AxiosError } from "axios";
|
||||||
@ -10,226 +10,240 @@ import * as Bowser from "bowser";
|
|||||||
import { domain } from "../utils/defineDomain";
|
import { domain } from "../utils/defineDomain";
|
||||||
let SESSIONS = "";
|
let SESSIONS = "";
|
||||||
|
|
||||||
|
|
||||||
const md = new MobileDetect(window.navigator.userAgent);
|
const md = new MobileDetect(window.navigator.userAgent);
|
||||||
const userAgent = navigator.userAgent;
|
const userAgent = navigator.userAgent;
|
||||||
//операционная система
|
//операционная система
|
||||||
let OSDevice: string | undefined;
|
let OSDevice: string | undefined;
|
||||||
if (userAgent.toLowerCase().includes("linux")) { OSDevice = "Linux"; }
|
if (userAgent.toLowerCase().includes("linux")) {
|
||||||
if (userAgent.toLowerCase().includes("windows")) { OSDevice = "Windows"; }
|
OSDevice = "Linux";
|
||||||
if (/iPad|iPhone|iPod/.test(userAgent)) { OSDevice = "IOS"; }
|
}
|
||||||
if (userAgent.toLowerCase().includes("macintosh")) { OSDevice = "Mac OS"; }
|
if (userAgent.toLowerCase().includes("windows")) {
|
||||||
if (OSDevice === undefined) { OSDevice = userAgent; }
|
OSDevice = "Windows";
|
||||||
|
}
|
||||||
|
if (/iPad|iPhone|iPod/.test(userAgent)) {
|
||||||
|
OSDevice = "IOS";
|
||||||
|
}
|
||||||
|
if (userAgent.toLowerCase().includes("macintosh")) {
|
||||||
|
OSDevice = "Mac OS";
|
||||||
|
}
|
||||||
|
if (OSDevice === undefined) {
|
||||||
|
OSDevice = userAgent;
|
||||||
|
}
|
||||||
|
|
||||||
//браузер
|
//браузер
|
||||||
let browserUser: string;
|
let browserUser: string;
|
||||||
if (Bowser.name === "Chrome") {
|
if (Bowser.name === "Chrome") {
|
||||||
browserUser = "Chrome";
|
browserUser = "Chrome";
|
||||||
} else if (Bowser.name === "Firefox") {
|
} else if (Bowser.name === "Firefox") {
|
||||||
browserUser = "Firefox";
|
browserUser = "Firefox";
|
||||||
} else if (Bowser.name === "Safari") {
|
} else if (Bowser.name === "Safari") {
|
||||||
browserUser = "Safari";
|
browserUser = "Safari";
|
||||||
} else if (Bowser.name === "Yandex Browser") {
|
} else if (Bowser.name === "Yandex Browser") {
|
||||||
browserUser = "Yandex Browser";
|
browserUser = "Yandex Browser";
|
||||||
} else { browserUser = userAgent; }
|
} else {
|
||||||
|
browserUser = userAgent;
|
||||||
|
}
|
||||||
|
|
||||||
const DeviceType = device.type;
|
const DeviceType = device.type;
|
||||||
|
|
||||||
let Device = md.mobile();
|
let Device = md.mobile();
|
||||||
if (Device === null) { Device = userAgent; }
|
if (Device === null) {
|
||||||
|
Device = userAgent;
|
||||||
|
}
|
||||||
|
|
||||||
type PublicationMakeRequestParams = {
|
type PublicationMakeRequestParams = {
|
||||||
url: string;
|
url: string;
|
||||||
body: FormData;
|
body: FormData;
|
||||||
method: "POST";
|
method: "POST";
|
||||||
};
|
};
|
||||||
|
|
||||||
export const publicationMakeRequest = ({ url, body }: PublicationMakeRequestParams) => {
|
export const publicationMakeRequest = ({ url, body }: PublicationMakeRequestParams) => {
|
||||||
return axios(url, {
|
return axios(url, {
|
||||||
data: body,
|
data: body,
|
||||||
headers: {
|
headers: {
|
||||||
"X-Sessionkey": SESSIONS,
|
"X-Sessionkey": SESSIONS,
|
||||||
"Content-Type": "multipart/form-data",
|
"Content-Type": "multipart/form-data",
|
||||||
"DeviceType": DeviceType,
|
DeviceType: DeviceType,
|
||||||
"Device": Device,
|
Device: Device,
|
||||||
"OS": OSDevice,
|
OS: OSDevice,
|
||||||
"Browser": browserUser
|
Browser: browserUser,
|
||||||
},
|
},
|
||||||
method: "POST",
|
method: "POST",
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function getData(quizId: string): Promise<{
|
export async function getData(quizId: string): Promise<{
|
||||||
data: GetQuizDataResponse | null;
|
data: GetQuizDataResponse | null;
|
||||||
isRecentlyCompleted: boolean;
|
isRecentlyCompleted: boolean;
|
||||||
error?: AxiosError;
|
error?: AxiosError;
|
||||||
}> {
|
}> {
|
||||||
try {
|
try {
|
||||||
const { data, headers } = await axios<GetQuizDataResponse>(
|
const { data, headers } = await axios<GetQuizDataResponse>(domain + `/answer/settings`, {
|
||||||
domain + `/answer/settings`,
|
method: "POST",
|
||||||
{
|
headers: {
|
||||||
method: "POST",
|
"X-Sessionkey": SESSIONS,
|
||||||
headers: {
|
"Content-Type": "application/json",
|
||||||
"X-Sessionkey": SESSIONS,
|
DeviceType: DeviceType,
|
||||||
"Content-Type": "application/json",
|
Device: Device,
|
||||||
"DeviceType": DeviceType,
|
OS: OSDevice,
|
||||||
"Device": Device,
|
Browser: userAgent,
|
||||||
"OS": OSDevice,
|
},
|
||||||
"Browser": userAgent
|
data: {
|
||||||
},
|
quiz_id: quizId,
|
||||||
data: {
|
limit: 100,
|
||||||
quiz_id: quizId,
|
page: 0,
|
||||||
limit: 100,
|
need_config: true,
|
||||||
page: 0,
|
},
|
||||||
need_config: true,
|
});
|
||||||
},
|
const sessions = JSON.parse(localStorage.getItem("sessions") || "{}");
|
||||||
}
|
|
||||||
);
|
|
||||||
const sessions = JSON.parse(localStorage.getItem("sessions") || "{}");
|
|
||||||
|
|
||||||
if (typeof sessions[quizId] === "number") {
|
if (typeof sessions[quizId] === "number") {
|
||||||
// unix время. Если меньше суток прошло - выводить ошибку, иначе пустить дальше
|
// unix время. Если меньше суток прошло - выводить ошибку, иначе пустить дальше
|
||||||
if (Date.now() - sessions[quizId] < 86400000) {
|
if (Date.now() - sessions[quizId] < 86400000) {
|
||||||
return { data, isRecentlyCompleted: true };
|
return { data, isRecentlyCompleted: true };
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
SESSIONS = headers["x-sessionkey"] ? headers["x-sessionkey"] : SESSIONS;
|
|
||||||
|
|
||||||
return { data, isRecentlyCompleted: false };
|
|
||||||
} catch (nativeError) {
|
|
||||||
const error = nativeError as AxiosError;
|
|
||||||
|
|
||||||
return { data: null, isRecentlyCompleted: false, error: error };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SESSIONS = headers["x-sessionkey"] ? headers["x-sessionkey"] : SESSIONS;
|
||||||
|
|
||||||
|
return { data, isRecentlyCompleted: false };
|
||||||
|
} catch (nativeError) {
|
||||||
|
const error = nativeError as AxiosError;
|
||||||
|
|
||||||
|
return { data: null, isRecentlyCompleted: false, error: error };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getQuizData(quizId: string) {
|
export async function getQuizData(quizId: string) {
|
||||||
if (!quizId) throw new Error("No quiz id");
|
if (!quizId) throw new Error("No quiz id");
|
||||||
|
|
||||||
const response = await getData(quizId);
|
const response = await getData(quizId);
|
||||||
const quizDataResponse = response.data;
|
const quizDataResponse = response.data;
|
||||||
|
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
throw response.error;
|
throw response.error;
|
||||||
}
|
}
|
||||||
if (!quizDataResponse) {
|
if (!quizDataResponse) {
|
||||||
throw new Error("Quiz not found");
|
throw new Error("Quiz not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
const quizSettings = replaceSpacesToEmptyLines(parseQuizData(quizDataResponse));
|
const quizSettings = replaceSpacesToEmptyLines(parseQuizData(quizDataResponse));
|
||||||
|
|
||||||
const res = JSON.parse(JSON.stringify({ data: quizSettings }).replaceAll(/\\" \\"/g, '""').replaceAll(/" "/g, '""')).data as QuizSettings;
|
const res = JSON.parse(
|
||||||
res.recentlyCompleted = response.isRecentlyCompleted;
|
JSON.stringify({ data: quizSettings })
|
||||||
return res;
|
.replaceAll(/\\" \\"/g, '""')
|
||||||
|
.replaceAll(/" "/g, '""')
|
||||||
|
).data as QuizSettings;
|
||||||
|
res.recentlyCompleted = response.isRecentlyCompleted;
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
type SendAnswerProps = {
|
type SendAnswerProps = {
|
||||||
questionId: string;
|
questionId: string;
|
||||||
body: string | string[];
|
body: string | string[];
|
||||||
qid: string;
|
qid: string;
|
||||||
preview: boolean;
|
preview: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function sendAnswer({ questionId, body, qid, preview }: SendAnswerProps) {
|
export function sendAnswer({ questionId, body, qid, preview }: SendAnswerProps) {
|
||||||
if (preview) return;
|
if (preview) return;
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
|
|
||||||
const answers = [
|
const answers = [
|
||||||
{
|
{
|
||||||
question_id: questionId,
|
question_id: questionId,
|
||||||
content: body, //тут массив с ответом
|
content: body, //тут массив с ответом
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
formData.append("answers", JSON.stringify(answers));
|
formData.append("answers", JSON.stringify(answers));
|
||||||
console.log("QID", qid);
|
console.log("QID", qid);
|
||||||
formData.append("qid", qid);
|
formData.append("qid", qid);
|
||||||
|
|
||||||
return publicationMakeRequest({
|
return publicationMakeRequest({
|
||||||
url: domain + `/answer/answer`,
|
url: domain + `/answer/answer`,
|
||||||
body: formData,
|
body: formData,
|
||||||
method: "POST",
|
method: "POST",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//body ={file, filename}
|
//body ={file, filename}
|
||||||
type SendFileParams = {
|
type SendFileParams = {
|
||||||
questionId: string;
|
questionId: string;
|
||||||
body: {
|
body: {
|
||||||
name: string;
|
name: string;
|
||||||
file: File;
|
file: File;
|
||||||
preview: boolean;
|
preview: boolean;
|
||||||
};
|
};
|
||||||
qid: string;
|
qid: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type Answer = {
|
type Answer = {
|
||||||
question_id: string;
|
question_id: string;
|
||||||
content: string;
|
content: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function sendFile({ questionId, body, qid }: SendFileParams) {
|
export function sendFile({ questionId, body, qid }: SendFileParams) {
|
||||||
if (body.preview) return;
|
if (body.preview) return;
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
|
|
||||||
const answers: Answer[] = [
|
const answers: Answer[] = [
|
||||||
{
|
{
|
||||||
question_id: questionId,
|
question_id: questionId,
|
||||||
content: "file:" + body.name,
|
content: "file:" + body.name,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
formData.append("answers", JSON.stringify(answers));
|
formData.append("answers", JSON.stringify(answers));
|
||||||
formData.append(body.name, body.file);
|
formData.append(body.name, body.file);
|
||||||
console.log("QID", qid);
|
console.log("QID", qid);
|
||||||
formData.append("qid", qid);
|
formData.append("qid", qid);
|
||||||
|
|
||||||
return publicationMakeRequest({
|
return publicationMakeRequest({
|
||||||
url: domain + `/answer/answer`,
|
url: domain + `/answer/answer`,
|
||||||
body: formData,
|
body: formData,
|
||||||
method: "POST",
|
method: "POST",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//форма контактов
|
//форма контактов
|
||||||
export type SendFCParams = {
|
export type SendFCParams = {
|
||||||
questionId: string;
|
questionId: string;
|
||||||
body: {
|
body: {
|
||||||
name?: string;
|
name?: string;
|
||||||
email?: string;
|
email?: string;
|
||||||
phone?: string;
|
phone?: string;
|
||||||
address?: string;
|
address?: string;
|
||||||
customs?: Record<string, string>;
|
customs?: Record<string, string>;
|
||||||
};
|
};
|
||||||
qid: string;
|
qid: string;
|
||||||
preview: boolean;
|
preview: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function sendFC({ questionId, body, qid, preview }: SendFCParams) {
|
export function sendFC({ questionId, body, qid, preview }: SendFCParams) {
|
||||||
if (preview) return;
|
if (preview) return;
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
|
|
||||||
// const keysBody = Object.keys(body)
|
// const keysBody = Object.keys(body)
|
||||||
// const content:any = {}
|
// const content:any = {}
|
||||||
// fields.forEach((key) => {
|
// fields.forEach((key) => {
|
||||||
// if (keysBody.includes(key)) content[key] = body.key
|
// if (keysBody.includes(key)) content[key] = body.key
|
||||||
// })
|
// })
|
||||||
|
|
||||||
const answers = [
|
const answers = [
|
||||||
{
|
{
|
||||||
question_id: questionId,
|
question_id: questionId,
|
||||||
content: JSON.stringify(body),
|
content: JSON.stringify(body),
|
||||||
result: true,
|
result: true,
|
||||||
qid,
|
qid,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
formData.append("answers", JSON.stringify(answers));
|
formData.append("answers", JSON.stringify(answers));
|
||||||
formData.append("qid", qid);
|
formData.append("qid", qid);
|
||||||
|
|
||||||
return publicationMakeRequest({
|
return publicationMakeRequest({
|
||||||
url: domain + `/answer/answer`,
|
url: domain + `/answer/answer`,
|
||||||
body: formData,
|
body: formData,
|
||||||
method: "POST",
|
method: "POST",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,29 +1,32 @@
|
|||||||
import {Box, SxProps, Theme, useTheme} from "@mui/material";
|
import { Box, SxProps, Theme, useTheme } from "@mui/material";
|
||||||
|
|
||||||
interface Color{
|
interface Color {
|
||||||
color?: string
|
color?: string;
|
||||||
}
|
}
|
||||||
export default function ArrowDownIcon(
|
export default function ArrowDownIcon(props: any, { color = "#7E2AEA" }: Color) {
|
||||||
props: any,
|
const theme = useTheme();
|
||||||
{color = "#7E2AEA"}: Color
|
|
||||||
) {
|
|
||||||
const theme = useTheme();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
{...props}
|
{...props}
|
||||||
sx={{
|
sx={{
|
||||||
top: "25% !important",
|
top: "25% !important",
|
||||||
height: "24px",
|
height: "24px",
|
||||||
width: "24px",
|
width: "24px",
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
|
||||||
<path d="M19.5 9L12 16.5L4.5 9" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
|
<path
|
||||||
</svg>
|
d="M19.5 9L12 16.5L4.5 9"
|
||||||
</Box>
|
stroke="currentColor"
|
||||||
);
|
strokeWidth="1.5"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
}
|
}
|
@ -1,10 +1,26 @@
|
|||||||
export default function BlankImage() {
|
export default function BlankImage() {
|
||||||
|
return (
|
||||||
return (
|
<svg
|
||||||
<svg width="100%" height="100%" viewBox="0 -70 800 535" fill="none" display="block" preserveAspectRatio="xMidYMax meet" xmlns="http://www.w3.org/2000/svg">
|
width="100%"
|
||||||
<path fill="#F0F0F0" d="M555 47a47.003 47.003 0 0 1 29.014-43.422 46.999 46.999 0 0 1 61.408 61.408 46.997 46.997 0 0 1-76.656 15.248A47 47 0 0 1 555 47Z" />
|
height="100%"
|
||||||
<path fill="#F3F3F3" d="M641.874 240.665c7.74-7.74 20.263-7.82 28.102-.181L1051 611.837 779.035 883.805 383.869 498.67l258.005-258.005Z" />
|
viewBox="0 -70 800 535"
|
||||||
<path fill="#EDEDED" d="M183.393 61.546c7.692-7.037 19.499-6.985 27.129.12l677.42 630.746-690.929 382.738L-397 592.531 183.393 61.546Z" />
|
fill="none"
|
||||||
</svg>
|
display="block"
|
||||||
);
|
preserveAspectRatio="xMidYMax meet"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill="#F0F0F0"
|
||||||
|
d="M555 47a47.003 47.003 0 0 1 29.014-43.422 46.999 46.999 0 0 1 61.408 61.408 46.997 46.997 0 0 1-76.656 15.248A47 47 0 0 1 555 47Z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill="#F3F3F3"
|
||||||
|
d="M641.874 240.665c7.74-7.74 20.263-7.82 28.102-.181L1051 611.837 779.035 883.805 383.869 498.67l258.005-258.005Z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill="#EDEDED"
|
||||||
|
d="M183.393 61.546c7.692-7.037 19.499-6.985 27.129.12l677.42 630.746-690.929 382.738L-397 592.531 183.393 61.546Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Box, SxProps, Theme } from "@mui/material";
|
import { Box, SxProps, Theme } from "@mui/material";
|
||||||
interface Props {
|
interface Props {
|
||||||
sx?: SxProps<Theme>;
|
sx?: SxProps<Theme>;
|
||||||
}
|
}
|
||||||
export default function CalendarIcon({ sx }: Props) {
|
export default function CalendarIcon({ sx }: Props) {
|
||||||
return (
|
return (
|
||||||
@ -22,7 +22,7 @@ export default function CalendarIcon({ sx }: Props) {
|
|||||||
"&:active rect": {
|
"&:active rect": {
|
||||||
stroke: "#FB5607",
|
stroke: "#FB5607",
|
||||||
},
|
},
|
||||||
...sx
|
...sx,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<svg width="20" height="22" viewBox="0 0 20 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg width="20" height="22" viewBox="0 0 20 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
@ -5,7 +5,7 @@ type CheckboxIconProps = {
|
|||||||
color?: string;
|
color?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CheckboxIcon = ({ checked = false, color = "#7E2AEA", }: CheckboxIconProps) => {
|
export const CheckboxIcon = ({ checked = false, color = "#7E2AEA" }: CheckboxIconProps) => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -17,26 +17,13 @@ export const CheckboxIcon = ({ checked = false, color = "#7E2AEA", }: CheckboxIc
|
|||||||
display: "flex",
|
display: "flex",
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
backgroundColor: checked
|
backgroundColor: checked ? color : "#F2F3F7",
|
||||||
? color
|
|
||||||
: "#F2F3F7",
|
|
||||||
border: `1px solid #9A9AAF`,
|
border: `1px solid #9A9AAF`,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{checked && (
|
{checked && (
|
||||||
<svg
|
<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 25 18" fill="none">
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
<path d="M2 9L10 16.5L22.5 1.5" stroke="#ffffff" strokeWidth="4" strokeLinecap="round" />
|
||||||
width="15"
|
|
||||||
height="15"
|
|
||||||
viewBox="0 0 25 18"
|
|
||||||
fill="none"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M2 9L10 16.5L22.5 1.5"
|
|
||||||
stroke="#ffffff"
|
|
||||||
strokeWidth="4"
|
|
||||||
strokeLinecap="round"
|
|
||||||
/>
|
|
||||||
</svg>
|
</svg>
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
|
@ -8,13 +8,7 @@ export default function CloseBold({ width }: Props) {
|
|||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<svg
|
<svg width="35" height="33" viewBox="0 0 35 33" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
width="35"
|
|
||||||
height="33"
|
|
||||||
viewBox="0 0 35 33"
|
|
||||||
fill="none"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<g id="Close">
|
<g id="Close">
|
||||||
<g id="Rectangle 57" opacity="0.3" filter="url(#filter0_d_4080_12482)">
|
<g id="Rectangle 57" opacity="0.3" filter="url(#filter0_d_4080_12482)">
|
||||||
<rect x="6" y="4" width="24" height="24" rx="12" fill="#9A9AAF" />
|
<rect x="6" y="4" width="24" height="24" rx="12" fill="#9A9AAF" />
|
||||||
@ -55,30 +49,13 @@ export default function CloseBold({ width }: Props) {
|
|||||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||||
result="hardAlpha"
|
result="hardAlpha"
|
||||||
/>
|
/>
|
||||||
<feMorphology
|
<feMorphology radius="1" operator="dilate" in="SourceAlpha" result="effect1_dropShadow_4080_12482" />
|
||||||
radius="1"
|
|
||||||
operator="dilate"
|
|
||||||
in="SourceAlpha"
|
|
||||||
result="effect1_dropShadow_4080_12482"
|
|
||||||
/>
|
|
||||||
<feOffset dy="2" />
|
<feOffset dy="2" />
|
||||||
<feGaussianBlur stdDeviation="2.5" />
|
<feGaussianBlur stdDeviation="2.5" />
|
||||||
<feComposite in2="hardAlpha" operator="out" />
|
<feComposite in2="hardAlpha" operator="out" />
|
||||||
<feColorMatrix
|
<feColorMatrix type="matrix" values="0 0 0 0 0.416562 0 0 0 0 0.452406 0 0 0 0 0.775 0 0 0 0.18 0" />
|
||||||
type="matrix"
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_4080_12482" />
|
||||||
values="0 0 0 0 0.416562 0 0 0 0 0.452406 0 0 0 0 0.775 0 0 0 0.18 0"
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_4080_12482" result="shape" />
|
||||||
/>
|
|
||||||
<feBlend
|
|
||||||
mode="normal"
|
|
||||||
in2="BackgroundImageFix"
|
|
||||||
result="effect1_dropShadow_4080_12482"
|
|
||||||
/>
|
|
||||||
<feBlend
|
|
||||||
mode="normal"
|
|
||||||
in="SourceGraphic"
|
|
||||||
in2="effect1_dropShadow_4080_12482"
|
|
||||||
result="shape"
|
|
||||||
/>
|
|
||||||
</filter>
|
</filter>
|
||||||
</defs>
|
</defs>
|
||||||
</svg>
|
</svg>
|
||||||
|
@ -2,7 +2,7 @@ import { Box } from "@mui/material";
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
color: string;
|
color: string;
|
||||||
backgroundColor: string
|
backgroundColor: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function AddressIcon({ color, backgroundColor }: Props) {
|
export default function AddressIcon({ color, backgroundColor }: Props) {
|
||||||
@ -14,18 +14,12 @@ export default function AddressIcon({ color, backgroundColor }: Props) {
|
|||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
height: "58px",
|
height: "58px",
|
||||||
width: "45px",
|
width: "45px",
|
||||||
backgroundColor: {backgroundColor},
|
backgroundColor: { backgroundColor },
|
||||||
borderBottomLeftRadius: "12px",
|
borderBottomLeftRadius: "12px",
|
||||||
borderTopLeftRadius: "12px",
|
borderTopLeftRadius: "12px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<svg
|
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
width="15"
|
|
||||||
height="15"
|
|
||||||
viewBox="0 0 15 15"
|
|
||||||
fill="none"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
<path
|
||||||
d="M7.5 7.96875C8.53553 7.96875 9.375 7.12928 9.375 6.09375C9.375 5.05822 8.53553 4.21875 7.5 4.21875C6.46447 4.21875 5.625 5.05822 5.625 6.09375C5.625 7.12928 6.46447 7.96875 7.5 7.96875Z"
|
d="M7.5 7.96875C8.53553 7.96875 9.375 7.12928 9.375 6.09375C9.375 5.05822 8.53553 4.21875 7.5 4.21875C6.46447 4.21875 5.625 5.05822 5.625 6.09375C5.625 7.12928 6.46447 7.96875 7.5 7.96875Z"
|
||||||
stroke={color}
|
stroke={color}
|
||||||
|
@ -2,7 +2,7 @@ import { Box } from "@mui/material";
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
color: string;
|
color: string;
|
||||||
backgroundColor: string
|
backgroundColor: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function EmailIcon({ color, backgroundColor }: Props) {
|
export default function EmailIcon({ color, backgroundColor }: Props) {
|
||||||
@ -14,16 +14,21 @@ export default function EmailIcon({ color, backgroundColor }: Props) {
|
|||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
height: "58px",
|
height: "58px",
|
||||||
width: "45px",
|
width: "45px",
|
||||||
backgroundColor: {backgroundColor},
|
backgroundColor: { backgroundColor },
|
||||||
borderBottomLeftRadius: "12px",
|
borderBottomLeftRadius: "12px",
|
||||||
borderTopLeftRadius: "12px",
|
borderTopLeftRadius: "12px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<svg width="17" height="18" viewBox="0 0 17 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg width="17" height="18" viewBox="0 0 17 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<rect x="1" y="3" width="15" height="12" rx="3" stroke="#9A9AAF" strokeWidth="1.5"/>
|
<rect x="1" y="3" width="15" height="12" rx="3" stroke="#9A9AAF" strokeWidth="1.5" />
|
||||||
<path d="M4 6.75L7.3 9.225C8.01111 9.75833 8.98889 9.75833 9.7 9.225L13 6.75" stroke="#9A9AAF" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
|
<path
|
||||||
</svg>
|
d="M4 6.75L7.3 9.225C8.01111 9.75833 8.98889 9.75833 9.7 9.225L13 6.75"
|
||||||
|
stroke="#9A9AAF"
|
||||||
|
strokeWidth="1.5"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ import { Box } from "@mui/material";
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
color: string;
|
color: string;
|
||||||
backgroundColor: string
|
backgroundColor: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function NameIcon({ color, backgroundColor }: Props) {
|
export default function NameIcon({ color, backgroundColor }: Props) {
|
||||||
@ -14,15 +14,26 @@ export default function NameIcon({ color, backgroundColor }: Props) {
|
|||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
height: "58px",
|
height: "58px",
|
||||||
width: "45px",
|
width: "45px",
|
||||||
backgroundColor: {backgroundColor},
|
backgroundColor: { backgroundColor },
|
||||||
borderBottomLeftRadius: "12px",
|
borderBottomLeftRadius: "12px",
|
||||||
borderTopLeftRadius: "12px",
|
borderTopLeftRadius: "12px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<svg width="17" height="18" viewBox="0 0 17 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg width="17" height="18" viewBox="0 0 17 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<circle cx="2.97143" cy="2.97143" r="2.97143" transform="matrix(-1 0 0 1 11.4688 2.5)" stroke="#9A9AAF" strokeWidth="1.5"/>
|
<circle
|
||||||
<path d="M3.29688 12.8526C3.29688 12.2135 3.69865 11.6433 4.30054 11.4284V11.4284C7.01416 10.4592 9.97959 10.4592 12.6932 11.4284V11.4284C13.2951 11.6433 13.6969 12.2135 13.6969 12.8526V13.8298C13.6969 14.7119 12.9156 15.3895 12.0424 15.2648L11.7512 15.2232C9.59262 14.9148 7.40113 14.9148 5.24252 15.2232L4.95137 15.2648C4.07814 15.3895 3.29688 14.7119 3.29688 13.8298V12.8526Z" stroke="#9A9AAF" strokeWidth="1.5"/>
|
cx="2.97143"
|
||||||
</svg>
|
cy="2.97143"
|
||||||
|
r="2.97143"
|
||||||
|
transform="matrix(-1 0 0 1 11.4688 2.5)"
|
||||||
|
stroke="#9A9AAF"
|
||||||
|
strokeWidth="1.5"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M3.29688 12.8526C3.29688 12.2135 3.69865 11.6433 4.30054 11.4284V11.4284C7.01416 10.4592 9.97959 10.4592 12.6932 11.4284V11.4284C13.2951 11.6433 13.6969 12.2135 13.6969 12.8526V13.8298C13.6969 14.7119 12.9156 15.3895 12.0424 15.2648L11.7512 15.2232C9.59262 14.9148 7.40113 14.9148 5.24252 15.2232L4.95137 15.2648C4.07814 15.3895 3.29688 14.7119 3.29688 13.8298V12.8526Z"
|
||||||
|
stroke="#9A9AAF"
|
||||||
|
strokeWidth="1.5"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ import { Box } from "@mui/material";
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
color: string;
|
color: string;
|
||||||
backgroundColor: string
|
backgroundColor: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function PhoneIcon({ color, backgroundColor }: Props) {
|
export default function PhoneIcon({ color, backgroundColor }: Props) {
|
||||||
@ -14,14 +14,18 @@ export default function PhoneIcon({ color, backgroundColor }: Props) {
|
|||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
height: "58px",
|
height: "58px",
|
||||||
width: "45px",
|
width: "45px",
|
||||||
backgroundColor: {backgroundColor},
|
backgroundColor: { backgroundColor },
|
||||||
borderBottomLeftRadius: "12px",
|
borderBottomLeftRadius: "12px",
|
||||||
borderTopLeftRadius: "12px",
|
borderTopLeftRadius: "12px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<svg width="17" height="18" viewBox="0 0 17 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg width="17" height="18" viewBox="0 0 17 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="M13.6893 15.0369C12.2537 16.4725 8.57727 15.1236 5.47772 12.024C2.37818 8.9245 1.02926 5.24806 2.46484 3.81247L3.41006 2.86725C4.06259 2.21472 5.13781 2.23197 5.81163 2.90578L7.27569 4.36984C7.9495 5.04365 7.96675 6.11888 7.31421 6.77141L7.11119 6.97443C6.75888 7.32675 6.72441 7.8951 7.05178 8.29181C7.36754 8.67446 7.70796 9.0556 8.07707 9.4247C8.44617 9.7938 8.82731 10.1342 9.20996 10.45C9.60666 10.7774 10.175 10.7429 10.5273 10.3906L10.7304 10.1875C11.3829 9.53501 12.4581 9.55226 13.1319 10.2261L14.596 11.6901C15.2698 12.364 15.287 13.4392 14.6345 14.0917L13.6893 15.0369Z" stroke="#9A9AAF" strokeWidth="1.5"/>
|
<path
|
||||||
</svg>
|
d="M13.6893 15.0369C12.2537 16.4725 8.57727 15.1236 5.47772 12.024C2.37818 8.9245 1.02926 5.24806 2.46484 3.81247L3.41006 2.86725C4.06259 2.21472 5.13781 2.23197 5.81163 2.90578L7.27569 4.36984C7.9495 5.04365 7.96675 6.11888 7.31421 6.77141L7.11119 6.97443C6.75888 7.32675 6.72441 7.8951 7.05178 8.29181C7.36754 8.67446 7.70796 9.0556 8.07707 9.4247C8.44617 9.7938 8.82731 10.1342 9.20996 10.45C9.60666 10.7774 10.175 10.7429 10.5273 10.3906L10.7304 10.1875C11.3829 9.53501 12.4581 9.55226 13.1319 10.2261L14.596 11.6901C15.2698 12.364 15.287 13.4392 14.6345 14.0917L13.6893 15.0369Z"
|
||||||
|
stroke="#9A9AAF"
|
||||||
|
strokeWidth="1.5"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ import { Box } from "@mui/material";
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
color: string;
|
color: string;
|
||||||
backgroundColor: string
|
backgroundColor: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function TextIcon({ color, backgroundColor }: Props) {
|
export default function TextIcon({ color, backgroundColor }: Props) {
|
||||||
@ -14,24 +14,13 @@ export default function TextIcon({ color, backgroundColor }: Props) {
|
|||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
height: "58px",
|
height: "58px",
|
||||||
width: "45px",
|
width: "45px",
|
||||||
backgroundColor: {backgroundColor},
|
backgroundColor: { backgroundColor },
|
||||||
borderBottomLeftRadius: "12px",
|
borderBottomLeftRadius: "12px",
|
||||||
borderTopLeftRadius: "12px",
|
borderTopLeftRadius: "12px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<svg
|
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
width="15"
|
<path d="M8.67188 1.60156L8.67188 13.3838" stroke={color} strokeLinecap="round" strokeLinejoin="round" />
|
||||||
height="15"
|
|
||||||
viewBox="0 0 15 15"
|
|
||||||
fill="none"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M8.67188 1.60156L8.67188 13.3838"
|
|
||||||
stroke={color}
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
/>
|
|
||||||
<path
|
<path
|
||||||
d="M10.6016 4.21875H13.7768C13.8534 4.21875 13.9268 4.26814 13.9809 4.35604C14.035 4.44395 14.0655 4.56318 14.0655 4.6875V10.3125C14.0655 10.4368 14.035 10.556 13.9809 10.644C13.9268 10.7319 13.8534 10.7812 13.7768 10.7812H10.6016"
|
d="M10.6016 4.21875H13.7768C13.8534 4.21875 13.9268 4.26814 13.9809 4.35604C14.035 4.44395 14.0655 4.56318 14.0655 4.6875V10.3125C14.0655 10.4368 14.035 10.556 13.9809 10.644C13.9268 10.7319 13.8534 10.7812 13.7768 10.7812H10.6016"
|
||||||
stroke={color}
|
stroke={color}
|
||||||
@ -44,30 +33,10 @@ export default function TextIcon({ color, backgroundColor }: Props) {
|
|||||||
strokeLinecap="round"
|
strokeLinecap="round"
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
/>
|
/>
|
||||||
<path
|
<path d="M3.98438 6.5625H5.625" stroke={color} strokeLinecap="round" strokeLinejoin="round" />
|
||||||
d="M3.98438 6.5625H5.625"
|
<path d="M7.85156 1.60156H9.49219" stroke={color} strokeLinecap="round" strokeLinejoin="round" />
|
||||||
stroke={color}
|
<path d="M7.85156 13.3828H9.49219" stroke={color} strokeLinecap="round" strokeLinejoin="round" />
|
||||||
strokeLinecap="round"
|
<path d="M4.80469 6.5625V8.67188" stroke={color} strokeLinecap="round" strokeLinejoin="round" />
|
||||||
strokeLinejoin="round"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M7.85156 1.60156H9.49219"
|
|
||||||
stroke={color}
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M7.85156 13.3828H9.49219"
|
|
||||||
stroke={color}
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M4.80469 6.5625V8.67188"
|
|
||||||
stroke={color}
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
/>
|
|
||||||
</svg>
|
</svg>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
@ -6,23 +6,13 @@ type InfoProps = {
|
|||||||
sx?: SxProps;
|
sx?: SxProps;
|
||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
className?: string;
|
className?: string;
|
||||||
color?: string
|
color?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function Info({ width = 20, height = 20, sx, onClick, className, color = "#7e2aea" }: InfoProps) {
|
export default function Info({ width = 20, height = 20, sx, onClick, className, color = "#7e2aea" }: InfoProps) {
|
||||||
return (
|
return (
|
||||||
<IconButton
|
<IconButton sx={sx} className={className} onClick={onClick}>
|
||||||
sx={sx}
|
<svg width={width} height={height} viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
className={className}
|
|
||||||
onClick={onClick}
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
width={width}
|
|
||||||
height={height}
|
|
||||||
viewBox="0 0 20 20"
|
|
||||||
fill="none"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
<path
|
||||||
d="M10 19C14.9706 19 19 14.9706 19 10C19 5.02944 14.9706 1 10 1C5.02944 1 1 5.02944 1 10C1 14.9706 5.02944 19 10 19Z"
|
d="M10 19C14.9706 19 19 14.9706 19 10C19 5.02944 14.9706 1 10 1C5.02944 1 1 5.02944 1 10C1 14.9706 5.02944 19 10 19Z"
|
||||||
stroke={color}
|
stroke={color}
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,27 +1,39 @@
|
|||||||
import { Box, useTheme } from "@mui/material";
|
import { Box, useTheme } from "@mui/material";
|
||||||
|
|
||||||
interface Props{
|
interface Props {
|
||||||
color?: string
|
color?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function UploadIcon({color= "#9A9AAF"}: Props) {
|
export default function UploadIcon({ color = "#9A9AAF" }: Props) {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
height: "32px",
|
height: "32px",
|
||||||
width: "32px",
|
width: "32px",
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" fill="none">
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" fill="none">
|
||||||
<path d="M10.75 10.25L16 5L21.25 10.25" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
|
<path
|
||||||
<path d="M16 19V5" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
|
d="M10.75 10.25L16 5L21.25 10.25"
|
||||||
<path d="M27 19V26C27 26.2652 26.8946 26.5196 26.7071 26.7071C26.5196 26.8946 26.2652 27 26 27H6C5.73478 27 5.48043 26.8946 5.29289 26.7071C5.10536 26.5196 5 26.2652 5 26V19" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
|
stroke={color}
|
||||||
</svg>
|
strokeWidth="2"
|
||||||
</Box>
|
strokeLinecap="round"
|
||||||
);
|
strokeLinejoin="round"
|
||||||
|
/>
|
||||||
|
<path d="M16 19V5" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
|
||||||
|
<path
|
||||||
|
d="M27 19V26C27 26.2652 26.8946 26.5196 26.7071 26.7071C26.5196 26.8946 26.2652 27 26 27H6C5.73478 27 5.48043 26.8946 5.29289 26.7071C5.10536 26.5196 5 26.2652 5 26V19"
|
||||||
|
stroke={color}
|
||||||
|
strokeWidth="2"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
}
|
}
|
@ -16,24 +16,9 @@ export default function FlagIcon({ color, width = 30 }: Props) {
|
|||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<svg
|
<svg width={width} height={width} viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
width={width}
|
<path d="M5 27V6" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
|
||||||
height={width}
|
<path d="M5 21.0016C13 15.0016 19 27.0016 27 21.0016V6.00158C19 12.0016 13 0.00158215 5 6.00158" fill={color} />
|
||||||
viewBox="0 0 32 32"
|
|
||||||
fill="none"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M5 27V6"
|
|
||||||
stroke={color}
|
|
||||||
strokeWidth="2"
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M5 21.0016C13 15.0016 19 27.0016 27 21.0016V6.00158C19 12.0016 13 0.00158215 5 6.00158"
|
|
||||||
fill={color}
|
|
||||||
/>
|
|
||||||
<path
|
<path
|
||||||
d="M5 21.0016C13 15.0016 19 27.0016 27 21.0016V6.00158C19 12.0016 13 0.00158203 5 6.00158"
|
d="M5 21.0016C13 15.0016 19 27.0016 27 21.0016V6.00158C19 12.0016 13 0.00158203 5 6.00158"
|
||||||
stroke={color}
|
stroke={color}
|
||||||
|
@ -5,7 +5,7 @@ interface Props {
|
|||||||
width?: number;
|
width?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function HashtagIcon({ color, width = 30, }: Props) {
|
export default function HashtagIcon({ color, width = 30 }: Props) {
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
@ -16,13 +16,7 @@ export default function HashtagIcon({ color, width = 30, }: Props) {
|
|||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<svg
|
<svg width={width} height={width} viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
width={width}
|
|
||||||
height={width}
|
|
||||||
viewBox="0 0 32 32"
|
|
||||||
fill="none"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
<path
|
||||||
d="M3 11.3333H29M3 20.6667H29M13.6364 2L8.90909 30M23.0909 2L18.3636 30"
|
d="M3 11.3333H29M3 20.6667H29M13.6364 2L8.90909 30M23.0909 2L18.3636 30"
|
||||||
stroke={color}
|
stroke={color}
|
||||||
|
@ -2,7 +2,7 @@ import { Box } from "@mui/material";
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
color: string;
|
color: string;
|
||||||
width: number
|
width: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function HeartIcon({ color, width }: Props) {
|
export default function HeartIcon({ color, width }: Props) {
|
||||||
@ -16,13 +16,7 @@ export default function HeartIcon({ color, width }: Props) {
|
|||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<svg
|
<svg width={width} height={width} viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
width={width}
|
|
||||||
height={width}
|
|
||||||
viewBox="0 0 32 32"
|
|
||||||
fill="none"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
<path
|
||||||
d="M16 27C16 27 3.5 20 3.5 11.5C3.5 9.99737 4.02062 8.54114 4.97328 7.37908C5.92593 6.21703 7.25178 5.42093 8.72525 5.12624C10.1987 4.83154 11.7288 5.05646 13.0551 5.76272C14.3814 6.46898 15.4221 7.61296 16 9.00001C16.5779 7.61296 17.6186 6.46898 18.9449 5.76272C20.2712 5.05646 21.8013 4.83154 23.2748 5.12624C24.7482 5.42093 26.0741 6.21703 27.0267 7.37908C27.9794 8.54114 28.5 9.99737 28.5 11.5C28.5 20 16 27 16 27Z"
|
d="M16 27C16 27 3.5 20 3.5 11.5C3.5 9.99737 4.02062 8.54114 4.97328 7.37908C5.92593 6.21703 7.25178 5.42093 8.72525 5.12624C10.1987 4.83154 11.7288 5.05646 13.0551 5.76272C14.3814 6.46898 15.4221 7.61296 16 9.00001C16.5779 7.61296 17.6186 6.46898 18.9449 5.76272C20.2712 5.05646 21.8013 4.83154 23.2748 5.12624C24.7482 5.42093 26.0741 6.21703 27.0267 7.37908C27.9794 8.54114 28.5 9.99737 28.5 11.5C28.5 20 16 27 16 27Z"
|
||||||
fill={color}
|
fill={color}
|
||||||
|
@ -2,10 +2,10 @@ import { Box } from "@mui/material";
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
color: string;
|
color: string;
|
||||||
width: number
|
width: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function LightbulbIcon({ color , width }: Props) {
|
export default function LightbulbIcon({ color, width }: Props) {
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
@ -16,20 +16,8 @@ export default function LightbulbIcon({ color , width }: Props) {
|
|||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<svg
|
<svg width={width} height={width} viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
width={width}
|
<path d="M11 29H21" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
|
||||||
height={width}
|
|
||||||
viewBox="0 0 32 32"
|
|
||||||
fill="none"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M11 29H21"
|
|
||||||
stroke={color}
|
|
||||||
strokeWidth="2"
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
/>
|
|
||||||
<path
|
<path
|
||||||
d="M9.83761 20.8739C8.6471 19.9482 7.68288 18.7637 7.01801 17.4102C6.35313 16.0566 6.00504 14.5694 6.00011 13.0614C5.97511 7.6364 10.3376 3.1239 15.7626 2.9989C17.8622 2.94913 19.9242 3.56166 21.6561 4.74961C23.388 5.93756 24.7019 7.64064 25.4115 9.6173C26.1211 11.594 26.1904 13.7439 25.6094 15.7621C25.0285 17.7803 23.827 19.5644 22.1751 20.8614C21.8102 21.1435 21.5146 21.5052 21.311 21.919C21.1073 22.3328 21.001 22.7877 21.0001 23.2489V23.9989C21.0001 24.2641 20.8948 24.5185 20.7072 24.706C20.5197 24.8935 20.2653 24.9989 20.0001 24.9989H12.0001C11.7349 24.9989 11.4805 24.8935 11.293 24.706C11.1055 24.5185 11.0001 24.2641 11.0001 23.9989V23.2489C10.997 22.7912 10.8909 22.34 10.6896 21.9289C10.4884 21.5177 10.1972 21.1572 9.83761 20.8739V20.8739Z"
|
d="M9.83761 20.8739C8.6471 19.9482 7.68288 18.7637 7.01801 17.4102C6.35313 16.0566 6.00504 14.5694 6.00011 13.0614C5.97511 7.6364 10.3376 3.1239 15.7626 2.9989C17.8622 2.94913 19.9242 3.56166 21.6561 4.74961C23.388 5.93756 24.7019 7.64064 25.4115 9.6173C26.1211 11.594 26.1904 13.7439 25.6094 15.7621C25.0285 17.7803 23.827 19.5644 22.1751 20.8614C21.8102 21.1435 21.5146 21.5052 21.311 21.919C21.1073 22.3328 21.001 22.7877 21.0001 23.2489V23.9989C21.0001 24.2641 20.8948 24.5185 20.7072 24.706C20.5197 24.8935 20.2653 24.9989 20.0001 24.9989H12.0001C11.7349 24.9989 11.4805 24.8935 11.293 24.706C11.1055 24.5185 11.0001 24.2641 11.0001 23.9989V23.2489C10.997 22.7912 10.8909 22.34 10.6896 21.9289C10.4884 21.5177 10.1972 21.1572 9.83761 20.8739V20.8739Z"
|
||||||
stroke={color}
|
stroke={color}
|
||||||
|
@ -2,7 +2,7 @@ import { Box } from "@mui/material";
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
color: string;
|
color: string;
|
||||||
width: number
|
width: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function LikeIcon({ color, width }: Props) {
|
export default function LikeIcon({ color, width }: Props) {
|
||||||
@ -16,13 +16,7 @@ export default function LikeIcon({ color, width }: Props) {
|
|||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<svg
|
<svg width={width} height={width} viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
width={width}
|
|
||||||
height={width}
|
|
||||||
viewBox="0 0 40 40"
|
|
||||||
fill="none"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
<path
|
||||||
d="M8 17H14V30H8C7.73478 30 7.48043 29.8946 7.29289 29.7071C7.10536 29.5196 7 29.2652 7 29V18C7 17.7348 7.10536 17.4804 7.29289 17.2929C7.48043 17.1054 7.73478 17 8 17V17Z"
|
d="M8 17H14V30H8C7.73478 30 7.48043 29.8946 7.29289 29.7071C7.10536 29.5196 7 29.2652 7 29V18C7 17.7348 7.10536 17.4804 7.29289 17.2929C7.48043 17.1054 7.73478 17 8 17V17Z"
|
||||||
stroke={color}
|
stroke={color}
|
||||||
|
@ -2,7 +2,7 @@ import { Box } from "@mui/material";
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
color: string;
|
color: string;
|
||||||
width: number
|
width: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function TropfyIcon({ color, width }: Props) {
|
export default function TropfyIcon({ color, width }: Props) {
|
||||||
@ -16,13 +16,7 @@ export default function TropfyIcon({ color, width }: Props) {
|
|||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<svg
|
<svg width={width} height={width} viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
width={width}
|
|
||||||
height={width}
|
|
||||||
viewBox="0 0 32 32"
|
|
||||||
fill="none"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
<path
|
||||||
d="M7 7V13.8875C7 18.85 10.975 22.9625 15.9375 23C17.1246 23.0082 18.3017 22.7815 19.4008 22.3329C20.5 21.8843 21.4995 21.2227 22.3419 20.3862C23.1843 19.5496 23.8528 18.5547 24.309 17.4586C24.7652 16.3626 25 15.1872 25 14V7C25 6.73478 24.8946 6.48043 24.7071 6.29289C24.5196 6.10536 24.2652 6 24 6H8C7.73478 6 7.48043 6.10536 7.29289 6.29289C7.10536 6.48043 7 6.73478 7 7Z"
|
d="M7 7V13.8875C7 18.85 10.975 22.9625 15.9375 23C17.1246 23.0082 18.3017 22.7815 19.4008 22.3329C20.5 21.8843 21.4995 21.2227 22.3419 20.3862C23.1843 19.5496 23.8528 18.5547 24.309 17.4586C24.7652 16.3626 25 15.1872 25 14V7C25 6.73478 24.8946 6.48043 24.7071 6.29289C24.5196 6.10536 24.2652 6 24 6H8C7.73478 6 7.48043 6.10536 7.29289 6.29289C7.10536 6.48043 7 6.73478 7 7Z"
|
||||||
fill={color}
|
fill={color}
|
||||||
@ -31,20 +25,8 @@ export default function TropfyIcon({ color, width }: Props) {
|
|||||||
strokeLinecap="round"
|
strokeLinecap="round"
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
/>
|
/>
|
||||||
<path
|
<path d="M12 28H20" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
|
||||||
d="M12 28H20"
|
<path d="M16 23V28" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
|
||||||
stroke={color}
|
|
||||||
strokeWidth="2"
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M16 23V28"
|
|
||||||
stroke={color}
|
|
||||||
strokeWidth="2"
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
/>
|
|
||||||
<path
|
<path
|
||||||
d="M24.7754 16H26.0004C27.0613 16 28.0787 15.5786 28.8288 14.8284C29.579 14.0783 30.0004 13.0609 30.0004 12V10C30.0004 9.73478 29.895 9.48043 29.7075 9.29289C29.52 9.10536 29.2656 9 29.0004 9H25.0004"
|
d="M24.7754 16H26.0004C27.0613 16 28.0787 15.5786 28.8288 14.8284C29.579 14.0783 30.0004 13.0609 30.0004 12V10C30.0004 9.73478 29.895 9.48043 29.7075 9.29289C29.52 9.10536 29.2656 9 29.0004 9H25.0004"
|
||||||
stroke={color}
|
stroke={color}
|
||||||
|
@ -1,20 +1,9 @@
|
|||||||
import {
|
import { startTransition, useEffect, useLayoutEffect, useRef, useState } from "react";
|
||||||
startTransition,
|
|
||||||
useEffect,
|
|
||||||
useLayoutEffect,
|
|
||||||
useRef,
|
|
||||||
useState,
|
|
||||||
} from "react";
|
|
||||||
import { ErrorBoundary } from "react-error-boundary";
|
import { ErrorBoundary } from "react-error-boundary";
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
import { SnackbarProvider } from "notistack";
|
import { SnackbarProvider } from "notistack";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import {
|
import { Box, ScopedCssBaseline, CssBaseline, ThemeProvider } from "@mui/material";
|
||||||
Box,
|
|
||||||
ScopedCssBaseline,
|
|
||||||
CssBaseline,
|
|
||||||
ThemeProvider,
|
|
||||||
} from "@mui/material";
|
|
||||||
import { LocalizationProvider } from "@mui/x-date-pickers";
|
import { LocalizationProvider } from "@mui/x-date-pickers";
|
||||||
import { AdapterMoment } from "@mui/x-date-pickers/AdapterMoment";
|
import { AdapterMoment } from "@mui/x-date-pickers/AdapterMoment";
|
||||||
import { ruRU } from "@mui/x-date-pickers/locales";
|
import { ruRU } from "@mui/x-date-pickers/locales";
|
||||||
@ -38,8 +27,7 @@ import lightTheme from "@utils/themes/light";
|
|||||||
import type { QuizSettings } from "@model/settingsData";
|
import type { QuizSettings } from "@model/settingsData";
|
||||||
|
|
||||||
moment.locale("ru");
|
moment.locale("ru");
|
||||||
const localeText =
|
const localeText = ruRU.components.MuiLocalizationProvider.defaultProps.localeText;
|
||||||
ruRU.components.MuiLocalizationProvider.defaultProps.localeText;
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
quizSettings?: QuizSettings;
|
quizSettings?: QuizSettings;
|
||||||
@ -59,9 +47,7 @@ function QuizAnswererInner({
|
|||||||
disableGlobalCss = false,
|
disableGlobalCss = false,
|
||||||
}: Props) {
|
}: Props) {
|
||||||
const [quizViewStore] = useState(createQuizViewStore);
|
const [quizViewStore] = useState(createQuizViewStore);
|
||||||
const [rootContainerWidth, setRootContainerWidth] = useState<number>(
|
const [rootContainerWidth, setRootContainerWidth] = useState<number>(() => window.innerWidth);
|
||||||
() => window.innerWidth
|
|
||||||
);
|
|
||||||
const rootContainerRef = useRef<HTMLDivElement>(null);
|
const rootContainerRef = useRef<HTMLDivElement>(null);
|
||||||
const { data, error, isLoading } = useSWR(
|
const { data, error, isLoading } = useSWR(
|
||||||
quizSettings ? null : ["quizData", quizId],
|
quizSettings ? null : ["quizData", quizId],
|
||||||
@ -73,12 +59,8 @@ function QuizAnswererInner({
|
|||||||
refreshInterval: 0,
|
refreshInterval: 0,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
const vkMetrics = useVkMetricsGoals(
|
const vkMetrics = useVkMetricsGoals(quizSettings?.settings.cfg.vkMetricsNumber);
|
||||||
quizSettings?.settings.cfg.vkMetricsNumber
|
const yandexMetrics = useYandexMetricsGoals(quizSettings?.settings.cfg.yandexMetricsNumber);
|
||||||
);
|
|
||||||
const yandexMetrics = useYandexMetricsGoals(
|
|
||||||
quizSettings?.settings.cfg.yandexMetricsNumber
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@ -88,15 +70,13 @@ function QuizAnswererInner({
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
if (rootContainerRef.current)
|
if (rootContainerRef.current) setRootContainerWidth(rootContainerRef.current.clientWidth);
|
||||||
setRootContainerWidth(rootContainerRef.current.clientWidth);
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleWindowResize = () => {
|
const handleWindowResize = () => {
|
||||||
startTransition(() => {
|
startTransition(() => {
|
||||||
if (rootContainerRef.current)
|
if (rootContainerRef.current) setRootContainerWidth(rootContainerRef.current.clientWidth);
|
||||||
setRootContainerWidth(rootContainerRef.current.clientWidth);
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
window.addEventListener("resize", handleWindowResize);
|
window.addEventListener("resize", handleWindowResize);
|
||||||
@ -112,8 +92,7 @@ function QuizAnswererInner({
|
|||||||
quizSettings ??= data;
|
quizSettings ??= data;
|
||||||
if (!quizSettings) throw new Error("Quiz data is null");
|
if (!quizSettings) throw new Error("Quiz data is null");
|
||||||
|
|
||||||
if (quizSettings.questions.length === 0)
|
if (quizSettings.questions.length === 0) return <ApologyPage error={new Error("No questions found")} />;
|
||||||
return <ApologyPage error={new Error("No questions found")} />;
|
|
||||||
if (!quizId) return <ApologyPage error={new Error("No quiz id")} />;
|
if (!quizId) return <ApologyPage error={new Error("No quiz id")} />;
|
||||||
|
|
||||||
const quizContainer = (
|
const quizContainer = (
|
||||||
@ -126,10 +105,7 @@ function QuizAnswererInner({
|
|||||||
position: "relative",
|
position: "relative",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ErrorBoundary
|
<ErrorBoundary FallbackComponent={ApologyPage} onError={handleComponentError}>
|
||||||
FallbackComponent={ApologyPage}
|
|
||||||
onError={handleComponentError}
|
|
||||||
>
|
|
||||||
<ViewPublicationPage />
|
<ViewPublicationPage />
|
||||||
</ErrorBoundary>
|
</ErrorBoundary>
|
||||||
</Box>
|
</Box>
|
||||||
@ -138,9 +114,7 @@ function QuizAnswererInner({
|
|||||||
return (
|
return (
|
||||||
<QuizViewContext.Provider value={quizViewStore}>
|
<QuizViewContext.Provider value={quizViewStore}>
|
||||||
<RootContainerWidthContext.Provider value={rootContainerWidth}>
|
<RootContainerWidthContext.Provider value={rootContainerWidth}>
|
||||||
<QuizDataContext.Provider
|
<QuizDataContext.Provider value={{ ...quizSettings, quizId, preview, changeFaviconAndTitle }}>
|
||||||
value={{ ...quizSettings, quizId, preview, changeFaviconAndTitle }}
|
|
||||||
>
|
|
||||||
{disableGlobalCss ? (
|
{disableGlobalCss ? (
|
||||||
<ScopedCssBaseline
|
<ScopedCssBaseline
|
||||||
sx={{
|
sx={{
|
||||||
@ -162,16 +136,9 @@ function QuizAnswererInner({
|
|||||||
|
|
||||||
export default function QuizAnswerer(props: Props) {
|
export default function QuizAnswerer(props: Props) {
|
||||||
return (
|
return (
|
||||||
<LocalizationProvider
|
<LocalizationProvider dateAdapter={AdapterMoment} adapterLocale="ru" localeText={localeText}>
|
||||||
dateAdapter={AdapterMoment}
|
|
||||||
adapterLocale="ru"
|
|
||||||
localeText={localeText}
|
|
||||||
>
|
|
||||||
<ThemeProvider theme={lightTheme}>
|
<ThemeProvider theme={lightTheme}>
|
||||||
<SnackbarProvider
|
<SnackbarProvider preventDuplicate={true} style={{ backgroundColor: lightTheme.palette.brightPurple.main }}>
|
||||||
preventDuplicate={true}
|
|
||||||
style={{ backgroundColor: lightTheme.palette.brightPurple.main }}
|
|
||||||
>
|
|
||||||
<QuizAnswererInner {...props} />
|
<QuizAnswererInner {...props} />
|
||||||
</SnackbarProvider>
|
</SnackbarProvider>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
|
@ -4,30 +4,32 @@ import { FallbackProps } from "react-error-boundary";
|
|||||||
type Props = Partial<FallbackProps>;
|
type Props = Partial<FallbackProps>;
|
||||||
|
|
||||||
export const ApologyPage = ({ error }: Props) => {
|
export const ApologyPage = ({ error }: Props) => {
|
||||||
let message = "Что-то пошло не так";
|
let message = "Что-то пошло не так";
|
||||||
|
|
||||||
if (error.response?.data === "quiz is inactive") message = "Квиз не активирован";
|
if (error.response?.data === "quiz is inactive") message = "Квиз не активирован";
|
||||||
if (error.message === "No questions found") message = "Нет созданных вопросов";
|
if (error.message === "No questions found") message = "Нет созданных вопросов";
|
||||||
if (error.message === "Quiz already completed") message = "Вы уже прошли этот опрос";
|
if (error.message === "Quiz already completed") message = "Вы уже прошли этот опрос";
|
||||||
if (error.message === "No quiz id") message = "Отсутствует id квиза";
|
if (error.message === "No quiz id") message = "Отсутствует id квиза";
|
||||||
if (error.response?.data === "Invalid request data") message = "Такого квиза не существует";
|
if (error.response?.data === "Invalid request data") message = "Такого квиза не существует";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
height: "100%",
|
height: "100%",
|
||||||
backgroundColor: "#F2F3F7",
|
backgroundColor: "#F2F3F7",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography
|
<Typography
|
||||||
sx={{
|
sx={{
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
color: "text.primary",
|
color: "text.primary",
|
||||||
}}
|
}}
|
||||||
>{message}</Typography>
|
>
|
||||||
</Box>
|
{message}
|
||||||
);
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
@ -21,10 +21,7 @@ import { DESIGN_LIST } from "@utils/designList";
|
|||||||
|
|
||||||
import { NameplateLogo } from "@icons/NameplateLogo";
|
import { NameplateLogo } from "@icons/NameplateLogo";
|
||||||
|
|
||||||
import type {
|
import type { FormContactFieldData, FormContactFieldName } from "@model/settingsData";
|
||||||
FormContactFieldData,
|
|
||||||
FormContactFieldName,
|
|
||||||
} from "@model/settingsData";
|
|
||||||
import type { QuizQuestionResult } from "@model/questionTypes/result";
|
import type { QuizQuestionResult } from "@model/questionTypes/result";
|
||||||
import type { AnyTypedQuizQuestion } from "@model/questionTypes/shared";
|
import type { AnyTypedQuizQuestion } from "@model/questionTypes/shared";
|
||||||
|
|
||||||
@ -69,18 +66,12 @@ export const ContactForm = ({ currentQuestion, onShowResult }: Props) => {
|
|||||||
currentQuestion.type === "result"
|
currentQuestion.type === "result"
|
||||||
? currentQuestion
|
? currentQuestion
|
||||||
: questions.find((question): question is QuizQuestionResult => {
|
: questions.find((question): question is QuizQuestionResult => {
|
||||||
if (settings?.cfg.haveRoot) {
|
if (settings?.cfg.haveRoot) {
|
||||||
return (
|
return question.type === "result" && question.content.rule.parentId === currentQuestion.content.id;
|
||||||
question.type === "result" &&
|
} else {
|
||||||
question.content.rule.parentId === currentQuestion.content.id
|
return question.type === "result" && question.content.rule.parentId === "line";
|
||||||
);
|
}
|
||||||
} else {
|
});
|
||||||
return (
|
|
||||||
question.type === "result" &&
|
|
||||||
question.content.rule.parentId === "line"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!resultQuestion) throw new Error("Result question not found");
|
if (!resultQuestion) throw new Error("Result question not found");
|
||||||
|
|
||||||
@ -103,10 +94,7 @@ export const ContactForm = ({ currentQuestion, onShowResult }: Props) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const sessions = JSON.parse(localStorage.getItem("sessions") || "{}");
|
const sessions = JSON.parse(localStorage.getItem("sessions") || "{}");
|
||||||
localStorage.setItem(
|
localStorage.setItem("sessions", JSON.stringify({ ...sessions, [quizId]: new Date().getTime() }));
|
||||||
"sessions",
|
|
||||||
JSON.stringify({ ...sessions, [quizId]: new Date().getTime() })
|
|
||||||
);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
enqueueSnackbar("ответ не был засчитан");
|
enqueueSnackbar("ответ не был засчитан");
|
||||||
}
|
}
|
||||||
@ -116,9 +104,7 @@ export const ContactForm = ({ currentQuestion, onShowResult }: Props) => {
|
|||||||
const FCcopy: Record<FormContactFieldName, FormContactFieldData> =
|
const FCcopy: Record<FormContactFieldName, FormContactFieldData> =
|
||||||
settings.cfg.formContact.fields || settings.cfg.formContact;
|
settings.cfg.formContact.fields || settings.cfg.formContact;
|
||||||
|
|
||||||
const filteredFC: Partial<
|
const filteredFC: Partial<Record<FormContactFieldName, FormContactFieldData>> = {};
|
||||||
Record<FormContactFieldName, FormContactFieldData>
|
|
||||||
> = {};
|
|
||||||
for (const i in FCcopy) {
|
for (const i in FCcopy) {
|
||||||
const field = FCcopy[i as keyof typeof FCcopy];
|
const field = FCcopy[i as keyof typeof FCcopy];
|
||||||
if (field.used) {
|
if (field.used) {
|
||||||
@ -133,13 +119,7 @@ export const ContactForm = ({ currentQuestion, onShowResult }: Props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (fireOnce.current) {
|
if (fireOnce.current) {
|
||||||
if (
|
if (name.length === 0 && email.length === 0 && phone.length === 0 && text.length === 0 && adress.length === 0)
|
||||||
name.length === 0 &&
|
|
||||||
email.length === 0 &&
|
|
||||||
phone.length === 0 &&
|
|
||||||
text.length === 0 &&
|
|
||||||
adress.length === 0
|
|
||||||
)
|
|
||||||
return enqueueSnackbar("Пожалуйста, заполните поля");
|
return enqueueSnackbar("Пожалуйста, заполните поля");
|
||||||
|
|
||||||
//почта валидна, хоть одно поле заполнено
|
//почта валидна, хоть одно поле заполнено
|
||||||
@ -189,172 +169,168 @@ export const ContactForm = ({ currentQuestion, onShowResult }: Props) => {
|
|||||||
yandexMetrics.contactsFormOpened();
|
yandexMetrics.contactsFormOpened();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
backgroundColor: theme.palette.background.default,
|
||||||
|
height: screenHeight > 500 ? "100%" : "auto",
|
||||||
|
overflow: "auto",
|
||||||
|
"&::-webkit-scrollbar": {
|
||||||
|
width: "0",
|
||||||
|
display: "none",
|
||||||
|
msOverflowStyle: "none",
|
||||||
|
},
|
||||||
|
scrollbarWidth: "none",
|
||||||
|
msOverflowStyle: "none",
|
||||||
|
backgroundPosition: "center",
|
||||||
|
backgroundSize: "cover",
|
||||||
|
backgroundImage:
|
||||||
|
settings.cfg.design && !isMobile
|
||||||
|
? quizThemes[settings.cfg.theme].isLight
|
||||||
|
? `url(${DESIGN_LIST[settings.cfg.theme]})`
|
||||||
|
: `linear-gradient(90deg, rgba(39, 38, 38, 0.95) 7.66%, rgba(42, 42, 46, 0.85) 42.12%, rgba(51, 54, 71, 0.4) 100%), url(${
|
||||||
|
DESIGN_LIST[settings.cfg.theme]
|
||||||
|
})`
|
||||||
|
: null,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
width: !isMobile ? "100%" : isMobile ? undefined : "530px",
|
||||||
|
borderRadius: "4px",
|
||||||
|
height: isMobile ? "100%" : "auto",
|
||||||
|
minHeight: "100%",
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: isMobile ? "column" : "row",
|
||||||
|
background: settings.cfg.design && !isMobile ? undefined : theme.palette.background.default,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ContactTextBlock settings={settings} />
|
||||||
<Box
|
<Box
|
||||||
|
sx={{
|
||||||
|
flexGrow: isMobile ? 1 : 0,
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
flexDirection: "column",
|
||||||
|
backgroundColor: theme.palette.background.default,
|
||||||
|
height: "auto",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: isMobile ? undefined : "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
flexDirection: "column",
|
||||||
|
p: isMobile ? "0 20px" : isTablet ? "105px 40px 0 60px" : "105px 60px 0 60px",
|
||||||
|
margin: isMobile ? "0" : "auto 0",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
mt: isMobile ? "10px" : "20px",
|
||||||
|
mb: "20px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Inputs
|
||||||
|
name={name}
|
||||||
|
setName={setName}
|
||||||
|
email={email}
|
||||||
|
setEmail={setEmail}
|
||||||
|
phone={phone}
|
||||||
|
setPhone={setPhone}
|
||||||
|
text={text}
|
||||||
|
setText={setText}
|
||||||
|
adress={adress}
|
||||||
|
setAdress={setAdress}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
width: isMobile ? "300px" : "390px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<CustomCheckbox
|
||||||
|
label=""
|
||||||
|
handleChange={({ target }) => {
|
||||||
|
setReady(target.checked);
|
||||||
|
}}
|
||||||
|
checked={ready}
|
||||||
|
colorIcon={theme.palette.primary.main}
|
||||||
|
sx={{ marginRight: "0" }}
|
||||||
|
/>
|
||||||
|
<Typography
|
||||||
|
sx={{
|
||||||
|
color: theme.palette.text.primary,
|
||||||
|
lineHeight: "18.96px",
|
||||||
|
}}
|
||||||
|
fontSize={"16px"}
|
||||||
|
>
|
||||||
|
С 
|
||||||
|
<Link href={"https://shub.pena.digital/ppdd"} target="_blank">
|
||||||
|
Положением об обработке персональных данных{" "}
|
||||||
|
</Link>
|
||||||
|
 и 
|
||||||
|
<Link href={"https://shub.pena.digital/docs/privacy"} target="_blank">
|
||||||
|
{" "}
|
||||||
|
Политикой конфиденциальности{" "}
|
||||||
|
</Link>
|
||||||
|
 ознакомлен
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
disabled={!(ready && !fire)}
|
||||||
|
variant="contained"
|
||||||
|
onClick={handleShowResultsClick}
|
||||||
|
sx={{
|
||||||
|
border: `1px solid ${theme.palette.primary.main}`,
|
||||||
|
margin: isMobile ? "auto" : undefined,
|
||||||
|
mt: "20px",
|
||||||
|
p: "10px 20px",
|
||||||
|
"&:disabled": {
|
||||||
|
border: "1px solid #9A9AAF",
|
||||||
|
color: "#9A9AAF",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{settings.cfg.formContact?.button || "Получить результаты"}
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
{show_badge && (
|
||||||
|
<Box
|
||||||
|
component={Link}
|
||||||
|
target={"_blank"}
|
||||||
|
href={`https://${
|
||||||
|
window.location.hostname.includes("s") ? "s" : ""
|
||||||
|
}quiz.pena.digital/squiz/quiz/logo?q=${quizId}`}
|
||||||
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
justifyContent: "center",
|
mt: "55px",
|
||||||
backgroundColor: theme.palette.background.default,
|
mb: isMobile ? "30px" : isTablet ? "40px" : "50px",
|
||||||
height: screenHeight > 500 ? "100%" : "auto",
|
gap: "10px",
|
||||||
overflow: "auto",
|
textDecoration: "none",
|
||||||
"&::-webkit-scrollbar": {
|
margitTop: "auto",
|
||||||
width: "0",
|
}}
|
||||||
display: "none",
|
|
||||||
msOverflowStyle: "none",
|
|
||||||
},
|
|
||||||
scrollbarWidth: "none",
|
|
||||||
msOverflowStyle: "none",
|
|
||||||
backgroundPosition: "center",
|
|
||||||
backgroundSize: "cover",
|
|
||||||
backgroundImage:
|
|
||||||
settings.cfg.design && !isMobile
|
|
||||||
? quizThemes[settings.cfg.theme].isLight
|
|
||||||
? `url(${DESIGN_LIST[settings.cfg.theme]})`
|
|
||||||
: `linear-gradient(90deg, rgba(39, 38, 38, 0.95) 7.66%, rgba(42, 42, 46, 0.85) 42.12%, rgba(51, 54, 71, 0.4) 100%), url(${DESIGN_LIST[settings.cfg.theme]
|
|
||||||
})`
|
|
||||||
: null,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
width: !isMobile ? "100%" : isMobile ? undefined : "530px",
|
|
||||||
borderRadius: "4px",
|
|
||||||
height: isMobile ? "100%" : "auto",
|
|
||||||
minHeight: "100%",
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: isMobile ? "column" : "row",
|
|
||||||
background:
|
|
||||||
settings.cfg.design && !isMobile
|
|
||||||
? undefined
|
|
||||||
: theme.palette.background.default,
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<ContactTextBlock settings={settings}/>
|
<NameplateLogo
|
||||||
<Box sx={{
|
style={{
|
||||||
flexGrow: isMobile ? 1 : 0,
|
fontSize: "20px",
|
||||||
display: "flex",
|
color: quizThemes[settings.cfg.theme].isLight ? "#151515" : "#FFFFFF",
|
||||||
alignItems: "center",
|
}}
|
||||||
justifyContent: "space-between",
|
/>
|
||||||
flexDirection: "column",
|
|
||||||
backgroundColor: theme.palette.background.default,
|
|
||||||
height: "auto",
|
|
||||||
}}>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
display: "flex",
|
|
||||||
alignItems: isMobile ? undefined : "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
flexDirection: "column",
|
|
||||||
p: isMobile ? "0 20px" : isTablet ? "105px 40px 0 60px" : "105px 60px 0 60px",
|
|
||||||
margin: isMobile ? "0" : "auto 0",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
mt: isMobile ? "10px" : "20px",
|
|
||||||
mb: "20px"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Inputs
|
|
||||||
name={name}
|
|
||||||
setName={setName}
|
|
||||||
email={email}
|
|
||||||
setEmail={setEmail}
|
|
||||||
phone={phone}
|
|
||||||
setPhone={setPhone}
|
|
||||||
text={text}
|
|
||||||
setText={setText}
|
|
||||||
adress={adress}
|
|
||||||
setAdress={setAdress}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
display: "flex",
|
|
||||||
width: isMobile ? "300px" : "390px",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<CustomCheckbox
|
|
||||||
label=""
|
|
||||||
handleChange={({target}) => {
|
|
||||||
setReady(target.checked);
|
|
||||||
}}
|
|
||||||
checked={ready}
|
|
||||||
colorIcon={theme.palette.primary.main}
|
|
||||||
sx={{marginRight: "0"}}
|
|
||||||
/>
|
|
||||||
<Typography sx={{
|
|
||||||
color: theme.palette.text.primary,
|
|
||||||
lineHeight: "18.96px"
|
|
||||||
}} fontSize={"16px"}>
|
|
||||||
С 
|
|
||||||
<Link href={"https://shub.pena.digital/ppdd"}
|
|
||||||
target="_blank">
|
|
||||||
Положением об обработке персональных
|
|
||||||
данных{" "}
|
|
||||||
</Link>
|
|
||||||
 и 
|
|
||||||
<Link
|
|
||||||
href={"https://shub.pena.digital/docs/privacy"}
|
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
{" "}
|
|
||||||
Политикой конфиденциальности{" "}
|
|
||||||
</Link>
|
|
||||||
 ознакомлен
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
disabled={!(ready && !fire)}
|
|
||||||
variant="contained"
|
|
||||||
onClick={handleShowResultsClick}
|
|
||||||
sx={{
|
|
||||||
border: `1px solid ${theme.palette.primary.main}`,
|
|
||||||
margin: isMobile ? "auto" : undefined,
|
|
||||||
mt: "20px",
|
|
||||||
p: "10px 20px",
|
|
||||||
"&:disabled": {
|
|
||||||
border: "1px solid #9A9AAF",
|
|
||||||
color: "#9A9AAF",
|
|
||||||
},
|
|
||||||
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{settings.cfg.formContact?.button || "Получить результаты"}
|
|
||||||
</Button>
|
|
||||||
</Box>
|
|
||||||
{show_badge && (
|
|
||||||
<Box
|
|
||||||
component={Link}
|
|
||||||
target={"_blank"}
|
|
||||||
href={`https://${window.location.hostname.includes("s") ? "s" : ""
|
|
||||||
}quiz.pena.digital/squiz/quiz/logo?q=${quizId}`}
|
|
||||||
sx={{
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
mt: "55px",
|
|
||||||
mb: isMobile ? "30px" : isTablet ? "40px" : "50px",
|
|
||||||
gap: "10px",
|
|
||||||
textDecoration: "none",
|
|
||||||
margitTop: "auto",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<NameplateLogo
|
|
||||||
style={{
|
|
||||||
fontSize: "20px",
|
|
||||||
color: quizThemes[settings.cfg.theme].isLight
|
|
||||||
? "#151515"
|
|
||||||
: "#FFFFFF",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
</Box>
|
|
||||||
</Box>
|
</Box>
|
||||||
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
);
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,66 +1,65 @@
|
|||||||
import {Box, Typography, useTheme} from "@mui/material";
|
import { Box, Typography, useTheme } from "@mui/material";
|
||||||
import {useRootContainerSize} from "@contexts/RootContainerWidthContext.ts";
|
import { useRootContainerSize } from "@contexts/RootContainerWidthContext.ts";
|
||||||
import {QuizSettingsConfig} from "@model/settingsData.ts";
|
import { QuizSettingsConfig } from "@model/settingsData.ts";
|
||||||
import {FC} from "react";
|
import { FC } from "react";
|
||||||
|
|
||||||
type ContactTextBlockProps = {
|
type ContactTextBlockProps = {
|
||||||
settings: QuizSettingsConfig;
|
settings: QuizSettingsConfig;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const ContactTextBlock: FC<ContactTextBlockProps> = ({settings}) => {
|
export const ContactTextBlock: FC<ContactTextBlockProps> = ({ settings }) => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const isMobile = useRootContainerSize() < 850;
|
const isMobile = useRootContainerSize() < 850;
|
||||||
const isTablet = useRootContainerSize() < 1000;
|
const isTablet = useRootContainerSize() < 1000;
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
flexGrow: isMobile ? 0 : 1,
|
flexGrow: isMobile ? 0 : 1,
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
borderRight: isMobile ? undefined : "1px solid #9A9AAF80",
|
borderRight: isMobile ? undefined : "1px solid #9A9AAF80",
|
||||||
margin: isMobile ? 0 : "40px 0",
|
margin: isMobile ? 0 : "40px 0",
|
||||||
padding: isMobile ? "0" : "0 40px"
|
padding: isMobile ? "0" : "0 40px",
|
||||||
}}
|
}}
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
maxWidth: isMobile ? "100%" : isTablet ? "410px" : "630px",
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
alignItems: "flex-start",
|
||||||
|
justifyContent: "center",
|
||||||
|
padding: isMobile ? "40px 20px 0 20px" : "0",
|
||||||
|
mt: isMobile ? 0 : isTablet ? "-180px" : "-47px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography
|
||||||
|
sx={{
|
||||||
|
textAlign: isTablet ? undefined : "center",
|
||||||
|
fontSize: "24px",
|
||||||
|
lineHeight: "normal",
|
||||||
|
fontWeight: 501,
|
||||||
|
color: theme.palette.text.primary,
|
||||||
|
wordBreak: "break-word",
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Box
|
{settings.cfg.formContact.title || "Заполните форму, чтобы получить результаты теста"}
|
||||||
sx={{
|
</Typography>
|
||||||
maxWidth: isMobile ? "100%" : isTablet ? "410px" : "630px",
|
{settings.cfg.formContact.desc && (
|
||||||
display: "flex",
|
<Typography
|
||||||
flexDirection: "column",
|
sx={{
|
||||||
alignItems: "flex-start",
|
color: theme.palette.text.primary,
|
||||||
justifyContent: "center",
|
m: "20px 0",
|
||||||
padding: isMobile ? "40px 20px 0 20px" : "0",
|
fontSize: "18px",
|
||||||
mt: isMobile ? 0 : isTablet ? "-180px" : "-47px",
|
wordBreak: "break-word",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography
|
{settings.cfg.formContact.desc}
|
||||||
sx={{
|
</Typography>
|
||||||
textAlign: isTablet ? undefined : "center",
|
)}
|
||||||
fontSize: "24px",
|
</Box>
|
||||||
lineHeight: "normal",
|
</Box>
|
||||||
fontWeight: 501,
|
);
|
||||||
color: theme.palette.text.primary,
|
};
|
||||||
wordBreak: "break-word",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{settings.cfg.formContact.title ||
|
|
||||||
"Заполните форму, чтобы получить результаты теста"}
|
|
||||||
</Typography>
|
|
||||||
{settings.cfg.formContact.desc && (
|
|
||||||
<Typography
|
|
||||||
sx={{
|
|
||||||
color: theme.palette.text.primary,
|
|
||||||
m: "20px 0",
|
|
||||||
fontSize: "18px",
|
|
||||||
wordBreak: "break-word",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{settings.cfg.formContact.desc}
|
|
||||||
</Typography>
|
|
||||||
)}
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
@ -1,67 +1,65 @@
|
|||||||
import {MenuItem, Select, SelectChangeEvent, useTheme} from "@mui/material";
|
import { MenuItem, Select, SelectChangeEvent, useTheme } from "@mui/material";
|
||||||
import {Dispatch, FC, SetStateAction, useState} from "react";
|
import { Dispatch, FC, SetStateAction, useState } from "react";
|
||||||
import {phoneMasksByCountry} from "@utils/phoneMasksByCountry.tsx";
|
import { phoneMasksByCountry } from "@utils/phoneMasksByCountry.tsx";
|
||||||
import {Value} from "react-phone-number-input";
|
import { Value } from "react-phone-number-input";
|
||||||
|
|
||||||
type CountrySelectorProps = {
|
type CountrySelectorProps = {
|
||||||
setMask: Dispatch<SetStateAction<string>>;
|
setMask: Dispatch<SetStateAction<string>>;
|
||||||
}
|
|
||||||
|
|
||||||
export const CountrySelector: FC<CountrySelectorProps> = ({setMask}) => {
|
|
||||||
const theme = useTheme();
|
|
||||||
const [country, setCountry] = useState('RU');
|
|
||||||
|
|
||||||
const handleChange = (e: SelectChangeEvent<Value>) => {
|
|
||||||
setCountry(e.target.value);
|
|
||||||
setMask(phoneMasksByCountry[e.target.value][1]);
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<Select
|
|
||||||
//@ts-ignore
|
|
||||||
value={country}
|
|
||||||
onChange={handleChange}
|
|
||||||
renderValue={(value) => value}
|
|
||||||
MenuProps={{
|
|
||||||
PaperProps: {
|
|
||||||
style: {
|
|
||||||
backgroundColor: theme.palette.background.default,
|
|
||||||
borderRadius: '12px',
|
|
||||||
scrollbarWidth: "none",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
sx={{
|
|
||||||
minWidth: 50,
|
|
||||||
backgroundColor: theme.palette.background.default,
|
|
||||||
"& .MuiSelect-select": {
|
|
||||||
paddingLeft: "5px",
|
|
||||||
paddingRight: "5px",
|
|
||||||
color: 'gray',
|
|
||||||
fontSize: "12px",
|
|
||||||
border: "none",
|
|
||||||
},
|
|
||||||
"& .MuiOutlinedInput-notchedOutline": {
|
|
||||||
border: "none",
|
|
||||||
},
|
|
||||||
"&:hover .MuiOutlinedInput-notchedOutline": {
|
|
||||||
border: "none",
|
|
||||||
},
|
|
||||||
"&:hover:before": {
|
|
||||||
border: "none",
|
|
||||||
},
|
|
||||||
"&.Mui-focused .MuiOutlinedInput-notchedOutline": {
|
|
||||||
border: "none",
|
|
||||||
},
|
|
||||||
"&.Mui-focused:hover .MuiOutlinedInput-notchedOutline": {
|
|
||||||
border: "none",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{Object.keys(phoneMasksByCountry).map((countryCode) => {
|
|
||||||
return <MenuItem
|
|
||||||
value={countryCode}>{phoneMasksByCountry[countryCode][0]}</MenuItem>
|
|
||||||
})}
|
|
||||||
</Select>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const CountrySelector: FC<CountrySelectorProps> = ({ setMask }) => {
|
||||||
|
const theme = useTheme();
|
||||||
|
const [country, setCountry] = useState("RU");
|
||||||
|
|
||||||
|
const handleChange = (e: SelectChangeEvent<Value>) => {
|
||||||
|
setCountry(e.target.value);
|
||||||
|
setMask(phoneMasksByCountry[e.target.value][1]);
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<Select
|
||||||
|
//@ts-ignore
|
||||||
|
value={country}
|
||||||
|
onChange={handleChange}
|
||||||
|
renderValue={(value) => value}
|
||||||
|
MenuProps={{
|
||||||
|
PaperProps: {
|
||||||
|
style: {
|
||||||
|
backgroundColor: theme.palette.background.default,
|
||||||
|
borderRadius: "12px",
|
||||||
|
scrollbarWidth: "none",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
sx={{
|
||||||
|
minWidth: 50,
|
||||||
|
backgroundColor: theme.palette.background.default,
|
||||||
|
"& .MuiSelect-select": {
|
||||||
|
paddingLeft: "5px",
|
||||||
|
paddingRight: "5px",
|
||||||
|
color: "gray",
|
||||||
|
fontSize: "12px",
|
||||||
|
border: "none",
|
||||||
|
},
|
||||||
|
"& .MuiOutlinedInput-notchedOutline": {
|
||||||
|
border: "none",
|
||||||
|
},
|
||||||
|
"&:hover .MuiOutlinedInput-notchedOutline": {
|
||||||
|
border: "none",
|
||||||
|
},
|
||||||
|
"&:hover:before": {
|
||||||
|
border: "none",
|
||||||
|
},
|
||||||
|
"&.Mui-focused .MuiOutlinedInput-notchedOutline": {
|
||||||
|
border: "none",
|
||||||
|
},
|
||||||
|
"&.Mui-focused:hover .MuiOutlinedInput-notchedOutline": {
|
||||||
|
border: "none",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{Object.keys(phoneMasksByCountry).map((countryCode) => {
|
||||||
|
return <MenuItem value={countryCode}>{phoneMasksByCountry[countryCode][0]}</MenuItem>;
|
||||||
|
})}
|
||||||
|
</Select>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
@ -1,91 +1,70 @@
|
|||||||
import {
|
import { Box, InputAdornment, TextField as MuiTextField, TextFieldProps, Typography, useTheme } from "@mui/material";
|
||||||
Box,
|
import { useRootContainerSize } from "@contexts/RootContainerWidthContext.ts";
|
||||||
InputAdornment,
|
import { useQuizData } from "@contexts/QuizDataContext.ts";
|
||||||
TextField as MuiTextField,
|
import { useIMask } from "react-imask";
|
||||||
TextFieldProps,
|
import { quizThemes } from "@utils/themes/Publication/themePublication.ts";
|
||||||
Typography,
|
import { FC, useState } from "react";
|
||||||
useTheme
|
import { CountrySelector } from "@/components/ViewPublicationPage/ContactForm/CustomInput/CountrySelector/CountrySelector.tsx";
|
||||||
} from "@mui/material";
|
import { phoneMasksByCountry } from "@utils/phoneMasksByCountry.tsx";
|
||||||
import {useRootContainerSize} from "@contexts/RootContainerWidthContext.ts";
|
|
||||||
import {useQuizData} from "@contexts/QuizDataContext.ts";
|
|
||||||
import {useIMask} from "react-imask";
|
|
||||||
import {quizThemes} from "@utils/themes/Publication/themePublication.ts";
|
|
||||||
import {FC, useState} from "react";
|
|
||||||
import {
|
|
||||||
CountrySelector
|
|
||||||
} from "@/components/ViewPublicationPage/ContactForm/CustomInput/CountrySelector/CountrySelector.tsx";
|
|
||||||
import {phoneMasksByCountry} from "@utils/phoneMasksByCountry.tsx";
|
|
||||||
|
|
||||||
type InputProps = {
|
type InputProps = {
|
||||||
title: string;
|
title: string;
|
||||||
desc: string;
|
desc: string;
|
||||||
Icon: FC<{ color: string; backgroundColor: string }>;
|
Icon: FC<{ color: string; backgroundColor: string }>;
|
||||||
onChange: TextFieldProps["onChange"];
|
onChange: TextFieldProps["onChange"];
|
||||||
id: string;
|
id: string;
|
||||||
isPhone?:boolean
|
isPhone?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const TextField = MuiTextField as unknown as FC<TextFieldProps>;
|
const TextField = MuiTextField as unknown as FC<TextFieldProps>;
|
||||||
|
|
||||||
|
export const CustomInput = ({ title, desc, Icon, onChange, isPhone }: InputProps) => {
|
||||||
|
const theme = useTheme();
|
||||||
|
const isMobile = useRootContainerSize() < 600;
|
||||||
|
const { settings } = useQuizData();
|
||||||
|
const [mask, setMask] = useState(phoneMasksByCountry["RU"][1]);
|
||||||
|
const { ref } = useIMask({ mask });
|
||||||
|
return (
|
||||||
|
<Box m="10px 0">
|
||||||
|
<Typography mb="7px" color={theme.palette.text.primary} fontSize={"16px"}>
|
||||||
|
{title}
|
||||||
|
</Typography>
|
||||||
|
|
||||||
export const CustomInput = ({ title, desc, Icon, onChange ,isPhone}: InputProps) => {
|
<TextField
|
||||||
const theme = useTheme();
|
inputRef={isPhone ? ref : null}
|
||||||
const isMobile = useRootContainerSize() < 600;
|
onChange={onChange}
|
||||||
const { settings } = useQuizData();
|
sx={{
|
||||||
const [mask, setMask] = useState(phoneMasksByCountry['RU'][1]);
|
width: isMobile ? "100%" : "390px",
|
||||||
const { ref } = useIMask({mask});
|
backgroundColor: theme.palette.background.default,
|
||||||
return (
|
fontSize: "16px",
|
||||||
<Box m="10px 0">
|
"& .MuiOutlinedInput-notchedOutline": {
|
||||||
<Typography mb="7px" color={theme.palette.text.primary} fontSize={"16px"}>
|
borderColor: "#9A9AAF80",
|
||||||
{title}
|
borderRadius: "12px",
|
||||||
</Typography>
|
},
|
||||||
|
"& .MuiInputBase-root": {
|
||||||
<TextField
|
paddingLeft: 0,
|
||||||
inputRef={isPhone? ref : null}
|
},
|
||||||
onChange={onChange}
|
"& .MuiOutlinedInput-input": {
|
||||||
sx={{
|
paddingLeft: "10px",
|
||||||
width: isMobile ? "100%" : "390px",
|
},
|
||||||
backgroundColor: theme.palette.background.default,
|
"& .MuiOutlinedInput-root": {
|
||||||
fontSize: "16px",
|
"&:hover fieldset": {
|
||||||
"& .MuiOutlinedInput-notchedOutline": {
|
borderColor: theme.palette.primary.main,
|
||||||
borderColor: "#9A9AAF80",
|
},
|
||||||
borderRadius: "12px",
|
},
|
||||||
},
|
}}
|
||||||
"& .MuiInputBase-root": {
|
placeholder={desc}
|
||||||
paddingLeft: 0,
|
InputProps={{
|
||||||
},
|
startAdornment: (
|
||||||
"& .MuiOutlinedInput-input": {
|
<InputAdornment position="start">
|
||||||
paddingLeft: "10px",
|
<Icon color="gray" backgroundColor={quizThemes[settings.cfg.theme].isLight ? "#F2F3F7" : "#F2F3F71A"} />
|
||||||
},
|
</InputAdornment>
|
||||||
"& .MuiOutlinedInput-root": {
|
),
|
||||||
"&:hover fieldset": {
|
endAdornment: (
|
||||||
borderColor: theme.palette.primary.main,
|
<InputAdornment position="end">{isPhone && <CountrySelector setMask={setMask} />}</InputAdornment>
|
||||||
},
|
),
|
||||||
},
|
}}
|
||||||
}}
|
/>
|
||||||
placeholder={desc}
|
</Box>
|
||||||
InputProps={{
|
);
|
||||||
startAdornment: (
|
|
||||||
<InputAdornment position="start" >
|
|
||||||
<Icon
|
|
||||||
color="gray"
|
|
||||||
backgroundColor={
|
|
||||||
quizThemes[settings.cfg.theme].isLight
|
|
||||||
? "#F2F3F7"
|
|
||||||
: "#F2F3F71A"
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</InputAdornment>
|
|
||||||
),
|
|
||||||
endAdornment: (
|
|
||||||
<InputAdornment position="end">
|
|
||||||
{isPhone && (
|
|
||||||
<CountrySelector setMask={setMask} />)}
|
|
||||||
</InputAdornment>
|
|
||||||
),
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
@ -1,107 +1,105 @@
|
|||||||
import {useQuizData} from "@contexts/QuizDataContext.ts";
|
import { useQuizData } from "@contexts/QuizDataContext.ts";
|
||||||
import NameIcon from "@icons/ContactFormIcon/NameIcon.tsx";
|
import NameIcon from "@icons/ContactFormIcon/NameIcon.tsx";
|
||||||
import EmailIcon from "@icons/ContactFormIcon/EmailIcon.tsx";
|
import EmailIcon from "@icons/ContactFormIcon/EmailIcon.tsx";
|
||||||
import TextIcon from "@icons/ContactFormIcon/TextIcon.tsx";
|
import TextIcon from "@icons/ContactFormIcon/TextIcon.tsx";
|
||||||
import AddressIcon from "@icons/ContactFormIcon/AddressIcon.tsx";
|
import AddressIcon from "@icons/ContactFormIcon/AddressIcon.tsx";
|
||||||
import {Dispatch, SetStateAction} from "react";
|
import { Dispatch, SetStateAction } from "react";
|
||||||
import {
|
import { CustomInput } from "@/components/ViewPublicationPage/ContactForm/CustomInput/CustomInput.tsx";
|
||||||
CustomInput
|
|
||||||
} from "@/components/ViewPublicationPage/ContactForm/CustomInput/CustomInput.tsx";
|
|
||||||
import PhoneIcon from "@icons/ContactFormIcon/PhoneIcon.tsx";
|
import PhoneIcon from "@icons/ContactFormIcon/PhoneIcon.tsx";
|
||||||
|
|
||||||
type InputsProps = {
|
type InputsProps = {
|
||||||
name: string;
|
name: string;
|
||||||
setName: Dispatch<SetStateAction<string>>;
|
setName: Dispatch<SetStateAction<string>>;
|
||||||
email: string;
|
email: string;
|
||||||
setEmail: Dispatch<SetStateAction<string>>;
|
setEmail: Dispatch<SetStateAction<string>>;
|
||||||
phone: string;
|
phone: string;
|
||||||
setPhone: Dispatch<SetStateAction<string>>;
|
setPhone: Dispatch<SetStateAction<string>>;
|
||||||
text: string;
|
text: string;
|
||||||
setText: Dispatch<SetStateAction<string>>;
|
setText: Dispatch<SetStateAction<string>>;
|
||||||
adress: string;
|
adress: string;
|
||||||
setAdress: Dispatch<SetStateAction<string>>;
|
setAdress: Dispatch<SetStateAction<string>>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Inputs = ({
|
export const Inputs = ({
|
||||||
name,
|
name,
|
||||||
setName,
|
setName,
|
||||||
email,
|
email,
|
||||||
setEmail,
|
setEmail,
|
||||||
phone,
|
phone,
|
||||||
setPhone,
|
setPhone,
|
||||||
text,
|
text,
|
||||||
setText,
|
setText,
|
||||||
adress,
|
adress,
|
||||||
setAdress,
|
setAdress,
|
||||||
}: InputsProps) => {
|
}: InputsProps) => {
|
||||||
const { settings } = useQuizData();
|
const { settings } = useQuizData();
|
||||||
const FC = settings.cfg.formContact.fields;
|
const FC = settings.cfg.formContact.fields;
|
||||||
|
|
||||||
if (!FC) return null;
|
if (!FC) return null;
|
||||||
const Name = (
|
const Name = (
|
||||||
<CustomInput
|
<CustomInput
|
||||||
onChange={({ target }) => setName(target.value)}
|
onChange={({ target }) => setName(target.value)}
|
||||||
id={name}
|
id={name}
|
||||||
title={FC["name"].innerText || "Введите имя"}
|
title={FC["name"].innerText || "Введите имя"}
|
||||||
desc={FC["name"].text || "Имя"}
|
desc={FC["name"].text || "Имя"}
|
||||||
Icon={NameIcon}
|
Icon={NameIcon}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
const Email = (
|
const Email = (
|
||||||
<CustomInput
|
<CustomInput
|
||||||
onChange={({ target }) => setEmail(target.value.replaceAll(/\s/g, ""))}
|
onChange={({ target }) => setEmail(target.value.replaceAll(/\s/g, ""))}
|
||||||
id={email}
|
id={email}
|
||||||
title={FC["email"].innerText || "Введите Email"}
|
title={FC["email"].innerText || "Введите Email"}
|
||||||
desc={FC["email"].text || "Email"}
|
desc={FC["email"].text || "Email"}
|
||||||
Icon={EmailIcon}
|
Icon={EmailIcon}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
const Phone = (
|
const Phone = (
|
||||||
<CustomInput
|
<CustomInput
|
||||||
onChange={({ target }) => setPhone(target.value)}
|
onChange={({ target }) => setPhone(target.value)}
|
||||||
id={phone}
|
id={phone}
|
||||||
title={FC["phone"].innerText || "Введите номер телефона"}
|
title={FC["phone"].innerText || "Введите номер телефона"}
|
||||||
desc={FC["phone"].text || "Номер телефона"}
|
desc={FC["phone"].text || "Номер телефона"}
|
||||||
Icon={PhoneIcon}
|
Icon={PhoneIcon}
|
||||||
isPhone={true}
|
isPhone={true}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
const Text = (
|
const Text = (
|
||||||
<CustomInput
|
<CustomInput
|
||||||
onChange={({ target }) => setText(target.value)}
|
onChange={({ target }) => setText(target.value)}
|
||||||
id={text}
|
id={text}
|
||||||
title={FC["text"].text || "Введите фамилию"}
|
title={FC["text"].text || "Введите фамилию"}
|
||||||
desc={FC["text"].innerText || "Фамилия"}
|
desc={FC["text"].innerText || "Фамилия"}
|
||||||
Icon={TextIcon}
|
Icon={TextIcon}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
const Adress = (
|
const Adress = (
|
||||||
<CustomInput
|
<CustomInput
|
||||||
onChange={({ target }) => setAdress(target.value)}
|
onChange={({ target }) => setAdress(target.value)}
|
||||||
id={adress}
|
id={adress}
|
||||||
title={FC["address"].innerText || "Введите адрес"}
|
title={FC["address"].innerText || "Введите адрес"}
|
||||||
desc={FC["address"].text || "Адрес"}
|
desc={FC["address"].text || "Адрес"}
|
||||||
Icon={AddressIcon}
|
Icon={AddressIcon}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
if (Object.values(FC).some((data) => data.used)) {
|
if (Object.values(FC).some((data) => data.used)) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{FC["name"].used ? Name : <></>}
|
{FC["name"].used ? Name : <></>}
|
||||||
{FC["email"].used ? Email : <></>}
|
{FC["email"].used ? Email : <></>}
|
||||||
{FC["phone"].used ? Phone : <></>}
|
{FC["phone"].used ? Phone : <></>}
|
||||||
{FC["text"].used ? Text : <></>}
|
{FC["text"].used ? Text : <></>}
|
||||||
{FC["address"].used ? Adress : <></>}
|
{FC["address"].used ? Adress : <></>}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{Name}
|
{Name}
|
||||||
{Email}
|
{Email}
|
||||||
{Phone}
|
{Phone}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -6,53 +6,49 @@ import { useQuizData } from "@contexts/QuizDataContext";
|
|||||||
import Stepper from "@ui_kit/Stepper";
|
import Stepper from "@ui_kit/Stepper";
|
||||||
|
|
||||||
type FooterProps = {
|
type FooterProps = {
|
||||||
stepNumber: number | null;
|
stepNumber: number | null;
|
||||||
nextButton: ReactNode;
|
nextButton: ReactNode;
|
||||||
prevButton: ReactNode;
|
prevButton: ReactNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Footer = ({ stepNumber, nextButton, prevButton }: FooterProps) => {
|
export const Footer = ({ stepNumber, nextButton, prevButton }: FooterProps) => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { questions, settings } = useQuizData();
|
const { questions, settings } = useQuizData();
|
||||||
const questionsAmount = questions.filter(
|
const questionsAmount = questions.filter(({ type }) => type !== "result").length;
|
||||||
({ type }) => type !== "result"
|
|
||||||
).length;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
position: "relative",
|
position: "relative",
|
||||||
padding: "15px 0",
|
padding: "15px 0",
|
||||||
borderTop: `1px solid #9A9AAF80`,
|
borderTop: `1px solid #9A9AAF80`,
|
||||||
height: "75px",
|
height: "75px",
|
||||||
display: "flex",
|
display: "flex",
|
||||||
background: settings.cfg.design
|
background: settings.cfg.design ? "rgba(154,154,175, 0.2)" : "transparent",
|
||||||
? "rgba(154,154,175, 0.2)"
|
}}
|
||||||
: "transparent",
|
>
|
||||||
}}
|
<Box
|
||||||
>
|
sx={{
|
||||||
<Box
|
width: "100%",
|
||||||
sx={{
|
maxWidth: "1410px",
|
||||||
width: "100%",
|
padding: "10px",
|
||||||
maxWidth: "1410px",
|
margin: "0 auto",
|
||||||
padding: "10px",
|
display: "flex",
|
||||||
margin: "0 auto",
|
alignItems: "center",
|
||||||
display: "flex",
|
gap: "10px",
|
||||||
alignItems: "center",
|
}}
|
||||||
gap: "10px",
|
>
|
||||||
}}
|
{stepNumber !== null && (
|
||||||
>
|
<Box sx={{ flexGrow: 1 }}>
|
||||||
{stepNumber !== null && (
|
<Typography sx={{ color: theme.palette.text.primary }}>
|
||||||
<Box sx={{ flexGrow: 1 }}>
|
Вопрос {stepNumber} из {questionsAmount}
|
||||||
<Typography sx={{ color: theme.palette.text.primary }}>
|
</Typography>
|
||||||
Вопрос {stepNumber} из {questionsAmount}
|
<Stepper activeStep={stepNumber} steps={questionsAmount} />
|
||||||
</Typography>
|
</Box>
|
||||||
<Stepper activeStep={stepNumber} steps={questionsAmount} />
|
)}
|
||||||
</Box>
|
{prevButton}
|
||||||
)}
|
{nextButton}
|
||||||
{prevButton}
|
</Box>
|
||||||
{nextButton}
|
</Box>
|
||||||
</Box>
|
);
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
@ -48,9 +48,7 @@ export const Question = ({
|
|||||||
height: "100%",
|
height: "100%",
|
||||||
backgroundPosition: "center",
|
backgroundPosition: "center",
|
||||||
backgroundSize: "cover",
|
backgroundSize: "cover",
|
||||||
backgroundImage: settings.cfg.design
|
backgroundImage: settings.cfg.design ? `url(${DESIGN_LIST[settings.cfg.theme]})` : null,
|
||||||
? `url(${DESIGN_LIST[settings.cfg.theme]})`
|
|
||||||
: null,
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Box
|
<Box
|
||||||
@ -125,23 +123,13 @@ export const Question = ({
|
|||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
{questionSelect}
|
{questionSelect}
|
||||||
<Footer
|
<Footer stepNumber={currentQuestionStepNumber} prevButton={prevButton} nextButton={nextButton} />
|
||||||
stepNumber={currentQuestionStepNumber}
|
|
||||||
prevButton={prevButton}
|
|
||||||
nextButton={nextButton}
|
|
||||||
/>
|
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
function QuestionByType({
|
function QuestionByType({ question, stepNumber }: { question: RealTypedQuizQuestion; stepNumber: number | null }) {
|
||||||
question,
|
|
||||||
stepNumber,
|
|
||||||
}: {
|
|
||||||
question: RealTypedQuizQuestion;
|
|
||||||
stepNumber: number | null;
|
|
||||||
}) {
|
|
||||||
switch (question.type) {
|
switch (question.type) {
|
||||||
case "variant":
|
case "variant":
|
||||||
return <Variant currentQuestion={question} />;
|
return <Variant currentQuestion={question} />;
|
||||||
|
@ -2,111 +2,111 @@ import { useQuizData } from "@/contexts/QuizDataContext";
|
|||||||
import { AnyTypedQuizQuestion } from "@/model/questionTypes/shared";
|
import { AnyTypedQuizQuestion } from "@/model/questionTypes/shared";
|
||||||
import { Box, FormControl, MenuItem, Select as MuiSelect, useTheme } from "@mui/material";
|
import { Box, FormControl, MenuItem, Select as MuiSelect, useTheme } from "@mui/material";
|
||||||
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
selectedQuestion: AnyTypedQuizQuestion;
|
selectedQuestion: AnyTypedQuizQuestion;
|
||||||
setQuestion: (questionIdF: string) => void;
|
setQuestion: (questionIdF: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function QuestionSelect({ selectedQuestion, setQuestion }: Props) {
|
export default function QuestionSelect({ selectedQuestion, setQuestion }: Props) {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { questions, preview } = useQuizData();
|
const { questions, preview } = useQuizData();
|
||||||
|
|
||||||
if (!preview) return null;
|
if (!preview) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box sx={{
|
<Box
|
||||||
p: "20px",
|
sx={{
|
||||||
display: "flex",
|
p: "20px",
|
||||||
justifyContent: "center",
|
display: "flex",
|
||||||
}}>
|
justifyContent: "center",
|
||||||
<FormControl
|
}}
|
||||||
fullWidth
|
>
|
||||||
size="small"
|
<FormControl
|
||||||
|
fullWidth
|
||||||
|
size="small"
|
||||||
|
sx={{
|
||||||
|
maxWidth: "500px",
|
||||||
|
minWidth: "200px",
|
||||||
|
height: "48px",
|
||||||
|
}}
|
||||||
|
className="cancel"
|
||||||
|
>
|
||||||
|
<MuiSelect
|
||||||
|
id="category-select"
|
||||||
|
variant="outlined"
|
||||||
|
value={selectedQuestion.id}
|
||||||
|
placeholder="Заголовок вопроса"
|
||||||
|
onChange={({ target }) => {
|
||||||
|
setQuestion(target.value);
|
||||||
|
}}
|
||||||
|
sx={{
|
||||||
|
height: "48px",
|
||||||
|
borderRadius: "8px",
|
||||||
|
"& .MuiOutlinedInput-notchedOutline": {
|
||||||
|
border: `1px solid ${theme.palette.primary.main} !important`,
|
||||||
|
},
|
||||||
|
"& .MuiSelect-icon": {
|
||||||
|
color: theme.palette.primary.main,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
MenuProps={{
|
||||||
|
PaperProps: {
|
||||||
|
sx: {
|
||||||
|
mt: "8px",
|
||||||
|
p: "4px",
|
||||||
|
borderRadius: "8px",
|
||||||
|
border: "1px solid #EEE4FC",
|
||||||
|
boxShadow: "0px 8px 24px rgba(210, 208, 225, 0.4)",
|
||||||
|
backgroundColor: theme.palette.background.default,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MenuListProps: {
|
||||||
|
sx: {
|
||||||
|
py: 0,
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
gap: "8px",
|
||||||
|
"& .Mui-selected": {
|
||||||
|
backgroundColor: theme.palette.background.default,
|
||||||
|
color: theme.palette.primary.main,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
inputProps={{
|
||||||
|
sx: {
|
||||||
|
color: theme.palette.primary.main,
|
||||||
|
display: "block",
|
||||||
|
px: "9px",
|
||||||
|
gap: "20px",
|
||||||
|
width: "87%",
|
||||||
|
overflow: "hidden",
|
||||||
|
textOverflow: "ellipsis",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{questions
|
||||||
|
.filter((q) => q.type !== "result")
|
||||||
|
.map((question, index) => (
|
||||||
|
<MenuItem
|
||||||
|
key={question.id}
|
||||||
|
value={question.id}
|
||||||
sx={{
|
sx={{
|
||||||
maxWidth: "500px",
|
display: "flex",
|
||||||
minWidth: "200px",
|
alignItems: "center",
|
||||||
height: "48px",
|
gap: "20px",
|
||||||
|
p: "4px",
|
||||||
|
borderRadius: "5px",
|
||||||
|
color: "#9A9AAF",
|
||||||
|
wordBreak: "break-word",
|
||||||
|
whiteSpace: "normal",
|
||||||
}}
|
}}
|
||||||
className="cancel"
|
>
|
||||||
>
|
{`${index + 1}. ${question.title}`}
|
||||||
<MuiSelect
|
</MenuItem>
|
||||||
id="category-select"
|
))}
|
||||||
variant="outlined"
|
</MuiSelect>
|
||||||
value={selectedQuestion.id}
|
</FormControl>
|
||||||
placeholder="Заголовок вопроса"
|
</Box>
|
||||||
onChange={({ target }) => {
|
);
|
||||||
setQuestion(target.value);
|
|
||||||
}}
|
|
||||||
sx={{
|
|
||||||
height: "48px",
|
|
||||||
borderRadius: "8px",
|
|
||||||
"& .MuiOutlinedInput-notchedOutline": {
|
|
||||||
border: `1px solid ${theme.palette.primary.main} !important`,
|
|
||||||
},
|
|
||||||
"& .MuiSelect-icon": {
|
|
||||||
color: theme.palette.primary.main,
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
MenuProps={{
|
|
||||||
PaperProps: {
|
|
||||||
sx: {
|
|
||||||
mt: "8px",
|
|
||||||
p: "4px",
|
|
||||||
borderRadius: "8px",
|
|
||||||
border: "1px solid #EEE4FC",
|
|
||||||
boxShadow: "0px 8px 24px rgba(210, 208, 225, 0.4)",
|
|
||||||
backgroundColor: theme.palette.background.default,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
MenuListProps: {
|
|
||||||
sx: {
|
|
||||||
py: 0,
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
gap: "8px",
|
|
||||||
"& .Mui-selected": {
|
|
||||||
backgroundColor: theme.palette.background.default,
|
|
||||||
color: theme.palette.primary.main,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
inputProps={{
|
|
||||||
sx: {
|
|
||||||
color: theme.palette.primary.main,
|
|
||||||
display: "block",
|
|
||||||
px: "9px",
|
|
||||||
gap: "20px",
|
|
||||||
width: "87%",
|
|
||||||
overflow: "hidden",
|
|
||||||
textOverflow: "ellipsis",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{questions.filter((q) => q.type !== "result").map(
|
|
||||||
(question, index) => (
|
|
||||||
<MenuItem
|
|
||||||
key={question.id}
|
|
||||||
value={question.id}
|
|
||||||
sx={{
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
gap: "20px",
|
|
||||||
p: "4px",
|
|
||||||
borderRadius: "5px",
|
|
||||||
color: "#9A9AAF",
|
|
||||||
wordBreak: "break-word",
|
|
||||||
whiteSpace: "normal",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{`${index + 1}. ${question.title}`}
|
|
||||||
</MenuItem>
|
|
||||||
),
|
|
||||||
)}
|
|
||||||
</MuiSelect>
|
|
||||||
</FormControl>
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
@ -26,9 +26,7 @@ export const ResultForm = ({ resultQuestion }: ResultFormProps) => {
|
|||||||
const isMobile = useRootContainerSize() < 650;
|
const isMobile = useRootContainerSize() < 650;
|
||||||
const isTablet = useRootContainerSize() < 1000;
|
const isTablet = useRootContainerSize() < 1000;
|
||||||
const { settings, show_badge, quizId } = useQuizData();
|
const { settings, show_badge, quizId } = useQuizData();
|
||||||
const setCurrentQuizStep = useQuizViewStore(
|
const setCurrentQuizStep = useQuizViewStore((state) => state.setCurrentQuizStep);
|
||||||
(state) => state.setCurrentQuizStep
|
|
||||||
);
|
|
||||||
const spec = settings.cfg.spec;
|
const spec = settings.cfg.spec;
|
||||||
const vkMetrics = useVkMetricsGoals(settings.cfg.vkMetricsNumber);
|
const vkMetrics = useVkMetricsGoals(settings.cfg.vkMetricsNumber);
|
||||||
const yandexMetrics = useYandexMetricsGoals(settings.cfg.yandexMetricsNumber);
|
const yandexMetrics = useYandexMetricsGoals(settings.cfg.yandexMetricsNumber);
|
||||||
@ -38,246 +36,236 @@ export const ResultForm = ({ resultQuestion }: ResultFormProps) => {
|
|||||||
yandexMetrics.resultIdShown(resultQuestion.id);
|
yandexMetrics.resultIdShown(resultQuestion.id);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
height: "100%",
|
||||||
|
minHeight: "100%",
|
||||||
|
width: "100%",
|
||||||
|
backgroundColor: theme.palette.background.default,
|
||||||
|
backgroundPosition: "center",
|
||||||
|
backgroundSize: "cover",
|
||||||
|
backgroundImage: settings.cfg.design && !isMobile ? `url(${DESIGN_LIST[settings.cfg.theme]})` : null,
|
||||||
|
position: "relative",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
alignItems: "center",
|
||||||
|
width: "100%",
|
||||||
|
height: "100%",
|
||||||
|
background:
|
||||||
|
settings.cfg.design && !isMobile
|
||||||
|
? quizThemes[settings.cfg.theme].isLight
|
||||||
|
? "transparent"
|
||||||
|
: "linear-gradient(90deg, rgba(39, 38, 38, 0.95) 7.66%, rgba(42, 42, 46, 0.85) 42.12%, rgba(51, 54, 71, 0.4) 100%)"
|
||||||
|
: theme.palette.background.default,
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
justifyContent: "space-between",
|
width: "100%",
|
||||||
height: "100%",
|
height: "100%",
|
||||||
minHeight: "100%",
|
overflow: "auto",
|
||||||
width: "100%",
|
padding: "0 20px 20px",
|
||||||
backgroundColor: theme.palette.background.default,
|
scrollbarWidth: "none",
|
||||||
backgroundPosition: "center",
|
"&::-webkit-scrollbar": {
|
||||||
backgroundSize: "cover",
|
width: 0,
|
||||||
backgroundImage:
|
},
|
||||||
settings.cfg.design && !isMobile
|
}}
|
||||||
? `url(${DESIGN_LIST[settings.cfg.theme]})`
|
|
||||||
: null,
|
|
||||||
position: "relative",
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
alignItems: "center",
|
||||||
justifyContent: "space-between",
|
flexWrap: "wrap",
|
||||||
alignItems: "center",
|
mb: "10px",
|
||||||
width: "100%",
|
width: "100%",
|
||||||
height: "100%",
|
maxWidth: "700px",
|
||||||
background:
|
backgroundColor: "#9A9AAF1A",
|
||||||
settings.cfg.design && !isMobile
|
borderRadius: "0 0 12px 12px",
|
||||||
? quizThemes[settings.cfg.theme].isLight
|
padding: "20px 20px 15px",
|
||||||
? "transparent"
|
}}
|
||||||
: "linear-gradient(90deg, rgba(39, 38, 38, 0.95) 7.66%, rgba(42, 42, 46, 0.85) 42.12%, rgba(51, 54, 71, 0.4) 100%)"
|
>
|
||||||
: theme.palette.background.default,
|
<Typography
|
||||||
}}
|
sx={{
|
||||||
|
fontSize: "17px",
|
||||||
|
color: "#9A9AAF",
|
||||||
|
wordBreak: "break-word",
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Box
|
Ваш результат:
|
||||||
sx={{
|
</Typography>
|
||||||
display: "flex",
|
</Box>
|
||||||
flexDirection: "column",
|
<Box
|
||||||
alignItems: "center",
|
sx={{
|
||||||
width: "100%",
|
display: "flex",
|
||||||
height: "100%",
|
flexDirection: "column",
|
||||||
overflow: "auto",
|
alignItems: "flex-start",
|
||||||
padding: "0 20px 20px",
|
width: "100%",
|
||||||
scrollbarWidth: "none",
|
maxWidth: "700px",
|
||||||
"&::-webkit-scrollbar": {
|
}}
|
||||||
width: 0,
|
>
|
||||||
},
|
{!resultQuestion?.content.useImage && resultQuestion.content.video && (
|
||||||
}}
|
<YoutubeEmbedIframe
|
||||||
>
|
videoUrl={resultQuestion.content.video}
|
||||||
<Box
|
containerSX={{
|
||||||
sx={{
|
width: "100%",
|
||||||
display: "flex",
|
maxWidth: "700px",
|
||||||
alignItems: "center",
|
height: isMobile ? "100%" : "306px",
|
||||||
flexWrap: "wrap",
|
}}
|
||||||
mb: "10px",
|
/>
|
||||||
width: "100%",
|
)}
|
||||||
maxWidth: "700px",
|
{resultQuestion?.content.useImage && resultQuestion.content.back && (
|
||||||
backgroundColor: "#9A9AAF1A",
|
<Box
|
||||||
borderRadius: "0 0 12px 12px",
|
sx={{
|
||||||
padding: "20px 20px 15px",
|
width: "100%",
|
||||||
}}
|
display: "flex",
|
||||||
>
|
justifyContent: "center",
|
||||||
<Typography
|
}}
|
||||||
sx={{
|
>
|
||||||
fontSize: "17px",
|
<img
|
||||||
color: "#9A9AAF",
|
alt="resultImage"
|
||||||
wordBreak: "break-word",
|
src={resultQuestion.content.back}
|
||||||
}}
|
style={{
|
||||||
>
|
width: "100%",
|
||||||
Ваш результат:
|
height: spec ? "auto" : isMobile ? "236px" : "306px",
|
||||||
</Typography>
|
borderRadius: "12px",
|
||||||
</Box>
|
objectFit: "cover",
|
||||||
<Box
|
overflow: "hidden",
|
||||||
sx={{
|
}}
|
||||||
display: "flex",
|
/>
|
||||||
flexDirection: "column",
|
</Box>
|
||||||
alignItems: "flex-start",
|
)}
|
||||||
width: "100%",
|
{resultQuestion.description !== "" && resultQuestion.description !== " " && (
|
||||||
maxWidth: "700px",
|
<Typography
|
||||||
}}
|
sx={{
|
||||||
>
|
fontSize: "27px",
|
||||||
{!resultQuestion?.content.useImage &&
|
lineHeight: "32px",
|
||||||
resultQuestion.content.video && (
|
fontWeight: 700,
|
||||||
<YoutubeEmbedIframe
|
mt: "30px",
|
||||||
videoUrl={resultQuestion.content.video}
|
color: theme.palette.text.primary,
|
||||||
containerSX={{
|
wordBreak: "break-word",
|
||||||
width: "100%",
|
}}
|
||||||
maxWidth: "700px",
|
>
|
||||||
height: isMobile ? "100%" : "306px",
|
{resultQuestion.description}
|
||||||
}}
|
</Typography>
|
||||||
/>
|
)}
|
||||||
)}
|
|
||||||
{resultQuestion?.content.useImage &&
|
|
||||||
resultQuestion.content.back && (
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
width: "100%",
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
alt="resultImage"
|
|
||||||
src={resultQuestion.content.back}
|
|
||||||
style={{
|
|
||||||
width: "100%",
|
|
||||||
height: spec ? "auto" : isMobile ? "236px" : "306px",
|
|
||||||
borderRadius: "12px",
|
|
||||||
objectFit: "cover",
|
|
||||||
overflow: "hidden",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
{resultQuestion.description !== "" &&
|
|
||||||
resultQuestion.description !== " " && (
|
|
||||||
<Typography
|
|
||||||
sx={{
|
|
||||||
fontSize: "27px",
|
|
||||||
lineHeight: "32px",
|
|
||||||
fontWeight: 700,
|
|
||||||
mt: "30px",
|
|
||||||
color: theme.palette.text.primary,
|
|
||||||
wordBreak: "break-word",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{resultQuestion.description}
|
|
||||||
</Typography>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<Typography
|
<Typography
|
||||||
sx={{
|
sx={{
|
||||||
mt: "12px",
|
mt: "12px",
|
||||||
fontSize: "17px",
|
fontSize: "17px",
|
||||||
lineHeight: "20px",
|
lineHeight: "20px",
|
||||||
color: theme.palette.text.primary,
|
color: theme.palette.text.primary,
|
||||||
wordBreak: "break-word",
|
wordBreak: "break-word",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{resultQuestion.title}
|
{resultQuestion.title}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
{resultQuestion.content.text !== "" &&
|
{resultQuestion.content.text !== "" && resultQuestion.content.text !== " " && (
|
||||||
resultQuestion.content.text !== " " && (
|
<Typography
|
||||||
<Typography
|
sx={{
|
||||||
sx={{
|
fontSize: "17px",
|
||||||
fontSize: "17px",
|
lineHeight: "20px",
|
||||||
lineHeight: "20px",
|
mt: "25px ",
|
||||||
mt: "25px ",
|
wordBreak: "break-word",
|
||||||
wordBreak: "break-word",
|
color: theme.palette.text.primary,
|
||||||
color: theme.palette.text.primary,
|
}}
|
||||||
}}
|
>
|
||||||
>
|
{resultQuestion.content.text}
|
||||||
{resultQuestion.content.text}
|
</Typography>
|
||||||
</Typography>
|
)}
|
||||||
)}
|
</Box>
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
{show_badge && (
|
|
||||||
<Box
|
|
||||||
component={Link}
|
|
||||||
target={"_blank"}
|
|
||||||
href={`https://${
|
|
||||||
window.location.hostname.includes("s") ? "s" : ""
|
|
||||||
}quiz.pena.digital/squiz/quiz/logo?q=${quizId}`}
|
|
||||||
sx={{
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
alignSelf: isMobile ? "center" : "end",
|
|
||||||
margin: isMobile ? "15px 0 0" : "15px 25px 0 0",
|
|
||||||
gap: "10px",
|
|
||||||
textDecoration: "none",
|
|
||||||
mb: "15px",
|
|
||||||
position: isTablet || isMobile ? "sticky" : "absolute",
|
|
||||||
bottom: "90px",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<NameplateLogo
|
|
||||||
style={{
|
|
||||||
fontSize: "23px",
|
|
||||||
color: quizThemes[settings.cfg.theme].isLight
|
|
||||||
? "#000000"
|
|
||||||
: "#F5F7FF",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
width: "100%",
|
|
||||||
flexDirection: "column",
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
borderTop: "1px solid #9A9AAF80",
|
|
||||||
p: "20px",
|
|
||||||
position: "sticky",
|
|
||||||
bottom: 0,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{settings.cfg.resultInfo.showResultForm === "before" &&
|
|
||||||
!settings.cfg.score && (
|
|
||||||
<Button
|
|
||||||
onClick={() => setCurrentQuizStep("contactform")}
|
|
||||||
variant="contained"
|
|
||||||
sx={{
|
|
||||||
p: "10px 20px",
|
|
||||||
width: "auto",
|
|
||||||
height: "50px",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{resultQuestion.content.hint.text || "Узнать подробнее"}
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
{settings.cfg.resultInfo.showResultForm === "after" &&
|
|
||||||
resultQuestion.content.redirect && (
|
|
||||||
<Button
|
|
||||||
onClick={() => {
|
|
||||||
vkMetrics.resultLink();
|
|
||||||
yandexMetrics.resultLink();
|
|
||||||
setTimeout(() => {
|
|
||||||
location.href =
|
|
||||||
(resultQuestion.content.redirect.includes("https")
|
|
||||||
? resultQuestion.content.redirect
|
|
||||||
: `https://${resultQuestion.content.redirect}`).replace(/\s+/g, "");
|
|
||||||
}, 1000)
|
|
||||||
}}
|
|
||||||
variant="contained"
|
|
||||||
sx={{
|
|
||||||
p: "10px 20px",
|
|
||||||
width: "auto",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{resultQuestion.content.hint.text || "Перейти на сайт"}
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
</Box>
|
||||||
);
|
{show_badge && (
|
||||||
|
<Box
|
||||||
|
component={Link}
|
||||||
|
target={"_blank"}
|
||||||
|
href={`https://${
|
||||||
|
window.location.hostname.includes("s") ? "s" : ""
|
||||||
|
}quiz.pena.digital/squiz/quiz/logo?q=${quizId}`}
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
alignSelf: isMobile ? "center" : "end",
|
||||||
|
margin: isMobile ? "15px 0 0" : "15px 25px 0 0",
|
||||||
|
gap: "10px",
|
||||||
|
textDecoration: "none",
|
||||||
|
mb: "15px",
|
||||||
|
position: isTablet || isMobile ? "sticky" : "absolute",
|
||||||
|
bottom: "90px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<NameplateLogo
|
||||||
|
style={{
|
||||||
|
fontSize: "23px",
|
||||||
|
color: quizThemes[settings.cfg.theme].isLight ? "#000000" : "#F5F7FF",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
width: "100%",
|
||||||
|
flexDirection: "column",
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
borderTop: "1px solid #9A9AAF80",
|
||||||
|
p: "20px",
|
||||||
|
position: "sticky",
|
||||||
|
bottom: 0,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{settings.cfg.resultInfo.showResultForm === "before" && !settings.cfg.score && (
|
||||||
|
<Button
|
||||||
|
onClick={() => setCurrentQuizStep("contactform")}
|
||||||
|
variant="contained"
|
||||||
|
sx={{
|
||||||
|
p: "10px 20px",
|
||||||
|
width: "auto",
|
||||||
|
height: "50px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{resultQuestion.content.hint.text || "Узнать подробнее"}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
{settings.cfg.resultInfo.showResultForm === "after" && resultQuestion.content.redirect && (
|
||||||
|
<Button
|
||||||
|
onClick={() => {
|
||||||
|
vkMetrics.resultLink();
|
||||||
|
yandexMetrics.resultLink();
|
||||||
|
setTimeout(() => {
|
||||||
|
location.href = (
|
||||||
|
resultQuestion.content.redirect.includes("https")
|
||||||
|
? resultQuestion.content.redirect
|
||||||
|
: `https://${resultQuestion.content.redirect}`
|
||||||
|
).replace(/\s+/g, "");
|
||||||
|
}, 1000);
|
||||||
|
}}
|
||||||
|
variant="contained"
|
||||||
|
sx={{
|
||||||
|
p: "10px 20px",
|
||||||
|
width: "auto",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{resultQuestion.content.hint.text || "Перейти на сайт"}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
@ -3,10 +3,7 @@ import { StartPageMobile } from "./StartPageMobile";
|
|||||||
|
|
||||||
import { useRootContainerSize } from "@contexts/RootContainerWidthContext";
|
import { useRootContainerSize } from "@contexts/RootContainerWidthContext";
|
||||||
|
|
||||||
import type {
|
import type { QuizStartpageAlignType, QuizStartpageType } from "@model/settingsData";
|
||||||
QuizStartpageAlignType,
|
|
||||||
QuizStartpageType,
|
|
||||||
} from "@model/settingsData";
|
|
||||||
|
|
||||||
type QuizPreviewLayoutByTypeProps = {
|
type QuizPreviewLayoutByTypeProps = {
|
||||||
quizHeaderBlock: JSX.Element;
|
quizHeaderBlock: JSX.Element;
|
||||||
|
@ -1,277 +1,261 @@
|
|||||||
import {Box} from "@mui/material";
|
import { Box } from "@mui/material";
|
||||||
|
|
||||||
import {useRootContainerSize} from "@contexts/RootContainerWidthContext";
|
import { useRootContainerSize } from "@contexts/RootContainerWidthContext";
|
||||||
import {useQuizData} from "@contexts/QuizDataContext";
|
import { useQuizData } from "@contexts/QuizDataContext";
|
||||||
|
|
||||||
import {notReachable} from "@utils/notReachable";
|
import { notReachable } from "@utils/notReachable";
|
||||||
import {quizThemes} from "@utils/themes/Publication/themePublication";
|
import { quizThemes } from "@utils/themes/Publication/themePublication";
|
||||||
|
|
||||||
import type {
|
import type { QuizStartpageAlignType, QuizStartpageType } from "@model/settingsData";
|
||||||
QuizStartpageAlignType,
|
import { DESIGN_LIST } from "@/utils/designList";
|
||||||
QuizStartpageType,
|
|
||||||
} from "@model/settingsData";
|
|
||||||
import {DESIGN_LIST} from "@/utils/designList";
|
|
||||||
|
|
||||||
type StartPageDesktopProps = {
|
type StartPageDesktopProps = {
|
||||||
quizHeaderBlock: JSX.Element;
|
quizHeaderBlock: JSX.Element;
|
||||||
quizMainBlock: JSX.Element;
|
quizMainBlock: JSX.Element;
|
||||||
backgroundBlock: JSX.Element | null;
|
backgroundBlock: JSX.Element | null;
|
||||||
startpageType: QuizStartpageType;
|
startpageType: QuizStartpageType;
|
||||||
alignType: QuizStartpageAlignType;
|
alignType: QuizStartpageAlignType;
|
||||||
};
|
};
|
||||||
|
|
||||||
type LayoutProps = Omit<StartPageDesktopProps, "startpageType">;
|
type LayoutProps = Omit<StartPageDesktopProps, "startpageType">;
|
||||||
|
|
||||||
const StandartLayout = ({
|
const StandartLayout = ({ alignType, quizHeaderBlock, quizMainBlock, backgroundBlock }: LayoutProps) => {
|
||||||
alignType,
|
const size = useRootContainerSize();
|
||||||
quizHeaderBlock,
|
const isTablet = size >= 700 && size < 1100;
|
||||||
quizMainBlock,
|
const { settings } = useQuizData();
|
||||||
backgroundBlock,
|
|
||||||
}: LayoutProps) => {
|
|
||||||
const size = useRootContainerSize();
|
|
||||||
const isTablet = size >= 700 && size < 1100;
|
|
||||||
const {settings} = useQuizData();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<Box
|
||||||
|
id="pain"
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: alignType === "left" ? "row" : "row-reverse",
|
||||||
|
height: "100%",
|
||||||
|
backgroundPosition: "center",
|
||||||
|
backgroundSize: "cover",
|
||||||
|
backgroundImage: settings.cfg.design ? `url(${DESIGN_LIST[settings.cfg.theme]})` : null,
|
||||||
|
scrollbarWidth: "none",
|
||||||
|
"&::-webkit-scrollbar": {
|
||||||
|
width: 0,
|
||||||
|
},
|
||||||
|
overflowY: "auto",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: alignType === "left" ? "row" : "row-reverse",
|
||||||
|
padding: isTablet ? "15px" : "0",
|
||||||
|
width: "100%",
|
||||||
|
background:
|
||||||
|
settings.cfg.design && !quizThemes[settings.cfg.theme].isLight
|
||||||
|
? alignType === "left"
|
||||||
|
? "linear-gradient(90deg, #272626, transparent)"
|
||||||
|
: alignType === "right"
|
||||||
|
? "linear-gradient(-90deg, #272626, transparent)"
|
||||||
|
: "linear-gradient(0deg, #272626, transparent)"
|
||||||
|
: null,
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Box
|
<Box
|
||||||
id="pain"
|
sx={{
|
||||||
sx={{
|
width: settings.cfg.startpage.background.desktop ? "40%" : undefined,
|
||||||
display: "flex",
|
height: "100%",
|
||||||
flexDirection: alignType === "left" ? "row" : "row-reverse",
|
display: "flex",
|
||||||
height: "100%",
|
flexDirection: "column",
|
||||||
backgroundPosition: "center",
|
justifyContent: "space-between",
|
||||||
backgroundSize: "cover",
|
alignItems: "flex-start",
|
||||||
backgroundImage: settings.cfg.design
|
p: isTablet ? "25px" : alignType === "left" ? "25px 25px 25px 35px" : "25px 35px 25px 25px",
|
||||||
? `url(${DESIGN_LIST[settings.cfg.theme]})`
|
overflowY: "auto",
|
||||||
: null,
|
scrollbarWidth: "none",
|
||||||
scrollbarWidth: "none",
|
"&::-webkit-scrollbar": {
|
||||||
"&::-webkit-scrollbar": {
|
width: 0,
|
||||||
width: 0,
|
},
|
||||||
},
|
}}
|
||||||
overflowY: "auto",
|
|
||||||
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<Box
|
{quizHeaderBlock}
|
||||||
sx={{
|
{quizMainBlock}
|
||||||
display: "flex",
|
|
||||||
flexDirection: alignType === "left" ? "row" : "row-reverse",
|
|
||||||
padding: isTablet ? "15px" : "0",
|
|
||||||
width: "100%",
|
|
||||||
background: settings.cfg.design && !quizThemes[settings.cfg.theme].isLight
|
|
||||||
? alignType === 'left'
|
|
||||||
? "linear-gradient(90deg, #272626, transparent)"
|
|
||||||
: alignType === 'right'
|
|
||||||
? "linear-gradient(-90deg, #272626, transparent)"
|
|
||||||
: "linear-gradient(0deg, #272626, transparent)"
|
|
||||||
: null,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
width: settings.cfg.startpage.background.desktop ? "40%" : undefined,
|
|
||||||
height: "100%",
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
justifyContent: "space-between",
|
|
||||||
alignItems: "flex-start",
|
|
||||||
p: isTablet ? "25px" : alignType === 'left' ? "25px 25px 25px 35px" : "25px 35px 25px 25px",
|
|
||||||
overflowY: "auto",
|
|
||||||
scrollbarWidth: "none",
|
|
||||||
"&::-webkit-scrollbar": {
|
|
||||||
width: 0,
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{quizHeaderBlock}
|
|
||||||
{quizMainBlock}
|
|
||||||
</Box>
|
|
||||||
{settings.cfg.startpage.background.desktop && (
|
|
||||||
<Box sx={{width: "60%", overflow: "hidden"}}><Box
|
|
||||||
sx={{
|
|
||||||
width: "100%",
|
|
||||||
height: "100%",
|
|
||||||
padding: alignType === "left" ? "25px 25px 25px 15px" : "25px 15px 25px 25px",
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
"& > img": {width: "100%", borderRadius: "12px"},
|
|
||||||
}}
|
|
||||||
>{backgroundBlock}</Box></Box>
|
|
||||||
)}
|
|
||||||
</Box>
|
|
||||||
</Box>
|
</Box>
|
||||||
);
|
{settings.cfg.startpage.background.desktop && (
|
||||||
|
<Box sx={{ width: "60%", overflow: "hidden" }}>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
width: "100%",
|
||||||
|
height: "100%",
|
||||||
|
padding: alignType === "left" ? "25px 25px 25px 15px" : "25px 15px 25px 25px",
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "center",
|
||||||
|
"& > img": { width: "100%", borderRadius: "12px" },
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{backgroundBlock}
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const ExpandedLayout = ({
|
const ExpandedLayout = ({ alignType, quizHeaderBlock, quizMainBlock, backgroundBlock }: LayoutProps) => {
|
||||||
alignType,
|
const size = useRootContainerSize();
|
||||||
quizHeaderBlock,
|
const isTablet = size >= 700 && size < 1100;
|
||||||
quizMainBlock,
|
return (
|
||||||
backgroundBlock,
|
<>
|
||||||
}: LayoutProps) => {
|
<Box
|
||||||
const size = useRootContainerSize();
|
sx={{
|
||||||
const isTablet = size >= 700 && size < 1100;
|
height: "100%",
|
||||||
return (
|
width: alignType === "center" ? "100%" : isTablet ? "46%" : "42%",
|
||||||
<>
|
display: "flex",
|
||||||
<Box
|
padding:
|
||||||
sx={{
|
alignType === "center"
|
||||||
height: "100%",
|
? isTablet
|
||||||
width: alignType === "center" ? "100%" : isTablet ? "46%" : "42%",
|
? "30px 40px"
|
||||||
display: "flex",
|
: "30px 35px"
|
||||||
padding:
|
: alignType === "left"
|
||||||
alignType === "center"
|
? isTablet
|
||||||
? isTablet ? "30px 40px" : "30px 35px"
|
? "25px 0 31px 40px"
|
||||||
: alignType === "left"
|
: "25px 0 31px 35px"
|
||||||
? isTablet ? "25px 0 31px 40px" : "25px 0 31px 35px"
|
: isTablet
|
||||||
: isTablet ? "25px 40px 31px 0" : "25px 35px 31px 0",
|
? "25px 40px 31px 0"
|
||||||
margin:
|
: "25px 35px 31px 0",
|
||||||
alignType === "center"
|
margin: alignType === "center" ? "0 auto" : alignType === "left" ? "0" : "0 0 0 auto",
|
||||||
? "0 auto"
|
scrollbarWidth: "none",
|
||||||
: alignType === "left"
|
"&::-webkit-scrollbar": {
|
||||||
? "0"
|
width: 0,
|
||||||
: "0 0 0 auto",
|
},
|
||||||
scrollbarWidth: "none",
|
overflowY: "auto",
|
||||||
"&::-webkit-scrollbar": {
|
}}
|
||||||
width: 0,
|
>
|
||||||
},
|
|
||||||
overflowY: "auto",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
minHeight: "calc(100% - 32px)",
|
|
||||||
position: "relative",
|
|
||||||
width: "100%",
|
|
||||||
|
|
||||||
padding:
|
|
||||||
alignType === "center"
|
|
||||||
? "0"
|
|
||||||
: alignType === "left"
|
|
||||||
? "0 40px 0 0"
|
|
||||||
: "0 0 0 40px",
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
justifyContent: "space-between",
|
|
||||||
alignItems: alignType === "center" ? "center" : "start",
|
|
||||||
borderRight: alignType === "left" ? "1px solid #9A9AAF80" : null,
|
|
||||||
borderLeft: alignType === "right" ? "1px solid #9A9AAF80" : null,
|
|
||||||
scrollbarWidth: "none",
|
|
||||||
"&::-webkit-scrollbar": {
|
|
||||||
width: 0,
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{alignType !== "center" && quizHeaderBlock}
|
|
||||||
{quizMainBlock}
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
position: "absolute",
|
|
||||||
zIndex: -1,
|
|
||||||
left: 0,
|
|
||||||
top: 0,
|
|
||||||
height: "100%",
|
|
||||||
width: "100%",
|
|
||||||
overflow: "hidden",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{backgroundBlock}
|
|
||||||
</Box>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const CenteredLayout = ({
|
|
||||||
quizHeaderBlock,
|
|
||||||
quizMainBlock,
|
|
||||||
backgroundBlock,
|
|
||||||
}: LayoutProps) => {
|
|
||||||
const isTablet = useRootContainerSize() < 1100;
|
|
||||||
const {settings} = useQuizData();
|
|
||||||
return (
|
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
overflow: "auto",
|
minHeight: "calc(100% - 32px)",
|
||||||
padding: isTablet ? "25px 40px 40px" : "25px 25px 25px",
|
position: "relative",
|
||||||
display: "flex",
|
width: "100%",
|
||||||
flexDirection: "column",
|
|
||||||
alignItems: "center",
|
padding: alignType === "center" ? "0" : alignType === "left" ? "0 40px 0 0" : "0 0 0 40px",
|
||||||
height: "100%",
|
display: "flex",
|
||||||
backgroundPosition: "center",
|
flexDirection: "column",
|
||||||
backgroundSize: "cover",
|
justifyContent: "space-between",
|
||||||
backgroundImage: !settings.cfg.design ? null : settings.cfg.design && !quizThemes[settings.cfg.theme].isLight
|
alignItems: alignType === "center" ? "center" : "start",
|
||||||
? `linear-gradient(0deg, #272626, transparent), url(${DESIGN_LIST[settings.cfg.theme]})` : `url(${DESIGN_LIST[settings.cfg.theme]})`,
|
borderRight: alignType === "left" ? "1px solid #9A9AAF80" : null,
|
||||||
scrollbarWidth: "none",
|
borderLeft: alignType === "right" ? "1px solid #9A9AAF80" : null,
|
||||||
"&::-webkit-scrollbar": {
|
scrollbarWidth: "none",
|
||||||
width: 0,
|
"&::-webkit-scrollbar": {
|
||||||
},
|
width: 0,
|
||||||
overflowY: "auto",
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{quizHeaderBlock}
|
{alignType !== "center" && quizHeaderBlock}
|
||||||
{backgroundBlock && settings.cfg.startpage.background.desktop && (
|
{quizMainBlock}
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
width: "100%",
|
|
||||||
maxWidth: "844px",
|
|
||||||
height: isTablet ? "530px" : "306px",
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
"& > img": {width: "100%", borderRadius: "12px"},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{backgroundBlock}
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
{quizMainBlock}
|
|
||||||
</Box>
|
</Box>
|
||||||
);
|
</Box>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
position: "absolute",
|
||||||
|
zIndex: -1,
|
||||||
|
left: 0,
|
||||||
|
top: 0,
|
||||||
|
height: "100%",
|
||||||
|
width: "100%",
|
||||||
|
overflow: "hidden",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{backgroundBlock}
|
||||||
|
</Box>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const CenteredLayout = ({ quizHeaderBlock, quizMainBlock, backgroundBlock }: LayoutProps) => {
|
||||||
|
const isTablet = useRootContainerSize() < 1100;
|
||||||
|
const { settings } = useQuizData();
|
||||||
|
return (
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
overflow: "auto",
|
||||||
|
padding: isTablet ? "25px 40px 40px" : "25px 25px 25px",
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
alignItems: "center",
|
||||||
|
height: "100%",
|
||||||
|
backgroundPosition: "center",
|
||||||
|
backgroundSize: "cover",
|
||||||
|
backgroundImage: !settings.cfg.design
|
||||||
|
? null
|
||||||
|
: settings.cfg.design && !quizThemes[settings.cfg.theme].isLight
|
||||||
|
? `linear-gradient(0deg, #272626, transparent), url(${DESIGN_LIST[settings.cfg.theme]})`
|
||||||
|
: `url(${DESIGN_LIST[settings.cfg.theme]})`,
|
||||||
|
scrollbarWidth: "none",
|
||||||
|
"&::-webkit-scrollbar": {
|
||||||
|
width: 0,
|
||||||
|
},
|
||||||
|
overflowY: "auto",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{quizHeaderBlock}
|
||||||
|
{backgroundBlock && settings.cfg.startpage.background.desktop && (
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
width: "100%",
|
||||||
|
maxWidth: "844px",
|
||||||
|
height: isTablet ? "530px" : "306px",
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "center",
|
||||||
|
"& > img": { width: "100%", borderRadius: "12px" },
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{backgroundBlock}
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
{quizMainBlock}
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const StartPageDesktop = ({
|
export const StartPageDesktop = ({
|
||||||
quizHeaderBlock,
|
quizHeaderBlock,
|
||||||
quizMainBlock,
|
quizMainBlock,
|
||||||
backgroundBlock,
|
backgroundBlock,
|
||||||
startpageType,
|
startpageType,
|
||||||
alignType,
|
alignType,
|
||||||
}: StartPageDesktopProps) => {
|
}: StartPageDesktopProps) => {
|
||||||
switch (startpageType) {
|
switch (startpageType) {
|
||||||
case null:
|
case null:
|
||||||
case "standard": {
|
case "standard": {
|
||||||
return (
|
return (
|
||||||
<StandartLayout
|
<StandartLayout
|
||||||
alignType={alignType}
|
alignType={alignType}
|
||||||
quizHeaderBlock={quizHeaderBlock}
|
quizHeaderBlock={quizHeaderBlock}
|
||||||
quizMainBlock={quizMainBlock}
|
quizMainBlock={quizMainBlock}
|
||||||
backgroundBlock={backgroundBlock}
|
backgroundBlock={backgroundBlock}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
case "expanded": {
|
|
||||||
return (
|
|
||||||
<ExpandedLayout
|
|
||||||
alignType={alignType}
|
|
||||||
quizHeaderBlock={quizHeaderBlock}
|
|
||||||
quizMainBlock={quizMainBlock}
|
|
||||||
backgroundBlock={backgroundBlock}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
case "centered": {
|
|
||||||
return (
|
|
||||||
<CenteredLayout
|
|
||||||
alignType={alignType}
|
|
||||||
quizHeaderBlock={quizHeaderBlock}
|
|
||||||
quizMainBlock={quizMainBlock}
|
|
||||||
backgroundBlock={backgroundBlock}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
notReachable(startpageType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case "expanded": {
|
||||||
|
return (
|
||||||
|
<ExpandedLayout
|
||||||
|
alignType={alignType}
|
||||||
|
quizHeaderBlock={quizHeaderBlock}
|
||||||
|
quizMainBlock={quizMainBlock}
|
||||||
|
backgroundBlock={backgroundBlock}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
case "centered": {
|
||||||
|
return (
|
||||||
|
<CenteredLayout
|
||||||
|
alignType={alignType}
|
||||||
|
quizHeaderBlock={quizHeaderBlock}
|
||||||
|
quizMainBlock={quizMainBlock}
|
||||||
|
backgroundBlock={backgroundBlock}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
notReachable(startpageType);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,283 +1,270 @@
|
|||||||
import {Box} from "@mui/material";
|
import { Box } from "@mui/material";
|
||||||
|
|
||||||
import {useQuizData} from "@contexts/QuizDataContext";
|
import { useQuizData } from "@contexts/QuizDataContext";
|
||||||
|
|
||||||
import {notReachable} from "@utils/notReachable";
|
import { notReachable } from "@utils/notReachable";
|
||||||
import {quizThemes} from "@utils/themes/Publication/themePublication";
|
import { quizThemes } from "@utils/themes/Publication/themePublication";
|
||||||
|
|
||||||
import type {QuizStartpageType} from "@model/settingsData";
|
import type { QuizStartpageType } from "@model/settingsData";
|
||||||
import {DESIGN_LIST} from "@/utils/designList";
|
import { DESIGN_LIST } from "@/utils/designList";
|
||||||
|
|
||||||
type StartPageMobileProps = {
|
type StartPageMobileProps = {
|
||||||
quizHeaderBlock: JSX.Element;
|
quizHeaderBlock: JSX.Element;
|
||||||
quizMainBlock: JSX.Element;
|
quizMainBlock: JSX.Element;
|
||||||
backgroundBlock: JSX.Element | null;
|
backgroundBlock: JSX.Element | null;
|
||||||
startpageType: QuizStartpageType;
|
startpageType: QuizStartpageType;
|
||||||
};
|
};
|
||||||
|
|
||||||
type MobileLayoutProps = Omit<StartPageMobileProps, "startpageType">;
|
type MobileLayoutProps = Omit<StartPageMobileProps, "startpageType">;
|
||||||
|
|
||||||
const StandartMobileLayout = ({
|
const StandartMobileLayout = ({ quizHeaderBlock, quizMainBlock, backgroundBlock }: MobileLayoutProps) => {
|
||||||
quizHeaderBlock,
|
const { settings } = useQuizData();
|
||||||
quizMainBlock,
|
|
||||||
backgroundBlock,
|
|
||||||
}: MobileLayoutProps) => {
|
|
||||||
const {settings} = useQuizData();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
justifyContent: "flex-end",
|
justifyContent: "flex-end",
|
||||||
minHeight: "100%",
|
minHeight: "100%",
|
||||||
height: "100%",
|
height: "100%",
|
||||||
"&::-webkit-scrollbar": {width: 0},
|
"&::-webkit-scrollbar": { width: 0 },
|
||||||
backgroundPosition: "center",
|
backgroundPosition: "center",
|
||||||
backgroundSize: "cover",
|
backgroundSize: "cover",
|
||||||
backgroundImage: settings.cfg.design
|
backgroundImage: settings.cfg.design ? `url(${DESIGN_LIST[settings.cfg.theme]})` : null,
|
||||||
? `url(${DESIGN_LIST[settings.cfg.theme]})`
|
}}
|
||||||
: null,
|
>
|
||||||
}}
|
<Box
|
||||||
>
|
sx={{
|
||||||
|
width: "100%",
|
||||||
|
display: "flex",
|
||||||
|
flexGrow: 1,
|
||||||
|
flexDirection: "column",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
alignItems: "flex-start",
|
||||||
|
p: "20px",
|
||||||
|
height: "100%",
|
||||||
|
overflowY: "auto",
|
||||||
|
overflowX: "hidden",
|
||||||
|
background:
|
||||||
|
settings.cfg.design && !quizThemes[settings.cfg.theme].isLight
|
||||||
|
? "linear-gradient(90deg,#272626,transparent)"
|
||||||
|
: null,
|
||||||
|
"&::-webkit-scrollbar": {
|
||||||
|
width: "4px",
|
||||||
|
},
|
||||||
|
"&::-webkit-scrollbar-thumb": {
|
||||||
|
backgroundColor: "#b8babf",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box sx={{ marginBottom: "13px" }}>{quizHeaderBlock}</Box>
|
||||||
|
{settings.cfg.startpage.background.desktop && (
|
||||||
|
<Box sx={{ width: "100%", overflow: "hidden" }}>
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
width: "100%",
|
width: "100%",
|
||||||
display: "flex",
|
height: "100%",
|
||||||
flexGrow: 1,
|
display: "flex",
|
||||||
flexDirection: "column",
|
justifyContent: "center",
|
||||||
justifyContent: "space-between",
|
"& > img": {
|
||||||
alignItems: "flex-start",
|
width: "100%",
|
||||||
p: "20px",
|
borderRadius: "12px",
|
||||||
height: "100%",
|
},
|
||||||
overflowY: "auto",
|
}}
|
||||||
overflowX: "hidden",
|
|
||||||
background:
|
|
||||||
settings.cfg.design && !quizThemes[settings.cfg.theme].isLight
|
|
||||||
? "linear-gradient(90deg,#272626,transparent)"
|
|
||||||
: null,
|
|
||||||
"&::-webkit-scrollbar": {
|
|
||||||
width: "4px",
|
|
||||||
},
|
|
||||||
"&::-webkit-scrollbar-thumb": {
|
|
||||||
backgroundColor: "#b8babf",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<Box sx={{marginBottom: "13px"}}>
|
{backgroundBlock}
|
||||||
{quizHeaderBlock}
|
|
||||||
</Box>
|
|
||||||
{settings.cfg.startpage.background.desktop && (
|
|
||||||
<Box sx={{width: "100%", overflow: "hidden"}}>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
width: "100%",
|
|
||||||
height: "100%",
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
"& > img": {
|
|
||||||
width: "100%",
|
|
||||||
borderRadius: "12px"
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{backgroundBlock}
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
height: "80%",
|
|
||||||
display: "flex",
|
|
||||||
flexGrow: 1,
|
|
||||||
flexDirection: "column",
|
|
||||||
justifyContent: "space-between",
|
|
||||||
width: "100%",
|
|
||||||
marginTop: "30px"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{quizMainBlock}
|
|
||||||
</Box>
|
|
||||||
</Box>
|
</Box>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
height: "80%",
|
||||||
|
display: "flex",
|
||||||
|
flexGrow: 1,
|
||||||
|
flexDirection: "column",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
width: "100%",
|
||||||
|
marginTop: "30px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{quizMainBlock}
|
||||||
</Box>
|
</Box>
|
||||||
);
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const ExpandedMobileLayout = ({
|
const ExpandedMobileLayout = ({ quizHeaderBlock, quizMainBlock, backgroundBlock }: MobileLayoutProps) => (
|
||||||
quizHeaderBlock,
|
<Box
|
||||||
quizMainBlock,
|
sx={{
|
||||||
backgroundBlock,
|
display: "flex",
|
||||||
}: MobileLayoutProps) => (
|
flexDirection: "column-reverse",
|
||||||
|
flexGrow: 1,
|
||||||
|
justifyContent: "flex-end",
|
||||||
|
minHeight: "100%",
|
||||||
|
height: "100%",
|
||||||
|
"&::-webkit-scrollbar": { width: 0 },
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
zIndex: 3,
|
||||||
flexDirection: "column-reverse",
|
width: "100%",
|
||||||
flexGrow: 1,
|
display: "flex",
|
||||||
justifyContent: "flex-end",
|
flexGrow: 1,
|
||||||
minHeight: "100%",
|
flexDirection: "column",
|
||||||
height: "100%",
|
justifyContent: "space-between",
|
||||||
"&::-webkit-scrollbar": {width: 0},
|
alignItems: "flex-start",
|
||||||
}}
|
height: "100%",
|
||||||
|
overflowY: "auto",
|
||||||
|
overflowX: "hidden",
|
||||||
|
"&::-webkit-scrollbar": { width: "4px" },
|
||||||
|
"&::-webkit-scrollbar-thumb": { backgroundColor: "#b8babf" },
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
zIndex: 3,
|
padding: "20px",
|
||||||
width: "100%",
|
height: "80%",
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
justifyContent: "space-between",
|
justifyContent: "space-between",
|
||||||
alignItems: "flex-start",
|
width: "100%",
|
||||||
height: "100%",
|
}}
|
||||||
overflowY: "auto",
|
>
|
||||||
overflowX: "hidden",
|
{quizHeaderBlock}
|
||||||
"&::-webkit-scrollbar": {width: "4px"},
|
{quizMainBlock}
|
||||||
"&::-webkit-scrollbar-thumb": {backgroundColor: "#b8babf"},
|
</Box>
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
padding: "20px",
|
|
||||||
height: "80%",
|
|
||||||
display: "flex",
|
|
||||||
flexGrow: 1,
|
|
||||||
flexDirection: "column",
|
|
||||||
justifyContent: "space-between",
|
|
||||||
width: "100%",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{quizHeaderBlock}
|
|
||||||
{quizMainBlock}
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
zIndex: -1,
|
|
||||||
position: "absolute",
|
|
||||||
left: 0,
|
|
||||||
top: 0,
|
|
||||||
width: "100%",
|
|
||||||
height: "100%",
|
|
||||||
// minHeight: "100%",
|
|
||||||
overflow: "hidden",
|
|
||||||
"& > img": {
|
|
||||||
display: "block",
|
|
||||||
minHeight: "100%",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{backgroundBlock}
|
|
||||||
</Box>
|
|
||||||
</Box>
|
</Box>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
zIndex: -1,
|
||||||
|
position: "absolute",
|
||||||
|
left: 0,
|
||||||
|
top: 0,
|
||||||
|
width: "100%",
|
||||||
|
height: "100%",
|
||||||
|
// minHeight: "100%",
|
||||||
|
overflow: "hidden",
|
||||||
|
"& > img": {
|
||||||
|
display: "block",
|
||||||
|
minHeight: "100%",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{backgroundBlock}
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
);
|
);
|
||||||
|
|
||||||
const CenteredMobileLayout = ({
|
const CenteredMobileLayout = ({ quizHeaderBlock, quizMainBlock, backgroundBlock }: MobileLayoutProps) => {
|
||||||
quizHeaderBlock,
|
const { settings } = useQuizData();
|
||||||
quizMainBlock,
|
return (
|
||||||
backgroundBlock,
|
<Box
|
||||||
}: MobileLayoutProps) => {
|
sx={{
|
||||||
const {settings} = useQuizData();
|
display: "flex",
|
||||||
return (
|
flexDirection: "column-reverse",
|
||||||
<Box
|
flexGrow: 1,
|
||||||
|
justifyContent: "flex-end",
|
||||||
|
minHeight: "100%",
|
||||||
|
height: "100%",
|
||||||
|
backgroundPosition: "center",
|
||||||
|
backgroundSize: "cover",
|
||||||
|
backgroundImage: !settings.cfg.design
|
||||||
|
? null
|
||||||
|
: settings.cfg.design && !quizThemes[settings.cfg.theme].isLight
|
||||||
|
? `linear-gradient(0deg, #272626, transparent), url(${DESIGN_LIST[settings.cfg.theme]})`
|
||||||
|
: `url(${DESIGN_LIST[settings.cfg.theme]})`,
|
||||||
|
"&::-webkit-scrollbar": { width: 0 },
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
width: "100%",
|
||||||
|
display: "flex",
|
||||||
|
flexGrow: 1,
|
||||||
|
flexDirection: "column",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
alignItems: "flex-start",
|
||||||
|
padding: "20px",
|
||||||
|
height: "100%",
|
||||||
|
overflowY: "auto",
|
||||||
|
overflowX: "hidden",
|
||||||
|
"&::-webkit-scrollbar": { width: "4px" },
|
||||||
|
"&::-webkit-scrollbar-thumb": { backgroundColor: "#b8babf" },
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{quizHeaderBlock}
|
||||||
|
{settings.cfg.startpage.background.desktop && (
|
||||||
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
width: "100%",
|
||||||
flexDirection: "column-reverse",
|
overflow: "hidden",
|
||||||
flexGrow: 1,
|
"& > img": { width: "100%", borderRadius: "12px" },
|
||||||
justifyContent: "flex-end",
|
|
||||||
minHeight: "100%",
|
|
||||||
height: "100%",
|
|
||||||
backgroundPosition: "center",
|
|
||||||
backgroundSize: "cover",
|
|
||||||
backgroundImage: !settings.cfg.design ? null : settings.cfg.design && !quizThemes[settings.cfg.theme].isLight
|
|
||||||
? `linear-gradient(0deg, #272626, transparent), url(${DESIGN_LIST[settings.cfg.theme]})` : `url(${DESIGN_LIST[settings.cfg.theme]})`,
|
|
||||||
"&::-webkit-scrollbar": {width: 0},
|
|
||||||
}}
|
}}
|
||||||
|
>
|
||||||
|
{backgroundBlock}
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
height: "80%",
|
||||||
|
display: "flex",
|
||||||
|
flexGrow: 1,
|
||||||
|
flexDirection: "column",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
width: "100%",
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Box
|
{quizMainBlock}
|
||||||
sx={{
|
|
||||||
width: "100%",
|
|
||||||
display: "flex",
|
|
||||||
flexGrow: 1,
|
|
||||||
flexDirection: "column",
|
|
||||||
justifyContent: "space-between",
|
|
||||||
alignItems: "flex-start",
|
|
||||||
padding: "20px",
|
|
||||||
height: "100%",
|
|
||||||
overflowY: "auto",
|
|
||||||
overflowX: "hidden",
|
|
||||||
"&::-webkit-scrollbar": {width: "4px"},
|
|
||||||
"&::-webkit-scrollbar-thumb": {backgroundColor: "#b8babf"},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{quizHeaderBlock}
|
|
||||||
{settings.cfg.startpage.background.desktop && (
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
width: "100%",
|
|
||||||
overflow: "hidden",
|
|
||||||
"& > img": {width: "100%", borderRadius: "12px"},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{backgroundBlock}
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
height: "80%",
|
|
||||||
display: "flex",
|
|
||||||
flexGrow: 1,
|
|
||||||
flexDirection: "column",
|
|
||||||
justifyContent: "space-between",
|
|
||||||
width: "100%",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{quizMainBlock}
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
</Box>
|
||||||
);
|
</Box>
|
||||||
}
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export const StartPageMobile = ({
|
export const StartPageMobile = ({
|
||||||
quizHeaderBlock,
|
quizHeaderBlock,
|
||||||
quizMainBlock,
|
quizMainBlock,
|
||||||
backgroundBlock,
|
backgroundBlock,
|
||||||
startpageType,
|
startpageType,
|
||||||
}: StartPageMobileProps) => {
|
}: StartPageMobileProps) => {
|
||||||
switch (startpageType) {
|
switch (startpageType) {
|
||||||
case null:
|
case null:
|
||||||
case "standard": {
|
case "standard": {
|
||||||
return (
|
return (
|
||||||
<StandartMobileLayout
|
<StandartMobileLayout
|
||||||
quizHeaderBlock={quizHeaderBlock}
|
quizHeaderBlock={quizHeaderBlock}
|
||||||
quizMainBlock={quizMainBlock}
|
quizMainBlock={quizMainBlock}
|
||||||
backgroundBlock={backgroundBlock}
|
backgroundBlock={backgroundBlock}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
case "expanded": {
|
|
||||||
return (
|
|
||||||
<ExpandedMobileLayout
|
|
||||||
quizHeaderBlock={quizHeaderBlock}
|
|
||||||
quizMainBlock={quizMainBlock}
|
|
||||||
backgroundBlock={backgroundBlock}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
case "centered": {
|
|
||||||
return (
|
|
||||||
<CenteredMobileLayout
|
|
||||||
quizHeaderBlock={quizHeaderBlock}
|
|
||||||
quizMainBlock={quizMainBlock}
|
|
||||||
backgroundBlock={backgroundBlock}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
notReachable(startpageType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case "expanded": {
|
||||||
|
return (
|
||||||
|
<ExpandedMobileLayout
|
||||||
|
quizHeaderBlock={quizHeaderBlock}
|
||||||
|
quizMainBlock={quizMainBlock}
|
||||||
|
backgroundBlock={backgroundBlock}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
case "centered": {
|
||||||
|
return (
|
||||||
|
<CenteredMobileLayout
|
||||||
|
quizHeaderBlock={quizHeaderBlock}
|
||||||
|
quizMainBlock={quizMainBlock}
|
||||||
|
backgroundBlock={backgroundBlock}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
notReachable(startpageType);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,12 +1,4 @@
|
|||||||
import {
|
import { Box, Button, ButtonBase, Link, Paper, Typography, useTheme } from "@mui/material";
|
||||||
Box,
|
|
||||||
Button,
|
|
||||||
ButtonBase,
|
|
||||||
Link,
|
|
||||||
Paper,
|
|
||||||
Typography,
|
|
||||||
useTheme,
|
|
||||||
} from "@mui/material";
|
|
||||||
|
|
||||||
import { QuizPreviewLayoutByType } from "./QuizPreviewLayoutByType";
|
import { QuizPreviewLayoutByType } from "./QuizPreviewLayoutByType";
|
||||||
|
|
||||||
@ -29,9 +21,7 @@ export const StartPageViewPublication = () => {
|
|||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { settings, show_badge, quizId, questions } = useQuizData();
|
const { settings, show_badge, quizId, questions } = useQuizData();
|
||||||
const { isMobileDevice } = useUADevice();
|
const { isMobileDevice } = useUADevice();
|
||||||
const setCurrentQuizStep = useQuizViewStore(
|
const setCurrentQuizStep = useQuizViewStore((state) => state.setCurrentQuizStep);
|
||||||
(state) => state.setCurrentQuizStep
|
|
||||||
);
|
|
||||||
|
|
||||||
const size = useRootContainerSize();
|
const size = useRootContainerSize();
|
||||||
const isMobile = size < 700;
|
const isMobile = size < 700;
|
||||||
@ -50,18 +40,11 @@ export const StartPageViewPublication = () => {
|
|||||||
const background =
|
const background =
|
||||||
settings.cfg.startpage.background.type === "image" ? (
|
settings.cfg.startpage.background.type === "image" ? (
|
||||||
<img
|
<img
|
||||||
src={
|
src={settings.cfg.startpage.background.desktop || DESIGN_LIST[settings.cfg.theme] || ""}
|
||||||
settings.cfg.startpage.background.desktop ||
|
|
||||||
DESIGN_LIST[settings.cfg.theme] ||
|
|
||||||
""
|
|
||||||
}
|
|
||||||
alt=""
|
alt=""
|
||||||
style={{
|
style={{
|
||||||
display: "block",
|
display: "block",
|
||||||
width:
|
width: isMobile || settings.cfg.startpageType === "expanded" ? "100%" : undefined,
|
||||||
isMobile || settings.cfg.startpageType === "expanded"
|
|
||||||
? "100%"
|
|
||||||
: undefined,
|
|
||||||
height: "100%",
|
height: "100%",
|
||||||
minWidth: "100%",
|
minWidth: "100%",
|
||||||
maxHeight: "100%",
|
maxHeight: "100%",
|
||||||
@ -75,10 +58,8 @@ export const StartPageViewPublication = () => {
|
|||||||
videoUrl={settings.cfg.startpage.background.video}
|
videoUrl={settings.cfg.startpage.background.video}
|
||||||
containerSX={{
|
containerSX={{
|
||||||
width: settings.cfg.startpageType === "centered" ? "550px" : "100%",
|
width: settings.cfg.startpageType === "centered" ? "550px" : "100%",
|
||||||
height:
|
height: settings.cfg.startpageType === "centered" ? "275px" : "100%",
|
||||||
settings.cfg.startpageType === "centered" ? "275px" : "100%",
|
borderRadius: settings.cfg.startpageType === "centered" ? "10px" : "0",
|
||||||
borderRadius:
|
|
||||||
settings.cfg.startpageType === "centered" ? "10px" : "0",
|
|
||||||
overflow: "hidden",
|
overflow: "hidden",
|
||||||
"& iframe": {
|
"& iframe": {
|
||||||
width: "100%",
|
width: "100%",
|
||||||
@ -106,8 +87,7 @@ export const StartPageViewPublication = () => {
|
|||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
flexWrap:
|
flexWrap:
|
||||||
settings.cfg.startpageType === "expanded" &&
|
settings.cfg.startpageType === "expanded" && settings.cfg.startpage.position === "center"
|
||||||
settings.cfg.startpage.position === "center"
|
|
||||||
? "nowrap"
|
? "nowrap"
|
||||||
: "wrap",
|
: "wrap",
|
||||||
gap: isMobile ? "20px" : "30px",
|
gap: isMobile ? "20px" : "30px",
|
||||||
@ -116,15 +96,11 @@ export const StartPageViewPublication = () => {
|
|||||||
? isMobile
|
? isMobile
|
||||||
? "20px"
|
? "20px"
|
||||||
: "25px"
|
: "25px"
|
||||||
: settings.cfg.startpageType === "expanded" &&
|
: settings.cfg.startpageType === "expanded" && settings.cfg.startpage.position === "center" && !isMobile
|
||||||
settings.cfg.startpage.position === "center" &&
|
|
||||||
!isMobile
|
|
||||||
? 0
|
? 0
|
||||||
: "7px",
|
: "7px",
|
||||||
justifyContent:
|
justifyContent:
|
||||||
settings.cfg.startpageType === "expanded" &&
|
settings.cfg.startpageType === "expanded" && settings.cfg.startpage.position === "center" && isMobile
|
||||||
settings.cfg.startpage.position === "center" &&
|
|
||||||
isMobile
|
|
||||||
? "center"
|
? "center"
|
||||||
: undefined,
|
: undefined,
|
||||||
}}
|
}}
|
||||||
@ -143,13 +119,9 @@ export const StartPageViewPublication = () => {
|
|||||||
<Typography
|
<Typography
|
||||||
sx={{
|
sx={{
|
||||||
fontSize: "12px",
|
fontSize: "12px",
|
||||||
color:
|
color: settings.cfg.startpageType === "expanded" ? "white" : theme.palette.text.primary,
|
||||||
settings.cfg.startpageType === "expanded"
|
|
||||||
? "white"
|
|
||||||
: theme.palette.text.primary,
|
|
||||||
wordBreak:
|
wordBreak:
|
||||||
settings.cfg.startpageType === "expanded" &&
|
settings.cfg.startpageType === "expanded" && settings.cfg.startpage.position === "center"
|
||||||
settings.cfg.startpage.position === "center"
|
|
||||||
? "normal"
|
? "normal"
|
||||||
: "break-word",
|
: "break-word",
|
||||||
}}
|
}}
|
||||||
@ -164,8 +136,7 @@ export const StartPageViewPublication = () => {
|
|||||||
<Box
|
<Box
|
||||||
component={Link}
|
component={Link}
|
||||||
target={"_blank"}
|
target={"_blank"}
|
||||||
href={`https://${window.location.hostname.includes("s") ? "s" : ""
|
href={`https://${window.location.hostname.includes("s") ? "s" : ""}quiz.pena.digital/squiz/quiz/logo?q=${quizId}`}
|
||||||
}quiz.pena.digital/squiz/quiz/logo?q=${quizId}`}
|
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
@ -173,9 +144,9 @@ export const StartPageViewPublication = () => {
|
|||||||
textDecoration: "none",
|
textDecoration: "none",
|
||||||
marginLeft:
|
marginLeft:
|
||||||
settings.cfg.startpageType === "expanded" &&
|
settings.cfg.startpageType === "expanded" &&
|
||||||
settings.cfg.startpage.position === "center" &&
|
settings.cfg.startpage.position === "center" &&
|
||||||
!isTablet &&
|
!isTablet &&
|
||||||
!isMobile
|
!isMobile
|
||||||
? "61px"
|
? "61px"
|
||||||
: undefined,
|
: undefined,
|
||||||
}}
|
}}
|
||||||
@ -223,14 +194,11 @@ export const StartPageViewPublication = () => {
|
|||||||
vkMetrics.emailOpened();
|
vkMetrics.emailOpened();
|
||||||
yandexMetrics.emailOpened();
|
yandexMetrics.emailOpened();
|
||||||
|
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
location.href = (
|
location.href = (
|
||||||
settings.cfg.info.site.includes("https")
|
settings.cfg.info.site.includes("https") ? settings.cfg.info.site : `https://${settings.cfg.info.site}`
|
||||||
? settings.cfg.info.site
|
|
||||||
: `https://${settings.cfg.info.site}`
|
|
||||||
).replace(/\s+/g, "");
|
).replace(/\s+/g, "");
|
||||||
}, 1000)
|
}, 1000);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -242,8 +210,7 @@ export const StartPageViewPublication = () => {
|
|||||||
width: "100%",
|
width: "100%",
|
||||||
background:
|
background:
|
||||||
settings.cfg.startpageType === "expanded"
|
settings.cfg.startpageType === "expanded"
|
||||||
? settings.cfg.startpage.position === "left" ||
|
? settings.cfg.startpage.position === "left" || (isMobile && settings.cfg.startpage.position === "right")
|
||||||
(isMobile && settings.cfg.startpage.position === "right")
|
|
||||||
? "linear-gradient(90deg, rgba(39, 38, 38, 0.95) 7.66%, rgba(42, 42, 46, 0.85) 42.12%, rgba(51, 54, 71, 0.4) 100%)"
|
? "linear-gradient(90deg, rgba(39, 38, 38, 0.95) 7.66%, rgba(42, 42, 46, 0.85) 42.12%, rgba(51, 54, 71, 0.4) 100%)"
|
||||||
: settings.cfg.startpage.position === "center"
|
: settings.cfg.startpage.position === "center"
|
||||||
? "linear-gradient(0deg, rgba(39, 38, 38, 0.95) 7.66%, rgba(42, 42, 46, 0.85) 42.12%, rgba(51, 54, 71, 0.4) 100%)"
|
? "linear-gradient(0deg, rgba(39, 38, 38, 0.95) 7.66%, rgba(42, 42, 46, 0.85) 42.12%, rgba(51, 54, 71, 0.4) 100%)"
|
||||||
@ -261,10 +228,7 @@ export const StartPageViewPublication = () => {
|
|||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
justifyContent:
|
justifyContent: settings.cfg.startpageType === "standard" && isMobile ? "start" : "center",
|
||||||
settings.cfg.startpageType === "standard" && isMobile
|
|
||||||
? "start"
|
|
||||||
: "center",
|
|
||||||
flexGrow: settings.cfg.startpageType === "centered" ? 0 : 1,
|
flexGrow: settings.cfg.startpageType === "centered" ? 0 : 1,
|
||||||
wordBreak: "break-word",
|
wordBreak: "break-word",
|
||||||
alignItems:
|
alignItems:
|
||||||
@ -275,19 +239,14 @@ export const StartPageViewPublication = () => {
|
|||||||
? "center"
|
? "center"
|
||||||
: "start"
|
: "start"
|
||||||
: "start",
|
: "start",
|
||||||
marginTop:
|
marginTop: settings.cfg.startpageType === "centered" ? "30px" : isMobile ? "0px" : "5px",
|
||||||
settings.cfg.startpageType === "centered"
|
|
||||||
? "30px"
|
|
||||||
: isMobile
|
|
||||||
? "0px"
|
|
||||||
: "5px",
|
|
||||||
maxWidth: isMobile
|
maxWidth: isMobile
|
||||||
? "100%"
|
? "100%"
|
||||||
: settings.cfg.startpageType === "centered"
|
: settings.cfg.startpageType === "centered"
|
||||||
? "700px"
|
? "700px"
|
||||||
: isTablet &&
|
: isTablet &&
|
||||||
settings.cfg.startpageType !== "expanded" &&
|
settings.cfg.startpageType !== "expanded" &&
|
||||||
settings.cfg.startpage.position !== "center"
|
settings.cfg.startpage.position !== "center"
|
||||||
? "380px"
|
? "380px"
|
||||||
: "531px",
|
: "531px",
|
||||||
}}
|
}}
|
||||||
@ -302,14 +261,10 @@ export const StartPageViewPublication = () => {
|
|||||||
overflowWrap: "break-word",
|
overflowWrap: "break-word",
|
||||||
width: "100%",
|
width: "100%",
|
||||||
textAlign:
|
textAlign:
|
||||||
settings.cfg.startpageType === "centered" ||
|
settings.cfg.startpageType === "centered" || settings.cfg.startpage.position === "center"
|
||||||
settings.cfg.startpage.position === "center"
|
|
||||||
? "center"
|
? "center"
|
||||||
: "-moz-initial",
|
: "-moz-initial",
|
||||||
color:
|
color: settings.cfg.startpageType === "expanded" ? "white" : theme.palette.text.primary,
|
||||||
settings.cfg.startpageType === "expanded"
|
|
||||||
? "white"
|
|
||||||
: theme.palette.text.primary,
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{settings.name}
|
{settings.name}
|
||||||
@ -323,23 +278,15 @@ export const StartPageViewPublication = () => {
|
|||||||
overflowWrap: "break-word",
|
overflowWrap: "break-word",
|
||||||
width: "100%",
|
width: "100%",
|
||||||
textAlign:
|
textAlign:
|
||||||
settings.cfg.startpageType === "centered" ||
|
settings.cfg.startpageType === "centered" || settings.cfg.startpage.position === "center"
|
||||||
settings.cfg.startpage.position === "center"
|
|
||||||
? "center"
|
? "center"
|
||||||
: "-moz-initial",
|
: "-moz-initial",
|
||||||
color:
|
color: settings.cfg.startpageType === "expanded" ? "white" : theme.palette.text.primary,
|
||||||
settings.cfg.startpageType === "expanded"
|
|
||||||
? "white"
|
|
||||||
: theme.palette.text.primary,
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{settings.cfg.startpage.description}
|
{settings.cfg.startpage.description}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Box
|
<Box width={settings.cfg.startpageType === "standard" ? "100%" : "auto"}>
|
||||||
width={
|
|
||||||
settings.cfg.startpageType === "standard" ? "100%" : "auto"
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Button
|
<Button
|
||||||
variant="contained"
|
variant="contained"
|
||||||
disabled={realQuestionsCount === 0}
|
disabled={realQuestionsCount === 0}
|
||||||
@ -352,34 +299,26 @@ export const StartPageViewPublication = () => {
|
|||||||
}}
|
}}
|
||||||
onClick={onQuizStart}
|
onClick={onQuizStart}
|
||||||
>
|
>
|
||||||
{settings.cfg.startpage.button.trim()
|
{settings.cfg.startpage.button.trim() ? settings.cfg.startpage.button : "Пройти тест"}
|
||||||
? settings.cfg.startpage.button
|
|
||||||
: "Пройти тест"}
|
|
||||||
</Button>
|
</Button>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexGrow:
|
flexGrow: settings.cfg.startpageType === "centered" ? (isMobile ? 0 : 1) : 0,
|
||||||
settings.cfg.startpageType === "centered"
|
|
||||||
? isMobile
|
|
||||||
? 0
|
|
||||||
: 1
|
|
||||||
: 0,
|
|
||||||
gap: isMobile ? "30px" : "40px",
|
gap: isMobile ? "30px" : "40px",
|
||||||
alignItems: "flex-end",
|
alignItems: "flex-end",
|
||||||
justifyContent:
|
justifyContent:
|
||||||
(settings.cfg.startpageType === "expanded" &&
|
(settings.cfg.startpageType === "expanded" &&
|
||||||
settings.cfg.startpage.position === "center" &&
|
settings.cfg.startpage.position === "center" &&
|
||||||
isMobile) ||
|
isMobile) ||
|
||||||
(settings.cfg.startpageType === "centered" && isMobile)
|
(settings.cfg.startpageType === "centered" && isMobile)
|
||||||
? "center"
|
? "center"
|
||||||
: "space-between",
|
: "space-between",
|
||||||
width: "100%",
|
width: "100%",
|
||||||
flexWrap:
|
flexWrap:
|
||||||
settings.cfg.startpageType === "expanded" &&
|
settings.cfg.startpageType === "expanded" && settings.cfg.startpage.position === "center"
|
||||||
settings.cfg.startpage.position === "center"
|
|
||||||
? isMobile
|
? isMobile
|
||||||
? "wrap-reverse"
|
? "wrap-reverse"
|
||||||
: "nowrap"
|
: "nowrap"
|
||||||
@ -395,16 +334,15 @@ export const StartPageViewPublication = () => {
|
|||||||
maxWidth: "300px",
|
maxWidth: "300px",
|
||||||
display:
|
display:
|
||||||
(settings.cfg.startpageType === "centered" && isMobile) ||
|
(settings.cfg.startpageType === "centered" && isMobile) ||
|
||||||
(settings.cfg.startpageType === "expanded" &&
|
(settings.cfg.startpageType === "expanded" &&
|
||||||
settings.cfg.startpage.position === "center" &&
|
settings.cfg.startpage.position === "center" &&
|
||||||
isMobile)
|
isMobile)
|
||||||
? "flex"
|
? "flex"
|
||||||
: "block",
|
: "block",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
order:
|
order:
|
||||||
settings.cfg.startpageType === "expanded" &&
|
settings.cfg.startpageType === "expanded" && settings.cfg.startpage.position === "center"
|
||||||
settings.cfg.startpage.position === "center"
|
|
||||||
? "2"
|
? "2"
|
||||||
: "0",
|
: "0",
|
||||||
}}
|
}}
|
||||||
@ -418,8 +356,8 @@ export const StartPageViewPublication = () => {
|
|||||||
marginTop: "10px",
|
marginTop: "10px",
|
||||||
marginLeft:
|
marginLeft:
|
||||||
settings.cfg.startpageType === "expanded" &&
|
settings.cfg.startpageType === "expanded" &&
|
||||||
settings.cfg.startpage.position === "center" &&
|
settings.cfg.startpage.position === "center" &&
|
||||||
!isMobile
|
!isMobile
|
||||||
? "auto"
|
? "auto"
|
||||||
: undefined,
|
: undefined,
|
||||||
}}
|
}}
|
||||||
@ -430,12 +368,14 @@ export const StartPageViewPublication = () => {
|
|||||||
fontSize: "16px",
|
fontSize: "16px",
|
||||||
textAlign:
|
textAlign:
|
||||||
settings.cfg.startpageType === "expanded" &&
|
settings.cfg.startpageType === "expanded" &&
|
||||||
settings.cfg.startpage.position === "center" &&
|
settings.cfg.startpage.position === "center" &&
|
||||||
!isMobile
|
!isMobile
|
||||||
? "end" : settings.cfg.startpageType === "expanded" &&
|
? "end"
|
||||||
settings.cfg.startpage.position === "center" &&
|
: (settings.cfg.startpageType === "expanded" &&
|
||||||
isMobile || settings.cfg.startpageType === "centered" &&
|
settings.cfg.startpage.position === "center" &&
|
||||||
isMobile ? "center"
|
isMobile) ||
|
||||||
|
(settings.cfg.startpageType === "centered" && isMobile)
|
||||||
|
? "center"
|
||||||
: "start",
|
: "start",
|
||||||
color: theme.palette.primary.main,
|
color: theme.palette.primary.main,
|
||||||
overflow: "hidden",
|
overflow: "hidden",
|
||||||
@ -454,15 +394,11 @@ export const StartPageViewPublication = () => {
|
|||||||
sx={{
|
sx={{
|
||||||
lineHeight: "19px",
|
lineHeight: "19px",
|
||||||
textAlign:
|
textAlign:
|
||||||
settings.cfg.startpageType === "expanded" &&
|
settings.cfg.startpageType === "expanded" && settings.cfg.startpage.position === "center"
|
||||||
settings.cfg.startpage.position === "center"
|
|
||||||
? "end"
|
? "end"
|
||||||
: "none",
|
: "none",
|
||||||
fontSize: "16px",
|
fontSize: "16px",
|
||||||
color:
|
color: settings.cfg.startpageType === "expanded" ? "#FFFFFF" : theme.palette.text.primary,
|
||||||
settings.cfg.startpageType === "expanded"
|
|
||||||
? "#FFFFFF"
|
|
||||||
: theme.palette.text.primary,
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{settings.cfg.info.phonenumber}
|
{settings.cfg.info.phonenumber}
|
||||||
@ -476,8 +412,8 @@ export const StartPageViewPublication = () => {
|
|||||||
marginTop: "10px",
|
marginTop: "10px",
|
||||||
marginLeft:
|
marginLeft:
|
||||||
settings.cfg.startpageType === "expanded" &&
|
settings.cfg.startpageType === "expanded" &&
|
||||||
settings.cfg.startpage.position === "center" &&
|
settings.cfg.startpage.position === "center" &&
|
||||||
!isMobile
|
!isMobile
|
||||||
? "auto"
|
? "auto"
|
||||||
: undefined,
|
: undefined,
|
||||||
}}
|
}}
|
||||||
@ -485,16 +421,12 @@ export const StartPageViewPublication = () => {
|
|||||||
<Typography
|
<Typography
|
||||||
sx={{
|
sx={{
|
||||||
textAlign:
|
textAlign:
|
||||||
settings.cfg.startpageType === "expanded" &&
|
settings.cfg.startpageType === "expanded" && settings.cfg.startpage.position === "center"
|
||||||
settings.cfg.startpage.position === "center"
|
|
||||||
? "end"
|
? "end"
|
||||||
: "none",
|
: "none",
|
||||||
fontSize: "16px",
|
fontSize: "16px",
|
||||||
lineHeight: "19px",
|
lineHeight: "19px",
|
||||||
color:
|
color: settings.cfg.startpageType === "expanded" ? "#FFFFFF" : theme.palette.text.primary,
|
||||||
settings.cfg.startpageType === "expanded"
|
|
||||||
? "#FFFFFF"
|
|
||||||
: theme.palette.text.primary,
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{settings.cfg.info.phonenumber}
|
{settings.cfg.info.phonenumber}
|
||||||
@ -506,16 +438,12 @@ export const StartPageViewPublication = () => {
|
|||||||
sx={{
|
sx={{
|
||||||
lineHeight: "19px",
|
lineHeight: "19px",
|
||||||
textAlign:
|
textAlign:
|
||||||
settings.cfg.startpageType === "expanded" &&
|
settings.cfg.startpageType === "expanded" && settings.cfg.startpage.position === "center"
|
||||||
settings.cfg.startpage.position === "center"
|
|
||||||
? "end"
|
? "end"
|
||||||
: "none",
|
: "none",
|
||||||
fontSize: "16px",
|
fontSize: "16px",
|
||||||
marginTop: "10px",
|
marginTop: "10px",
|
||||||
color:
|
color: settings.cfg.startpageType === "expanded" ? "#FFFFFF" : theme.palette.text.primary,
|
||||||
settings.cfg.startpageType === "expanded"
|
|
||||||
? "#FFFFFF"
|
|
||||||
: theme.palette.text.primary,
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{settings.cfg.info.phonenumber}
|
{settings.cfg.info.phonenumber}
|
||||||
@ -530,24 +458,20 @@ export const StartPageViewPublication = () => {
|
|||||||
fontSize: "12px",
|
fontSize: "12px",
|
||||||
textAlign:
|
textAlign:
|
||||||
settings.cfg.startpageType === "expanded" &&
|
settings.cfg.startpageType === "expanded" &&
|
||||||
settings.cfg.startpage.position === "center" &&
|
settings.cfg.startpage.position === "center" &&
|
||||||
!isMobile
|
!isMobile
|
||||||
? "end"
|
? "end"
|
||||||
: (settings.cfg.startpageType === "expanded" &&
|
: (settings.cfg.startpageType === "expanded" &&
|
||||||
settings.cfg.startpage.position === "center" &&
|
settings.cfg.startpage.position === "center" &&
|
||||||
isMobile) ||
|
isMobile) ||
|
||||||
(settings.cfg.startpageType === "centered" &&
|
(settings.cfg.startpageType === "centered" && isMobile)
|
||||||
isMobile)
|
|
||||||
? "center"
|
? "center"
|
||||||
: "none",
|
: "none",
|
||||||
maxHeight: "120px",
|
maxHeight: "120px",
|
||||||
overflow: "auto",
|
overflow: "auto",
|
||||||
marginTop: "10px",
|
marginTop: "10px",
|
||||||
"&::-webkit-scrollbar": { width: 0 },
|
"&::-webkit-scrollbar": { width: 0 },
|
||||||
color:
|
color: settings.cfg.startpageType === "expanded" ? "white" : theme.palette.text.primary,
|
||||||
settings.cfg.startpageType === "expanded"
|
|
||||||
? "white"
|
|
||||||
: theme.palette.text.primary,
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{settings.cfg.info.law}
|
{settings.cfg.info.law}
|
||||||
|
@ -18,13 +18,7 @@ import { useVKMetrics } from "@/utils/hooks/metrics/useVKMetrics";
|
|||||||
import { ContactForm } from "@/components/ViewPublicationPage/ContactForm/ContactForm.tsx";
|
import { ContactForm } from "@/components/ViewPublicationPage/ContactForm/ContactForm.tsx";
|
||||||
|
|
||||||
export default function ViewPublicationPage() {
|
export default function ViewPublicationPage() {
|
||||||
const {
|
const { settings, recentlyCompleted, quizId, preview, changeFaviconAndTitle } = useQuizData();
|
||||||
settings,
|
|
||||||
recentlyCompleted,
|
|
||||||
quizId,
|
|
||||||
preview,
|
|
||||||
changeFaviconAndTitle,
|
|
||||||
} = useQuizData();
|
|
||||||
const answers = useQuizViewStore((state) => state.answers);
|
const answers = useQuizViewStore((state) => state.answers);
|
||||||
let currentQuizStep = useQuizViewStore((state) => state.currentQuizStep);
|
let currentQuizStep = useQuizViewStore((state) => state.currentQuizStep);
|
||||||
const {
|
const {
|
||||||
@ -40,9 +34,7 @@ export default function ViewPublicationPage() {
|
|||||||
useYandexMetrics(settings?.cfg?.yandexMetricsNumber);
|
useYandexMetrics(settings?.cfg?.yandexMetricsNumber);
|
||||||
useVKMetrics(settings?.cfg?.vkMetricsNumber);
|
useVKMetrics(settings?.cfg?.vkMetricsNumber);
|
||||||
|
|
||||||
const isAnswer = answers.some(
|
const isAnswer = answers.some((ans) => ans.questionId === currentQuestion?.id);
|
||||||
(ans) => ans.questionId === currentQuestion?.id
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(
|
useEffect(
|
||||||
function setFaviconAndTitle() {
|
function setFaviconAndTitle() {
|
||||||
@ -59,14 +51,11 @@ export default function ViewPublicationPage() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (recentlyCompleted) throw new Error("Quiz already completed");
|
if (recentlyCompleted) throw new Error("Quiz already completed");
|
||||||
if (currentQuizStep === "startpage" && settings.cfg.noStartPage)
|
if (currentQuizStep === "startpage" && settings.cfg.noStartPage) currentQuizStep = "question";
|
||||||
currentQuizStep = "question";
|
|
||||||
|
|
||||||
if (!currentQuestion)
|
if (!currentQuestion)
|
||||||
return (
|
return (
|
||||||
<ThemeProvider
|
<ThemeProvider theme={quizThemes[settings.cfg.theme || "StandardTheme"].theme}>
|
||||||
theme={quizThemes[settings.cfg.theme || "StandardTheme"].theme}
|
|
||||||
>
|
|
||||||
<Typography textAlign={"center"} mt="50px">
|
<Typography textAlign={"center"} mt="50px">
|
||||||
Вопрос не выбран
|
Вопрос не выбран
|
||||||
</Typography>
|
</Typography>
|
||||||
@ -91,10 +80,7 @@ export default function ViewPublicationPage() {
|
|||||||
currentQuestion={currentQuestion}
|
currentQuestion={currentQuestion}
|
||||||
currentQuestionStepNumber={currentQuestionStepNumber}
|
currentQuestionStepNumber={currentQuestionStepNumber}
|
||||||
prevButton={
|
prevButton={
|
||||||
<PrevButton
|
<PrevButton isPreviousButtonEnabled={isPreviousButtonEnabled} moveToPrevQuestion={moveToPrevQuestion} />
|
||||||
isPreviousButtonEnabled={isPreviousButtonEnabled}
|
|
||||||
moveToPrevQuestion={moveToPrevQuestion}
|
|
||||||
/>
|
|
||||||
}
|
}
|
||||||
nextButton={
|
nextButton={
|
||||||
<NextButton
|
<NextButton
|
||||||
@ -116,23 +102,13 @@ export default function ViewPublicationPage() {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
questionSelect={
|
questionSelect={<QuestionSelect selectedQuestion={currentQuestion} setQuestion={setQuestion} />}
|
||||||
<QuestionSelect
|
|
||||||
selectedQuestion={currentQuestion}
|
|
||||||
setQuestion={setQuestion}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "contactform": {
|
case "contactform": {
|
||||||
quizStepElement = (
|
quizStepElement = <ContactForm currentQuestion={currentQuestion} onShowResult={showResultAfterContactForm} />;
|
||||||
<ContactForm
|
|
||||||
currentQuestion={currentQuestion}
|
|
||||||
onShowResult={showResultAfterContactForm}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -140,10 +116,6 @@ export default function ViewPublicationPage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ThemeProvider
|
<ThemeProvider theme={quizThemes[settings.cfg.theme || "StandardTheme"].theme}>{quizStepElement}</ThemeProvider>
|
||||||
theme={quizThemes[settings.cfg.theme || "StandardTheme"].theme}
|
|
||||||
>
|
|
||||||
{quizStepElement}
|
|
||||||
</ThemeProvider>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -25,9 +25,7 @@ export const Date = ({ currentQuestion }: DateProps) => {
|
|||||||
const answers = useQuizViewStore((state) => state.answers);
|
const answers = useQuizViewStore((state) => state.answers);
|
||||||
const { updateAnswer } = useQuizViewStore((state) => state);
|
const { updateAnswer } = useQuizViewStore((state) => state);
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const answer = answers.find(
|
const answer = answers.find(({ questionId }) => questionId === currentQuestion.id)?.answer as string;
|
||||||
({ questionId }) => questionId === currentQuestion.id
|
|
||||||
)?.answer as string;
|
|
||||||
const currentAnswer = moment(answer) || moment();
|
const currentAnswer = moment(answer) || moment();
|
||||||
|
|
||||||
const onDateChange = async (date: Moment | null) => {
|
const onDateChange = async (date: Moment | null) => {
|
||||||
@ -52,11 +50,7 @@ export const Date = ({ currentQuestion }: DateProps) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
<Typography
|
<Typography variant="h5" color={theme.palette.text.primary} sx={{ wordBreak: "break-word" }}>
|
||||||
variant="h5"
|
|
||||||
color={theme.palette.text.primary}
|
|
||||||
sx={{ wordBreak: "break-word" }}
|
|
||||||
>
|
|
||||||
{currentQuestion.title}
|
{currentQuestion.title}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Box
|
<Box
|
||||||
@ -94,8 +88,8 @@ export const Date = ({ currentQuestion }: DateProps) => {
|
|||||||
? "#F2F3F7"
|
? "#F2F3F7"
|
||||||
: "rgba(154,154,175, 0.2)"
|
: "rgba(154,154,175, 0.2)"
|
||||||
: quizThemes[settings.cfg.theme].isLight
|
: quizThemes[settings.cfg.theme].isLight
|
||||||
? "white"
|
? "white"
|
||||||
: theme.palette.background.default,
|
: theme.palette.background.default,
|
||||||
borderRadius: "10px",
|
borderRadius: "10px",
|
||||||
maxWidth: "250px",
|
maxWidth: "250px",
|
||||||
pr: "30px",
|
pr: "30px",
|
||||||
|
@ -1,11 +1,4 @@
|
|||||||
import {
|
import { Box, FormControl, FormControlLabel, Radio, Typography, useTheme } from "@mui/material";
|
||||||
Box,
|
|
||||||
FormControl,
|
|
||||||
FormControlLabel,
|
|
||||||
Radio,
|
|
||||||
Typography,
|
|
||||||
useTheme,
|
|
||||||
} from "@mui/material";
|
|
||||||
import { polyfillCountryFlagEmojis } from "country-flag-emoji-polyfill";
|
import { polyfillCountryFlagEmojis } from "country-flag-emoji-polyfill";
|
||||||
import { enqueueSnackbar } from "notistack";
|
import { enqueueSnackbar } from "notistack";
|
||||||
|
|
||||||
@ -31,19 +24,12 @@ type EmojiVariantProps = {
|
|||||||
setIsSending: (isSending: boolean) => void;
|
setIsSending: (isSending: boolean) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const EmojiVariant = ({
|
export const EmojiVariant = ({ currentQuestion, variant, index, isSending, setIsSending }: EmojiVariantProps) => {
|
||||||
currentQuestion,
|
|
||||||
variant,
|
|
||||||
index,
|
|
||||||
isSending,
|
|
||||||
setIsSending,
|
|
||||||
}: EmojiVariantProps) => {
|
|
||||||
const { quizId, settings, preview } = useQuizData();
|
const { quizId, settings, preview } = useQuizData();
|
||||||
const answers = useQuizViewStore((state) => state.answers);
|
const answers = useQuizViewStore((state) => state.answers);
|
||||||
const { updateAnswer, deleteAnswer } = useQuizViewStore((state) => state);
|
const { updateAnswer, deleteAnswer } = useQuizViewStore((state) => state);
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { answer } =
|
const { answer } = answers.find(({ questionId }) => questionId === currentQuestion.id) ?? {};
|
||||||
answers.find(({ questionId }) => questionId === currentQuestion.id) ?? {};
|
|
||||||
|
|
||||||
const onVariantClick = async (event: MouseEvent<HTMLDivElement>) => {
|
const onVariantClick = async (event: MouseEvent<HTMLDivElement>) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
@ -54,9 +40,7 @@ export const EmojiVariant = ({
|
|||||||
await sendAnswer({
|
await sendAnswer({
|
||||||
questionId: currentQuestion.id,
|
questionId: currentQuestion.id,
|
||||||
body:
|
body:
|
||||||
currentQuestion.content.variants[index].extendedText +
|
currentQuestion.content.variants[index].extendedText + " " + currentQuestion.content.variants[index].answer,
|
||||||
" " +
|
|
||||||
currentQuestion.content.variants[index].answer,
|
|
||||||
qid: quizId,
|
qid: quizId,
|
||||||
preview,
|
preview,
|
||||||
});
|
});
|
||||||
@ -94,8 +78,7 @@ export const EmojiVariant = ({
|
|||||||
sx={{
|
sx={{
|
||||||
borderRadius: "12px",
|
borderRadius: "12px",
|
||||||
border: `1px solid`,
|
border: `1px solid`,
|
||||||
borderColor:
|
borderColor: answer === variant.id ? theme.palette.primary.main : "#9A9AAF",
|
||||||
answer === variant.id ? theme.palette.primary.main : "#9A9AAF",
|
|
||||||
overflow: "hidden",
|
overflow: "hidden",
|
||||||
maxWidth: "317px",
|
maxWidth: "317px",
|
||||||
width: "100%",
|
width: "100%",
|
||||||
@ -103,10 +86,9 @@ export const EmojiVariant = ({
|
|||||||
background:
|
background:
|
||||||
settings.cfg.design && !quizThemes[settings.cfg.theme].isLight
|
settings.cfg.design && !quizThemes[settings.cfg.theme].isLight
|
||||||
? "rgba(255,255,255, 0.3)"
|
? "rgba(255,255,255, 0.3)"
|
||||||
: (settings.cfg.design && quizThemes[settings.cfg.theme].isLight) ||
|
: (settings.cfg.design && quizThemes[settings.cfg.theme].isLight) || quizThemes[settings.cfg.theme].isLight
|
||||||
quizThemes[settings.cfg.theme].isLight
|
? "#FFFFFF"
|
||||||
? "#FFFFFF"
|
: "transparent",
|
||||||
: "transparent",
|
|
||||||
"&:hover": { borderColor: theme.palette.primary.main },
|
"&:hover": { borderColor: theme.palette.primary.main },
|
||||||
}}
|
}}
|
||||||
// value={index}
|
// value={index}
|
||||||
@ -128,9 +110,7 @@ export const EmojiVariant = ({
|
|||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{variant.extendedText && (
|
{variant.extendedText && <Typography fontSize="100px">{variant.extendedText}</Typography>}
|
||||||
<Typography fontSize="100px">{variant.extendedText}</Typography>
|
|
||||||
)}
|
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
@ -168,9 +148,7 @@ export const EmojiVariant = ({
|
|||||||
}
|
}
|
||||||
label={
|
label={
|
||||||
<Box sx={{ display: "flex", gap: "10px" }}>
|
<Box sx={{ display: "flex", gap: "10px" }}>
|
||||||
<Typography sx={{ wordBreak: "break-word", lineHeight: "normal" }}>
|
<Typography sx={{ wordBreak: "break-word", lineHeight: "normal" }}>{variant.answer}</Typography>
|
||||||
{variant.answer}
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
</Box>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
@ -18,23 +18,16 @@ export const Emoji = ({ currentQuestion }: EmojiProps) => {
|
|||||||
const answers = useQuizViewStore((state) => state.answers);
|
const answers = useQuizViewStore((state) => state.answers);
|
||||||
const { updateAnswer } = useQuizViewStore((state) => state);
|
const { updateAnswer } = useQuizViewStore((state) => state);
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { answer } =
|
const { answer } = answers.find(({ questionId }) => questionId === currentQuestion.id) ?? {};
|
||||||
answers.find(({ questionId }) => questionId === currentQuestion.id) ?? {};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
<Typography
|
<Typography variant="h5" color={theme.palette.text.primary} sx={{ wordBreak: "break-word" }}>
|
||||||
variant="h5"
|
|
||||||
color={theme.palette.text.primary}
|
|
||||||
sx={{ wordBreak: "break-word" }}
|
|
||||||
>
|
|
||||||
{currentQuestion.title}
|
{currentQuestion.title}
|
||||||
</Typography>
|
</Typography>
|
||||||
<RadioGroup
|
<RadioGroup
|
||||||
name={currentQuestion.id}
|
name={currentQuestion.id}
|
||||||
value={currentQuestion.content.variants.findIndex(
|
value={currentQuestion.content.variants.findIndex(({ id }) => answer === id)}
|
||||||
({ id }) => answer === id
|
|
||||||
)}
|
|
||||||
onChange={({ target }) =>
|
onChange={({ target }) =>
|
||||||
updateAnswer(
|
updateAnswer(
|
||||||
currentQuestion.id,
|
currentQuestion.id,
|
||||||
@ -50,9 +43,7 @@ export const Emoji = ({ currentQuestion }: EmojiProps) => {
|
|||||||
marginTop: "20px",
|
marginTop: "20px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Box
|
<Box sx={{ display: "flex", width: "100%", gap: "42px", flexWrap: "wrap" }}>
|
||||||
sx={{ display: "flex", width: "100%", gap: "42px", flexWrap: "wrap" }}
|
|
||||||
>
|
|
||||||
{currentQuestion.content.variants.map((variant, index) => (
|
{currentQuestion.content.variants.map((variant, index) => (
|
||||||
<EmojiVariant
|
<EmojiVariant
|
||||||
key={variant.id}
|
key={variant.id}
|
||||||
|
@ -26,32 +26,24 @@ type UploadFileProps = {
|
|||||||
setIsSending: (isSending: boolean) => void;
|
setIsSending: (isSending: boolean) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const UploadFile = ({
|
export const UploadFile = ({ currentQuestion, setModalWarningType, isSending, setIsSending }: UploadFileProps) => {
|
||||||
currentQuestion,
|
|
||||||
setModalWarningType,
|
|
||||||
isSending,
|
|
||||||
setIsSending,
|
|
||||||
}: UploadFileProps) => {
|
|
||||||
const { quizId, preview } = useQuizData();
|
const { quizId, preview } = useQuizData();
|
||||||
const [isDropzoneHighlighted, setIsDropzoneHighlighted] =
|
const [isDropzoneHighlighted, setIsDropzoneHighlighted] = useState<boolean>(false);
|
||||||
useState<boolean>(false);
|
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const answers = useQuizViewStore((state) => state.answers);
|
const answers = useQuizViewStore((state) => state.answers);
|
||||||
const { updateAnswer } = useQuizViewStore((state) => state);
|
const { updateAnswer } = useQuizViewStore((state) => state);
|
||||||
const isMobile = useRootContainerSize() < 500;
|
const isMobile = useRootContainerSize() < 500;
|
||||||
|
|
||||||
const answer = answers.find(
|
const answer = answers.find(({ questionId }) => questionId === currentQuestion.id)?.answer as string;
|
||||||
({ questionId }) => questionId === currentQuestion.id
|
|
||||||
)?.answer as string;
|
|
||||||
|
|
||||||
const uploadFile = async (file: File | undefined) => {
|
const uploadFile = async (file: File | undefined) => {
|
||||||
if (isSending) return;
|
if (isSending) return;
|
||||||
if (!file) return;
|
if (!file) return;
|
||||||
if (file.size > MAX_FILE_SIZE) return setModalWarningType("errorSize");
|
if (file.size > MAX_FILE_SIZE) return setModalWarningType("errorSize");
|
||||||
|
|
||||||
const isFileTypeAccepted = ACCEPT_SEND_FILE_TYPES_MAP[
|
const isFileTypeAccepted = ACCEPT_SEND_FILE_TYPES_MAP[currentQuestion.content.type].some((fileType) =>
|
||||||
currentQuestion.content.type
|
file.name.toLowerCase().endsWith(fileType)
|
||||||
].some((fileType) => file.name.toLowerCase().endsWith(fileType));
|
);
|
||||||
|
|
||||||
if (!isFileTypeAccepted) return setModalWarningType("errorType");
|
if (!isFileTypeAccepted) return setModalWarningType("errorType");
|
||||||
|
|
||||||
@ -76,11 +68,7 @@ export const UploadFile = ({
|
|||||||
preview,
|
preview,
|
||||||
});
|
});
|
||||||
|
|
||||||
updateAnswer(
|
updateAnswer(currentQuestion.id, `${file.name}|${URL.createObjectURL(file)}`, 0);
|
||||||
currentQuestion.id,
|
|
||||||
`${file.name}|${URL.createObjectURL(file)}`,
|
|
||||||
0
|
|
||||||
);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
enqueueSnackbar("ответ не был засчитан");
|
enqueueSnackbar("ответ не был засчитан");
|
||||||
@ -101,28 +89,18 @@ export const UploadFile = ({
|
|||||||
return (
|
return (
|
||||||
<Box sx={{ display: "flex", alignItems: "center" }}>
|
<Box sx={{ display: "flex", alignItems: "center" }}>
|
||||||
{isSending ? (
|
{isSending ? (
|
||||||
<Skeleton
|
<Skeleton variant="rounded" sx={{ width: "100%", height: "120px", maxWidth: "560px" }} />
|
||||||
variant="rounded"
|
|
||||||
sx={{ width: "100%", height: "120px", maxWidth: "560px" }}
|
|
||||||
/>
|
|
||||||
) : (
|
) : (
|
||||||
<ButtonBase
|
<ButtonBase component="label" sx={{ justifyContent: "flex-start", width: "100%" }}>
|
||||||
component="label"
|
|
||||||
sx={{ justifyContent: "flex-start", width: "100%" }}
|
|
||||||
>
|
|
||||||
<input
|
<input
|
||||||
onChange={({ target }) => uploadFile(target.files?.[0])}
|
onChange={({ target }) => uploadFile(target.files?.[0])}
|
||||||
hidden
|
hidden
|
||||||
accept={ACCEPT_SEND_FILE_TYPES_MAP[
|
accept={ACCEPT_SEND_FILE_TYPES_MAP[currentQuestion.content.type].join(",")}
|
||||||
currentQuestion.content.type
|
|
||||||
].join(",")}
|
|
||||||
multiple
|
multiple
|
||||||
type="file"
|
type="file"
|
||||||
/>
|
/>
|
||||||
<Box
|
<Box
|
||||||
onDragEnter={() =>
|
onDragEnter={() => !answer?.split("|")[0] && setIsDropzoneHighlighted(true)}
|
||||||
!answer?.split("|")[0] && setIsDropzoneHighlighted(true)
|
|
||||||
}
|
|
||||||
onDragLeave={() => setIsDropzoneHighlighted(false)}
|
onDragLeave={() => setIsDropzoneHighlighted(false)}
|
||||||
onDragOver={(event) => event.preventDefault()}
|
onDragOver={(event) => event.preventDefault()}
|
||||||
onDrop={onDrop}
|
onDrop={onDrop}
|
||||||
@ -142,10 +120,7 @@ export const UploadFile = ({
|
|||||||
<UploadIcon />
|
<UploadIcon />
|
||||||
<Box>
|
<Box>
|
||||||
<Typography sx={{ color: "#9A9AAF", fontWeight: 500 }}>
|
<Typography sx={{ color: "#9A9AAF", fontWeight: 500 }}>
|
||||||
{
|
{UPLOAD_FILE_DESCRIPTIONS_MAP[currentQuestion.content.type].title}
|
||||||
UPLOAD_FILE_DESCRIPTIONS_MAP[currentQuestion.content.type]
|
|
||||||
.title
|
|
||||||
}
|
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography
|
<Typography
|
||||||
sx={{
|
sx={{
|
||||||
@ -154,10 +129,7 @@ export const UploadFile = ({
|
|||||||
lineHeight: "19px",
|
lineHeight: "19px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{
|
{UPLOAD_FILE_DESCRIPTIONS_MAP[currentQuestion.content.type].description}
|
||||||
UPLOAD_FILE_DESCRIPTIONS_MAP[currentQuestion.content.type]
|
|
||||||
.description
|
|
||||||
}
|
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
@ -13,18 +13,13 @@ type UploadedFileProps = {
|
|||||||
setIsSending: (isSending: boolean) => void;
|
setIsSending: (isSending: boolean) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const UploadedFile = ({
|
export const UploadedFile = ({ currentQuestion, setIsSending }: UploadedFileProps) => {
|
||||||
currentQuestion,
|
|
||||||
setIsSending,
|
|
||||||
}: UploadedFileProps) => {
|
|
||||||
const { quizId, preview } = useQuizData();
|
const { quizId, preview } = useQuizData();
|
||||||
const answers = useQuizViewStore((state) => state.answers);
|
const answers = useQuizViewStore((state) => state.answers);
|
||||||
const { updateAnswer } = useQuizViewStore((state) => state);
|
const { updateAnswer } = useQuizViewStore((state) => state);
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
const answer = answers.find(
|
const answer = answers.find(({ questionId }) => questionId === currentQuestion.id)?.answer as string;
|
||||||
({ questionId }) => questionId === currentQuestion.id
|
|
||||||
)?.answer as string;
|
|
||||||
|
|
||||||
const deleteFile = async () => {
|
const deleteFile = async () => {
|
||||||
if (answer.length > 0) {
|
if (answer.length > 0) {
|
||||||
|
@ -11,14 +11,7 @@ import { ACCEPT_SEND_FILE_TYPES_MAP } from "@/components/ViewPublicationPage/too
|
|||||||
|
|
||||||
import type { QuizQuestionFile } from "@model/questionTypes/file";
|
import type { QuizQuestionFile } from "@model/questionTypes/file";
|
||||||
|
|
||||||
export type ModalWarningType =
|
export type ModalWarningType = "errorType" | "errorSize" | "picture" | "video" | "audio" | "document" | null;
|
||||||
| "errorType"
|
|
||||||
| "errorSize"
|
|
||||||
| "picture"
|
|
||||||
| "video"
|
|
||||||
| "audio"
|
|
||||||
| "document"
|
|
||||||
| null;
|
|
||||||
|
|
||||||
type FileProps = {
|
type FileProps = {
|
||||||
currentQuestion: QuizQuestionFile;
|
currentQuestion: QuizQuestionFile;
|
||||||
@ -27,22 +20,15 @@ type FileProps = {
|
|||||||
export const File = ({ currentQuestion }: FileProps) => {
|
export const File = ({ currentQuestion }: FileProps) => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const answers = useQuizViewStore((state) => state.answers);
|
const answers = useQuizViewStore((state) => state.answers);
|
||||||
const [modalWarningType, setModalWarningType] =
|
const [modalWarningType, setModalWarningType] = useState<ModalWarningType>(null);
|
||||||
useState<ModalWarningType>(null);
|
|
||||||
const [isSending, setIsSending] = useState<boolean>(false);
|
const [isSending, setIsSending] = useState<boolean>(false);
|
||||||
const isMobile = useRootContainerSize() < 500;
|
const isMobile = useRootContainerSize() < 500;
|
||||||
|
|
||||||
const answer = answers.find(
|
const answer = answers.find(({ questionId }) => questionId === currentQuestion.id)?.answer as string;
|
||||||
({ questionId }) => questionId === currentQuestion.id
|
|
||||||
)?.answer as string;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
<Typography
|
<Typography variant="h5" color={theme.palette.text.primary} sx={{ wordBreak: "break-word" }}>
|
||||||
variant="h5"
|
|
||||||
color={theme.palette.text.primary}
|
|
||||||
sx={{ wordBreak: "break-word" }}
|
|
||||||
>
|
|
||||||
{currentQuestion.title}
|
{currentQuestion.title}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Box
|
<Box
|
||||||
@ -55,10 +41,7 @@ export const File = ({ currentQuestion }: FileProps) => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{answer?.split("|")[0] ? (
|
{answer?.split("|")[0] ? (
|
||||||
<UploadedFile
|
<UploadedFile currentQuestion={currentQuestion} setIsSending={setIsSending} />
|
||||||
currentQuestion={currentQuestion}
|
|
||||||
setIsSending={setIsSending}
|
|
||||||
/>
|
|
||||||
) : (
|
) : (
|
||||||
<UploadFile
|
<UploadFile
|
||||||
currentQuestion={currentQuestion}
|
currentQuestion={currentQuestion}
|
||||||
@ -68,11 +51,7 @@ export const File = ({ currentQuestion }: FileProps) => {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{answer && currentQuestion.content.type === "picture" && (
|
{answer && currentQuestion.content.type === "picture" && (
|
||||||
<img
|
<img src={answer.split("|")[1]} style={{ marginTop: "15px", maxWidth: "300px", maxHeight: "300px" }} alt="" />
|
||||||
src={answer.split("|")[1]}
|
|
||||||
style={{ marginTop: "15px", maxWidth: "300px", maxHeight: "300px" }}
|
|
||||||
alt=""
|
|
||||||
/>
|
|
||||||
)}
|
)}
|
||||||
{answer && currentQuestion.content.type === "video" && (
|
{answer && currentQuestion.content.type === "video" && (
|
||||||
<video
|
<video
|
||||||
@ -86,10 +65,7 @@ export const File = ({ currentQuestion }: FileProps) => {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
<Modal
|
<Modal open={modalWarningType !== null} onClose={() => setModalWarningType(null)}>
|
||||||
open={modalWarningType !== null}
|
|
||||||
onClose={() => setModalWarningType(null)}
|
|
||||||
>
|
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
@ -117,17 +93,13 @@ const CurrentModal = ({ status }: { status: ModalWarningType }) => {
|
|||||||
case "errorType":
|
case "errorType":
|
||||||
return <Typography>Выбран некорректный тип файла</Typography>;
|
return <Typography>Выбран некорректный тип файла</Typography>;
|
||||||
case "errorSize":
|
case "errorSize":
|
||||||
return (
|
return <Typography>Файл слишком большой. Максимальный размер 50 МБ</Typography>;
|
||||||
<Typography>Файл слишком большой. Максимальный размер 50 МБ</Typography>
|
|
||||||
);
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Typography>Допустимые расширения файлов:</Typography>
|
<Typography>Допустимые расширения файлов:</Typography>
|
||||||
<Typography>
|
<Typography>{ACCEPT_SEND_FILE_TYPES_MAP[status].join(" ")}</Typography>
|
||||||
{ACCEPT_SEND_FILE_TYPES_MAP[status].join(" ")}
|
|
||||||
</Typography>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -21,21 +21,13 @@ type ImagesProps = {
|
|||||||
index: number;
|
index: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ImageVariant = ({
|
export const ImageVariant = ({ currentQuestion, variant, isSending, setIsSending, index }: ImagesProps) => {
|
||||||
currentQuestion,
|
|
||||||
variant,
|
|
||||||
isSending,
|
|
||||||
setIsSending,
|
|
||||||
index,
|
|
||||||
}: ImagesProps) => {
|
|
||||||
const { quizId, preview } = useQuizData();
|
const { quizId, preview } = useQuizData();
|
||||||
const { settings } = useQuizData();
|
const { settings } = useQuizData();
|
||||||
const answers = useQuizViewStore((state) => state.answers);
|
const answers = useQuizViewStore((state) => state.answers);
|
||||||
const { deleteAnswer, updateAnswer } = useQuizViewStore((state) => state);
|
const { deleteAnswer, updateAnswer } = useQuizViewStore((state) => state);
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const answer = answers.find(
|
const answer = answers.find(({ questionId }) => questionId === currentQuestion.id)?.answer;
|
||||||
({ questionId }) => questionId === currentQuestion.id
|
|
||||||
)?.answer;
|
|
||||||
|
|
||||||
const onVariantClick = async (event: MouseEvent<HTMLDivElement>) => {
|
const onVariantClick = async (event: MouseEvent<HTMLDivElement>) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
@ -81,16 +73,14 @@ export const ImageVariant = ({
|
|||||||
cursor: "pointer",
|
cursor: "pointer",
|
||||||
borderRadius: "12px",
|
borderRadius: "12px",
|
||||||
border: `1px solid`,
|
border: `1px solid`,
|
||||||
borderColor:
|
borderColor: answer === variant.id ? theme.palette.primary.main : "#9A9AAF",
|
||||||
answer === variant.id ? theme.palette.primary.main : "#9A9AAF",
|
|
||||||
"&:hover": { borderColor: theme.palette.primary.main },
|
"&:hover": { borderColor: theme.palette.primary.main },
|
||||||
background:
|
background:
|
||||||
settings.cfg.design && !quizThemes[settings.cfg.theme].isLight
|
settings.cfg.design && !quizThemes[settings.cfg.theme].isLight
|
||||||
? "rgba(255,255,255, 0.3)"
|
? "rgba(255,255,255, 0.3)"
|
||||||
: (settings.cfg.design && quizThemes[settings.cfg.theme].isLight) ||
|
: (settings.cfg.design && quizThemes[settings.cfg.theme].isLight) || quizThemes[settings.cfg.theme].isLight
|
||||||
quizThemes[settings.cfg.theme].isLight
|
? "#FFFFFF"
|
||||||
? "#FFFFFF"
|
: "transparent",
|
||||||
: "transparent",
|
|
||||||
}}
|
}}
|
||||||
onClick={onVariantClick}
|
onClick={onVariantClick}
|
||||||
>
|
>
|
||||||
|
@ -16,26 +16,18 @@ export const Images = ({ currentQuestion }: ImagesProps) => {
|
|||||||
const [isSending, setIsSending] = useState<boolean>(false);
|
const [isSending, setIsSending] = useState<boolean>(false);
|
||||||
const answers = useQuizViewStore((state) => state.answers);
|
const answers = useQuizViewStore((state) => state.answers);
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const answer = answers.find(
|
const answer = answers.find(({ questionId }) => questionId === currentQuestion.id)?.answer;
|
||||||
({ questionId }) => questionId === currentQuestion.id
|
|
||||||
)?.answer;
|
|
||||||
const isTablet = useRootContainerSize() < 1000;
|
const isTablet = useRootContainerSize() < 1000;
|
||||||
const isMobile = useRootContainerSize() < 500;
|
const isMobile = useRootContainerSize() < 500;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
<Typography
|
<Typography variant="h5" color={theme.palette.text.primary} sx={{ wordBreak: "break-word" }}>
|
||||||
variant="h5"
|
|
||||||
color={theme.palette.text.primary}
|
|
||||||
sx={{ wordBreak: "break-word" }}
|
|
||||||
>
|
|
||||||
{currentQuestion.title}
|
{currentQuestion.title}
|
||||||
</Typography>
|
</Typography>
|
||||||
<RadioGroup
|
<RadioGroup
|
||||||
name={currentQuestion.id}
|
name={currentQuestion.id}
|
||||||
value={currentQuestion.content.variants.findIndex(
|
value={currentQuestion.content.variants.findIndex(({ id }) => answer === id)}
|
||||||
({ id }) => answer === id
|
|
||||||
)}
|
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexWrap: "wrap",
|
flexWrap: "wrap",
|
||||||
@ -48,11 +40,7 @@ export const Images = ({ currentQuestion }: ImagesProps) => {
|
|||||||
sx={{
|
sx={{
|
||||||
display: "grid",
|
display: "grid",
|
||||||
gap: "15px",
|
gap: "15px",
|
||||||
gridTemplateColumns: isTablet
|
gridTemplateColumns: isTablet ? (isMobile ? "repeat(1, 1fr)" : "repeat(2, 1fr)") : "repeat(3, 1fr)",
|
||||||
? isMobile
|
|
||||||
? "repeat(1, 1fr)"
|
|
||||||
: "repeat(2, 1fr)"
|
|
||||||
: "repeat(3, 1fr)",
|
|
||||||
width: "100%",
|
width: "100%",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
@ -27,29 +27,22 @@ export const Number = ({ currentQuestion }: NumberProps) => {
|
|||||||
const [maxRange, setMaxRange] = useState<string>("100000000000");
|
const [maxRange, setMaxRange] = useState<string>("100000000000");
|
||||||
const [reversedInputValue, setReversedInputValue] = useState<string>("0");
|
const [reversedInputValue, setReversedInputValue] = useState<string>("0");
|
||||||
const [reversedMinRange, setReversedMinRange] = useState<string>("0");
|
const [reversedMinRange, setReversedMinRange] = useState<string>("0");
|
||||||
const [reversedMaxRange, setReversedMaxRange] =
|
const [reversedMaxRange, setReversedMaxRange] = useState<string>("100000000000");
|
||||||
useState<string>("100000000000");
|
|
||||||
const { settings, quizId, preview } = useQuizData();
|
const { settings, quizId, preview } = useQuizData();
|
||||||
const { updateAnswer } = useQuizViewStore((state) => state);
|
const { updateAnswer } = useQuizViewStore((state) => state);
|
||||||
const answers = useQuizViewStore((state) => state.answers);
|
const answers = useQuizViewStore((state) => state.answers);
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
const [minBorder, maxBorder] = currentQuestion.content.range
|
const [minBorder, maxBorder] = currentQuestion.content.range.split("—").map(window.Number);
|
||||||
.split("—")
|
|
||||||
.map(window.Number);
|
|
||||||
const min = minBorder < maxBorder ? minBorder : maxBorder;
|
const min = minBorder < maxBorder ? minBorder : maxBorder;
|
||||||
const max = minBorder < maxBorder ? maxBorder : minBorder;
|
const max = minBorder < maxBorder ? maxBorder : minBorder;
|
||||||
const reversed = minBorder > maxBorder;
|
const reversed = minBorder > maxBorder;
|
||||||
|
|
||||||
const answer = answers.find(
|
const answer = answers.find(({ questionId }) => questionId === currentQuestion.id)?.answer as string;
|
||||||
({ questionId }) => questionId === currentQuestion.id
|
|
||||||
)?.answer as string;
|
|
||||||
|
|
||||||
const sliderValue =
|
const sliderValue =
|
||||||
answer ||
|
answer ||
|
||||||
(reversed
|
(reversed ? max + min - currentQuestion.content.start + "—" + max : currentQuestion.content.start + "—" + max);
|
||||||
? max + min - currentQuestion.content.start + "—" + max
|
|
||||||
: currentQuestion.content.start + "—" + max);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log("reversed:", reversed);
|
console.log("reversed:", reversed);
|
||||||
@ -81,15 +74,11 @@ export const Number = ({ currentQuestion }: NumberProps) => {
|
|||||||
window.Number(value) < window.Number(min)
|
window.Number(value) < window.Number(min)
|
||||||
? String(min)
|
? String(min)
|
||||||
: window.Number(value) > window.Number(max)
|
: window.Number(value) > window.Number(max)
|
||||||
? String(max)
|
? String(max)
|
||||||
: value;
|
: value;
|
||||||
|
|
||||||
setReversedInputValue(newValue);
|
setReversedInputValue(newValue);
|
||||||
updateAnswer(
|
updateAnswer(currentQuestion.id, String(max + min - window.Number(newValue)), 0);
|
||||||
currentQuestion.id,
|
|
||||||
String(max + min - window.Number(newValue)),
|
|
||||||
0
|
|
||||||
);
|
|
||||||
await sendAnswerToBackend(String(window.Number(newValue)), true);
|
await sendAnswerToBackend(String(window.Number(newValue)), true);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -99,107 +88,73 @@ export const Number = ({ currentQuestion }: NumberProps) => {
|
|||||||
window.Number(value) < window.Number(minRange)
|
window.Number(value) < window.Number(minRange)
|
||||||
? minRange
|
? minRange
|
||||||
: window.Number(value) > window.Number(maxRange)
|
: window.Number(value) > window.Number(maxRange)
|
||||||
? maxRange
|
? maxRange
|
||||||
: value;
|
: value;
|
||||||
|
|
||||||
setInputValue(newValue);
|
setInputValue(newValue);
|
||||||
await sendAnswerToBackend(newValue);
|
await sendAnswerToBackend(newValue);
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
const updateMinRangeDebounced = useDebouncedCallback(
|
const updateMinRangeDebounced = useDebouncedCallback(async (value: string, crowded = false) => {
|
||||||
async (value: string, crowded = false) => {
|
if (reversed) {
|
||||||
if (reversed) {
|
const newMinRange = crowded
|
||||||
const newMinRange = crowded
|
? window.Number(value.split("—")[1])
|
||||||
? window.Number(value.split("—")[1])
|
: max + min - window.Number(value.split("—")[0]) < min
|
||||||
: max + min - window.Number(value.split("—")[0]) < min
|
|
||||||
? min
|
? min
|
||||||
: max + min - window.Number(value.split("—")[0]);
|
: max + min - window.Number(value.split("—")[0]);
|
||||||
|
|
||||||
const newMinValue =
|
const newMinValue = window.Number(value.split("—")[0]) > max ? String(max) : value.split("—")[0];
|
||||||
window.Number(value.split("—")[0]) > max
|
|
||||||
? String(max)
|
|
||||||
: value.split("—")[0];
|
|
||||||
|
|
||||||
setReversedMinRange(
|
setReversedMinRange(crowded ? String(max + min - window.Number(newMinValue)) : newMinValue);
|
||||||
crowded ? String(max + min - window.Number(newMinValue)) : newMinValue
|
updateAnswer(currentQuestion.id, `${newMinRange}—${value.split("—")[1]}`, 0);
|
||||||
);
|
await sendAnswerToBackend(`${newMinValue}—${value.split("—")[1]}`, true);
|
||||||
updateAnswer(
|
|
||||||
currentQuestion.id,
|
|
||||||
`${newMinRange}—${value.split("—")[1]}`,
|
|
||||||
0
|
|
||||||
);
|
|
||||||
await sendAnswerToBackend(
|
|
||||||
`${newMinValue}—${value.split("—")[1]}`,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const newMinValue = crowded
|
const newMinValue = crowded
|
||||||
? maxRange
|
? maxRange
|
||||||
: window.Number(value.split("—")[0]) < min
|
: window.Number(value.split("—")[0]) < min
|
||||||
? String(min)
|
? String(min)
|
||||||
: value.split("—")[0];
|
: value.split("—")[0];
|
||||||
|
|
||||||
setMinRange(newMinValue);
|
setMinRange(newMinValue);
|
||||||
await sendAnswerToBackend(`${newMinValue}—${value.split("—")[1]}`);
|
await sendAnswerToBackend(`${newMinValue}—${value.split("—")[1]}`);
|
||||||
},
|
}, 1000);
|
||||||
1000
|
|
||||||
);
|
|
||||||
|
|
||||||
const updateMaxRangeDebounced = useDebouncedCallback(
|
const updateMaxRangeDebounced = useDebouncedCallback(async (value: string, crowded = false) => {
|
||||||
async (value: string, crowded = false) => {
|
if (reversed) {
|
||||||
if (reversed) {
|
const newMaxRange = crowded
|
||||||
const newMaxRange = crowded
|
? window.Number(value.split("—")[1])
|
||||||
? window.Number(value.split("—")[1])
|
: max + min - window.Number(value.split("—")[1]) > max
|
||||||
: max + min - window.Number(value.split("—")[1]) > max
|
|
||||||
? max
|
? max
|
||||||
: max + min - window.Number(value.split("—")[1]);
|
: max + min - window.Number(value.split("—")[1]);
|
||||||
|
|
||||||
const newMaxValue =
|
const newMaxValue = window.Number(value.split("—")[1]) < min ? String(min) : value.split("—")[1];
|
||||||
window.Number(value.split("—")[1]) < min
|
|
||||||
? String(min)
|
|
||||||
: value.split("—")[1];
|
|
||||||
|
|
||||||
setReversedMaxRange(
|
setReversedMaxRange(crowded ? String(max + min - window.Number(newMaxValue)) : newMaxValue);
|
||||||
crowded ? String(max + min - window.Number(newMaxValue)) : newMaxValue
|
updateAnswer(currentQuestion.id, `${value.split("—")[0]}—${newMaxRange}`, 0);
|
||||||
);
|
await sendAnswerToBackend(`${value.split("—")[0]}—${newMaxValue}`, true);
|
||||||
updateAnswer(
|
|
||||||
currentQuestion.id,
|
|
||||||
`${value.split("—")[0]}—${newMaxRange}`,
|
|
||||||
0
|
|
||||||
);
|
|
||||||
await sendAnswerToBackend(
|
|
||||||
`${value.split("—")[0]}—${newMaxValue}`,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const newMaxValue = crowded
|
const newMaxValue = crowded
|
||||||
? minRange
|
? minRange
|
||||||
: window.Number(value.split("—")[1]) > max
|
: window.Number(value.split("—")[1]) > max
|
||||||
? String(max)
|
? String(max)
|
||||||
: value.split("—")[1];
|
: value.split("—")[1];
|
||||||
|
|
||||||
setMaxRange(newMaxValue);
|
setMaxRange(newMaxValue);
|
||||||
await sendAnswerToBackend(`${value.split("—")[0]}—${newMaxValue}`);
|
await sendAnswerToBackend(`${value.split("—")[0]}—${newMaxValue}`);
|
||||||
},
|
}, 1000);
|
||||||
1000
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (answer) {
|
if (answer) {
|
||||||
if (answer.includes("—")) {
|
if (answer.includes("—")) {
|
||||||
if (reversed) {
|
if (reversed) {
|
||||||
setReversedMinRange(
|
setReversedMinRange(String(max + min - window.Number(answer.split("—")[0])));
|
||||||
String(max + min - window.Number(answer.split("—")[0]))
|
setReversedMaxRange(String(max + min - window.Number(answer.split("—")[1])));
|
||||||
);
|
|
||||||
setReversedMaxRange(
|
|
||||||
String(max + min - window.Number(answer.split("—")[1]))
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
setMinRange(answer.split("—")[0]);
|
setMinRange(answer.split("—")[0]);
|
||||||
setMaxRange(answer.split("—")[1]);
|
setMaxRange(answer.split("—")[1]);
|
||||||
@ -228,17 +183,12 @@ export const Number = ({ currentQuestion }: NumberProps) => {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const onSliderChange = (_: Event, value: number | number[]) => {
|
const onSliderChange = (_: Event, value: number | number[]) => {
|
||||||
const range = Array.isArray(value)
|
const range = Array.isArray(value) ? `${value[0]}—${value[1]}` : String(value);
|
||||||
? `${value[0]}—${value[1]}`
|
|
||||||
: String(value);
|
|
||||||
|
|
||||||
updateAnswer(currentQuestion.id, range, 0);
|
updateAnswer(currentQuestion.id, range, 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onChangeCommitted = async (
|
const onChangeCommitted = async (_: Event | SyntheticEvent<Element, Event>, value: number | number[]) => {
|
||||||
_: Event | SyntheticEvent<Element, Event>,
|
|
||||||
value: number | number[]
|
|
||||||
) => {
|
|
||||||
if (currentQuestion.content.chooseRange && Array.isArray(value)) {
|
if (currentQuestion.content.chooseRange && Array.isArray(value)) {
|
||||||
if (reversed) {
|
if (reversed) {
|
||||||
const newMinReversedValue = String(max + min - value[0]);
|
const newMinReversedValue = String(max + min - value[0]);
|
||||||
@ -248,10 +198,7 @@ export const Number = ({ currentQuestion }: NumberProps) => {
|
|||||||
setMaxRange(String(value[1]));
|
setMaxRange(String(value[1]));
|
||||||
setReversedMinRange(newMinReversedValue);
|
setReversedMinRange(newMinReversedValue);
|
||||||
setReversedMaxRange(newMaxReversedValue);
|
setReversedMaxRange(newMaxReversedValue);
|
||||||
await sendAnswerToBackend(
|
await sendAnswerToBackend(`${newMinReversedValue}—${newMaxReversedValue}`, true);
|
||||||
`${newMinReversedValue}—${newMaxReversedValue}`,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -277,9 +224,7 @@ export const Number = ({ currentQuestion }: NumberProps) => {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
const [minSliderBorder, maxSliderBorder] = sliderValue
|
const [minSliderBorder, maxSliderBorder] = sliderValue.split("—").map(window.Number);
|
||||||
.split("—")
|
|
||||||
.map(window.Number);
|
|
||||||
|
|
||||||
if (value === minSliderBorder) {
|
if (value === minSliderBorder) {
|
||||||
return max + min - minSliderBorder;
|
return max + min - minSliderBorder;
|
||||||
@ -313,9 +258,7 @@ export const Number = ({ currentQuestion }: NumberProps) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateMinRangeDebounced(
|
updateMinRangeDebounced(`${newValue}—${max + min - window.Number(reversedMaxRange)}`);
|
||||||
`${newValue}—${max + min - window.Number(reversedMaxRange)}`
|
|
||||||
);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -344,9 +287,7 @@ export const Number = ({ currentQuestion }: NumberProps) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateMaxRangeDebounced(
|
updateMaxRangeDebounced(`${max + min - window.Number(reversedMinRange)}—${newValue}`);
|
||||||
`${max + min - window.Number(reversedMinRange)}—${newValue}`
|
|
||||||
);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -364,11 +305,7 @@ export const Number = ({ currentQuestion }: NumberProps) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
<Typography
|
<Typography variant="h5" color={theme.palette.text.primary} sx={{ wordBreak: "break-word" }}>
|
||||||
variant="h5"
|
|
||||||
color={theme.palette.text.primary}
|
|
||||||
sx={{ wordBreak: "break-word" }}
|
|
||||||
>
|
|
||||||
{currentQuestion.title}
|
{currentQuestion.title}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Box
|
<Box
|
||||||
@ -417,9 +354,7 @@ export const Number = ({ currentQuestion }: NumberProps) => {
|
|||||||
"& .MuiOutlinedInput-root": { background: "transparent" },
|
"& .MuiOutlinedInput-root": { background: "transparent" },
|
||||||
"& .MuiInputBase-input": { textAlign: "center", zIndex: 1 },
|
"& .MuiInputBase-input": { textAlign: "center", zIndex: 1 },
|
||||||
"& .MuiOutlinedInput-notchedOutline": {
|
"& .MuiOutlinedInput-notchedOutline": {
|
||||||
backgroundColor: quizThemes[settings.cfg.theme].isLight
|
backgroundColor: quizThemes[settings.cfg.theme].isLight ? "white" : theme.palette.background.default,
|
||||||
? "white"
|
|
||||||
: theme.palette.background.default,
|
|
||||||
borderColor: "#9A9AAF",
|
borderColor: "#9A9AAF",
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
@ -445,9 +380,7 @@ export const Number = ({ currentQuestion }: NumberProps) => {
|
|||||||
"& .MuiOutlinedInput-root": { background: "transparent" },
|
"& .MuiOutlinedInput-root": { background: "transparent" },
|
||||||
"& .MuiInputBase-input": { textAlign: "center", zIndex: 1 },
|
"& .MuiInputBase-input": { textAlign: "center", zIndex: 1 },
|
||||||
"& .MuiOutlinedInput-notchedOutline": {
|
"& .MuiOutlinedInput-notchedOutline": {
|
||||||
backgroundColor: quizThemes[settings.cfg.theme].isLight
|
backgroundColor: quizThemes[settings.cfg.theme].isLight ? "white" : theme.palette.background.default,
|
||||||
? "white"
|
|
||||||
: theme.palette.background.default,
|
|
||||||
borderColor: "#9A9AAF",
|
borderColor: "#9A9AAF",
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
@ -462,9 +395,7 @@ export const Number = ({ currentQuestion }: NumberProps) => {
|
|||||||
"& .MuiOutlinedInput-root": { background: "transparent" },
|
"& .MuiOutlinedInput-root": { background: "transparent" },
|
||||||
"& .MuiInputBase-input": { textAlign: "center", zIndex: 1 },
|
"& .MuiInputBase-input": { textAlign: "center", zIndex: 1 },
|
||||||
"& .MuiOutlinedInput-notchedOutline": {
|
"& .MuiOutlinedInput-notchedOutline": {
|
||||||
backgroundColor: quizThemes[settings.cfg.theme].isLight
|
backgroundColor: quizThemes[settings.cfg.theme].isLight ? "white" : theme.palette.background.default,
|
||||||
? "white"
|
|
||||||
: theme.palette.background.default,
|
|
||||||
borderColor: "#9A9AAF",
|
borderColor: "#9A9AAF",
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
|
@ -23,10 +23,7 @@ export const Page = ({ currentQuestion }: PageProps) => {
|
|||||||
>
|
>
|
||||||
{currentQuestion.title}
|
{currentQuestion.title}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography
|
<Typography color={theme.palette.text.primary} sx={{ wordBreak: "break-word" }}>
|
||||||
color={theme.palette.text.primary}
|
|
||||||
sx={{ wordBreak: "break-word" }}
|
|
||||||
>
|
|
||||||
{currentQuestion.content.text}
|
{currentQuestion.content.text}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Box
|
<Box
|
||||||
|
@ -1,10 +1,5 @@
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import {
|
import { Box, Rating as RatingComponent, Typography, useTheme } from "@mui/material";
|
||||||
Box,
|
|
||||||
Rating as RatingComponent,
|
|
||||||
Typography,
|
|
||||||
useTheme,
|
|
||||||
} from "@mui/material";
|
|
||||||
import { enqueueSnackbar } from "notistack";
|
import { enqueueSnackbar } from "notistack";
|
||||||
|
|
||||||
import { sendAnswer } from "@api/quizRelase";
|
import { sendAnswer } from "@api/quizRelase";
|
||||||
@ -25,45 +20,31 @@ import type { QuizQuestionRating } from "@model/questionTypes/rating";
|
|||||||
const RATING_FORM_BUTTONS = [
|
const RATING_FORM_BUTTONS = [
|
||||||
{
|
{
|
||||||
name: "star",
|
name: "star",
|
||||||
icon: (color: string, width: number) => (
|
icon: (color: string, width: number) => <StarIconMini width={width} color={color} />,
|
||||||
<StarIconMini width={width} color={color} />
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "trophie",
|
name: "trophie",
|
||||||
icon: (color: string, width: number) => (
|
icon: (color: string, width: number) => <TropfyIcon width={width} color={color} />,
|
||||||
<TropfyIcon width={width} color={color} />
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "flag",
|
name: "flag",
|
||||||
icon: (color: string, width: number) => (
|
icon: (color: string, width: number) => <FlagIcon width={width} color={color} />,
|
||||||
<FlagIcon width={width} color={color} />
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "heart",
|
name: "heart",
|
||||||
icon: (color: string, width: number) => (
|
icon: (color: string, width: number) => <HeartIcon width={width} color={color} />,
|
||||||
<HeartIcon width={width} color={color} />
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "like",
|
name: "like",
|
||||||
icon: (color: string, width: number) => (
|
icon: (color: string, width: number) => <LikeIcon width={width} color={color} />,
|
||||||
<LikeIcon width={width} color={color} />
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "bubble",
|
name: "bubble",
|
||||||
icon: (color: string, width: number) => (
|
icon: (color: string, width: number) => <LightbulbIcon width={width} color={color} />,
|
||||||
<LightbulbIcon width={width} color={color} />
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "hashtag",
|
name: "hashtag",
|
||||||
icon: (color: string, width: number) => (
|
icon: (color: string, width: number) => <HashtagIcon width={width} color={color} />,
|
||||||
<HashtagIcon width={width} color={color} />
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -79,11 +60,8 @@ export const Rating = ({ currentQuestion }: RatingProps) => {
|
|||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const isMobile = useRootContainerSize() < 650;
|
const isMobile = useRootContainerSize() < 650;
|
||||||
const isTablet = useRootContainerSize() < 750;
|
const isTablet = useRootContainerSize() < 750;
|
||||||
const { answer } =
|
const { answer } = answers.find(({ questionId }) => questionId === currentQuestion.id) ?? {};
|
||||||
answers.find(({ questionId }) => questionId === currentQuestion.id) ?? {};
|
const form = RATING_FORM_BUTTONS.find(({ name }) => name === currentQuestion.content.form);
|
||||||
const form = RATING_FORM_BUTTONS.find(
|
|
||||||
({ name }) => name === currentQuestion.content.form
|
|
||||||
);
|
|
||||||
|
|
||||||
const sendRating = async (value: number | null) => {
|
const sendRating = async (value: number | null) => {
|
||||||
setIsSending(true);
|
setIsSending(true);
|
||||||
@ -106,11 +84,7 @@ export const Rating = ({ currentQuestion }: RatingProps) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
<Typography
|
<Typography variant="h5" color={theme.palette.text.primary} sx={{ wordBreak: "break-word" }}>
|
||||||
variant="h5"
|
|
||||||
color={theme.palette.text.primary}
|
|
||||||
sx={{ wordBreak: "break-word" }}
|
|
||||||
>
|
|
||||||
{currentQuestion.title}
|
{currentQuestion.title}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Box
|
<Box
|
||||||
@ -134,14 +108,8 @@ export const Rating = ({ currentQuestion }: RatingProps) => {
|
|||||||
"& .MuiRating-icon": { mr: isMobile ? undefined : "15px" },
|
"& .MuiRating-icon": { mr: isMobile ? undefined : "15px" },
|
||||||
}}
|
}}
|
||||||
max={currentQuestion.content.steps}
|
max={currentQuestion.content.steps}
|
||||||
icon={form?.icon(
|
icon={form?.icon(theme.palette.primary.main, isMobile ? 30 : isTablet ? 40 : 50)}
|
||||||
theme.palette.primary.main,
|
emptyIcon={form?.icon("#9A9AAF", isMobile ? 30 : isTablet ? 40 : 50)}
|
||||||
isMobile ? 30 : isTablet ? 40 : 50
|
|
||||||
)}
|
|
||||||
emptyIcon={form?.icon(
|
|
||||||
"#9A9AAF",
|
|
||||||
isMobile ? 30 : isTablet ? 40 : 50
|
|
||||||
)}
|
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
<Box
|
<Box
|
||||||
@ -152,12 +120,8 @@ export const Rating = ({ currentQuestion }: RatingProps) => {
|
|||||||
width: "100%",
|
width: "100%",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography sx={{ color: "#9A9AAF" }}>
|
<Typography sx={{ color: "#9A9AAF" }}>{currentQuestion.content.ratingNegativeDescription}</Typography>
|
||||||
{currentQuestion.content.ratingNegativeDescription}
|
<Typography sx={{ color: "#9A9AAF" }}>{currentQuestion.content.ratingPositiveDescription}</Typography>
|
||||||
</Typography>
|
|
||||||
<Typography sx={{ color: "#9A9AAF" }}>
|
|
||||||
{currentQuestion.content.ratingPositiveDescription}
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
@ -22,8 +22,7 @@ export const Select = ({ currentQuestion }: SelectProps) => {
|
|||||||
const { updateAnswer, deleteAnswer } = useQuizViewStore((state) => state);
|
const { updateAnswer, deleteAnswer } = useQuizViewStore((state) => state);
|
||||||
const answers = useQuizViewStore((state) => state.answers);
|
const answers = useQuizViewStore((state) => state.answers);
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { answer } =
|
const { answer } = answers.find(({ questionId }) => questionId === currentQuestion.id) ?? {};
|
||||||
answers.find(({ questionId }) => questionId === currentQuestion.id) ?? {};
|
|
||||||
|
|
||||||
const sendSelectedAnswer = async (value: number) => {
|
const sendSelectedAnswer = async (value: number) => {
|
||||||
setIsSending(true);
|
setIsSending(true);
|
||||||
@ -63,11 +62,7 @@ export const Select = ({ currentQuestion }: SelectProps) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
<Typography
|
<Typography variant="h5" color={theme.palette.text.primary} sx={{ wordBreak: "break-word" }}>
|
||||||
variant="h5"
|
|
||||||
color={theme.palette.text.primary}
|
|
||||||
sx={{ wordBreak: "break-word" }}
|
|
||||||
>
|
|
||||||
{currentQuestion.title}
|
{currentQuestion.title}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Box
|
<Box
|
||||||
|
@ -18,11 +18,7 @@ interface TextNormalProps {
|
|||||||
stepNumber?: number | null;
|
stepNumber?: number | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const TextNormal = ({
|
export const TextNormal = ({ currentQuestion, answer, inputHC }: TextNormalProps) => {
|
||||||
currentQuestion,
|
|
||||||
answer,
|
|
||||||
inputHC,
|
|
||||||
}: TextNormalProps) => {
|
|
||||||
const { settings } = useQuizData();
|
const { settings } = useQuizData();
|
||||||
const { updateAnswer } = useQuizViewStore((state) => state);
|
const { updateAnswer } = useQuizViewStore((state) => state);
|
||||||
const isMobile = useRootContainerSize() < 650;
|
const isMobile = useRootContainerSize() < 650;
|
||||||
@ -35,11 +31,7 @@ export const TextNormal = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
<Typography
|
<Typography variant="h5" color={theme.palette.text.primary} sx={{ wordBreak: "break-word" }}>
|
||||||
variant="h5"
|
|
||||||
color={theme.palette.text.primary}
|
|
||||||
sx={{ wordBreak: "break-word" }}
|
|
||||||
>
|
|
||||||
{currentQuestion.title}
|
{currentQuestion.title}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Box
|
<Box
|
||||||
@ -67,24 +59,23 @@ export const TextNormal = ({
|
|||||||
"&:focus-visible": { borderColor: theme.palette.primary.main },
|
"&:focus-visible": { borderColor: theme.palette.primary.main },
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{currentQuestion.content.back &&
|
{currentQuestion.content.back && currentQuestion.content.back !== " " && (
|
||||||
currentQuestion.content.back !== " " && (
|
<Box
|
||||||
<Box
|
sx={{
|
||||||
sx={{
|
maxWidth: "400px",
|
||||||
maxWidth: "400px",
|
width: "100%",
|
||||||
width: "100%",
|
height: "300px",
|
||||||
height: "300px",
|
margin: "15px",
|
||||||
margin: "15px",
|
}}
|
||||||
}}
|
>
|
||||||
>
|
<img
|
||||||
<img
|
key={currentQuestion.id}
|
||||||
key={currentQuestion.id}
|
src={currentQuestion.content.back}
|
||||||
src={currentQuestion.content.back}
|
style={{ width: "100%", height: "100%", objectFit: "cover" }}
|
||||||
style={{ width: "100%", height: "100%", objectFit: "cover" }}
|
alt=""
|
||||||
alt=""
|
/>
|
||||||
/>
|
</Box>
|
||||||
</Box>
|
)}
|
||||||
)}
|
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
@ -1,10 +1,4 @@
|
|||||||
import {
|
import { Box, TextField as MuiTextField, TextFieldProps, Typography, useTheme } from "@mui/material";
|
||||||
Box,
|
|
||||||
TextField as MuiTextField,
|
|
||||||
TextFieldProps,
|
|
||||||
Typography,
|
|
||||||
useTheme,
|
|
||||||
} from "@mui/material";
|
|
||||||
|
|
||||||
import { Answer, useQuizViewStore } from "@stores/quizView";
|
import { Answer, useQuizViewStore } from "@stores/quizView";
|
||||||
import { useQuizData } from "@contexts/QuizDataContext";
|
import { useQuizData } from "@contexts/QuizDataContext";
|
||||||
@ -51,12 +45,7 @@ interface TextSpecialProps {
|
|||||||
stepNumber?: number | null;
|
stepNumber?: number | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const TextSpecial = ({
|
export const TextSpecial = ({ currentQuestion, answer, inputHC, stepNumber }: TextSpecialProps) => {
|
||||||
currentQuestion,
|
|
||||||
answer,
|
|
||||||
inputHC,
|
|
||||||
stepNumber,
|
|
||||||
}: TextSpecialProps) => {
|
|
||||||
const { settings } = useQuizData();
|
const { settings } = useQuizData();
|
||||||
const { updateAnswer } = useQuizViewStore((state) => state);
|
const { updateAnswer } = useQuizViewStore((state) => state);
|
||||||
const isHorizontal = ORIENTATION[Number(stepNumber) - 1].horizontal;
|
const isHorizontal = ORIENTATION[Number(stepNumber) - 1].horizontal;
|
||||||
@ -86,25 +75,19 @@ export const TextSpecial = ({
|
|||||||
gap: "20px",
|
gap: "20px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography
|
<Typography variant="h5" color={theme.palette.text.primary} sx={{ wordBreak: "break-word" }}>
|
||||||
variant="h5"
|
|
||||||
color={theme.palette.text.primary}
|
|
||||||
sx={{ wordBreak: "break-word" }}
|
|
||||||
>
|
|
||||||
{currentQuestion.title}
|
{currentQuestion.title}
|
||||||
</Typography>
|
</Typography>
|
||||||
{isHorizontal &&
|
{isHorizontal && currentQuestion.content.back && currentQuestion.content.back !== " " && (
|
||||||
currentQuestion.content.back &&
|
<Box sx={{ margin: "30px", width: "50vw", maxHeight: "550px" }}>
|
||||||
currentQuestion.content.back !== " " && (
|
<img
|
||||||
<Box sx={{ margin: "30px", width: "50vw", maxHeight: "550px" }}>
|
key={currentQuestion.id}
|
||||||
<img
|
src={currentQuestion.content.back}
|
||||||
key={currentQuestion.id}
|
style={{ width: "100%", height: "100%", objectFit: "cover" }}
|
||||||
src={currentQuestion.content.back}
|
alt=""
|
||||||
style={{ width: "100%", height: "100%", objectFit: "cover" }}
|
/>
|
||||||
alt=""
|
</Box>
|
||||||
/>
|
)}
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
{
|
{
|
||||||
<TextField
|
<TextField
|
||||||
autoFocus={true}
|
autoFocus={true}
|
||||||
@ -124,9 +107,7 @@ export const TextSpecial = ({
|
|||||||
sx={{
|
sx={{
|
||||||
width: "100%",
|
width: "100%",
|
||||||
"& .MuiOutlinedInput-root": {
|
"& .MuiOutlinedInput-root": {
|
||||||
backgroundColor: settings.cfg.design
|
backgroundColor: settings.cfg.design ? "rgba(154,154,175, 0.2)" : "#FFFFFF",
|
||||||
? "rgba(154,154,175, 0.2)"
|
|
||||||
: "#FFFFFF",
|
|
||||||
},
|
},
|
||||||
"&:focus-visible": {
|
"&:focus-visible": {
|
||||||
borderColor: theme.palette.primary.main,
|
borderColor: theme.palette.primary.main,
|
||||||
@ -135,18 +116,16 @@ export const TextSpecial = ({
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
</Box>
|
</Box>
|
||||||
{!isHorizontal &&
|
{!isHorizontal && currentQuestion.content.back && currentQuestion.content.back !== " " && (
|
||||||
currentQuestion.content.back &&
|
<Box sx={{ margin: "15px", width: "40vw" }}>
|
||||||
currentQuestion.content.back !== " " && (
|
<img
|
||||||
<Box sx={{ margin: "15px", width: "40vw" }}>
|
key={currentQuestion.id}
|
||||||
<img
|
src={currentQuestion.content.back}
|
||||||
key={currentQuestion.id}
|
style={{ width: "100%", height: "100%", objectFit: "cover" }}
|
||||||
src={currentQuestion.content.back}
|
alt=""
|
||||||
style={{ width: "100%", height: "100%", objectFit: "cover" }}
|
/>
|
||||||
alt=""
|
</Box>
|
||||||
/>
|
)}
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -21,8 +21,7 @@ export const Text = ({ currentQuestion, stepNumber }: TextProps) => {
|
|||||||
const { settings, preview } = useQuizData();
|
const { settings, preview } = useQuizData();
|
||||||
const { quizId } = useQuizData();
|
const { quizId } = useQuizData();
|
||||||
const answers = useQuizViewStore((state) => state.answers);
|
const answers = useQuizViewStore((state) => state.answers);
|
||||||
const { answer } =
|
const { answer } = answers.find(({ questionId }) => questionId === currentQuestion.id) ?? {};
|
||||||
answers.find(({ questionId }) => questionId === currentQuestion.id) ?? {};
|
|
||||||
|
|
||||||
const inputHC = useDebouncedCallback(async (text) => {
|
const inputHC = useDebouncedCallback(async (text) => {
|
||||||
setIsSending(true);
|
setIsSending(true);
|
||||||
@ -48,30 +47,13 @@ export const Text = ({ currentQuestion, stepNumber }: TextProps) => {
|
|||||||
switch (settings.cfg.spec) {
|
switch (settings.cfg.spec) {
|
||||||
case true:
|
case true:
|
||||||
return (
|
return (
|
||||||
<TextSpecial
|
<TextSpecial currentQuestion={currentQuestion} answer={answer} inputHC={inputHC} stepNumber={stepNumber} />
|
||||||
currentQuestion={currentQuestion}
|
|
||||||
answer={answer}
|
|
||||||
inputHC={inputHC}
|
|
||||||
stepNumber={stepNumber}
|
|
||||||
/>
|
|
||||||
);
|
);
|
||||||
|
|
||||||
case undefined:
|
case undefined:
|
||||||
return (
|
return <TextNormal currentQuestion={currentQuestion} answer={answer} inputHC={inputHC} />;
|
||||||
<TextNormal
|
|
||||||
currentQuestion={currentQuestion}
|
|
||||||
answer={answer}
|
|
||||||
inputHC={inputHC}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return (
|
return <TextNormal currentQuestion={currentQuestion} answer={answer} inputHC={inputHC} />;
|
||||||
<TextNormal
|
|
||||||
currentQuestion={currentQuestion}
|
|
||||||
answer={answer}
|
|
||||||
inputHC={inputHC}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,11 +1,4 @@
|
|||||||
import {
|
import { Checkbox, FormControlLabel, TextField as MuiTextField, Radio, TextFieldProps, useTheme } from "@mui/material";
|
||||||
Checkbox,
|
|
||||||
FormControlLabel,
|
|
||||||
TextField as MuiTextField,
|
|
||||||
Radio,
|
|
||||||
TextFieldProps,
|
|
||||||
useTheme,
|
|
||||||
} from "@mui/material";
|
|
||||||
import { enqueueSnackbar } from "notistack";
|
import { enqueueSnackbar } from "notistack";
|
||||||
|
|
||||||
import { sendAnswer } from "@api/quizRelase";
|
import { sendAnswer } from "@api/quizRelase";
|
||||||
@ -96,9 +89,7 @@ export const VariantItem = ({
|
|||||||
updateAnswer(
|
updateAnswer(
|
||||||
currentQuestion.id,
|
currentQuestion.id,
|
||||||
variantId,
|
variantId,
|
||||||
answer === variantId
|
answer === variantId ? 0 : currentQuestion.content.variants[index].points || 0
|
||||||
? 0
|
|
||||||
: currentQuestion.content.variants[index].points || 0
|
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
@ -133,15 +124,14 @@ export const VariantItem = ({
|
|||||||
color: theme.palette.text.primary,
|
color: theme.palette.text.primary,
|
||||||
padding: "15px",
|
padding: "15px",
|
||||||
border: `1px solid`,
|
border: `1px solid`,
|
||||||
borderColor:
|
borderColor: answer === variant.id ? theme.palette.primary.main : "#9A9AAF",
|
||||||
answer === variant.id ? theme.palette.primary.main : "#9A9AAF",
|
|
||||||
backgroundColor: settings.cfg.design
|
backgroundColor: settings.cfg.design
|
||||||
? quizThemes[settings.cfg.theme].isLight
|
? quizThemes[settings.cfg.theme].isLight
|
||||||
? "#FFFFFF"
|
? "#FFFFFF"
|
||||||
: "rgba(255,255,255, 0.3)"
|
: "rgba(255,255,255, 0.3)"
|
||||||
: quizThemes[settings.cfg.theme].isLight
|
: quizThemes[settings.cfg.theme].isLight
|
||||||
? "white"
|
? "white"
|
||||||
: theme.palette.background.default,
|
: theme.palette.background.default,
|
||||||
display: "flex",
|
display: "flex",
|
||||||
maxWidth: "685px",
|
maxWidth: "685px",
|
||||||
maxHeight: "85px",
|
maxHeight: "85px",
|
||||||
@ -167,16 +157,11 @@ export const VariantItem = ({
|
|||||||
currentQuestion.content.multi ? (
|
currentQuestion.content.multi ? (
|
||||||
<Checkbox
|
<Checkbox
|
||||||
checked={!!answer?.includes(variant.id)}
|
checked={!!answer?.includes(variant.id)}
|
||||||
checkedIcon={
|
checkedIcon={<CheckboxIcon checked color={theme.palette.primary.main} />}
|
||||||
<CheckboxIcon checked color={theme.palette.primary.main} />
|
|
||||||
}
|
|
||||||
icon={<CheckboxIcon />}
|
icon={<CheckboxIcon />}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<Radio
|
<Radio checkedIcon={<RadioCheck color={theme.palette.primary.main} />} icon={<RadioIcon />} />
|
||||||
checkedIcon={<RadioCheck color={theme.palette.primary.main} />}
|
|
||||||
icon={<RadioIcon />}
|
|
||||||
/>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
label={own ? <TextField label="Другое..." /> : variant.answer}
|
label={own ? <TextField label="Другое..." /> : variant.answer}
|
||||||
|
@ -1,11 +1,5 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import {
|
import { Box, FormGroup, RadioGroup, Typography, useTheme } from "@mui/material";
|
||||||
Box,
|
|
||||||
FormGroup,
|
|
||||||
RadioGroup,
|
|
||||||
Typography,
|
|
||||||
useTheme,
|
|
||||||
} from "@mui/material";
|
|
||||||
|
|
||||||
import { VariantItem } from "./VariantItem";
|
import { VariantItem } from "./VariantItem";
|
||||||
|
|
||||||
@ -26,11 +20,8 @@ export const Variant = ({ currentQuestion }: VariantProps) => {
|
|||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const isMobile = useRootContainerSize() < 650;
|
const isMobile = useRootContainerSize() < 650;
|
||||||
|
|
||||||
const { answer } =
|
const { answer } = answers.find(({ questionId }) => questionId === currentQuestion.id) ?? {};
|
||||||
answers.find(({ questionId }) => questionId === currentQuestion.id) ?? {};
|
const ownVariant = ownVariants.find((variant) => variant.id === currentQuestion.id);
|
||||||
const ownVariant = ownVariants.find(
|
|
||||||
(variant) => variant.id === currentQuestion.id
|
|
||||||
);
|
|
||||||
|
|
||||||
const Group = currentQuestion.content.multi ? FormGroup : RadioGroup;
|
const Group = currentQuestion.content.multi ? FormGroup : RadioGroup;
|
||||||
|
|
||||||
@ -44,11 +35,7 @@ export const Variant = ({ currentQuestion }: VariantProps) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
<Typography
|
<Typography variant="h5" color={theme.palette.text.primary} sx={{ wordBreak: "break-word" }}>
|
||||||
variant="h5"
|
|
||||||
color={theme.palette.text.primary}
|
|
||||||
sx={{ wordBreak: "break-word" }}
|
|
||||||
>
|
|
||||||
{currentQuestion.title}
|
{currentQuestion.title}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Box
|
<Box
|
||||||
@ -61,9 +48,7 @@ export const Variant = ({ currentQuestion }: VariantProps) => {
|
|||||||
>
|
>
|
||||||
<Group
|
<Group
|
||||||
name={currentQuestion.id.toString()}
|
name={currentQuestion.id.toString()}
|
||||||
value={currentQuestion.content.variants.findIndex(
|
value={currentQuestion.content.variants.findIndex(({ id }) => answer === id)}
|
||||||
({ id }) => answer === id
|
|
||||||
)}
|
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexWrap: "wrap",
|
flexWrap: "wrap",
|
||||||
@ -107,17 +92,16 @@ export const Variant = ({ currentQuestion }: VariantProps) => {
|
|||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
</Group>
|
</Group>
|
||||||
{currentQuestion.content.back &&
|
{currentQuestion.content.back && currentQuestion.content.back !== " " && (
|
||||||
currentQuestion.content.back !== " " && (
|
<Box sx={{ maxWidth: "400px", width: "100%", height: "300px" }}>
|
||||||
<Box sx={{ maxWidth: "400px", width: "100%", height: "300px" }}>
|
<img
|
||||||
<img
|
key={currentQuestion.id}
|
||||||
key={currentQuestion.id}
|
src={currentQuestion.content.back}
|
||||||
src={currentQuestion.content.back}
|
style={{ width: "100%", height: "100%", objectFit: "cover" }}
|
||||||
style={{ width: "100%", height: "100%", objectFit: "cover" }}
|
alt=""
|
||||||
alt=""
|
/>
|
||||||
/>
|
</Box>
|
||||||
</Box>
|
)}
|
||||||
)}
|
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
@ -23,21 +23,14 @@ type VarimgVariantProps = {
|
|||||||
setIsSending: (isSending: boolean) => void;
|
setIsSending: (isSending: boolean) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const VarimgVariant = ({
|
export const VarimgVariant = ({ currentQuestion, variant, index, isSending, setIsSending }: VarimgVariantProps) => {
|
||||||
currentQuestion,
|
|
||||||
variant,
|
|
||||||
index,
|
|
||||||
isSending,
|
|
||||||
setIsSending,
|
|
||||||
}: VarimgVariantProps) => {
|
|
||||||
const { settings, quizId, preview } = useQuizData();
|
const { settings, quizId, preview } = useQuizData();
|
||||||
const { updateAnswer, deleteAnswer } = useQuizViewStore((state) => state);
|
const { updateAnswer, deleteAnswer } = useQuizViewStore((state) => state);
|
||||||
const answers = useQuizViewStore((state) => state.answers);
|
const answers = useQuizViewStore((state) => state.answers);
|
||||||
|
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
const { answer } =
|
const { answer } = answers.find(({ questionId }) => questionId === currentQuestion.id) ?? {};
|
||||||
answers.find(({ questionId }) => questionId === currentQuestion.id) ?? {};
|
|
||||||
|
|
||||||
const sendVariant = async (event: MouseEvent<HTMLLabelElement>) => {
|
const sendVariant = async (event: MouseEvent<HTMLLabelElement>) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
@ -93,11 +86,10 @@ export const VarimgVariant = ({
|
|||||||
? "#FFFFFF"
|
? "#FFFFFF"
|
||||||
: "rgba(255,255,255, 0.3)"
|
: "rgba(255,255,255, 0.3)"
|
||||||
: quizThemes[settings.cfg.theme].isLight
|
: quizThemes[settings.cfg.theme].isLight
|
||||||
? "white"
|
? "white"
|
||||||
: theme.palette.background.default,
|
: theme.palette.background.default,
|
||||||
border: `1px solid`,
|
border: `1px solid`,
|
||||||
borderColor:
|
borderColor: answer === variant.id ? theme.palette.primary.main : "#9A9AAF",
|
||||||
answer === variant.id ? theme.palette.primary.main : "#9A9AAF",
|
|
||||||
display: "flex",
|
display: "flex",
|
||||||
margin: 0,
|
margin: 0,
|
||||||
justifyContent: "space-between",
|
justifyContent: "space-between",
|
||||||
@ -118,12 +110,7 @@ export const VarimgVariant = ({
|
|||||||
value={index}
|
value={index}
|
||||||
onClick={sendVariant}
|
onClick={sendVariant}
|
||||||
label={variant.answer}
|
label={variant.answer}
|
||||||
control={
|
control={<Radio checkedIcon={<RadioCheck color={theme.palette.primary.main} />} icon={<RadioIcon />} />}
|
||||||
<Radio
|
|
||||||
checkedIcon={<RadioCheck color={theme.palette.primary.main} />}
|
|
||||||
icon={<RadioIcon />}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -21,19 +21,12 @@ export const Varimg = ({ currentQuestion }: VarimgProps) => {
|
|||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const isMobile = useRootContainerSize() < 650;
|
const isMobile = useRootContainerSize() < 650;
|
||||||
|
|
||||||
const { answer } =
|
const { answer } = answers.find(({ questionId }) => questionId === currentQuestion.id) ?? {};
|
||||||
answers.find(({ questionId }) => questionId === currentQuestion.id) ?? {};
|
const variant = currentQuestion.content.variants.find(({ id }) => answer === id);
|
||||||
const variant = currentQuestion.content.variants.find(
|
|
||||||
({ id }) => answer === id
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
<Typography
|
<Typography variant="h5" color={theme.palette.text.primary} sx={{ wordBreak: "break-word" }}>
|
||||||
variant="h5"
|
|
||||||
color={theme.palette.text.primary}
|
|
||||||
sx={{ wordBreak: "break-word" }}
|
|
||||||
>
|
|
||||||
{currentQuestion.title}
|
{currentQuestion.title}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Box
|
<Box
|
||||||
@ -47,9 +40,7 @@ export const Varimg = ({ currentQuestion }: VarimgProps) => {
|
|||||||
>
|
>
|
||||||
<RadioGroup
|
<RadioGroup
|
||||||
name={currentQuestion.id}
|
name={currentQuestion.id}
|
||||||
value={currentQuestion.content.variants.findIndex(
|
value={currentQuestion.content.variants.findIndex(({ id }) => answer === id)}
|
||||||
({ id }) => answer === id
|
|
||||||
)}
|
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexWrap: "wrap",
|
flexWrap: "wrap",
|
||||||
@ -116,8 +107,7 @@ export const Varimg = ({ currentQuestion }: VarimgProps) => {
|
|||||||
style={{ width: "100%", height: "100%", objectFit: "cover" }}
|
style={{ width: "100%", height: "100%", objectFit: "cover" }}
|
||||||
alt=""
|
alt=""
|
||||||
/>
|
/>
|
||||||
) : currentQuestion.content.replText !== " " &&
|
) : currentQuestion.content.replText !== " " && currentQuestion.content.replText.length > 0 ? (
|
||||||
currentQuestion.content.replText.length > 0 ? (
|
|
||||||
currentQuestion.content.replText
|
currentQuestion.content.replText
|
||||||
) : variant?.extendedText || isMobile ? (
|
) : variant?.extendedText || isMobile ? (
|
||||||
"Выберите вариант ответа ниже"
|
"Выберите вариант ответа ниже"
|
||||||
|
@ -1,28 +1,29 @@
|
|||||||
import {Button, useTheme} from "@mui/material";
|
import { Button, useTheme } from "@mui/material";
|
||||||
import { quizThemes } from "@utils/themes/Publication/themePublication";
|
import { quizThemes } from "@utils/themes/Publication/themePublication";
|
||||||
import { useQuizData } from "@contexts/QuizDataContext";
|
import { useQuizData } from "@contexts/QuizDataContext";
|
||||||
|
|
||||||
interface Props{
|
interface Props {
|
||||||
isNextButtonEnabled: boolean,
|
isNextButtonEnabled: boolean;
|
||||||
moveToNextQuestion: () => void,
|
moveToNextQuestion: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function NextButton ({isNextButtonEnabled, moveToNextQuestion}: Props) {
|
export default function NextButton({ isNextButtonEnabled, moveToNextQuestion }: Props) {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { settings } = useQuizData();
|
const { settings } = useQuizData();
|
||||||
return(
|
return (
|
||||||
<Button
|
<Button
|
||||||
disabled={!isNextButtonEnabled}
|
disabled={!isNextButtonEnabled}
|
||||||
variant="contained"
|
variant="contained"
|
||||||
sx={{
|
sx={{
|
||||||
fontSize: "16px",
|
fontSize: "16px",
|
||||||
padding: "10px 15px",
|
padding: "10px 15px",
|
||||||
"&:disabled": {
|
"&:disabled": {
|
||||||
background: quizThemes[settings.cfg.theme].isLight ? "#F2F3F7" : "#FFFFFF26"
|
background: quizThemes[settings.cfg.theme].isLight ? "#F2F3F7" : "#FFFFFF26",
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
onClick={moveToNextQuestion}
|
onClick={moveToNextQuestion}
|
||||||
>
|
>
|
||||||
Далее →
|
Далее →
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
);
|
||||||
|
}
|
||||||
|
@ -4,36 +4,38 @@ import { quizThemes } from "@utils/themes/Publication/themePublication";
|
|||||||
import { useQuizData } from "@contexts/QuizDataContext";
|
import { useQuizData } from "@contexts/QuizDataContext";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
isPreviousButtonEnabled: boolean,
|
isPreviousButtonEnabled: boolean;
|
||||||
moveToPrevQuestion: () => void,
|
moveToPrevQuestion: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function PrevButton({ isPreviousButtonEnabled, moveToPrevQuestion }: Props) {
|
export default function PrevButton({ isPreviousButtonEnabled, moveToPrevQuestion }: Props) {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { settings } = useQuizData();
|
const { settings } = useQuizData();
|
||||||
const isMobileMini = useRootContainerSize() < 382;
|
const isMobileMini = useRootContainerSize() < 382;
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
disabled={!isPreviousButtonEnabled}
|
disabled={!isPreviousButtonEnabled}
|
||||||
variant="contained"
|
variant="contained"
|
||||||
sx={{
|
sx={{
|
||||||
ml: "auto",
|
ml: "auto",
|
||||||
fontSize: "16px",
|
fontSize: "16px",
|
||||||
padding: "10px 15px",
|
padding: "10px 15px",
|
||||||
color: quizThemes[settings.cfg.theme].isLight ? theme.palette.primary.main : "#FFFFFF",
|
color: quizThemes[settings.cfg.theme].isLight ? theme.palette.primary.main : "#FFFFFF",
|
||||||
border: quizThemes[settings.cfg.theme].isLight ? `1px solid ${theme.palette.primary.main}` : "1px solid #9A9AAF",
|
border: quizThemes[settings.cfg.theme].isLight
|
||||||
background: quizThemes[settings.cfg.theme].isLight ? "#FFFFFF" : "#FFFFFF26",
|
? `1px solid ${theme.palette.primary.main}`
|
||||||
"&:hover": {
|
: "1px solid #9A9AAF",
|
||||||
color: "#FFFFFF",
|
background: quizThemes[settings.cfg.theme].isLight ? "#FFFFFF" : "#FFFFFF26",
|
||||||
border: `1px solid ${theme.palette.primary.dark}`,
|
"&:hover": {
|
||||||
},
|
color: "#FFFFFF",
|
||||||
"&:disabled": {
|
border: `1px solid ${theme.palette.primary.dark}`,
|
||||||
background: quizThemes[settings.cfg.theme].isLight ? "#F2F3F7" : "#FFFFFF26"
|
},
|
||||||
},
|
"&:disabled": {
|
||||||
}}
|
background: quizThemes[settings.cfg.theme].isLight ? "#F2F3F7" : "#FFFFFF26",
|
||||||
onClick={moveToPrevQuestion}
|
},
|
||||||
>
|
}}
|
||||||
{isMobileMini ? "←" : "← Назад"}
|
onClick={moveToPrevQuestion}
|
||||||
</Button>
|
>
|
||||||
);
|
{isMobileMini ? "←" : "← Назад"}
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,5 @@
|
|||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import {
|
import { Select as MuiSelect, MenuItem, FormControl, Typography, useTheme } from "@mui/material";
|
||||||
Select as MuiSelect,
|
|
||||||
MenuItem,
|
|
||||||
FormControl,
|
|
||||||
Typography,
|
|
||||||
useTheme,
|
|
||||||
} from "@mui/material";
|
|
||||||
|
|
||||||
import ArrowDown from "@icons/ArrowDownIcon";
|
import ArrowDown from "@icons/ArrowDownIcon";
|
||||||
|
|
||||||
@ -34,9 +28,7 @@ export const Select = ({
|
|||||||
colorPlaceholder = "#9A9AAF",
|
colorPlaceholder = "#9A9AAF",
|
||||||
disabled = false,
|
disabled = false,
|
||||||
}: SelectProps) => {
|
}: SelectProps) => {
|
||||||
const [activeItem, setActiveItem] = useState<number>(
|
const [activeItem, setActiveItem] = useState<number>(empty ? -1 : activeItemIndex);
|
||||||
empty ? -1 : activeItemIndex
|
|
||||||
);
|
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -58,22 +50,11 @@ export const Select = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FormControl
|
<FormControl disabled={disabled} fullWidth size="small" sx={{ width: "100%", height: "48px", ...sx }}>
|
||||||
disabled={disabled}
|
|
||||||
fullWidth
|
|
||||||
size="small"
|
|
||||||
sx={{ width: "100%", height: "48px", ...sx }}
|
|
||||||
>
|
|
||||||
<MuiSelect
|
<MuiSelect
|
||||||
displayEmpty
|
displayEmpty
|
||||||
renderValue={(value) =>
|
renderValue={(value) =>
|
||||||
value ? (
|
value ? items[Number(value)] : <Typography sx={{ color: colorPlaceholder }}>{placeholder}</Typography>
|
||||||
items[Number(value)]
|
|
||||||
) : (
|
|
||||||
<Typography sx={{ color: colorPlaceholder }}>
|
|
||||||
{placeholder}
|
|
||||||
</Typography>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
id="display-select"
|
id="display-select"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
@ -88,8 +69,8 @@ export const Select = ({
|
|||||||
borderRadius: "10px",
|
borderRadius: "10px",
|
||||||
},
|
},
|
||||||
"& .MuiSelect-icon": {
|
"& .MuiSelect-icon": {
|
||||||
color: theme.palette.primary.main
|
color: theme.palette.primary.main,
|
||||||
}
|
},
|
||||||
}}
|
}}
|
||||||
MenuProps={{
|
MenuProps={{
|
||||||
PaperProps: {
|
PaperProps: {
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
import { QuizQuestionResult } from "@model/questionTypes/result";
|
import { QuizQuestionResult } from "@model/questionTypes/result";
|
||||||
|
|
||||||
export const isResultQuestionEmpty = (resultQuestion: QuizQuestionResult) => {
|
export const isResultQuestionEmpty = (resultQuestion: QuizQuestionResult) => {
|
||||||
if (
|
if (
|
||||||
(resultQuestion.title.length > 0 && resultQuestion.title !== " ")
|
(resultQuestion.title.length > 0 && resultQuestion.title !== " ") ||
|
||||||
|| (resultQuestion.description.length > 0 && resultQuestion.description !== " ")
|
(resultQuestion.description.length > 0 && resultQuestion.description !== " ") ||
|
||||||
|| (resultQuestion.content.back.length > 0 && resultQuestion.content.back !== " ")
|
(resultQuestion.content.back.length > 0 && resultQuestion.content.back !== " ") ||
|
||||||
|| (resultQuestion.content.originalBack.length > 0 && resultQuestion.content.originalBack !== " ")
|
(resultQuestion.content.originalBack.length > 0 && resultQuestion.content.originalBack !== " ") ||
|
||||||
|| (resultQuestion.content.innerName.length > 0 && resultQuestion.content.innerName !== " ")
|
(resultQuestion.content.innerName.length > 0 && resultQuestion.content.innerName !== " ") ||
|
||||||
|| (resultQuestion.content.text.length > 0 && resultQuestion.content.text !== " ")
|
(resultQuestion.content.text.length > 0 && resultQuestion.content.text !== " ") ||
|
||||||
|| (resultQuestion.content.video.length > 0 && resultQuestion.content.video !== " ")
|
(resultQuestion.content.video.length > 0 && resultQuestion.content.video !== " ") ||
|
||||||
|| (resultQuestion.content.hint.text.length > 0 && resultQuestion.content.hint.text !== " ")
|
(resultQuestion.content.hint.text.length > 0 && resultQuestion.content.hint.text !== " ")
|
||||||
) return false;
|
)
|
||||||
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
@ -1,69 +1,23 @@
|
|||||||
import { UploadFileType } from "@model/questionTypes/file";
|
import { UploadFileType } from "@model/questionTypes/file";
|
||||||
|
|
||||||
|
|
||||||
export const MAX_FILE_SIZE = 419430400;
|
export const MAX_FILE_SIZE = 419430400;
|
||||||
|
|
||||||
export const UPLOAD_FILE_DESCRIPTIONS_MAP = {
|
export const UPLOAD_FILE_DESCRIPTIONS_MAP = {
|
||||||
picture: {
|
picture: {
|
||||||
title: "Добавить изображение",
|
title: "Добавить изображение",
|
||||||
description: "Принимает изображения",
|
description: "Принимает изображения",
|
||||||
},
|
},
|
||||||
video: {
|
video: {
|
||||||
title: "Добавить видео",
|
title: "Добавить видео",
|
||||||
description: "Принимает .mp4 и .mov формат — максимум 50мб",
|
description: "Принимает .mp4 и .mov формат — максимум 50мб",
|
||||||
},
|
},
|
||||||
audio: { title: "Добавить аудиофайл", description: "Принимает аудиофайлы" },
|
audio: { title: "Добавить аудиофайл", description: "Принимает аудиофайлы" },
|
||||||
document: { title: "Добавить документ", description: "Принимает документы" },
|
document: { title: "Добавить документ", description: "Принимает документы" },
|
||||||
} as const satisfies Record<UploadFileType, { title: string; description: string; }>;
|
} as const satisfies Record<UploadFileType, { title: string; description: string }>;
|
||||||
|
|
||||||
export const ACCEPT_SEND_FILE_TYPES_MAP = {
|
export const ACCEPT_SEND_FILE_TYPES_MAP = {
|
||||||
picture: [
|
picture: [".jpeg", ".jpg", ".png", ".ico", ".gif", ".tiff", ".webp", ".eps", ".svg"],
|
||||||
".jpeg",
|
video: [".mp4", ".mov", ".wmv", ".avi", ".avchd", ".flv", ".f4v", ".swf", ".mkv", ".webm", ".mpeg-2"],
|
||||||
".jpg",
|
audio: [".aac", ".aiff", ".dsd", ".flac", ".mp3", ".mqa", ".ogg", ".wav", ".wma"],
|
||||||
".png",
|
document: [".doc", ".docx", ".dotx", ".rtf", ".odt", ".pdf", ".txt", ".xls", ".ppt", ".xlsx", ".pptx", ".pages"],
|
||||||
".ico",
|
|
||||||
".gif",
|
|
||||||
".tiff",
|
|
||||||
".webp",
|
|
||||||
".eps",
|
|
||||||
".svg"
|
|
||||||
],
|
|
||||||
video: [
|
|
||||||
".mp4",
|
|
||||||
".mov",
|
|
||||||
".wmv",
|
|
||||||
".avi",
|
|
||||||
".avchd",
|
|
||||||
".flv",
|
|
||||||
".f4v",
|
|
||||||
".swf",
|
|
||||||
".mkv",
|
|
||||||
".webm",
|
|
||||||
".mpeg-2"
|
|
||||||
],
|
|
||||||
audio: [
|
|
||||||
".aac",
|
|
||||||
".aiff",
|
|
||||||
".dsd",
|
|
||||||
".flac",
|
|
||||||
".mp3",
|
|
||||||
".mqa",
|
|
||||||
".ogg",
|
|
||||||
".wav",
|
|
||||||
".wma"
|
|
||||||
],
|
|
||||||
document: [
|
|
||||||
".doc",
|
|
||||||
".docx",
|
|
||||||
".dotx",
|
|
||||||
".rtf",
|
|
||||||
".odt",
|
|
||||||
".pdf",
|
|
||||||
".txt",
|
|
||||||
".xls",
|
|
||||||
".ppt",
|
|
||||||
".xlsx",
|
|
||||||
".pptx",
|
|
||||||
".pages",
|
|
||||||
],
|
|
||||||
} as const;
|
} as const;
|
||||||
|
@ -11,11 +11,7 @@ export const replaceSpacesToEmptyLines = <T = unknown>(object: T): T => {
|
|||||||
|
|
||||||
for (const [key, value] of Object.entries(object)) {
|
for (const [key, value] of Object.entries(object)) {
|
||||||
if (typeof value === "string") {
|
if (typeof value === "string") {
|
||||||
|
result[key] = value.replace("squiz.pena.digital", "storage.yandexcloud.net");
|
||||||
result[key] = value.replace(
|
|
||||||
"squiz.pena.digital",
|
|
||||||
"storage.yandexcloud.net"
|
|
||||||
);
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -2,16 +2,16 @@ import { QuizSettings } from "@model/settingsData";
|
|||||||
import { createContext, useContext } from "react";
|
import { createContext, useContext } from "react";
|
||||||
|
|
||||||
type QuizData = QuizSettings & {
|
type QuizData = QuizSettings & {
|
||||||
quizId: string;
|
quizId: string;
|
||||||
preview: boolean;
|
preview: boolean;
|
||||||
changeFaviconAndTitle: boolean;
|
changeFaviconAndTitle: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const QuizDataContext = createContext<QuizData | null>(null);
|
export const QuizDataContext = createContext<QuizData | null>(null);
|
||||||
|
|
||||||
export const useQuizData = () => {
|
export const useQuizData = () => {
|
||||||
const quizData = useContext(QuizDataContext);
|
const quizData = useContext(QuizDataContext);
|
||||||
if (quizData === null) throw new Error("QuizData context is null");
|
if (quizData === null) throw new Error("QuizData context is null");
|
||||||
|
|
||||||
return quizData;
|
return quizData;
|
||||||
};
|
};
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import { createContext, useContext } from "react";
|
import { createContext, useContext } from "react";
|
||||||
|
|
||||||
|
|
||||||
export const RootContainerWidthContext = createContext<number | null>(null);
|
export const RootContainerWidthContext = createContext<number | null>(null);
|
||||||
|
|
||||||
export const useRootContainerSize = () => {
|
export const useRootContainerSize = () => {
|
||||||
const rootContainerSize = useContext(RootContainerWidthContext);
|
const rootContainerSize = useContext(RootContainerWidthContext);
|
||||||
if (rootContainerSize === null) throw new Error("rootContainerSize context is null");
|
if (rootContainerSize === null) throw new Error("rootContainerSize context is null");
|
||||||
|
|
||||||
return rootContainerSize;
|
return rootContainerSize;
|
||||||
};
|
};
|
||||||
|
@ -2,54 +2,54 @@ import { AnyTypedQuizQuestion } from "@model/questionTypes/shared";
|
|||||||
import { QuizSettings } from "@model/settingsData";
|
import { QuizSettings } from "@model/settingsData";
|
||||||
|
|
||||||
export interface GetQuizDataResponse {
|
export interface GetQuizDataResponse {
|
||||||
cnt: number;
|
cnt: number;
|
||||||
settings: {
|
settings: {
|
||||||
fp: boolean;
|
fp: boolean;
|
||||||
rep: boolean;
|
rep: boolean;
|
||||||
name: string;
|
name: string;
|
||||||
cfg: string;
|
cfg: string;
|
||||||
lim: number;
|
lim: number;
|
||||||
due: number;
|
due: number;
|
||||||
delay: number;
|
delay: number;
|
||||||
pausable: boolean;
|
pausable: boolean;
|
||||||
};
|
};
|
||||||
items: {
|
items: {
|
||||||
id: number;
|
id: number;
|
||||||
title: string;
|
title: string;
|
||||||
desc: string;
|
desc: string;
|
||||||
typ: string;
|
typ: string;
|
||||||
req: boolean;
|
req: boolean;
|
||||||
p: number;
|
p: number;
|
||||||
c: string;
|
c: string;
|
||||||
}[];
|
}[];
|
||||||
show_badge: boolean;
|
show_badge: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function parseQuizData(quizDataResponse: GetQuizDataResponse): Omit<QuizSettings, "recentlyCompleted"> {
|
export function parseQuizData(quizDataResponse: GetQuizDataResponse): Omit<QuizSettings, "recentlyCompleted"> {
|
||||||
const items: QuizSettings["questions"] = quizDataResponse.items.map((item) => {
|
const items: QuizSettings["questions"] = quizDataResponse.items.map((item) => {
|
||||||
const content = JSON.parse(item.c);
|
const content = JSON.parse(item.c);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
description: item.desc,
|
description: item.desc,
|
||||||
id: item.id,
|
id: item.id,
|
||||||
page: item.p,
|
page: item.p,
|
||||||
required: item.req,
|
required: item.req,
|
||||||
title: item.title,
|
title: item.title,
|
||||||
type: item.typ,
|
type: item.typ,
|
||||||
content
|
content,
|
||||||
} as unknown as AnyTypedQuizQuestion;
|
} as unknown as AnyTypedQuizQuestion;
|
||||||
});
|
});
|
||||||
|
|
||||||
const settings: QuizSettings["settings"] = {
|
const settings: QuizSettings["settings"] = {
|
||||||
fp: quizDataResponse.settings.fp,
|
fp: quizDataResponse.settings.fp,
|
||||||
rep: quizDataResponse.settings.rep,
|
rep: quizDataResponse.settings.rep,
|
||||||
name: quizDataResponse.settings.name,
|
name: quizDataResponse.settings.name,
|
||||||
cfg: JSON.parse(quizDataResponse?.settings.cfg),
|
cfg: JSON.parse(quizDataResponse?.settings.cfg),
|
||||||
lim: quizDataResponse.settings.lim,
|
lim: quizDataResponse.settings.lim,
|
||||||
due: quizDataResponse.settings.due,
|
due: quizDataResponse.settings.due,
|
||||||
delay: quizDataResponse.settings.delay,
|
delay: quizDataResponse.settings.delay,
|
||||||
pausable: quizDataResponse.settings.pausable
|
pausable: quizDataResponse.settings.pausable,
|
||||||
};
|
};
|
||||||
|
|
||||||
return { cnt: quizDataResponse.cnt, settings, questions: items, show_badge: quizDataResponse.show_badge };
|
return { cnt: quizDataResponse.cnt, settings, questions: items, show_badge: quizDataResponse.show_badge };
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1 @@
|
|||||||
export type MetricsMessengers =
|
export type MetricsMessengers = "telegram" | "viber" | "whatsapp" | "vkontakte" | "messenger" | "skype" | "instagram";
|
||||||
| "telegram"
|
|
||||||
| "viber"
|
|
||||||
| "whatsapp"
|
|
||||||
| "vkontakte"
|
|
||||||
| "messenger"
|
|
||||||
| "skype"
|
|
||||||
| "instagram";
|
|
||||||
|
@ -1,8 +1,4 @@
|
|||||||
import type {
|
import type { QuizQuestionBase, QuestionHint, QuestionBranchingRule } from "./shared";
|
||||||
QuizQuestionBase,
|
|
||||||
QuestionHint,
|
|
||||||
QuestionBranchingRule,
|
|
||||||
} from "./shared";
|
|
||||||
|
|
||||||
export interface QuizQuestionDate extends QuizQuestionBase {
|
export interface QuizQuestionDate extends QuizQuestionBase {
|
||||||
type: "date";
|
type: "date";
|
||||||
|
@ -1,9 +1,4 @@
|
|||||||
import type {
|
import type { QuizQuestionBase, QuestionVariant, QuestionHint, QuestionBranchingRule } from "./shared";
|
||||||
QuizQuestionBase,
|
|
||||||
QuestionVariant,
|
|
||||||
QuestionHint,
|
|
||||||
QuestionBranchingRule,
|
|
||||||
} from "./shared";
|
|
||||||
|
|
||||||
export interface QuizQuestionEmoji extends QuizQuestionBase {
|
export interface QuizQuestionEmoji extends QuizQuestionBase {
|
||||||
type: "emoji";
|
type: "emoji";
|
||||||
|
@ -1,8 +1,4 @@
|
|||||||
import type {
|
import type { QuizQuestionBase, QuestionHint, QuestionBranchingRule } from "./shared";
|
||||||
QuizQuestionBase,
|
|
||||||
QuestionHint,
|
|
||||||
QuestionBranchingRule,
|
|
||||||
} from "./shared";
|
|
||||||
|
|
||||||
export const UPLOAD_FILE_TYPES_MAP = {
|
export const UPLOAD_FILE_TYPES_MAP = {
|
||||||
picture: "Изображения",
|
picture: "Изображения",
|
||||||
|
@ -1,37 +1,32 @@
|
|||||||
import type {
|
import type { QuestionHint, QuestionVariant, QuizQuestionBase, QuestionBranchingRule } from "./shared";
|
||||||
QuestionHint,
|
|
||||||
QuestionVariant,
|
|
||||||
QuizQuestionBase,
|
|
||||||
QuestionBranchingRule,
|
|
||||||
} from "./shared";
|
|
||||||
|
|
||||||
export interface QuizQuestionImages extends QuizQuestionBase {
|
export interface QuizQuestionImages extends QuizQuestionBase {
|
||||||
type: "images";
|
type: "images";
|
||||||
content: {
|
content: {
|
||||||
id: string;
|
id: string;
|
||||||
/** Чекбокс "Вариант "свой ответ"" */
|
/** Чекбокс "Вариант "свой ответ"" */
|
||||||
own: boolean;
|
own: boolean;
|
||||||
/** Чекбокс "Можно несколько" */
|
/** Чекбокс "Можно несколько" */
|
||||||
multi: boolean;
|
multi: boolean;
|
||||||
/** Пропорции */
|
/** Пропорции */
|
||||||
xy: "1:1" | "1:2" | "2:1";
|
xy: "1:1" | "1:2" | "2:1";
|
||||||
/** Чекбокс "Внутреннее название вопроса" */
|
/** Чекбокс "Внутреннее название вопроса" */
|
||||||
innerNameCheck: boolean;
|
innerNameCheck: boolean;
|
||||||
/** Поле "Внутреннее название вопроса" */
|
/** Поле "Внутреннее название вопроса" */
|
||||||
innerName: string;
|
innerName: string;
|
||||||
/** Чекбокс "Большие картинки" */
|
/** Чекбокс "Большие картинки" */
|
||||||
large: boolean;
|
large: boolean;
|
||||||
/** Форма */
|
/** Форма */
|
||||||
format: "carousel" | "masonry";
|
format: "carousel" | "masonry";
|
||||||
/** Чекбокс "Необязательный вопрос" */
|
/** Чекбокс "Необязательный вопрос" */
|
||||||
required: boolean;
|
required: boolean;
|
||||||
/** Варианты (картинки) */
|
/** Варианты (картинки) */
|
||||||
variants: QuestionVariant[];
|
variants: QuestionVariant[];
|
||||||
hint: QuestionHint;
|
hint: QuestionHint;
|
||||||
rule: QuestionBranchingRule;
|
rule: QuestionBranchingRule;
|
||||||
back: string | null;
|
back: string | null;
|
||||||
originalBack: string | null;
|
originalBack: string | null;
|
||||||
autofill: boolean;
|
autofill: boolean;
|
||||||
largeCheck: boolean;
|
largeCheck: boolean;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,4 @@
|
|||||||
import type {
|
import type { QuizQuestionBase, QuestionHint, QuestionBranchingRule } from "./shared";
|
||||||
QuizQuestionBase,
|
|
||||||
QuestionHint,
|
|
||||||
QuestionBranchingRule,
|
|
||||||
} from "./shared";
|
|
||||||
|
|
||||||
export interface QuizQuestionNumber extends QuizQuestionBase {
|
export interface QuizQuestionNumber extends QuizQuestionBase {
|
||||||
type: "number";
|
type: "number";
|
||||||
|
@ -1,8 +1,4 @@
|
|||||||
import type {
|
import type { QuizQuestionBase, QuestionHint, QuestionBranchingRule } from "./shared";
|
||||||
QuizQuestionBase,
|
|
||||||
QuestionHint,
|
|
||||||
QuestionBranchingRule,
|
|
||||||
} from "./shared";
|
|
||||||
|
|
||||||
export interface QuizQuestionPage extends QuizQuestionBase {
|
export interface QuizQuestionPage extends QuizQuestionBase {
|
||||||
type: "page";
|
type: "page";
|
||||||
|
@ -1,8 +1,4 @@
|
|||||||
import type {
|
import type { QuizQuestionBase, QuestionHint, QuestionBranchingRule } from "./shared";
|
||||||
QuizQuestionBase,
|
|
||||||
QuestionHint,
|
|
||||||
QuestionBranchingRule,
|
|
||||||
} from "./shared";
|
|
||||||
|
|
||||||
export interface QuizQuestionRating extends QuizQuestionBase {
|
export interface QuizQuestionRating extends QuizQuestionBase {
|
||||||
type: "rating";
|
type: "rating";
|
||||||
|
@ -1,11 +1,7 @@
|
|||||||
import type {
|
import type { QuizQuestionBase, QuestionBranchingRule, QuestionHint } from "./shared";
|
||||||
QuizQuestionBase,
|
|
||||||
QuestionBranchingRule,
|
|
||||||
QuestionHint,
|
|
||||||
} from "./shared";
|
|
||||||
|
|
||||||
interface ResultQuestionBranchingRule extends QuestionBranchingRule {
|
interface ResultQuestionBranchingRule extends QuestionBranchingRule {
|
||||||
minScore?: number
|
minScore?: number;
|
||||||
}
|
}
|
||||||
export interface QuizQuestionResult extends QuizQuestionBase {
|
export interface QuizQuestionResult extends QuizQuestionBase {
|
||||||
type: "result";
|
type: "result";
|
||||||
@ -18,9 +14,9 @@ export interface QuizQuestionResult extends QuizQuestionBase {
|
|||||||
text: string;
|
text: string;
|
||||||
price: [number] | [number, number];
|
price: [number] | [number, number];
|
||||||
useImage: boolean;
|
useImage: boolean;
|
||||||
rule: ResultQuestionBranchingRule,
|
rule: ResultQuestionBranchingRule;
|
||||||
hint: QuestionHint;
|
hint: QuestionHint;
|
||||||
autofill: boolean;
|
autofill: boolean;
|
||||||
redirect: string
|
redirect: string;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,4 @@
|
|||||||
import type {
|
import type { QuizQuestionBase, QuestionVariant, QuestionHint, QuestionBranchingRule } from "./shared";
|
||||||
QuizQuestionBase,
|
|
||||||
QuestionVariant,
|
|
||||||
QuestionHint,
|
|
||||||
QuestionBranchingRule,
|
|
||||||
} from "./shared";
|
|
||||||
|
|
||||||
export interface QuizQuestionSelect extends QuizQuestionBase {
|
export interface QuizQuestionSelect extends QuizQuestionBase {
|
||||||
type: "select";
|
type: "select";
|
||||||
|
@ -13,115 +13,121 @@ import type { QuizQuestionVariant } from "./variant";
|
|||||||
import type { QuizQuestionVarImg } from "./varimg";
|
import type { QuizQuestionVarImg } from "./varimg";
|
||||||
|
|
||||||
export interface QuestionBranchingRuleMain {
|
export interface QuestionBranchingRuleMain {
|
||||||
next: string;
|
next: string;
|
||||||
or: boolean;
|
or: boolean;
|
||||||
rules: {
|
rules: {
|
||||||
question: string; //id родителя (пока что)
|
question: string; //id родителя (пока что)
|
||||||
answers: string[];
|
answers: string[];
|
||||||
}[];
|
}[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface QuestionBranchingRule {
|
export interface QuestionBranchingRule {
|
||||||
children: string[];
|
children: string[];
|
||||||
//список условий
|
//список условий
|
||||||
main: QuestionBranchingRuleMain[];
|
main: QuestionBranchingRuleMain[];
|
||||||
parentId: string | null | "root";
|
parentId: string | null | "root";
|
||||||
default: string;
|
default: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface QuestionHint {
|
export interface QuestionHint {
|
||||||
/** Текст подсказки */
|
/** Текст подсказки */
|
||||||
text: string;
|
text: string;
|
||||||
/** URL видео подсказки */
|
/** URL видео подсказки */
|
||||||
video: string;
|
video: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type QuestionVariant = {
|
export type QuestionVariant = {
|
||||||
id: string;
|
id: string;
|
||||||
/** Текст */
|
/** Текст */
|
||||||
answer: string;
|
answer: string;
|
||||||
/** Текст подсказки */
|
/** Текст подсказки */
|
||||||
hints: string;
|
hints: string;
|
||||||
/** Дополнительное поле для текста, emoji, ссылки на картинку */
|
/** Дополнительное поле для текста, emoji, ссылки на картинку */
|
||||||
extendedText: string;
|
extendedText: string;
|
||||||
/** Оригинал изображения (до кропа) */
|
/** Оригинал изображения (до кропа) */
|
||||||
originalImageUrl: string;
|
originalImageUrl: string;
|
||||||
points?: number;
|
points?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type QuestionType =
|
export type QuestionType =
|
||||||
| "variant"
|
| "variant"
|
||||||
| "images"
|
| "images"
|
||||||
| "varimg"
|
| "varimg"
|
||||||
| "emoji"
|
| "emoji"
|
||||||
| "text"
|
| "text"
|
||||||
| "select"
|
| "select"
|
||||||
| "date"
|
| "date"
|
||||||
| "number"
|
| "number"
|
||||||
| "file"
|
| "file"
|
||||||
| "page"
|
| "page"
|
||||||
| "rating"
|
| "rating"
|
||||||
| "result";
|
| "result";
|
||||||
|
|
||||||
export interface QuizQuestionBase {
|
export interface QuizQuestionBase {
|
||||||
/** Stable id, generated on client */
|
/** Stable id, generated on client */
|
||||||
|
id: string;
|
||||||
|
quizId: number;
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
page: number;
|
||||||
|
type?: QuestionType | null;
|
||||||
|
expanded: boolean;
|
||||||
|
openedModalSettings: boolean;
|
||||||
|
deleted: boolean;
|
||||||
|
required: boolean;
|
||||||
|
deleteTimeoutId: number;
|
||||||
|
content: {
|
||||||
id: string;
|
id: string;
|
||||||
quizId: number;
|
hint: QuestionHint;
|
||||||
title: string;
|
rule: QuestionBranchingRule;
|
||||||
description: string;
|
back: string | null;
|
||||||
page: number;
|
originalBack: string | null;
|
||||||
type?: QuestionType | null;
|
autofill: boolean;
|
||||||
expanded: boolean;
|
};
|
||||||
openedModalSettings: boolean;
|
|
||||||
deleted: boolean;
|
|
||||||
required: boolean;
|
|
||||||
deleteTimeoutId: number;
|
|
||||||
content: {
|
|
||||||
id: string;
|
|
||||||
hint: QuestionHint;
|
|
||||||
rule: QuestionBranchingRule;
|
|
||||||
back: string | null;
|
|
||||||
originalBack: string | null;
|
|
||||||
autofill: boolean;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type AnyTypedQuizQuestion =
|
export type AnyTypedQuizQuestion =
|
||||||
| QuizQuestionVariant
|
| QuizQuestionVariant
|
||||||
| QuizQuestionImages
|
| QuizQuestionImages
|
||||||
| QuizQuestionVarImg
|
| QuizQuestionVarImg
|
||||||
| QuizQuestionEmoji
|
| QuizQuestionEmoji
|
||||||
| QuizQuestionText
|
| QuizQuestionText
|
||||||
| QuizQuestionSelect
|
| QuizQuestionSelect
|
||||||
| QuizQuestionDate
|
| QuizQuestionDate
|
||||||
| QuizQuestionNumber
|
| QuizQuestionNumber
|
||||||
| QuizQuestionFile
|
| QuizQuestionFile
|
||||||
| QuizQuestionPage
|
| QuizQuestionPage
|
||||||
| QuizQuestionRating
|
| QuizQuestionRating
|
||||||
| QuizQuestionResult;
|
| QuizQuestionResult;
|
||||||
|
|
||||||
export type RealTypedQuizQuestion = Exclude<AnyTypedQuizQuestion, QuizQuestionResult>;
|
export type RealTypedQuizQuestion = Exclude<AnyTypedQuizQuestion, QuizQuestionResult>;
|
||||||
|
|
||||||
type FilterQuestionsWithVariants<T> = T extends {
|
type FilterQuestionsWithVariants<T> = T extends {
|
||||||
content: { variants: QuestionVariant[]; };
|
content: { variants: QuestionVariant[] };
|
||||||
} ? T : never;
|
}
|
||||||
|
? T
|
||||||
|
: never;
|
||||||
|
|
||||||
export type QuizQuestionsWithVariants = FilterQuestionsWithVariants<AnyTypedQuizQuestion>;
|
export type QuizQuestionsWithVariants = FilterQuestionsWithVariants<AnyTypedQuizQuestion>;
|
||||||
|
|
||||||
|
export const createBranchingRuleMain: (targetId: string, parentId: string) => QuestionBranchingRuleMain = (
|
||||||
export const createBranchingRuleMain: (targetId: string, parentId: string) => QuestionBranchingRuleMain = (targetId, parentId) => ({
|
targetId,
|
||||||
next: targetId,
|
parentId
|
||||||
or: false,
|
) => ({
|
||||||
rules: [{
|
next: targetId,
|
||||||
question: parentId,
|
or: false,
|
||||||
answers: [] as string[],
|
rules: [
|
||||||
}]
|
{
|
||||||
|
question: parentId,
|
||||||
|
answers: [] as string[],
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
export const createQuestionVariant: () => QuestionVariant = () => ({
|
export const createQuestionVariant: () => QuestionVariant = () => ({
|
||||||
id: nanoid(),
|
id: nanoid(),
|
||||||
answer: "",
|
answer: "",
|
||||||
extendedText: "",
|
extendedText: "",
|
||||||
hints: "",
|
hints: "",
|
||||||
originalImageUrl: "",
|
originalImageUrl: "",
|
||||||
});
|
});
|
||||||
|
@ -1,8 +1,4 @@
|
|||||||
import type {
|
import type { QuizQuestionBase, QuestionHint, QuestionBranchingRule } from "./shared";
|
||||||
QuizQuestionBase,
|
|
||||||
QuestionHint,
|
|
||||||
QuestionBranchingRule,
|
|
||||||
} from "./shared";
|
|
||||||
|
|
||||||
export interface QuizQuestionText extends QuizQuestionBase {
|
export interface QuizQuestionText extends QuizQuestionBase {
|
||||||
type: "text";
|
type: "text";
|
||||||
|
@ -1,9 +1,4 @@
|
|||||||
import type {
|
import type { QuizQuestionBase, QuestionVariant, QuestionHint, QuestionBranchingRule } from "./shared";
|
||||||
QuizQuestionBase,
|
|
||||||
QuestionVariant,
|
|
||||||
QuestionHint,
|
|
||||||
QuestionBranchingRule,
|
|
||||||
} from "./shared";
|
|
||||||
|
|
||||||
export interface QuizQuestionVariant extends QuizQuestionBase {
|
export interface QuizQuestionVariant extends QuizQuestionBase {
|
||||||
type: "variant";
|
type: "variant";
|
||||||
|
@ -1,29 +1,24 @@
|
|||||||
import type {
|
import type { QuestionHint, QuestionVariant, QuizQuestionBase, QuestionBranchingRule } from "./shared";
|
||||||
QuestionHint,
|
|
||||||
QuestionVariant,
|
|
||||||
QuizQuestionBase,
|
|
||||||
QuestionBranchingRule,
|
|
||||||
} from "./shared";
|
|
||||||
|
|
||||||
export interface QuizQuestionVarImg extends QuizQuestionBase {
|
export interface QuizQuestionVarImg extends QuizQuestionBase {
|
||||||
type: "varimg";
|
type: "varimg";
|
||||||
content: {
|
content: {
|
||||||
id: string;
|
id: string;
|
||||||
/** Чекбокс "Вариант "свой ответ"" */
|
/** Чекбокс "Вариант "свой ответ"" */
|
||||||
own: boolean;
|
own: boolean;
|
||||||
/** Чекбокс "Внутреннее название вопроса" */
|
/** Чекбокс "Внутреннее название вопроса" */
|
||||||
innerNameCheck: boolean;
|
innerNameCheck: boolean;
|
||||||
/** Поле "Внутреннее название вопроса" */
|
/** Поле "Внутреннее название вопроса" */
|
||||||
innerName: string;
|
innerName: string;
|
||||||
/** Чекбокс "Необязательный вопрос" */
|
/** Чекбокс "Необязательный вопрос" */
|
||||||
required: boolean;
|
required: boolean;
|
||||||
variants: QuestionVariant[];
|
variants: QuestionVariant[];
|
||||||
hint: QuestionHint;
|
hint: QuestionHint;
|
||||||
rule: QuestionBranchingRule;
|
rule: QuestionBranchingRule;
|
||||||
back: string;
|
back: string;
|
||||||
originalBack: string;
|
originalBack: string;
|
||||||
autofill: boolean;
|
autofill: boolean;
|
||||||
largeCheck: boolean;
|
largeCheck: boolean;
|
||||||
replText: string;
|
replText: string;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import {AnyTypedQuizQuestion} from "./questionTypes/shared";
|
import { AnyTypedQuizQuestion } from "./questionTypes/shared";
|
||||||
|
|
||||||
export type QuizStartpageType = "standard" | "expanded" | "centered" | null;
|
export type QuizStartpageType = "standard" | "expanded" | "centered" | null;
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ export type QuizSettingsConfig = {
|
|||||||
delay: number;
|
delay: number;
|
||||||
pausable: boolean;
|
pausable: boolean;
|
||||||
cfg: QuizConfig;
|
cfg: QuizConfig;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type QuizSettings = {
|
export type QuizSettings = {
|
||||||
questions: AnyTypedQuizQuestion[];
|
questions: AnyTypedQuizQuestion[];
|
||||||
@ -114,12 +114,7 @@ export interface QuizConfig {
|
|||||||
vkMetricsNumber: number | undefined;
|
vkMetricsNumber: number | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type FormContactFieldName =
|
export type FormContactFieldName = "name" | "email" | "phone" | "text" | "address";
|
||||||
| "name"
|
|
||||||
| "email"
|
|
||||||
| "phone"
|
|
||||||
| "text"
|
|
||||||
| "address";
|
|
||||||
|
|
||||||
export type FormContactFieldData = {
|
export type FormContactFieldData = {
|
||||||
text: string;
|
text: string;
|
||||||
|
@ -1,28 +1,28 @@
|
|||||||
export interface BannerWidgetComponentProps {
|
export interface BannerWidgetComponentProps {
|
||||||
quizId: string;
|
quizId: string;
|
||||||
position: "topleft" | "topright" | "bottomleft" | "bottomright";
|
position: "topleft" | "topright" | "bottomleft" | "bottomright";
|
||||||
onWidgetClose?: () => void;
|
onWidgetClose?: () => void;
|
||||||
dialogDimensions?: { width: string; height: string; };
|
dialogDimensions?: { width: string; height: string };
|
||||||
appealText?: string;
|
appealText?: string;
|
||||||
quizHeaderText?: string;
|
quizHeaderText?: string;
|
||||||
buttonTextColor?: string;
|
buttonTextColor?: string;
|
||||||
buttonBackgroundColor?: string;
|
buttonBackgroundColor?: string;
|
||||||
/**
|
/**
|
||||||
* Показывать виджет через X секунд
|
* Показывать виджет через X секунд
|
||||||
*/
|
*/
|
||||||
autoShowWidgetTime?: number;
|
autoShowWidgetTime?: number;
|
||||||
/**
|
/**
|
||||||
* Открыть квиз через X секунд, 0 - сразу, null - не открывать
|
* Открыть квиз через X секунд, 0 - сразу, null - не открывать
|
||||||
*/
|
*/
|
||||||
autoShowQuizTime?: number | null;
|
autoShowQuizTime?: number | null;
|
||||||
openOnLeaveAttempt?: boolean;
|
openOnLeaveAttempt?: boolean;
|
||||||
buttonFlash?: boolean;
|
buttonFlash?: boolean;
|
||||||
hideOnMobile?: boolean;
|
hideOnMobile?: boolean;
|
||||||
withShadow?: boolean;
|
withShadow?: boolean;
|
||||||
rounded?: boolean;
|
rounded?: boolean;
|
||||||
bannerFullWidth?: boolean;
|
bannerFullWidth?: boolean;
|
||||||
pulsation?: boolean;
|
pulsation?: boolean;
|
||||||
fullScreen?: boolean;
|
fullScreen?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type BannerWidgetParams = Omit<BannerWidgetComponentProps, "onWidgetClose">;
|
export type BannerWidgetParams = Omit<BannerWidgetComponentProps, "onWidgetClose">;
|
||||||
|
@ -1,30 +1,30 @@
|
|||||||
export interface ButtonWidgetComponentProps {
|
export interface ButtonWidgetComponentProps {
|
||||||
quizId: string;
|
quizId: string;
|
||||||
fixedSide?: "left" | "right";
|
fixedSide?: "left" | "right";
|
||||||
dialogDimensions?: { width: string; height: string; };
|
dialogDimensions?: { width: string; height: string };
|
||||||
/**
|
/**
|
||||||
* Открыть квиз через X секунд, 0 - сразу, null - не открывать
|
* Открыть квиз через X секунд, 0 - сразу, null - не открывать
|
||||||
*/
|
*/
|
||||||
autoShowQuizTime?: number | null;
|
autoShowQuizTime?: number | null;
|
||||||
hideOnMobile?: boolean;
|
hideOnMobile?: boolean;
|
||||||
openOnLeaveAttempt?: boolean;
|
openOnLeaveAttempt?: boolean;
|
||||||
buttonFlash?: boolean;
|
buttonFlash?: boolean;
|
||||||
withShadow?: boolean;
|
withShadow?: boolean;
|
||||||
rounded?: boolean;
|
rounded?: boolean;
|
||||||
buttonText?: string;
|
buttonText?: string;
|
||||||
buttonTextColor?: string;
|
buttonTextColor?: string;
|
||||||
buttonBackgroundColor?: string;
|
buttonBackgroundColor?: string;
|
||||||
fullScreen?: boolean;
|
fullScreen?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ButtonWidgetParams = Omit<ButtonWidgetComponentProps, "fixedSide"> & {
|
export type ButtonWidgetParams = Omit<ButtonWidgetComponentProps, "fixedSide"> & {
|
||||||
selector: string;
|
selector: string;
|
||||||
/**
|
/**
|
||||||
* In seconds, null - polling disabled
|
* In seconds, null - polling disabled
|
||||||
*/
|
*/
|
||||||
selectorPollingTimeLimit?: number | null;
|
selectorPollingTimeLimit?: number | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ButtonWidgetFixedParams = Omit<ButtonWidgetComponentProps, "selector"> & {
|
export type ButtonWidgetFixedParams = Omit<ButtonWidgetComponentProps, "selector"> & {
|
||||||
fixedSide: "left" | "right";
|
fixedSide: "left" | "right";
|
||||||
};
|
};
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
import { ButtonWidgetComponentProps } from "./button";
|
import { ButtonWidgetComponentProps } from "./button";
|
||||||
|
|
||||||
export type ContainerWidgetComponentProps = ButtonWidgetComponentProps & {
|
export type ContainerWidgetComponentProps = ButtonWidgetComponentProps & {
|
||||||
quizId: string;
|
quizId: string;
|
||||||
showButtonOnMobile?: boolean;
|
showButtonOnMobile?: boolean;
|
||||||
dimensions?: { width: string; height: string; };
|
dimensions?: { width: string; height: string };
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ContainerWidgetParams = ContainerWidgetComponentProps & {
|
export type ContainerWidgetParams = ContainerWidgetComponentProps & {
|
||||||
selector: string;
|
selector: string;
|
||||||
/**
|
/**
|
||||||
* In seconds, null - polling disabled
|
* In seconds, null - polling disabled
|
||||||
*/
|
*/
|
||||||
selectorPollingTimeLimit?: number | null;
|
selectorPollingTimeLimit?: number | null;
|
||||||
};
|
};
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
export interface PopupWidgetComponentProps {
|
export interface PopupWidgetComponentProps {
|
||||||
quizId: string;
|
quizId: string;
|
||||||
dialogDimensions?: { width: string; height: string; };
|
dialogDimensions?: { width: string; height: string };
|
||||||
/**
|
/**
|
||||||
* Открыть квиз через X секунд, 0 - сразу, null - не открывать
|
* Открыть квиз через X секунд, 0 - сразу, null - не открывать
|
||||||
*/
|
*/
|
||||||
autoShowQuizTime?: number | null;
|
autoShowQuizTime?: number | null;
|
||||||
hideOnMobile?: boolean;
|
hideOnMobile?: boolean;
|
||||||
openOnLeaveAttempt?: boolean;
|
openOnLeaveAttempt?: boolean;
|
||||||
fullScreen?: boolean;
|
fullScreen?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PopupWidgetParams = PopupWidgetComponentProps;
|
export type PopupWidgetParams = PopupWidgetComponentProps;
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
export interface SideWidgetComponentProps {
|
export interface SideWidgetComponentProps {
|
||||||
quizId: string;
|
quizId: string;
|
||||||
position: "left" | "right";
|
position: "left" | "right";
|
||||||
buttonBackgroundColor?: string;
|
buttonBackgroundColor?: string;
|
||||||
buttonTextColor?: string;
|
buttonTextColor?: string;
|
||||||
dialogDimensions?: { width: string; height: string; };
|
dialogDimensions?: { width: string; height: string };
|
||||||
fullScreen?: boolean;
|
fullScreen?: boolean;
|
||||||
buttonFlash?: boolean;
|
buttonFlash?: boolean;
|
||||||
/**
|
/**
|
||||||
* Показывать виджет через X секунд
|
* Показывать виджет через X секунд
|
||||||
*/
|
*/
|
||||||
autoShowWidgetTime?: number;
|
autoShowWidgetTime?: number;
|
||||||
/**
|
/**
|
||||||
* Открыть квиз через X секунд, 0 - сразу, null - не открывать
|
* Открыть квиз через X секунд, 0 - сразу, null - не открывать
|
||||||
*/
|
*/
|
||||||
autoShowQuizTime?: number | null;
|
autoShowQuizTime?: number | null;
|
||||||
hideOnMobile?: boolean;
|
hideOnMobile?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SideWidgetParams = SideWidgetComponentProps;
|
export type SideWidgetParams = SideWidgetComponentProps;
|
||||||
|
@ -9,96 +9,95 @@ import { immer } from "zustand/middleware/immer";
|
|||||||
export type Answer = string | string[] | Moment;
|
export type Answer = string | string[] | Moment;
|
||||||
|
|
||||||
type QuestionAnswer = {
|
type QuestionAnswer = {
|
||||||
questionId: string;
|
questionId: string;
|
||||||
answer: Answer
|
answer: Answer;
|
||||||
};
|
};
|
||||||
|
|
||||||
type OwnVariant = {
|
type OwnVariant = {
|
||||||
id: string;
|
id: string;
|
||||||
variant: QuestionVariant;
|
variant: QuestionVariant;
|
||||||
};
|
};
|
||||||
|
|
||||||
interface QuizViewStore {
|
interface QuizViewStore {
|
||||||
answers: QuestionAnswer[];
|
answers: QuestionAnswer[];
|
||||||
ownVariants: OwnVariant[];
|
ownVariants: OwnVariant[];
|
||||||
pointsSum: number;
|
pointsSum: number;
|
||||||
points: Record<string, number>;
|
points: Record<string, number>;
|
||||||
currentQuizStep: QuizStep;
|
currentQuizStep: QuizStep;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface QuizViewActions {
|
interface QuizViewActions {
|
||||||
updateAnswer: (questionId: string, answer: string | string[] | Moment, points: number) => void;
|
updateAnswer: (questionId: string, answer: string | string[] | Moment, points: number) => void;
|
||||||
deleteAnswer: (questionId: string) => void;
|
deleteAnswer: (questionId: string) => void;
|
||||||
updateOwnVariant: (id: string, answer: string) => void;
|
updateOwnVariant: (id: string, answer: string) => void;
|
||||||
deleteOwnVariant: (id: string) => void;
|
deleteOwnVariant: (id: string) => void;
|
||||||
setCurrentQuizStep: (step: QuizStep) => void;
|
setCurrentQuizStep: (step: QuizStep) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const QuizViewContext = createContext<ReturnType<typeof createQuizViewStore> | null>(null);
|
export const QuizViewContext = createContext<ReturnType<typeof createQuizViewStore> | null>(null);
|
||||||
|
|
||||||
export function useQuizViewStore<U>(selector: (state: QuizViewStore & QuizViewActions) => U): U {
|
export function useQuizViewStore<U>(selector: (state: QuizViewStore & QuizViewActions) => U): U {
|
||||||
const store = useContext(QuizViewContext);
|
const store = useContext(QuizViewContext);
|
||||||
if (!store) throw new Error("QuizViewStore context is null");
|
if (!store) throw new Error("QuizViewStore context is null");
|
||||||
|
|
||||||
return useStore(store, selector);
|
return useStore(store, selector);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const createQuizViewStore = () => createStore<QuizViewStore & QuizViewActions>()(
|
export const createQuizViewStore = () =>
|
||||||
immer(
|
createStore<QuizViewStore & QuizViewActions>()(
|
||||||
(set, get) => ({
|
immer((set, get) => ({
|
||||||
answers: [],
|
answers: [],
|
||||||
ownVariants: [],
|
ownVariants: [],
|
||||||
points: {},
|
points: {},
|
||||||
pointsSum: 0,
|
pointsSum: 0,
|
||||||
currentQuizStep: "startpage",
|
currentQuizStep: "startpage",
|
||||||
updateAnswer(questionId, answer, points) {
|
updateAnswer(questionId, answer, points) {
|
||||||
set(state => {
|
set((state) => {
|
||||||
const index = state.answers.findIndex(answer => questionId === answer.questionId);
|
const index = state.answers.findIndex((answer) => questionId === answer.questionId);
|
||||||
|
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
state.answers.push({ questionId, answer });
|
state.answers.push({ questionId, answer });
|
||||||
} else {
|
} else {
|
||||||
state.answers[index] = { questionId, answer };
|
state.answers[index] = { questionId, answer };
|
||||||
}
|
}
|
||||||
|
|
||||||
state.points = { ...state.points, ...{ [questionId]: points } };
|
state.points = { ...state.points, ...{ [questionId]: points } };
|
||||||
|
|
||||||
state.pointsSum = Object.values(state.points).reduce((sum, value) => sum + value);
|
state.pointsSum = Object.values(state.points).reduce((sum, value) => sum + value);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
deleteAnswer(questionId) {
|
deleteAnswer(questionId) {
|
||||||
set(state => {
|
set((state) => {
|
||||||
state.answers = state.answers.filter(answer => questionId !== answer.questionId);
|
state.answers = state.answers.filter((answer) => questionId !== answer.questionId);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
updateOwnVariant(id, answer) {
|
updateOwnVariant(id, answer) {
|
||||||
set(state => {
|
set((state) => {
|
||||||
const index = state.ownVariants.findIndex((variant) => variant.id === id);
|
const index = state.ownVariants.findIndex((variant) => variant.id === id);
|
||||||
|
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
state.ownVariants.push({
|
state.ownVariants.push({
|
||||||
id,
|
id,
|
||||||
variant: {
|
variant: {
|
||||||
id: nanoid(),
|
id: nanoid(),
|
||||||
answer,
|
answer,
|
||||||
extendedText: "",
|
extendedText: "",
|
||||||
hints: "",
|
hints: "",
|
||||||
originalImageUrl: "",
|
originalImageUrl: "",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
state.ownVariants[index].variant.answer = answer;
|
state.ownVariants[index].variant.answer = answer;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
deleteOwnVariant(id) {
|
deleteOwnVariant(id) {
|
||||||
set(state => {
|
set((state) => {
|
||||||
state.ownVariants = state.ownVariants.filter((variant) => variant.id !== id);
|
state.ownVariants = state.ownVariants.filter((variant) => variant.id !== id);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
setCurrentQuizStep(step) {
|
setCurrentQuizStep(step) {
|
||||||
set({ currentQuizStep: step });
|
set({ currentQuizStep: step });
|
||||||
},
|
},
|
||||||
})
|
}))
|
||||||
)
|
);
|
||||||
);
|
|
||||||
|
@ -15,7 +15,6 @@ interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function CustomCheckbox({ label, handleChange, checked, sx, dataCy, colorIcon }: Props) {
|
export default function CustomCheckbox({ label, handleChange, checked, sx, dataCy, colorIcon }: Props) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
control={
|
control={
|
||||||
|
@ -10,10 +10,7 @@ type CustomSliderProps = {
|
|||||||
step?: number;
|
step?: number;
|
||||||
sx?: SxProps<Theme>;
|
sx?: SxProps<Theme>;
|
||||||
onChange?: (_: Event, value: number | number[]) => void;
|
onChange?: (_: Event, value: number | number[]) => void;
|
||||||
onChangeCommitted?: (
|
onChangeCommitted?: (_: React.SyntheticEvent | Event, value: number | number[]) => void;
|
||||||
_: React.SyntheticEvent | Event,
|
|
||||||
value: number | number[]
|
|
||||||
) => void;
|
|
||||||
valueLabelFormat?: (value: number, index: number) => ReactNode;
|
valueLabelFormat?: (value: number, index: number) => ReactNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2,71 +2,70 @@ import { FormControl, TextField as MuiTextField, SxProps, Theme, useTheme } from
|
|||||||
|
|
||||||
import type { InputProps, TextFieldProps } from "@mui/material";
|
import type { InputProps, TextFieldProps } from "@mui/material";
|
||||||
import type { ChangeEvent, FC, FocusEvent, KeyboardEvent } from "react";
|
import type { ChangeEvent, FC, FocusEvent, KeyboardEvent } from "react";
|
||||||
import {Answer} from "@stores/quizView.ts";
|
import { Answer } from "@stores/quizView.ts";
|
||||||
|
|
||||||
|
|
||||||
const TextField = MuiTextField as unknown as FC<TextFieldProps>; // temporary fix ts(2590)
|
const TextField = MuiTextField as unknown as FC<TextFieldProps>; // temporary fix ts(2590)
|
||||||
|
|
||||||
interface CustomTextFieldProps {
|
interface CustomTextFieldProps {
|
||||||
placeholder: string;
|
placeholder: string;
|
||||||
value?: Answer;
|
value?: Answer;
|
||||||
error?: string;
|
error?: string;
|
||||||
onChange?: (event: ChangeEvent<HTMLInputElement>) => void;
|
onChange?: (event: ChangeEvent<HTMLInputElement>) => void;
|
||||||
onKeyDown?: (event: KeyboardEvent<HTMLInputElement>) => void;
|
onKeyDown?: (event: KeyboardEvent<HTMLInputElement>) => void;
|
||||||
onBlur?: (event: FocusEvent<HTMLInputElement>) => void;
|
onBlur?: (event: FocusEvent<HTMLInputElement>) => void;
|
||||||
text?: string;
|
text?: string;
|
||||||
sx?: SxProps<Theme>;
|
sx?: SxProps<Theme>;
|
||||||
InputProps?: Partial<InputProps>;
|
InputProps?: Partial<InputProps>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function CustomTextField({
|
export default function CustomTextField({
|
||||||
placeholder,
|
placeholder,
|
||||||
value,
|
value,
|
||||||
text,
|
text,
|
||||||
sx,
|
sx,
|
||||||
error,
|
error,
|
||||||
onChange,
|
onChange,
|
||||||
onKeyDown,
|
onKeyDown,
|
||||||
onBlur,
|
onBlur,
|
||||||
InputProps,
|
InputProps,
|
||||||
}: CustomTextFieldProps) {
|
}: CustomTextFieldProps) {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FormControl fullWidth variant="standard" sx={{ p: 0 }}>
|
<FormControl fullWidth variant="standard" sx={{ p: 0 }}>
|
||||||
<TextField
|
<TextField
|
||||||
defaultValue={text}
|
defaultValue={text}
|
||||||
fullWidth
|
fullWidth
|
||||||
value={value}
|
value={value}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
error={!!error}
|
error={!!error}
|
||||||
label={error}
|
label={error}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
onKeyDown={onKeyDown}
|
onKeyDown={onKeyDown}
|
||||||
onBlur={onBlur}
|
onBlur={onBlur}
|
||||||
sx={{
|
sx={{
|
||||||
"& .MuiInputBase-root": {
|
"& .MuiInputBase-root": {
|
||||||
backgroundColor: theme.palette.background.default,
|
backgroundColor: theme.palette.background.default,
|
||||||
height: "48px",
|
height: "48px",
|
||||||
borderRadius: "10px",
|
borderRadius: "10px",
|
||||||
},
|
},
|
||||||
"& .MuiInputLabel-root": {
|
"& .MuiInputLabel-root": {
|
||||||
fontSize: "13.5px",
|
fontSize: "13.5px",
|
||||||
marginTop: "3px",
|
marginTop: "3px",
|
||||||
},
|
},
|
||||||
...sx,
|
...sx,
|
||||||
}}
|
}}
|
||||||
InputProps={InputProps}
|
InputProps={InputProps}
|
||||||
inputProps={{
|
inputProps={{
|
||||||
sx: {
|
sx: {
|
||||||
borderRadius: "10px",
|
borderRadius: "10px",
|
||||||
fontSize: "18px",
|
fontSize: "18px",
|
||||||
lineHeight: "21px",
|
lineHeight: "21px",
|
||||||
py: 0,
|
py: 0,
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
data-cy="textfield"
|
data-cy="textfield"
|
||||||
/>
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,15 @@
|
|||||||
import { Skeleton } from "@mui/material";
|
import { Skeleton } from "@mui/material";
|
||||||
|
|
||||||
|
|
||||||
export default function LoadingSkeleton() {
|
export default function LoadingSkeleton() {
|
||||||
|
return (
|
||||||
return (
|
<Skeleton
|
||||||
<Skeleton
|
component="div"
|
||||||
component="div"
|
variant="rectangular"
|
||||||
variant="rectangular"
|
sx={{
|
||||||
sx={{
|
bgcolor: "grey",
|
||||||
bgcolor: "grey",
|
width: "100%",
|
||||||
width: "100%",
|
height: "100%",
|
||||||
height: "100%",
|
}}
|
||||||
}}
|
/>
|
||||||
/>
|
);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
@ -1,26 +1,25 @@
|
|||||||
import { Box, useTheme } from "@mui/material";
|
import { Box, useTheme } from "@mui/material";
|
||||||
interface Props {
|
interface Props {
|
||||||
color?: string;
|
color?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function RadioCheck({ color = "#7E2AEA" }: Props) {
|
export default function RadioCheck({ color = "#7E2AEA" }: Props) {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
|
sx={{
|
||||||
sx={{
|
height: "26px",
|
||||||
height: "26px",
|
width: "26px",
|
||||||
width: "26px",
|
display: "flex",
|
||||||
display: "flex",
|
alignItems: "center",
|
||||||
alignItems: "center",
|
justifyContent: "center",
|
||||||
justifyContent: "center",
|
}}
|
||||||
}}
|
>
|
||||||
>
|
<svg width="26" height="26" viewBox="0 0 26 26" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<svg width="26" height="26" viewBox="0 0 26 26" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<rect x="0.5" y="0.5" width="25" height="25" rx="12.5" fill={color} stroke={color} />
|
||||||
<rect x="0.5" y="0.5" width="25" height="25" rx="12.5" fill={color} stroke={color}/>
|
<rect x="8" y="8" width="10" height="10" rx="5" fill="white" />
|
||||||
<rect x="8" y="8" width="10" height="10" rx="5" fill="white"/>
|
</svg>
|
||||||
</svg>
|
</Box>
|
||||||
</Box>
|
);
|
||||||
);
|
|
||||||
}
|
}
|
@ -1,23 +1,21 @@
|
|||||||
import { Box, useTheme } from "@mui/material";
|
import { Box, useTheme } from "@mui/material";
|
||||||
|
|
||||||
|
|
||||||
export default function RadioIcon() {
|
export default function RadioIcon() {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
|
sx={{
|
||||||
sx={{
|
height: "26px",
|
||||||
height: "26px",
|
width: "26px",
|
||||||
width: "26px",
|
display: "flex",
|
||||||
display: "flex",
|
alignItems: "center",
|
||||||
alignItems: "center",
|
justifyContent: "center",
|
||||||
justifyContent: "center",
|
}}
|
||||||
}}
|
>
|
||||||
>
|
<svg width="26" height="26" viewBox="0 0 26 26" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<svg width="26" height="26" viewBox="0 0 26 26" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<rect x="0.5" y="0.5" width="25" height="25" rx="12.5" fill="#F2F3F7" stroke="#9A9AAF" />
|
||||||
<rect x="0.5" y="0.5" width="25" height="25" rx="12.5" fill="#F2F3F7" stroke="#9A9AAF"/>
|
</svg>
|
||||||
</svg>
|
</Box>
|
||||||
</Box>
|
);
|
||||||
);
|
|
||||||
}
|
}
|
@ -6,11 +6,12 @@ let domain = "https://hbpn.link";
|
|||||||
const currentDomain = location.hostname;
|
const currentDomain = location.hostname;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
currentDomain === "s.hbpn.link"
|
currentDomain === "s.hbpn.link" ||
|
||||||
//Исключение - туризм. Он на стейджинговом квизе и на чужом для публикации домене
|
//Исключение - туризм. Он на стейджинговом квизе и на чужом для публикации домене
|
||||||
|| currentDomain === "tourism.pena.digital"
|
currentDomain === "tourism.pena.digital" ||
|
||||||
|| currentDomain.includes("localhost")
|
currentDomain.includes("localhost") ||
|
||||||
|| currentDomain.includes("127.0.0.1")
|
currentDomain.includes("127.0.0.1")
|
||||||
) domain = "https://s.hbpn.link";
|
)
|
||||||
|
domain = "https://s.hbpn.link";
|
||||||
|
|
||||||
export { domain };
|
export { domain };
|
||||||
|
@ -1,27 +1,26 @@
|
|||||||
import type { QuizTheme } from "@model/settingsData";
|
import type { QuizTheme } from "@model/settingsData";
|
||||||
import { domain } from "./defineDomain";
|
import { domain } from "./defineDomain";
|
||||||
|
|
||||||
|
|
||||||
export const DESIGN_LIST: Record<QuizTheme, string> = {
|
export const DESIGN_LIST: Record<QuizTheme, string> = {
|
||||||
Design1: `${domain}/designs/design1.jpg`,
|
Design1: `${domain}/designs/design1.jpg`,
|
||||||
Design2: `${domain}/designs/design2.jpg`,
|
Design2: `${domain}/designs/design2.jpg`,
|
||||||
Design3: `${domain}/designs/design3.jpg`,
|
Design3: `${domain}/designs/design3.jpg`,
|
||||||
Design4: `${domain}/designs/design4.jpg`,
|
Design4: `${domain}/designs/design4.jpg`,
|
||||||
Design5: `${domain}/designs/design5.jpg`,
|
Design5: `${domain}/designs/design5.jpg`,
|
||||||
Design6: `${domain}/designs/design6.jpg`,
|
Design6: `${domain}/designs/design6.jpg`,
|
||||||
Design7: `${domain}/designs/design7.jpg`,
|
Design7: `${domain}/designs/design7.jpg`,
|
||||||
Design8: `${domain}/designs/design8.jpg`,
|
Design8: `${domain}/designs/design8.jpg`,
|
||||||
Design9: `${domain}/designs/design9.jpg`,
|
Design9: `${domain}/designs/design9.jpg`,
|
||||||
Design10: `${domain}/designs/design10.jpg`,
|
Design10: `${domain}/designs/design10.jpg`,
|
||||||
StandardTheme: ``,
|
StandardTheme: ``,
|
||||||
StandardDarkTheme: ``,
|
StandardDarkTheme: ``,
|
||||||
PinkTheme: ``,
|
PinkTheme: ``,
|
||||||
PinkDarkTheme: ``,
|
PinkDarkTheme: ``,
|
||||||
BlackWhiteTheme: ``,
|
BlackWhiteTheme: ``,
|
||||||
OliveTheme: ``,
|
OliveTheme: ``,
|
||||||
YellowTheme: ``,
|
YellowTheme: ``,
|
||||||
GoldDarkTheme: ``,
|
GoldDarkTheme: ``,
|
||||||
PurpleTheme: ``,
|
PurpleTheme: ``,
|
||||||
BlueTheme: ``,
|
BlueTheme: ``,
|
||||||
BlueDarkTheme: ``,
|
BlueDarkTheme: ``,
|
||||||
};
|
};
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
export const EMAIL_REGEXP =
|
export const EMAIL_REGEXP =
|
||||||
/^(([^<>()[\].,:\s@"]+(\.[^<>()[\].,:\s@"]+)*)|(".+"))@(([^<>()[\].,:\s@"]+\.)+[^<>()[\].,:\s@"]{2,})$/iu;
|
/^(([^<>()[\].,:\s@"]+(\.[^<>()[\].,:\s@"]+)*)|(".+"))@(([^<>()[\].,:\s@"]+\.)+[^<>()[\].,:\s@"]{2,})$/iu;
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user