Procházet zdrojové kódy

Merged with feature 602

bugfix/519
Djordje Mitrovic před 3 roky
rodič
revize
e563317fe0

+ 42
- 0
package-lock.json Zobrazit soubor

"es6-symbol": "^3.1.1" "es6-symbol": "^3.1.1"
} }
}, },
"es6-promise": {
"version": "4.2.8",
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
"integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w=="
},
"es6-symbol": { "es6-symbol": {
"version": "3.1.3", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
"whatwg-fetch": "^3.4.1" "whatwg-fetch": "^3.4.1"
} }
}, },
"react-autosuggest": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/react-autosuggest/-/react-autosuggest-10.1.0.tgz",
"integrity": "sha512-/azBHmc6z/31s/lBf6irxPf/7eejQdR0IqnZUzjdSibtlS8+Rw/R79pgDAo6Ft5QqCUTyEQ+f0FhL+1olDQ8OA==",
"requires": {
"es6-promise": "^4.2.8",
"prop-types": "^15.7.2",
"react-themeable": "^1.1.0",
"section-iterator": "^2.0.0",
"shallow-equal": "^1.2.1"
}
},
"react-dev-utils": { "react-dev-utils": {
"version": "11.0.4", "version": "11.0.4",
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-11.0.4.tgz", "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-11.0.4.tgz",
"resolved": "https://registry.npmjs.org/react-singleton-hook/-/react-singleton-hook-3.4.0.tgz", "resolved": "https://registry.npmjs.org/react-singleton-hook/-/react-singleton-hook-3.4.0.tgz",
"integrity": "sha512-eQEpyacGAaRejmWUizUdNNQFn5AO0iaKRSl1jxgC0FQadVY/I1WFuPrYiutglPzO9s8yEbIh95UXVJQel4d7HQ==" "integrity": "sha512-eQEpyacGAaRejmWUizUdNNQFn5AO0iaKRSl1jxgC0FQadVY/I1WFuPrYiutglPzO9s8yEbIh95UXVJQel4d7HQ=="
}, },
"react-themeable": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/react-themeable/-/react-themeable-1.1.0.tgz",
"integrity": "sha512-kl5tQ8K+r9IdQXZd8WLa+xxYN04lLnJXRVhHfdgwsUJr/SlKJxIejoc9z9obEkx1mdqbTw1ry43fxEUwyD9u7w==",
"requires": {
"object-assign": "^3.0.0"
},
"dependencies": {
"object-assign": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz",
"integrity": "sha512-jHP15vXVGeVh1HuaA2wY6lxk+whK/x4KBG88VXeRma7CCun7iGD5qPc4eYykQ9sdQvg8jkwFKsSxHln2ybW3xQ=="
}
}
},
"react-toastify": { "react-toastify": {
"version": "9.0.3", "version": "9.0.3",
"resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-9.0.3.tgz", "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-9.0.3.tgz",
"ajv-keywords": "^3.5.2" "ajv-keywords": "^3.5.2"
} }
}, },
"section-iterator": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/section-iterator/-/section-iterator-2.0.0.tgz",
"integrity": "sha512-xvTNwcbeDayXotnV32zLb3duQsP+4XosHpb/F+tu6VzEZFmIjzPdNk6/O+QOOx5XTh08KL2ufdXeCO33p380pQ=="
},
"select-hose": { "select-hose": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
"safe-buffer": "^5.0.1" "safe-buffer": "^5.0.1"
} }
}, },
"shallow-equal": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz",
"integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA=="
},
"shallowequal": { "shallowequal": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz",

+ 1
- 0
package.json Zobrazit soubor

"owasp-password-strength-test": "^1.3.0", "owasp-password-strength-test": "^1.3.0",
"query-string": "^7.1.1", "query-string": "^7.1.1",
"react": "^17.0.2", "react": "^17.0.2",
"react-autosuggest": "^10.1.0",
"react-dom": "^17.0.2", "react-dom": "^17.0.2",
"react-helmet-async": "^1.0.9", "react-helmet-async": "^1.0.9",
"react-i18next": "^11.10.0", "react-i18next": "^11.10.0",

+ 38
- 11
src/App.js Zobrazit soubor

const URL = "https://trampa-api-test.dilig.net/"; const URL = "https://trampa-api-test.dilig.net/";
const socket = io(URL, {autoConnect: true}); const socket = io(URL, {autoConnect: true});
const App = () => { const App = () => {
console.log(io)
console.log(socket);


const [isConnected, setIsConnected] = useState(socket.connected); const [isConnected, setIsConnected] = useState(socket.connected);
const [lastPong, setLastPong] = useState(null); const [lastPong, setLastPong] = useState(null);
console.log(); console.log();
useEffect(() => { useEffect(() => {
socket.auth = {
// userId: "62de57c6dff6f986e43d14ec",
userId: "62de5844dff6f986e43d14f6",
sessionID: localStorage.getItem("sessionID"),
};
socket.on("connect", (client) => { socket.on("connect", (client) => {
console.log(client);
console.log("client: ", client);
setIsConnected(true); setIsConnected(true);
}); });
socket.on("session", ({ sessionID, userID }) => {
localStorage.setItem("sessionID", sessionID);
localStorage.setItem("userID", userID);
console.log("sessionID: ", sessionID);
console.log("userID: ", userID);
});
// socket.on("connect_error", (err) => { // socket.on("connect_error", (err) => {
// console.log(err); // console.log(err);
// }); // });
setIsConnected(false); setIsConnected(false);
}); });


socket.on("user disconnected", (userID) => {
console.log(userID);
});

// socket.on('emit', (client) => { // socket.on('emit', (client) => {
// console.log(client); // console.log(client);
// }) // })
socket.on("sokkk", (clg) => { socket.on("sokkk", (clg) => {
console.log(clg); console.log(clg);
})
});
// socket.onAny((event, ...args) => { // socket.onAny((event, ...args) => {
// console.log(event, args); // console.log(event, args);
// }); // });
socket.on('povratna', (data) => {
console.log(data)

})
socket.on("povratna", (data) => {
console.log(data);
});
socket.on("private_message", (data) => {
console.log(data);
});


// socket.open; // socket.open;


// socket.emit("sock") // socket.emit("sock")
}; };
const sendPing = () => { const sendPing = () => {
socket.emit("sokkk", {
poruka: "Za Duleta"
socket.emit("private_message", {
text: "Probica",
// toUserId: "62de5844dff6f986e43d14f6",
toUserId: "62de57c6dff6f986e43d14ec",
chatId: "62eb8424632e1112ef467750",
}); });
}; };
const disconnect = () => {
// socket.disconnect();
socket.disconnect();
};
console.log(socket);
return ( return (
<Router history={history}> <Router history={history}>
<Helmet> <Helmet>
<Header /> <Header />
<GlobalStyle /> <GlobalStyle />
<ToastContainer /> <ToastContainer />
{/* <div>
{/* <div style={{ position: "relative", top: "100px", left: "400px" }}>
<p>Connected: {"" + isConnected}</p> <p>Connected: {"" + isConnected}</p>
<br /> <br />
<p>Last pong: {lastPong || "-"}</p> <p>Last pong: {lastPong || "-"}</p>
<br /> <br />
<button onClick={sendPing}>Send ping</button> <button onClick={sendPing}>Send ping</button>
<br />
<button onClick={disconnect}>Disconnect</button>
</div> */} </div> */}
<AppRoutes />
<AppRoutes />
</StyledEngineProvider> </StyledEngineProvider>
</Router> </Router>
); );

