routing
This commit is contained in:
parent
eda38247ba
commit
28882e7038
10 changed files with 190 additions and 33 deletions
61
SurveyFrontend/package-lock.json
generated
61
SurveyFrontend/package-lock.json
generated
|
|
@ -11,6 +11,7 @@
|
||||||
"@formkit/tempo": "^0.1.2",
|
"@formkit/tempo": "^0.1.2",
|
||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
"react-dom": "^19.0.0",
|
"react-dom": "^19.0.0",
|
||||||
|
"react-router-dom": "^7.5.2",
|
||||||
"uuid": "^11.1.0"
|
"uuid": "^11.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
@ -1731,6 +1732,15 @@
|
||||||
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
|
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/cookie": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/cross-spawn": {
|
"node_modules/cross-spawn": {
|
||||||
"version": "7.0.6",
|
"version": "7.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||||
|
|
@ -2626,6 +2636,45 @@
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-router": {
|
||||||
|
"version": "7.5.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-router/-/react-router-7.5.2.tgz",
|
||||||
|
"integrity": "sha512-9Rw8r199klMnlGZ8VAsV/I8WrIF6IyJ90JQUdboupx1cdkgYqwnrYjH+I/nY/7cA1X5zia4mDJqH36npP7sxGQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"cookie": "^1.0.1",
|
||||||
|
"set-cookie-parser": "^2.6.0",
|
||||||
|
"turbo-stream": "2.4.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=18",
|
||||||
|
"react-dom": ">=18"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"react-dom": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/react-router-dom": {
|
||||||
|
"version": "7.5.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.5.2.tgz",
|
||||||
|
"integrity": "sha512-yk1XW8Fj7gK7flpYBXF3yzd2NbX6P7Kxjvs2b5nu1M04rb5pg/Zc4fGdBNTeT4eDYL2bvzWNyKaIMJX/RKHTTg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"react-router": "7.5.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=18",
|
||||||
|
"react-dom": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/resolve-from": {
|
"node_modules/resolve-from": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
|
||||||
|
|
@ -2720,6 +2769,12 @@
|
||||||
"semver": "bin/semver.js"
|
"semver": "bin/semver.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/set-cookie-parser": {
|
||||||
|
"version": "2.7.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz",
|
||||||
|
"integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/shebang-command": {
|
"node_modules/shebang-command": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||||
|
|
@ -2798,6 +2853,12 @@
|
||||||
"typescript": ">=4.8.4"
|
"typescript": ">=4.8.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/turbo-stream": {
|
||||||
|
"version": "2.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/turbo-stream/-/turbo-stream-2.4.0.tgz",
|
||||||
|
"integrity": "sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
"node_modules/type-check": {
|
"node_modules/type-check": {
|
||||||
"version": "0.4.0",
|
"version": "0.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
"@formkit/tempo": "^0.1.2",
|
"@formkit/tempo": "^0.1.2",
|
||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
"react-dom": "^19.0.0",
|
"react-dom": "^19.0.0",
|
||||||
|
"react-router-dom": "^7.5.2",
|
||||||
"uuid": "^11.1.0"
|
"uuid": "^11.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,22 @@
|
||||||
import React from 'react';
|
|
||||||
import './App.css'
|
import './App.css'
|
||||||
import Questions from './pages/Questions.tsx'
|
import {BrowserRouter, Navigate, Route, Routes} from "react-router-dom";
|
||||||
|
import {SurveyEditingPage} from "./pages/SurveyEditingPage/SurveyEditingPage.tsx";
|
||||||
|
import Survey from "./components/Survey/Survey.tsx";
|
||||||
|
import SettingSurvey from "./components/SettingSurvey/SettingSurvey.tsx";
|
||||||
|
|
||||||
const App: React.FC = () => {
|
const App = () => {
|
||||||
return (
|
return(
|
||||||
<Questions />
|
<BrowserRouter>
|
||||||
)
|
<Routes>
|
||||||
|
<Route path="/" element={<Navigate to="/survey/edit/questions" replace />} />
|
||||||
|
|
||||||
|
<Route path="survey/edit" element={<SurveyEditingPage />}>
|
||||||
|
<Route path="questions" element={<Survey />} />
|
||||||
|
<Route path="settings" element={<SettingSurvey />} />
|
||||||
|
</Route>
|
||||||
|
</Routes>
|
||||||
|
</BrowserRouter>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,3 +6,38 @@
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pagesNav{
|
||||||
|
display: flex;
|
||||||
|
gap: 60px;
|
||||||
|
list-style: none;
|
||||||
|
align-items: center;
|
||||||
|
margin-right: 40%;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.pageLink{
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #2A6DAE;
|
||||||
|
padding: 0;
|
||||||
|
border: none;
|
||||||
|
background-color: #ffffff;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.active{
|
||||||
|
margin-bottom: -15px;
|
||||||
|
color: #000000;
|
||||||
|
text-decoration-color: #3881C8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activeLine{
|
||||||
|
display: block;
|
||||||
|
margin-top: 5px;
|
||||||
|
border: 1px solid #000000;
|
||||||
|
width: 50%;
|
||||||
|
padding: 0;
|
||||||
|
box-shadow: 0 1px 4px 0 #3881C8;
|
||||||
|
}
|
||||||
|
|
@ -1,27 +1,33 @@
|
||||||
import React, {useState} from "react";
|
import React from "react";
|
||||||
import Logo from "../Logo/Logo.tsx";
|
import Logo from "../Logo/Logo.tsx";
|
||||||
import Account from "../Account/Account.tsx";
|
import Account from "../Account/Account.tsx";
|
||||||
import styles from './Header.module.css'
|
import styles from './Header.module.css'
|
||||||
import SurveyPagesList from "../SurveyPagesList/SurveyPagesList.tsx";
|
import {Link, useLocation} from "react-router-dom";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const Header: React.FC = () => {
|
const Header: React.FC = () => {
|
||||||
const [activePage, setActivePage] = useState('Создать опрос');
|
const location = useLocation();
|
||||||
|
const isCreateSurveyActive = location.pathname.includes('/survey/edit');
|
||||||
const handlePageClick = (name: string)=> {
|
const isMySurveyActive = location.pathname === '/my-surveys';
|
||||||
setActivePage(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.header}>
|
<div className={styles.header}>
|
||||||
<Logo href='' />
|
<Logo href='/' />
|
||||||
<SurveyPagesList
|
<nav className={styles.pagesNav}>
|
||||||
activePage={activePage}
|
<Link to='/survey/edit/questions'
|
||||||
onPageClick = {handlePageClick}
|
className={`${styles.pageLink} ${isCreateSurveyActive ? styles.active : ''}`}>
|
||||||
/>
|
Создать опрос
|
||||||
|
{isCreateSurveyActive && <hr className={styles.activeLine}/>}
|
||||||
|
</Link>
|
||||||
|
<Link to='/my-surveys'
|
||||||
|
className={`${styles.pageLink} ${isMySurveyActive ? styles.active : ''}`}>
|
||||||
|
Мои опросы
|
||||||
|
{isMySurveyActive && <hr className={styles.activeLine}/>}
|
||||||
|
</Link>
|
||||||
|
</nav>
|
||||||
<Account
|
<Account
|
||||||
href=''
|
href='/profile'
|
||||||
user='Иванов Иван'
|
user='Иванов Иван'
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,25 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
import {useLocation, useNavigate} from 'react-router-dom'
|
||||||
import styles from './Navigation.module.css'
|
import styles from './Navigation.module.css'
|
||||||
import NavigationItem from "../NavigationItem/NavigationItem.tsx";
|
import NavigationItem from "../NavigationItem/NavigationItem.tsx";
|
||||||
import SaveButton from "../SaveButton/SaveButton.tsx";
|
import SaveButton from "../SaveButton/SaveButton.tsx";
|
||||||
|
|
||||||
interface NavigationProps {
|
|
||||||
onNavigationClick: (title: string) => void;
|
|
||||||
activePage: string
|
|
||||||
}
|
|
||||||
|
|
||||||
const Navigation: React.FC<NavigationProps> = ({onNavigationClick, activePage}) => {
|
const Navigation: React.FC = () => {
|
||||||
const items: string[] = ['Вопросы', 'Настройки', 'Результаты']
|
const location = useLocation();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
const activePage = location.pathname.split('/').pop() || 'questions'
|
||||||
|
|
||||||
|
const items = [
|
||||||
|
{id: 'questions', title: 'Вопросы'},
|
||||||
|
{id: 'settings', title: 'Настройки'},
|
||||||
|
{id: 'results', title: 'Результаты'}
|
||||||
|
]
|
||||||
|
|
||||||
|
const handleNavigationClick = (padeId: string) => {
|
||||||
|
navigate(`${padeId}`);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.navContainer}>
|
<div className={styles.navContainer}>
|
||||||
|
|
@ -17,10 +27,10 @@ const Navigation: React.FC<NavigationProps> = ({onNavigationClick, activePage})
|
||||||
<ul className={styles.navList}>
|
<ul className={styles.navList}>
|
||||||
{items.map(item => (
|
{items.map(item => (
|
||||||
<NavigationItem
|
<NavigationItem
|
||||||
key={item}
|
key={item.id}
|
||||||
title={item}
|
title={item.title}
|
||||||
isActive={activePage === item}
|
isActive={activePage === item.id}
|
||||||
onClick={() => onNavigationClick(item)}
|
onClick={() => handleNavigationClick(item.id)}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
/*SettingSurvey.module.css*/
|
/*SettingSurvey.module.css*/
|
||||||
|
|
||||||
.settingSurvey{
|
.settingSurvey{
|
||||||
width: 65%;
|
width: 85%;
|
||||||
margin-left: 8.9%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.startEndTime{
|
.startEndTime{
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
/*Survey.module.css*/
|
/*Survey.module.css*/
|
||||||
|
|
||||||
.survey{
|
.survey{
|
||||||
width: 65%;
|
width: 85%;
|
||||||
margin-left: 8.9%;
|
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
/*SurveyEditingPage.module.css*/
|
||||||
|
|
||||||
|
.layout{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main{
|
||||||
|
width: 100%;
|
||||||
|
min-height: 85vh;
|
||||||
|
display: flex;
|
||||||
|
background-color: #F6F6F6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content{
|
||||||
|
width: 100%;
|
||||||
|
margin-left: 8.9%;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
import Header from "../../components/Header/Header.tsx";
|
||||||
|
import Navigation from "../../components/Navigation/Navigation.tsx";
|
||||||
|
import styles from './SurveyEditingPage.module.css'
|
||||||
|
import { Outlet } from "react-router-dom";
|
||||||
|
|
||||||
|
export const SurveyEditingPage = () => {
|
||||||
|
return (
|
||||||
|
<div className={styles.layout}>
|
||||||
|
<Header />
|
||||||
|
<div className={styles.main}>
|
||||||
|
<Navigation />
|
||||||
|
<div className={styles.content}>
|
||||||
|
<Outlet />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
Loading…
Add table
Add a link
Reference in a new issue