From 72c3028d6f06aa813c0e742abe7c0c99f3338182 Mon Sep 17 00:00:00 2001 From: Sofia Bilous Date: Thu, 19 Oct 2023 21:11:21 +0300 Subject: [PATCH] stars, swr --- FrontEnd/src/App.js | 2 +- FrontEnd/src/components/SearchPage/Search.js | 61 +++---- .../SearchPage/search_field/SearchResults.js | 7 +- .../search_field/companies/Companies.js | 107 ------------- .../search_field/companies/CompanyCard.js | 151 ++++++++++++++++++ ...ards.module.css => CompanyCard.module.css} | 5 + .../src/components/basicPage/BasicPage.jsx | 10 +- 7 files changed, 191 insertions(+), 152 deletions(-) delete mode 100644 FrontEnd/src/components/SearchPage/search_field/companies/Companies.js create mode 100644 FrontEnd/src/components/SearchPage/search_field/companies/CompanyCard.js rename FrontEnd/src/components/SearchPage/search_field/companies/{CompaniesCards.module.css => CompanyCard.module.css} (98%) diff --git a/FrontEnd/src/App.js b/FrontEnd/src/App.js index cbb520131..7b06606b4 100644 --- a/FrontEnd/src/App.js +++ b/FrontEnd/src/App.js @@ -17,7 +17,7 @@ function App() { } /> } /> - } /> + } /> diff --git a/FrontEnd/src/components/SearchPage/Search.js b/FrontEnd/src/components/SearchPage/Search.js index 8b64fd5f5..374ffa510 100644 --- a/FrontEnd/src/components/SearchPage/Search.js +++ b/FrontEnd/src/components/SearchPage/Search.js @@ -1,5 +1,6 @@ import axios from 'axios'; -// import { useSWRConfig } from 'swr'; +import { useSWRConfig } from 'swr'; +import useSWRMutation from 'swr/mutation'; import { useState, useEffect } from 'react'; import { useLocation } from 'react-router-dom'; import BreadCrumbs from '../BreadCrumbs/BreadCrumbs'; @@ -21,48 +22,36 @@ export function Search(props) { const searchTerm = searchParams.get('name'); const servedAddress = process.env.REACT_APP_BASE_API_URL; const searchUrl = 'search'; + const { mutate } = useSWRConfig(); - // useEffect(() => { - // if (searchTerm) { - // // Make an AJAX request to Django API to get search results - // axios - // .get(`${servedAddress}/api/search/?name=${searchTerm}`) - // .then((response) => { - // setSearchResults(response.data); - // setSearchPerformed(true); - // setError(null); // Clear error on successful response - // }) - // .catch((error) => { - // console.error('Error fetching search results:', error); - // setError(error.response ? error.response.data : 'An error occurred'); - // }); - // } - // }, [searchTerm, servedAddress, searchUrl]); + const fetcher = (url) => axios.get(url).then((res) => res.data); + + async function getRequest(url) { + const data = await fetcher(url); + setSearchResults(data); + setSearchPerformed(true); + setError(null); + } + + const { trigger } = useSWRMutation( + `${servedAddress}/api/search/?name=${searchTerm}`, + getRequest + ); + + mutate((key) => typeof key === 'string' && key.startsWith('/api/search/'), { + revalidate: true, + }); useEffect(() => { if (searchTerm) { - // Make an AJAX request to Django API to get search results - axios - .get(`${servedAddress}/api/search/?name=${searchTerm}`) - .then((response) => { - setSearchResults(response.data); - setSearchPerformed(true); - setError(null); // Clear error on successful response - }) - .catch((error) => { - console.error('Error fetching search results:', error); - setError(error.response ? error.response.data : 'An error occurred'); - }); + try { + trigger(); + } catch (error) { + console.error(error); + } } }, [searchTerm, servedAddress, searchUrl]); - // const fetcher = url => axios.get(url).then(res => res.data) - - // function fetchSearchResults () { - // const { data, error } = useSWR('/api/data', fetcher) - // // ... - // } - const [currentPage, setCurrentPage] = useState(1); const totalItems = searchResults.length; const totalPages = Math.ceil(totalItems / ITEMS_PER_PAGE); diff --git a/FrontEnd/src/components/SearchPage/search_field/SearchResults.js b/FrontEnd/src/components/SearchPage/search_field/SearchResults.js index a812d07e7..8f51981ef 100644 --- a/FrontEnd/src/components/SearchPage/search_field/SearchResults.js +++ b/FrontEnd/src/components/SearchPage/search_field/SearchResults.js @@ -1,4 +1,4 @@ -import MainCompanies from './companies/Companies'; +import CompanyCard from './companies/CompanyCard'; import styles from './Text.module.css'; const SearchResults = ({ results, displayedResults, isAuthorized }) => { @@ -15,10 +15,7 @@ const SearchResults = ({ results, displayedResults, isAuthorized }) => {
{displayedResults.map((result, resultIndex) => (
- +
))}
diff --git a/FrontEnd/src/components/SearchPage/search_field/companies/Companies.js b/FrontEnd/src/components/SearchPage/search_field/companies/Companies.js deleted file mode 100644 index 030c35426..000000000 --- a/FrontEnd/src/components/SearchPage/search_field/companies/Companies.js +++ /dev/null @@ -1,107 +0,0 @@ -import { Link } from 'react-router-dom'; -import wish_list_checklist from './img/wish_list_checklist.svg'; -import wish_list_checklist_added from './img/wish_list_checklist_added.svg'; -import styles from './CompaniesCards.module.css'; - -const MainCompanies = ({ companyData, isAuthorized }) => { - const currentDate = new Date(); - const currentYear = currentDate.getFullYear(); - - const usersSavedList = []; - const yearsOfExperiense = companyData.founded - ? currentYear - companyData.founded - : 0; - - return ( -
-
-
- {companyData.name} -
-
-
-
- {companyData.categories && - companyData.categories - .map((category) => category.name) - .join(' ')} -
-
- - {companyData.name} - -
-
-
-
- {companyData.address} -
-
-
-
-
- {yearsOfExperiense} років досвіду -
-
-
- - {/* if user is authorized - show add to favorite button*/} - {isAuthorized === true && ( - <> - {/* Add checking if company is in user list */} - {usersSavedList.includes(companyData.id) ? ( - <> -
- {/* if company added - del from saved list */} - -
- - ) : ( - <> -
- {/* if compony not added - add to saved list */} - -
- - )} - - )} -
-
-
-
-
- - {/* {`${companyData.name} */} -
-
-
- ); -}; - -export default MainCompanies; diff --git a/FrontEnd/src/components/SearchPage/search_field/companies/CompanyCard.js b/FrontEnd/src/components/SearchPage/search_field/companies/CompanyCard.js new file mode 100644 index 000000000..a2d57a383 --- /dev/null +++ b/FrontEnd/src/components/SearchPage/search_field/companies/CompanyCard.js @@ -0,0 +1,151 @@ +import { Link } from 'react-router-dom'; +import { StarOutlined, StarFilled } from '@ant-design/icons'; +import { useState, useEffect } from 'react'; +import { useSWRConfig } from 'swr'; +import useSWRMutation from 'swr/mutation'; +// import useSWR from 'swr'; +import axios from 'axios'; +import styles from './CompanyCard.module.css'; + +const CompanyCard = ({ companyData, isAuthorized }) => { + const { mutate } = useSWRConfig(); + const authToken = localStorage.getItem('Token'); + const currentDate = new Date(); + const currentYear = currentDate.getFullYear(); + const yearsOfExperiense = companyData.founded + ? currentYear - companyData.founded + : 0; + const [usersSavedList, setUsersSavedList] = useState([]); + const [star, setStar] = useState(false); + const [isSaved, setIsSaved] = useState(false); + + async function sendRequest(url, { arg: data }) { + return fetch(url, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Token ${authToken}`, + }, + body: JSON.stringify(data), + }).then(); + } + + const { trigger } = useSWRMutation( + `${process.env.REACT_APP_BASE_API_URL}/api/saved-list/`, + sendRequest + ); + + const handleClick = async () => { + try { + await trigger( + { company_pk: companyData.id }, + { optimisticData: () => setIsSaved(!isSaved) } + ); + } catch (error) { + console.error(error); + } + }; + + mutate((key) => typeof key === 'string' && key.startsWith('/api/profiles/'), { + revalidate: true, + }); + + const filledStar = ( + + ); + const outlinedStar = ( + + ); + + useEffect(() => { + if (isAuthorized) + axios + .get( + `${process.env.REACT_APP_BASE_API_URL}/api/profiles/?is_saved=True`, + { + withCredentials: true, + headers: { + Authorization: 'Token ' + authToken, + }, + } + ) + .then((response) => { + const NewList = []; + for (let item of response.data.results) { + NewList.push(item['id']); + } + + setUsersSavedList(NewList); + if (usersSavedList.includes(companyData.id)) { + setStar(filledStar); + setIsSaved(true); + } else { + setIsSaved(false); + setStar(outlinedStar); + } + }) + .catch((error) => { + console.error('Error fetching search results:', error); + }); + }, [usersSavedList]); + + return ( +
+
+
+ {companyData.name} +
+
+
+
+ {companyData.categories && + companyData.categories + .map((category) => category.name) + .join(' ')} +
+
+ + {companyData.name} + +
+
+
+
+ {companyData.address} +
+
+
+
+
+ {yearsOfExperiense} років досвіду +
+
+
+ {/* {isAuthorized ? (isSaved ? filledStar : outlinedStar) : null} */} + {star} + {/*
{}
*/} +
+
+
+
+
+ +
+
+
+ ); +}; + +export default CompanyCard; diff --git a/FrontEnd/src/components/SearchPage/search_field/companies/CompaniesCards.module.css b/FrontEnd/src/components/SearchPage/search_field/companies/CompanyCard.module.css similarity index 98% rename from FrontEnd/src/components/SearchPage/search_field/companies/CompaniesCards.module.css rename to FrontEnd/src/components/SearchPage/search_field/companies/CompanyCard.module.css index edcfcb72c..a98db543c 100644 --- a/FrontEnd/src/components/SearchPage/search_field/companies/CompaniesCards.module.css +++ b/FrontEnd/src/components/SearchPage/search_field/companies/CompanyCard.module.css @@ -158,3 +158,8 @@ .product-card__buttons:hover { cursor: pointer; } + +.star { + color: #ffd800; + font-size: 24px; +} diff --git a/FrontEnd/src/components/basicPage/BasicPage.jsx b/FrontEnd/src/components/basicPage/BasicPage.jsx index 71f9d1a09..195d5e7dd 100644 --- a/FrontEnd/src/components/basicPage/BasicPage.jsx +++ b/FrontEnd/src/components/basicPage/BasicPage.jsx @@ -14,7 +14,7 @@ import { SignUpPage } from '../SignUp/pages/SignUpPage'; import ScrollToTopButton from '../PrivacyPolicyPage/privacy/ScrollToTopButton'; import TermsAndConditions from '../terms-and-conditions-app/terms_conditions/TermsAndConditionsComponent'; import { useAuth } from '../../hooks'; - +import { Search } from '../SearchPage/Search'; function BasicPage() { const auth = useAuth(); @@ -56,7 +56,10 @@ function BasicPage() { } /> } /> - }/> + } + /> {auth.isAuth ? ( } /> ) : ( @@ -66,10 +69,11 @@ function BasicPage() { } /> } /> } /> + } />