+ 10
- 1
src/components/Popovers/HeaderPopover/HeaderPopover.js Zobrazit soubor

import PropTypes from "prop-types"; import PropTypes from "prop-types";
import { import {
HeaderPopoverContainer, HeaderPopoverContainer,
NameOfProduct,
PopoverButton, PopoverButton,
PopoverButtonsContainer, PopoverButtonsContainer,
PopoverList, PopoverList,
PopoverListItemTextContainer, PopoverListItemTextContainer,
PopoverNoItemsText, PopoverNoItemsText,
PopoverTitle, PopoverTitle,
SecondaryText,
SecondaryTextContainer,
} from "./HeaderPopover.styled"; } from "./HeaderPopover.styled";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";


onClick: item.onClick, onClick: item.onClick,
}} }}
primary={item.title} primary={item.title}
secondary={item.text}
secondary={
<SecondaryTextContainer>
<SecondaryText>{item.text}</SecondaryText>
<NameOfProduct>{item?.bigText}</NameOfProduct>
</SecondaryTextContainer>
}
></PopoverListItemTextContainer> ></PopoverListItemTextContainer>
</PopoverListItem> </PopoverListItem>
)) ))
buttonOnClick: PropTypes.func, buttonOnClick: PropTypes.func,
secondButtonOnClick: PropTypes.func, secondButtonOnClick: PropTypes.func,
hideButtons: PropTypes.bool, hideButtons: PropTypes.bool,
bigText: PropTypes.string,
}; };


