feat: Add rich text formatting to sermon notes

Implement comprehensive rich text editing capabilities using Tiptap editor with full formatting toolbar and functionality.

Features:
- Bold, italic, underline, strikethrough text formatting
- Highlight text with yellow marker
- Bullet and numbered lists
- Heading styles (H2, H3)
- Text alignment (left, center, right)
- Undo/redo support
- Clear formatting option
- Intuitive toolbar with icons and tooltips
- Responsive font size support

Technical changes:
- Added Tiptap dependencies to package.json (@tiptap/vue-3, starter-kit, extensions)
- Created RichTextEditor component with full toolbar and formatting options
- Integrated editor into sermon notes section replacing textarea
- Updated download API to convert HTML to formatted plain text
- Updated email API to handle HTML content properly
- Notes now stored as HTML with rich formatting preserved

The editor provides a professional writing experience with all standard formatting tools while maintaining automatic save functionality and seamless integration with email/download features.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-07 09:47:23 -05:00
parent 3f1c573a67
commit 3a50cbebdd
5 changed files with 340 additions and 10 deletions

View File

@@ -117,13 +117,11 @@
<p class="mb-3 text-sm text-red-600 font-medium">
Notes are deleted if a Sermon is deleted by an admin. Please email or download notes to have a copy sent to you.
</p>
<textarea
<RichTextEditor
v-model="notes"
@input="handleNotesChange"
placeholder="Take notes during the sermon..."
class="w-full h-64 px-4 py-3 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 resize-y"
:class="fontSizeClasses"
></textarea>
@update:modelValue="handleNotesChange"
:editorClass="fontSizeClasses"
/>
<div class="mt-2 flex items-center justify-between">
<p v-if="saveStatus" class="text-sm" :class="saveStatus === 'Saved' ? 'text-green-600' : 'text-gray-500'">
{{ saveStatus }}