From 187efe6a79e7518788ccb3869453fed99ed3d2a0 Mon Sep 17 00:00:00 2001 From: DianaUzun Date: Tue, 19 Sep 2023 17:05:42 +0300 Subject: [PATCH 1/4] add request for regions, fix regions --- FrontEnd/package-lock.json | 26 ++++++ FrontEnd/package.json | 1 + .../FormFields/OneSelectChip.js | 88 +++++++++++++++++++ .../ProfilePage/FormComponents/GeneralInfo.js | 23 ++++- .../src/components/ProfilePage/ProfilePage.js | 2 +- .../ProfilePageComponents/ProfileContent.js | 12 --- .../signup/signup-form/SignUpFormContent.js | 1 - .../components/authorization/LoginContent.jsx | 1 - .../landing-page/companies/Companies.js | 11 --- forum/settings.py | 2 +- profiles/serializers.py | 2 +- 11 files changed, 137 insertions(+), 32 deletions(-) create mode 100644 FrontEnd/src/components/ProfilePage/FormComponents/FormFields/OneSelectChip.js diff --git a/FrontEnd/package-lock.json b/FrontEnd/package-lock.json index 819dc02b9..783f784a8 100644 --- a/FrontEnd/package-lock.json +++ b/FrontEnd/package-lock.json @@ -22,6 +22,7 @@ "react-router-dom": "^6.4.1", "react-router-hash-link": "^2.4.3", "react-scripts": "5.0.1", + "swr": "^2.2.2", "validator": "^13.11.0", "web-vitals": "^2.1.4" } @@ -6210,6 +6211,11 @@ "node": ">=0.10.0" } }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" + }, "node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -16173,6 +16179,18 @@ "node": ">=4" } }, + "node_modules/swr": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/swr/-/swr-2.2.2.tgz", + "integrity": "sha512-CbR41AoMD4TQBQw9ic3GTXspgfM9Y8Mdhb5Ob4uIKXhWqnRLItwA5fpGvB7SmSw3+zEjb0PdhiEumtUvYoQ+bQ==", + "dependencies": { + "client-only": "^0.0.1", + "use-sync-external-store": "^1.2.0" + }, + "peerDependencies": { + "react": "^16.11.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", @@ -16774,6 +16792,14 @@ "requires-port": "^1.0.0" } }, + "node_modules/use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", diff --git a/FrontEnd/package.json b/FrontEnd/package.json index d99fbb5df..1f2d344cc 100644 --- a/FrontEnd/package.json +++ b/FrontEnd/package.json @@ -17,6 +17,7 @@ "react-router-dom": "^6.4.1", "react-router-hash-link": "^2.4.3", "react-scripts": "5.0.1", + "swr": "^2.2.2", "validator": "^13.11.0", "web-vitals": "^2.1.4" }, diff --git a/FrontEnd/src/components/ProfilePage/FormComponents/FormFields/OneSelectChip.js b/FrontEnd/src/components/ProfilePage/FormComponents/FormFields/OneSelectChip.js new file mode 100644 index 000000000..8dafebad2 --- /dev/null +++ b/FrontEnd/src/components/ProfilePage/FormComponents/FormFields/OneSelectChip.js @@ -0,0 +1,88 @@ +import css from './MultipleSelectChip.module.css'; +import Box from '@mui/material/Box'; +import Chip from '@mui/material/Chip'; +import FormControl from '@mui/material/FormControl'; +import InputLabel from '@mui/material/InputLabel'; +import MenuItem from '@mui/material/MenuItem'; +import OutlinedInput from '@mui/material/OutlinedInput'; +import Select from '@mui/material/Select'; +import { useTheme } from '@mui/material/styles'; + + +const ITEM_HEIGHT = 48; +const ITEM_PADDING_TOP = 8; +const MenuProps = { + PaperProps: { + style: { + maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP, + width: 250, + }, + }, +}; + +function getStyles(name, selectedOptions, theme) { + return { + fontWeight: + selectedOptions.indexOf(name) === -1 + ? theme.typography.fontWeightRegular + : theme.typography.fontWeightMedium, + }; +} + +export default function OneSelectChip(props) { + const theme = useTheme(); + return ( +
+
+ {props.requredField && } + +
+ + {props.defaultValue} + + + {props.requredField && +
+ {props.error} +
+ } +
+ ); +} diff --git a/FrontEnd/src/components/ProfilePage/FormComponents/GeneralInfo.js b/FrontEnd/src/components/ProfilePage/FormComponents/GeneralInfo.js index df1e1397f..90ff85e63 100644 --- a/FrontEnd/src/components/ProfilePage/FormComponents/GeneralInfo.js +++ b/FrontEnd/src/components/ProfilePage/FormComponents/GeneralInfo.js @@ -1,11 +1,13 @@ import css from './FormComponents.module.css'; import { useState, useEffect } from 'react'; +import useSWR from 'swr'; import CheckBoxField from './FormFields/CheckBoxField'; import FullField from './FormFields/FullField'; import HalfFormField from './FormFields/HalfFormField'; import ImageField from './FormFields/ImageField'; import MultipleSelectChip from './FormFields/MultipleSelectChip'; +import OneSelectChip from './FormFields/OneSelectChip'; import TextField from './FormFields/TextField'; const LABELS = { @@ -90,6 +92,8 @@ const ERRORS = { const TEXT_AREA_MAX_LENGTH = 1000; const IMAGE_SIZE = 50 * 1024 * 1024; +const fetcher = (...args) => fetch(...args).then(res => res.json()); + const GeneralInfo = (props) => { const [user, setUser] = useState(props.user); const [formStateErr, setFormStateErr] = useState(ERRORS); @@ -97,6 +101,8 @@ const GeneralInfo = (props) => { const [imageLogoError, setImageLogoError] = useState(null); const [edrpouError, setEdrpouError] = useState(null); + const { data, error, isLoading } = useSWR('http://127.0.0.1:8000/api/regions/', fetcher); + useEffect(() => { props.currentFormNameHandler(props.curForm); }, []); @@ -131,6 +137,13 @@ const GeneralInfo = (props) => { }); }; + const onUpdateOneSelectField = e => { + setUser((prevState) => { + const selectedRegion = data.find((el) => el.value === e.target.value); + return { ...prevState, [e.target.name]: selectedRegion.key }; + }); + }; + const onUpdateEdrpouField = e => { if (e.target.value && e.target.value.length !== 8) { setEdrpouError('ЄДРПОУ має містити 8 символів'); @@ -248,15 +261,17 @@ const GeneralInfo = (props) => { value={user.edrpou} error={edrpouError} /> - el.key === user.regions)? data.find((el) => el.key === user.regions).value : ''} /> + }
{ } /> - - {/* {INFOLINKS.map((el, index) => ( - } - key={el.title} - /> - ))} */} - } /> } /> } /> } /> } /> } /> - -
diff --git a/FrontEnd/src/components/SignUp/components/signup/signup-form/SignUpFormContent.js b/FrontEnd/src/components/SignUp/components/signup/signup-form/SignUpFormContent.js index 0d69203ee..779e8dde8 100644 --- a/FrontEnd/src/components/SignUp/components/signup/signup-form/SignUpFormContent.js +++ b/FrontEnd/src/components/SignUp/components/signup/signup-form/SignUpFormContent.js @@ -1,6 +1,5 @@ import { useEffect, useState } from "react"; import { useForm } from "react-hook-form"; -import axios from 'axios'; import EyeInvisible from "../../../../authorization/EyeInvisible"; import EyeVisible from "../../../../authorization/EyeVisible"; import styles from "./SignUpFormContent.module.css"; diff --git a/FrontEnd/src/components/authorization/LoginContent.jsx b/FrontEnd/src/components/authorization/LoginContent.jsx index 6effb3fc3..335d35166 100644 --- a/FrontEnd/src/components/authorization/LoginContent.jsx +++ b/FrontEnd/src/components/authorization/LoginContent.jsx @@ -1,6 +1,5 @@ import { useForm } from "react-hook-form"; import { useState, useEffect} from "react"; -import axios from 'axios'; import validator from "validator"; import EyeVisible from "./EyeVisible"; import EyeInvisible from "./EyeInvisible"; diff --git a/FrontEnd/src/components/landing-page/companies/Companies.js b/FrontEnd/src/components/landing-page/companies/Companies.js index 2e25dc841..58ccb0269 100644 --- a/FrontEnd/src/components/landing-page/companies/Companies.js +++ b/FrontEnd/src/components/landing-page/companies/Companies.js @@ -1,17 +1,6 @@ -import axios from 'axios'; import './Companies.css'; import {ProductCard} from "./companies-product-cards/CompaniesProductCards"; -async function list_of_companies() { -const companiesList = axios.get('http://localhost:8000/api/profiles/') - - .then(function (response) { - return response.data; - }) - .catch(error => {console.log(error)}); -return companiesList; -} -console.log(list_of_companies()); const MainCompanies = () => { const companyDataList = [ diff --git a/forum/settings.py b/forum/settings.py index 17e5afbe7..f987335fc 100644 --- a/forum/settings.py +++ b/forum/settings.py @@ -62,7 +62,7 @@ ] CORS_ALLOW_CREDENTIALS = True -CORS_ALLOW_ALL_ORIGINS = False +CORS_ALLOW_ALL_ORIGINS = True CORS_ORIGIN_WHITELIST = [ 'http://localhost', diff --git a/profiles/serializers.py b/profiles/serializers.py index 5a3d89d7f..c6251eeed 100644 --- a/profiles/serializers.py +++ b/profiles/serializers.py @@ -88,4 +88,4 @@ def validate(self, attrs): class RegionSerializer(serializers.Serializer): def to_representation(self, obj): - return {obj[0]: obj[1]} + return {'key':obj[0], 'value': obj[1]} From 1549a24ffa38992a51e820930480e39bb28e2533 Mon Sep 17 00:00:00 2001 From: DianaUzun Date: Tue, 19 Sep 2023 17:58:24 +0300 Subject: [PATCH 2/4] initial example of request with token --- .../ProfilePage/FormComponents/GeneralInfo.js | 28 ------------------- .../src/components/ProfilePage/ProfilePage.js | 20 +++++++++++++ 2 files changed, 20 insertions(+), 28 deletions(-) diff --git a/FrontEnd/src/components/ProfilePage/FormComponents/GeneralInfo.js b/FrontEnd/src/components/ProfilePage/FormComponents/GeneralInfo.js index 90ff85e63..c582ed39b 100644 --- a/FrontEnd/src/components/ProfilePage/FormComponents/GeneralInfo.js +++ b/FrontEnd/src/components/ProfilePage/FormComponents/GeneralInfo.js @@ -38,34 +38,6 @@ const CATEGORIES = [ { name: "Спеції" }, ]; -const REGIONS = [ - { name: "Київська область" }, - { name: "Вінницька область" }, - { name: "Волинська область" }, - { name: "Дніпропетровська область" }, - { name: "Донецька область" }, - { name: "Житомирська область" }, - { name: "Закарпатська область" }, - { name: "Запорізька область" }, - { name: "Івано-Франківська область" }, - { name: "Кіровоградська область" }, - { name: "Крим" }, - { name: "Луганська область" }, - { name: "Львівська область" }, - { name: "Миколаївська область" }, - { name: "Одеська область" }, - { name: "Полтавська область" }, - { name: "Рівненська область" }, - { name: "Сумська область" }, - { name: "Тернопільська область" }, - { name: "Харківська область" }, - { name: "Херсонська область" }, - { name: "Хмельницька область" }, - { name: "Черкаська область" }, - { name: "Чернівецька область" }, - { name: "Чернігівська область" }, -]; - const ACTIVITIES = [ { name: "Виробництво" }, { name: "Роздрібна мережа" }, diff --git a/FrontEnd/src/components/ProfilePage/ProfilePage.js b/FrontEnd/src/components/ProfilePage/ProfilePage.js index 7f6e3c44e..d4e162b7e 100644 --- a/FrontEnd/src/components/ProfilePage/ProfilePage.js +++ b/FrontEnd/src/components/ProfilePage/ProfilePage.js @@ -3,6 +3,7 @@ import Description from './ProfilePageComponents/Description'; import ProfileContent from './ProfilePageComponents/ProfileContent'; import { useState } from 'react'; import BreadCrumbs from '../BreadCrumbs/BreadCrumbs'; +import useSWR from 'swr'; const USER = { 'email': 'ex@gmail.com', @@ -53,6 +54,19 @@ const USER = { 'Youtube': '', }; +// const fetcher = (...args) => fetch(...args).then(res => res.json()); +const fetcher = async (url, token) => { + const headers = { + Authorization: `Token ${token}`, + }; + const response = await fetch(url, { headers }); + + if (!response.ok) { + throw new Error('Network response was not ok'); + } + return response.json(); + }; + const ProfilePage = () => { const [mainUser, setMainUser] = useState(USER); const [formName, setFormName] = useState(''); @@ -60,6 +74,12 @@ const ProfilePage = () => { setFormName(currentName); }; + const token = '661d6d53d89502c80fbb3d0408c302e81364a8a3'; + const { data, error } = useSWR(['http://127.0.0.1:8000/api/profiles/1', token], ([url, token]) => fetcher(url, token)) + + console.log('in app', data); + + const profileUpdateHandler = (myUser) => { console.log('in app'); console.log(myUser); From 569db69b728d8b0385107094aae7a70ad7b303a1 Mon Sep 17 00:00:00 2001 From: DianaUzun Date: Wed, 20 Sep 2023 16:56:24 +0300 Subject: [PATCH 3/4] remove useless code --- .../ProfilePage/FormComponents/GeneralInfo.js | 10 +++++---- .../src/components/ProfilePage/ProfilePage.js | 21 +------------------ forum/settings.py | 6 +++--- 3 files changed, 10 insertions(+), 27 deletions(-) diff --git a/FrontEnd/src/components/ProfilePage/FormComponents/GeneralInfo.js b/FrontEnd/src/components/ProfilePage/FormComponents/GeneralInfo.js index c582ed39b..f82df61c6 100644 --- a/FrontEnd/src/components/ProfilePage/FormComponents/GeneralInfo.js +++ b/FrontEnd/src/components/ProfilePage/FormComponents/GeneralInfo.js @@ -73,7 +73,7 @@ const GeneralInfo = (props) => { const [imageLogoError, setImageLogoError] = useState(null); const [edrpouError, setEdrpouError] = useState(null); - const { data, error, isLoading } = useSWR('http://127.0.0.1:8000/api/regions/', fetcher); + const { data: fetchedRegions, error, isLoading } = useSWR('http://127.0.0.1:8000/api/regions/', fetcher); useEffect(() => { props.currentFormNameHandler(props.curForm); @@ -111,7 +111,7 @@ const GeneralInfo = (props) => { const onUpdateOneSelectField = e => { setUser((prevState) => { - const selectedRegion = data.find((el) => el.value === e.target.value); + const selectedRegion = fetchedRegions.find((el) => el.value === e.target.value); return { ...prevState, [e.target.name]: selectedRegion.key }; }); }; @@ -236,12 +236,14 @@ const GeneralInfo = (props) => { {!isLoading && el.key === user.regions)? data.find((el) => el.key === user.regions).value : ''} + value={fetchedRegions.find((el) => el.key === user.regions) + ? fetchedRegions.find((el) => el.key === user.regions).value + : ''} /> } diff --git a/FrontEnd/src/components/ProfilePage/ProfilePage.js b/FrontEnd/src/components/ProfilePage/ProfilePage.js index d4e162b7e..a87c7f7da 100644 --- a/FrontEnd/src/components/ProfilePage/ProfilePage.js +++ b/FrontEnd/src/components/ProfilePage/ProfilePage.js @@ -3,7 +3,7 @@ import Description from './ProfilePageComponents/Description'; import ProfileContent from './ProfilePageComponents/ProfileContent'; import { useState } from 'react'; import BreadCrumbs from '../BreadCrumbs/BreadCrumbs'; -import useSWR from 'swr'; + const USER = { 'email': 'ex@gmail.com', @@ -54,19 +54,6 @@ const USER = { 'Youtube': '', }; -// const fetcher = (...args) => fetch(...args).then(res => res.json()); -const fetcher = async (url, token) => { - const headers = { - Authorization: `Token ${token}`, - }; - const response = await fetch(url, { headers }); - - if (!response.ok) { - throw new Error('Network response was not ok'); - } - return response.json(); - }; - const ProfilePage = () => { const [mainUser, setMainUser] = useState(USER); const [formName, setFormName] = useState(''); @@ -74,12 +61,6 @@ const ProfilePage = () => { setFormName(currentName); }; - const token = '661d6d53d89502c80fbb3d0408c302e81364a8a3'; - const { data, error } = useSWR(['http://127.0.0.1:8000/api/profiles/1', token], ([url, token]) => fetcher(url, token)) - - console.log('in app', data); - - const profileUpdateHandler = (myUser) => { console.log('in app'); console.log(myUser); diff --git a/forum/settings.py b/forum/settings.py index f987335fc..7746844cf 100644 --- a/forum/settings.py +++ b/forum/settings.py @@ -62,16 +62,16 @@ ] CORS_ALLOW_CREDENTIALS = True -CORS_ALLOW_ALL_ORIGINS = True +CORS_ALLOW_ALL_ORIGINS = False CORS_ORIGIN_WHITELIST = [ - 'http://localhost', + 'http://localhost:3000', 'http://127.0.0.1', 'http://0.0.0.0', ] CORS_ALLOWED_ORIGINS = [ - 'http://localhost', + 'http://localhost:3000', 'http://127.0.0.1', 'http://0.0.0.0', ] From cdcfab916ab7da7df5577e11e15ce3913752382a Mon Sep 17 00:00:00 2001 From: DianaUzun Date: Sat, 23 Sep 2023 19:40:28 +0300 Subject: [PATCH 4/4] improve a condition expression --- .../ProfilePage/FormComponents/FormFields/OneSelectChip.js | 2 +- .../src/components/ProfilePage/FormComponents/GeneralInfo.js | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/FrontEnd/src/components/ProfilePage/FormComponents/FormFields/OneSelectChip.js b/FrontEnd/src/components/ProfilePage/FormComponents/FormFields/OneSelectChip.js index 8dafebad2..d5434efde 100644 --- a/FrontEnd/src/components/ProfilePage/FormComponents/FormFields/OneSelectChip.js +++ b/FrontEnd/src/components/ProfilePage/FormComponents/FormFields/OneSelectChip.js @@ -64,7 +64,7 @@ export default function OneSelectChip(props) { key={option.key} value={option.value} style={{ - ...getStyles(option.name, props.value, theme), + ...getStyles(option.value, props.value, theme), fontFamily: 'Inter, sans-serif', fontSize: '14px', fontWeight: 400, diff --git a/FrontEnd/src/components/ProfilePage/FormComponents/GeneralInfo.js b/FrontEnd/src/components/ProfilePage/FormComponents/GeneralInfo.js index f82df61c6..4c78db86e 100644 --- a/FrontEnd/src/components/ProfilePage/FormComponents/GeneralInfo.js +++ b/FrontEnd/src/components/ProfilePage/FormComponents/GeneralInfo.js @@ -241,9 +241,7 @@ const GeneralInfo = (props) => { updateHandler={onUpdateOneSelectField} requredField={false} defaultValue="Оберіть" - value={fetchedRegions.find((el) => el.key === user.regions) - ? fetchedRegions.find((el) => el.key === user.regions).value - : ''} + value={fetchedRegions.find((el) => el.key === user.regions)?.value ?? ''} /> }