Showing
32 changed files
with
906 additions
and
38 deletions
This diff is collapsed. Click to expand it.
| 1 | -.App { | 1 | +.trigger { |
| 2 | - text-align: center; | 2 | + font-size: 18px; |
| 3 | + line-height: 64px; | ||
| 4 | + padding: 0 24px; | ||
| 5 | + cursor: pointer; | ||
| 6 | + transition: color 0.3s; | ||
| 3 | } | 7 | } |
| 4 | 8 | ||
| 5 | -.App-logo { | 9 | +.trigger:hover { |
| 6 | - height: 40vmin; | 10 | + color: #1890ff; |
| 7 | - pointer-events: none; | ||
| 8 | } | 11 | } |
| 9 | 12 | ||
| 10 | -@media (prefers-reduced-motion: no-preference) { | 13 | +.logo { |
| 11 | - .App-logo { | 14 | + height: 32px; |
| 12 | - animation: App-logo-spin infinite 20s linear; | 15 | + background: rgba(255, 255, 255, 0.2); |
| 13 | - } | 16 | + margin: 16px; |
| 14 | } | 17 | } |
| 15 | 18 | ||
| 16 | -.App-header { | 19 | +.site-layout .site-layout-background { |
| 17 | - background-color: #282c34; | 20 | + background: #fff; |
| 18 | - min-height: 100vh; | ||
| 19 | - display: flex; | ||
| 20 | - flex-direction: column; | ||
| 21 | - align-items: center; | ||
| 22 | - justify-content: center; | ||
| 23 | - font-size: calc(10px + 2vmin); | ||
| 24 | - color: white; | ||
| 25 | -} | ||
| 26 | - | ||
| 27 | -.App-link { | ||
| 28 | - color: #61dafb; | ||
| 29 | -} | ||
| 30 | - | ||
| 31 | -@keyframes App-logo-spin { | ||
| 32 | - from { | ||
| 33 | - transform: rotate(0deg); | ||
| 34 | - } | ||
| 35 | - to { | ||
| 36 | - transform: rotate(360deg); | ||
| 37 | - } | ||
| 38 | } | 21 | } |
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
minsung/src/Container/Home.css
0 → 100644
| 1 | +.site-layout .site-layout-background { | ||
| 2 | + background: #fff; | ||
| 3 | +} | ||
| 4 | + | ||
| 5 | +[data-theme="dark"] .site-layout .site-layout-background { | ||
| 6 | + background: #141414; | ||
| 7 | +} | ||
| 8 | + | ||
| 9 | +/* | ||
| 10 | +.ant-menu-item.ant-menu-item-only-child.ant-menu-item:link { | ||
| 11 | + background-color: red; | ||
| 12 | +} | ||
| 13 | + | ||
| 14 | +.ant-menu-item.ant-menu-item-only-child.ant-menu-item:visited { | ||
| 15 | + background-color: red; | ||
| 16 | +} | ||
| 17 | +*/ | ||
| 18 | +.logout { | ||
| 19 | + position: absolute; | ||
| 20 | + right:15px; | ||
| 21 | + top:15px; | ||
| 22 | + text-align: center; | ||
| 23 | + justify-content: center; | ||
| 24 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
minsung/src/Container/Home.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/Container/Login.js
0 → 100644
| 1 | +import React,{useState} from 'react'; | ||
| 2 | +import LoginForm from '../component/LoginForm'; | ||
| 3 | +import { getLoginInfo } from '../lib/api/login'; | ||
| 4 | +import {Redirect, withRouter} from "react-router-dom"; | ||
| 5 | + | ||
| 6 | +const fetchLogInfo= async(data) =>{ | ||
| 7 | + try{ | ||
| 8 | + const result = await getLoginInfo(data); | ||
| 9 | + if(result.status ===200){ | ||
| 10 | + console.log("서버 데이터와 일치: "+ result.data ); // result의 반환값 확인 | ||
| 11 | + return true; | ||
| 12 | + } | ||
| 13 | + } catch(e){ | ||
| 14 | + console.log(e); | ||
| 15 | + alert("id와 비밀번호를 확인해주세요!"); | ||
| 16 | + return false; | ||
| 17 | + } | ||
| 18 | +} | ||
| 19 | + | ||
| 20 | +const Login = () => { | ||
| 21 | + | ||
| 22 | + const [authenticated,setAuthenticated] = useState(false); | ||
| 23 | + const onFinish = async (values)=> { | ||
| 24 | + console.log('Received values of form: ', values); | ||
| 25 | + const isAuth = await fetchLogInfo(values); | ||
| 26 | + sessionStorage.setItem("isAuth", isAuth); //세션 스토리지 저장 | ||
| 27 | + sessionStorage.setItem("id",values.userid); | ||
| 28 | + | ||
| 29 | + setAuthenticated(isAuth); | ||
| 30 | + } | ||
| 31 | + if(authenticated){ | ||
| 32 | + // history.push('/Home'); | ||
| 33 | + return <Redirect to="/Home"/> | ||
| 34 | + }else{ | ||
| 35 | + return <LoginForm onFinish={onFinish} > | ||
| 36 | + </LoginForm> | ||
| 37 | + } | ||
| 38 | +}; | ||
| 39 | + | ||
| 40 | +export default withRouter(Login); |
minsung/src/Container/Tikz.css
0 → 100644
| 1 | +.trigger { | ||
| 2 | + font-size: 18px; | ||
| 3 | + line-height: 64px; | ||
| 4 | + padding: 0 24px; | ||
| 5 | + cursor: pointer; | ||
| 6 | + transition: color 0.3s; | ||
| 7 | +} | ||
| 8 | + | ||
| 9 | +.trigger:hover { | ||
| 10 | + color: #1890ff; | ||
| 11 | +} | ||
| 12 | + | ||
| 13 | +.logo { | ||
| 14 | + height: 32px; | ||
| 15 | + background: rgba(255, 255, 255, 0.2); | ||
| 16 | + margin: 16px; | ||
| 17 | +} | ||
| 18 | + | ||
| 19 | +.site-layout .site-layout-background { | ||
| 20 | + background: #fff; | ||
| 21 | +} | ||
| 22 | + | ||
| 23 | + | ||
| 24 | +div.demo-editor.rdw-editor-main { | ||
| 25 | + border: 1px solid #f1f1f1; | ||
| 26 | + height: 65vh; | ||
| 27 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
minsung/src/Container/Tikz.js
0 → 100644
| 1 | +import React, { useState, useEffect, useCallback } from 'react'; | ||
| 2 | +import { Drawer, message } from 'antd'; | ||
| 3 | +import { UploadOutlined, RetweetOutlined } from '@ant-design/icons'; | ||
| 4 | +import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css'; | ||
| 5 | +import { getTexToSvg, checkQno, saveFileAndQno } from '../lib/api/tikz'; // Request api | ||
| 6 | +import TikzForm from '../component/tikzForm'; | ||
| 7 | + | ||
| 8 | + | ||
| 9 | + | ||
| 10 | +const fetchTexToSvg = async (data) => { | ||
| 11 | + // getTexToSvg api를 이용하기 위한 const | ||
| 12 | + try { | ||
| 13 | + const result = await getTexToSvg({ tex: data }); | ||
| 14 | + if (result.status === 200) { | ||
| 15 | + console.log(result.status); | ||
| 16 | + console.log(result.data); | ||
| 17 | + return result.data; | ||
| 18 | + } | ||
| 19 | + } catch (e) { | ||
| 20 | + console.log(e); | ||
| 21 | + //Notification. 추가해서 변환상태 알려주기 | ||
| 22 | + return null; | ||
| 23 | + } | ||
| 24 | +}; | ||
| 25 | + | ||
| 26 | + | ||
| 27 | +const fetchSaveData = async (data) => { | ||
| 28 | + try{ | ||
| 29 | + const result = await saveFileAndQno(data); | ||
| 30 | + console.log(result); | ||
| 31 | + if(result.status===200){ | ||
| 32 | + return result.data; | ||
| 33 | + } | ||
| 34 | + }catch(e){ | ||
| 35 | + console.log(e); | ||
| 36 | + message.warning(e.message); | ||
| 37 | + } | ||
| 38 | + } | ||
| 39 | + | ||
| 40 | +/* 문항번호 체크 */ | ||
| 41 | +const fetchCheckQno = async(qno) => { | ||
| 42 | + try{ | ||
| 43 | + const result = await checkQno(qno); | ||
| 44 | + if(result.status===200){ | ||
| 45 | + console.log(result); | ||
| 46 | + message.info("사용 가능한 문항 번호 입니다."); | ||
| 47 | + return true; | ||
| 48 | + }else{ | ||
| 49 | + message.info("존재 하지 않는 문항 번호 입니다."); | ||
| 50 | + return false; | ||
| 51 | + } | ||
| 52 | + }catch(e){ | ||
| 53 | + console.log(e); | ||
| 54 | + message.info("존재 하지 않는 문항 번호 입니다."); | ||
| 55 | + return false; | ||
| 56 | + } | ||
| 57 | + } | ||
| 58 | + | ||
| 59 | + | ||
| 60 | + const _tikzcode= "% 예시 (x축, y축, 반지름이 1cm인 원의 그림) %\n\ | ||
| 61 | +% 오른쪽의 변환 버튼을 눌러보세요! %\n\n\ | ||
| 62 | + \\documentclass{article}\n\ | ||
| 63 | + \\usepackage{tikz}\n\ | ||
| 64 | + \\begin{document}\n\n\n\ | ||
| 65 | + \\begin{tikzpicture}\n\ | ||
| 66 | + \\draw (-1.5,0) -- (1.5,0);\n\ | ||
| 67 | + \\draw (0,-1.5) -- (0,1.5);\n\ | ||
| 68 | + \\draw (0,0) circle (1cm);\n\ | ||
| 69 | + \\end{tikzpicture}\n\n\n\ | ||
| 70 | + \\end{document}"; | ||
| 71 | + | ||
| 72 | + | ||
| 73 | + const Tikz = ({ onLeave, visible, callback, selectItem, mode }) => { | ||
| 74 | + const [fields,setFields] =useState([]); | ||
| 75 | + const [qno, setQno] = useState(null); | ||
| 76 | + const [number, setNumber] = useState(null); //문항번호를 저장하는 state | ||
| 77 | + const [inputText, setinputText] = useState(_tikzcode); //tikz code를 저장하는 state | ||
| 78 | + const [svg, setSvg] = useState(null); //변환된 svg 데이터를 저장하는 state | ||
| 79 | + const [qnoCheck,setQnoCheck] = useState(false); | ||
| 80 | + const [tikzcode,setTikzCode] = useState(_tikzcode); | ||
| 81 | + //svg | ||
| 82 | + //onclickevent : Tikz 변환하기 Button의 onClick Event | ||
| 83 | + //onChangeTikz : TextArea 컴포넌트의 onChange event | ||
| 84 | + //onFinish : Form data를 제출하기 위한 event | ||
| 85 | + | ||
| 86 | + useEffect(()=> { | ||
| 87 | + if(mode==='preview'&&selectItem){ | ||
| 88 | + console.log(selectItem); | ||
| 89 | + | ||
| 90 | + let initFields = [ | ||
| 91 | + {name:['qno'],value:selectItem.qno}, | ||
| 92 | + {name:['typeSol'],value:selectItem.typeSol}, | ||
| 93 | + {name:['typeQue'],value:selectItem.typeQue}, | ||
| 94 | + {name:['creator'],value:selectItem.creator}, | ||
| 95 | + | ||
| 96 | + ]; | ||
| 97 | + setQno(selectItem.qno); | ||
| 98 | + setTikzCode(selectItem.tex); | ||
| 99 | + setFields(initFields); | ||
| 100 | + setSvg(null); | ||
| 101 | + } | ||
| 102 | + },[mode, selectItem]); | ||
| 103 | + | ||
| 104 | + useEffect(()=>{ | ||
| 105 | + if(mode === 'new'){ | ||
| 106 | + let initFields = [ | ||
| 107 | + {name:['qno'],value:null}, | ||
| 108 | + {name:['typeSol'],value:null}, | ||
| 109 | + {name:['typeQue'],value:null}, | ||
| 110 | + {name:['creator'],value:null}, | ||
| 111 | + ]; | ||
| 112 | + setQno(null); | ||
| 113 | + setTikzCode(_tikzcode); | ||
| 114 | + setFields(initFields); | ||
| 115 | + setSvg(null); | ||
| 116 | + } | ||
| 117 | + },[mode]); | ||
| 118 | + | ||
| 119 | + const onClickEvent = (e) => { | ||
| 120 | + if(inputText){ | ||
| 121 | + callbackSVG(inputText); | ||
| 122 | + } | ||
| 123 | + | ||
| 124 | + if (inputText === null) { | ||
| 125 | + console.log(inputText); | ||
| 126 | + alert( | ||
| 127 | + //data에 null이 입력된 경우 | ||
| 128 | + 'Code 값을 입력해주세요!' | ||
| 129 | + ); | ||
| 130 | + } else { | ||
| 131 | + console.log(inputText); | ||
| 132 | + callbackSVG(inputText); | ||
| 133 | + } | ||
| 134 | + }; | ||
| 135 | + const onChangeQno = (value) => { | ||
| 136 | + console.log(value); | ||
| 137 | + setQno(value); | ||
| 138 | + setFields([...fields, {name:['qno'],value:value}]); | ||
| 139 | + }; | ||
| 140 | +/* | ||
| 141 | + useEffect(()=>{ | ||
| 142 | + if(!visible ){ | ||
| 143 | + let initFields = [ | ||
| 144 | + {name:['qno'],value:null}, | ||
| 145 | + {name:['typeSol'],value:null}, | ||
| 146 | + {name:['typeQue'],value:null}, | ||
| 147 | + {name:['creator'],value:null}, | ||
| 148 | + ]; | ||
| 149 | + setQno(null); | ||
| 150 | + setTikzCode(tikzcode); | ||
| 151 | + setFields(initFields); | ||
| 152 | + } | ||
| 153 | + },[visible,mode]); | ||
| 154 | +*/ | ||
| 155 | + const callbackSVG = useCallback(async () => { | ||
| 156 | + const result = await fetchTexToSvg(inputText); | ||
| 157 | + setSvg(result); //api로 받아온 result를 svg state에 저장 | ||
| 158 | + }, [inputText]); | ||
| 159 | + | ||
| 160 | + const onChangeTikz = (e) => { | ||
| 161 | + if (e) { | ||
| 162 | + setinputText(e.target.value); | ||
| 163 | + } else setinputText(null); | ||
| 164 | + }; | ||
| 165 | + | ||
| 166 | + const onSaveEvent = () => { | ||
| 167 | + try { | ||
| 168 | + //서버에 저장이 확인 됐을때 200, 500(오류) http status | ||
| 169 | + const result = alert('전송이 성공적으로 완료됐습니다.'); | ||
| 170 | + } catch (e) { | ||
| 171 | + //서버에 저장 오류가 났을때 | ||
| 172 | + console.log(e); | ||
| 173 | + alert(e); | ||
| 174 | + } | ||
| 175 | + }; | ||
| 176 | + const onClickQno = async(e)=>{ | ||
| 177 | + e.preventDefault(); | ||
| 178 | + //번호가 호출 성공시 setQnoCheck(true); | ||
| 179 | + if(qno){ | ||
| 180 | + const _checkQno= await fetchCheckQno(qno); | ||
| 181 | + setQnoCheck(_checkQno); | ||
| 182 | + } | ||
| 183 | + }; | ||
| 184 | + | ||
| 185 | + | ||
| 186 | + const onFinish = async(values) => { | ||
| 187 | + console.log(values); | ||
| 188 | + console.log(qnoCheck); | ||
| 189 | + if(!qnoCheck){ | ||
| 190 | + message.warning("문제 번호를 확인해 주세요.") | ||
| 191 | + return; | ||
| 192 | + }else{ | ||
| 193 | + const creator = sessionStorage.getItem('id'); | ||
| 194 | + console.log('Received values of form: ', values); | ||
| 195 | + const result = await fetchSaveData({...values, creator}); | ||
| 196 | + console.log(result); | ||
| 197 | + if(result){ | ||
| 198 | + message.info(result.message); | ||
| 199 | + let initFields = [ | ||
| 200 | + {name:['qno'],value:null}, | ||
| 201 | + {name:['typeSol'],value:null}, | ||
| 202 | + {name:['typeQue'],value:null}, | ||
| 203 | + {name:['creator'],value:null}, | ||
| 204 | + ]; | ||
| 205 | + setFields(initFields); | ||
| 206 | + onLeave(); | ||
| 207 | + callback({status:'SAVE_OK'}); | ||
| 208 | + setQno(null); | ||
| 209 | + }else{ | ||
| 210 | + callback({status:'SAVE_FAIL'}) | ||
| 211 | + } | ||
| 212 | + } | ||
| 213 | + }; | ||
| 214 | + | ||
| 215 | + | ||
| 216 | + const onChangeTypeSol = (value) => { | ||
| 217 | + console.log(value); | ||
| 218 | + setFields([...fields, {name:['typeSol'],value:value}]); | ||
| 219 | + } | ||
| 220 | + | ||
| 221 | + const onChangeTypeQue = (value) => { | ||
| 222 | + console.log(value); | ||
| 223 | + setFields([...fields, {name:['typeQue'],value:value}]) | ||
| 224 | + } | ||
| 225 | + | ||
| 226 | + return ( | ||
| 227 | + <Drawer | ||
| 228 | + title={'Tikz Editor'} | ||
| 229 | + placement={'bottom'} | ||
| 230 | + closable={true} | ||
| 231 | + height={'90vh'} | ||
| 232 | + onClose={onLeave} | ||
| 233 | + visible={visible}> | ||
| 234 | + <TikzForm | ||
| 235 | + svg={svg} | ||
| 236 | + onClickEvent={onClickEvent} | ||
| 237 | + onChangeTikz={onChangeTikz} | ||
| 238 | + onSaveEvent={onSaveEvent} | ||
| 239 | + onFinish={onFinish} | ||
| 240 | + tikzcode={tikzcode} | ||
| 241 | + fields={fields} | ||
| 242 | + onClickQno={onClickQno} | ||
| 243 | + onChangeQno={onChangeQno} | ||
| 244 | + onChangeTypeSol={onChangeTypeSol} | ||
| 245 | + onChangeTypeQue={onChangeTypeQue} | ||
| 246 | + qno={qno}> | ||
| 247 | + </TikzForm> | ||
| 248 | + </Drawer> | ||
| 249 | + ); | ||
| 250 | +}; | ||
| 251 | + | ||
| 252 | +export default Tikz; | ||
| 253 | + | ||
| 254 | +//<Transform value={tikzHtml}></Transform> |
minsung/src/component/DropMenu.js
0 → 100644
| 1 | +import React from 'react'; | ||
| 2 | +import { Menu, Dropdown, Button } from 'antd'; | ||
| 3 | +//import Scroll from '../component/Slider'; | ||
| 4 | +// 화살표 함수에서 {} 가 들어가는 경우에는 처리해야 되는 루틴이 있을때 return 값만 있을때는 () or 생략도 가능하다. | ||
| 5 | +// | ||
| 6 | + | ||
| 7 | +//기본적인 도형들을 그리는 도형상수 | ||
| 8 | +const draw = () => ( | ||
| 9 | + <Menu> | ||
| 10 | + <Menu.Item> | ||
| 11 | + <button onclick="">Triangle</button> | ||
| 12 | + </Menu.Item> | ||
| 13 | + <Menu.Item> | ||
| 14 | + <a | ||
| 15 | + target="_blank" | ||
| 16 | + rel="noopener noreferrer" | ||
| 17 | + href="http://www.taobao.com/"> | ||
| 18 | + Rectangle | ||
| 19 | + </a> | ||
| 20 | + </Menu.Item> | ||
| 21 | + <Menu.Item> | ||
| 22 | + <a target="_blank" rel="noopener noreferrer" href="http://www.tmall.com/"> | ||
| 23 | + pentagon | ||
| 24 | + </a> | ||
| 25 | + </Menu.Item> | ||
| 26 | + <Menu.Item danger>도형 디자인</Menu.Item> | ||
| 27 | + </Menu> | ||
| 28 | +); | ||
| 29 | + | ||
| 30 | +//기본적인 그래프를 그리는 그래프 상수 | ||
| 31 | +const graph = () => ( | ||
| 32 | + <Menu> | ||
| 33 | + <Menu.Item> | ||
| 34 | + <a | ||
| 35 | + target="_blank" | ||
| 36 | + rel="noopener noreferrer" | ||
| 37 | + href="http://www.alipay.com/"> | ||
| 38 | + 2차함수 | ||
| 39 | + </a> | ||
| 40 | + </Menu.Item> | ||
| 41 | + <Menu.Item> | ||
| 42 | + <a | ||
| 43 | + target="_blank" | ||
| 44 | + rel="noopener noreferrer" | ||
| 45 | + href="http://www.taobao.com/"> | ||
| 46 | + 3차함수 | ||
| 47 | + </a> | ||
| 48 | + </Menu.Item> | ||
| 49 | + | ||
| 50 | + <Menu.Item danger>함수 디자인</Menu.Item> | ||
| 51 | + </Menu> | ||
| 52 | +); | ||
| 53 | + | ||
| 54 | +// x축 y축을 그리게 만드는 상수 | ||
| 55 | +const grid = () => ( | ||
| 56 | + <Menu> | ||
| 57 | + <Menu.Item> | ||
| 58 | + <a | ||
| 59 | + target="_blank" | ||
| 60 | + rel="noopener noreferrer" | ||
| 61 | + href="http://www.alipay.com/"> | ||
| 62 | + 2차원 | ||
| 63 | + </a> | ||
| 64 | + </Menu.Item> | ||
| 65 | + <Menu.Item> | ||
| 66 | + <a | ||
| 67 | + target="_blank" | ||
| 68 | + rel="noopener noreferrer" | ||
| 69 | + href="http://www.taobao.com/"> | ||
| 70 | + 3차원 | ||
| 71 | + </a> | ||
| 72 | + </Menu.Item> | ||
| 73 | + <Menu.Item> | ||
| 74 | + <a target="_blank" rel="noopener noreferrer" href="http://www.tmall.com/"> | ||
| 75 | + 3rd menu item | ||
| 76 | + </a> | ||
| 77 | + </Menu.Item> | ||
| 78 | + <Menu.Item danger>좌표축 디자인</Menu.Item> | ||
| 79 | + </Menu> | ||
| 80 | +); | ||
| 81 | + | ||
| 82 | +// 수학 공식들을 선택하는 상수 | ||
| 83 | +const MathFunction = () => ( | ||
| 84 | + <Menu> | ||
| 85 | + <Menu.Item> | ||
| 86 | + <a | ||
| 87 | + target="_blank" | ||
| 88 | + rel="noopener noreferrer" | ||
| 89 | + href="http://www.alipay.com/"></a> | ||
| 90 | + </Menu.Item> | ||
| 91 | + <Menu.Item> | ||
| 92 | + <a | ||
| 93 | + target="_blank" | ||
| 94 | + rel="noopener noreferrer" | ||
| 95 | + href="http://www.taobao.com/"> | ||
| 96 | + 2nd menu item | ||
| 97 | + </a> | ||
| 98 | + </Menu.Item> | ||
| 99 | + <Menu.Item> | ||
| 100 | + <a target="_blank" rel="noopener noreferrer" href="http://www.tmall.com/"> | ||
| 101 | + 3rd menu item | ||
| 102 | + </a> | ||
| 103 | + </Menu.Item> | ||
| 104 | + <Menu.Item danger>a danger item</Menu.Item> | ||
| 105 | + </Menu> | ||
| 106 | +); | ||
| 107 | + | ||
| 108 | +//위의 상수 값들을 집어넣어 Dropdowm 메뉴 바들을 구성해준다. | ||
| 109 | +const DropMenu = () => ( | ||
| 110 | + //위의 상수 값들을 집어넣어 Dropdowm 메뉴 바들을 구성해준다. const DropMenu | ||
| 111 | + | ||
| 112 | + <div style={{ display: 'inline-block' }}> | ||
| 113 | + <Dropdown overlay={draw} placement="bottomLeft" arrow> | ||
| 114 | + <Button>Draw</Button> | ||
| 115 | + </Dropdown> | ||
| 116 | + <Button>Graph</Button> | ||
| 117 | + | ||
| 118 | + <Dropdown overlay={grid} placement="bottomRight" arrow> | ||
| 119 | + <Button>Grid</Button> | ||
| 120 | + </Dropdown> | ||
| 121 | + <Dropdown overlay={MathFunction} arrow> | ||
| 122 | + <Button>Function</Button> | ||
| 123 | + </Dropdown> | ||
| 124 | + </div> | ||
| 125 | +); | ||
| 126 | +export default DropMenu; | ||
| 127 | + | ||
| 128 | +//<Scroll> </Scroll> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
minsung/src/component/LoginForm.js
0 → 100644
| 1 | +import React from 'react'; | ||
| 2 | +import { Form, Input, Button, Checkbox, Row, Col } from 'antd'; | ||
| 3 | +import { UserOutlined, LockOutlined } from '@ant-design/icons'; | ||
| 4 | +import {HeartOutlined} from '@ant-design/icons'; | ||
| 5 | + | ||
| 6 | +const LoginForm = ({onFinish},) => { | ||
| 7 | + | ||
| 8 | + return ( | ||
| 9 | + <Form name="normal_login" className="login-form" initialValues={{remember: true, }} onFinish={onFinish}> | ||
| 10 | + <Row justify="center" style={{marginTop:'80px'}}> | ||
| 11 | + <HeartOutlined /> | ||
| 12 | + </Row> | ||
| 13 | + | ||
| 14 | + <Row justify="center" style={{marginTop:'20px'}}> | ||
| 15 | + <Col> | ||
| 16 | + <Form.Item name="userid" rules={[{required: true, message: 'id를 입력해주세요.', },]}> | ||
| 17 | + <Input prefix={<UserOutlined className="site-form-item-icon" />} placeholder="User id" /> | ||
| 18 | + </Form.Item> | ||
| 19 | + </Col> | ||
| 20 | + </Row> | ||
| 21 | + | ||
| 22 | + <Row justify="center" style={{marginTop:'10px'}}> | ||
| 23 | + <Col> | ||
| 24 | + <Form.Item name="userpwd" rules={[{required: true, message: '비밀번호를 입력해주세요.'},]}> | ||
| 25 | + <Input prefix={<LockOutlined className="site-form-item-icon" />} type="password" placeholder="Password"/> | ||
| 26 | + </Form.Item> | ||
| 27 | + </Col> | ||
| 28 | + </Row> | ||
| 29 | + | ||
| 30 | + <Row justify="center" style={{marginTop:'10px'}}> | ||
| 31 | + <Col> | ||
| 32 | + <Form.Item name="remember" valuePropName="checked" noStyle> | ||
| 33 | + <Checkbox>Remember me</Checkbox> | ||
| 34 | + </Form.Item> | ||
| 35 | + </Col> | ||
| 36 | + </Row> | ||
| 37 | + | ||
| 38 | + <Row justify="center" style={{marginTop:'10px'}}> | ||
| 39 | + <Col> | ||
| 40 | + <Form.Item> | ||
| 41 | + <Button type="primary" htmlType="submit" className="login-form-button"> | ||
| 42 | + 로그인하기 | ||
| 43 | + </Button> | ||
| 44 | + </Form.Item> | ||
| 45 | + </Col> | ||
| 46 | + </Row> | ||
| 47 | + | ||
| 48 | + </Form> | ||
| 49 | + ); | ||
| 50 | +} | ||
| 51 | + | ||
| 52 | +export default LoginForm; | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
minsung/src/component/tikzForm.js
0 → 100644
| 1 | +import React,{Flagment} from 'react'; | ||
| 2 | +import { Drawer, Input, Button, Menu, Form, Col, Row, AutoComplete, Tooltip, Select } from 'antd'; | ||
| 3 | +import { UploadOutlined, RetweetOutlined } from '@ant-design/icons'; | ||
| 4 | +import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css'; | ||
| 5 | +import { PanZoom } from 'react-easy-panzoom'; | ||
| 6 | +import { InputNumber } from 'antd'; | ||
| 7 | +import { IFrame } from './iframe'; | ||
| 8 | +import './tikzForm.css'; | ||
| 9 | +const { TextArea } = Input; | ||
| 10 | +const {Option} = Select; | ||
| 11 | + | ||
| 12 | +const TikzForm = ({ svg, onClickEvent, onChangeTikz, onFinish, onChangeQno, onClickQno, tikzcode, fields, qno, onChangeTypeSol,onChangeTypeQue}) => { | ||
| 13 | + //svg | ||
| 14 | + //onclickevent : Tikz 변환하기 Button의 onClick Event | ||
| 15 | + //onChangeTikz : TextArea 컴포넌트의 onChange event | ||
| 16 | + //onFinish : Form data를 제출하기 위한 event | ||
| 17 | + //onSaveEvent : Tikz 등록하기의 버튼 event | ||
| 18 | + | ||
| 19 | +console.log(fields); | ||
| 20 | + | ||
| 21 | + return ( | ||
| 22 | + | ||
| 23 | + <Form onFinish={onFinish} fields={[...fields]}> | ||
| 24 | + | ||
| 25 | +<Form.Item | ||
| 26 | + name="qno" | ||
| 27 | + label="문제 번호" | ||
| 28 | + rules={[ | ||
| 29 | + { | ||
| 30 | + required: true, | ||
| 31 | + message: '문항번호를 입력해 주세요.', | ||
| 32 | + }, | ||
| 33 | + ]}><Row> | ||
| 34 | + <Col> | ||
| 35 | + <InputNumber | ||
| 36 | + min={0} | ||
| 37 | + max={10000} | ||
| 38 | + value={qno} | ||
| 39 | + onChange={onChangeQno}> | ||
| 40 | + </InputNumber> | ||
| 41 | + </Col> | ||
| 42 | + <Col> | ||
| 43 | + <Button onClick={onClickQno}>번호 확인</Button> | ||
| 44 | + </Col> | ||
| 45 | + </Row> | ||
| 46 | + </Form.Item> | ||
| 47 | + | ||
| 48 | + <Form.Item | ||
| 49 | + name="typeSol" | ||
| 50 | + label="문제 타입" | ||
| 51 | + wrapperCol={{span: 2 }} | ||
| 52 | + rules={[ | ||
| 53 | + { | ||
| 54 | + required: true, | ||
| 55 | + message: '문제 타입을 선택해 주세요.', | ||
| 56 | + }, | ||
| 57 | + ]}> | ||
| 58 | + <Select onChange={onChangeTypeSol}> | ||
| 59 | + <Option value="오지선다형">오지선다형</Option> | ||
| 60 | + <Option value="단답형">단답형</Option> | ||
| 61 | + <Option value="계산식">계산식</Option> | ||
| 62 | + </Select> | ||
| 63 | + </Form.Item> | ||
| 64 | + | ||
| 65 | + <Form.Item | ||
| 66 | + name="typeQue" | ||
| 67 | + label="문제/풀이 구분" | ||
| 68 | + rules={[ | ||
| 69 | + { | ||
| 70 | + required: true, | ||
| 71 | + message: '문제/풀이 구분을 선택해 주세요.', | ||
| 72 | + }, | ||
| 73 | + ]} | ||
| 74 | + wrapperCol={{span: 2 }} | ||
| 75 | + > | ||
| 76 | + <Select onChange={onChangeTypeQue}> | ||
| 77 | + <Option value="문제">문제</Option> | ||
| 78 | + <Option value="풀이">풀이</Option> | ||
| 79 | + </Select> | ||
| 80 | + </Form.Item> | ||
| 81 | + | ||
| 82 | + | ||
| 83 | + | ||
| 84 | + <Row justify="space-between" align="middle"> | ||
| 85 | + <Col span={11}> | ||
| 86 | + <Form.Item name="tikzCode" rules={[{ required: true, message: 'tikz 코드를 입력해 주세요.' }]} initialValue={tikzcode}> | ||
| 87 | + <TextArea | ||
| 88 | + style={{ width: '44vw', height: '70vh' }} | ||
| 89 | + onChange={onChangeTikz} | ||
| 90 | + /> | ||
| 91 | + </Form.Item> | ||
| 92 | + </Col> | ||
| 93 | + | ||
| 94 | + <Col span={2} style={{textAlign:'center'}} > | ||
| 95 | + <Tooltip title={'tikz 미리보기'}> | ||
| 96 | + <Button type="ghost" icon={<RetweetOutlined />} onClick={onClickEvent}></Button> | ||
| 97 | + </Tooltip> | ||
| 98 | + </Col> | ||
| 99 | + | ||
| 100 | + <Col span={11} > | ||
| 101 | + <IFrame | ||
| 102 | + style={{ | ||
| 103 | + width: '44vw', | ||
| 104 | + height: '70vh', | ||
| 105 | + marginTop: '-15px', | ||
| 106 | + border: '1px solid #d9d9d9', | ||
| 107 | + }}> | ||
| 108 | + <PanZoom | ||
| 109 | + style={{ | ||
| 110 | + display: 'block', | ||
| 111 | + outline: 'none', | ||
| 112 | + width: '44vw', | ||
| 113 | + height: '70vh', | ||
| 114 | + margin: '0px', | ||
| 115 | + }}> | ||
| 116 | + <div dangerouslySetInnerHTML={{ __html: svg }} /> | ||
| 117 | + </PanZoom> | ||
| 118 | + </IFrame> | ||
| 119 | + </Col> | ||
| 120 | + </Row> | ||
| 121 | + <Form.Item> | ||
| 122 | + <Button type="primary" htmlType="submit"> | ||
| 123 | + 저장하기 | ||
| 124 | + </Button> | ||
| 125 | + </Form.Item> | ||
| 126 | + </Form> | ||
| 127 | + ); | ||
| 128 | +}; | ||
| 129 | + | ||
| 130 | +export default TikzForm; |
minsung/src/component/uploadForm.js
0 → 100644
| 1 | +import { Upload, Button, message } from 'antd'; | ||
| 2 | +import { UploadOutlined } from '@ant-design/icons'; | ||
| 3 | +import reqwest from 'reqwest'; | ||
| 4 | + | ||
| 5 | +class Demo extends React.Component { | ||
| 6 | + state = { | ||
| 7 | + fileList: [], | ||
| 8 | + uploading: false, | ||
| 9 | + }; | ||
| 10 | + | ||
| 11 | + handleUpload = () => { | ||
| 12 | + const { fileList } = this.state; | ||
| 13 | + const formData = new FormData(); | ||
| 14 | + fileList.forEach((file) => { | ||
| 15 | + formData.append('files[]', file); | ||
| 16 | + }); | ||
| 17 | + | ||
| 18 | + this.setState({ | ||
| 19 | + uploading: true, | ||
| 20 | + }); | ||
| 21 | + | ||
| 22 | + // You can use any AJAX library you like | ||
| 23 | + reqwest({ | ||
| 24 | + url: 'https://localhost:5000/user', | ||
| 25 | + method: 'post', | ||
| 26 | + processData: false, | ||
| 27 | + data: formData, | ||
| 28 | + success: () => { | ||
| 29 | + this.setState({ | ||
| 30 | + fileList: [], | ||
| 31 | + uploading: false, | ||
| 32 | + }); | ||
| 33 | + message.success('upload successfully.'); | ||
| 34 | + }, | ||
| 35 | + error: () => { | ||
| 36 | + this.setState({ | ||
| 37 | + uploading: false, | ||
| 38 | + }); | ||
| 39 | + message.error('upload failed.'); | ||
| 40 | + }, | ||
| 41 | + }); | ||
| 42 | + }; | ||
| 43 | + | ||
| 44 | + render() { | ||
| 45 | + const { uploading, fileList } = this.state; | ||
| 46 | + const props = { | ||
| 47 | + onRemove: (file) => { | ||
| 48 | + this.setState((state) => { | ||
| 49 | + const index = state.fileList.indexOf(file); | ||
| 50 | + const newFileList = state.fileList.slice(); | ||
| 51 | + newFileList.splice(index, 1); | ||
| 52 | + return { | ||
| 53 | + fileList: newFileList, | ||
| 54 | + }; | ||
| 55 | + }); | ||
| 56 | + }, | ||
| 57 | + beforeUpload: (file) => { | ||
| 58 | + this.setState((state) => ({ | ||
| 59 | + fileList: [...state.fileList, file], | ||
| 60 | + })); | ||
| 61 | + return false; | ||
| 62 | + }, | ||
| 63 | + fileList, | ||
| 64 | + }; | ||
| 65 | + | ||
| 66 | + return ( | ||
| 67 | + <> | ||
| 68 | + <Upload {...props}> | ||
| 69 | + <Button> | ||
| 70 | + <UploadOutlined /> Select File | ||
| 71 | + </Button> | ||
| 72 | + </Upload> | ||
| 73 | + <Button | ||
| 74 | + type="primary" | ||
| 75 | + onClick={this.handleUpload} | ||
| 76 | + disabled={fileList.length === 0} | ||
| 77 | + loading={uploading} | ||
| 78 | + style={{ marginTop: 16 }}> | ||
| 79 | + {uploading ? 'Uploading' : 'Start Upload'} | ||
| 80 | + </Button> | ||
| 81 | + </> | ||
| 82 | + ); | ||
| 83 | + } | ||
| 84 | +} |
| ... | @@ -2,16 +2,21 @@ import React from 'react'; | ... | @@ -2,16 +2,21 @@ import React from 'react'; |
| 2 | import ReactDOM from 'react-dom'; | 2 | import ReactDOM from 'react-dom'; |
| 3 | import './index.css'; | 3 | import './index.css'; |
| 4 | import App from './App'; | 4 | import App from './App'; |
| 5 | -import reportWebVitals from './reportWebVitals'; | 5 | +import * as serviceWorker from './serviceWorker'; |
| 6 | +import { createBrowserHistory } from 'history'; | ||
| 7 | +import { BrowserRouter,Router } from 'react-router-dom'; | ||
| 6 | 8 | ||
| 9 | +const history = createBrowserHistory(); | ||
| 10 | +//<BrowserRouter history={history}></BrowserRouter> | ||
| 7 | ReactDOM.render( | 11 | ReactDOM.render( |
| 8 | - <React.StrictMode> | 12 | + <BrowserRouter history={history}> |
| 9 | <App /> | 13 | <App /> |
| 10 | - </React.StrictMode>, | 14 | + </BrowserRouter> |
| 15 | + , | ||
| 11 | document.getElementById('root') | 16 | document.getElementById('root') |
| 12 | ); | 17 | ); |
| 13 | 18 | ||
| 14 | -// If you want to start measuring performance in your app, pass a function | 19 | +// If you want your app to work offline and load faster, you can change |
| 15 | -// to log results (for example: reportWebVitals(console.log)) | 20 | +// unregister() to register() below. Note this comes with some pitfalls. |
| 16 | -// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals | 21 | +// Learn more about service workers: https://bit.ly/CRA-PWA |
| 17 | -reportWebVitals(); | 22 | +serviceWorker.unregister(); | ... | ... |
minsung/src/lib/api/checkFiles.js
0 → 100644
| 1 | +import axios from 'axios'; | ||
| 2 | +import qs from 'qs'; | ||
| 3 | +export const checkFiles = (data, whatUpload) => { | ||
| 4 | + const options = { | ||
| 5 | + method: 'POST', | ||
| 6 | + headers: { 'content-type': 'application/x-www-form-urlencoded' }, | ||
| 7 | + data: qs.stringify(data), | ||
| 8 | + url: 'http://localhost:5000/{whatUpload}', | ||
| 9 | + }; | ||
| 10 | + return axios(options); | ||
| 11 | +}; | ||
| 12 | + | ||
| 13 | +//export const tikz = (id) => tikz.post(`/users?id=${id != null ? id : ''}`); | ||
| 14 | +//export const testAdd = (name, tel) => client.post('/users/add', { name, tel }); |
minsung/src/lib/api/client.js
0 → 100644
minsung/src/lib/api/feedback.js
0 → 100644
minsung/src/lib/api/html.js
0 → 100644
| 1 | +import axios from 'axios'; | ||
| 2 | +const hostMath = "http://ai.natmal.com:7070"; | ||
| 3 | + | ||
| 4 | +export const checkQno = (qno) => axios.get(`${hostMath}/checkQno?qno=${qno}`); | ||
| 5 | + | ||
| 6 | +export const saveFileAndQno = (formData) => | ||
| 7 | +{ | ||
| 8 | + return axios({ | ||
| 9 | + method: 'post', | ||
| 10 | + url: '/upload/html', | ||
| 11 | + data: formData, | ||
| 12 | + headers: { | ||
| 13 | + 'Content-Type': 'multipart/form-data', | ||
| 14 | + }, | ||
| 15 | + }); | ||
| 16 | +} | ||
| 17 | + | ||
| 18 | +export const getData = (user, pageSize, currentPage,orderWhat,orderKind) => axios.post('/tikzs',{user, pageSize, currentPage,orderWhat,orderKind}); | ||
| 19 | + |
minsung/src/lib/api/login.js
0 → 100644
| 1 | +import axios from 'axios'; | ||
| 2 | +import qs from 'qs'; | ||
| 3 | +export const getLoginInfo = (data) => | ||
| 4 | +{ | ||
| 5 | + const options = { | ||
| 6 | + method: 'POST', | ||
| 7 | + headers: { 'content-type': 'application/x-www-form-urlencoded' }, | ||
| 8 | + data: qs.stringify(data), | ||
| 9 | + url:'http://ai.natmal.com:7070/checkUser', | ||
| 10 | + }; | ||
| 11 | + return axios(options); | ||
| 12 | + | ||
| 13 | + | ||
| 14 | +} | ||
| 15 | + | ||
| 16 | + | ||
| 17 | +//export const tikz = (id) => tikz.post(`/users?id=${id != null ? id : ''}`); | ||
| 18 | +//export const testAdd = (name, tel) => client.post('/users/add', { name, tel }); |
minsung/src/lib/api/matchInfo.js
0 → 100644
| 1 | +import axios from 'axios'; | ||
| 2 | +import qs from 'qs'; | ||
| 3 | +export const matchInfo = (data) => | ||
| 4 | +{ | ||
| 5 | + const options = { | ||
| 6 | + method: 'GET', | ||
| 7 | + headers: { 'content-type': 'application/x-www-form-urlencoded' }, | ||
| 8 | + data: qs.stringify(data), | ||
| 9 | + url:'http://localhost:5000/users', | ||
| 10 | + }; | ||
| 11 | + return axios(options); | ||
| 12 | + | ||
| 13 | + | ||
| 14 | +} | ||
| 15 | + | ||
| 16 | + | ||
| 17 | +//export const tikz = (id) => tikz.post(`/users?id=${id != null ? id : ''}`); | ||
| 18 | +//export const testAdd = (name, tel) => client.post('/users/add', { name, tel }); |
minsung/src/lib/api/mathCha.js
0 → 100644
| 1 | +import axios from 'axios'; | ||
| 2 | +const hostMath = 'http://ai.natmal.com:7070'; | ||
| 3 | + | ||
| 4 | +export const checkQno = (qno) => axios.get(`${hostMath}/checkQno?qno=${qno}`); | ||
| 5 | +export const saveFileAndQno = (formData) => | ||
| 6 | +{ | ||
| 7 | + console.log(formData); | ||
| 8 | + return axios({ | ||
| 9 | + method: 'post', | ||
| 10 | + url: '/upload/math', | ||
| 11 | + data: formData, | ||
| 12 | + headers: { | ||
| 13 | + 'Content-Type': 'multipart/form-data', | ||
| 14 | + }, | ||
| 15 | + }); | ||
| 16 | +} | ||
| 17 | + | ||
| 18 | +//export const getMathData = (user, pageSize, currentPage,orderWhat) => axios.post('/tikzs',{user, pageSize, currentPage,ordeWhat}); | ||
| 19 | + | ||
| 20 | + |
minsung/src/lib/api/test.js
0 → 100644
| 1 | +import client from './client'; | ||
| 2 | + | ||
| 3 | +export const testFind = (id) => client.get(`/users?id=${id != null ? id : ''}`); | ||
| 4 | +export const testAdd = (name, tel) => client.post('/users/add', { name, tel }); | ||
| 5 | +export const testEdit = (id, name, tel) => | ||
| 6 | + client.post('/users/edit', { id, name, tel }); | ||
| 7 | +export const testDelete = (id) => client.get('/users/delete?id=' + id); |
minsung/src/lib/api/tikz.js
0 → 100644
| 1 | +import axios from 'axios'; | ||
| 2 | +import qs from 'qs'; | ||
| 3 | +export const getTexToSvg = (data) => | ||
| 4 | +{ | ||
| 5 | + const options = { | ||
| 6 | + method: 'POST', | ||
| 7 | + headers: { 'content-type': 'application/x-www-form-urlencoded' }, | ||
| 8 | + data: qs.stringify(data), | ||
| 9 | + url:'http://ai.natmal.com:9292', | ||
| 10 | + }; | ||
| 11 | + return axios(options); | ||
| 12 | + | ||
| 13 | +} | ||
| 14 | + | ||
| 15 | +const hostMath = "http://ai.natmal.com:7070"; | ||
| 16 | + | ||
| 17 | +export const checkQno = (qno) => axios.get(`${hostMath}/checkQno?qno=${qno}`); | ||
| 18 | + | ||
| 19 | +export const saveFileAndQno = (data) => axios.post('/upload/tikz',{...data}); | ||
| 20 | + | ||
| 21 | +export const removeItem = (id) => axios.get(`/tikzs/removeItem?id=${id}`); | ||
| 22 | + | ||
| 23 | +export const removeItems = (ids) => axios.post("/tikzs/removeItems",{ids}); | ||
| 24 | + | ||
| 25 | + | ||
| 26 | +//export const getData = (user, pageSize, currentPage,orderWhat) => axios.post('/tikzs',{user, pageSize, currentPage,ordeWhat}); | ||
| 27 | + | ||
| 28 | + | ||
| 29 | + | ||
| 30 | + | ||
| 31 | +//export const tikz = (id) => tikz.post(`/users?id=${id != null ? id : ''}`); | ||
| 32 | +//export const testAdd = (name, tel) => client.post('/users/add', { name, tel }); |
minsung/src/lib/bluejuicer.png
0 → 100644
47.9 KB
minsung/src/lib/giflogo.gif
0 → 100644
705 KB
minsung/src/lib/graphconsole.png
0 → 100644
51.1 KB
minsung/src/lib/heartgraph.png
0 → 100644
5.76 KB
minsung/src/lib/latexlogo.png
0 → 100644
29.6 KB
minsung/src/lib/mathbank.png
0 → 100644
41.2 KB
minsung/src/lib/newspaper.jpg
0 → 100644
472 KB
minsung/src/lib/orangejuicer.png
0 → 100644
47.8 KB
minsung/src/lib/pngegg.png
0 → 100644
3.62 KB
minsung/src/lib/skybluejuicer.png
0 → 100644
47.5 KB
minsung/src/lib/yellowjuicer.png
0 → 100644
48 KB
-
Please register or login to post a comment