diff --git a/components/episode-ai-thingy.tsx b/components/episode-ai-thingy.tsx new file mode 100644 index 0000000..90577e3 --- /dev/null +++ b/components/episode-ai-thingy.tsx @@ -0,0 +1,167 @@ +'use client'; + +import type { Tables } from '@/types/supabase/database'; + +import { Box, Button, Flex, Text } from '@radix-ui/themes'; +import { useCallback, useEffect, useMemo, useState } from 'react'; +import { PiRobotBold } from 'react-icons/pi'; + +import { CollapsiblePanel } from './ui/collapsible-panel'; + +type Props = { + id: Tables<'episode'>['id']; +}; + +function MockAIThingy() { + return ( + + Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam quod + voluptatum quia quos, voluptatem quibusdam quae voluptas, quas, doloribus + voluptate. Lorem ipsum dolor sit amet consectetur adipisicing elit. + Quisquam quod voluptatum quia quos, voluptatem quibusdam quae voluptas, + quas, doloribus voluptate. Lorem ipsum dolor sit amet consectetur + adipisicing elit. Quisquam quod voluptatum quia quos, voluptatem quibusdam + quae voluptas, quas, doloribus voluptate. Lorem ipsum dolor sit amet + consectetur adipisicing elit. Quisquam quod voluptatum quia quos, + voluptatem quibusdam quae voluptas, quas, doloribus voluptate. Lorem ipsum + dolor sit amet consectetur adipisicing elit. Quisquam quod voluptatum quia + quos, voluptatem quibusdam quae voluptas, quas, doloribus voluptate. Lorem + ipsum dolor sit amet consectetur adipisicing elit. Quisquam quod + voluptatum quia quos, voluptatem quibusdam quae voluptas, quas, doloribus + voluptate. Lorem ipsum dolor sit amet consectetur adipisicing elit. + Quisquam quod voluptatum quia quos, voluptatem quibusdam quae voluptas, + quas, doloribus voluptate. +
+
+ Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam quod + voluptatum quia quos, voluptatem quibusdam quae voluptas, quas, doloribus + voluptate. Lorem ipsum dolor sit amet consectetur adipisicing elit. + Quisquam quod voluptatum quia quos, voluptatem quibusdam quae voluptas, + quas, doloribus voluptate. Lorem ipsum dolor sit amet consectetur + adipisicing elit. Quisquam quod voluptatum quia quos, voluptatem quibusdam + quae voluptas, quas, doloribus voluptate. Lorem ipsum dolor sit amet + consectetur adipisicing elit. Quisquam quod voluptatum quia quos, + voluptatem quibusdam quae voluptas, quas, doloribus voluptate. Lorem ipsum + dolor sit amet consectetur adipisicing elit. Quisquam quod voluptatum quia + quos, voluptatem quibusdam quae voluptas, quas, doloribus voluptate. Lorem + ipsum dolor sit amet consectetur adipisicing elit. Quisquam quod + voluptatum quia quos, voluptatem quibusdam quae voluptas, quas, doloribus + voluptate. Lorem ipsum dolor sit amet consectetur adipisicing elit. + Quisquam quod voluptatum quia quos, voluptatem quibusdam quae voluptas, + quas, doloribus voluptate. +
+ ); +} + +type State = + | { + timeRemaining: number; + type: 'countdown'; + } + | { + type: 'error'; + } + | { + type: 'idle'; + } + | { + type: 'loading'; + } + | { + type: 'success'; + }; + +export function EpisodeAIThingy(props: Props) { + const [state, setState] = useState({ type: 'idle' }); + + const doTheThingy = useCallback(async () => { + if (state.type !== 'idle') { + return; + } + + try { + setState({ type: 'loading' }); + await fetch(`https://dummyjson.com/todos`); + setState({ timeRemaining: 5, type: 'countdown' }); + } catch (error) { + setState({ type: 'error' }); + } + }, [state.type]); + + useEffect(() => { + if (state.type === 'countdown') { + const interval = setInterval(() => { + setState((_state) => { + if (_state.type !== 'countdown') { + return _state; + } + + if (_state.timeRemaining <= 0) { + return { type: 'success' }; + } + + return { ..._state, timeRemaining: _state.timeRemaining - 1 }; + }); + }, 1000); + + return () => { + clearInterval(interval); + }; + } + }, [state]); + + const buttonText = useMemo(() => { + switch (state.type) { + case 'countdown': + return state.timeRemaining === 0 + ? `THERE YOU GO!` + : `Presenting the AI thingy in ${state.timeRemaining} seconds...`; + case 'error': + return 'Error'; + case 'idle': + return 'Do the AI thingy!'; + case 'loading': + return 'Doing the AI thingy...'; + case 'success': + return 'Done!'; + } + }, [state]); + + return ( + + {state.type === 'success' ? null : ( + + + + )} + + + + + + ); +} diff --git a/components/episode-detail.stories.tsx b/components/episode-detail.stories.tsx index a58520b..fd265fd 100644 --- a/components/episode-detail.stories.tsx +++ b/components/episode-detail.stories.tsx @@ -7,6 +7,7 @@ export const Primary: StoryObj = { , - 'description' | 'duration' | 'image' | 'published_date' | 'title' + 'description' | 'duration' | 'id' | 'image' | 'published_date' | 'title' > & { show: { id: Tables<'show'>['id']; @@ -51,9 +52,7 @@ function EpisodeDetailContent( ) : null} - - - + ); } @@ -75,6 +74,7 @@ async function EpisodeDetailPage(props: { id: Tables<'episode'>['id'] }) {