diff --git a/client/src/App.jsx b/client/src/App.jsx index 89e0a96..8269173 100644 --- a/client/src/App.jsx +++ b/client/src/App.jsx @@ -10,6 +10,7 @@ import Login from "./components/Login/Login"; import { useNavigate } from "react-router-dom"; import { Routes, Route } from "react-router-dom"; import GithubCallback from "./components/GithubCallback"; +import PreviousRecommendations from "./components/PreviousRecomendations/PreviousRecommendations"; function App() { const [recommendations, setRecommendations] = useState([]); @@ -72,7 +73,11 @@ function App() { return (
- +
} /> @@ -82,10 +87,18 @@ function App() { element={ isAuthenticated ? ( <> -
0 ? "with-recommendations" : ""}`}> +
0 ? "with-recommendations" : "" + }`} + >
-
0 ? "visible" : ""}`}> +
0 ? "visible" : "" + }`} + > {loading ? (
@@ -95,6 +108,7 @@ function App() { ) : null}
+ ) : ( @@ -110,4 +124,4 @@ function App() { ); } -export default App; +export default App; \ No newline at end of file diff --git a/client/src/components/PreviousRecomendations/PreviousRecommendations.jsx b/client/src/components/PreviousRecomendations/PreviousRecommendations.jsx new file mode 100644 index 0000000..d3e7975 --- /dev/null +++ b/client/src/components/PreviousRecomendations/PreviousRecommendations.jsx @@ -0,0 +1,146 @@ +import React, { useEffect, useState } from "react"; +import { formatDistanceToNow } from "date-fns"; + +const PreviousRecommendations = ({ userData }) => { + const [recommendationIds, setRecommendationIds] = useState([]); + const [selectedRecommendation, setSelectedRecommendation] = useState(null); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + useEffect(() => { + const fetchRecommendationIds = async () => { + setLoading(true); + setError(null); + try { + const response = await fetch( + `http://127.0.0.1:8000/api/user-recommendations?username=${encodeURIComponent( + userData.username + )}`, + { + method: "GET", + headers: { + Authorization: `Bearer ${localStorage.getItem("jwt_token")}`, + "Content-Type": "application/json", + }, + } + ); + + if (response.ok) { + const data = await response.json(); + + if (Array.isArray(data)) { + setRecommendationIds(data.map((rec) => rec.recommendation_id)); + } else { + throw new Error("Invalid data format: Expected an array"); + } + } else { + throw new Error("Failed to fetch previous recommendations"); + } + } catch (error) { + setError(error.message); + } finally { + setLoading(false); + } + }; + + fetchRecommendationIds(); + }, [userData.username]); + + const fetchRecommendationDetails = async (recommendationId) => { + setLoading(true); + setError(null); + try { + const response = await fetch( + `http://127.0.0.1:8000/api/recommendation/${recommendationId}`, + { + method: "GET", + headers: { + Authorization: `Bearer ${localStorage.getItem("jwt_token")}`, + "Content-Type": "application/json", + }, + } + ); + if (response.ok) { + const data = await response.json(); + setSelectedRecommendation(data.recommendations || []); + } else { + throw new Error("Failed to fetch recommendation details"); + } + } catch (error) { + setError(error.message); + } finally { + setLoading(false); + } + }; + + const timeAgo = (date) => + formatDistanceToNow(new Date(date), { addSuffix: true }); + + return ( +
+

Previous Recommendations

+ {loading &&

Loading...

} + {error &&

Error: {error}

} +
    + {recommendationIds.map((id, index) => ( +
  • + +
  • + ))} +
+ + {selectedRecommendation && ( +
+

Recommendation Details

+
    + {selectedRecommendation.map((repo, index) => ( +
  • +
    +
    + +

    {repo.full_name}

    +
    +

    {repo.description}

    +
    + Topics: + {repo.topics + .split(", ") + .slice(0, 7) + .map((topic, idx) => ( +
    + {topic} +
    + ))} +
    +
    +
    + + ⭐ {Math.round(repo.stargazers_count / 100) / 10}k + + 🔵 {repo.language} + issues: {repo.open_issues_count} + forks: {repo.forks_count} + Updated {timeAgo(repo.updated_at)} +
    +
    + +
    +
    +
  • + ))} +
+
+ )} +
+ ); +}; + +export default PreviousRecommendations;