export default HeaderPopover; export default HeaderPopover;

+ 18
- 0
src/components/Popovers/HeaderPopover/HeaderPopover.styled.js Zobrazit soubor

font-size: 13px; font-size: 13px;
font-family: "DM Sans"; font-family: "DM Sans";
`; `;
export const NameOfProduct = styled(Typography)`
font-size: 12px;
font-weight: 700;
font-family: "DM Sans";
letter-spacing: 0.02em;
color: ${selectedTheme.primaryDarkText};
`;
export const SecondaryTextContainer = styled(Box)`
display: flex;
flex-direction: row;
gap: 4px;
`;
export const SecondaryText = styled(Typography)`
font-family: "DM Sans";
font-size: 9px;
letter-spacing: 0.01em;
color: ${selectedTheme.primaryDarkText};
`;

+ 3
- 1
src/components/Popovers/MyMessages/MyMessages.js Zobrazit soubor

const [lastChats, setLastChats] = useState([]); const [lastChats, setLastChats] = useState([]);


const convertMessages = (messages) => { const convertMessages = (messages) => {
console.log(messages)
return messages return messages
.map((item) => ({ .map((item) => ({
src: item.interlocutorData.image, src: item.interlocutorData.image,
title: item.interlocutorData.name, title: item.interlocutorData.name,
onClick: () => goToMessage(item?.chat?._id), onClick: () => goToMessage(item?.chat?._id),
text: item?.chat?.messages[item?.chat?.messages?.length - 1]?.text,
text: "Proizvod: ",
bigText: item.offerData.name
})) }))
.slice(0, 2); .slice(0, 2);
}; };

+ 73
- 0
src/components/TextFields/AutoSuggestTextField/AutoSuggestTextField.js Zobrazit soubor

import React, { useState } from "react";
import PropTypes from "prop-types";
import Autosuggest from "react-autosuggest";
import { AutoSuggestTextFieldContainer } from "./AutoSuggestTextField.styled";

const escapeRegexCharacters = (str) =>
str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");

const AutoSuggestTextField = (props) => {
const [suggestions, setSuggestions] = useState([]);
const data = [...props.data];

const getSuggestions = (value) => {
const escapedValue = escapeRegexCharacters(value.trim());
if (escapedValue === "") {
return [];
}
const regex = new RegExp("^" + escapedValue, "i");
const suggestions = data.filter((dataItem) => regex.test(dataItem.name));
if (suggestions.length === 0) {
return [{ isAddNew: true }];
}
return suggestions;
};

const getSuggestionValue = (suggestion) => {
return suggestion.name;
};

const onSuggestionsFetchRequested = ({ value }) => {
setSuggestions(getSuggestions(value));
};

const onSuggestionsClearRequested = () => {
setSuggestions([]);
};

const renderSuggestion = (suggestion) => {
return suggestion.name;
};
const inputProps = {
placeholder: props.placeholder,
value: props.value,
onChange: props.onChange,
};

return (
<AutoSuggestTextFieldContainer>
<Autosuggest
suggestions={suggestions}
onSuggestionsFetchRequested={onSuggestionsFetchRequested}
onSuggestionsClearRequested={onSuggestionsClearRequested}
getSuggestionValue={getSuggestionValue}
renderSuggestion={renderSuggestion}
inputProps={inputProps}
/>
</AutoSuggestTextFieldContainer>
);
};

