corrected components

This commit is contained in:
Tatiana Nikolaeva 2025-04-05 11:24:07 +05:00
parent a27087d681
commit 1bc96d830e
33 changed files with 618 additions and 247 deletions

View file

@ -1,42 +1,3 @@
#root {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
text-align: center;
}
.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: filter 300ms;
}
.logo:hover {
filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.react:hover {
filter: drop-shadow(0 0 2em #61dafbaa);
}
@keyframes logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
@media (prefers-reduced-motion: no-preference) {
a:nth-of-type(2) .logo {
animation: logo-spin infinite 20s linear;
}
}
.card {
padding: 2em;
}
.read-the-docs {
color: #888;
}
body{
width: 100%;
}

View file

@ -1,35 +1,11 @@
import { useState } from 'react'
import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
// import { useState } from 'react'
import './App.css'
import Questions from "./pages/Questions.tsx";
function App() {
const [count, setCount] = useState(0)
return (
<>
<div>
<a href="https://vite.dev" target="_blank">
<img src={viteLogo} className="logo" alt="Vite logo" />
</a>
<a href="https://react.dev" target="_blank">
<img src={reactLogo} className="logo react" alt="React logo" />
</a>
</div>
<h1>Vite + React</h1>
<div className="card">
<button onClick={() => setCount((count) => count + 1)}>
count is {count}
</button>
<p>
Edit <code>src/App.tsx</code> and save to test HMR
</p>
</div>
<p className="read-the-docs">
Click on the Vite and React logos to learn more
</p>
</>
)
const App: React.FC = () => {
return (
<Questions />
);
}
export default App

View file

@ -1,9 +1,10 @@
/*Account.module.css*/
.account {
margin: 0;
padding: 0;
width: 52px;
height: 52px;
margin: 31px 39px 25px 0;
}
.accountImg{
width: 55px;
}

View file

@ -1,15 +1,21 @@
/// <reference types="vite-plugin-svgr/client" />
import React from 'react';
import styles from './Account.module.css'
import AccountSvg from '../../../public/account.svg?react'
interface AccountProps {
href: string
href: string;
user: string;
}
const Account: React.FC<AccountProps> = ({href}) => {
const Account: React.FC<AccountProps> = ({href, user}) => {
return (
<a className={styles.account} href={href}>
<img src='../../../public/account.svg' alt='Личный кабинет'/>
</a>
<div>
<a className={styles.account} href={href}>
<AccountSvg className={styles.accountImg}/>
{user}
</a>
</div>
);
};

View file

@ -1,6 +1,8 @@
import React from "react";
import styles from './AddAnswerButton.module.css'
import AddAnswerSvg from '../../../public/add_answer.svg?react'
interface AddAnswerButtonProps {
onClick(): void;
}
@ -9,7 +11,7 @@ const AddAnswerButton: React.FC<AddAnswerButtonProps> = ({onClick}) => {
return (
<button className={styles.answerButton} onClick={onClick}>
Добавить вариант ответа
<img className={styles.addAnswerImg} src='../../../public/add_answer.svg' alt=''/>
<AddAnswerSvg className={styles.addAnswerImg} />
</button>
);
};

View file

@ -1,5 +1,6 @@
import React from "react";
import styles from './AddQuestionButton.module.css'
import AddQuestionSvg from '../../../public/add_question.svg?react'
interface AddQuestionButtonProps {
onClick: () => void;
@ -8,7 +9,7 @@ interface AddQuestionButtonProps {
const AddQuestionButton: React.FC<AddQuestionButtonProps> = ({onClick}) => {
return (
<button className={styles.questionButton} onClick={onClick}>
<img className={styles.questionButtonImg} src='../../../public/add_question.svg' alt=''/>
<AddQuestionSvg className={styles.questionButtonImg} />
Добавить вопрос
</button>
);

View file

@ -50,6 +50,7 @@ const AnswerOption: React.FC<AnswerOptionProps> = ({src, index, value, onChange}
return (
<div className={styles.answer}>
{/*<div className={styles.answerIconContainer}> <Icon className={styles.answerIcon}/></div>*/}
<img className={styles.answerIcon} src={src} alt="" />
{isEditing ? (
<textarea className={styles.answerInput}
@ -61,9 +62,9 @@ const AnswerOption: React.FC<AnswerOptionProps> = ({src, index, value, onChange}
placeholder={`Ответ ${index}`}
/>
) : (
<span className={styles.textAnswer} onClick={handleSpanClick}>
{currentValue || `Ответ ${index}`}
</span>
<button className={styles.textAnswer} onClick={handleSpanClick}>
{currentValue || `Ответ ${index}`}
</button>
)}
</div>
);

View file

@ -5,5 +5,4 @@
padding: 0;
width: 100%;
display: flex;
/*justify-content: space-between;*/
}

View file

@ -20,7 +20,10 @@ const Header: React.FC<HeaderProps> = () => {
activePage={activePage}
onPageClick = {handlePageClick}
/>
<Account href='' />
<Account
href=''
user='Иванов Иван'
/>
</div>
);
};

View file

@ -1,7 +1,6 @@
/*Logo.module.css*/
.logo {
margin: 0;
padding: 0;
height: 52px;
width: 52px;

View file

@ -1,5 +1,6 @@
import React from "react";
import styles from './Logo.module.css'
import LogoSvg from '../../../public/logo.svg?react'
interface LogoProps {
href: string;
@ -8,7 +9,7 @@ interface LogoProps {
const Logo: React.FC<LogoProps> = ({href}) => {
return (
<a className={styles.logo} href={href}>
<img src='../../../public/logo.svg' alt='Логотип'/>
<LogoSvg />
</a>
);
};

View file

@ -9,7 +9,7 @@
.active{
text-decoration: underline 2px #556FB7;
color: #000000;;
color: #000000;
}
.navItem:last-child{

View file

@ -10,9 +10,9 @@ interface NavigationItemProps{
const NavigationItem: React.FC<NavigationItemProps> = ({title, onClick, isActive}) => {
return (
<li className={styles.navItem}>
<a className={`${styles.page} ${isActive ? styles.active : ''}`} onClick={onClick}>
<button className={`${styles.page} ${isActive ? styles.active : ''}`} onClick={onClick}>
{title}
</a>
</button>
</li>
);
};

View file

@ -9,28 +9,4 @@
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 *!*/
/*}*/
}

View file

@ -10,9 +10,9 @@ interface PageSurveyProps{
const PageSurvey: React.FC<PageSurveyProps> = ({name, isActive, onClick}) => {
return (
<li className={styles.pagesSurveyItem}>
<a className={`${styles.pageSurvey} ${isActive ? styles.active : ''}`} onClick={onClick}>
<button className={`${styles.pageSurvey} ${isActive ? styles.active : ''}`} onClick={onClick}>
{name}
</a>
</button>
</li>
);
};

View file

@ -12,7 +12,3 @@
.questionCard:last-child{
margin-bottom: 0;
}
.questionContainer{
}

View file

@ -4,8 +4,9 @@ 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'
import SingleChoiceIcon from '../../../public/radio_button_checked.svg?react';
import MultiplyChoiceIcon from '../../../public/check_box.svg?react';
interface QuestionItemProps {
indexQuestion: number;
@ -21,10 +22,6 @@ const QuestionItem: React.FC<QuestionItemProps> = ({indexQuestion, initialTextQu
setAnswerOption([...answerOption, '']);
};
// const handleTypeChange = (type: string) => {
// setQuestionType(type);
// }
const handleAnswerChange = (index: number, value: string) => {
const newAnswerOption = [...answerOption];
newAnswerOption[index] = value;
@ -47,9 +44,9 @@ const QuestionItem: React.FC<QuestionItemProps> = ({indexQuestion, initialTextQu
{answerOption.map((answerText, index) => (
<AnswerOption
key={index}
src={questionType === "single" ? <SingleChoiceIcon /> : <MultiplyChoiceIcon />}
index={index + 1} // Индекс ответа
value={answerText}
src={questionType === "single" ? singleChoiceIcon : multiplyChoiceIcon}
onChange={(value) => handleAnswerChange(index, value)}
/>
))}

View file

@ -1,7 +1,6 @@
/*SaveButton.module.css*/
.createSurveyButton {
/*width: 15%;*/
margin-left: 40px;
padding: 25px 50.5px;
border: none;

View file

@ -5,7 +5,7 @@ interface CreateSurveyButtonProps {
// onClick(): void;
}
const SaveButton: React.FC<CreateSurveyButtonProps> = ({}) => {
const SaveButton: React.FC<CreateSurveyButtonProps> = () => {
return (
<button className={styles.createSurveyButton}>
Сохранить

View file

@ -2,7 +2,6 @@
.blockInfo{
background-color: #ffffff;
/*margin: 0;*/
padding: 0;
width: 100%;
margin-top: 34px;

View file

@ -1,5 +1,6 @@
import React, {useState} from "react";
import styles from './SurveyInfo.module.css'
import DescripButtonSvg from '../../../public/add_circle.svg?react'
interface SurveyInfoProps {}
@ -44,6 +45,37 @@ const SurveyInfo: React.FC<SurveyInfoProps> = () => {
setShowDescriptionField(true);
}
const renderDescription = ()=> {
if (descriptionSurvey && !showDescriptionField) {
return (
<button className={styles.description} onClick={handleParagraphClick}>
<p>{descriptionSurvey}</p>
</button>
);
} else if (showDescriptionField) {
return (
<p className={styles.description}>
<textarea
className={styles.textareaDescrip}
value={descriptionSurvey}
onChange={handleDescriptionChange}
onKeyDown={handleDescriptionKeyDown}
/>
</p>
);
} else {
return (
<button
className={styles.descripButton}
onClick={handleAddDescriptionClick}
>
<span className={styles.textButton}>Добавить описание</span>
<DescripButtonSvg className={styles.descButtonImg}/>
</button>
);
}
}
return (
<div className={styles.blockInfo}>
<div className={styles.info}>
@ -57,28 +89,14 @@ const SurveyInfo: React.FC<SurveyInfoProps> = () => {
/>
</h1>
) : (
<h1 className={styles.titleSurvey} onClick={handleAddNewTitleClick}>{titleSurvey}</h1>
<button className={styles.titleSurvey} onClick={handleAddNewTitleClick}>
<h1>{titleSurvey}</h1>
</button>
)
}
{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>
)}
{renderDescription()}
</div>
</div>
);

View file

@ -39,7 +39,6 @@
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);

View file

@ -33,7 +33,7 @@ const TypeDropdown: React.FC = () => {
};
}, [dropdownRef]);
const getImage = (typeValue: string, isSelected: boolean): string => {
const getImage = (typeValue: string): string => {
if (typeValue === 'multiply') {
return multiple_selected;
} else {
@ -45,7 +45,7 @@ const TypeDropdown: React.FC = () => {
<div className={styles.dropdownContainer} ref={dropdownRef}>
<button className={styles.dropdownButton} onClick={handleToggle}>
<img
src={getImage(selectedType, true)}
src={getImage(selectedType)}
alt={selectedType === "single" ? "Одиночный выбор" : "Множественный выбор"}
className={styles.selectedTypeIcon}
/>
@ -55,27 +55,26 @@ const TypeDropdown: React.FC = () => {
{isOpen && (
<ul className={styles.dropdownList}>
<li
className={styles.dropdownItem}
onClick={() => handleSelect("single")}
>
<li>
<button onClick={() => handleSelect("single")}
className={styles.dropdownItem}>
<img
src={getImage("single", selectedType === "single")}
alt="Одиночный выбор"
className={styles.dropdownItemIcon}
/>
src={getImage("single")}
alt=""/>{' '}
Одиночный выбор
</button>
</li>
<li
className={styles.dropdownItem}
onClick={() => handleSelect("multiply")}
>
<img
src={getImage("multiply", selectedType === "multiply")}
alt="Множественный выбор"
className={styles.dropdownItemIcon}
/>
Множественный выбор
<li>
<button className={styles.dropdownItem}
onClick={() => handleSelect("multiply")}>
<img
src={getImage("multiply")}
alt="Множественный выбор"
className={styles.dropdownItemIcon}
/>{' '}
Множественный выбор
</button>
</li>
</ul>
)}

View file

@ -1,68 +0,0 @@
:root {
font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;
color-scheme: light dark;
color: rgba(255, 255, 255, 0.87);
background-color: #242424;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}
body {
margin: 0;
display: flex;
place-items: center;
min-width: 320px;
min-height: 100vh;
}
h1 {
font-size: 3.2em;
line-height: 1.1;
}
button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
background-color: #1a1a1a;
cursor: pointer;
transition: border-color 0.25s;
}
button:hover {
border-color: #646cff;
}
button:focus,
button:focus-visible {
outline: 4px auto -webkit-focus-ring-color;
}
@media (prefers-color-scheme: light) {
:root {
color: #213547;
background-color: #ffffff;
}
a:hover {
color: #747bff;
}
button {
background-color: #f9f9f9;
}
}

5
SurveyFrontend/src/svg.d.ts vendored Normal file
View file

@ -0,0 +1,5 @@
declare module "*.svg" {
import React from 'react';
const ReactComponent: React.FC<React.SVGProps<SVGSVGElement>>;
export default ReactComponent;
}