|
<script lang="ts"> |
|
import type { PicletWorkflowState } from '$lib/types'; |
|
import type { PicletInstance } from '$lib/db/schema'; |
|
import { TYPE_DATA, PicletType } from '$lib/types/picletTypes'; |
|
import { generatedDataToPicletInstance } from '$lib/db/piclets'; |
|
import PicletCard from '../Piclets/PicletCard.svelte'; |
|
import PicletDetail from '../Piclets/PicletDetail.svelte'; |
|
|
|
interface Props { |
|
workflowState: PicletWorkflowState; |
|
onReset: () => void; |
|
} |
|
|
|
let { workflowState, onReset }: Props = $props(); |
|
let isSaving = $state(false); |
|
let isSaved = $state(false); |
|
let picletInstance: PicletInstance | null = $state(null); |
|
let showDetailView = $state(false); |
|
let saveError: string | null = $state(null); |
|
|
|
|
|
$effect(() => { |
|
if (workflowState.picletImage && workflowState.picletConcept && workflowState.picletStats) { |
|
try { |
|
const picletData = { |
|
name: workflowState.picletStats.name || 'Unknown Piclet', |
|
imageUrl: workflowState.picletImage.imageUrl, |
|
imageData: workflowState.picletImage.imageData, |
|
imageCaption: workflowState.imageCaption || '', |
|
concept: workflowState.picletConcept, |
|
imagePrompt: workflowState.imagePrompt || '', |
|
stats: workflowState.picletStats, |
|
createdAt: new Date() |
|
}; |
|
|
|
|
|
generatedDataToPicletInstance(picletData).then(instance => { |
|
picletInstance = { ...instance, id: 0 }; |
|
}).catch(error => { |
|
console.error('Failed to create piclet instance:', error); |
|
saveError = `Failed to create piclet: ${(error as Error).message || String(error)}`; |
|
}); |
|
} catch (error) { |
|
console.error('Failed to create piclet instance:', error); |
|
saveError = `Failed to create piclet: ${(error as Error).message || String(error)}`; |
|
} |
|
} |
|
}); |
|
|
|
function handleCardClick() { |
|
if (picletInstance) { |
|
showDetailView = true; |
|
} |
|
} |
|
|
|
function handleCloseDetail() { |
|
showDetailView = false; |
|
} |
|
</script> |
|
|
|
{#if showDetailView && picletInstance} |
|
<PicletDetail |
|
instance={picletInstance} |
|
onClose={handleCloseDetail} |
|
/> |
|
{:else} |
|
<div class="result-container"> |
|
<div class="success-header"> |
|
<div class="success-icon">✨</div> |
|
<h2>Success!</h2> |
|
<p class="success-message"> |
|
{#if picletInstance?.caught} |
|
<strong>{picletInstance?.nickname || 'This creature'}</strong> has been caught and added to your roster! |
|
{:else} |
|
You can now encounter <strong>{picletInstance?.nickname || 'this creature'}</strong>! |
|
{/if} |
|
</p> |
|
</div> |
|
|
|
{#if picletInstance} |
|
<div class="piclet-preview"> |
|
<PicletCard |
|
piclet={picletInstance} |
|
size={140} |
|
onClick={handleCardClick} |
|
/> |
|
<p class="tap-hint">Tap to view details</p> |
|
</div> |
|
{/if} |
|
|
|
<div class="action-buttons"> |
|
<button class="action-button primary" onclick={onReset}> |
|
Create Another |
|
</button> |
|
</div> |
|
</div> |
|
{/if} |
|
|
|
<style> |
|
.result-container { |
|
max-width: 500px; |
|
margin: 0 auto; |
|
padding: 2rem; |
|
text-align: center; |
|
} |
|
|
|
.success-header { |
|
margin-bottom: 2rem; |
|
} |
|
|
|
.success-icon { |
|
font-size: 3rem; |
|
margin-bottom: 1rem; |
|
} |
|
|
|
.success-header h2 { |
|
color: #333; |
|
margin: 0 0 1rem; |
|
font-size: 1.8rem; |
|
font-weight: 600; |
|
} |
|
|
|
.success-message { |
|
color: #666; |
|
font-size: 1.1rem; |
|
margin: 0; |
|
} |
|
|
|
.success-message strong { |
|
color: #333; |
|
font-weight: 600; |
|
} |
|
|
|
.piclet-preview { |
|
display: flex; |
|
flex-direction: column; |
|
align-items: center; |
|
gap: 1rem; |
|
margin: 2rem 0; |
|
} |
|
|
|
.tap-hint { |
|
color: #888; |
|
font-size: 0.9rem; |
|
margin: 0; |
|
font-style: italic; |
|
} |
|
|
|
.action-buttons { |
|
display: flex; |
|
justify-content: center; |
|
margin-top: 2rem; |
|
} |
|
|
|
.action-button { |
|
padding: 0.875rem 2rem; |
|
border: none; |
|
border-radius: 12px; |
|
font-weight: 600; |
|
font-size: 1rem; |
|
cursor: pointer; |
|
transition: all 0.2s ease; |
|
min-width: 160px; |
|
} |
|
|
|
.action-button.primary { |
|
background: linear-gradient(135deg, #3b82f6, #1d4ed8); |
|
color: white; |
|
box-shadow: 0 4px 12px rgba(59, 130, 246, 0.4); |
|
} |
|
|
|
.action-button.primary:hover { |
|
background: linear-gradient(135deg, #2563eb, #1e40af); |
|
transform: translateY(-2px); |
|
box-shadow: 0 6px 16px rgba(59, 130, 246, 0.4); |
|
} |
|
|
|
.action-button.primary:active { |
|
transform: translateY(0); |
|
} |
|
|
|
@media (max-width: 768px) { |
|
.result-container { |
|
padding: 1rem; |
|
} |
|
} |
|
</style> |