Showing
3 changed files
with
295 additions
and
19 deletions
| 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'; | ||
| 6 | + | ||
| 7 | + | ||
| 8 | +const authentication = () => {} | ||
| 9 | + | ||
| 3 | 10 | ||
| 4 | function App() { | 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); | ... | ... |
minsung/src/Container/Html.js
0 → 100644
| 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; |
-
Please register or login to post a comment