эмоджи выбирается и отправляется на бек

This commit is contained in:
Nastya 2025-06-20 16:37:04 +03:00
parent 522d8f14a4
commit 2e8325bf00
4 changed files with 65 additions and 53 deletions

@ -107,41 +107,46 @@ export const EmojiVariant = ({
ownPlaceholder,
}: EmojiVariantProps) => {
const { settings } = useQuizStore();
const answers = useQuizViewStore((state) => state.answers);
const { updateAnswer, deleteAnswer } = useQuizViewStore((state) => state);
const { updateAnswer, deleteAnswer, updateOwnVariant, ownVariants } = useQuizViewStore();
const theme = useTheme();
const { t } = useTranslation();
const customEmoji = ownVariants.find((v) => v.id === variant.id)?.variant.extendedText || "";
const onVariantClick = async (event: MouseEvent<HTMLDivElement>) => {
event.preventDefault();
const variantId = variant.id;
if (isMulti) {
const currentAnswer = typeof answer !== "string" ? answer || [] : [];
return updateAnswer(
questionId,
currentAnswer.includes(variantId)
? currentAnswer?.filter((item) => item !== variantId)
: [...currentAnswer, variantId],
variant.points || 0
);
}
updateAnswer(questionId, variant.id, variant.points || 0);
if (answer === variant.id) {
deleteAnswer(questionId);
const currentAnswer = Array.isArray(answer) ? answer : [];
const newAnswer = currentAnswer.includes(variantId)
? currentAnswer.filter((item) => item !== variantId)
: [...currentAnswer, variantId];
updateAnswer(questionId, newAnswer, variant.points || 0);
} else {
if (answer === variant.id) {
deleteAnswer(questionId);
} else {
updateAnswer(questionId, variant.id, variant.points || 0);
}
}
};
const handleEmojiSelect = (emoji: string) => {
// We store custom emoji in ownVariants store, with a specific field to differentiate
const currentOwnAnswer = ownVariants.find((v) => v.id === variant.id)?.variant.answer || "";
updateOwnVariant(variant.id, currentOwnAnswer, emoji);
};
const isSelected = isMulti ? Array.isArray(answer) && answer.includes(variant.id) : answer === variant.id;
return (
<FormControl
key={index}
sx={{
borderRadius: "12px",
border: `1px solid`,
borderColor: answer?.includes(variant.id) ? theme.palette.primary.main : "#9A9AAF",
borderColor: isSelected ? theme.palette.primary.main : "#9A9AAF",
overflow: "hidden",
maxWidth: "317px",
width: "100%",
@ -154,7 +159,6 @@ export const EmojiVariant = ({
: "transparent",
"&:hover": { borderColor: theme.palette.primary.main },
}}
// value={index}
onClick={onVariantClick}
>
<Box
@ -167,7 +171,10 @@ export const EmojiVariant = ({
}}
>
{own ? (
<OwnEmojiPicker emoji={variant.extendedText} />
<OwnEmojiPicker
emoji={customEmoji || variant.extendedText}
onEmojiSelect={handleEmojiSelect}
/>
) : (
<Box
sx={{
@ -222,13 +229,14 @@ export const EmojiVariant = ({
control={
isMulti ? (
<Checkbox
checked={!!answer?.includes(variant.id)}
checked={isSelected}
checkedIcon={<RadioCheck color={theme.palette.primary.main} />}
icon={<RadioIcon />}
sx={{ position: "absolute", top: "-162px", right: "12px" }}
/>
) : (
<Radio
checked={isSelected}
checkedIcon={<RadioCheck color={theme.palette.primary.main} />}
icon={<RadioIcon />}
sx={{ position: "absolute", top: "-162px", right: "12px" }}

@ -13,10 +13,11 @@ type EmojiProps = {
export const Emoji = ({ currentQuestion }: EmojiProps) => {
const answers = useQuizViewStore((state) => state.answers);
const { updateAnswer } = useQuizViewStore((state) => state);
const theme = useTheme();
const { answer } = answers.find(({ questionId }) => questionId === currentQuestion.id) ?? {};
const selectedVariantId = Array.isArray(answer) ? answer[0] : answer;
if (moment.isMoment(answer)) throw new Error("Answer is Moment in Variant question");
return (
@ -30,14 +31,7 @@ export const Emoji = ({ currentQuestion }: EmojiProps) => {
</Typography>
<RadioGroup
name={currentQuestion.id}
value={currentQuestion.content.variants.findIndex(({ id }) => answer === id)}
onChange={({ target }) =>
updateAnswer(
currentQuestion.id,
currentQuestion.content.variants[Number(target.value)].answer,
currentQuestion.content.variants[Number(target.value)].points || 0
)
}
value={selectedVariantId}
sx={{
display: "flex",
flexWrap: "wrap",

@ -30,7 +30,7 @@ interface QuizViewStore {
interface QuizViewActions {
updateAnswer: (questionId: string, answer: string | string[] | Moment, points: number) => void;
deleteAnswer: (questionId: string) => void;
updateOwnVariant: (id: string, answer: string) => void;
updateOwnVariant: (id: string, answer: string, extendedText?: string) => void;
deleteOwnVariant: (id: string) => void;
setCurrentQuizStep: (step: QuizStep) => void;
}
@ -90,7 +90,7 @@ export const createQuizViewStore = () =>
}
);
},
updateOwnVariant(id, answer) {
updateOwnVariant(id, answer, extendedText) {
set(
(state) => {
const index = state.ownVariants.findIndex((variant) => variant.id === id);
@ -101,13 +101,16 @@ export const createQuizViewStore = () =>
variant: {
id: id,
answer,
extendedText: "",
extendedText: extendedText || "",
hints: "",
originalImageUrl: "",
},
});
} else {
state.ownVariants[index].variant.answer = answer;
if (extendedText) {
state.ownVariants[index].variant.extendedText = extendedText;
}
}
},
false,

@ -50,25 +50,17 @@ export async function sendQuestionAnswer(
}
case "emoji": {
if (question.content.multi) {
const answer = questionAnswer.answer;
const ownVariant = Array.isArray(answer)
? ownVariants[ownVariants.findIndex((variant) => answer.some((a: string) => a === variant.id))]?.variant || ""
: ownVariants[ownVariants.findIndex((variant) => variant.id === questionAnswer.answer)]?.variant || "";
const answer = questionAnswer.answer as string[];
let answerString = ``;
if (moment.isMoment(answer)) throw new Error("Answer is Moment in Variant question");
//Оставляем только выбранные варианты
const selectedVariants = question.content.variants.filter((v) => answer.includes(v.id));
let answerString = ``;
selectedVariants.forEach((e) => {
if (e.isOwn) {
if (question.content.own && selectedVariants.some((v) => v.isOwn)) {
answerString += `\`${e.extendedText} ${ownVariant?.answer ?? ""}\`,`;
}
} else {
answerString += `\`${e.extendedText} ${e.answer ?? ""}\`,`;
}
selectedVariants.forEach((variant) => {
const ownVariantData = ownVariants.find((v) => v.id === variant.id)?.variant;
const customEmoji = ownVariantData?.extendedText || "";
const emojiToSend = customEmoji || variant.extendedText;
const textToSend = variant.isOwn ? ownVariantData?.answer || "" : variant.answer;
answerString += `\`${emojiToSend} ${textToSend}\`,`;
});
answerString = answerString.slice(0, -1);
@ -80,12 +72,27 @@ export async function sendQuestionAnswer(
});
}
const variant = question.content.variants.find((v) => v.id === questionAnswer.answer);
if (!variant) throw new Error(`Cannot find variant with id ${questionAnswer.answer} in question ${question.id}`);
// Fallback for old string format for single choice
const answer = questionAnswer.answer as string;
const variant = question.content.variants.find((v) => v.id === answer);
if (!variant) {
// This can happen if the answer is not set, so we don't throw an error, just send empty
return sendAnswer({
questionId: question.id,
body: "",
qid: quizId,
});
}
const ownVariantData = ownVariants.find((v) => v.id === variant.id)?.variant;
const customEmoji = ownVariantData?.extendedText || "";
const emojiToSend = customEmoji || variant.extendedText;
const textToSend = variant.isOwn ? ownVariantData?.answer || "" : variant.answer;
const body = `${emojiToSend} ${textToSend}`.trim();
return sendAnswer({
questionId: question.id,
body: variant.extendedText + " " + variant.answer,
body: body,
qid: quizId,
});
}