createStory
Create a new AI-generated story based on a Bible chapter.
The Bible translation identifier (e.g., “KJV”, “NIV”)
The AI-generated story content
The unique identifier of the Bible chapter this story is based on
Human-readable chapter reference (e.g., “Genesis 1”, “John 3”)
The unique identifier of the user creating the story
The narrative perspective used in the story (e.g., “first-person”, “third-person”)
The setting or context for the story retelling
The tone of the story (e.g., “dramatic”, “conversational”, “poetic”)
The target length of the story (e.g., “short”, “medium”, “long”)
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.
The unique identifier of the user whose stories to retrieve
Array of story objects belonging to the user
Bible translation identifier
Human-readable chapter reference
User who created the story
Timestamp when story was created
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.
The unique identifier of the story to retrieve
The user ID requesting access to verify ownership
The complete story object
Bible translation identifier
Human-readable chapter reference
User who created the story
The complete story content
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.
The unique identifier of the story to delete
The user ID requesting the deletion to verify ownership
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>
);
}