diff --git a/website/components/CommentCard/CommentCard.js b/website/components/CommentCard/CommentCard.js
index b3a577b..578a721 100644
--- a/website/components/CommentCard/CommentCard.js
+++ b/website/components/CommentCard/CommentCard.js
@@ -11,6 +11,7 @@ const CommentCard = forwardRef((props, ref) => {
const { isAuth, user } = useContext(UserContext);
const deleteCommentById = async () => {
+ props.manageComment.setLoadingComments(true);
if (isAuth && user.token != undefined) {
try {
await api.delete(`/comments?commentId=${props.id}`, { headers: { 'Authorization': user.token } });
@@ -20,6 +21,7 @@ const CommentCard = forwardRef((props, ref) => {
props.manageComment.setCommentsData({ hasMore: props.manageComment.commentsData.hasMore, rows: newCommentsData.rows });
} catch {}
}
+ props.manageComment.setLoadingComments(false);
}
return (
diff --git a/website/components/FunctionComments/FunctionComments.js b/website/components/FunctionComments/FunctionComments.js
index 6296e77..b98f8f5 100644
--- a/website/components/FunctionComments/FunctionComments.js
+++ b/website/components/FunctionComments/FunctionComments.js
@@ -17,6 +17,14 @@ const FunctionComments = ({ functionId }) => {
const [isLoadingComments, setLoadingComments] = useState(true);
const [pageComments, setPageComments] = useState(1);
+ // Récupère les commentaires si la page change
+ useEffect(() => {
+ getCommentsData().then((data) => setCommentsData({
+ hasMore: data.hasMore,
+ rows: [...commentsData.rows, ...data.rows]
+ }));
+ }, [pageComments]);
+
// Permet la pagination au scroll
const observer = useRef();
const lastCommentCardRef = useCallback((node) => {
@@ -39,14 +47,6 @@ const FunctionComments = ({ functionId }) => {
});
}
- // Récupère les commentaires si la page change
- useEffect(() => {
- getCommentsData().then((data) => setCommentsData({
- hasMore: data.hasMore,
- rows: [...commentsData.rows, ...data.rows]
- }));
- }, [pageComments]);
-
const handleChange = (event) => {
const inputStateNew = { ...inputState };
inputStateNew[event.target.name] = event.target.value;
@@ -102,9 +102,9 @@ const FunctionComments = ({ functionId }) => {
{commentsData.rows.map((comment, index) => {
// Si c'est le dernier élément
if (commentsData.rows.length === index + 1) {
- return ;
+ return ;
}
- return ;
+ return ;
})}
diff --git a/website/components/FunctionComponentTop.js b/website/components/FunctionComponentTop.js
index a8a1497..9ece2a2 100644
--- a/website/components/FunctionComponentTop.js
+++ b/website/components/FunctionComponentTop.js
@@ -1,21 +1,65 @@
+import { useState, useEffect, useContext } from 'react';
import Link from 'next/link';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { faStar } from '@fortawesome/free-solid-svg-icons';
+import { faStar as farStar } from '@fortawesome/free-regular-svg-icons';
+import { UserContext } from '../contexts/UserContext';
+import api from '../utils/api';
+import './FunctionCard/FunctionCard.css';
-const FunctionComponentTop = (props) => (
-
-
-
-
-
{props.title}
-
{props.description}
-
-
-
{props.categorie.name}
-
-
{props.publicationDate}
+const FunctionComponentTop = (props) => {
+
+ const { isAuth, user } = useContext(UserContext);
+ const [isFavorite, setIsFavorite] = useState(false);
+
+ useEffect(() => {
+ if (isAuth && user.token != undefined) {
+ fetchFavorite();
+ }
+ }, [isAuth]);
+
+ const fetchFavorite = async () => {
+ try {
+ const favoriteResponse = await api.get(`/favorites/${props.id}`, { headers: { 'Authorization': user.token } });
+ setIsFavorite(favoriteResponse.data.isFavorite);
+ } catch {}
+ }
+
+ const toggleFavorite = async () => {
+ if (isAuth && user.token != undefined) {
+ try {
+ if (isFavorite) {
+ const response = await api.delete(`/favorites/${props.id}`, { headers: { 'Authorization': user.token } });
+ if (response.status === 200) return setIsFavorite(false);
+ }
+ const response = await api.post(`/favorites/${props.id}`, {}, { headers: { 'Authorization': user.token } });
+ if (response.status === 201) return setIsFavorite(true);
+ } catch {}
+ }
+ }
+
+ return (
+
+
+
+
+ {(isAuth) &&
+
+ }
+
+
+
{props.title}
+
{props.description}
+
-
-);
+ );
+}
export default FunctionComponentTop;
\ No newline at end of file
diff --git a/website/contexts/FunctionTabsContext.js b/website/contexts/FunctionTabsContext.js
index c12b30a..f080886 100644
--- a/website/contexts/FunctionTabsContext.js
+++ b/website/contexts/FunctionTabsContext.js
@@ -4,7 +4,7 @@ export const FunctionTabsContext = createContext();
function FunctionTabsContextProvider(props) {
- const [slideIndex, setSlideIndex] = useState(2);
+ const [slideIndex, setSlideIndex] = useState(0);
return (
diff --git a/website/package-lock.json b/website/package-lock.json
index c172428..193bbf6 100644
--- a/website/package-lock.json
+++ b/website/package-lock.json
@@ -1408,6 +1408,14 @@
"@fortawesome/fontawesome-common-types": "^0.2.28"
}
},
+ "@fortawesome/free-regular-svg-icons": {
+ "version": "5.13.0",
+ "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-5.13.0.tgz",
+ "integrity": "sha512-70FAyiS5j+ANYD4dh9NGowTorNDnyvQHHpCM7FpnF7GxtDjBUCKdrFqCPzesEIpNDFNd+La3vex+jDk4nnUfpA==",
+ "requires": {
+ "@fortawesome/fontawesome-common-types": "^0.2.28"
+ }
+ },
"@fortawesome/free-solid-svg-icons": {
"version": "5.13.0",
"resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.13.0.tgz",
diff --git a/website/package.json b/website/package.json
index 4e36188..ea68c48 100644
--- a/website/package.json
+++ b/website/package.json
@@ -9,6 +9,7 @@
},
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.28",
+ "@fortawesome/free-regular-svg-icons": "^5.13.0",
"@fortawesome/free-solid-svg-icons": "^5.13.0",
"@fortawesome/react-fontawesome": "^0.1.9",
"@zeit/next-css": "^1.0.1",
diff --git a/website/pages/functions/index.js b/website/pages/functions/index.js
index 36ca75e..5f6cb04 100644
--- a/website/pages/functions/index.js
+++ b/website/pages/functions/index.js
@@ -20,6 +20,26 @@ const Functions = () => {
const [isLoadingFunctions, setLoadingFunctions] = useState(true);
const [pageFunctions, setPageFunctions] = useState(1);
+ // Récupère la catégorie avec la query categoryId
+ useEffect(() => {
+ if (categoryId) {
+ handleChange({ target: { name: "selectedCategory", value: categoryId } });
+ }
+ }, [categoryId]);
+
+ // Récupère les fonctions si la page change
+ useEffect(() => {
+ getFunctionsData().then((data) => setFunctionsData({
+ hasMore: data.hasMore,
+ rows: [...functionsData.rows, ...data.rows]
+ }));
+ }, [pageFunctions]);
+
+ // Récupère les fonctions si la catégorie/recherche change
+ useEffect(() => {
+ getFunctionsData().then((data) => setFunctionsData(data));
+ }, [inputSearch.selectedCategory, inputSearch.search]);
+
// Permet la pagination au scroll
const observer = useRef();
const lastFunctionCardRef = useCallback((node) => {
@@ -41,26 +61,6 @@ const Functions = () => {
next(result.data);
});
}
-
- // Récupère la catégorie avec la query categoryId
- useEffect(() => {
- if (categoryId) {
- handleChange({ target: { name: "selectedCategory", value: categoryId } });
- }
- }, [categoryId]);
-
- // Récupère les fonctions si la page change
- useEffect(() => {
- getFunctionsData().then((data) => setFunctionsData({
- hasMore: data.hasMore,
- rows: [...functionsData.rows, ...data.rows]
- }));
- }, [pageFunctions]);
-
- // Récupère les fonctions si la catégorie/recherche change
- useEffect(() => {
- getFunctionsData().then((data) => setFunctionsData(data));
- }, [inputSearch.selectedCategory, inputSearch.search]);
const handleChange = (event) => {
const inputSearchNew = { ...inputSearch };
diff --git a/website/public/css/pages/FunctionComponent.css b/website/public/css/pages/FunctionComponent.css
index 1c45d55..67d17c8 100644
--- a/website/public/css/pages/FunctionComponent.css
+++ b/website/public/css/pages/FunctionComponent.css
@@ -18,4 +18,17 @@
}
.FunctionComponent__slide {
margin-top: 30px;
+}
+.FunctionComponent__image {
+ width: 150px;
+}
+.FunctionComponent__star-favorite {
+ color: var(--important);
+ width: 2em !important;
+ height: 2em !important;
+ position: absolute;
+ right: 0;
+ top: 15px;
+ margin-right: 15px;
+ cursor: pointer;
}
\ No newline at end of file