Skip to main content

createStory

Create a new AI-generated story based on a Bible chapter.
bibleId
string
required
The Bible translation identifier (e.g., “KJV”, “NIV”)
story
string
required
The AI-generated story content
chapterId
string
required
The unique identifier of the Bible chapter this story is based on
chapterReference
string
required
Human-readable chapter reference (e.g., “Genesis 1”, “John 3”)
userId
string
required
The unique identifier of the user creating the story
perspective
string
required
The narrative perspective used in the story (e.g., “first-person”, “third-person”)
setting
string
required
The setting or context for the story retelling
tone
string
required
The tone of the story (e.g., “dramatic”, “conversational”, “poetic”)
storyLength
string
required
The target length of the story (e.g., “short”, “medium”, “long”)
title
string
required
The title of the story
storyId
Id<'stories'>
The unique identifier of the newly created story
import { useMutation } from "convex/react";
import { api } from "@/convex/_generated/api";

function GenerateStory({ chapterId }: { chapterId: string }) {
  const createStory = useMutation(api.stories.createStory);
  const [generating, setGenerating] = useState(false);

  const handleGenerate = async () => {
    setGenerating(true);
    try {
      // Generate story content with your AI service
      const generatedContent = await generateStoryWithAI({
        chapterId,
        perspective: "first-person",
        setting: "modern day",
        tone: "conversational",
        storyLength: "medium"
      });

      const storyId = await createStory({
        bibleId: "NIV",
        story: generatedContent.text,
        chapterId,
        chapterReference: "Genesis 1",
        userId: "user_123",
        perspective: "first-person",
        setting: "modern day",
        tone: "conversational",
        storyLength: "medium",
        title: generatedContent.title
      });

      console.log("Created story:", storyId);
    } finally {
      setGenerating(false);
    }
  };

  return (
    <button onClick={handleGenerate} disabled={generating}>
      {generating ? "Generating..." : "Generate Story"}
    </button>
  );
}

getStories

Retrieve all stories created by a specific user.
userId
string
required
The unique identifier of the user whose stories to retrieve
stories
array
Array of story objects belonging to the user
import { useQuery } from "convex/react";
import { api } from "@/convex/_generated/api";

function MyStories() {
  const stories = useQuery(api.stories.getStories, {
    userId: "user_123"
  });

  if (!stories) return <div>Loading...</div>;

  return (
    <div>
      <h2>My Bible Stories</h2>
      {stories.map((story) => (
        <div key={story._id}>
          <h3>{story.title}</h3>
          <p>
            <strong>{story.chapterReference}</strong> - {story.tone} tone
          </p>
          <p>{story.story.substring(0, 200)}...</p>
        </div>
      ))}
    </div>
  );
}

getStory

Retrieve a single story by its ID.
id
Id<'stories'>
required
The unique identifier of the story to retrieve
userId
string
required
The user ID requesting access to verify ownership
story
object
The complete story object
This function validates that the requesting user owns the story before returning data.
import { useQuery } from "convex/react";
import { api } from "@/convex/_generated/api";
import { Id } from "@/convex/_generated/dataModel";

function StoryDetail({ storyId }: { storyId: Id<"stories"> }) {
  const story = useQuery(api.stories.getStory, {
    id: storyId,
    userId: "user_123"
  });

  if (!story) return <div>Loading...</div>;

  return (
    <article>
      <h1>{story.title}</h1>
      <div>
        <span>Based on {story.chapterReference}</span>
        <span>Perspective: {story.perspective}</span>
        <span>Tone: {story.tone}</span>
      </div>
      <div>
        {story.story}
      </div>
    </article>
  );
}

deleteStory

Delete a story permanently.
id
Id<'stories'>
required
The unique identifier of the story to delete
userId
string
required
The user ID requesting the deletion to verify ownership
response
null
Returns null on successful deletion
This function validates that the requesting user owns the story before allowing deletion. This action is permanent and cannot be undone.
import { useMutation } from "convex/react";
import { api } from "@/convex/_generated/api";
import { Id } from "@/convex/_generated/dataModel";

function DeleteStoryButton({ storyId }: { storyId: Id<"stories"> }) {
  const deleteStory = useMutation(api.stories.deleteStory);
  const [deleting, setDeleting] = useState(false);

  const handleDelete = async () => {
    if (!confirm("Are you sure you want to delete this story? This cannot be undone.")) {
      return;
    }

    setDeleting(true);
    try {
      await deleteStory({
        id: storyId,
        userId: "user_123"
      });
      // Redirect or update UI after deletion
    } finally {
      setDeleting(false);
    }
  };

  return (
    <button onClick={handleDelete} disabled={deleting}>
      {deleting ? "Deleting..." : "Delete Story"}
    </button>
  );
}