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'] }) {