Tikz.js 8.91 KB
import React, { useState, useEffect, useCallback } from 'react';
import { Drawer, message } from 'antd';
import { UploadOutlined, RetweetOutlined } from '@ant-design/icons';
import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css';
import { getTexToSvg, checkQno, saveFileAndQno } from '../lib/api/tikz'; // Request api
import TikzForm from '../component/tikzForm';
import 'tui-image-editor/dist/tui-image-editor.css'
import ImageEditor from '@toast-ui/react-image-editor'


const fetchTexToSvg = async (data) => {
	// getTexToSvg api를 이용하기 위한 const
	try {
		const result = await getTexToSvg({ tex: data });
		if (result.status === 200) {
			console.log(result.status);
			console.log(result.data);
			return result.data;
		}
	} catch (e) {
		console.log(e);
		//Notification. 추가해서 변환상태 알려주기
		return null;
	}
};


const fetchSaveData = async (data) => {
	try{
	  const result = await saveFileAndQno(data);
	  console.log(result);
	  if(result.status===200){
		return result.data;
	  }    
	}catch(e){
	  console.log(e);
	  message.warning(e.message);
	}
  }

/* 문항번호 체크 */
const fetchCheckQno = async(qno) => {
	try{
	  const result = await checkQno(qno);
	  if(result.status===200){
		console.log(result);
		message.info("사용 가능한 그림 번호 입니다.");
		return true;
	  }else{ 
		message.info("존재 하지 않는 그림 번호 입니다.");
		return false;
	  }
	}catch(e){
	  console.log(e);
	  message.info("존재 하지 않는 그림 번호 입니다.");
	  return false;
	}
  }


  const _tikzcode= "%   예시 (x축, y축, 반지름이 1cm인 원의 그림)   %\n\
%   오른쪽의 변환 버튼을 눌러보세요!   %\n\n\
 \\documentclass{article}\n\
 \\usepackage{tikz}\n\
 \\begin{document}\n\n\n\
 \\begin{tikzpicture}\n\
 \\draw (-1.5,0) -- (1.5,0);\n\
 \\draw (0,-1.5) -- (0,1.5);\n\
 \\draw (0,0) circle (1cm);\n\
 \\end{tikzpicture}\n\n\n\
 \\end{document}";
  
  
  const Tikz = ({ onLeave, visible, callback, selectItem, mode }) => {
	const [fields,setFields] =useState([]);
	const [qno, setQno] = useState(null);
	const [number, setNumber] = useState(null); //문항번호를 저장하는 state
	const [inputText, setinputText] = useState(_tikzcode); //tikz code를 저장하는 state
	const [svg, setSvg] = useState(null); //변환된 svg 데이터를 저장하는 state
	const [qnoCheck,setQnoCheck] = useState(false);
	const [tikzcode,setTikzCode] = useState(_tikzcode);
	//svg
	//onclickevent : Tikz 변환하기 Button의 onClick Event
	//onChangeTikz : TextArea 컴포넌트의 onChange event
	//onFinish : Form data를 제출하기 위한 event
	
	useEffect(()=> {
			if(mode==='preview'&&selectItem){
				console.log(selectItem);

				let initFields = [
					{name:['qno'],value:selectItem.qno},
					{name:['typeSol'],value:selectItem.typeSol},
					{name:['typeQue'],value:selectItem.typeQue},
					{name:['creator'],value:selectItem.creator},
				
				  ];
				  setQno(selectItem.qno);
				  setTikzCode(selectItem.tex);
				  setFields(initFields);
				  setSvg(null);
			}
	},[mode, selectItem]);

	useEffect(()=>{
		if(mode === 'new'){
			let initFields = [
				{name:['qno'],value:null},
				{name:['typeSol'],value:null},
				{name:['typeQue'],value:null},
				{name:['creator'],value:null},
			  ];
			  setQno(null);
			  setTikzCode(_tikzcode);
			  setFields(initFields);
			  setSvg(null);
		}
	},[mode]);

	const onClickEvent = (e) => {
		if(inputText){
			callbackSVG(inputText);
		}
		
		if (inputText === null) {
			console.log(inputText);
			alert(
				//data에 null이 입력된 경우
				'Code 값을 입력해주세요!'
			);
		} else {
			console.log(inputText);
			callbackSVG(inputText);
		}
	};
	const onChangeQno = (value) => {
		console.log(value);
		setQno(value);
		setFields([...fields, {name:['qno'],value:value}]);
	};
/*
	useEffect(()=>{
		if(!visible ){
		  let initFields = [
			{name:['qno'],value:null},
			{name:['typeSol'],value:null},
			{name:['typeQue'],value:null},
			{name:['creator'],value:null},
		  ];
		  setQno(null);
		  setTikzCode(tikzcode);
		  setFields(initFields);
		}
	  },[visible,mode]);
*/
	const callbackSVG = useCallback(async () => {
		const result = await fetchTexToSvg(inputText);
		setSvg(result); //api로 받아온 result를 svg state에 저장
	}, [inputText]);

	const onChangeTikz = (e) => {
		if (e) {
			setinputText(e.target.value);
		} else setinputText(null);
	};

	const onSaveEvent = () => {
		try {
			//서버에 저장이 확인 됐을때  200, 500(오류) http status
			const result = alert('전송이 성공적으로 완료됐습니다.');
		} catch (e) {
			//서버에 저장 오류가 났을때
			console.log(e);
			alert(e);
		}
	};
	const onClickQno = async(e)=>{
		e.preventDefault();
		//번호가 호출 성공시 setQnoCheck(true);
		if(qno){
		  const _checkQno= await fetchCheckQno(qno);
		  setQnoCheck(_checkQno);
		}
	  };
	

	const onFinish = async(values) => {
		console.log(values);
		console.log(qnoCheck);
		if(!qnoCheck){
		  message.warning("그림 번호를 확인해 주세요.")
		  return;
		}else{
			const creator = sessionStorage.getItem('id');
			console.log('Received values of form: ', values); 
			const result = await fetchSaveData({...values, creator});
			console.log(result);
			if(result){
			  message.info(result.message);
			  let initFields = [
				{name:['qno'],value:null},
				{name:['typeSol'],value:null},
				{name:['typeQue'],value:null},
				{name:['creator'],value:null},
			  ];
			  setFields(initFields);
			  onLeave();
			  callback({status:'SAVE_OK'});
			  setQno(null);
			}else{
				callback({status:'SAVE_FAIL'})
			} 
		}
	};

	
	const onChangeTypeSol = (value) => {
		console.log(value);
		setFields([...fields, {name:['typeSol'],value:value}]);
	}
	
	const onChangeTypeQue = (value) => {
		console.log(value);
		setFields([...fields, {name:['typeQue'],value:value}])
	}

	const myTheme = {
		'common.bi.image': 'https://uicdn.toast.com/toastui/img/tui-image-editor-bi.png',
'common.bisize.width': '251px',
'common.bisize.height': '21px',
'common.backgroundImage': 'none',
'common.backgroundColor': '#1e1e1e',
'common.border': '0px',

// header
'header.backgroundImage': 'none',
'header.backgroundColor': 'transparent',
'header.border': '0px',

// load button
'loadButton.backgroundColor': '#fff',
'loadButton.border': '1px solid #ddd',
'loadButton.color': '#222',
'loadButton.fontFamily': 'NotoSans, sans-serif',
'loadButton.fontSize': '12px',

// download button
'downloadButton.backgroundColor': '#fdba3b',
'downloadButton.border': '1px solid #fdba3b',
'downloadButton.color': '#fff',
'downloadButton.fontFamily': 'NotoSans, sans-serif',
'downloadButton.fontSize': '12px',

// icons default
'menu.normalIcon.color': '#8a8a8a',
'menu.activeIcon.color': '#555555',
'menu.disabledIcon.color': '#434343',
'menu.hoverIcon.color': '#e9e9e9',
'submenu.normalIcon.color': '#8a8a8a',
'submenu.activeIcon.color': '#e9e9e9',

'menu.iconSize.width': '24px',
'menu.iconSize.height': '24px',
'submenu.iconSize.width': '32px',
'submenu.iconSize.height': '32px',

// submenu primary color
'submenu.backgroundColor': '#1e1e1e',
'submenu.partition.color': '#858585',

// submenu labels
'submenu.normalLabel.color': '#858585',
'submenu.normalLabel.fontWeight': 'lighter',
'submenu.activeLabel.color': '#fff',
'submenu.activeLabel.fontWeight': 'lighter',

// checkbox style
'checkbox.border': '1px solid #ccc',
'checkbox.backgroundColor': '#fff',

// rango style
'range.pointer.color': '#fff',
'range.bar.color': '#666',
'range.subbar.color': '#d1d1d1',

'range.disabledPointer.color': '#414141',
'range.disabledBar.color': '#282828',
'range.disabledSubbar.color': '#414141',

'range.value.color': '#fff',
'range.value.fontWeight': 'lighter',
'range.value.fontSize': '11px',
'range.value.border': '1px solid #353535',
'range.value.backgroundColor': '#151515',
'range.title.color': '#fff',
'range.title.fontWeight': 'lighter',

// colorpicker style
'colorpicker.button.border': '1px solid #1e1e1e',
'colorpicker.title.color': '#fff'
};
	return (
		<Drawer
			title={'Image Editor'}
			placement={'bottom'}
			closable={true}
			height={'90vh'}
			onClose={onLeave}
			visible={visible}>
			<TikzForm
				svg={svg}
				onClickEvent={onClickEvent}
				onChangeTikz={onChangeTikz}
				onSaveEvent={onSaveEvent}
				onFinish={onFinish}
				tikzcode={tikzcode}
				fields={fields}
				onClickQno={onClickQno}
				onChangeQno={onChangeQno}
				onChangeTypeSol={onChangeTypeSol}
				onChangeTypeQue={onChangeTypeQue}
				qno={qno}>
			</TikzForm>
			<ImageEditor
					includeUI={{
					loadImage: {
						path: '../img/1.jpg',
						name: 'SampleImage'
					},
					theme: myTheme,
					menu: ['shape', 'filter'],
					initMenu: 'filter',
					uiSize: {
						width: '1000px',
						height: '700px'
					},
					menuBarPosition: 'bottom'
					}}
					cssMaxHeight={500}
					cssMaxWidth={700}
					selectionStyle={{
					cornerSize: 20,
					rotatingPointOffset: 70
					}}
					usageStatistics={true}
				/>
							
		</Drawer>
	);
};

export default Tikz;

//<Transform value={tikzHtml}></Transform>