| @@ -2,6 +2,7 @@ import React from "react"; | |||
| import PropTypes from "prop-types"; | |||
| import { | |||
| HeaderPopoverContainer, | |||
| NameOfProduct, | |||
| PopoverButton, | |||
| PopoverButtonsContainer, | |||
| PopoverList, | |||
| @@ -12,6 +13,8 @@ import { | |||
| PopoverListItemTextContainer, | |||
| PopoverNoItemsText, | |||
| PopoverTitle, | |||
| SecondaryText, | |||
| SecondaryTextContainer, | |||
| } from "./HeaderPopover.styled"; | |||
| import { useTranslation } from "react-i18next"; | |||
| @@ -44,7 +47,12 @@ const HeaderPopover = (props) => { | |||
| onClick: item.onClick, | |||
| }} | |||
| primary={item.title} | |||
| secondary={item.text} | |||
| secondary={ | |||
| <SecondaryTextContainer> | |||
| <SecondaryText>{item.text}</SecondaryText> | |||
| <NameOfProduct>{item?.bigText}</NameOfProduct> | |||
| </SecondaryTextContainer> | |||
| } | |||
| ></PopoverListItemTextContainer> | |||
| </PopoverListItem> | |||
| )) | |||
| @@ -95,6 +103,7 @@ HeaderPopover.propTypes = { | |||
| buttonOnClick: PropTypes.func, | |||
| secondButtonOnClick: PropTypes.func, | |||
| hideButtons: PropTypes.bool, | |||
| bigText: PropTypes.string, | |||
| }; | |||
| export default HeaderPopover; | |||
| @@ -85,3 +85,21 @@ export const PopoverNoItemsText = styled(Typography)` | |||
| font-size: 13px; | |||
| 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}; | |||
| `; | |||
| @@ -17,12 +17,14 @@ export const MyMessages = (props) => { | |||
| const [lastChats, setLastChats] = useState([]); | |||
| const convertMessages = (messages) => { | |||
| console.log(messages) | |||
| return messages | |||
| .map((item) => ({ | |||
| src: item.interlocutorData.image, | |||
| title: item.interlocutorData.name, | |||
| onClick: () => goToMessage(item?.chat?._id), | |||
| text: item?.chat?.messages[item?.chat?.messages?.length - 1]?.text, | |||
| text: "Proizvod: ", | |||
| bigText: item.offerData.name | |||
| })) | |||
| .slice(0, 2); | |||
| }; | |||
| @@ -3,96 +3,31 @@ import PropTypes from "prop-types"; | |||
| import Autosuggest from "react-autosuggest"; | |||
| import { AutoSuggestTextFieldContainer } from "./AutoSuggestTextField.styled"; | |||
| const languages = [ | |||
| { | |||
| name: "C", | |||
| year: 1972, | |||
| }, | |||
| { | |||
| name: "C#", | |||
| year: 2000, | |||
| }, | |||
| { | |||
| name: "C++", | |||
| year: 1983, | |||
| }, | |||
| { | |||
| name: "Clojure", | |||
| year: 2007, | |||
| }, | |||
| { | |||
| name: "Elm", | |||
| year: 2012, | |||
| }, | |||
| { | |||
| name: "Go", | |||
| year: 2009, | |||
| }, | |||
| { | |||
| name: "Haskell", | |||
| year: 1990, | |||
| }, | |||
| { | |||
| name: "Java", | |||
| year: 1995, | |||
| }, | |||
| { | |||
| name: "Javascript", | |||
| year: 1995, | |||
| }, | |||
| { | |||
| name: "Perl", | |||
| year: 1987, | |||
| }, | |||
| { | |||
| name: "PHP", | |||
| year: 1995, | |||
| }, | |||
| { | |||
| name: "Python", | |||
| year: 1991, | |||
| }, | |||
| { | |||
| name: "Ruby", | |||
| year: 1995, | |||
| }, | |||
| { | |||
| name: "Scala", | |||
| year: 2003, | |||
| }, | |||
| ]; | |||
| const escapeRegexCharacters = (str) => | |||
| str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); | |||
| const getSuggestions = (value) => { | |||
| const escapedValue = escapeRegexCharacters(value.trim()); | |||
| if (escapedValue === "") { | |||
| return []; | |||
| } | |||
| const regex = new RegExp("^" + escapedValue, "i"); | |||
| const suggestions = languages.filter((language) => regex.test(language.name)); | |||
| if (suggestions.length === 0) { | |||
| return [{ isAddNew: true }]; | |||
| } | |||
| return suggestions; | |||
| }; | |||
| const AutoSuggestTextField = () => { | |||
| const [value, setValue] = useState(""); | |||
| const AutoSuggestTextField = (props) => { | |||
| const [suggestions, setSuggestions] = useState([]); | |||
| const data = [...props.data]; | |||
| const onChange = (event, { newValue }) => { | |||
| setValue(newValue); | |||
| 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) => { | |||
| if (suggestion.isAddNew) { | |||
| return value; | |||
| } | |||
| return suggestion.name; | |||
| }; | |||
| @@ -104,27 +39,13 @@ const AutoSuggestTextField = () => { | |||
| setSuggestions([]); | |||
| }; | |||
| const onSuggestionSelected = (event, { suggestion }) => { | |||
| if (suggestion.isAddNew) { | |||
| console.log("Add new:", value); | |||
| } | |||
| }; | |||
| const renderSuggestion = (suggestion) => { | |||
| if (suggestion.isAddNew) { | |||
| return ( | |||
| <span> | |||
| [+] Add new: <strong>{value}</strong> | |||
| </span> | |||
| ); | |||
| } | |||
| return suggestion.name; | |||
| }; | |||
| const inputProps = { | |||
| placeholder: "Type 'c'", | |||
| value, | |||
| onChange: onChange, | |||
| placeholder: props.placeholder, | |||
| value: props.value, | |||
| onChange: props.onChange, | |||
| }; | |||
| return ( | |||
| @@ -135,7 +56,6 @@ const AutoSuggestTextField = () => { | |||
| onSuggestionsClearRequested={onSuggestionsClearRequested} | |||
| getSuggestionValue={getSuggestionValue} | |||
| renderSuggestion={renderSuggestion} | |||
| onSuggestionSelected={onSuggestionSelected} | |||
| inputProps={inputProps} | |||
| /> | |||
| </AutoSuggestTextFieldContainer> | |||
| @@ -144,6 +64,10 @@ const AutoSuggestTextField = () => { | |||
| AutoSuggestTextField.propTypes = { | |||
| children: PropTypes.node, | |||
| placeholder: PropTypes.string, | |||
| value: PropTypes.string, | |||
| onChange: PropTypes.func, | |||
| data: PropTypes.array, | |||
| }; | |||
| export default AutoSuggestTextField; | |||
| @@ -20,15 +20,40 @@ export const AutoSuggestTextFieldContainer = styled(Box)` | |||
| font-size: 16px; | |||
| padding-bottom: 6px; | |||
| } | |||
| & input:hover { | |||
| /* & 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 { | |||
| background-color: white; | |||
| 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}; | |||
| } | |||
| } | |||
| `; | |||
| @@ -101,5 +101,5 @@ TextField.defaultProps = { | |||
| italicPlaceholder: false, | |||
| showAnimation: false, | |||
| height: "48px", | |||
| // font: "DM Sans" | |||
| font: "DM Sans" | |||
| }; | |||
| @@ -4,6 +4,7 @@ import { | |||
| authScopeSetHelper, | |||
| authScopeStringGetHelper, | |||
| } from '../util/helpers/authScopeHelpers'; | |||
| import selectedTheme from '../themes'; | |||
| const useToggleColorMode = () => { | |||
| const currentColorMode = authScopeStringGetHelper('colorMode') || 'light'; | |||
| @@ -19,7 +20,9 @@ const useToggleColorMode = () => { | |||
| () => | |||
| createTheme({ | |||
| palette: { | |||
| mode, | |||
| primary: { | |||
| main: selectedTheme.primaryPurple | |||
| } | |||
| }, | |||
| }), | |||
| [mode] | |||
| @@ -99,6 +99,9 @@ export default { | |||
| welcome: "Dobro došli na trampu, želimo vam uspešno trampovanje!", | |||
| imageError: "Slika je obavezna!", | |||
| 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: { | |||
| title: "Povrati lozinku", | |||
| @@ -11,32 +11,38 @@ import { TextField } from "../../../../components/TextFields/TextField/TextField | |||
| import { PrimaryButton } from "../../../../components/Buttons/PrimaryButton/PrimaryButton"; | |||
| 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 { t } = useTranslation(); | |||
| const locations = useSelector(selectLocations); | |||
| useEffect(() => { | |||
| if (props.informations?.phoneNumber) { | |||
| formik.setFieldValue("phoneNumber", props.informations?.phoneNumber) | |||
| formik.setFieldValue("phoneNumber", props.informations?.phoneNumber); | |||
| } | |||
| if (props.informations?.location) { | |||
| formik.setFieldValue("location", props.informations?.location) | |||
| formik.setFieldValue("location", props.informations?.location); | |||
| } | |||
| if (props.informations?.website) { | |||
| formik.setFieldValue("website", props.informations?.website) | |||
| formik.setFieldValue("website", props.informations?.website); | |||
| } | |||
| }, [props.informations]) | |||
| }, [props.informations]); | |||
| 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"); | |||
| } else { | |||
| props.handleSubmit(formik.values); | |||
| } | |||
| } | |||
| }; | |||
| const formik = useFormik({ | |||
| initialValues: { | |||
| @@ -46,8 +52,11 @@ const ThirdPartOfRegistration = (props) => { | |||
| }, | |||
| validationSchema: Yup.object().shape({ | |||
| phoneNumber: Yup.number(), | |||
| location: Yup.string(), | |||
| website: Yup.string() | |||
| location: Yup.string().oneOf( | |||
| locations.map((item) => item.city), | |||
| "Greska!!!" | |||
| ), | |||
| website: Yup.string(), | |||
| }), | |||
| onSubmit: handleSubmit, | |||
| validateOnBlur: true, | |||
| @@ -67,15 +76,13 @@ const ThirdPartOfRegistration = (props) => { | |||
| type="number" | |||
| value={formik.values.phoneNumber} | |||
| 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} | |||
| autoFocus | |||
| fullWidth | |||
| /> | |||
| <TextField | |||
| {/* <TextField | |||
| name="location" | |||
| placeholder={t("common.labelLocation")} | |||
| margin="normal" | |||
| @@ -85,6 +92,15 @@ const ThirdPartOfRegistration = (props) => { | |||
| error={formik.touched.location && Boolean(formik.errors.location)} | |||
| helperText={formik.touched.location && formik.errors.location} | |||
| 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 | |||
| @@ -99,7 +115,7 @@ const ThirdPartOfRegistration = (props) => { | |||
| fullWidth | |||
| /> | |||
| <AutoSuggestTextField /> | |||
| <ErrorMessage>{formik.errors.phoneNumber}</ErrorMessage> | |||
| <PrimaryButton | |||
| type="submit" | |||