전략 설명 추가

This commit is contained in:
Macbook
2026-06-16 21:35:59 +09:00
parent 26bfca7b4c
commit 822d99f6b0
6 changed files with 363 additions and 11 deletions
@@ -0,0 +1,104 @@
/**
* LOGIC EXPRESSION 아래 — 조건을 알기 쉬운 문장으로 설명
*/
import React, { useMemo } from 'react';
import type { LogicNode } from '../../utils/strategyTypes';
import type { DefType } from '../../utils/strategyEditorShared';
import {
buildStrategyNarrative,
type StrategyDescriptionInput,
} from '../../utils/strategyDescriptionNarrative';
import type { EditorConditionState } from '../../utils/strategyConditionSerde';
import { emptyEditorConditionState } from '../../utils/strategyConditionSerde';
interface Props {
name?: string;
description?: string;
buyCondition: LogicNode | null;
sellCondition: LogicNode | null;
buyEditorState?: EditorConditionState;
sellEditorState?: EditorConditionState;
orphanCount?: number;
def: DefType;
/** 터미널·하단 패널 등 좁은 공간 — 서두·각주 생략, 핵심 bullet 위주 */
compact?: boolean;
className?: string;
}
export default function LogicExpressionNarrative({
name,
description,
buyCondition,
sellCondition,
buyEditorState,
sellEditorState,
orphanCount,
def,
compact = false,
className,
}: Props) {
const input: StrategyDescriptionInput = useMemo(() => ({
name,
description,
buyEditorState: buyEditorState ?? emptyEditorConditionState(),
sellEditorState: sellEditorState ?? emptyEditorConditionState(),
buyCondition,
sellCondition,
orphanCount,
def,
}), [
name,
description,
buyEditorState,
sellEditorState,
buyCondition,
sellCondition,
orphanCount,
def,
]);
const narrative = useMemo(() => buildStrategyNarrative(input), [input]);
const rootClass = ['se-narrative', compact ? 'se-narrative--compact' : '', className]
.filter(Boolean)
.join(' ');
return (
<div className={rootClass}>
{!compact && narrative.intro.map((p, i) => (
<p key={`intro-${i}`} className="se-narrative-intro">{p}</p>
))}
{narrative.sections.map(section => (
<section key={section.title} className="se-narrative-section">
<h4 className="se-narrative-section-title">{section.title}</h4>
{!compact && section.paragraphs.map((p, i) => (
<p key={`${section.title}-p-${i}`} className="se-narrative-para">{p}</p>
))}
{compact && section.paragraphs.length > 0 && (
<p className="se-narrative-para se-narrative-para--lead">
{section.paragraphs[section.paragraphs.length - 1]}
</p>
)}
{section.bullets && section.bullets.length > 0 && (
<ul className="se-narrative-list">
{section.bullets.map((line, i) => (
<li key={`${section.title}-b-${i}`} className="se-narrative-list-item">{line}</li>
))}
</ul>
)}
</section>
))}
{narrative.footnotes.length > 0 && (
<footer className="se-narrative-footnotes">
{narrative.footnotes.map((note, i) => (
<p key={`fn-${i}`} className="se-narrative-footnote">
{compact ? note : `${note}`}
</p>
))}
</footer>
)}
</div>
);
}