feat: Connect Generate page to AI providers and implement Save functionality #23

Closed
opened 2026-04-09 10:45:18 +00:00 by KnallerKalle · 1 comment
KnallerKalle commented 2026-04-09 10:45:18 +00:00 (Migrated from github.com)

Problem

The Generate page (/generate) has two critical gaps:

  1. Save button has no functionality: Users can generate a lesson preview but cannot save it to their library. The "Save" and "Edit" buttons in the preview panel have no onClick handlers.

  2. AI generation is simulated: The lesson generation uses a setTimeout with hardcoded templates instead of leveraging the existing AI provider infrastructure (src/lib/ai/). The OpenAI and Anthropic providers are fully implemented but not connected.

Current State

Generate Page (src/app/[locale]/generate/page.tsx)

  • handleGenerate uses setTimeout(2500) with template strings
  • Save button: <button>Save</button> — no handler
  • Edit button: <button>Edit</button> — no handler
  • Generated lesson is stored in state as a string, not saved to database

AI Provider Infrastructure (Already Built)

  • src/lib/ai/OpenAIProvider.ts — Full OpenAI API integration
  • src/lib/ai/AnthropicProvider.ts — Full Anthropic API integration
  • src/lib/ai/providerFactory.ts — Factory pattern for provider selection
  • src/lib/ai/cache.ts — Response caching
  • Settings page has API key management UI

Database API

  • DatabaseAPI.createLesson(lesson) — Ready to save lessons
  • DatabaseAPI.listApiKeys() — Can retrieve stored API keys
  • AIProviderFactory.createProvider(config) — Can create provider instances

Proposed Solution

1. Connect AI Provider to Generate Page

// Replace setTimeout with actual AI generation
const handleGenerate = async () => {
  setIsGenerating(true);
  try {
    const keys = await DatabaseAPI.listApiKeys();
    const activeKey = keys.find(k => k.key_type === "openai" || k.key_type === "anthropic");
    if (!activeKey) {
      toast.showError("Please configure an AI API key in Settings");
      return;
    }
    
    const provider = AIProviderFactory.createProvider({
      type: activeKey.key_type,
      apiKey: activeKey.key_value,
      ...AIProviderFactory.getDefaultConfig(activeKey.key_type)
    });
    
    const response = await provider.generateText(buildPrompt(params), {
      systemPrompt: FELDENKRAIS_SYSTEM_PROMPT,
      temperature: 0.8,
      maxTokens: 4096
    });
    
    setGeneratedLesson(response.data);
  } catch (error) {
    toast.showError("Generation failed: " + error);
  } finally {
    setIsGenerating(false);
  }
};

2. Implement Save Functionality

const handleSave = async () => {
  if (!generatedLesson) return;
  try {
    const lesson: Lesson = {
      id: crypto.randomUUID(),
      title: extractTitle(generatedLesson),
      content: generatedLesson,
      category: params.focusArea,
      difficulty: params.difficulty,
      duration: params.duration * 60,
      is_generated: true,
      status: "draft",
      created_at: new Date().toISOString(),
      updated_at: new Date().toISOString()
    };
    await DatabaseAPI.createLesson(lesson);
    toast.showSuccess("Lesson saved to library!");
    router.push(`/${locale}/library`);
  } catch (error) {
    toast.showError("Failed to save lesson");
  }
};

3. Implement Edit Functionality

  • Toggle between preview and edit mode
  • Textarea for editing generated content
  • Save after editing

Acceptance Criteria

  • Generate page uses AI provider when API key is configured
  • Falls back to template generation when no API key is set
  • Save button saves generated lesson to database
  • After save, redirects to library page
  • Edit button enables in-page editing
  • Toast notifications for success/error feedback
  • Loading states during generation and save
  • TypeScript types are correct

Priority

HIGH — Core user flow is broken: generate → save is incomplete

Files to Modify

  • src/app/[locale]/generate/page.tsx — Main implementation
  • src/lib/ai/types.ts — Possibly add Feldenkrais-specific types
  • src/types/database.ts — Ensure Lesson type compatibility
  • Issue #9: Phase 2 Planning
  • Issue #20: Cloud Storage (API key management)
