components
This commit is contained in:
commit
009a214b40
40 changed files with 966 additions and 0 deletions
3
SurveyFrontend/public/account.svg
Normal file
3
SurveyFrontend/public/account.svg
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
<svg width="52" height="52" viewBox="0 0 52 52" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M12.675 37.05C14.5167 35.6417 16.575 34.5312 18.85 33.7188C21.125 32.9062 23.5084 32.5 26 32.5C28.4917 32.5 30.875 32.9062 33.15 33.7188C35.425 34.5312 37.4834 35.6417 39.325 37.05C40.5889 35.5694 41.573 33.8903 42.2771 32.0125C42.9813 30.1347 43.3334 28.1306 43.3334 26C43.3334 21.1972 41.6452 17.1076 38.2688 13.7312C34.8924 10.3549 30.8028 8.66667 26 8.66667C21.1973 8.66667 17.1077 10.3549 13.7313 13.7312C10.3549 17.1076 8.66671 21.1972 8.66671 26C8.66671 28.1306 9.01879 30.1347 9.72296 32.0125C10.4271 33.8903 11.4112 35.5694 12.675 37.05ZM26 28.1667C23.8695 28.1667 22.073 27.4354 20.6105 25.9729C19.148 24.5104 18.4167 22.7139 18.4167 20.5833C18.4167 18.4528 19.148 16.6562 20.6105 15.1937C22.073 13.7312 23.8695 13 26 13C28.1306 13 29.9271 13.7312 31.3896 15.1937C32.8521 16.6562 33.5834 18.4528 33.5834 20.5833C33.5834 22.7139 32.8521 24.5104 31.3896 25.9729C29.9271 27.4354 28.1306 28.1667 26 28.1667ZM26 47.6667C23.0028 47.6667 20.1862 47.0979 17.55 45.9604C14.9139 44.8229 12.6209 43.2792 10.6709 41.3292C8.72087 39.3792 7.17712 37.0861 6.03962 34.45C4.90212 31.8139 4.33337 28.9972 4.33337 26C4.33337 23.0028 4.90212 20.1861 6.03962 17.55C7.17712 14.9139 8.72087 12.6208 10.6709 10.6708C12.6209 8.72083 14.9139 7.17708 17.55 6.03958C20.1862 4.90208 23.0028 4.33333 26 4.33333C28.9973 4.33333 31.8139 4.90208 34.45 6.03958C37.0862 7.17708 39.3792 8.72083 41.3292 10.6708C43.2792 12.6208 44.823 14.9139 45.9605 17.55C47.098 20.1861 47.6667 23.0028 47.6667 26C47.6667 28.9972 47.098 31.8139 45.9605 34.45C44.823 37.0861 43.2792 39.3792 41.3292 41.3292C39.3792 43.2792 37.0862 44.8229 34.45 45.9604C31.8139 47.0979 28.9973 47.6667 26 47.6667Z" fill="#79747E"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.7 KiB |
3
SurveyFrontend/public/add_circle.svg
Normal file
3
SurveyFrontend/public/add_circle.svg
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
<svg width="28" height="29" viewBox="0 0 28 29" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M12.8334 20.3333H15.1667V15.6667H19.8334V13.3333H15.1667V8.66668H12.8334V13.3333H8.16671V15.6667H12.8334V20.3333ZM14 26.1667C12.3862 26.1667 10.8695 25.8653 9.45004 25.2625C8.0306 24.6403 6.79587 23.8042 5.74587 22.7542C4.69587 21.7042 3.85976 20.4695 3.23754 19.05C2.63476 17.6306 2.33337 16.1139 2.33337 14.5C2.33337 12.8861 2.63476 11.3695 3.23754 9.95001C3.85976 8.53057 4.69587 7.29584 5.74587 6.24584C6.79587 5.19584 8.0306 4.36945 9.45004 3.76668C10.8695 3.14445 12.3862 2.83334 14 2.83334C15.6139 2.83334 17.1306 3.14445 18.55 3.76668C19.9695 4.36945 21.2042 5.19584 22.2542 6.24584C23.3042 7.29584 24.1306 8.53057 24.7334 9.95001C25.3556 11.3695 25.6667 12.8861 25.6667 14.5C25.6667 16.1139 25.3556 17.6306 24.7334 19.05C24.1306 20.4695 23.3042 21.7042 22.2542 22.7542C21.2042 23.8042 19.9695 24.6403 18.55 25.2625C17.1306 25.8653 15.6139 26.1667 14 26.1667ZM14 23.8333C16.6056 23.8333 18.8125 22.9292 20.6209 21.1208C22.4292 19.3125 23.3334 17.1056 23.3334 14.5C23.3334 11.8945 22.4292 9.68751 20.6209 7.87918C18.8125 6.07084 16.6056 5.16668 14 5.16668C11.3945 5.16668 9.18754 6.07084 7.37921 7.87918C5.57087 9.68751 4.66671 11.8945 4.66671 14.5C4.66671 17.1056 5.57087 19.3125 7.37921 21.1208C9.18754 22.9292 11.3945 23.8333 14 23.8333Z" fill="#7D7983"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
3
SurveyFrontend/public/logo.svg
Normal file
3
SurveyFrontend/public/logo.svg
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
<svg width="52" height="52" viewBox="0 0 52 52" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<circle opacity="0.05" cx="26" cy="26" r="26" fill="#222222"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 166 B |
9
SurveyFrontend/src/components/Account/Account.module.css
Normal file
9
SurveyFrontend/src/components/Account/Account.module.css
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
/*Account.module.css*/
|
||||||
|
|
||||||
|
.account {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
width: 52px;
|
||||||
|
height: 52px;
|
||||||
|
margin: 31px 39px 25px 0;
|
||||||
|
}
|
||||||
16
SurveyFrontend/src/components/Account/Account.tsx
Normal file
16
SurveyFrontend/src/components/Account/Account.tsx
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
import React from 'react';
|
||||||
|
import styles from './Account.module.css'
|
||||||
|
|
||||||
|
interface AccountProps {
|
||||||
|
href: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const Account: React.FC<AccountProps> = ({href}) => {
|
||||||
|
return (
|
||||||
|
<a className={styles.account} href={href}>
|
||||||
|
<img src='../../../public/account.svg' alt='Личный кабинет'/>
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Account;
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
/*AddAnswerButton.module.css*/
|
||||||
|
|
||||||
|
.answerButton {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
align-items: center;
|
||||||
|
border: none;
|
||||||
|
background-color: white;
|
||||||
|
color: #3788D6;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.addAnswerImg{
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
import React from "react";
|
||||||
|
import styles from './AddAnswerButton.module.css'
|
||||||
|
|
||||||
|
interface AddAnswerButtonProps {
|
||||||
|
onClick(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const AddAnswerButton: React.FC<AddAnswerButtonProps> = ({onClick}) => {
|
||||||
|
return (
|
||||||
|
<button className={styles.answerButton} onClick={onClick}>
|
||||||
|
Добавить вариант ответа
|
||||||
|
<img className={styles.addAnswerImg} src='../../../public/add_answer.svg' alt=''/>
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AddAnswerButton;
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
/*AddQuestionButton.module.css*/
|
||||||
|
|
||||||
|
.questionButton{
|
||||||
|
background-color: #F6F6F6;
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 600;
|
||||||
|
border: none;
|
||||||
|
margin: 104px auto 80px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.questionButtonImg{
|
||||||
|
vertical-align: middle;
|
||||||
|
margin: 0 auto;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
width: 54px;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
import React from "react";
|
||||||
|
import styles from './AddQuestionButton.module.css'
|
||||||
|
|
||||||
|
interface AddQuestionButtonProps {
|
||||||
|
onClick: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const AddQuestionButton: React.FC<AddQuestionButtonProps> = ({onClick}) => {
|
||||||
|
return (
|
||||||
|
<button className={styles.questionButton} onClick={onClick}>
|
||||||
|
<img className={styles.questionButtonImg} src='../../../public/add_question.svg' alt=''/>
|
||||||
|
Добавить вопрос
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AddQuestionButton;
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*AnswerOption.module.css*/
|
||||||
|
|
||||||
|
.answer{
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
margin-bottom: 17px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.textAnswer{
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 500;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.answerIcon{
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.answerInput{
|
||||||
|
outline: none;
|
||||||
|
border: none;
|
||||||
|
resize: none;
|
||||||
|
}
|
||||||
72
SurveyFrontend/src/components/AnswerOption/AnswerOption.tsx
Normal file
72
SurveyFrontend/src/components/AnswerOption/AnswerOption.tsx
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
import React, {useState, useRef, useEffect} from "react";
|
||||||
|
import styles from'./AnswerOption.module.css';
|
||||||
|
|
||||||
|
interface AnswerOptionProps{
|
||||||
|
src: string;
|
||||||
|
index: number;
|
||||||
|
value: string;
|
||||||
|
onChange: (value: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const AnswerOption: React.FC<AnswerOptionProps> = ({src, index, value, onChange}) => {
|
||||||
|
const [currentValue, setCurrentValue] = useState(value);
|
||||||
|
const [isEditing, setIsEditing] = useState(false); //редактируется ли сейчас
|
||||||
|
|
||||||
|
const textAreaRef = useRef<HTMLTextAreaElement>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setCurrentValue(value);
|
||||||
|
}, [value]);
|
||||||
|
|
||||||
|
const handleSpanClick = () => {
|
||||||
|
setIsEditing(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleTextareaChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
|
||||||
|
setCurrentValue(event.target.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSave = () => {
|
||||||
|
setIsEditing(false);
|
||||||
|
onChange(currentValue); // Отправляем измененное значение родителю
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleKeyDown = (event: React.KeyboardEvent<HTMLTextAreaElement>) => {
|
||||||
|
if (event.key === "Enter") {
|
||||||
|
event.preventDefault(); // Предотвращаем перенос строки в textarea
|
||||||
|
handleSave();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleBlur = () => {
|
||||||
|
handleSave();
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isEditing && textAreaRef.current) {
|
||||||
|
textAreaRef.current.focus();
|
||||||
|
}
|
||||||
|
}, [isEditing]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.answer}>
|
||||||
|
<img className={styles.answerIcon} src={src} alt="" />
|
||||||
|
{isEditing ? (
|
||||||
|
<textarea className={styles.answerInput}
|
||||||
|
ref={textAreaRef}
|
||||||
|
value={currentValue}
|
||||||
|
onChange={handleTextareaChange}
|
||||||
|
onKeyDown={handleKeyDown}
|
||||||
|
onBlur={handleBlur}
|
||||||
|
placeholder={`Ответ ${index}`}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<span className={styles.textAnswer} onClick={handleSpanClick}>
|
||||||
|
{currentValue || `Ответ ${index}`}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AnswerOption;
|
||||||
9
SurveyFrontend/src/components/Header/Header.module.css
Normal file
9
SurveyFrontend/src/components/Header/Header.module.css
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
/*Header.module.css*/
|
||||||
|
|
||||||
|
.header{
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
/*justify-content: space-between;*/
|
||||||
|
}
|
||||||
28
SurveyFrontend/src/components/Header/Header.tsx
Normal file
28
SurveyFrontend/src/components/Header/Header.tsx
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
import React, {useState} from "react";
|
||||||
|
import Logo from "../Logo/Logo.tsx";
|
||||||
|
import Account from "../Account/Account.tsx";
|
||||||
|
import styles from './Header.module.css'
|
||||||
|
import SurveyPagesList from "../SurveyPagesList/SurveyPagesList.tsx";
|
||||||
|
|
||||||
|
interface HeaderProps {}
|
||||||
|
|
||||||
|
const Header: React.FC<HeaderProps> = () => {
|
||||||
|
const [activePage, setActivePage] = useState('Создать опрос');
|
||||||
|
|
||||||
|
const handlePageClick = (name: string)=> {
|
||||||
|
setActivePage(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.header}>
|
||||||
|
<Logo href='' />
|
||||||
|
<SurveyPagesList
|
||||||
|
activePage={activePage}
|
||||||
|
onPageClick = {handlePageClick}
|
||||||
|
/>
|
||||||
|
<Account href='' />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Header;
|
||||||
9
SurveyFrontend/src/components/Logo/Logo.module.css
Normal file
9
SurveyFrontend/src/components/Logo/Logo.module.css
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
/*Logo.module.css*/
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
height: 52px;
|
||||||
|
width: 52px;
|
||||||
|
margin: 31px auto 25px 40px;
|
||||||
|
}
|
||||||
16
SurveyFrontend/src/components/Logo/Logo.tsx
Normal file
16
SurveyFrontend/src/components/Logo/Logo.tsx
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
import React from "react";
|
||||||
|
import styles from './Logo.module.css'
|
||||||
|
|
||||||
|
interface LogoProps {
|
||||||
|
href: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Logo: React.FC<LogoProps> = ({href}) => {
|
||||||
|
return (
|
||||||
|
<a className={styles.logo} href={href}>
|
||||||
|
<img src='../../../public/logo.svg' alt='Логотип'/>
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Logo;
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
.mainPage{
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
background-color: #F6F6F6;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
import Navigation from "../Navigation/Navigation.tsx";
|
||||||
|
import React, {useState} from "react";
|
||||||
|
import styles from './MainComponent.module.css'
|
||||||
|
import Survey from "../Survey/Survey.tsx";
|
||||||
|
|
||||||
|
const MainComponent: React.FC = () => {
|
||||||
|
const [activePage, setActivePage] = useState('Вопросы');
|
||||||
|
|
||||||
|
const handleNavigationClick = (title: string) => {
|
||||||
|
setActivePage(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<main className={styles.mainPage}>
|
||||||
|
<Navigation
|
||||||
|
activePage={activePage}
|
||||||
|
onNavigationClick={handleNavigationClick}
|
||||||
|
/>
|
||||||
|
<Survey />
|
||||||
|
</main>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MainComponent;
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
/*Navigation.module.css*/
|
||||||
|
|
||||||
|
.nav{
|
||||||
|
margin: 34px 0 48px 40px;
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navList{
|
||||||
|
list-style: none;
|
||||||
|
padding: 52px 57px 70px 36px;
|
||||||
|
}
|
||||||
34
SurveyFrontend/src/components/Navigation/Navigation.tsx
Normal file
34
SurveyFrontend/src/components/Navigation/Navigation.tsx
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
import React from 'react'
|
||||||
|
import styles from './Navigation.module.css'
|
||||||
|
import NavigationItem from "../NavigationItem/NavigationItem.tsx";
|
||||||
|
import SaveButton from "../SaveButton/SaveButton.tsx";
|
||||||
|
|
||||||
|
interface NavigationProps {
|
||||||
|
onNavigationClick: (title: string) => void;
|
||||||
|
activePage: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const Navigation: React.FC<NavigationProps> = ({onNavigationClick, activePage}) => {
|
||||||
|
const items: string[] = ['Вопросы', 'Настройки', 'Результаты']
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<nav className={styles.nav}>
|
||||||
|
<ul className={styles.navList}>
|
||||||
|
{items.map(item => (
|
||||||
|
<NavigationItem
|
||||||
|
key={item}
|
||||||
|
title={item}
|
||||||
|
isActive={activePage === item}
|
||||||
|
onClick={() => onNavigationClick(item)}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<SaveButton />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Navigation;
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
/*NavigationItem.module.css*/
|
||||||
|
|
||||||
|
.navItem{
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 24px;
|
||||||
|
color: #AFAFAF;
|
||||||
|
margin-bottom: 42px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.active{
|
||||||
|
text-decoration: underline 2px #556FB7;
|
||||||
|
color: #000000;;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navItem:last-child{
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
import React from 'react'
|
||||||
|
import styles from './NavigationItem.module.css'
|
||||||
|
|
||||||
|
interface NavigationItemProps{
|
||||||
|
title: string;
|
||||||
|
onClick(): void;
|
||||||
|
isActive: boolean; //Дописать для активной ссылки, для класса
|
||||||
|
}
|
||||||
|
|
||||||
|
const NavigationItem: React.FC<NavigationItemProps> = ({title, onClick, isActive}) => {
|
||||||
|
return (
|
||||||
|
<li className={styles.navItem}>
|
||||||
|
<a className={`${styles.page} ${isActive ? styles.active : ''}`} onClick={onClick}>
|
||||||
|
{title}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default NavigationItem;
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
.pagesSurveyItem{
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #2A6DAE;
|
||||||
|
}
|
||||||
|
|
||||||
|
.active{
|
||||||
|
color: #000000;
|
||||||
|
text-decoration: underline;
|
||||||
|
text-decoration-color: #3881C8;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*.pagesSurveyItem {*/
|
||||||
|
/* font-size: 24px;*/
|
||||||
|
/* font-weight: 600;*/
|
||||||
|
/* color: #2A6DAE;*/
|
||||||
|
/* position: relative; !* Necessary for positioning the underline *!*/
|
||||||
|
/* display: inline-block; !* Makes the width only as wide as the content *!*/
|
||||||
|
/*}*/
|
||||||
|
|
||||||
|
/*.active {*/
|
||||||
|
/* color: #000000;*/
|
||||||
|
/*}*/
|
||||||
|
|
||||||
|
/*.active::after {*/
|
||||||
|
/* content: "";*/
|
||||||
|
/* display: block; !* Makes it a block element for width/height control *!*/
|
||||||
|
/* width: 96px;*/
|
||||||
|
/* height: 2px; !* Adjust as needed for the thickness of the underline *!*/
|
||||||
|
/* background-color: #3881C8;*/
|
||||||
|
/* position: absolute;*/
|
||||||
|
/* left: 50%; !* Center horizontally *!*/
|
||||||
|
/* transform: translateX(-50%); !* Corrects the centering *!*/
|
||||||
|
/* bottom: -5px; !* Position 5px below the text *!*/
|
||||||
|
/*}*/
|
||||||
20
SurveyFrontend/src/components/PageSurvey/PageSurvey.tsx
Normal file
20
SurveyFrontend/src/components/PageSurvey/PageSurvey.tsx
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
import React from 'react';
|
||||||
|
import styles from './PageSurvey.module.css';
|
||||||
|
|
||||||
|
interface PageSurveyProps{
|
||||||
|
name: string;
|
||||||
|
isActive: boolean;
|
||||||
|
onClick(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const PageSurvey: React.FC<PageSurveyProps> = ({name, isActive, onClick}) => {
|
||||||
|
return (
|
||||||
|
<li className={styles.pagesSurveyItem}>
|
||||||
|
<a className={`${styles.pageSurvey} ${isActive ? styles.active : ''}`} onClick={onClick}>
|
||||||
|
{name}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PageSurvey;
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
/*QuestionItem.module.css*/
|
||||||
|
|
||||||
|
.questionCard{
|
||||||
|
width: 100%;
|
||||||
|
background-color: white;
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 34px;
|
||||||
|
padding: 27px 29px 26px 36px;
|
||||||
|
border-radius: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.questionCard:last-child{
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.questionContainer{
|
||||||
|
|
||||||
|
}
|
||||||
66
SurveyFrontend/src/components/QuestionItem/QuestionItem.tsx
Normal file
66
SurveyFrontend/src/components/QuestionItem/QuestionItem.tsx
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
import React, {useState} from "react";
|
||||||
|
import AnswerOption from '../AnswerOption/AnswerOption';
|
||||||
|
import AddAnswerButton from "../AddAnswerButton/AddAnswerButton.tsx";
|
||||||
|
import TypeDropdown from "../TypeDropdown/TypeDropdown.tsx";
|
||||||
|
import styles from './QuestionItem.module.css'
|
||||||
|
|
||||||
|
import singleChoiceIcon from '../../../public/radio_button_checked.svg'
|
||||||
|
import multiplyChoiceIcon from '../../../public/check_box.svg'
|
||||||
|
|
||||||
|
interface QuestionItemProps {
|
||||||
|
indexQuestion: number;
|
||||||
|
initialTextQuestion?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QuestionItem: React.FC<QuestionItemProps> = ({indexQuestion, initialTextQuestion = `Вопрос ${indexQuestion}`}) => {
|
||||||
|
const [answerOption, setAnswerOption] = useState(['']);
|
||||||
|
const [questionType] = useState('single');
|
||||||
|
const [textQuestion, setTextQuestion] = useState(initialTextQuestion);
|
||||||
|
|
||||||
|
const handleAddAnswer = () => {
|
||||||
|
setAnswerOption([...answerOption, '']);
|
||||||
|
};
|
||||||
|
|
||||||
|
// const handleTypeChange = (type: string) => {
|
||||||
|
// setQuestionType(type);
|
||||||
|
// }
|
||||||
|
|
||||||
|
const handleAnswerChange = (index: number, value: string) => {
|
||||||
|
const newAnswerOption = [...answerOption];
|
||||||
|
newAnswerOption[index] = value;
|
||||||
|
setAnswerOption(newAnswerOption);
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleQuestionChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
|
||||||
|
setTextQuestion(event.target.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.questionCard}>
|
||||||
|
<div className={styles.questionContainer}>
|
||||||
|
<h2>
|
||||||
|
<textarea
|
||||||
|
value={textQuestion}
|
||||||
|
onChange={handleQuestionChange}
|
||||||
|
/>
|
||||||
|
</h2>
|
||||||
|
{answerOption.map((answerText, index) => (
|
||||||
|
<AnswerOption
|
||||||
|
key={index}
|
||||||
|
index={index + 1} // Индекс ответа
|
||||||
|
value={answerText}
|
||||||
|
src={questionType === "single" ? singleChoiceIcon : multiplyChoiceIcon}
|
||||||
|
onChange={(value) => handleAnswerChange(index, value)}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
|
||||||
|
<AddAnswerButton
|
||||||
|
onClick={handleAddAnswer}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<TypeDropdown/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default QuestionItem;
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
/*QuestionsList.module.css*/
|
||||||
|
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
import React, {useState} from "react";
|
||||||
|
import QuestionItem from "../QuestionItem/QuestionItem.tsx";
|
||||||
|
import AddQuestionButton from "../AddQuestionButton/AddQuestionButton.tsx";
|
||||||
|
|
||||||
|
interface QuestionsListProps {}
|
||||||
|
|
||||||
|
interface Question {
|
||||||
|
id: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QuestionsList: React.FC<QuestionsListProps> = () => {
|
||||||
|
const [questions, setQuestions] = useState<Question[]>([
|
||||||
|
{id: 1},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const handleAddQuestion = () => {
|
||||||
|
// Find the highest ID in the current questions list
|
||||||
|
const maxId = questions.reduce((max, question) => Math.max(max, question.id), 0);
|
||||||
|
const newQuestion: Question = {
|
||||||
|
id: maxId + 1, // Increment the ID
|
||||||
|
};
|
||||||
|
setQuestions([...questions, newQuestion]); // Add the new question to the state
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{questions.map((question, index) => (
|
||||||
|
<QuestionItem
|
||||||
|
key={question.id}
|
||||||
|
indexQuestion={index + 1}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
<AddQuestionButton onClick={handleAddQuestion} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default QuestionsList;
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
/*SaveButton.module.css*/
|
||||||
|
|
||||||
|
.createSurveyButton {
|
||||||
|
/*width: 15%;*/
|
||||||
|
margin-left: 40px;
|
||||||
|
padding: 25px 50.5px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 20px;
|
||||||
|
background-color: #3788D6;
|
||||||
|
color: white;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 24px;
|
||||||
|
text-align: center;
|
||||||
|
box-shadow: 0 0 7.4px 0 rgba(154, 202, 247, 1);
|
||||||
|
}
|
||||||
16
SurveyFrontend/src/components/SaveButton/SaveButton.tsx
Normal file
16
SurveyFrontend/src/components/SaveButton/SaveButton.tsx
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
import React from 'react'
|
||||||
|
import styles from './SaveButton.module.css'
|
||||||
|
|
||||||
|
interface CreateSurveyButtonProps {
|
||||||
|
// onClick(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SaveButton: React.FC<CreateSurveyButtonProps> = ({}) => {
|
||||||
|
return (
|
||||||
|
<button className={styles.createSurveyButton}>
|
||||||
|
Сохранить
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SaveButton;
|
||||||
6
SurveyFrontend/src/components/Survey/Survey.module.css
Normal file
6
SurveyFrontend/src/components/Survey/Survey.module.css
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
/*Survey.module.css*/
|
||||||
|
|
||||||
|
.survey{
|
||||||
|
width: 63%;
|
||||||
|
margin-left: 8.9%;
|
||||||
|
}
|
||||||
15
SurveyFrontend/src/components/Survey/Survey.tsx
Normal file
15
SurveyFrontend/src/components/Survey/Survey.tsx
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
import React from "react";
|
||||||
|
import SurveyInfo from "../SurveyInfo/SurveyInfo.tsx";
|
||||||
|
import QuestionsList from "../QuestionsList/QuestionsList.tsx";
|
||||||
|
import styles from './Survey.module.css'
|
||||||
|
|
||||||
|
const Survey: React.FC = () => {
|
||||||
|
return (
|
||||||
|
<div className={styles.survey}>
|
||||||
|
<SurveyInfo />
|
||||||
|
<QuestionsList />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Survey;
|
||||||
|
|
@ -0,0 +1,73 @@
|
||||||
|
/*SurveyInfo.module.css*/
|
||||||
|
|
||||||
|
.blockInfo{
|
||||||
|
background-color: #ffffff;
|
||||||
|
/*margin: 0;*/
|
||||||
|
padding: 0;
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 34px;
|
||||||
|
margin-bottom: 49px;
|
||||||
|
border-radius: 14px;
|
||||||
|
height: 191px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info{
|
||||||
|
display: block;
|
||||||
|
padding: 35px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.titleSurvey{
|
||||||
|
resize: none;
|
||||||
|
text-align: center;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0 20px;
|
||||||
|
font-size: 40px;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 23px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.textareaTitle{
|
||||||
|
resize: none;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 40px;
|
||||||
|
font-weight: 600;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
border: none;
|
||||||
|
margin-bottom: 23px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description{
|
||||||
|
resize: none;
|
||||||
|
text-align: center;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0 20px;
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.textareaDescrip{
|
||||||
|
resize: none;
|
||||||
|
text-align: center;
|
||||||
|
margin: 0;
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.descripButton{
|
||||||
|
border: none;
|
||||||
|
background-color: #ffffff;
|
||||||
|
display: block;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.descButtonImg{
|
||||||
|
width: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.textButton{
|
||||||
|
vertical-align: center;
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #7D7983;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
87
SurveyFrontend/src/components/SurveyInfo/SurveyInfo.tsx
Normal file
87
SurveyFrontend/src/components/SurveyInfo/SurveyInfo.tsx
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
import React, {useState} from "react";
|
||||||
|
import styles from './SurveyInfo.module.css'
|
||||||
|
|
||||||
|
interface SurveyInfoProps {}
|
||||||
|
|
||||||
|
const SurveyInfo: React.FC<SurveyInfoProps> = () => {
|
||||||
|
const [descriptionSurvey, setDescriptionSurvey] = useState('');
|
||||||
|
const [titleSurvey, setTitleSurvey] = useState('Название опроса');
|
||||||
|
const [showDescriptionField, setShowDescriptionField] = useState(false);
|
||||||
|
const [showNewTitleField, setShowNewTitleField] = useState(false);
|
||||||
|
|
||||||
|
|
||||||
|
const handleDescriptionChange = (descripEvent: React.ChangeEvent<HTMLTextAreaElement>) => {
|
||||||
|
setDescriptionSurvey(descripEvent.target.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleNewTitleChange = (titleEvent: React.ChangeEvent<HTMLTextAreaElement>) => {
|
||||||
|
setTitleSurvey(titleEvent.target.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleAddNewTitleClick = () => {
|
||||||
|
setShowNewTitleField(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleAddDescriptionClick = () => {
|
||||||
|
setShowDescriptionField(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleTitleKeyDown = (titleClickEnter: React.KeyboardEvent<HTMLTextAreaElement>) => {
|
||||||
|
if (titleClickEnter.key === 'Enter'){
|
||||||
|
titleClickEnter.preventDefault();
|
||||||
|
setShowNewTitleField(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDescriptionKeyDown = (descripClickEnter: React.KeyboardEvent<HTMLTextAreaElement>) => {
|
||||||
|
if (descripClickEnter.key === 'Enter'){
|
||||||
|
descripClickEnter.preventDefault();
|
||||||
|
setShowDescriptionField(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleParagraphClick = () => {
|
||||||
|
setShowDescriptionField(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.blockInfo}>
|
||||||
|
<div className={styles.info}>
|
||||||
|
{
|
||||||
|
showNewTitleField ? (
|
||||||
|
<h1 className={styles.titleSurvey}>
|
||||||
|
<textarea className={styles.textareaTitle}
|
||||||
|
value={titleSurvey}
|
||||||
|
onChange={handleNewTitleChange}
|
||||||
|
onKeyDown={handleTitleKeyDown}
|
||||||
|
/>
|
||||||
|
</h1>
|
||||||
|
) : (
|
||||||
|
<h1 className={styles.titleSurvey} onClick={handleAddNewTitleClick}>{titleSurvey}</h1>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
{descriptionSurvey && !showDescriptionField ? (
|
||||||
|
<p className={styles.description} onClick={handleParagraphClick}>{descriptionSurvey}</p>
|
||||||
|
) : showDescriptionField ? (
|
||||||
|
<p className={styles.description}>
|
||||||
|
<textarea className={styles.textareaDescrip}
|
||||||
|
value={descriptionSurvey}
|
||||||
|
onChange={handleDescriptionChange}
|
||||||
|
onKeyDown={handleDescriptionKeyDown}
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
) : (
|
||||||
|
<button
|
||||||
|
className={styles.descripButton}
|
||||||
|
onClick={handleAddDescriptionClick}>
|
||||||
|
<span className={styles.textButton}>Добавить описание</span>
|
||||||
|
<img className={styles.descButtonImg} src='../../../public/add_circle.svg'/>
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SurveyInfo;
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
.listSurveyPages{
|
||||||
|
display: flex;
|
||||||
|
gap: 61px;
|
||||||
|
list-style: none;
|
||||||
|
align-items: center;
|
||||||
|
margin-right: 900px;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
import React from 'react';
|
||||||
|
import styles from './SurveyPagesList.module.css';
|
||||||
|
import PageSurvey from "../PageSurvey/PageSurvey.tsx";
|
||||||
|
|
||||||
|
interface SurveyPagesListProps{
|
||||||
|
activePage: string;
|
||||||
|
onPageClick: (name: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SurveyPagesList: React.FC<SurveyPagesListProps> = ({activePage, onPageClick}) => {
|
||||||
|
const listPages: string[] = ['Создать опрос', 'Мои опросы']
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ul className={styles.listSurveyPages}>
|
||||||
|
{listPages.map((page) => (
|
||||||
|
<PageSurvey
|
||||||
|
key={page}
|
||||||
|
name={page}
|
||||||
|
isActive={activePage === page}
|
||||||
|
onClick={() => onPageClick(page)}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SurveyPagesList;
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*TypeDropdown.module.css*/
|
||||||
|
|
||||||
|
.dropdownContainer {
|
||||||
|
width: 22%;
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdownButton {
|
||||||
|
background-color: #fff;
|
||||||
|
border: 1px solid #000000;
|
||||||
|
border-radius: 19px;
|
||||||
|
padding: 9px 7px 7px 10px;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: 118%;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selectedTypeIcon {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdownArrow {
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdownList {
|
||||||
|
margin-top: 11px;
|
||||||
|
position: absolute;
|
||||||
|
top: 100%;
|
||||||
|
left: 0;
|
||||||
|
background-color: #fff;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 5px 0;
|
||||||
|
list-style: none;
|
||||||
|
/*margin: 0;*/
|
||||||
|
z-index: 1; /* Убедитесь, что список отображается поверх других элементов */
|
||||||
|
width: 100%; /* Занимает всю ширину контейнера */
|
||||||
|
box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdownItem {
|
||||||
|
padding: 10px 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdownItem:hover {
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdownItemIcon {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selectedTypeIcon,
|
||||||
|
.dropdownItemIcon {
|
||||||
|
width: 20px; /* Задайте нужную ширину и высоту */
|
||||||
|
height: 20px;
|
||||||
|
margin-right: 5px;
|
||||||
|
vertical-align: middle; /* Выровняйте значок по вертикали */
|
||||||
|
}
|
||||||
87
SurveyFrontend/src/components/TypeDropdown/TypeDropdown.tsx
Normal file
87
SurveyFrontend/src/components/TypeDropdown/TypeDropdown.tsx
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
import React, { useState, useRef, useEffect } from "react";
|
||||||
|
|
||||||
|
import styles from './TypeDropdown.module.css'
|
||||||
|
|
||||||
|
const single_selected = '../../../public/radio_button_checked.svg';
|
||||||
|
const multiple_selected = '../../../public/check_box.svg';
|
||||||
|
|
||||||
|
|
||||||
|
const TypeDropdown: React.FC = () => {
|
||||||
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
const [selectedType, setSelectedType] = useState('single');
|
||||||
|
const dropdownRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
const handleToggle = () =>{
|
||||||
|
setIsOpen(!isOpen);
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSelect = (value: string) => {
|
||||||
|
setSelectedType(value);
|
||||||
|
setIsOpen(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleClickOutside = (event: MouseEvent) => {
|
||||||
|
if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
|
||||||
|
setIsOpen(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
document.addEventListener("mousedown", handleClickOutside);
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener("mousedown", handleClickOutside);
|
||||||
|
};
|
||||||
|
}, [dropdownRef]);
|
||||||
|
|
||||||
|
const getImage = (typeValue: string, isSelected: boolean): string => {
|
||||||
|
if (typeValue === 'multiply') {
|
||||||
|
return multiple_selected;
|
||||||
|
} else {
|
||||||
|
return single_selected;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.dropdownContainer} ref={dropdownRef}>
|
||||||
|
<button className={styles.dropdownButton} onClick={handleToggle}>
|
||||||
|
<img
|
||||||
|
src={getImage(selectedType, true)}
|
||||||
|
alt={selectedType === "single" ? "Одиночный выбор" : "Множественный выбор"}
|
||||||
|
className={styles.selectedTypeIcon}
|
||||||
|
/>
|
||||||
|
{selectedType === "single" ? "Одиночный выбор" : "Множественный выбор"}
|
||||||
|
<span className={styles.dropdownArrow}>▼</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{isOpen && (
|
||||||
|
<ul className={styles.dropdownList}>
|
||||||
|
<li
|
||||||
|
className={styles.dropdownItem}
|
||||||
|
onClick={() => handleSelect("single")}
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src={getImage("single", selectedType === "single")}
|
||||||
|
alt="Одиночный выбор"
|
||||||
|
className={styles.dropdownItemIcon}
|
||||||
|
/>
|
||||||
|
Одиночный выбор
|
||||||
|
</li>
|
||||||
|
<li
|
||||||
|
className={styles.dropdownItem}
|
||||||
|
onClick={() => handleSelect("multiply")}
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src={getImage("multiply", selectedType === "multiply")}
|
||||||
|
alt="Множественный выбор"
|
||||||
|
className={styles.dropdownItemIcon}
|
||||||
|
/>
|
||||||
|
Множественный выбор
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TypeDropdown;
|
||||||
|
|
||||||
13
SurveyFrontend/src/pages/Questions.tsx
Normal file
13
SurveyFrontend/src/pages/Questions.tsx
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
import Header from '../components/Header/Header.tsx'
|
||||||
|
import MainComponents from '../components/MainComponent/MainComponent.tsx'
|
||||||
|
|
||||||
|
const Questions = () => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Header />
|
||||||
|
<MainComponents />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Questions;
|
||||||
0
SurveyFrontend/src/pages/Results.tsx
Normal file
0
SurveyFrontend/src/pages/Results.tsx
Normal file
0
SurveyFrontend/src/pages/Settings.tsx
Normal file
0
SurveyFrontend/src/pages/Settings.tsx
Normal file
Loading…
Add table
Add a link
Reference in a new issue