Skip to content

Commit

Permalink
Merge pull request #36 from fga-eps-mds/feat#79/ingressar-na-jornada
Browse files Browse the repository at this point in the history
Feat(#79):ingressar na jornada
  • Loading branch information
DaviMatheus authored Sep 2, 2024
2 parents 587f9ef + a57dbd9 commit ea66d09
Show file tree
Hide file tree
Showing 15 changed files with 838 additions and 91 deletions.
103 changes: 103 additions & 0 deletions src/app/journey-page/[journeyId]/page.tsx
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>
);
}
34 changes: 34 additions & 0 deletions src/components/home/JourneyCard.tsx
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;
137 changes: 137 additions & 0 deletions src/components/home/StartPointsCard.tsx
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;
41 changes: 0 additions & 41 deletions src/components/home/homeJourneyCard.tsx

This file was deleted.

Loading

0 comments on commit ea66d09

Please sign in to comment.