├── src ├── react-app-env.d.ts ├── assets │ └── images │ │ ├── Edit.png │ │ ├── logo.png │ │ ├── Delete.png │ │ ├── teacher.png │ │ ├── checkemail.png │ │ ├── error404.gif │ │ └── userAvata.png ├── common │ ├── components │ │ ├── superCheckbox │ │ │ ├── SuperCheckbox.module.css │ │ │ └── SuperCheckbox.tsx │ │ ├── starRating │ │ │ ├── StarRating.module.css │ │ │ └── StarRating.tsx │ │ ├── superDoubleRange │ │ │ ├── SuperDoubleRange.module.css │ │ │ └── SuperDoubleRange.tsx │ │ ├── error404 │ │ │ ├── Error404.module.css │ │ │ └── Error404.tsx │ │ ├── superEditableSpan │ │ │ ├── SuperEditableSpan.module.css │ │ │ └── SuperEditableSpan.tsx │ │ ├── superInputText │ │ │ ├── SuperInputText.module.css │ │ │ └── SuperInputText.tsx │ │ ├── superButton │ │ │ ├── SuperButton.module.css │ │ │ └── SuperButton.tsx │ │ ├── modals │ │ │ ├── basicModal │ │ │ │ └── BasicModal.tsx │ │ │ ├── cards │ │ │ │ ├── BaseModal.tsx │ │ │ │ ├── DeleteModal.tsx │ │ │ │ ├── DeleteCardsPackModal.tsx │ │ │ │ ├── EditModal.tsx │ │ │ │ └── AddModal.tsx │ │ │ ├── Modal.module.css │ │ │ └── packs │ │ │ │ ├── DeletePackModal.tsx │ │ │ │ ├── AddNewPackModal.tsx │ │ │ │ └── EditPackModal.tsx │ │ ├── superSelect │ │ │ └── SuperSelect.tsx │ │ ├── displayOnError │ │ │ └── DisplayOnError.tsx │ │ ├── superRadio │ │ │ └── SuperRadio.tsx │ │ ├── eyeOnOff │ │ │ └── EyeOnOff.tsx │ │ └── svgSelector │ │ │ └── svgSelector.tsx │ ├── hooks │ │ ├── hooks.ts │ │ └── useDebounce.ts │ └── utils │ │ ├── query-params.ts │ │ ├── convertBase64.tsx │ │ ├── getCard.ts │ │ └── errors-utils.ts ├── setupTests.ts ├── app │ ├── App.module.css │ ├── app-reducer.test.ts │ ├── store.ts │ ├── app-reducer.ts │ └── App.tsx ├── reportWebVitals.ts ├── index.css ├── features │ ├── packs │ │ ├── pack │ │ │ ├── Pack.module.css │ │ │ └── Pack.tsx │ │ ├── Packs.module.css │ │ ├── packsPagination │ │ │ └── PacksPagination.tsx │ │ ├── setPacks │ │ │ ├── SetPacks.module.css │ │ │ └── SetPacks.tsx │ │ ├── packs-reducer.ts │ │ └── Packs.tsx │ ├── auth │ │ ├── password │ │ │ ├── checkEmail │ │ │ │ ├── CheckEmail.module.css │ │ │ │ └── CheckEmail.tsx │ │ │ ├── newPassword │ │ │ │ ├── NewPassword.module.css │ │ │ │ └── NewPassword.tsx │ │ │ └── forgotPassword │ │ │ │ ├── ForgotPassword.module.css │ │ │ │ └── ForgotPassword.tsx │ │ ├── registration │ │ │ ├── Registration.module.css │ │ │ └── Registration.tsx │ │ ├── login │ │ │ ├── Login.module.css │ │ │ └── Login.tsx │ │ ├── auth-reducer.test.ts │ │ └── auth-reducer.ts │ ├── cards │ │ ├── card │ │ │ ├── Card.module.css │ │ │ └── Card.tsx │ │ ├── cardsPagination │ │ │ └── CardsPagination.tsx │ │ ├── TableCards.module.css │ │ ├── cards-reducer.test.ts │ │ ├── cards-reducer.ts │ │ └── TableCards.tsx │ ├── learn │ │ ├── Learn.module.css │ │ └── Learn.tsx │ ├── profile │ │ ├── Profile.module.css │ │ └── Profile.tsx │ └── header │ │ ├── Header.module.css │ │ └── Header.tsx ├── index.tsx └── api │ └── api.ts ├── public ├── favicon.ico ├── logo192.png ├── logo512.png ├── robots.txt ├── manifest.json └── index.html ├── .gitignore ├── tsconfig.json ├── README.md └── package.json /src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Trajgiel/Learning-Cards/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Trajgiel/Learning-Cards/HEAD/public/logo192.png -------------------------------------------------------------------------------- /public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Trajgiel/Learning-Cards/HEAD/public/logo512.png -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /src/assets/images/Edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Trajgiel/Learning-Cards/HEAD/src/assets/images/Edit.png -------------------------------------------------------------------------------- /src/assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Trajgiel/Learning-Cards/HEAD/src/assets/images/logo.png -------------------------------------------------------------------------------- /src/assets/images/Delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Trajgiel/Learning-Cards/HEAD/src/assets/images/Delete.png -------------------------------------------------------------------------------- /src/assets/images/teacher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Trajgiel/Learning-Cards/HEAD/src/assets/images/teacher.png -------------------------------------------------------------------------------- /src/assets/images/checkemail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Trajgiel/Learning-Cards/HEAD/src/assets/images/checkemail.png -------------------------------------------------------------------------------- /src/assets/images/error404.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Trajgiel/Learning-Cards/HEAD/src/assets/images/error404.gif -------------------------------------------------------------------------------- /src/assets/images/userAvata.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Trajgiel/Learning-Cards/HEAD/src/assets/images/userAvata.png -------------------------------------------------------------------------------- /src/common/components/superCheckbox/SuperCheckbox.module.css: -------------------------------------------------------------------------------- 1 | .checkbox { 2 | 3 | } 4 | 5 | .spanClassName { 6 | 7 | } -------------------------------------------------------------------------------- /src/common/components/starRating/StarRating.module.css: -------------------------------------------------------------------------------- 1 | .stars { 2 | display: flex; 3 | } 4 | 5 | .star { 6 | margin: 0 2px; 7 | } -------------------------------------------------------------------------------- /src/common/components/superDoubleRange/SuperDoubleRange.module.css: -------------------------------------------------------------------------------- 1 | .range { 2 | display: inline-block; 3 | margin-left: 20px; 4 | margin-right: 20px; 5 | width: 200px; 6 | } -------------------------------------------------------------------------------- /src/setupTests.ts: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting eyeOnOff DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /src/app/App.module.css: -------------------------------------------------------------------------------- 1 | .appBlock { 2 | font-size: 16px; 3 | line-height: 1.6; 4 | } 5 | 6 | .appContainer { 7 | height: 100%; 8 | width: 80%; 9 | margin: 0 auto; 10 | } 11 | 12 | .init { 13 | position: fixed; 14 | top: 30%; 15 | text-align: center; 16 | width: 100%; 17 | } -------------------------------------------------------------------------------- /src/common/hooks/hooks.ts: -------------------------------------------------------------------------------- 1 | import {TypedUseSelectorHook, useDispatch, useSelector} from 'react-redux'; 2 | import {AppDispatch, AppRootStateType} from "../../app/store"; 3 | 4 | export const useAppDispatch: () => AppDispatch = useDispatch 5 | export const useAppSelector: TypedUseSelectorHook = useSelector -------------------------------------------------------------------------------- /src/common/components/error404/Error404.module.css: -------------------------------------------------------------------------------- 1 | .error404 { 2 | background-color: #F1F5F9; 3 | height: 100vh; 4 | width: 100%; 5 | position: fixed; 6 | top: 0; 7 | left: 0; 8 | text-align: center; 9 | } 10 | 11 | .error404 img { 12 | cursor: pointer; 13 | margin-top: 4vh; 14 | } -------------------------------------------------------------------------------- /src/common/utils/query-params.ts: -------------------------------------------------------------------------------- 1 | export const filterQueryParams = (searchParams: Record) => { 2 | const params: Record = searchParams 3 | 4 | for (let el in params) { 5 | if (params[el] === '' || params[el] === '0') { 6 | delete params[el] 7 | } 8 | } 9 | return params 10 | } -------------------------------------------------------------------------------- /src/common/components/superEditableSpan/SuperEditableSpan.module.css: -------------------------------------------------------------------------------- 1 | .span { 2 | display: inline-block; 3 | height: 36px; 4 | font-style: normal; 5 | font-weight: 500; 6 | font-size: 20px; 7 | line-height: 24px; 8 | position: relative; 9 | } 10 | 11 | .span svg { 12 | position: relative; 13 | top: 3px; 14 | right: -5px; 15 | } -------------------------------------------------------------------------------- /src/common/utils/convertBase64.tsx: -------------------------------------------------------------------------------- 1 | export const convertFileToBase64 = ( 2 | file: File, 3 | callBack: (value: string) => void, 4 | ): void => { 5 | const reader = new FileReader(); 6 | 7 | reader.onloadend = () => { 8 | const file64 = reader.result as string; 9 | callBack(file64); 10 | }; 11 | reader.readAsDataURL(file); 12 | }; 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | /.idea 7 | .pnp.js 8 | 9 | # testing 10 | /coverage 11 | 12 | # production 13 | /build 14 | 15 | # misc 16 | .DS_Store 17 | .env.local 18 | .env.development.local 19 | .env.test.local 20 | .env.production.local 21 | 22 | npm-debug.log* 23 | yarn-debug.log* 24 | yarn-error.log* 25 | -------------------------------------------------------------------------------- /src/common/components/superInputText/SuperInputText.module.css: -------------------------------------------------------------------------------- 1 | .superInput { 2 | height: 36px; 3 | border-radius: 10px; 4 | padding-left: 10px; 5 | border: 1px solid #9b9b9b; 6 | } 7 | 8 | .superInput:focus { 9 | outline: none; 10 | border: 1px solid #9b9b9b; 11 | } 12 | 13 | .errorInput { 14 | border: 3px solid #0F4787; 15 | background: rgba(255, 0, 0, 0.59); 16 | } 17 | 18 | .error { 19 | color: rgba(255, 0, 0, 0.55); 20 | } -------------------------------------------------------------------------------- /src/common/hooks/useDebounce.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react' 2 | 3 | export const useDebounce = (value: T, delay?: number): T => { 4 | const [debouncedValue, setDebouncedValue] = useState(value) 5 | 6 | useEffect(() => { 7 | const timer = setTimeout(() => setDebouncedValue(value), delay || 500) 8 | 9 | return () => { 10 | clearTimeout(timer) 11 | } 12 | }, [value, delay]) 13 | 14 | return debouncedValue 15 | } -------------------------------------------------------------------------------- /src/reportWebVitals.ts: -------------------------------------------------------------------------------- 1 | import { ReportHandler } from 'web-vitals'; 2 | 3 | const reportWebVitals = (onPerfEntry?: ReportHandler) => { 4 | if (onPerfEntry && onPerfEntry instanceof Function) { 5 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 6 | getCLS(onPerfEntry); 7 | getFID(onPerfEntry); 8 | getFCP(onPerfEntry); 9 | getLCP(onPerfEntry); 10 | getTTFB(onPerfEntry); 11 | }); 12 | } 13 | }; 14 | 15 | export default reportWebVitals; 16 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | margin: 0; 4 | padding: 0; 5 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 6 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 7 | sans-serif; 8 | font-style: normal; 9 | font-weight: 400; 10 | font-size: 16px; 11 | line-height: 17px; 12 | 13 | } 14 | 15 | * ::after, ::before { 16 | box-sizing: border-box; 17 | } 18 | 19 | body { 20 | background-color: rgba(162, 162, 162, 0.13); 21 | } -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /src/features/packs/pack/Pack.module.css: -------------------------------------------------------------------------------- 1 | .maneColumn { 2 | user-select: none; 3 | text-decoration: none; 4 | color: black; 5 | } 6 | 7 | .maneColumn:hover { 8 | color: #525252; 9 | } 10 | 11 | .icons { 12 | display: flex; 13 | justify-content: space-between; 14 | width: 100px; 15 | } 16 | 17 | .cardsColumn { 18 | width: 10% !important; 19 | } 20 | 21 | .dateColumn { 22 | width: 18% !important; 23 | } 24 | 25 | .userNameColumn { 26 | width: 17% !important; 27 | } 28 | 29 | .iconsColumn { 30 | width: 10% !important; 31 | } 32 | 33 | .icon { 34 | cursor: pointer; 35 | } -------------------------------------------------------------------------------- /src/common/utils/getCard.ts: -------------------------------------------------------------------------------- 1 | import {CardsType} from "../../api/api"; 2 | 3 | export const getCard = (cards: CardsType[]) => { 4 | const sum = cards.reduce((acc, card) => acc + (6 - card.grade) * (6 - card.grade), 0); 5 | const rand = Math.random() * sum; 6 | const res = cards.reduce((acc: { sum: number, id: number}, card, i) => { 7 | const newSum = acc.sum + (6 - card.grade) * (6 - card.grade); 8 | return {sum: newSum, id: newSum < rand ? i : acc.id} 9 | } 10 | , {sum: 0, id: -1}); 11 | // console.log('test: ', sum, rand, res) 12 | return cards[res.id + 1]; 13 | } -------------------------------------------------------------------------------- /src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import {App} from './app/App'; 5 | import reportWebVitals from './reportWebVitals'; 6 | import {Provider} from "react-redux"; 7 | import {store} from "./app/store"; 8 | import {HashRouter} from 'react-router-dom'; 9 | 10 | const root = ReactDOM.createRoot( 11 | document.getElementById('root') as HTMLElement 12 | ); 13 | root.render( 14 | 15 | 16 | 17 | 18 | 19 | ); 20 | 21 | reportWebVitals(); 22 | -------------------------------------------------------------------------------- /src/common/utils/errors-utils.ts: -------------------------------------------------------------------------------- 1 | import axios, {AxiosError} from "axios"; 2 | import {setAppErrorAC} from "../../app/app-reducer"; 3 | import {Dispatch} from "redux"; 4 | import {AppRootActionsType} from "../../app/store"; 5 | 6 | export const errorHandlerUtil = (e: any, dispatch: Dispatch) => { 7 | const err = e as Error | AxiosError 8 | if (axios.isAxiosError(err)) { 9 | const error = err.response?.data ? (err.response.data as { error: string }).error : err.message 10 | dispatch(setAppErrorAC(error)) 11 | } else { 12 | dispatch(setAppErrorAC(`Native error ${err.message}`)) 13 | } 14 | } -------------------------------------------------------------------------------- /src/common/components/error404/Error404.tsx: -------------------------------------------------------------------------------- 1 | import React, {useState} from 'react'; 2 | import styles from './Error404.module.css' 3 | import error404 from '../../../assets/images/error404.gif'; 4 | import {Navigate} from "react-router-dom"; 5 | 6 | export const Error404 = () => { 7 | 8 | const [error, setError] = useState(false) 9 | const onClickHandler = () => setError(true) 10 | 11 | if (error) { 12 | return 13 | } 14 | 15 | return ( 16 |
17 | {'qwe'} 18 |
19 | ) 20 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "allowJs": true, 10 | "skipLibCheck": true, 11 | "esModuleInterop": true, 12 | "allowSyntheticDefaultImports": true, 13 | "strict": true, 14 | "forceConsistentCasingInFileNames": true, 15 | "noFallthroughCasesInSwitch": true, 16 | "module": "esnext", 17 | "moduleResolution": "node", 18 | "resolveJsonModule": true, 19 | "isolatedModules": true, 20 | "noEmit": true, 21 | "jsx": "react-jsx" 22 | }, 23 | "include": [ 24 | "src" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 14 | Learning Cards 15 | 16 | 17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /src/features/auth/password/checkEmail/CheckEmail.module.css: -------------------------------------------------------------------------------- 1 | .containerCheckForm { 2 | display: flex; 3 | justify-content: center; 4 | align-items: center; 5 | flex-direction: column; 6 | margin: 0 auto; 7 | width: 413px; 8 | height: 500px; 9 | background: #FFFFFF; 10 | box-shadow: 1px 1px 10px rgba(187, 187, 187, 0.35); 11 | border-radius: 10px; 12 | padding: 30px 50px; 13 | } 14 | 15 | .title { 16 | font-size: 1.8rem; 17 | font-weight: 600; 18 | user-select: none; 19 | margin-bottom: 50px; 20 | } 21 | 22 | .checkBox { 23 | width: 100%; 24 | text-align: center; 25 | } 26 | 27 | .dontHaveAccountTitle { 28 | color: #757575; 29 | user-select: none; 30 | margin-top: 30px; 31 | margin-bottom: 50px; 32 | } 33 | 34 | .buttonForm button { 35 | width: 100%; 36 | } -------------------------------------------------------------------------------- /src/app/app-reducer.test.ts: -------------------------------------------------------------------------------- 1 | import {appReducer, InitialAppStateType, setAppErrorAC, setAppStatusAC, setIsInitializedAC} from "./app-reducer"; 2 | 3 | let state: InitialAppStateType 4 | 5 | beforeEach(() => { 6 | state = { 7 | status: 'idle', 8 | isInitialized: false, 9 | error: null, 10 | } 11 | }) 12 | 13 | test('set status', () => { 14 | const appReducer1 = appReducer(state, setAppStatusAC("loading")) 15 | expect(appReducer1.status).toBe("loading") 16 | }) 17 | 18 | test('set in initialized', () => { 19 | const appReducer1 = appReducer(state, setIsInitializedAC(true)) 20 | expect(appReducer1.isInitialized).toBe(true) 21 | }) 22 | 23 | test('set error', () => { 24 | const appReducer1 = appReducer(state, setAppErrorAC('Error messages')) 25 | expect(appReducer1.error).toBe('Error messages') 26 | }) 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/features/packs/Packs.module.css: -------------------------------------------------------------------------------- 1 | .packsHeader { 2 | display: flex; 3 | justify-content: space-between; 4 | align-items: center; 5 | flex-wrap: wrap; 6 | margin-bottom: 34px; 7 | } 8 | 9 | .packsHeader h2 { 10 | margin: 0; 11 | font-weight: 600; 12 | font-size: 22px; 13 | line-height: 27px; 14 | } 15 | 16 | .button { 17 | height: 36px; 18 | width: 175px; 19 | } 20 | 21 | .input input { 22 | min-width: 100%; 23 | height: 30px; 24 | } 25 | 26 | .input { 27 | padding: 5px 0 20px 0; 28 | } 29 | 30 | .headerRow { 31 | font-size: 18px !important; 32 | font-weight: bold !important; 33 | width: 50px !important; 34 | } 35 | 36 | @media (max-width: 430px) { 37 | 38 | .packsHeader { 39 | justify-content: center; 40 | } 41 | 42 | .packsHeader h2 { 43 | width: 100%; 44 | text-align: center; 45 | margin-bottom: 20px; 46 | } 47 | } -------------------------------------------------------------------------------- /src/common/components/superButton/SuperButton.module.css: -------------------------------------------------------------------------------- 1 | .default { 2 | background-color: #0b78ea; 3 | -webkit-transition-duration: 0.3s; 4 | transition-duration: 0.3s; 5 | padding: 7px 10px; 6 | color: white; 7 | border-radius: 20px; 8 | border: 1px solid #0b78ea; 9 | font-weight: 500; 10 | font-size: 20px; 11 | line-height: 20px; 12 | } 13 | 14 | .default:hover { 15 | cursor: pointer; 16 | background-color: #298eff; 17 | border: 1px solid #298eff; 18 | box-shadow: 0 6px 8px 0 rgba(0, 0, 0, 0.24), 0 9px 25px 0 rgba(0, 0, 0, 0.19); 19 | } 20 | 21 | .default:active { 22 | background-color: #4d5156; 23 | border: 1px solid #4d5156; 24 | } 25 | 26 | .disabled { 27 | opacity: 0.6; 28 | cursor: not-allowed !important; 29 | } 30 | 31 | .disabled:hover { 32 | background-color: #1976D2; 33 | box-shadow: none; 34 | } 35 | 36 | .red { 37 | background: red; 38 | } 39 | -------------------------------------------------------------------------------- /src/common/components/modals/basicModal/BasicModal.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {ReactNode} from 'react'; 3 | import Box from '@mui/material/Box'; 4 | import Modal from '@mui/material/Modal'; 5 | 6 | const style = { 7 | position: 'absolute' as 'absolute', 8 | top: '40%', 9 | left: '50%', 10 | transform: 'translate(-50%, -50%)', 11 | width: 380, 12 | bgcolor: 'background.paper', 13 | border: 'cancel', 14 | borderRadius: '10px', 15 | boxShadow: 24, 16 | p: 4, 17 | }; 18 | 19 | type BasicModalType = { 20 | children: ReactNode 21 | open: boolean 22 | handleClose: () => void 23 | } 24 | 25 | export const BasicModal = ({children, open, handleClose}: BasicModalType) => { 26 | return ( 27 | 31 | 32 | {children} 33 | 34 | 35 | ) 36 | } 37 | 38 | -------------------------------------------------------------------------------- /src/common/components/superButton/SuperButton.tsx: -------------------------------------------------------------------------------- 1 | import React, {ButtonHTMLAttributes, DetailedHTMLProps} from 'react' 2 | import styles from './SuperButton.module.css' 3 | 4 | // тип пропсов обычной кнопки, children в котором храниться название кнопки там уже описан 5 | type DefaultButtonPropsType = DetailedHTMLProps, HTMLButtonElement> 6 | 7 | type SuperButtonPropsType = DefaultButtonPropsType & { 8 | red?: boolean 9 | } 10 | 11 | const SuperButton: React.FC = ( 12 | { 13 | red, className, 14 | ...restProps// все остальные пропсы попадут в объект restProps, там же будет children 15 | } 16 | ) => { 17 | const finalClassName = `${restProps.disabled ? styles.disabled : ''} ${red ? styles.red : styles.default} ${className}` 18 | 19 | return ( 20 |