goldenChat base source add

This commit is contained in:
aidev
2026-05-23 15:11:48 +09:00
commit a4ea7762b5
2081 changed files with 1155760 additions and 0 deletions
@@ -0,0 +1,124 @@
import React, { useState, useEffect, useCallback, useRef } from 'react';
import type { IndicatorConfig } from '../types';
import { getIndicatorDef, enrichIndicatorConfig } from '../utils/indicatorRegistry';
import IndicatorSettingsForm from './IndicatorSettingsForm';
import { resetConfigToDefaults } from '../utils/indicatorSettingsEditor';
import { useDraggablePanel } from '../hooks/useDraggablePanel';
interface IndicatorSettingsModalProps {
config: IndicatorConfig;
chartMarket?: string;
onSave: (updated: IndicatorConfig) => void;
onCancel: () => void;
}
/** 차트·설정 화면 공통 — 입력·스타일·가시성 단일 화면 (탭 없음) */
const IndicatorSettingsModal: React.FC<IndicatorSettingsModalProps> = ({
config,
chartMarket = '',
onSave,
onCancel,
}) => {
const def = getIndicatorDef(config.type);
const draftRef = useRef(enrichIndicatorConfig(config));
const [formRevision, setFormRevision] = useState(0);
const [chartHidden, setChartHidden] = useState(() => draftRef.current.hidden ?? false);
const {
panelRef,
dragging,
onHeaderPointerDown, headerTouchStyle,
panelStyle,
headerCursor,
} = useDraggablePanel({ centerOnMount: true });
const openedIdRef = React.useRef<string | null>(null);
useEffect(() => {
if (openedIdRef.current !== config.id) {
openedIdRef.current = config.id;
draftRef.current = enrichIndicatorConfig(config);
setChartHidden(draftRef.current.hidden ?? false);
setFormRevision(r => r + 1);
}
}, [config]);
const title = def
? `${def.koreanName} (${def.name})`
: config.type;
const handleSave = useCallback(() => {
onSave(enrichIndicatorConfig(draftRef.current));
}, [onSave]);
const handleDefaults = useCallback(() => {
draftRef.current = resetConfigToDefaults(draftRef.current);
setChartHidden(draftRef.current.hidden ?? false);
setFormRevision(r => r + 1);
}, []);
const handleHidden = useCallback((showOnChart: boolean) => {
draftRef.current = { ...draftRef.current, hidden: !showOnChart };
setChartHidden(!showOnChart);
}, []);
const handleDraftRef = useCallback((updated: IndicatorConfig) => {
draftRef.current = updated;
}, []);
return (
<div
className="ism-overlay"
onMouseDown={e => { if (e.target === e.currentTarget) onCancel(); }}
>
<div
ref={panelRef}
className="ism-dialog ism-dialog-unified"
style={{
...panelStyle,
zIndex: 5001,
cursor: dragging ? 'grabbing' : undefined,
}}
onMouseDown={e => e.stopPropagation()}
onPointerDown={e => e.stopPropagation()}
>
<div
className="gc-popup-header"
onPointerDown={onHeaderPointerDown}
style={{ cursor: headerCursor, ...headerTouchStyle }}
>
<span className="gc-popup-title">{title}</span>
<button type="button" className="gc-popup-close" onClick={onCancel}></button>
</div>
<div
className="ism-body ism-body-unified"
onMouseDown={e => e.stopPropagation()}
onPointerDown={e => e.stopPropagation()}
>
<IndicatorSettingsForm
key={`${config.id}-${formRevision}`}
config={draftRef.current}
chartMarket={chartMarket}
variant="modal"
deferParentSync
chartHidden={chartHidden}
onChartHiddenChange={handleHidden}
onChange={handleDraftRef}
/>
</div>
<div className="ism-footer">
<button type="button" className="ism-btn-defaults" onClick={handleDefaults}>
<span style={{ opacity: 0.6, fontSize: 11 }}></span>
</button>
<div className="ism-footer-right">
<button type="button" className="ism-btn-cancel" onClick={onCancel}></button>
<button type="button" className="ism-btn-ok" onClick={handleSave}></button>
</div>
</div>
</div>
</div>
);
};
export default IndicatorSettingsModal;