diff --git a/src/App.tsx b/src/App.tsx index d40933cc..bf1eaa38 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -38,12 +38,12 @@ import { isAxiosError } from "axios"; import RecoverPassword from "./pages/auth/RecoverPassword"; import { InfoPrivilege } from "./pages/InfoPrivilege"; import OutdatedLink from "./pages/auth/OutdatedLink"; -import QuizGallery from "./pages/createQuize/QuizGallery"; import { useAfterpay } from "@utils/hooks/useAfterpay"; import { useUserAccountFetcher } from "@utils/hooks/useUserAccountFetcher"; const MyQuizzesFull = lazy(() => import("./pages/createQuize/MyQuizzesFull")); +const QuizGallery = lazy(() => import("./pages/createQuize/QuizGallery")); const ViewPage = lazy(() => import("./pages/ViewPublicationPage")); const Analytics = lazy(() => import("./pages/Analytics/Analytics")); const EditPage = lazy(() => import("./pages/startPage/EditPage")); @@ -202,7 +202,10 @@ export default function App() { /> } /> - } /> + } />} + /> } />} diff --git a/src/api/quiz.ts b/src/api/quiz.ts index e6d05a3d..c216f362 100644 --- a/src/api/quiz.ts +++ b/src/api/quiz.ts @@ -164,6 +164,24 @@ export const addQuizImages = async ( } }; +export const copyQuizTemplate = async ( + qid: string, +): Promise<[string | null, string?]> => { + try { + const copyQuizTemplateResult = await makeRequest<{ Qid: string }, string>({ + method: "POST", + url: `${API_URL}/quiz/template`, + body: { Qid: qid }, + }); + + return [copyQuizTemplateResult]; + } catch (nativeError) { + const [error] = parseAxiosError(nativeError); + + return [null, `Не удалось скопировать шаблон квиза. ${error}`]; + } +}; + export const quizApi = { create: createQuiz, getList: getQuizList, @@ -172,6 +190,7 @@ export const quizApi = { copy: copyQuiz, delete: deleteQuiz, addImages: addQuizImages, + copyTemplate: copyQuizTemplate, }; const defaultCreateQuizBody: CreateQuizRequest = { diff --git a/src/assets/quiz-templates/quiz-template-1.png b/src/assets/quiz-templates/quiz-template-1.png deleted file mode 100644 index 0703b74a..00000000 Binary files a/src/assets/quiz-templates/quiz-template-1.png and /dev/null differ diff --git a/src/assets/quiz-templates/quiz-template-2.png b/src/assets/quiz-templates/quiz-template-2.png deleted file mode 100644 index f92c8c6b..00000000 Binary files a/src/assets/quiz-templates/quiz-template-2.png and /dev/null differ diff --git a/src/assets/quiz-templates/quiz-template-3.png b/src/assets/quiz-templates/quiz-template-3.png deleted file mode 100644 index 8bb8e8c3..00000000 Binary files a/src/assets/quiz-templates/quiz-template-3.png and /dev/null differ diff --git a/src/assets/quiz-templates/quiz-template-4.png b/src/assets/quiz-templates/quiz-template-4.png deleted file mode 100644 index 11ecf89f..00000000 Binary files a/src/assets/quiz-templates/quiz-template-4.png and /dev/null differ diff --git a/src/assets/quiz-templates/quiz-template-5.png b/src/assets/quiz-templates/quiz-template-5.png deleted file mode 100644 index 4cbde4e2..00000000 Binary files a/src/assets/quiz-templates/quiz-template-5.png and /dev/null differ diff --git a/src/assets/quiz-templates/quiz-template-6.png b/src/assets/quiz-templates/quiz-template-6.png deleted file mode 100644 index 0308e86f..00000000 Binary files a/src/assets/quiz-templates/quiz-template-6.png and /dev/null differ diff --git a/src/assets/quiz-templates/services/service-1.jpg b/src/assets/quiz-templates/services/service-1.jpg new file mode 100644 index 00000000..51a36fb4 Binary files /dev/null and b/src/assets/quiz-templates/services/service-1.jpg differ diff --git a/src/assets/quiz-templates/services/service-10.jpg b/src/assets/quiz-templates/services/service-10.jpg new file mode 100644 index 00000000..a2303dff Binary files /dev/null and b/src/assets/quiz-templates/services/service-10.jpg differ diff --git a/src/assets/quiz-templates/services/service-11.jpg b/src/assets/quiz-templates/services/service-11.jpg new file mode 100644 index 00000000..15111b28 Binary files /dev/null and b/src/assets/quiz-templates/services/service-11.jpg differ diff --git a/src/assets/quiz-templates/services/service-2.jpg b/src/assets/quiz-templates/services/service-2.jpg new file mode 100644 index 00000000..08140977 Binary files /dev/null and b/src/assets/quiz-templates/services/service-2.jpg differ diff --git a/src/assets/quiz-templates/services/service-3.jpg b/src/assets/quiz-templates/services/service-3.jpg new file mode 100644 index 00000000..96b87209 Binary files /dev/null and b/src/assets/quiz-templates/services/service-3.jpg differ diff --git a/src/assets/quiz-templates/services/service-4.jpg b/src/assets/quiz-templates/services/service-4.jpg new file mode 100644 index 00000000..a04654e3 Binary files /dev/null and b/src/assets/quiz-templates/services/service-4.jpg differ diff --git a/src/assets/quiz-templates/services/service-5.jpg b/src/assets/quiz-templates/services/service-5.jpg new file mode 100644 index 00000000..8879f78e Binary files /dev/null and b/src/assets/quiz-templates/services/service-5.jpg differ diff --git a/src/assets/quiz-templates/services/service-6.jpg b/src/assets/quiz-templates/services/service-6.jpg new file mode 100644 index 00000000..aabcbbe4 Binary files /dev/null and b/src/assets/quiz-templates/services/service-6.jpg differ diff --git a/src/assets/quiz-templates/services/service-7.jpg b/src/assets/quiz-templates/services/service-7.jpg new file mode 100644 index 00000000..2abf2b63 Binary files /dev/null and b/src/assets/quiz-templates/services/service-7.jpg differ diff --git a/src/assets/quiz-templates/services/service-8.jpg b/src/assets/quiz-templates/services/service-8.jpg new file mode 100644 index 00000000..20d3bb74 Binary files /dev/null and b/src/assets/quiz-templates/services/service-8.jpg differ diff --git a/src/assets/quiz-templates/services/service-9.jpg b/src/assets/quiz-templates/services/service-9.jpg new file mode 100644 index 00000000..26556403 Binary files /dev/null and b/src/assets/quiz-templates/services/service-9.jpg differ diff --git a/src/assets/quiz-templates/tourism/tourism-1.jpg b/src/assets/quiz-templates/tourism/tourism-1.jpg new file mode 100644 index 00000000..f4c788be Binary files /dev/null and b/src/assets/quiz-templates/tourism/tourism-1.jpg differ diff --git a/src/assets/quiz-templates/tourism/tourism-10.jpg b/src/assets/quiz-templates/tourism/tourism-10.jpg new file mode 100644 index 00000000..c11ab435 Binary files /dev/null and b/src/assets/quiz-templates/tourism/tourism-10.jpg differ diff --git a/src/assets/quiz-templates/tourism/tourism-2.jpg b/src/assets/quiz-templates/tourism/tourism-2.jpg new file mode 100644 index 00000000..c6628bc7 Binary files /dev/null and b/src/assets/quiz-templates/tourism/tourism-2.jpg differ diff --git a/src/assets/quiz-templates/tourism/tourism-3.jpg b/src/assets/quiz-templates/tourism/tourism-3.jpg new file mode 100644 index 00000000..895d366c Binary files /dev/null and b/src/assets/quiz-templates/tourism/tourism-3.jpg differ diff --git a/src/assets/quiz-templates/tourism/tourism-4.jpg b/src/assets/quiz-templates/tourism/tourism-4.jpg new file mode 100644 index 00000000..863b593f Binary files /dev/null and b/src/assets/quiz-templates/tourism/tourism-4.jpg differ diff --git a/src/assets/quiz-templates/tourism/tourism-5.jpg b/src/assets/quiz-templates/tourism/tourism-5.jpg new file mode 100644 index 00000000..86913e09 Binary files /dev/null and b/src/assets/quiz-templates/tourism/tourism-5.jpg differ diff --git a/src/assets/quiz-templates/tourism/tourism-6.jpg b/src/assets/quiz-templates/tourism/tourism-6.jpg new file mode 100644 index 00000000..40912313 Binary files /dev/null and b/src/assets/quiz-templates/tourism/tourism-6.jpg differ diff --git a/src/assets/quiz-templates/tourism/tourism-7.jpg b/src/assets/quiz-templates/tourism/tourism-7.jpg new file mode 100644 index 00000000..25efa443 Binary files /dev/null and b/src/assets/quiz-templates/tourism/tourism-7.jpg differ diff --git a/src/assets/quiz-templates/tourism/tourism-8.jpg b/src/assets/quiz-templates/tourism/tourism-8.jpg new file mode 100644 index 00000000..a76a4437 Binary files /dev/null and b/src/assets/quiz-templates/tourism/tourism-8.jpg differ diff --git a/src/assets/quiz-templates/tourism/tourism-9.jpg b/src/assets/quiz-templates/tourism/tourism-9.jpg new file mode 100644 index 00000000..7db92d83 Binary files /dev/null and b/src/assets/quiz-templates/tourism/tourism-9.jpg differ diff --git a/src/pages/createQuize/QuizGallery/QuizTemplateCard.tsx b/src/pages/createQuize/QuizGallery/QuizTemplateCard.tsx index 04bc43c5..50bae248 100644 --- a/src/pages/createQuize/QuizGallery/QuizTemplateCard.tsx +++ b/src/pages/createQuize/QuizGallery/QuizTemplateCard.tsx @@ -5,25 +5,30 @@ import { enqueueSnackbar } from "notistack"; import { quizApi } from "@/api/quiz"; import { setEditQuizId } from "@root/quizes/actions"; -interface Props { - image: string; - quizId: number; +import type { Template } from "./Template"; + +interface QuizTemplateCardProps { + category: string; + template: Template; } -export default function QuizTemplateCard({ image, quizId }: Props) { +export const QuizTemplateCard = ({ + category, + template: { quizId, title, picture, categoryDescription }, +}: QuizTemplateCardProps) => { const navigate = useNavigate(); const theme = useTheme(); const isTablet = useMediaQuery(theme.breakpoints.down("md")); const copyTemplate = async () => { - try { - const { updated } = await quizApi.copy(quizId); + const [copiedQuizId, copyError] = await quizApi.copyTemplate(quizId); - setEditQuizId(updated); - navigate("/edit"); - } catch { - enqueueSnackbar("Ошибка создания квиза"); + if (copyError || !copiedQuizId) { + return enqueueSnackbar(copyError); } + + setEditQuizId(0); + navigate("/edit"); }; return ( @@ -49,10 +54,8 @@ export default function QuizTemplateCard({ image, quizId }: Props) { - + {categoryDescription && ( + + )} - - Название шаблона + + {title} ); -} +}; diff --git a/src/pages/createQuize/QuizGallery/SearchTemplate.tsx b/src/pages/createQuize/QuizGallery/SearchTemplate.tsx new file mode 100644 index 00000000..2b58e590 --- /dev/null +++ b/src/pages/createQuize/QuizGallery/SearchTemplate.tsx @@ -0,0 +1,21 @@ +import { FormControl } from "@mui/material"; + +import CustomTextField from "@ui_kit/CustomTextField"; + +type SearchTemplateProps = { + searchValue: string; + setSearchValue: (value: string) => void; +}; + +export const SearchTemplate = ({ + searchValue, + setSearchValue, +}: SearchTemplateProps) => ( + + setSearchValue(target.value)} + /> + +); diff --git a/src/pages/createQuize/QuizGallery/SelectCategory.tsx b/src/pages/createQuize/QuizGallery/SelectCategory.tsx new file mode 100644 index 00000000..426c3e3a --- /dev/null +++ b/src/pages/createQuize/QuizGallery/SelectCategory.tsx @@ -0,0 +1,71 @@ +import { FormControl, InputLabel, MenuItem, Select } from "@mui/material"; + +import ArrowDown from "@icons/ArrowDownIcon"; + +import type { CategoryType } from "./Template"; + +const CATEGORIES = [ + { categoryType: "All", category: "Все" }, + { categoryType: "Tourism", category: "Туризм" }, + { categoryType: "Services", category: "Услуги" }, + { categoryType: "RealEstate", category: "Недвижимость" }, + { categoryType: "Auto", category: "Авто" }, + { categoryType: "Health", category: "Здоровье и уход" }, + { categoryType: "Research", category: "Исследовательские" }, + { categoryType: "Production", category: "Производство" }, + { categoryType: "Repair", category: "Ремонт" }, + { categoryType: "Education", category: "Образование" }, +] as const; + +type SelectCategoryProps = { + categoryType: CategoryType | "All"; + setCategoryType: (categoryType: CategoryType) => void; +}; + +export const SelectCategory = ({ + categoryType, + setCategoryType, +}: SelectCategoryProps) => ( + + + Категории + + + +); diff --git a/src/pages/createQuize/QuizGallery/Template.tsx b/src/pages/createQuize/QuizGallery/Template.tsx index f0c69857..f12254d0 100644 --- a/src/pages/createQuize/QuizGallery/Template.tsx +++ b/src/pages/createQuize/QuizGallery/Template.tsx @@ -1,17 +1,37 @@ import { Box, Typography, useTheme, useMediaQuery } from "@mui/material"; -import QuizTemplateCard from "./QuizTemplateCard"; +import { QuizTemplateCard } from "./QuizTemplateCard"; + +export type CategoryType = + | "Tourism" + | "Services" + | "RealEstate" + | "Auto" + | "Health" + | "Research" + | "Production" + | "Repair" + | "Education"; export type Template = { + quizId: string; picture: string; - quizId: number; + title: string; + categoryDescription?: string; +}; + +export type Category = { + category: string; + categoryType: CategoryType; + templates: Template[]; }; type TemplateProps = { - title: string; - items: Template[]; + template: Category; }; -export const Template = ({ title, items }: TemplateProps) => { +export const Template = ({ + template: { category, templates }, +}: TemplateProps) => { const theme = useTheme(); const isSmallMonitor = useMediaQuery(theme.breakpoints.down(1100)); const isTablet = useMediaQuery(theme.breakpoints.down("md")); @@ -21,7 +41,7 @@ export const Template = ({ title, items }: TemplateProps) => { - {title} + {category} { mb: "0px", }} /> - ({items.length}) + ({templates.length}) { justifyContent: isTablet ? "center" : "normal", }} > - {items.map(({ picture, quizId }) => ( - + {templates.map((template) => ( + ))} diff --git a/src/pages/createQuize/QuizGallery/index.tsx b/src/pages/createQuize/QuizGallery/index.tsx index a012ebf9..79fb23a2 100644 --- a/src/pages/createQuize/QuizGallery/index.tsx +++ b/src/pages/createQuize/QuizGallery/index.tsx @@ -1,36 +1,41 @@ -import { useState } from "react"; -import { - Box, - Button, - FormControl, - InputAdornment, - InputLabel, - MenuItem, - Select, - TextField, - Typography, - useTheme, -} from "@mui/material"; +import { useState, useMemo } from "react"; +import { Box, Button, Typography, useTheme } from "@mui/material"; import ComplexNavText from "../ComplexNavText"; -import { TourismTemplate } from "./templates/Tourism"; -import { PoolsTemplate } from "./templates/Polls"; +import { SearchTemplate } from "./SearchTemplate"; +import { SelectCategory } from "./SelectCategory"; +import { TEMPLATES } from "./templates"; +import { Template } from "./Template"; -import SearchIcon from "@icons/SearchIcon"; import SectionWrapper from "@ui_kit/SectionWrapper"; -import ArrowDown from "@icons/ArrowDownIcon"; -const categories = [ - "Категория 1", - "Категория 2", - "Категория 3", - "Категория 4", -] as const; - -type Category = (typeof categories)[number]; +import type { Category, CategoryType } from "./Template"; export default function QuizGallery() { - const theme = useTheme(); - const [category, setCategory] = useState(""); + const [searchValue, setSearchValue] = useState(""); + const [categoryType, setCategoryType] = useState("All"); + + const filteredTemplates = useMemo( + () => + categoryType === "All" + ? TEMPLATES + : TEMPLATES.filter((item) => item.categoryType === categoryType), + [categoryType], + ); + const foundTemplates = useMemo( + () => + filteredTemplates.reduce((total, category) => { + const templates = category.templates.filter(({ title }) => + title.toLowerCase().includes(searchValue.toLowerCase()), + ); + + if (!templates.length) { + return total; + } + + return [...total, { ...category, templates }]; + }, [] as Category[]), + [searchValue, categoryType], + ); return ( - - - - - ), - }} - /> - - - - Категории - - - + + - - + {foundTemplates.map((template) => ( +