## Problem The Generate page (`/generate`) has two critical gaps: 1. **Save button has no functionality**: Users can generate a lesson preview but cannot save it to their library. The "Save" and "Edit" buttons in the preview panel have no `onClick` handlers. 2. **AI generation is simulated**: The lesson generation uses a `setTimeout` with hardcoded templates instead of leveraging the existing AI provider infrastructure (`src/lib/ai/`). The OpenAI and Anthropic providers are fully implemented but not connected. ## Current State ### Generate Page (`src/app/[locale]/generate/page.tsx`) - `handleGenerate` uses `setTimeout(2500)` with template strings - Save button: `<button>Save</button>` — no handler - Edit button: `<button>Edit</button>` — no handler - Generated lesson is stored in state as a string, not saved to database ### AI Provider Infrastructure (Already Built) - `src/lib/ai/OpenAIProvider.ts` — Full OpenAI API integration - `src/lib/ai/AnthropicProvider.ts` — Full Anthropic API integration - `src/lib/ai/providerFactory.ts` — Factory pattern for provider selection - `src/lib/ai/cache.ts` — Response caching - Settings page has API key management UI ### Database API - `DatabaseAPI.createLesson(lesson)` — Ready to save lessons - `DatabaseAPI.listApiKeys()` — Can retrieve stored API keys - `AIProviderFactory.createProvider(config)` — Can create provider instances ## Proposed Solution ### 1. Connect AI Provider to Generate Page ```typescript // Replace setTimeout with actual AI generation const handleGenerate = async () => { setIsGenerating(true); try { const keys = await DatabaseAPI.listApiKeys(); const activeKey = keys.find(k => k.key_type === "openai" || k.key_type === "anthropic"); if (!activeKey) { toast.showError("Please configure an AI API key in Settings"); return; } const provider = AIProviderFactory.createProvider({ type: activeKey.key_type, apiKey: activeKey.key_value, ...AIProviderFactory.getDefaultConfig(activeKey.key_type) }); const response = await provider.generateText(buildPrompt(params), { systemPrompt: FELDENKRAIS_SYSTEM_PROMPT, temperature: 0.8, maxTokens: 4096 }); setGeneratedLesson(response.data); } catch (error) { toast.showError("Generation failed: " + error); } finally { setIsGenerating(false); } }; ``` ### 2. Implement Save Functionality ```typescript const handleSave = async () => { if (!generatedLesson) return; try { const lesson: Lesson = { id: crypto.randomUUID(), title: extractTitle(generatedLesson), content: generatedLesson, category: params.focusArea, difficulty: params.difficulty, duration: params.duration * 60, is_generated: true, status: "draft", created_at: new Date().toISOString(), updated_at: new Date().toISOString() }; await DatabaseAPI.createLesson(lesson); toast.showSuccess("Lesson saved to library!"); router.push(`/${locale}/library`); } catch (error) { toast.showError("Failed to save lesson"); } }; ``` ### 3. Implement Edit Functionality - Toggle between preview and edit mode - Textarea for editing generated content - Save after editing ## Acceptance Criteria - [ ] Generate page uses AI provider when API key is configured - [ ] Falls back to template generation when no API key is set - [ ] Save button saves generated lesson to database - [ ] After save, redirects to library page - [ ] Edit button enables in-page editing - [ ] Toast notifications for success/error feedback - [ ] Loading states during generation and save - [ ] TypeScript types are correct ## Priority **HIGH** — Core user flow is broken: generate → save is incomplete ## Files to Modify - `src/app/[locale]/generate/page.tsx` — Main implementation - `src/lib/ai/types.ts` — Possibly add Feldenkrais-specific types - `src/types/database.ts` — Ensure Lesson type compatibility ## Related Issues - Issue #9: Phase 2 Planning - Issue #20: Cloud Storage (API key management)
KnallerKalle commented 2026-04-09 11:40:49 +00:00 (Migrated from github.com)

✅ Implemented in commit ebc4448

Changes Made

AI Provider Integration:

  • Generate page now checks for configured API keys (OpenAI/Anthropic)
  • Uses AIProviderFactory to create provider instances
  • Sends Feldenkrais-specific prompts with knowledge base context
  • Falls back to template generation when no API key is configured
  • Shows 'AI Generated' badge when AI was used

Save to Library:

  • Save button saves generated lesson to database via DatabaseAPI.createLesson()
  • Extracts title from markdown headings
  • Sets appropriate metadata (category, difficulty, duration, tags)
  • Redirects to library page after save
  • Loading state with spinner during save

Edit Mode:

  • Edit button toggles between preview and edit mode
  • Full-textarea editing in edit mode
  • Preview mode shows formatted markdown
  • Contextual tip text changes based on mode

Error Handling:

  • Toast notifications for all success/error states
  • Graceful fallback from AI to template generation
  • Loading states during generation and save

Files Modified

  • src/app/[locale]/generate/page.tsx — Complete AI integration + Save/Edit

Remaining (Future)

  • AI provider configuration check before generation attempt (UX improvement)
  • Generation history/versioning
  • Regenerate with different parameters
## ✅ Implemented in commit `ebc4448` ### Changes Made **AI Provider Integration**: - Generate page now checks for configured API keys (OpenAI/Anthropic) - Uses `AIProviderFactory` to create provider instances - Sends Feldenkrais-specific prompts with knowledge base context - Falls back to template generation when no API key is configured - Shows 'AI Generated' badge when AI was used **Save to Library**: - Save button saves generated lesson to database via `DatabaseAPI.createLesson()` - Extracts title from markdown headings - Sets appropriate metadata (category, difficulty, duration, tags) - Redirects to library page after save - Loading state with spinner during save **Edit Mode**: - Edit button toggles between preview and edit mode - Full-textarea editing in edit mode - Preview mode shows formatted markdown - Contextual tip text changes based on mode **Error Handling**: - Toast notifications for all success/error states - Graceful fallback from AI to template generation - Loading states during generation and save ### Files Modified - `src/app/[locale]/generate/page.tsx` — Complete AI integration + Save/Edit ### Remaining (Future) - [ ] AI provider configuration check before generation attempt (UX improvement) - [ ] Generation history/versioning - [ ] Regenerate with different parameters
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Kalle/ATM#23
No description provided.