전략 설명 추가
This commit is contained in:
@@ -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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user