AutoSuggestTextField.propTypes = {
children: PropTypes.node,
placeholder: PropTypes.string,
value: PropTypes.string,
onChange: PropTypes.func,
data: PropTypes.array,
};

export default AutoSuggestTextField;

+ 59
- 0
src/components/TextFields/AutoSuggestTextField/AutoSuggestTextField.styled.js Zobrazit soubor

import styled from "styled-components";
import { Box } from "@mui/material";
import selectedTheme from "../../../themes";

export const AutoSuggestTextFieldContainer = styled(Box)`
& .react-autosuggest__container {
width: 100%;
height: 48px;
position: relative;
z-index: 20;
& input {
width: 100%;
height: 48px;
padding: 4px 14px;
border-radius: 4px;
border: 1px solid rgba(0, 0, 0, 0.23);
outline-width: 0;
background-color: initial;
font-family: "DM Sans";
font-size: 16px;
padding-bottom: 6px;
}
/* & input:hover {
border: 1px solid rgba(0, 0, 0, 0.87);
} */
& input:focus-visible {
border: 2px solid ${selectedTheme.primaryPurple};
}
& input::placeholder {
color: rgba(0,0,0, 0.38);
}

& div {
z-index: 3000;
background-color: ${selectedTheme.primaryBackgroundColor};
}

& div ul {
border: 1px solid black;
border-radius: 4px;

padding: 10px;
}

& div ul li {
padding-left: 16px;
cursor: pointer;
height: 40px;
padding-top: 10px;
font-family: "DM Sans";
border-radius: 4px;
}

& div ul li:hover {
background-color: ${selectedTheme.primaryPurple};
color: ${selectedTheme.primaryBackgroundColor};
}
}
`;

+ 1
- 1
src/components/TextFields/TextField/TextField.js Zobrazit soubor

italicPlaceholder: false, italicPlaceholder: false,
showAnimation: false, showAnimation: false,
height: "48px", height: "48px",
// font: "DM Sans"
font: "DM Sans"
}; };

+ 4
- 1
src/hooks/useToggleColorMode.js Zobrazit soubor

authScopeSetHelper, authScopeSetHelper,
authScopeStringGetHelper, authScopeStringGetHelper,
} from '../util/helpers/authScopeHelpers'; } from '../util/helpers/authScopeHelpers';
import selectedTheme from '../themes';


