diff --git a/rsconcept/frontend/src/components/Common/Dropdown.tsx b/rsconcept/frontend/src/components/Common/Dropdown.tsx index af7b538c..1af03a68 100644 --- a/rsconcept/frontend/src/components/Common/Dropdown.tsx +++ b/rsconcept/frontend/src/components/Common/Dropdown.tsx @@ -7,7 +7,7 @@ interface DropdownProps { function Dropdown({ children, widthClass = 'w-fit', stretchLeft }: DropdownProps) { return (
-
+
{children}
diff --git a/rsconcept/frontend/src/components/Common/DropdownButton.tsx b/rsconcept/frontend/src/components/Common/DropdownButton.tsx index d3ac47de..16d77e8c 100644 --- a/rsconcept/frontend/src/components/Common/DropdownButton.tsx +++ b/rsconcept/frontend/src/components/Common/DropdownButton.tsx @@ -1,16 +1,16 @@ -interface NavigationTextItemProps { - description?: string | undefined +interface DropdownButtonProps { + tooltip?: string | undefined onClick?: () => void disabled?: boolean children: React.ReactNode } -function DropdownButton({ description = '', onClick, disabled, children }: NavigationTextItemProps) { - const behavior = (onClick ? 'cursor-pointer clr-hover' : 'cursor-default') + ' disabled:cursor-not-allowed'; +function DropdownButton({ tooltip, onClick, disabled, children }: DropdownButtonProps) { + const behavior = (onClick ? 'cursor-pointer disabled:cursor-not-allowed clr-hover' : 'cursor-default'); return (
{ error && } diff --git a/rsconcept/frontend/src/pages/HomePage.tsx b/rsconcept/frontend/src/pages/HomePage.tsx index 1184cdca..40eca170 100644 --- a/rsconcept/frontend/src/pages/HomePage.tsx +++ b/rsconcept/frontend/src/pages/HomePage.tsx @@ -13,7 +13,7 @@ function HomePage() { setTimeout(() => { navigate('/manuals'); }, TIMEOUT_UI_REFRESH); - } else if(!user.is_staff) { + } else { setTimeout(() => { navigate('/library'); }, TIMEOUT_UI_REFRESH); diff --git a/rsconcept/frontend/src/pages/LibraryPage/PickerStrategy.tsx b/rsconcept/frontend/src/pages/LibraryPage/PickerStrategy.tsx index 42738157..4236b2e1 100644 --- a/rsconcept/frontend/src/pages/LibraryPage/PickerStrategy.tsx +++ b/rsconcept/frontend/src/pages/LibraryPage/PickerStrategy.tsx @@ -1,9 +1,8 @@ import { useCallback } from 'react'; import Button from '../../components/Common/Button'; -import Checkbox from '../../components/Common/Checkbox'; import Dropdown from '../../components/Common/Dropdown'; -import DropdownButton from '../../components/Common/DropdownButton'; +import DropdownCheckbox from '../../components/Common/DropdownCheckbox'; import { FilterCogIcon } from '../../components/Icons'; import { useAuth } from '../../context/AuthContext'; import useDropdown from '../../hooks/useDropdown'; @@ -36,56 +35,44 @@ function PickerStrategy({ value, onChange }: PickerStrategyProps) { /> { pickerMenu.isActive && - handleChange(LibraryFilterStrategy.MANUAL)}> - - - handleChange(LibraryFilterStrategy.COMMON)}> - - - handleChange(LibraryFilterStrategy.CANONICAL)}> - - - handleChange(LibraryFilterStrategy.PERSONAL)}> - - - handleChange(LibraryFilterStrategy.SUBSCRIBE)}> - - - handleChange(LibraryFilterStrategy.OWNED)}> - - + handleChange(LibraryFilterStrategy.MANUAL)} + value={value === LibraryFilterStrategy.MANUAL} + label='Отображать все' + /> + handleChange(LibraryFilterStrategy.COMMON)} + value={value === LibraryFilterStrategy.COMMON} + label='Общедоступные' + tooltip='Отображать только общедоступные схемы' + /> + handleChange(LibraryFilterStrategy.CANONICAL)} + value={value === LibraryFilterStrategy.CANONICAL} + label='Неизменные' + tooltip='Отображать только неизменные схемы' + /> + handleChange(LibraryFilterStrategy.PERSONAL)} + value={value === LibraryFilterStrategy.PERSONAL} + label='Личные' + disabled={!user} + tooltip='Отображать только подписки и владеемые схемы' + /> + handleChange(LibraryFilterStrategy.SUBSCRIBE)} + value={value === LibraryFilterStrategy.SUBSCRIBE} + label='Подписки' + disabled={!user} + tooltip='Отображать только подписки' + /> + handleChange(LibraryFilterStrategy.OWNED)} + value={value === LibraryFilterStrategy.OWNED} + disabled={!user} + label='Я - Владелец!' + tooltip='Отображать только владеемые схемы' + /> } ); diff --git a/rsconcept/frontend/src/pages/LibraryPage/SearchPanel.tsx b/rsconcept/frontend/src/pages/LibraryPage/SearchPanel.tsx index dcaa1e7c..23815f43 100644 --- a/rsconcept/frontend/src/pages/LibraryPage/SearchPanel.tsx +++ b/rsconcept/frontend/src/pages/LibraryPage/SearchPanel.tsx @@ -3,6 +3,7 @@ import { useLocation, useNavigate } from 'react-router-dom'; import { MagnifyingGlassIcon } from '../../components/Icons'; import { useAuth } from '../../context/AuthContext'; +import useLocalStorage from '../../hooks/useLocalStorage'; import { ILibraryFilter, LibraryFilterStrategy } from '../../utils/models'; import PickerStrategy from './PickerStrategy'; @@ -30,7 +31,7 @@ function SearchPanel({ total, filtered, setFilter }: SearchPanelProps) { const { user } = useAuth(); const [query, setQuery] = useState(''); - const [strategy, setStrategy] = useState(LibraryFilterStrategy.MANUAL); + const [strategy, setStrategy] = useLocalStorage('search_strategy', LibraryFilterStrategy.MANUAL); function handleChangeQuery(event: React.ChangeEvent) { const newQuery = event.target.value; @@ -49,11 +50,15 @@ function SearchPanel({ total, filtered, setFilter }: SearchPanelProps) { useLayoutEffect(() => { const searchFilter = new URLSearchParams(search).get('filter') as LibraryFilterStrategy | null; + if (searchFilter === null) { + navigate(`/library?filter=${strategy}`); + return; + } const inputStrategy = searchFilter && Object.values(LibraryFilterStrategy).includes(searchFilter) ? searchFilter : LibraryFilterStrategy.MANUAL; setQuery('') setStrategy(inputStrategy) setFilter(ApplyStrategy(inputStrategy)); - }, [user, search, setQuery, setFilter]); + }, [user, search, setQuery, setFilter, setStrategy, strategy, navigate]); const handleChangeStrategy = useCallback( (value: LibraryFilterStrategy) => { diff --git a/rsconcept/frontend/src/pages/LoginPage.tsx b/rsconcept/frontend/src/pages/LoginPage.tsx index 303f62ad..77180be8 100644 --- a/rsconcept/frontend/src/pages/LoginPage.tsx +++ b/rsconcept/frontend/src/pages/LoginPage.tsx @@ -10,6 +10,7 @@ import { useAuth } from '../context/AuthContext'; import { IUserLoginData } from '../utils/models'; function LoginPage() { + const location = useLocation(); const navigate = useNavigate(); const search = useLocation().search; const { user, login, loading, error, setError } = useAuth(); @@ -34,7 +35,13 @@ function LoginPage() { username: username, password: password }; - login(data, () => navigate('/library')); + login(data, () => { + if (location.key !== "default") { + navigate(-1); + } else { + navigate('/library'); + } + }); } } @@ -44,7 +51,7 @@ function LoginPage() { ? {`Вы вошли в систему как ${user.username}`} :
@@ -64,10 +71,10 @@ function LoginPage() { onChange={event => setPassword(event.target.value)} /> -
+
diff --git a/rsconcept/frontend/src/pages/RSFormPage/RSTabsMenu.tsx b/rsconcept/frontend/src/pages/RSFormPage/RSTabsMenu.tsx index 0145774e..3f6d9fc7 100644 --- a/rsconcept/frontend/src/pages/RSFormPage/RSTabsMenu.tsx +++ b/rsconcept/frontend/src/pages/RSFormPage/RSTabsMenu.tsx @@ -1,9 +1,9 @@ import { useNavigate } from 'react-router-dom'; import Button from '../../components/Common/Button'; -import Checkbox from '../../components/Common/Checkbox'; import Dropdown from '../../components/Common/Dropdown'; import DropdownButton from '../../components/Common/DropdownButton'; +import DropdownCheckbox from '../../components/Common/DropdownCheckbox'; import { CloneIcon, CrownIcon, DownloadIcon, DumpBinIcon, EyeIcon, EyeOffIcon, MenuIcon, PenIcon, PlusIcon, ShareIcon, UploadIcon } from '../../components/Icons'; import { useAuth } from '../../context/AuthContext'; import { useRSForm } from '../../context/RSFormContext'; @@ -131,7 +131,7 @@ function RSTabsMenu({
@@ -142,22 +142,18 @@ function RSTabsMenu({
{(isOwned || user?.is_staff) && - - - } + } {user?.is_staff && - - - } + } }
diff --git a/rsconcept/frontend/src/pages/RegisterPage.tsx b/rsconcept/frontend/src/pages/RegisterPage.tsx index d5133fab..9345871a 100644 --- a/rsconcept/frontend/src/pages/RegisterPage.tsx +++ b/rsconcept/frontend/src/pages/RegisterPage.tsx @@ -1,8 +1,9 @@ import { useEffect, useState } from 'react'; -import { useNavigate } from 'react-router-dom'; +import { useLocation, useNavigate } from 'react-router-dom'; import { toast } from 'react-toastify'; import BackendError from '../components/BackendError'; +import Button from '../components/Common/Button'; import Form from '../components/Common/Form'; import SubmitButton from '../components/Common/SubmitButton'; import TextInput from '../components/Common/TextInput'; @@ -10,6 +11,7 @@ import { useAuth } from '../context/AuthContext'; import { type IUserSignupData } from '../utils/models'; function RegisterPage() { + const location = useLocation(); const navigate = useNavigate(); const { user, signup, loading, error, setError } = useAuth(); @@ -24,6 +26,14 @@ function RegisterPage() { setError(undefined); }, [username, email, password, password2, setError]); + function handleCancel() { + if (location.key !== "default") { + navigate(-1); + } else { + navigate('/library'); + } + } + function handleSubmit(event: React.FormEvent) { event.preventDefault(); if (!loading) { @@ -48,7 +58,7 @@ function RegisterPage() { {`Вы вошли в систему как ${user.username}. Если хотите зарегистрировать нового пользователя, выйдите из системы (меню в правом верхнем углу экрана)`}} { !user && @@ -89,8 +99,17 @@ function RegisterPage() { onChange={event => setLastName(event.target.value)} /> -
- +
+ +
{ error && }