Merge branch 'main' into staging
This commit is contained in:
commit
066e622420
24
.gitea/workflows/deployProd.yml
Normal file
24
.gitea/workflows/deployProd.yml
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
name: Deploy
|
||||||
|
run-name: ${{ gitea.actor }} build image and push to container registry
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- "main"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
CreateImage:
|
||||||
|
runs-on: [skeris]
|
||||||
|
uses: https://gitea.pena/PenaDevops/actions.git/.gitea/workflows/build-image.yml@v1.1.6-p
|
||||||
|
with:
|
||||||
|
runner: skeris
|
||||||
|
secrets:
|
||||||
|
REGISTRY_USER: ${{ secrets.REGISTRY_USER }}
|
||||||
|
REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
|
||||||
|
DeployService:
|
||||||
|
runs-on: [frontprod]
|
||||||
|
needs: CreateImage
|
||||||
|
uses: https://gitea.pena/PenaDevops/actions.git/.gitea/workflows/deploy.yml@v1.1.4-p7
|
||||||
|
with:
|
||||||
|
runner: hubprod
|
||||||
|
actionid: ${{ gitea.run_id }}
|
24
.gitea/workflows/deployStaging.yml
Normal file
24
.gitea/workflows/deployStaging.yml
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
name: Deploy
|
||||||
|
run-name: ${{ gitea.actor }} build image and push to container registry
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- "staging"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
CreateImage:
|
||||||
|
runs-on: [hubstaging]
|
||||||
|
uses: http://gitea.pena/PenaDevops/actions.git/.gitea/workflows/build-image.yml@v1.1.6-p
|
||||||
|
with:
|
||||||
|
runner: hubstaging
|
||||||
|
secrets:
|
||||||
|
REGISTRY_USER: ${{ secrets.REGISTRY_USER }}
|
||||||
|
REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
|
||||||
|
DeployService:
|
||||||
|
runs-on: [frontstaging]
|
||||||
|
needs: CreateImage
|
||||||
|
uses: http://gitea.pena/PenaDevops/actions.git/.gitea/workflows/deploy.yml@v1.1.4-p7
|
||||||
|
with:
|
||||||
|
runner: frontstaging
|
||||||
|
actionid: ${{ gitea.run_id }}
|
@ -4,11 +4,11 @@ run-name: ${{ gitea.actor }} produce linting
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- "sdev"
|
- "dev"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
Lint:
|
Lint:
|
||||||
runs-on: [hubstaging]
|
runs-on: [hubstaging]
|
||||||
uses: http://gitea.pena/PenaDevops/actions.git/.gitea/workflows/lint.yml@v1.1.2
|
uses: http://gitea.pena/PenaDevops/actions.git/.gitea/workflows/lint.yml@v1.1.0
|
||||||
with:
|
with:
|
||||||
runner: hubstaging
|
runner: hubstaging
|
||||||
|
1
.npmrc
Normal file
1
.npmrc
Normal file
@ -0,0 +1 @@
|
|||||||
|
@frontend:registry=http://gitea.pena/api/packages/skeris/npm/
|
3
CHANGELOG.md
Normal file
3
CHANGELOG.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
1.0.2 Страничка результатов способна показать историю и правильность ответов для балловго квиза
|
||||||
|
1.0.1 Отображение для баллового квиза на страничке результатов списка
|
||||||
|
1.0.0 Добавлены фичи "мультиответ", "перенос строки в своём ответе", "свой ответ", "плейсхолдер своего ответа"
|
@ -1,16 +1,15 @@
|
|||||||
FROM gitea.pena/penadevops/container-images/node:main as build
|
FROM gitea.pena/penadevops/container-images/node:main as build
|
||||||
|
|
||||||
RUN apk update && rm -rf /var/cache/apk/*
|
|
||||||
WORKDIR /usr/app
|
WORKDIR /usr/app
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
RUN yarn install --ignore-scripts --non-interactive --frozen-lockfile && yarn cache clean
|
RUN npm install --force && yarn cache clean
|
||||||
RUN yarn build
|
RUN npm run build
|
||||||
RUN yarn build:widget
|
RUN npm run build:widget
|
||||||
|
|
||||||
|
|
||||||
FROM gitea.pena/penadevops/container-images/nginx:main as result
|
FROM gitea.pena/penadevops/container-images/nginx:main as result
|
||||||
WORKDIR /usr/share/nginx/html
|
WORKDIR /usr/share/nginx/html
|
||||||
COPY --from=build /usr/app/dist/ /usr/share/nginx/html
|
COPY --from=build /usr/app/dist/ /usr/share/nginx/html
|
||||||
COPY --from=build /usr/app/widget/widget.js /usr/share/nginx/html/export/pub.js
|
COPY --from=build /usr/app/widget/widget.js /usr/share/nginx/html/export/pub.js
|
||||||
|
COPY ./widget_en.js /usr/share/nginx/html/export/pub_en.js
|
||||||
COPY hub.conf /etc/nginx/conf.d/default.conf
|
COPY hub.conf /etc/nginx/conf.d/default.conf
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
version: "3"
|
|
||||||
services:
|
services:
|
||||||
respondent:
|
respondent:
|
||||||
container_name: respondent
|
container_name: respondent
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
image: $CI_REGISTRY_IMAGE/main:$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID
|
image: gitea.pena/squiz/frontanswerer/main:$GITHUB_RUN_NUMBER
|
||||||
hostname: respondent
|
hostname: respondent
|
||||||
tty: true
|
tty: true
|
||||||
|
|
||||||
|
@ -147,6 +147,8 @@ export default function ViewPublicationPage() {
|
|||||||
...extractImageLinksFromQuestion(nextQuestion),
|
...extractImageLinksFromQuestion(nextQuestion),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
console.log(settings.cfg.theme);
|
||||||
|
console.log(quizThemes);
|
||||||
return (
|
return (
|
||||||
<ThemeProvider theme={quizThemes[settings.cfg.theme || "StandardTheme"].theme}>
|
<ThemeProvider theme={quizThemes[settings.cfg.theme || "StandardTheme"].theme}>
|
||||||
<Helmet>
|
<Helmet>
|
||||||
|
@ -14,6 +14,7 @@ type DateProps = {
|
|||||||
|
|
||||||
export default ({ currentQuestion }: DateProps) => {
|
export default ({ currentQuestion }: DateProps) => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
const today = moment();
|
||||||
const isMobile = useRootContainerSize() < 690;
|
const isMobile = useRootContainerSize() < 690;
|
||||||
const { settings } = useQuizSettings();
|
const { settings } = useQuizSettings();
|
||||||
const { updateAnswer } = useQuizViewStore((state) => state);
|
const { updateAnswer } = useQuizViewStore((state) => state);
|
||||||
@ -75,6 +76,7 @@ export default ({ currentQuestion }: DateProps) => {
|
|||||||
<Box>
|
<Box>
|
||||||
<span style={{ marginLeft: "25px", color: theme.palette.text.primary }}>До</span>
|
<span style={{ marginLeft: "25px", color: theme.palette.text.primary }}>До</span>
|
||||||
<DateCalendar
|
<DateCalendar
|
||||||
|
minDate={today}
|
||||||
sx={{
|
sx={{
|
||||||
"& .MuiInputBase-root": {
|
"& .MuiInputBase-root": {
|
||||||
backgroundColor: settings.cfg.design
|
backgroundColor: settings.cfg.design
|
||||||
|
@ -35,41 +35,41 @@ export const Page = ({ currentQuestion }: PageProps) => {
|
|||||||
marginTop: "20px",
|
marginTop: "20px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{currentQuestion.content.useImage ? (
|
{currentQuestion.content.useImage
|
||||||
currentQuestion.content.back && (
|
? currentQuestion.content.back && (
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
borderRadius: "12px",
|
borderRadius: "12px",
|
||||||
border: "1px solid #9A9AAF",
|
border: "1px solid #9A9AAF",
|
||||||
overflow: "hidden",
|
overflow: "hidden",
|
||||||
}}
|
|
||||||
onClick={(event) => event.preventDefault()}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
key={currentQuestion.id}
|
|
||||||
src={currentQuestion.content.back}
|
|
||||||
alt=""
|
|
||||||
style={{
|
|
||||||
display: "block",
|
|
||||||
width: "100%",
|
|
||||||
height: "100%",
|
|
||||||
objectFit: "contain",
|
|
||||||
}}
|
}}
|
||||||
|
onClick={(event) => event.preventDefault()}
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
key={currentQuestion.id}
|
||||||
|
src={currentQuestion.content.back}
|
||||||
|
alt=""
|
||||||
|
style={{
|
||||||
|
display: "block",
|
||||||
|
width: "100%",
|
||||||
|
height: "100%",
|
||||||
|
objectFit: "contain",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
)
|
||||||
|
: currentQuestion.content.video && (
|
||||||
|
<QuizVideo
|
||||||
|
containerSX={{
|
||||||
|
width: "100%",
|
||||||
|
height: "calc(100% - 270px)",
|
||||||
|
maxHeight: "80%",
|
||||||
|
objectFit: "contain",
|
||||||
|
aspectRatio: "16 / 9",
|
||||||
|
}}
|
||||||
|
videoUrl={currentQuestion.content.video}
|
||||||
/>
|
/>
|
||||||
</Box>
|
)}
|
||||||
)
|
|
||||||
) : (
|
|
||||||
<QuizVideo
|
|
||||||
containerSX={{
|
|
||||||
width: "100%",
|
|
||||||
height: "calc(100% - 270px)",
|
|
||||||
maxHeight: "80%",
|
|
||||||
objectFit: "contain",
|
|
||||||
aspectRatio: "16 / 9",
|
|
||||||
}}
|
|
||||||
videoUrl={currentQuestion.content.video}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
@ -0,0 +1,112 @@
|
|||||||
|
import { Box, TextField as MuiTextField, TextFieldProps, Typography, useTheme } from "@mui/material";
|
||||||
|
|
||||||
|
import { Answer, useQuizViewStore } from "@stores/quizView";
|
||||||
|
import { useQuizSettings } from "@contexts/QuizDataContext";
|
||||||
|
import { useRootContainerSize } from "@contexts/RootContainerWidthContext";
|
||||||
|
|
||||||
|
import { quizThemes } from "@utils/themes/Publication/themePublication";
|
||||||
|
|
||||||
|
import type { ChangeEvent, FC } from "react";
|
||||||
|
import type { QuizQuestionText } from "@model/questionTypes/text";
|
||||||
|
|
||||||
|
const TextField = MuiTextField as unknown as FC<TextFieldProps>; // temporary fix ts(2590)
|
||||||
|
|
||||||
|
interface TextSpecialProps {
|
||||||
|
currentQuestion: QuizQuestionText;
|
||||||
|
answer?: Answer;
|
||||||
|
stepNumber?: number | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const TextSpecialHorisontal = ({ currentQuestion, answer, stepNumber }: TextSpecialProps) => {
|
||||||
|
const { settings } = useQuizSettings();
|
||||||
|
const { updateAnswer } = useQuizViewStore((state) => state);
|
||||||
|
const isHorizontal = true;
|
||||||
|
const theme = useTheme();
|
||||||
|
const isMobile = useRootContainerSize() < 650;
|
||||||
|
|
||||||
|
const onInputChange = async ({ target }: ChangeEvent<HTMLInputElement>) => {
|
||||||
|
updateAnswer(currentQuestion.id, target.value, 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: isMobile ? "column" : undefined,
|
||||||
|
alignItems: isMobile ? "center" : undefined,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
width: "100%",
|
||||||
|
marginTop: "20px",
|
||||||
|
flexDirection: "column",
|
||||||
|
alignItems: "center",
|
||||||
|
gap: "20px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography
|
||||||
|
variant="h5"
|
||||||
|
color={theme.palette.text.primary}
|
||||||
|
sx={{ wordBreak: "break-word" }}
|
||||||
|
>
|
||||||
|
{currentQuestion.title}
|
||||||
|
</Typography>
|
||||||
|
{isHorizontal && currentQuestion.content.back && currentQuestion.content.back !== " " && (
|
||||||
|
<Box
|
||||||
|
sx={{ margin: "30px", width: "50vw", maxHeight: "550px" }}
|
||||||
|
onClick={(event) => event.preventDefault()}
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
key={currentQuestion.id}
|
||||||
|
src={currentQuestion.content.back}
|
||||||
|
style={{ width: "100%", height: "100%", objectFit: "cover" }}
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
{
|
||||||
|
<TextField
|
||||||
|
autoFocus={true}
|
||||||
|
multiline
|
||||||
|
maxRows={4}
|
||||||
|
placeholder={currentQuestion.content.placeholder}
|
||||||
|
value={answer || ""}
|
||||||
|
onChange={onInputChange}
|
||||||
|
inputProps={{
|
||||||
|
maxLength: 400,
|
||||||
|
background: settings.cfg.design
|
||||||
|
? quizThemes[settings.cfg.theme].isLight
|
||||||
|
? "#F2F3F7"
|
||||||
|
: "rgba(154,154,175, 0.2)"
|
||||||
|
: "transparent",
|
||||||
|
}}
|
||||||
|
sx={{
|
||||||
|
width: "100%",
|
||||||
|
"& .MuiOutlinedInput-root": {
|
||||||
|
backgroundColor: settings.cfg.design ? "rgba(154,154,175, 0.2)" : "#FFFFFF",
|
||||||
|
},
|
||||||
|
"&:focus-visible": {
|
||||||
|
borderColor: theme.palette.primary.main,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
</Box>
|
||||||
|
{!isHorizontal && currentQuestion.content.back && currentQuestion.content.back !== " " && (
|
||||||
|
<Box
|
||||||
|
sx={{ margin: "15px", width: "40vw" }}
|
||||||
|
onClick={(event) => event.preventDefault()}
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
key={currentQuestion.id}
|
||||||
|
src={currentQuestion.content.back}
|
||||||
|
style={{ width: "100%", height: "100%", objectFit: "cover" }}
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
@ -2,6 +2,7 @@ import { useQuizSettings } from "@contexts/QuizDataContext";
|
|||||||
import { useQuizViewStore } from "@stores/quizView";
|
import { useQuizViewStore } from "@stores/quizView";
|
||||||
import { TextNormal } from "./TextNormal";
|
import { TextNormal } from "./TextNormal";
|
||||||
import { TextSpecial } from "./TextSpecial";
|
import { TextSpecial } from "./TextSpecial";
|
||||||
|
import { TextSpecialHorisontal } from "./TextSpecialHorisontal";
|
||||||
|
|
||||||
import type { QuizQuestionText } from "@model/questionTypes/text";
|
import type { QuizQuestionText } from "@model/questionTypes/text";
|
||||||
|
|
||||||
@ -10,11 +11,21 @@ type TextProps = {
|
|||||||
stepNumber: number | null;
|
stepNumber: number | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const pathOnly = window.location.pathname;
|
||||||
|
|
||||||
export const Text = ({ currentQuestion, stepNumber }: TextProps) => {
|
export const Text = ({ currentQuestion, stepNumber }: TextProps) => {
|
||||||
const { settings } = useQuizSettings();
|
const { settings } = useQuizSettings();
|
||||||
const answers = useQuizViewStore((state) => state.answers);
|
const answers = useQuizViewStore((state) => state.answers);
|
||||||
const { answer } = answers.find(({ questionId }) => questionId === currentQuestion.id) ?? {};
|
const { answer } = answers.find(({ questionId }) => questionId === currentQuestion.id) ?? {};
|
||||||
|
|
||||||
|
if (pathOnly === "/92ed5e3e-8e6a-491e-87d0-d3197682d0e3")
|
||||||
|
return (
|
||||||
|
<TextSpecialHorisontal
|
||||||
|
currentQuestion={currentQuestion}
|
||||||
|
answer={answer}
|
||||||
|
stepNumber={stepNumber}
|
||||||
|
/>
|
||||||
|
);
|
||||||
switch (settings.cfg.spec) {
|
switch (settings.cfg.spec) {
|
||||||
case true:
|
case true:
|
||||||
return (
|
return (
|
||||||
|
@ -16,6 +16,7 @@ export type QuizTheme =
|
|||||||
| "PinkTheme"
|
| "PinkTheme"
|
||||||
| "PinkDarkTheme"
|
| "PinkDarkTheme"
|
||||||
| "BlackWhiteTheme"
|
| "BlackWhiteTheme"
|
||||||
|
| "crutch_FurnitureABC"
|
||||||
| "OliveTheme"
|
| "OliveTheme"
|
||||||
| "YellowTheme"
|
| "YellowTheme"
|
||||||
| "GoldDarkTheme"
|
| "GoldDarkTheme"
|
||||||
|
@ -12,6 +12,7 @@ export const DESIGN_LIST: Record<QuizTheme, string> = {
|
|||||||
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`,
|
||||||
|
crutch_FurnitureABC: `${domain}/designs/crutch_FurnitureABC.jpg`,
|
||||||
StandardTheme: ``,
|
StandardTheme: ``,
|
||||||
StandardDarkTheme: ``,
|
StandardDarkTheme: ``,
|
||||||
PinkTheme: ``,
|
PinkTheme: ``,
|
||||||
|
@ -136,7 +136,7 @@ export function sendQuestionAnswer(
|
|||||||
|
|
||||||
return sendAnswer({
|
return sendAnswer({
|
||||||
questionId: question.id,
|
questionId: question.id,
|
||||||
body: JSON.stringify(body),
|
body: `\`${JSON.stringify(body)}\``,
|
||||||
qid: quizId,
|
qid: quizId,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -235,6 +235,27 @@ const BlueDarkTheme = createTheme({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const crutch_FurnitureABC = createTheme({
|
||||||
|
...themePublic,
|
||||||
|
palette: {
|
||||||
|
primary: {
|
||||||
|
main: "#F2B133",
|
||||||
|
dark: "#E6A11C",
|
||||||
|
},
|
||||||
|
secondary: {
|
||||||
|
main: "#252734",
|
||||||
|
},
|
||||||
|
text: {
|
||||||
|
primary: "#FFFFFF",
|
||||||
|
secondary: "#F2B133",
|
||||||
|
},
|
||||||
|
|
||||||
|
background: {
|
||||||
|
default: "#333647",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const Design1 = createTheme({
|
const Design1 = createTheme({
|
||||||
...themePublic,
|
...themePublic,
|
||||||
palette: {
|
palette: {
|
||||||
@ -457,6 +478,7 @@ export const quizThemes: Record<QuizTheme, { theme: Theme; isLight: boolean }> =
|
|||||||
PurpleTheme: { theme: PurpleTheme, isLight: true },
|
PurpleTheme: { theme: PurpleTheme, isLight: true },
|
||||||
BlueTheme: { theme: BlueTheme, isLight: true },
|
BlueTheme: { theme: BlueTheme, isLight: true },
|
||||||
BlueDarkTheme: { theme: BlueDarkTheme, isLight: false },
|
BlueDarkTheme: { theme: BlueDarkTheme, isLight: false },
|
||||||
|
crutch_FurnitureABC: { theme: crutch_FurnitureABC, isLight: false },
|
||||||
Design1: { theme: Design1, isLight: false },
|
Design1: { theme: Design1, isLight: false },
|
||||||
Design2: { theme: Design2, isLight: false },
|
Design2: { theme: Design2, isLight: false },
|
||||||
Design3: { theme: Design3, isLight: true },
|
Design3: { theme: Design3, isLight: true },
|
||||||
|
7406
package-lock.json
generated
Normal file
7406
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@frontend/squzanswerer",
|
"name": "@frontend/squzanswerer",
|
||||||
"version": "1.0.57",
|
"version": "1.0.61",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist-package/index.js",
|
"main": "./dist-package/index.js",
|
||||||
"module": "./dist-package/index.js",
|
"module": "./dist-package/index.js",
|
||||||
|
BIN
public/designs/crutch_FurnitureABC.jpg
Normal file
BIN
public/designs/crutch_FurnitureABC.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 419 KiB |
47250
widget_en.js
Normal file
47250
widget_en.js
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user