feat(frontend): add next_steps to types, completion modal, and detail page

- Add next_steps to Session, SessionUpdate, SessionComplete, SessionExport types
- Add Next Steps textarea to SessionOutcomeModal
- Update TreeNavigationPage consumer callback for next_steps
- Display next_steps with whitespace-pre-wrap on SessionDetailPage

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Michael Chihlas
2026-02-13 09:38:04 -05:00
parent 8797ae0261
commit 7dab7d7782
4 changed files with 31 additions and 2 deletions

View File

@@ -6,7 +6,7 @@ import type { SessionOutcome } from '@/types'
interface SessionOutcomeModalProps { interface SessionOutcomeModalProps {
isOpen: boolean isOpen: boolean
onClose: () => void onClose: () => void
onSubmit: (data: { outcome: SessionOutcome; outcome_notes?: string }) => Promise<void> onSubmit: (data: { outcome: SessionOutcome; outcome_notes?: string; next_steps?: string }) => Promise<void>
isSubmitting?: boolean isSubmitting?: boolean
} }
@@ -30,10 +30,12 @@ export function SessionOutcomeModal({
const formData = new FormData(formRef.current) const formData = new FormData(formRef.current)
const outcome = (formData.get('session-outcome') as SessionOutcome | null) ?? 'resolved' const outcome = (formData.get('session-outcome') as SessionOutcome | null) ?? 'resolved'
const outcomeNotes = ((formData.get('outcome-notes') as string | null) ?? '').trim() const outcomeNotes = ((formData.get('outcome-notes') as string | null) ?? '').trim()
const nextSteps = ((formData.get('next-steps') as string | null) ?? '').trim()
await onSubmit({ await onSubmit({
outcome, outcome,
outcome_notes: outcomeNotes || undefined, outcome_notes: outcomeNotes || undefined,
next_steps: nextSteps || undefined,
}) })
} }
@@ -113,6 +115,21 @@ export function SessionOutcomeModal({
)} )}
/> />
</div> </div>
<div>
<label className="block text-sm font-medium text-white">Next Steps / Follow-Up (optional)</label>
<textarea
name="next-steps"
defaultValue=""
rows={3}
placeholder="Actions to take after this session..."
className={cn(
'mt-1 block w-full rounded-md border border-white/10 bg-black/50 px-3 py-2',
'text-sm text-white placeholder:text-white/40',
'focus:border-white/30 focus:outline-none focus:ring-1 focus:ring-white/20'
)}
/>
</div>
</form> </form>
</Modal> </Modal>
) )

View File

@@ -332,6 +332,12 @@ export function SessionDetailPage() {
{session.outcome_notes && ( {session.outcome_notes && (
<p className="mt-2 text-sm text-white/60">Outcome Notes: {session.outcome_notes}</p> <p className="mt-2 text-sm text-white/60">Outcome Notes: {session.outcome_notes}</p>
)} )}
{session.next_steps && (
<div className="mt-2">
<span className="text-sm text-white/40">Next Steps:</span>
<p className="mt-0.5 text-sm text-white/60 whitespace-pre-wrap">{session.next_steps}</p>
</div>
)}
</div> </div>
{/* Actions */} {/* Actions */}

View File

@@ -338,7 +338,7 @@ export function TreeNavigationPage() {
openCompletionModal(completionDecision, 'standard') openCompletionModal(completionDecision, 'standard')
} }
const handleSubmitOutcome = async (data: { outcome: SessionOutcome; outcome_notes?: string }) => { const handleSubmitOutcome = async (data: { outcome: SessionOutcome; outcome_notes?: string; next_steps?: string }) => {
if (!session) return if (!session) return
setIsCompleting(true) setIsCompleting(true)
setError(null) setError(null)

View File

@@ -57,6 +57,7 @@ export interface Session {
client_name: string | null client_name: string | null
exported: boolean exported: boolean
scratchpad: string scratchpad: string
next_steps: string
} }
export interface SessionCreate { export interface SessionCreate {
@@ -72,17 +73,22 @@ export interface SessionUpdate {
ticket_number?: string ticket_number?: string
client_name?: string client_name?: string
scratchpad?: string scratchpad?: string
next_steps?: string
} }
export interface SessionExport { export interface SessionExport {
format: 'text' | 'markdown' | 'html' | 'psa' format: 'text' | 'markdown' | 'html' | 'psa'
include_timestamps?: boolean include_timestamps?: boolean
include_tree_info?: boolean include_tree_info?: boolean
include_outcome_notes?: boolean
include_next_steps?: boolean
max_step_index?: number
} }
export interface SessionComplete { export interface SessionComplete {
outcome: SessionOutcome outcome: SessionOutcome
outcome_notes?: string outcome_notes?: string
next_steps?: string
} }
// Navigation state for active session // Navigation state for active session