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