feat(share): refactor page and enhance thumbnail extraction
- Extract 8 reusable components from monolithic share page - Add LLM health indicator with 30s polling - Implement stealth thumbnail extraction with 4-method cascade - Integrate real-time thumbnail preview component - Reduce share page from 306 to ~140 lines - Add comprehensive outcome documentation Components: - UrlInputSection: URL input and extraction trigger - ProgressIndicator: Loading state display - ExtractedTextViewer: Collapsible text preview - RecipeCard: Recipe display with Tandoor integration - ErrorState: Error handling UI - LogViewer: System logs with color coding - LlmHealthIndicator: LLM status with polling - ThumbnailPreview: Real-time thumbnail display Thumbnail Methods: 1. Meta tag extraction (og:image, twitter:image) 2. Video poster attribute 3. Instagram embedded JSON data 4. Screenshot fallback Stories Completed: - Story 1: Component extraction and refactoring - Story 2: LLM health status indicator - Story 3: Enhanced stealth thumbnail extraction - Story 4: Thumbnail preview integration Closes: RefactorSharePageAndEnhanceThumbnails
This commit is contained in:
72
src/routes/share/components/RecipeCard.svelte
Normal file
72
src/routes/share/components/RecipeCard.svelte
Normal file
@@ -0,0 +1,72 @@
|
||||
<script lang="ts">
|
||||
interface Recipe {
|
||||
name: string;
|
||||
description: string;
|
||||
servings: number;
|
||||
ingredients: Array<{ amount: string; unit: string; item: string }>;
|
||||
steps: string[];
|
||||
}
|
||||
|
||||
let {
|
||||
recipe = null,
|
||||
tandoorEnabled = false,
|
||||
tandoorImporting = false,
|
||||
tandoorError = null,
|
||||
onRetry,
|
||||
onImportToTandoor
|
||||
} = $props<{
|
||||
recipe: Recipe | null;
|
||||
tandoorEnabled: boolean;
|
||||
tandoorImporting: boolean;
|
||||
tandoorError: string | null;
|
||||
onRetry: () => void;
|
||||
onImportToTandoor: () => void;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
{#if recipe}
|
||||
<div class="border rounded p-4 bg-green-50 space-y-2">
|
||||
<h2 class="font-bold text-xl">{recipe.name}</h2>
|
||||
<p class="text-sm">{recipe.description}</p>
|
||||
<p class="text-muted"><strong>Servings:</strong> {recipe.servings}</p>
|
||||
|
||||
<h3 class="font-bold mt-2">Ingredients</h3>
|
||||
<ul class="list-disc pl-5 text-sm">
|
||||
{#each recipe.ingredients as ing}
|
||||
<li>{ing.amount} {ing.unit} {ing.item}</li>
|
||||
{/each}
|
||||
</ul>
|
||||
|
||||
<h3 class="font-bold mt-2">Steps</h3>
|
||||
<ol class="list-decimal pl-5 text-sm">
|
||||
{#each recipe.steps as step}
|
||||
<li>{step}</li>
|
||||
{/each}
|
||||
</ol>
|
||||
|
||||
{#if tandoorEnabled}
|
||||
<div class="mt-4 pt-4 border-t space-y-2">
|
||||
<h3 class="font-bold">Tandoor Integration</h3>
|
||||
{#if tandoorError}
|
||||
<div class="bg-red-100 text-red-800 p-2 rounded text-sm">
|
||||
Error: {tandoorError}
|
||||
</div>
|
||||
{/if}
|
||||
<button
|
||||
onclick={onImportToTandoor}
|
||||
disabled={tandoorImporting}
|
||||
class="bg-orange-600 text-white px-4 py-2 rounded shadow hover:bg-orange-700 w-full disabled:bg-gray-400 disabled:cursor-not-allowed"
|
||||
>
|
||||
{tandoorImporting ? 'Importing...' : 'Import to Tandoor'}
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<button
|
||||
onclick={onRetry}
|
||||
class="bg-blue-500 text-white px-4 py-2 rounded shadow hover:bg-blue-600 w-full mt-2"
|
||||
>
|
||||
🔄 Retry Extraction
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
Reference in New Issue
Block a user