-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #36 from fga-eps-mds/feat#79/ingressar-na-jornada
Feat(#79):ingressar na jornada
- Loading branch information
Showing
15 changed files
with
838 additions
and
91 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
'use client'; | ||
|
||
import React, { useEffect, useState } from 'react'; | ||
import { Box, CircularProgress, Divider, Typography } from '@mui/material'; | ||
import JourneyInfo from '@/components/journey/journeyInfo'; | ||
import JourneyPath from '@/components/journey/journeyPath'; | ||
import { addJourneyToUser, getJourney, getJourneysByUser, getTrails } from '@/services/studioMaker.service'; | ||
import { Journey } from '@/lib/interfaces/journey.interface'; | ||
import { Trail } from '@/lib/interfaces/trails.interface'; | ||
import { useParams } from 'next/navigation'; | ||
import { useSession } from 'next-auth/react'; | ||
import { subscribeJourney, getSubscribedJourneys } from '@/services/user.service'; | ||
|
||
export default function JourneyPage() { | ||
const { journeyId } = useParams(); | ||
const [journey, setJourney] = useState<Journey | null>(null); | ||
const [trails, setTrails] = useState<Trail[]>([]); | ||
const [error, setError] = useState<string | null>(null); | ||
const [hasJourney, setHasJourney] = useState(false); | ||
const { data: session } = useSession(); | ||
|
||
useEffect(() => { | ||
const fetchJourneyData = async () => { | ||
try { | ||
const id = Array.isArray(journeyId) ? journeyId[0] : journeyId; | ||
const token = JSON.parse(localStorage.getItem('token')!); | ||
|
||
const journeyData = await getJourney(id); | ||
setJourney(journeyData); | ||
|
||
const trailsData = await getTrails({ id, token }); | ||
setTrails(trailsData); | ||
|
||
if (session?.user?.id) { | ||
const userJourneys = await getSubscribedJourneys(session.user.id); | ||
console.log('User journeys: ', userJourneys); | ||
let isSubscribed = false; | ||
userJourneys.forEach((journeyId: string) => { | ||
if(journeyId === id) { | ||
isSubscribed = true; | ||
} | ||
}); | ||
setHasJourney(isSubscribed); | ||
} | ||
} catch (err) { | ||
setError('Failed to fetch journey data'); | ||
} | ||
}; | ||
|
||
fetchJourneyData(); | ||
}, [journeyId, session?.user?.id]); | ||
|
||
const handleJoin = async () => { | ||
if (session?.user.id) { | ||
const id = Array.isArray(journeyId) ? journeyId[0] : journeyId; | ||
console.log(session?.user.accessToken); | ||
await subscribeJourney({ userId: session.user.id, journeyId: id, accessToken: session?.user.accessToken}); | ||
setHasJourney(true); | ||
} | ||
|
||
|
||
}; | ||
|
||
if (error) { | ||
return <div>{error}</div>; | ||
} | ||
|
||
if (!journey) { | ||
return <CircularProgress />; | ||
} | ||
|
||
return ( | ||
<Box | ||
sx={{ | ||
display: 'flex', | ||
alignItems: 'center', | ||
justifyContent: 'center', | ||
backgroundColor: '#f1f1f1', | ||
height: 'auto', | ||
}} | ||
> | ||
<Box flex={1} pr={2}> | ||
<JourneyInfo | ||
title={journey.title} | ||
description={journey.description} | ||
trailCount={trails.length} | ||
hasJourney={hasJourney} | ||
onJoin={handleJoin} | ||
/> | ||
</Box> | ||
|
||
<Divider sx={{ height: '80%', marginTop: '100px' }} orientation="vertical" variant="middle" flexItem /> | ||
{!trails.length ? ( | ||
<Typography variant="h3" | ||
sx={{ fontFamily: 'Poppins, sans-serif', margin: '250px', color:'silver'}}> Ainda não há trilhas nessa jornada</Typography> | ||
) : ( | ||
<React.Fragment> | ||
<JourneyPath trails={trails} /> | ||
</React.Fragment> | ||
)} | ||
</Box> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
'use client'; | ||
import React from 'react'; | ||
import Image from 'next/image'; | ||
import 'react-multi-carousel/lib/styles.css'; | ||
import { useRouter } from 'next/navigation'; | ||
|
||
interface JourneyCardProps { | ||
title: string; | ||
image: string; | ||
Id: string; | ||
} | ||
|
||
const JourneyCard: React.FC<JourneyCardProps> = ({ title, image, Id }) => { | ||
|
||
const router = useRouter(); | ||
const handleClick = () => { | ||
router.push('/journey-page/' + Id); | ||
} | ||
|
||
return ( | ||
<div className="bg-[#FFFAFA] border-2 rounded-3xl w-44 h-60 overflow-hidden flex items-center flex-col gap-7 justify-center cursor-pointer" onClick={handleClick}> | ||
<Image | ||
src={image} | ||
alt={title} | ||
width={120} | ||
height={120} | ||
style={{ marginTop: '20px' }} | ||
/> | ||
<h3 className="text-lg font-bold text-center flex-1">{title}</h3> | ||
</div> | ||
); | ||
}; | ||
|
||
export default JourneyCard; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
'use client'; | ||
import React, { useState, useEffect } from 'react'; | ||
import Carousel from 'react-multi-carousel'; | ||
import Image from 'next/image'; | ||
import { ChevronUp, ChevronDown } from 'lucide-react'; | ||
import Foto from '@/public/calculus-logo.svg'; | ||
import JourneyService from './service/home.services'; | ||
import { useRouter } from 'next/navigation'; | ||
|
||
interface StartCardProps { | ||
title: string; | ||
image: string; | ||
description?: string; | ||
Id: string; | ||
} | ||
|
||
const StartCard: React.FC<StartCardProps> = ({ | ||
title, | ||
image, | ||
description, | ||
Id, | ||
}) => { | ||
const [isOpen, setIsOpen] = React.useState(false); | ||
const [journeys, setJourneys] = useState<any[]>([]); | ||
const router = useRouter(); | ||
|
||
const handleOnclick = (id: string) => { | ||
router.push('/journey-page/' + id); | ||
}; | ||
|
||
useEffect(() => { | ||
const loadJourneys = async () => { | ||
try { | ||
const { fetchJourneybyPoint, fetchJourneyById } = JourneyService(); | ||
const journeysId = await fetchJourneybyPoint(Id); | ||
|
||
if (!journeysId || journeysId.length === 0) { | ||
return; | ||
} | ||
|
||
const j: any[] = []; | ||
for (const journeyId of journeysId) { | ||
const journey = await fetchJourneyById(journeyId); | ||
if (journey) { | ||
j.push(journey); | ||
} else { | ||
console.error(`Journey with ID ${journeyId} not found.`); | ||
} | ||
} | ||
|
||
if (j.length === 0) { | ||
console.error('No valid journeys found.'); | ||
} | ||
|
||
setJourneys(j); | ||
} catch (error) { | ||
console.error('Error loading journeys:', error); | ||
} | ||
}; | ||
|
||
loadJourneys(); | ||
}, [Id]); | ||
|
||
const responsive = { | ||
superLargeDesktop: { | ||
// the naming can be any, depends on you. | ||
breakpoint: { max: 4000, min: 3000 }, | ||
items: 5, | ||
}, | ||
desktop: { | ||
breakpoint: { max: 3000, min: 1024 }, | ||
items: 5, | ||
}, | ||
tablet: { | ||
breakpoint: { max: 1024, min: 464 }, | ||
items: 3, | ||
}, | ||
mobile: { | ||
breakpoint: { max: 464, min: 0 }, | ||
items: 2, | ||
}, | ||
}; | ||
|
||
return ( | ||
<div className="w-full my-5 relative"> | ||
<div | ||
onClick={() => { | ||
setIsOpen(!isOpen); | ||
}} | ||
className="flex gap-3 py-5 px-4 hover:bg-[#ececec] rounded-xl cursor-pointer items-center" | ||
> | ||
<Image src={image} alt={title} width={80} height={80} /> | ||
<h3 className="text-xl font-bold text-center w-[40%] ">{title}</h3> | ||
<p className="text-sm font-light w-[40%] ">{description || ""}</p> | ||
<div className=" rounded-full h-7 w-7 absolute right-[1%]"> | ||
{isOpen ? <ChevronUp size={24} /> : <ChevronDown size={24} />} | ||
</div> | ||
</div> | ||
{isOpen && ( | ||
<div className="bg-[#ececec] p-8 rounded-xl"> | ||
{journeys.length > 0 ? ( | ||
<Carousel responsive={responsive}> | ||
{journeys.map((jornada, index) => ( | ||
<div | ||
key={index} | ||
className="h-52 w-58 flex flex-col items-center cursor-pointer " | ||
> | ||
<div | ||
className="bg-[#FFFAFA] h-40 w-44 flex place-content-center rounded-3xl border-2 border-[#e5e7eb] hover:border-[#dbdbdb] shadow-[0_6px_0_#e5e7eb] hover:shadow-[0_6px_0_#dbdbdb] relative" | ||
onClick={() => handleOnclick(jornada._id)} | ||
> | ||
<Image | ||
src={jornada.img || Foto} | ||
alt={jornada.title} | ||
width={120} | ||
height={120} | ||
/> | ||
</div> | ||
<h3 className="text-xl text-center mt-3">{jornada.title}</h3> | ||
|
||
{index < journeys.length - 1 && ( | ||
<div className="absolute top-[40%] right-[-30px] w-[60px] h-[3px] bg-[#dbdbdb] z-10"></div> | ||
)} | ||
</div> | ||
))} | ||
</Carousel> | ||
) : ( | ||
<p className="text-center text-gray-500">No journeys available.</p> | ||
)} | ||
</div> | ||
)} | ||
<div className="w-full h-0.5 px my-6 bg-[#dbdbdb]"></div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default StartCard; |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.