Skip to content

Commit

Permalink
Add last step
Browse files Browse the repository at this point in the history
  • Loading branch information
barbara-chaves committed Nov 30, 2023
1 parent 6d4217a commit 3ae79b4
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 91 deletions.
46 changes: 11 additions & 35 deletions client/src/containers/story/steps/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { PropsWithChildren, useEffect, useMemo, useRef } from 'react';
import { PropsWithChildren, useMemo } from 'react';

import { useRecoilValue } from 'recoil';

Expand All @@ -14,7 +14,7 @@ import {
import MapStepLayout from './layouts/map-step';
import MediaStepLayout from './layouts/media-step';
import OutroStepLayout from './layouts/outro-step';
import { getMedia, getStepType } from './utils';
import { getStepType } from './utils';

type StepProps = PropsWithChildren<{
media?: StepLayoutMediaStepComponentMedia | StepLayoutOutroStepComponentMedia;
Expand All @@ -26,20 +26,6 @@ type StepProps = PropsWithChildren<{
const Step = ({ step, category, index }: StepProps) => {
const currentStep = useRecoilValue(stepAtom);

const { image, video } = getMedia(step?.attributes?.layout[0]?.media);

const videoRef = useRef<HTMLVideoElement>(null);

useEffect(() => {
if (video?.href && videoRef.current) {
if (index === currentStep) {
videoRef.current.play();
} else {
videoRef.current.pause();
}
}
}, [currentStep, index, video?.href]);

const STEP_COMPONENT = useMemo(() => {
const type = getStepType(step);
const stepLayout = step?.attributes?.layout?.[0];
Expand All @@ -59,31 +45,21 @@ const Step = ({ step, category, index }: StepProps) => {
case 'media-step':
return <MediaStepLayout step={stepLayout} />;
case 'outro-step':
return <OutroStepLayout step={stepLayout} categoryId={category?.data?.id} />;
return (
<OutroStepLayout
step={stepLayout}
showContent={currentStep === index}
categoryId={category?.data?.id}
/>
);
default:
return null;
}
}, [category?.data?.attributes, category?.data?.id, step, index, currentStep]);

return (
<div
style={{
...(image && { backgroundImage: `url(${image})` }),
}}
className="pointer-events-none z-10 h-screen w-full bg-cover bg-no-repeat"
>
{video && (
<video
className="pointer-events-none absolute -z-10 h-screen w-full object-cover"
loop
muted
ref={videoRef}
src={video.href}
>
<source src={video.href} type={video.type} />
</video>
)}
<div className="z-20 h-full w-full px-14 pb-6 pt-[84px]">{STEP_COMPONENT}</div>
<div className="pointer-events-none z-10 h-screen w-full ">
<div className="z-20 h-full w-full px-14">{STEP_COMPONENT}</div>
</div>
);
};
Expand Down
52 changes: 25 additions & 27 deletions client/src/containers/story/steps/layouts/map-step.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const MapStepLayout = ({ step, category, showContent, stepIndex }: MapStepLayout
};

return (
<div className="pointer-events-none h-full">
<div className="pointer-events-none h-full max-h-screen ">
<div className="flex h-full justify-between px-14 pt-[84px]">
<div className="flex flex-1 flex-col space-y-8">
{!!story_summary?.length && (
Expand Down Expand Up @@ -78,34 +78,32 @@ const MapStepLayout = ({ step, category, showContent, stepIndex }: MapStepLayout
<Legend />
</div>
</div>
<div className="flex flex-1 items-end justify-end">
<div className="h-[150vh] w-fit">
<div className="sticky top-0 flex h-screen flex-col justify-end space-y-6 pb-6">
{card?.map((item) => (
<div
key={item?.id}
onClick={handleClickCard}
className={cn(
'pointer-events-auto cursor-pointer overflow-hidden rounded border border-gray-800 bg-[#335e6f] bg-opacity-50 p-8 backdrop-blur transition-all duration-300 ease-in-out',
showContent ? 'opacity-100' : 'opacity-0'
<div className="">
<div className="flex h-fit min-h-full flex-col items-end justify-center space-y-6 pb-6">
{card?.map((item) => (
<div
key={item?.id}
onClick={handleClickCard}
className={cn(
'pointer-events-auto cursor-pointer overflow-hidden rounded border border-gray-800 bg-[#335e6f] bg-opacity-50 p-8 backdrop-blur transition-all duration-300 ease-in-out',
showContent ? 'opacity-100' : 'opacity-0'
)}
>
<div className="w-[500px] space-y-1">
{item?.title && <h3 className="text-2xl font-bold">{item?.title}</h3>}
{!!item?.content && (
<div className="space-y-4">
{item.content.split('\n').map((p, i) => (
<p key={i} className="font-inter text-sm">
{p}
</p>
))}
</div>
)}
>
<div className="h-full w-[500px] space-y-1">
{item?.title && <h3 className="text-2xl font-bold">{item?.title}</h3>}
{!!item?.content && (
<div className="space-y-4">
{item.content.split('\n').map((p, i) => (
<p key={i} className="font-inter text-sm">
{p}
</p>
))}
</div>
)}
{!!item?.widget && <Chart options={item?.widget} />}
</div>
{!!item?.widget && <Chart options={item?.widget} />}
</div>
))}
</div>
</div>
))}
</div>
</div>
</div>
Expand Down
156 changes: 128 additions & 28 deletions client/src/containers/story/steps/layouts/outro-step.tsx
Original file line number Diff line number Diff line change
@@ -1,46 +1,146 @@
import { useGetStories } from '@/types/generated/story';
'use client';

import { useCallback, useEffect, useRef, useState } from 'react';

import { useRouter } from 'next/navigation';

import { useScroll, motion, useTransform } from 'framer-motion';
import { useResetRecoilState } from 'recoil';

import env from '@/env.mjs';

import { tmpBboxAtom } from '@/store';

import { StepLayoutItem, StepLayoutOutroStepComponent } from '@/types/generated/strapi.schemas';

import StorySummary from '@/components/ui/story-summary';
const apiBaseUrl = env.NEXT_PUBLIC_API_URL.replace('/api', '');

type MediaStepLayoutProps = {
step: StepLayoutItem;
categoryId?: number;
showContent: boolean;
};

const OutroStepLayout = ({ step, categoryId }: MediaStepLayoutProps) => {
const OutroStepLayout = ({ step, showContent }: MediaStepLayoutProps) => {
const { push } = useRouter();

const resetBbox = useResetRecoilState(tmpBboxAtom);

const { content, title } = step as StepLayoutOutroStepComponent;
const containerRef = useRef<HTMLDivElement>(null);

const { data: suggestions } = useGetStories(
{
filters: {
category: categoryId,
},
'pagination[limit]': 3,
},
{
query: {
enabled: !!categoryId,
},
const { scrollYProgress } = useScroll({
target: containerRef,
offset: ['start end', 'end start'],
smooth: 10000,
});

const [show, setShow] = useState(false);

useTransform(scrollYProgress, (v) => {
if (!show && showContent && v > 0.2) {
setShow(true);
}
});

useEffect(() => {
if (!showContent) setShow(false);
}, [showContent]);

useTransform(scrollYProgress, (v) => {
if (v > 0.6) {
resetBbox();
push('/');
}
});

const media = (step as any)?.media?.data?.attributes;

const videoRef = useRef<HTMLVideoElement>(null);

const mediaType = media?.mime?.split('/')[0];

const mediaSrc = `${apiBaseUrl}${media.url}`;
const mediaMime = media?.mime;

const isVideo = mediaType.includes('video');

const handlePlayVideo = useCallback(
(e: React.MouseEvent<HTMLVideoElement, MouseEvent>, action: 'play' | 'pause') => {
if (action === 'play') e.currentTarget.play();
else e.currentTarget.pause();
},
[]
);

const scale = useTransform(scrollYProgress, [0.5, 0.7], ['1', '2']);
const scaleContent = useTransform(scrollYProgress, [0.5, 0.7], ['1', '0.75']);

return (
<div className="h-full w-full">
<div className="mx-auto flex h-full w-full max-w-5xl flex-col justify-end space-y-16 py-10">
<div className="max-w-lg">
<h3 className="text-enlight-yellow-500 text-[40px] font-bold tracking-wider">{title}</h3>
<p>{content}</p>
</div>
<div className="flex flex-col gap-y-4">
<p className="text-gray-500">Explore more stories</p>
<div className="flex gap-x-8">
{suggestions?.data?.map((story) => (
<StorySummary key={story.id} story={story} />
))}
<div ref={containerRef} className="flex h-[300vh]">
{showContent && show && (
<motion.div className="fixed top-0 flex h-screen w-screen flex-col items-center justify-center sm:px-14 2xl:px-24">
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 2 }}
className="step-blur bg-background/10 fixed bottom-0 left-0 h-full w-screen backdrop-blur-sm"
/>
<div className="flex w-full flex-1 items-center">
<div className="flex w-full flex-1 flex-col justify-between gap-12 lg:flex-row">
{isVideo && (
<motion.div
initial={{ opacity: 0, x: '-300%' }}
animate={{ opacity: 1, x: 0 }}
exit={{ opacity: 0 }}
transition={{ duration: 2 }}
className="flex-1"
style={{ scale: scaleContent }}
>
<video
width="100%"
height="100%"
src={mediaSrc}
ref={videoRef}
muted
loop
autoPlay={true}
className={''}
onMouseEnter={(e) => handlePlayVideo(e, 'play')}
onMouseLeave={(e) => handlePlayVideo(e, 'pause')}
>
<source src={mediaSrc} type={mediaMime} />
</video>
</motion.div>
)}
<motion.div
className="flex w-full max-w-5xl flex-1 items-center justify-center space-y-16"
initial={{ opacity: 0, x: '300%' }}
animate={{ opacity: 1, x: 0 }}
exit={{ opacity: 0 }}
transition={{ duration: 2.5 }}
style={{ scale: scaleContent }}
>
<div className="max-w-lg space-y-4">
<h3 className="text-enlight-yellow-500 text-2xl font-bold tracking-wider">
{title}
</h3>
<p>{content}</p>
</div>
</motion.div>
</div>
</div>
</div>
</div>
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 2.5 }}
style={{ scale }}
className="font-notes z-10 w-full place-self-end pb-[10vh] text-center text-sm italic text-white"
>
Continue scrolling to explore more stories
</motion.div>
</motion.div>
)}
</div>
);
};
Expand Down
4 changes: 3 additions & 1 deletion client/src/lib/scroll/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ const useIsomorphicLayoutEffect =

export const ScrollProvider = ({ children }: PropsWithChildren<any>) => {
const [scrollItems, setScrollItems] = useState<ScrollItem[]>([]);
const { scrollY } = useScroll();
const { scrollY } = useScroll({
offset: ['start end', 'start center'],
});

const setStep = useSetRecoilState(stepAtom);

Expand Down
5 changes: 5 additions & 0 deletions cms/src/components/step-layout/outro-step.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@
"images",
"videos"
]
},
"layers": {
"type": "relation",
"relation": "oneToMany",
"target": "api::layer.layer"
}
}
}

0 comments on commit 3ae79b4

Please sign in to comment.