From 00dde35812bd7914d144ed970cc736f7519a391c Mon Sep 17 00:00:00 2001 From: aleksandr-raw <104529174+aleksandr-raw@users.noreply.github.com> Date: Tue, 26 Mar 2024 12:26:13 +0400 Subject: [PATCH 1/3] added copy btn to quiz card --- src/pages/createQuize/QuizCard.tsx | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/pages/createQuize/QuizCard.tsx b/src/pages/createQuize/QuizCard.tsx index 8de7c7af..e6ae8bcb 100755 --- a/src/pages/createQuize/QuizCard.tsx +++ b/src/pages/createQuize/QuizCard.tsx @@ -1,5 +1,4 @@ -import { useState, useRef, useLayoutEffect } from "react"; -import ChartIcon from "@icons/ChartIcon"; +import React, { useLayoutEffect, useRef, useState } from "react"; import LinkIcon from "@icons/LinkIcon"; import PencilIcon from "@icons/PencilIcon"; import { Quiz } from "@model/quiz/quiz"; @@ -8,10 +7,10 @@ import { Box, Button, IconButton, + Popover, Typography, useMediaQuery, useTheme, - Popover, } from "@mui/material"; import { deleteQuiz, setEditQuizId } from "@root/quizes/actions"; import { Link, useNavigate } from "react-router-dom"; @@ -19,6 +18,7 @@ import { inCart } from "../../pages/Tariffs/Tariffs"; import { makeRequest } from "@frontend/kitui"; import { enqueueSnackbar } from "notistack"; import { useDomainDefine } from "@utils/hooks/useDomainDefine"; +import CopyIcon from "@icons/CopyIcon"; interface Props { quiz: Quiz; @@ -196,6 +196,12 @@ export default function QuizCard({ }, }} /> */} + + + Date: Tue, 26 Mar 2024 16:52:07 +0400 Subject: [PATCH 2/3] Realized copying and refetch of quizzes by clicking the copy button --- src/pages/createQuize/MyQuizzesFull.tsx | 16 +++++++++++++--- src/pages/createQuize/QuizCard.tsx | 7 ++++++- src/stores/quizes/actions.ts | 17 +++++++++++++++-- src/stores/quizes/hooks.ts | 6 ++++-- 4 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/pages/createQuize/MyQuizzesFull.tsx b/src/pages/createQuize/MyQuizzesFull.tsx index 0932ea27..43c24a80 100644 --- a/src/pages/createQuize/MyQuizzesFull.tsx +++ b/src/pages/createQuize/MyQuizzesFull.tsx @@ -7,12 +7,16 @@ import { useMediaQuery, useTheme, } from "@mui/material"; -import { createQuiz, updateQuiz } from "@root/quizes/actions"; +import { + copyQuiz, + createQuiz, + resetEditConfig, + updateQuiz, +} from "@root/quizes/actions"; import { useQuizes } from "@root/quizes/hooks"; import SectionWrapper from "@ui_kit/SectionWrapper"; import React from "react"; import { useNavigate } from "react-router-dom"; -import { resetEditConfig } from "@root/quizes/actions"; import FirstQuiz from "./FirstQuiz"; import QuizCard from "./QuizCard"; import HeaderFull from "@ui_kit/Header/HeaderFull"; @@ -27,11 +31,16 @@ export default function MyQuizzesFull({ outerContainerSx: sx, children, }: Props) { - const { quizes } = useQuizes(); + const { quizes, refetch } = useQuizes(); const navigate = useNavigate(); const theme = useTheme(); const isMobile = useMediaQuery(theme.breakpoints.down(500)); + const onClickCopy = (value: string) => { + copyQuiz(value); + refetch(); + }; + return ( <> @@ -98,6 +107,7 @@ export default function MyQuizzesFull({ ).toFixed(1) : 0 } + onClickCopy={onClickCopy} /> ); })} diff --git a/src/pages/createQuize/QuizCard.tsx b/src/pages/createQuize/QuizCard.tsx index e6ae8bcb..cf73a6c8 100755 --- a/src/pages/createQuize/QuizCard.tsx +++ b/src/pages/createQuize/QuizCard.tsx @@ -25,6 +25,7 @@ interface Props { openCount?: number; applicationCount?: number; conversionPercent?: number; + onClickCopy: (value: string) => void; } export default function QuizCard({ @@ -32,6 +33,7 @@ export default function QuizCard({ openCount = 0, applicationCount = 0, conversionPercent = 0, + onClickCopy, }: Props) { const theme = useTheme(); const isMobile = useMediaQuery(theme.breakpoints.down(600)); @@ -196,7 +198,10 @@ export default function QuizCard({ }, }} /> */} - + onClickCopy(quiz.id)} + sx={{ borderRadius: "6px", padding: "0 4px" }} + > { }); }; -// TODO copy quiz +export const copyQuiz = async (quizId: string) => + requestQueue.enqueue(`copyQuiz`, async () => { + const quiz = useQuizStore.getState().quizes.find((q) => q.id === quizId); + if (!quiz) return; + + try { + await quizApi.copy(quiz.backendId); + } catch (error) { + devlog("Error copying quiz", error); + + const message = getMessageFromFetchError(error) ?? ""; + enqueueSnackbar(`Не удалось скопировать quiz. ${message}`); + } + }); export const uploadQuizImage = async ( quizId: string, diff --git a/src/stores/quizes/hooks.ts b/src/stores/quizes/hooks.ts index b95ec60d..0ad45066 100644 --- a/src/stores/quizes/hooks.ts +++ b/src/stores/quizes/hooks.ts @@ -7,7 +7,7 @@ import { devlog } from "@frontend/kitui"; import { enqueueSnackbar } from "notistack"; export function useQuizes() { - const { isLoading, error, isValidating } = useSWR( + const { isLoading, error, isValidating, mutate } = useSWR( "quizes", () => quizApi.getList(), { @@ -24,7 +24,9 @@ export function useQuizes() { ); const quizes = useQuizStore((state) => state.quizes); - return { quizes, isLoading, error, isValidating }; + const refetch = () => mutate(); + + return { quizes, isLoading, error, isValidating, refetch }; } export function useCurrentQuiz() { From c87e190706cc208090c8bf560d4819a7adb9d395 Mon Sep 17 00:00:00 2001 From: Nastya Date: Thu, 28 Mar 2024 00:03:46 +0300 Subject: [PATCH 3/3] =?UTF-8?q?=D1=80=D0=B5=D0=B0=D0=BA=D1=82=D0=B8=D0=B2?= =?UTF-8?q?=D0=BD=D0=BE=D1=81=D1=82=D1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/createQuize/MyQuizzesFull.tsx | 3 +-- src/stores/quizes/actions.ts | 13 ++++++++++++- src/stores/quizes/hooks.ts | 6 ++---- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/pages/createQuize/MyQuizzesFull.tsx b/src/pages/createQuize/MyQuizzesFull.tsx index 43c24a80..cb6e9752 100644 --- a/src/pages/createQuize/MyQuizzesFull.tsx +++ b/src/pages/createQuize/MyQuizzesFull.tsx @@ -31,14 +31,13 @@ export default function MyQuizzesFull({ outerContainerSx: sx, children, }: Props) { - const { quizes, refetch } = useQuizes(); + const { quizes } = useQuizes(); const navigate = useNavigate(); const theme = useTheme(); const isMobile = useMediaQuery(theme.breakpoints.down(500)); const onClickCopy = (value: string) => { copyQuiz(value); - refetch(); }; return ( diff --git a/src/stores/quizes/actions.ts b/src/stores/quizes/actions.ts index 92c6bbb8..d3b7edd0 100644 --- a/src/stores/quizes/actions.ts +++ b/src/stores/quizes/actions.ts @@ -249,7 +249,18 @@ export const copyQuiz = async (quizId: string) => if (!quiz) return; try { - await quizApi.copy(quiz.backendId); + const { updated } = await quizApi.copy(quiz.backendId); + let newQuiz = { ...quiz, id: updated }; + + setProducedState( + (state) => { + state.quizes.unshift(quiz); + }, + { + type: "addQuiz", + quiz, + }, + ); } catch (error) { devlog("Error copying quiz", error); diff --git a/src/stores/quizes/hooks.ts b/src/stores/quizes/hooks.ts index 0ad45066..b95ec60d 100644 --- a/src/stores/quizes/hooks.ts +++ b/src/stores/quizes/hooks.ts @@ -7,7 +7,7 @@ import { devlog } from "@frontend/kitui"; import { enqueueSnackbar } from "notistack"; export function useQuizes() { - const { isLoading, error, isValidating, mutate } = useSWR( + const { isLoading, error, isValidating } = useSWR( "quizes", () => quizApi.getList(), { @@ -24,9 +24,7 @@ export function useQuizes() { ); const quizes = useQuizStore((state) => state.quizes); - const refetch = () => mutate(); - - return { quizes, isLoading, error, isValidating, refetch }; + return { quizes, isLoading, error, isValidating }; } export function useCurrentQuiz() {