1- import React , { useEffect , useState } from "react" ;
1+ import React , { useContext , useEffect , useState } from "react" ;
22import { useParams } from "react-router" ;
33import { getProjectById , incrementProjectView , toggleProjectLike , getProjectLikeStatus } from "../../../services/projectService" ;
44import { ProjectInfoCard } from "../components/ProjectInfoCard" ;
55import { GitHubFileTree } from "../components/GitHubFileTree" ;
66import { GitHubLanguagesTag } from "../components/GitHubLanguagesTag" ;
77import { CodeBlock } from "../../../styles/ReactParser" ;
88import { LikeButtonRounded } from "../../../components/LikeButtonRounded" ;
9+ import { AuthContext } from "../../../context/authContext" ;
10+
911
1012function useWindowWidth ( ) {
1113 const [ width , setWidth ] = useState ( window . innerWidth ) ;
@@ -34,7 +36,8 @@ export const ProjectDetailsPage = () => {
3436 const [ currentIndex , setCurrentIndex ] = useState ( 0 ) ;
3537 const width = useWindowWidth ( ) ;
3638 const isDesktop = width >= 1200 ;
37-
39+ const { profile, socket, setNotifications } = useContext ( AuthContext ) ;
40+ const [ selectedOwner , setSelectedOwner ] = useState ( null ) ;
3841 const token = localStorage . getItem ( 'token' ) || '' ;
3942
4043 // Estados del botón de like
@@ -43,46 +46,46 @@ export const ProjectDetailsPage = () => {
4346 const [ loadingLike , setLoadingLike ] = useState ( true ) ;
4447
4548 useEffect ( ( ) => {
46- const incrementViewWithCooldown = async ( ) => {
47- if ( typeof window === "undefined" || ! window . localStorage ) return ;
48-
49- const cooldownTime = 1000 * 60 * 60 ; // 1 hora en ms
50- const lastViewKey = `project_${ id } _last_view` ;
51- const lastView = localStorage . getItem ( lastViewKey ) ;
52- const now = Date . now ( ) ;
49+ const incrementViewWithCooldown = async ( ) => {
50+ if ( typeof window === "undefined" || ! window . localStorage ) return ;
51+
52+ const cooldownTime = 1000 * 60 * 60 ; // 1 hora en ms
53+ const lastViewKey = `project_${ id } _last_view` ;
54+ const lastView = localStorage . getItem ( lastViewKey ) ;
55+ const now = Date . now ( ) ;
56+
57+ if ( ! lastView || now - parseInt ( lastView , 10 ) > cooldownTime ) {
58+ try {
59+ await incrementProjectView ( id ) ;
60+ localStorage . setItem ( lastViewKey , now . toString ( ) ) ;
61+
62+ // Actualizar localmente el contador de views para reflejar el cambio instantáneamente:
63+ setProject ( prev => prev ? { ...prev , views : ( prev . views || 0 ) + 1 } : prev ) ;
64+ } catch ( error ) {
65+ console . error ( "Error incrementando views:" , error ) ;
66+ }
67+ }
68+ } ;
5369
54- if ( ! lastView || now - parseInt ( lastView , 10 ) > cooldownTime ) {
70+ const fetchProjectAndLikeStatus = async ( ) => {
5571 try {
56- await incrementProjectView ( id ) ;
57- localStorage . setItem ( lastViewKey , now . toString ( ) ) ;
58-
59- // Actualizar localmente el contador de views para reflejar el cambio instantáneamente:
60- setProject ( prev => prev ? { ...prev , views : ( prev . views || 0 ) + 1 } : prev ) ;
72+ const data = await getProjectById ( id ) ;
73+ if ( data && ! data . error ) {
74+ setProject ( data ) ;
75+ setCurrentIndex ( 0 ) ;
76+ }
77+ const likeStatus = await getProjectLikeStatus ( id , token ) ;
78+ setLiked ( likeStatus . liked ) ;
6179 } catch ( error ) {
62- console . error ( "Error incrementando views:" , error ) ;
63- }
64- }
65- } ;
66-
67- const fetchProjectAndLikeStatus = async ( ) => {
68- try {
69- const data = await getProjectById ( id ) ;
70- if ( data && ! data . error ) {
71- setProject ( data ) ;
72- setCurrentIndex ( 0 ) ;
80+ console . error ( "Error fetching project or like status:" , error ) ;
81+ } finally {
82+ setLoadingLike ( false ) ;
7383 }
74- const likeStatus = await getProjectLikeStatus ( id , token ) ;
75- setLiked ( likeStatus . liked ) ;
76- } catch ( error ) {
77- console . error ( "Error fetching project or like status:" , error ) ;
78- } finally {
79- setLoadingLike ( false ) ;
80- }
81- } ;
84+ } ;
8285
83- fetchProjectAndLikeStatus ( ) ;
84- incrementViewWithCooldown ( ) ;
85- } , [ id , token ] ) ;
86+ fetchProjectAndLikeStatus ( ) ;
87+ incrementViewWithCooldown ( ) ;
88+ } , [ id , token ] ) ;
8689
8790
8891 // Función para manejar el click del like
@@ -93,12 +96,24 @@ export const ProjectDetailsPage = () => {
9396 try {
9497 const data = await toggleProjectLike ( id , token ) ;
9598 setLiked ( data . liked ) ;
96- // Actualizamos el proyecto con la info de likes para que refleje contador, estado, etc.
9799 setProject ( ( prevProject ) => ( {
98100 ...prevProject ,
99101 liked : data . liked ,
100102 likes : data . likes ,
101103 } ) ) ;
104+
105+ if ( data . liked && selectedOwner . _id && selectedOwner . _id !== profile . _id ) {
106+ const notif = {
107+ senderId : profile . _id ,
108+ senderName : profile . name ,
109+ receiverId : selectedOwner . _id ,
110+ receiverName : selectedOwner . name ,
111+ type : 2 ,
112+ createdAt : Date . now ( )
113+ } ;
114+ socket . emit ( "sendNotification" , notif ) ;
115+ setNotifications ( prev => [ notif , ...prev ] ) ;
116+ }
102117 } catch ( error ) {
103118 console . error ( error ) ;
104119 } finally {
@@ -133,7 +148,7 @@ export const ProjectDetailsPage = () => {
133148 ? parseRepoUrl ( project . githubProjectLink )
134149 : null ;
135150
136-
151+
137152 return (
138153 < div className = "w-full flex flex-col items-center gap-6" >
139154 < div className = "relative w-full h-[256px] overflow-hidden" >
@@ -164,9 +179,8 @@ export const ProjectDetailsPage = () => {
164179 key = { index }
165180 src = { url }
166181 alt = { `slide-${ index } ` }
167- className = { `absolute inset-0 w-full h-full object-cover rounded-lg transition-opacity duration-700 ease-in-out ${
168- index === currentIndex ? "opacity-100 z-10" : "opacity-0 z-0"
169- } `}
182+ className = { `absolute inset-0 w-full h-full object-cover rounded-lg transition-opacity duration-700 ease-in-out ${ index === currentIndex ? "opacity-100 z-10" : "opacity-0 z-0"
183+ } `}
170184 />
171185 ) ) }
172186 < button
@@ -208,7 +222,7 @@ export const ProjectDetailsPage = () => {
208222 </ div >
209223
210224 < div className = "flex flex-col" >
211- < ProjectInfoCard project = { project } />
225+ < ProjectInfoCard project = { project } setSelectedOwner = { setSelectedOwner } />
212226
213227 < div className = "flex justify-center items-center rounded-full p-6" >
214228 < LikeButtonRounded
@@ -251,9 +265,8 @@ export const ProjectDetailsPage = () => {
251265 key = { index }
252266 src = { url }
253267 alt = { `slide-${ index } ` }
254- className = { `absolute inset-0 w-full h-full object-cover rounded-lg transition-opacity duration-700 ease-in-out ${
255- index === currentIndex ? "opacity-100 z-10" : "opacity-0 z-0"
256- } `}
268+ className = { `absolute inset-0 w-full h-full object-cover rounded-lg transition-opacity duration-700 ease-in-out ${ index === currentIndex ? "opacity-100 z-10" : "opacity-0 z-0"
269+ } `}
257270 />
258271 ) ) }
259272 < button
@@ -273,7 +286,7 @@ export const ProjectDetailsPage = () => {
273286 ) ;
274287
275288 case "ProjectInfoCard" :
276- return < ProjectInfoCard key = "infoCard" project = { project } /> ;
289+ return < ProjectInfoCard key = "infoCard" project = { project } setSelectedOwner = { setSelectedOwner } /> ;
277290
278291 case "Description" :
279292 return project . description ? (
0 commit comments