| import { useEffect, useState } from 'react'
|
| import { useNavigate } from 'react-router-dom'
|
| import { PERSONA_PROMPT_LOW_CONFIDENCE_COPY } from '../lib/personaPromptBuildCopy'
|
| import {
|
| PERSONA_PROMPT_BUILD_COMPLETE,
|
| PERSONA_PROMPT_BUILD_END,
|
| PERSONA_PROMPT_BUILD_ERROR,
|
| PERSONA_PROMPT_BUILD_START,
|
| type PersonaPromptBuildCompleteDetail,
|
| } from '../lib/personaPromptBuildEvents'
|
|
|
| |
| |
|
|
| export function PersonaPromptBuildHost() {
|
| const navigate = useNavigate()
|
| const [banner, setBanner] = useState(false)
|
| const [modal, setModal] = useState<PersonaPromptBuildCompleteDetail | null>(null)
|
| const [errorMsg, setErrorMsg] = useState<string | null>(null)
|
|
|
| useEffect(() => {
|
| const onStart = () => {
|
| setErrorMsg(null)
|
| setBanner(true)
|
| }
|
| const onEnd = () => setBanner(false)
|
| const onComplete = (e: Event) => {
|
| setBanner(false)
|
| const d = (e as CustomEvent<PersonaPromptBuildCompleteDetail>).detail
|
| if (d?.personaId) setModal(d)
|
| }
|
| const onError = (e: Event) => {
|
| setBanner(false)
|
| const m = (e as CustomEvent<{ message?: string }>).detail?.message
|
| setErrorMsg(m || 'Could not build persona prompt.')
|
| }
|
| window.addEventListener(PERSONA_PROMPT_BUILD_START, onStart)
|
| window.addEventListener(PERSONA_PROMPT_BUILD_END, onEnd)
|
| window.addEventListener(PERSONA_PROMPT_BUILD_COMPLETE, onComplete)
|
| window.addEventListener(PERSONA_PROMPT_BUILD_ERROR, onError)
|
| return () => {
|
| window.removeEventListener(PERSONA_PROMPT_BUILD_START, onStart)
|
| window.removeEventListener(PERSONA_PROMPT_BUILD_END, onEnd)
|
| window.removeEventListener(PERSONA_PROMPT_BUILD_COMPLETE, onComplete)
|
| window.removeEventListener(PERSONA_PROMPT_BUILD_ERROR, onError)
|
| }
|
| }, [])
|
|
|
| const goExperiment = () => {
|
| if (!modal) return
|
| const id = modal.personaId
|
| setModal(null)
|
| navigate(`/experiment?persona=${encodeURIComponent(id)}`)
|
| }
|
|
|
| return (
|
| <>
|
| {banner && (
|
| <div className="persona-prompt-build-banner" role="status" aria-live="polite">
|
| Building, feel free to do other things while you wait
|
| </div>
|
| )}
|
| {errorMsg && (
|
| <div className="modal-overlay" role="alertdialog" aria-modal>
|
| <div className="modal-box">
|
| <h2>Build failed</h2>
|
| <p>{errorMsg}</p>
|
| <div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: '1rem' }}>
|
| <button type="button" className="btn btn-primary" onClick={() => setErrorMsg(null)}>
|
| OK
|
| </button>
|
| </div>
|
| </div>
|
| </div>
|
| )}
|
| {modal && (
|
| <div className="modal-overlay" role="dialog" aria-modal aria-labelledby="persona-build-done-title">
|
| <div className="modal-box">
|
| <h2 id="persona-build-done-title">Persona prompt ready</h2>
|
| <p>
|
| Finished building <strong>{modal.personaName}</strong>. Would you like to see it?
|
| </p>
|
| <p style={{ fontSize: '0.88rem', color: 'var(--text-secondary)', marginBottom: 0 }}>
|
| Opens <strong>Persona Prompt Testing</strong> (Experiment with Personas workshop) with this persona
|
| loaded.
|
| </p>
|
| {modal.confidence === 'low' && (
|
| <p className="persona-prompt-build-warn">
|
| {modal.qualityMessage?.trim() || PERSONA_PROMPT_LOW_CONFIDENCE_COPY}
|
| </p>
|
| )}
|
| <div style={{ display: 'flex', flexWrap: 'wrap', gap: '0.5rem', justifyContent: 'flex-end', marginTop: '1rem' }}>
|
| <button type="button" className="btn btn-secondary" onClick={() => setModal(null)}>
|
| Not now
|
| </button>
|
| <button type="button" className="btn btn-primary" onClick={goExperiment}>
|
| Yes
|
| </button>
|
| </div>
|
| </div>
|
| </div>
|
| )}
|
| </>
|
| )
|
| }
|
|
|