| "react-transition-group": "^4.3.0" | "react-transition-group": "^4.3.0" | ||||
| } | } | ||||
| }, | }, | ||||
| "react-toastify": { | |||||
| "version": "9.0.3", | |||||
| "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-9.0.3.tgz", | |||||
| "integrity": "sha512-0QZJk0SqYBxouRBGCFU3ymvjlwimRRhVH7SzqGRiVrQ001KSoUNbGKx9Yq42aoPv18n45yJzEFG82zqv3HnASg==", | |||||
| "requires": { | |||||
| "clsx": "^1.1.1" | |||||
| } | |||||
| }, | |||||
| "react-transition-group": { | "react-transition-group": { | ||||
| "version": "4.4.2", | "version": "4.4.2", | ||||
| "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.2.tgz", | "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.2.tgz", |
| "react-router-dom": "^5.2.0", | "react-router-dom": "^5.2.0", | ||||
| "react-scripts": "4.0.3", | "react-scripts": "4.0.3", | ||||
| "react-select": "^4.3.1", | "react-select": "^4.3.1", | ||||
| "react-toastify": "^9.0.3", | |||||
| "redux": "^4.1.0", | "redux": "^4.1.0", | ||||
| "redux-persist": "^6.0.0", | "redux-persist": "^6.0.0", | ||||
| "redux-persist-transform-filter": "0.0.20", | "redux-persist-transform-filter": "0.0.20", |
| import Header from "./components/Header/Header"; | import Header from "./components/Header/Header"; | ||||
| import { StyledEngineProvider } from "@mui/material"; | import { StyledEngineProvider } from "@mui/material"; | ||||
| import GlobalStyle from "./components/Styles/globalStyles"; | import GlobalStyle from "./components/Styles/globalStyles"; | ||||
| import { useDispatch } from "react-redux"; | |||||
| import { setToastMessage } from "./store/actions/toast/toastActions"; | |||||
| import { ToastContainer } from "./components/Toast/Toast.styled"; | |||||
| import { ToastContainer } from "react-toastify"; | |||||
| import "react-toastify/dist/ReactToastify.css"; | |||||
| // const URL = "http://192.168.88.143:3001"; | // const URL = "http://192.168.88.143:3001"; | ||||
| // const socket = io(URL, {autoConnect: true, transports: ['websocket']}); | // const socket = io(URL, {autoConnect: true, transports: ['websocket']}); | ||||
| const App = () => { | const App = () => { | ||||
| const dispatch = useDispatch(); | |||||
| // console.log(io) | // console.log(io) | ||||
| // const [isConnected, setIsConnected] = useState(socket.connected); | // const [isConnected, setIsConnected] = useState(socket.connected); | ||||
| <title>{i18next.t("app.title")}</title> | <title>{i18next.t("app.title")}</title> | ||||
| </Helmet> | </Helmet> | ||||
| <StyledEngineProvider injectFirst> | <StyledEngineProvider injectFirst> | ||||
| {/* <button onClick={handleClick}>Kik</button> */} | |||||
| <Header /> | <Header /> | ||||
| <GlobalStyle /> | <GlobalStyle /> | ||||
| <button onClick={() => { | |||||
| dispatch(setToastMessage({ | |||||
| position: "top", | |||||
| timeout: 5000, | |||||
| render: (<div>Tekst familijo</div>), | |||||
| show: true, | |||||
| })) | |||||
| }}>Tekst</button> | |||||
| <ToastContainer /> | <ToastContainer /> | ||||
| {/* <div> | {/* <div> | ||||
| <p>Connected: {"" + isConnected}</p> | <p>Connected: {"" + isConnected}</p> | ||||
| </div> */} | </div> */} | ||||
| <AppRoutes /> | <AppRoutes /> | ||||
| </StyledEngineProvider> | </StyledEngineProvider> | ||||
| {/* </main> */} | |||||
| </Router> | </Router> | ||||
| ); | ); | ||||
| }; | }; |
| import React, { useCallback, useEffect, useMemo } from "react"; | |||||
| import { useDispatch, useSelector } from "react-redux"; | |||||
| import { clearToastMessage } from "../../store/actions/toast/toastActions"; | |||||
| import { selectToastMessage } from "../../store/selectors/toastSelectors"; | |||||
| import { ToastContainer } from "./Toast.styled"; | |||||
| const Toast = () => { | |||||
| const toastMessage = useSelector(selectToastMessage); | |||||
| const dispatch = useDispatch(); | |||||
| const ToastContent = useMemo(() => { | |||||
| if (toastMessage?.render) return toastMessage.render; | |||||
| return <></> | |||||
| }, [toastMessage]) | |||||
| const autoDeleteMessage = useCallback(() => { | |||||
| dispatch(clearToastMessage()); | |||||
| }, []) | |||||
| useEffect(() => { | |||||
| let timeoutObject; | |||||
| if (toastMessage?.timeout) { | |||||
| timeoutObject = setTimeout(autoDeleteMessage, toastMessage.timeout); | |||||
| } | |||||
| return () => clearTimeout(timeoutObject); | |||||
| }, [toastMessage]) | |||||
| return ( | |||||
| <ToastContainer>{toastMessage?.show && <ToastContent />}</ToastContainer> | |||||
| ); | |||||
| }; | |||||
| export default Toast; |
| import { Box } from "@mui/material"; | |||||
| import styled from "styled-components"; | |||||
| export const ToastContainer = styled(Box)` | |||||
| position: absolute; | |||||
| top: 0; | |||||
| right: 0; | |||||
| left: 0; | |||||
| width: 100px; | |||||
| background-color: green; | |||||
| height: 100px; | |||||
| ` |
| export const SET_TOAST_MESSAGE = "TOAST_MESSAGE_SET"; | |||||
| export const CLEAR_TOAST_MESSAGE = "TOAST_MESSAGE_CLEAR"; |
| import { CLEAR_TOAST_MESSAGE, SET_TOAST_MESSAGE } from "./toastActionConstants"; | |||||
| export const setToastMessage = (payload) => ({ | |||||
| type: SET_TOAST_MESSAGE, | |||||
| payload, | |||||
| }) | |||||
| export const clearToastMessage = () => ({ | |||||
| type: CLEAR_TOAST_MESSAGE | |||||
| }) |
| import queryStringReducer from "./queryString/queryStringReducer"; | import queryStringReducer from "./queryString/queryStringReducer"; | ||||
| import exchangeReducer from "./exchange/exchangeReducer"; | import exchangeReducer from "./exchange/exchangeReducer"; | ||||
| import reviewReducer from "./review/reviewReducer"; | import reviewReducer from "./review/reviewReducer"; | ||||
| import toastReducer from "./toast/toastReducer"; | |||||
| const loginPersistConfig = { | const loginPersistConfig = { | ||||
| key: "login", | key: "login", | ||||
| queryString: queryStringReducer, | queryString: queryStringReducer, | ||||
| exchange: exchangeReducer, | exchange: exchangeReducer, | ||||
| review: reviewReducer, | review: reviewReducer, | ||||
| toast: toastReducer, | |||||
| }); | }); |
| import createReducer from "../../utils/createReducer"; | |||||
| import { | |||||
| CLEAR_TOAST_MESSAGE, | |||||
| SET_TOAST_MESSAGE, | |||||
| } from "../../actions/toast/toastActionConstants"; | |||||
| const initialState = { | |||||
| toastMessage: {}, | |||||
| }; | |||||
| export default createReducer( | |||||
| { | |||||
| [SET_TOAST_MESSAGE]: setToastMessage, | |||||
| [CLEAR_TOAST_MESSAGE]: clearToastMessage, | |||||
| }, | |||||
| initialState | |||||
| ); | |||||
| function setToastMessage(state, action) { | |||||
| return { | |||||
| ...state, | |||||
| toastMessage: action.payload, | |||||
| }; | |||||
| } | |||||
| function clearToastMessage() { | |||||
| return initialState; | |||||
| } |
| import { createSelector } from "reselect"; | |||||
| const toastSelector = (state) => state.toast; | |||||
| export const selectToastMessage = createSelector( | |||||
| toastSelector, | |||||
| (state) => state.toastMessage | |||||
| ) |
| import { toast } from 'react-toastify'; | |||||
| const defaultOptions = { | |||||
| position: "top-center", | |||||
| autoClose: 5000, | |||||
| hideProgressBar: true, | |||||
| closeOnClick: true, | |||||
| pauseOnHover: true, | |||||
| draggable: true, | |||||
| } | |||||
| export const makeToastMessage = (text, options = defaultOptions) => toast(text, options); |