MinsoftK

기초파일 생성

1 -import logo from './logo.svg'; 1 +import React,{useState, useEffect} from 'react';
2 -import './App.css'; 2 +import { Route, Redirect, withRouter, Switch} from 'react-router-dom';
3 +import { Home, Html, Mathcha, Tikz, Login} from './Container';
4 +import {isauth} from './Container/Login';
5 +//import {ConnectedRouter} from 'connected-react-router';
3 6
4 -function App() { 7 +
8 +const authentication = () => {}
9 +
10 +
11 +function App() {
5 return ( 12 return (
6 - <div className="App"> 13 + <div>
7 - <header className="App-header"> 14 + <Switch>
8 - <img src={logo} className="App-logo" alt="logo" /> 15 + <Route exact path="/" component={Login}/>
9 - <p> 16 + <Route path="/Home" component={Home}/>
10 - Edit <code>src/App.js</code> and save to reload. 17 + </Switch>
11 - </p>
12 - <a
13 - className="App-link"
14 - href="https://reactjs.org"
15 - target="_blank"
16 - rel="noopener noreferrer"
17 - >
18 - Learn React
19 - </a>
20 - </header>
21 </div> 18 </div>
22 ); 19 );
23 } 20 }
24 - 21 +//history를 쓰는 경우는 Link
25 -export default App; 22 +export default withRouter(App);
......
1 +import React, { useState, useEffect } from 'react';
2 +import { Modal, Upload, message, Form, InputNumber, Button , Select ,Row, Col} from 'antd';
3 +import { InboxOutlined, LockOutlined, SaveTwoTone } from '@ant-design/icons';
4 +import { saveFileAndQno } from 'lib/api/html';
5 +import { checkQno } from '../lib/api/html';
6 +
7 +const { Option} = Select;
8 +//파일 업로드
9 +//업로드 폼에서의 로직
10 +
11 +const fetchSaveData = async (data) => {
12 + try{
13 + console.log(data);
14 + const result = await saveFileAndQno(data);
15 + if(result.status===200){
16 + return result.data;
17 + }
18 + }catch(e){
19 + console.log(e);
20 + message.warn(e.message);
21 + }
22 +}
23 +
24 +const fetchCheckQno = async(qno) => {
25 + try{
26 + const result = await checkQno(qno);
27 + if(result.status===200){
28 + console.log(result);
29 + message.info("사용 가능한 문항 번호 입니다.");
30 + return true;
31 + }else{
32 + message.info("존재 하지 않는 문항 번호 입니다.");
33 + return false;
34 + }
35 + }catch(e){
36 + console.log(e);
37 + message.info("존재 하지 않는 문항 번호 입니다.");
38 + return false;
39 + }
40 +}
41 +
42 +const Html = ({ visible, onCancel, callback }) => {
43 + const [fields,setFields] =useState([]);
44 + const [qno, setQno] = useState(null);
45 + const [upload,setUpload]=useState(false);
46 + const [fileList, setFileList]=useState([]);
47 + const [qnoCheck,setQnoCheck] =useState(false);
48 +
49 +
50 + const changeNumber = (value) => {
51 + setQno(value);
52 + setFields([...fields, {name:['qno'],value:value}]);
53 + };
54 +
55 +
56 + useEffect(()=>{
57 + if(!visible){
58 + let initFields = [
59 + {name:['qno'],value:null},
60 + {name:['typeSol'],value:null},
61 + {name:['typeQue'],value:null},
62 + {name:['creator'],value:null},
63 + ];
64 + setQno(null);
65 + setFields(initFields);
66 + setFileList([]);
67 + }
68 + },[visible]);
69 +
70 + const props = {
71 + multiple:false,
72 + //data: { qno: qno },
73 + accept:'.html',
74 + onRemove: file => {
75 + const index = fileList.indexOf(file);
76 + const newFileList = fileList.slice();
77 + newFileList.splice(index, 1);
78 + return {
79 + fileList: newFileList,
80 + };
81 + },
82 +
83 + beforeUpload: file => {
84 + console.log(file);
85 + if(file.name.indexOf('.html')>0)
86 + {
87 + setFileList([file]);
88 + }else {
89 + setFileList([]);
90 + message.info("Html 형식의 파일이 아닙니다.");
91 + }
92 + return false;
93 +
94 + },
95 + };
96 +
97 + const onOk = () => {
98 + setUpload(true)
99 + };
100 +
101 +
102 + const normFile = e => {
103 + console.log('Upload event:', e);
104 + if (Array.isArray(e)) {
105 + return e;
106 + }
107 + return e && e.fileList;
108 + };
109 +
110 + const onClickQno = async(e)=>{
111 + e.preventDefault();
112 + //번호가 호출 성공시 setQnoCheck(true);
113 + if(qno){
114 + const _checkQno= await fetchCheckQno(qno);
115 + setQnoCheck(_checkQno);
116 + }
117 + };
118 +
119 + const onFinish = async values => {
120 + console.log(qnoCheck);
121 + if(!qnoCheck){
122 + message.warning("문제 번호를 확인해 주세요.")
123 + return;
124 + }else{
125 + const creator = sessionStorage.getItem('id');
126 + console.log('Received values of form: ', values);
127 + const formData = new FormData();
128 + formData.append('qno', values.qno);
129 + formData.append('typeSol', values.typeSol);
130 + formData.append('typeQue', values.typeQue);
131 + formData.append('html', values.html[0]);
132 + formData.append('creator', creator);
133 +
134 + const result = await fetchSaveData(formData);
135 + console.log(result);
136 + if(result){
137 + message.info(result.message);
138 + let initFields = [
139 + {name:['qno'],value:null},
140 + {name:['typeSol'],value:null},
141 + {name:['typeQue'],value:null},
142 + {name:['creator'],value:null},
143 + ];
144 + setQno(null);
145 + setFields(initFields);
146 + setFileList([]);
147 + onCancel();
148 + callback({status:'SAVE_OK'});
149 + }else{
150 + callback({status:'SAVE_FAIL'})
151 + }
152 + }
153 + };
154 +
155 + const onChangeTypeSol = (value) => {
156 + console.log(value);
157 + setFields([...fields, {name:['typeSol'],value:value}]);
158 + }
159 +
160 + const onChangeTypeQue = (value) => {
161 + console.log(value);
162 + setFields([...fields, {name:['typeQue'],value:value}])
163 + }
164 +
165 +
166 +
167 + const formItemLayout = {
168 + labelCol: { span: 6 },
169 + wrapperCol: { span: 14 },
170 + };
171 +
172 + return (
173 + <Modal
174 + placement={'bottom'}
175 + closable={true}
176 + height={'75%'}
177 + visible={visible}
178 + okText={'저장'}
179 + cancelText={'이전'}
180 + onCancel={onCancel}
181 + footer={null}
182 + >
183 + <Form name="validate_other"
184 + {...formItemLayout}
185 + onFinish={onFinish}
186 + fields={[{name:['html'],value:fileList},...fields]}
187 + >
188 + <Form.Item
189 + name="qno"
190 + label="문제 번호"
191 + rules={[
192 + {
193 + required: true,
194 + message: '저장할 html의 문항번호를 입력해 주세요.',
195 + },
196 + ]}>
197 + <Row>
198 + <Col>
199 + <InputNumber
200 + min={0}
201 + max={10000}
202 + value={qno}
203 + onChange={changeNumber}>
204 + </InputNumber>
205 + </Col>
206 + <Col>
207 + <Button onClick={onClickQno}>번호 확인</Button>
208 + </Col>
209 + </Row>
210 + </Form.Item>
211 + <Form.Item
212 + name="typeSol"
213 + label="문제 타입"
214 + rules={[
215 + {
216 + required: true,
217 + message: '저장할 html의 문제 타입을 선택해 주세요.',
218 + },
219 + ]}>
220 + <Select onChange={onChangeTypeSol}>
221 + <Option value="오지선다형">오지선다형</Option>
222 + <Option value="단답형">단답형</Option>
223 + <Option value="계산식">계산식</Option>
224 + </Select>
225 + </Form.Item>
226 + <Form.Item
227 + name="typeQue"
228 + label="문제/풀이 구분"
229 + rules={[
230 + {
231 + required: true,
232 + message: '저장할 html의 문제/풀이 구분을 선택해 주세요.',
233 + },
234 + ]}>
235 + <Select onChange={onChangeTypeQue}>
236 + <Option value="문제">문제</Option>
237 + <Option value="풀이">풀이</Option>
238 + </Select>
239 + </Form.Item>
240 + <Form.Item label="파일 업로드">
241 + <Form.Item
242 + name="html"
243 + valuePropName="fileList"
244 + getValueFromEvent={normFile}
245 +
246 + noStyle
247 + rules={[
248 + {
249 + required: true,
250 + message: '파일을 드래그하거나 선택해 주세요.',
251 + },
252 + ]}>
253 + <Upload.Dragger name="files" {...props} >
254 + <p className="ant-upload-drag-icon">
255 + <InboxOutlined />
256 + </p>
257 + <p className="ant-upload-text">Click or drag file to this area to upload</p>
258 + <p className="ant-upload-hint">Support for a single or bulk upload.</p>
259 + </Upload.Dragger>
260 + </Form.Item>
261 + </Form.Item>
262 +
263 + <Form.Item style={{alignContent:'middle'}} wrapperCol={{ span: 12, offset: 6 }}>
264 + <Button type="primary" htmlType="submit">
265 + 저장
266 + </Button>
267 + </Form.Item>
268 + </Form>
269 +
270 + </Modal>
271 + );
272 +};
273 +
274 +export default Html;
1 +export { default as Home } from './Home';
2 +export { default as Html } from './Html';
3 +export { default as Mathcha } from './Mathcha';
4 +export { default as Tikz } from './Tikz';
5 +export { default as Login} from './Login';