const useToggleColorMode = () => { const useToggleColorMode = () => {
const currentColorMode = authScopeStringGetHelper('colorMode') || 'light'; const currentColorMode = authScopeStringGetHelper('colorMode') || 'light';
() => () =>
createTheme({ createTheme({
palette: { palette: {
mode,
primary: {
main: selectedTheme.primaryPurple
}
}, },
}), }),
[mode] [mode]

+ 3
- 0
src/i18n/resources/rs.js Zobrazit soubor

welcome: "Dobro došli na trampu, želimo vam uspešno trampovanje!", welcome: "Dobro došli na trampu, želimo vam uspešno trampovanje!",
imageError: "Slika je obavezna!", imageError: "Slika je obavezna!",
serverError: "Greška sa serverom!", serverError: "Greška sa serverom!",
phoneNumberNoOfCharacters: "Broj telefona mora imati izmedju 6 i 15 karaktera!",
locationError: "Odaberite ispravnu lokaciju!",
websiteError: "Unesite ispravnu adresu svog website!"
}, },
forgotPassword: { forgotPassword: {
title: "Povrati lozinku", title: "Povrati lozinku",

+ 34
- 15
src/pages/RegisterPages/Register/ThirdPart/ThirdPartOfRegistration.js Zobrazit soubor

import { TextField } from "../../../../components/TextFields/TextField/TextField"; import { TextField } from "../../../../components/TextFields/TextField/TextField";
import { PrimaryButton } from "../../../../components/Buttons/PrimaryButton/PrimaryButton"; import { PrimaryButton } from "../../../../components/Buttons/PrimaryButton/PrimaryButton";
import selectedTheme from "../../../../themes"; import selectedTheme from "../../../../themes";
import AutoSuggestTextField from "../../../../components/TextFields/AutoSuggestTextField/AutoSuggestTextField";
import { useSelector } from "react-redux";
import { selectLocations } from "../../../../store/selectors/locationsSelectors";
import { ErrorMessage } from "../FirstPart/FirstPartOfRegistration.styled";


const ThirdPartOfRegistration = (props) => { const ThirdPartOfRegistration = (props) => {
const { t } = useTranslation(); const { t } = useTranslation();
const locations = useSelector(selectLocations);


useEffect(() => { useEffect(() => {
if (props.informations?.phoneNumber) { if (props.informations?.phoneNumber) {
formik.setFieldValue("phoneNumber", props.informations?.phoneNumber)
formik.setFieldValue("phoneNumber", props.informations?.phoneNumber);
} }
if (props.informations?.location) { if (props.informations?.location) {
formik.setFieldValue("location", props.informations?.location)
formik.setFieldValue("location", props.informations?.location);
} }
if (props.informations?.website) { if (props.informations?.website) {
formik.setFieldValue("website", props.informations?.website)
formik.setFieldValue("website", props.informations?.website);
} }
}, [props.informations])
}, [props.informations]);


const handleSubmit = () => { const handleSubmit = () => {
if (formik.values.website?.length !== 0 && !formik.values.website.match(
/^((ftp|http|https):\/\/)?(www.)?(?!.*(ftp|http|https|www.))[a-zA-Z0-9_-]+(\.[a-zA-Z]+)+((\/)[\w#]+)*(\/\w+\?[a-zA-Z0-9_]+=\w+(&[a-zA-Z0-9_]+=\w+)*)?$/gm
)) {
if (
formik.values.website?.length !== 0 &&
!formik.values.website.match(
/^((ftp|http|https):\/\/)?(www.)?(?!.*(ftp|http|https|www.))[a-zA-Z0-9_-]+(\.[a-zA-Z]+)+((\/)[\w#]+)*(\/\w+\?[a-zA-Z0-9_]+=\w+(&[a-zA-Z0-9_]+=\w+)*)?$/gm
)
) {
formik.setFieldError("website"); formik.setFieldError("website");
} else { } else {
props.handleSubmit(formik.values); props.handleSubmit(formik.values);
} }

}
};


const formik = useFormik({ const formik = useFormik({
initialValues: { initialValues: {
}, },
validationSchema: Yup.object().shape({ validationSchema: Yup.object().shape({
phoneNumber: Yup.number(), phoneNumber: Yup.number(),
location: Yup.string(),
website: Yup.string()
location: Yup.string().oneOf(
locations.map((item) => item.city),
"Greska!!!"
),
website: Yup.string(),
}), }),
onSubmit: handleSubmit, onSubmit: handleSubmit,
validateOnBlur: true, validateOnBlur: true,
type="number" type="number"
value={formik.values.phoneNumber} value={formik.values.phoneNumber}
onChange={formik.handleChange} onChange={formik.handleChange}
error={
(formik.touched.phoneNumber && Boolean(formik.errors.phoneNumber))
}
error={formik.touched.phoneNumber && Boolean(formik.errors.phoneNumber)}
helperText={formik.touched.phoneNumber && formik.errors.phoneNumber} helperText={formik.touched.phoneNumber && formik.errors.phoneNumber}
autoFocus autoFocus
fullWidth fullWidth
/> />


<TextField
{/* <TextField
name="location" name="location"
placeholder={t("common.labelLocation")} placeholder={t("common.labelLocation")}
margin="normal" margin="normal"
error={formik.touched.location && Boolean(formik.errors.location)} error={formik.touched.location && Boolean(formik.errors.location)}
helperText={formik.touched.location && formik.errors.location} helperText={formik.touched.location && formik.errors.location}
fullWidth fullWidth
/> */}

<AutoSuggestTextField
placeholder={t("common.labelLocation")}
data={locations.map((item) => ({ name: item.city }))}
value={formik.values.location}
onChange={(event, { newValue }) =>
formik.setFieldValue("location", newValue)
}
/> />


<TextField <TextField
fullWidth fullWidth
/> />


<ErrorMessage>{formik.errors.phoneNumber}</ErrorMessage>

<PrimaryButton <PrimaryButton
type="submit" type="submit"
variant="contained" variant="contained"

Načítá se…
Zrušit
Uložit