Commit 13004059 authored by Ha YeaJin's avatar Ha YeaJin
Browse files

react bootstrap

parent 4eac88a0
...@@ -12,6 +12,7 @@ const loginRouter = require('./routes/login'); ...@@ -12,6 +12,7 @@ const loginRouter = require('./routes/login');
const reservesRouter = require('./routes/reserves'); const reservesRouter = require('./routes/reserves');
const noticeRouter = require('./routes/notices'); const noticeRouter = require('./routes/notices');
const connect = require('./schemas'); const connect = require('./schemas');
const writesRouter = require('./routes/writes');
const app = express(); const app = express();
connect(); connect();
...@@ -31,6 +32,7 @@ app.use('/users', usersRouter, reservesRouter); ...@@ -31,6 +32,7 @@ app.use('/users', usersRouter, reservesRouter);
app.use('/login', loginRouter); app.use('/login', loginRouter);
app.use('/reserves', reservesRouter); app.use('/reserves', reservesRouter);
app.use('/notices', noticeRouter); app.use('/notices', noticeRouter);
app.use('/writes', writesRouter);
app.listen(port, () => console.log(port)); app.listen(port, () => console.log(port));
......
...@@ -3173,39 +3173,6 @@ ...@@ -3173,39 +3173,6 @@
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz",
"integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==" "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ=="
}, },
"bl": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz",
"integrity": "sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==",
"requires": {
"readable-stream": "^2.3.5",
"safe-buffer": "^5.1.1"
},
"dependencies": {
"readable-stream": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"requires": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
},
"string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"requires": {
"safe-buffer": "~5.1.0"
}
}
}
},
"bluebird": { "bluebird": {
"version": "3.7.2", "version": "3.7.2",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
...@@ -3442,11 +3409,6 @@ ...@@ -3442,11 +3409,6 @@
"node-int64": "^0.4.0" "node-int64": "^0.4.0"
} }
}, },
"bson": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/bson/-/bson-1.1.5.tgz",
"integrity": "sha512-kDuEzldR21lHciPQAIulLs1LZlCXdLziXI6Mb/TDkwXhb//UORJNPXgcRs2CuO4H0DcMkpfT3/ySsP3unoZjBg=="
},
"buffer": { "buffer": {
"version": "4.9.2", "version": "4.9.2",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz",
...@@ -4688,11 +4650,6 @@ ...@@ -4688,11 +4650,6 @@
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o="
}, },
"denque": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/denque/-/denque-1.4.1.tgz",
"integrity": "sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ=="
},
"depd": { "depd": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
...@@ -8191,11 +8148,6 @@ ...@@ -8191,11 +8148,6 @@
"object.assign": "^4.1.0" "object.assign": "^4.1.0"
} }
}, },
"kareem": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.1.tgz",
"integrity": "sha512-l3hLhffs9zqoDe8zjmb/mAN4B8VT3L56EUvKNqLFVs9YlFA+zx7ke1DO8STAdDyYNkeSo1nKmjuvQeI12So8Xw=="
},
"killable": { "killable": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
...@@ -8534,12 +8486,6 @@ ...@@ -8534,12 +8486,6 @@
} }
} }
}, },
"memory-pager": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
"integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==",
"optional": true
},
"merge-deep": { "merge-deep": {
"version": "3.0.2", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/merge-deep/-/merge-deep-3.0.2.tgz", "resolved": "https://registry.npmjs.org/merge-deep/-/merge-deep-3.0.2.tgz",
...@@ -8835,43 +8781,6 @@ ...@@ -8835,43 +8781,6 @@
"run-queue": "^1.0.3" "run-queue": "^1.0.3"
} }
}, },
"mpath": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/mpath/-/mpath-0.7.0.tgz",
"integrity": "sha512-Aiq04hILxhz1L+f7sjGyn7IxYzWm1zLNNXcfhDtx04kZ2Gk7uvFdgZ8ts1cWa/6d0TQmag2yR8zSGZUmp0tFNg=="
},
"mquery": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/mquery/-/mquery-3.2.2.tgz",
"integrity": "sha512-XB52992COp0KP230I3qloVUbkLUxJIu328HBP2t2EsxSFtf4W1HPSOBWOXf1bqxK4Xbb66lfMJ+Bpfd9/yZE1Q==",
"requires": {
"bluebird": "3.5.1",
"debug": "3.1.0",
"regexp-clone": "^1.0.0",
"safe-buffer": "5.1.2",
"sliced": "1.0.1"
},
"dependencies": {
"bluebird": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
"integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA=="
},
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"requires": {
"ms": "2.0.0"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
}
}
},
"ms": { "ms": {
"version": "2.1.2", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
...@@ -11621,11 +11530,6 @@ ...@@ -11621,11 +11530,6 @@
"resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.10.tgz", "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.10.tgz",
"integrity": "sha512-8t6074A68gHfU8Neftl0Le6KTDwfGAj7IyjPIMSfikI2wJUTHDMaIq42bUsfVnj8mhx0R+45rdUXHGpN164avA==" "integrity": "sha512-8t6074A68gHfU8Neftl0Le6KTDwfGAj7IyjPIMSfikI2wJUTHDMaIq42bUsfVnj8mhx0R+45rdUXHGpN164avA=="
}, },
"regexp-clone": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-1.0.0.tgz",
"integrity": "sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw=="
},
"regexp.prototype.flags": { "regexp.prototype.flags": {
"version": "1.3.0", "version": "1.3.0",
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz",
...@@ -11820,27 +11724,6 @@ ...@@ -11820,27 +11724,6 @@
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
}, },
"require_optional": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz",
"integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==",
"requires": {
"resolve-from": "^2.0.0",
"semver": "^5.1.0"
},
"dependencies": {
"resolve-from": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz",
"integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c="
},
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
}
}
},
"requires-port": { "requires-port": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
...@@ -12074,15 +11957,6 @@ ...@@ -12074,15 +11957,6 @@
"resolved": "https://registry.npmjs.org/sanitize.css/-/sanitize.css-10.0.0.tgz", "resolved": "https://registry.npmjs.org/sanitize.css/-/sanitize.css-10.0.0.tgz",
"integrity": "sha512-vTxrZz4dX5W86M6oVWVdOVe72ZiPs41Oi7Z6Km4W5Turyz28mrXSJhhEBZoRtzJWIv3833WKVwLSDWWkEfupMg==" "integrity": "sha512-vTxrZz4dX5W86M6oVWVdOVe72ZiPs41Oi7Z6Km4W5Turyz28mrXSJhhEBZoRtzJWIv3833WKVwLSDWWkEfupMg=="
}, },
"saslprep": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz",
"integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==",
"optional": true,
"requires": {
"sparse-bitfield": "^3.0.3"
}
},
"sass-loader": { "sass-loader": {
"version": "8.0.2", "version": "8.0.2",
"resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-8.0.2.tgz", "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-8.0.2.tgz",
...@@ -12394,11 +12268,6 @@ ...@@ -12394,11 +12268,6 @@
"object-inspect": "^1.8.0" "object-inspect": "^1.8.0"
} }
}, },
"sift": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/sift/-/sift-7.0.1.tgz",
"integrity": "sha512-oqD7PMJ+uO6jV9EQCl0LrRw1OwsiPsiFQR5AR30heR+4Dl7jBBbDLnNvWiak20tzZlSE1H7RB30SX/1j/YYT7g=="
},
"signal-exit": { "signal-exit": {
"version": "3.0.3", "version": "3.0.3",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
...@@ -12446,11 +12315,6 @@ ...@@ -12446,11 +12315,6 @@
} }
} }
}, },
"sliced": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz",
"integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E="
},
"snapdragon": { "snapdragon": {
"version": "0.8.2", "version": "0.8.2",
"resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
...@@ -12648,15 +12512,6 @@ ...@@ -12648,15 +12512,6 @@
"resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
"integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM="
}, },
"sparse-bitfield": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
"integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=",
"optional": true,
"requires": {
"memory-pager": "^1.0.2"
}
},
"spdx-correct": { "spdx-correct": {
"version": "3.1.1", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
......
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { Link, Redirect } from 'react-router-dom'; import { Link, Redirect } from 'react-router-dom';
import styled from 'styled-components'; import styled from 'styled-components';
import { Navbar, Nav, NavDropdown } from 'react-bootstrap';
const Nav = styled.nav` const MENU = styled(Navbar)`
background-color: #7B031D; background-color: #7B031D;
height: 6vh;
a {
color: #ffffff;
}
& .logoutBtn:hover {
text-decoration: underline;
}
` `
function Menu() { function Menu() {
const [state, setState] = useState() const [state, setState] = useState()
const name = localStorage.getItem('name'); const name = localStorage.getItem('name');
if (state) return <Redirect to="/" />;
function logout() { function logout() {
localStorage.clear(); localStorage.clear();
alert("로그아웃 되었습니다."); alert("로그아웃 되었습니다.");
setState(true); setState(true);
} }
if (state) return <Redirect to="/" />
return ( return (
<Nav className="navbar sticky-top navbar-expand-md"> <MENU expand="md" variant="dark">
<a class="navbar-brand" href="#">대관 서비스</a> <Navbar.Brand href="#">대관 서비스</Navbar.Brand>
<button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar" aria-controls="collapsibleNavbar"> <Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="mr-auto">
<Nav.Link><Link to="/notice">공지사항</Link></Nav.Link>
<Nav.Link><Link to="/home">대관 현황</Link></Nav.Link>
<Nav.Link><Link to={{
pathname: `/apply/${localStorage.getItem('_id')}`,
state: { id: localStorage.getItem('_id') },
}} className="nav-link">대관 신청</Link></Nav.Link>
<Nav.Link><Link to={{
pathname: `/check/${localStorage.getItem('_id')}`,
state: { id: localStorage.getItem('_id') },
}} className="nav-link">
대관 확인/취소</Link></Nav.Link>
<Nav.Link><Link to={{
pathname: `/acheck/${localStorage.getItem('_id')}`,
state: { id: localStorage.getItem('_id') },
}} className="nav-link">
대관 확인/취소(관리자)</Link></Nav.Link>
<Nav.Link>
<div className="text-white text-right font-weight-light"><small>{name}</small></div>
<div className="text-white text-right font-weight-light"><small>
<Link to={{
pathname: `/change/${localStorage.getItem('_id')}`,
state: { id: localStorage.getItem('_id') },
}}>비밀번호 변경</Link> / <span className="logoutBtn" onClick={logout} >로그아웃</span></small></div>
</Nav.Link>
</Nav>
</Navbar.Collapse>
{/* <button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar" aria-controls="collapsibleNavbar">
<span className="navbar-toggler-icon"></span> <span className="navbar-toggler-icon"></span>
</button> </button> */}
<div className="collapse navbar-collapse justify-content-between" id="collapsibleNavbar"> {/* <div className="collapse navbar-collapse justify-content-between" id="collapsibleNavbar">
<ul className="navbar-nav"> <ul className="navbar-nav">
<li className="nav-item"> <li className="nav-item">
<Link to="/notice" className="nav-link">공지사항</Link> <Link to="/notice" className="nav-link">공지사항</Link>
...@@ -70,8 +94,8 @@ function Menu() { ...@@ -70,8 +94,8 @@ function Menu() {
state: { id: localStorage.getItem('_id') }, state: { id: localStorage.getItem('_id') },
}}>비밀번호 변경</Link> / <span className="logoutBtn" onClick={logout} >로그아웃</span></small></div> }}>비밀번호 변경</Link> / <span className="logoutBtn" onClick={logout} >로그아웃</span></small></div>
</div> </div>
</div> </div> */}
</Nav> </MENU >
) )
} }
......
...@@ -2,11 +2,21 @@ import React, { useState } from 'react'; ...@@ -2,11 +2,21 @@ import React, { useState } from 'react';
import { Field, Formik } from 'formik'; import { Field, Formik } from 'formik';
import * as Yup from 'yup'; import * as Yup from 'yup';
import axios from 'axios'; import axios from 'axios';
import 'bootstrap/dist/css/bootstrap.css';
import { Link, Redirect } from 'react-router-dom'; import { Link, Redirect } from 'react-router-dom';
import styled from 'styled-components';
import { Container, Row, Col } from 'react-bootstrap';
const Nav = styled.nav`
background-color: #7B031D;
height: 10vh;
a {
color: #ffffff;
}
`
function Find() { function Find() {
const [state, setState] = useState(); const [state, setState] = useState(false);
if (state) { if (state) {
return <Redirect to={{ return <Redirect to={{
...@@ -14,88 +24,96 @@ function Find() { ...@@ -14,88 +24,96 @@ function Find() {
state: { id: localStorage.getItem('_id') }, state: { id: localStorage.getItem('_id') },
}} />; }} />;
} }
return ( return (
<div className="d-flex flex-column justify-content-between vh-100"> <div className="vh-100">
<Formik <Nav className="navbar sticky-top navbar-expand-md">
initialValues={{ id: '', question: '', answer: '' }} <a class="navbar-brand" href="#">비밀번호 찾기</a>
validationSchema={Yup.object({ </Nav>
id: Yup.string() <Container fluid>
.required('학번을 입력해주세요.'), <Row className="justify-content-center rrooww">
answer: Yup.string() <Col md={4} className="d-flex align-items-center h-100">
.required('답변을 입력해주세요.'), <Formik
})} initialValues={{ id: '', question: '', answer: '' }}
onSubmit={(values, { setSubmitting }) => { validationSchema={Yup.object({
axios({ id: Yup.string()
method: 'post', .required('학번을 입력해주세요.'),
url: '/login/find', answer: Yup.string()
data: values, .required('답변을 입력해주세요.'),
}).then(res => { })}
if (res.status === 404) return alert(res.data.error) onSubmit={(values, { setSubmitting }) => {
localStorage.setItem('_id', res.data.users._id) axios({
setState(true); method: 'post',
}) url: '/login/find',
.catch(err => { data: values,
alert(err.error) }).then(res => {
}); if (res.status === 404) return alert(res.data.error)
localStorage.setItem('_id', res.data.users._id)
setState(true);
})
.catch(err => {
alert(err.error)
});
console.log(values); console.log(values);
setTimeout(() => { setTimeout(() => {
setSubmitting(false); setSubmitting(false);
}, 400); // finish the cycle in handler }, 400); // finish the cycle in handler
}} }}
> >
{({ {({
errors, errors,
touched, touched,
handleSubmit, handleSubmit,
getFieldProps, // contain values, handleChange, handleBlur getFieldProps, // contain values, handleChange, handleBlur
isSubmitting, isSubmitting,
}) => ( }) => (
<div className="row justify-content-center align-items-center"> <Row className="justify-content-center align-items-center">
<form onSubmit={handleSubmit} className="col-sm-3"> <form onSubmit={handleSubmit}>
<div className="form-group mb-4"> <Col sm={3}>
<input <div className="form-group mb-4">
className={(touched.id && errors.id ? 'form-control is-invalid' : "form-control")} <input
type="number" className={(touched.id && errors.id ? 'form-control is-invalid' : "form-control")}
name="id" type="number"
{...getFieldProps('id')} name="id"
placeholder="Input Student Id" {...getFieldProps('id')}
/> placeholder="Input Student Id"
{touched.id && errors.id ? ( />
<div className="invalid-feedback text-left">{errors.id}</div> {touched.id && errors.id ? (
) : null} <div className="invalid-feedback text-left">{errors.id}</div>
</div> ) : null}
<div className="form-group mb-4"> </div>
<label>본인 확인 질문</label> <div className="form-group mb-4">
<Field as="select" name="question"> <label>본인 확인 질문</label>
<option value="">질문을 선택하세요</option> <Field as="select" name="question">
<option value="life">자신의 인생 좌우명은?</option> <option value="">질문을 선택하세요</option>
<option value="school">자신이 다녔던 초등학교의 이름은?</option> <option value="life">자신의 인생 좌우명은?</option>
<option value="place">기억에 남는 추억의 장소는?</option> <option value="school">자신이 다녔던 초등학교의 이름은?</option>
</Field> <option value="place">기억에 남는 추억의 장소는?</option>
</div> </Field>
<div className="form-group mb-4"> </div>
<input <div className="form-group mb-4">
className={(touched.answer && errors.answer ? 'form-control is-invalid' : "form-control")} <input
type="text" className={(touched.answer && errors.answer ? 'form-control is-invalid' : "form-control")}
name="answer" type="text"
{...getFieldProps('answer')} name="answer"
placeholder="Input answer" /> {...getFieldProps('answer')}
{touched.answer && errors.answer ? ( placeholder="Input answer" />
<div className="invalid-feedback text-left">{errors.answer}</div> {touched.answer && errors.answer ? (
) : null} <div className="invalid-feedback text-left">{errors.answer}</div>
</div> ) : null}
<button type="submit" className="btn btn-dark" disabled={isSubmitting}> </div>
submit <button type="submit" className="btn btn-dark" disabled={isSubmitting}>submit </button>
</button> <button><Link to="/login">로그인</Link></button>
<button><Link to="/login">로그인</Link></button> <button><Link to="/"></Link></button>
<button><Link to="/"></Link></button> </Col>
</form> </form>
</div> </Row>
)} )}
</Formik> </Formik>
</div> </Col>
</Row>
</Container >
</div >
); );
} }
......
...@@ -37,11 +37,12 @@ const Col_1 = styled.div` ...@@ -37,11 +37,12 @@ const Col_1 = styled.div`
const Col_2 = styled.div` const Col_2 = styled.div`
background-color: rgb(239, 218, 200); background-color: rgb(239, 218, 200);
a { a {
color : #7B031D; color : #7B031D;
} }
&.mob-formik { & .mob-formik {
height : 80vh; height : 80vh;
width: 100%; width: 100%;
display: flex; display: flex;
...@@ -49,14 +50,14 @@ const Col_2 = styled.div` ...@@ -49,14 +50,14 @@ const Col_2 = styled.div`
align-items: center; align-items: center;
} }
&.web-formik { & .web-form {
height: 100%; height: 100%;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
& .mobb { & .mob-container {
height: 35vh; height: 35vh;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
...@@ -67,7 +68,7 @@ const Col_2 = styled.div` ...@@ -67,7 +68,7 @@ const Col_2 = styled.div`
flex-direction: column; flex-direction: column;
} }
& .qwer { & .web-container {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
height: 12vh; height: 12vh;
...@@ -84,7 +85,10 @@ const Col_2 = styled.div` ...@@ -84,7 +85,10 @@ const Col_2 = styled.div`
} }
& .mob-input-form { & .mob-input-form {
display: flex;
flex-direction: column;
justify-content: space-around;
} }
` `
...@@ -105,7 +109,7 @@ function Login() { ...@@ -105,7 +109,7 @@ function Login() {
} }
return ( return (
<Container fluid className="p-0"> <Container fluid className="p-0">
<Row className="vw-100 vh-100 m-0" > <Row className="vw-100 vh-100 m-0 " >
<Col_1 className={"col-md-4 col-12" + (mobile ? " mobile" : " web")}> <Col_1 className={"col-md-4 col-12" + (mobile ? " mobile" : " web")}>
<div className={mobile ? "mob-head" : ""}> <div className={mobile ? "mob-head" : ""}>
<img className={mobile ? "mob-img" : "img-fluid"} src={Logo} /> <img className={mobile ? "mob-img" : "img-fluid"} src={Logo} />
...@@ -114,7 +118,7 @@ function Login() { ...@@ -114,7 +118,7 @@ function Login() {
</div> </div>
</div> </div>
</Col_1> </Col_1>
<Col_2 className={"col-md-8 col-12" + (mobile ? " mob-formik p-0" : " web-formik")}> <Col_2 className="col-md-8 col-12" >
<Formik <Formik
initialValues={{ id: '', password: '' }} initialValues={{ id: '', password: '' }}
validationSchema={Yup.object({ validationSchema={Yup.object({
...@@ -153,35 +157,37 @@ function Login() { ...@@ -153,35 +157,37 @@ function Login() {
getFieldProps, // contain values, handleChange, handleBlur getFieldProps, // contain values, handleChange, handleBlur
isSubmitting, isSubmitting,
}) => ( }) => (
<form onSubmit={handleSubmit} className={mobile ? "w-75 h-50vh" : "d-flex webb"}> <div className={mobile ? " mob-formik p-0" : " web-form"}>
<div className={mobile ? "mobb" : "qwer"}> <form onSubmit={handleSubmit} className={mobile ? "w-75 h-50vh" : "d-flex webb"}>
<div className={(mobile ? "mob-" : "web-") + "input-form"}> <div className={mobile ? "mob-container" : "web-container"}>
<div className={"form-group m-0" + (mobile ? " mb-2" : "")}> <div className={mobile ? "mob-input-form h-100" : "web-input-form"}>
<input <div className={"form-group m-0" + (mobile ? " mb-2" : "")}>
className={(touched.id && errors.id ? 'form-control is-invalid' : "form-control")} <input
type="number" className={(touched.id && errors.id ? 'form-control is-invalid' : "form-control")}
name="id" type="number"
{...getFieldProps('id')} name="id"
placeholder="Input Student Id" {...getFieldProps('id')}
/> placeholder="Input Student Id"
</div> />
<div className="form-group m-0"> </div>
<input <div className="form-group h-80 m-0">
className={(touched.password && errors.password ? 'form-control is-invalid' : "form-control")} <input
type="password" className={(touched.password && errors.password ? 'form-control is-invalid' : "form-control")}
name="password" type="password"
{...getFieldProps('password')} name="password"
placeholder="Input Password" {...getFieldProps('password')}
/> placeholder="Input Password"
/>
</div>
</div> </div>
<button type="submit" className={"btn btn-dark" + (mobile ? " w-100" : " w-20")} disabled={isSubmitting}> Login </button>
</div> </div>
<button type="submit" className={"btn btn-dark" + (mobile ? " w-100" : " w-20")} disabled={isSubmitting}> Login </button>
</div>
<div><Link to="/find">비밀번호를 잊으셨나요?</Link></div> <div><Link to="/find">비밀번호를 잊으셨나요?</Link></div>
<div><Link to="/signup">회원이 아니신가요?</Link></div> <div><Link to="/signup">회원이 아니신가요?</Link></div>
</form> </form>
</div>
)} )}
</Formik> </Formik>
</Col_2> </Col_2>
......
import React, { useState, useEffect, useRef } from 'react'; import React, { useState, useEffect, useRef } from 'react';
import Menu from '../Components/Menu'; import Menu from '../Components/Menu';
import axios from 'axios'; import axios from 'axios';
import styled from 'styled-components'; import { Link } from 'react-router-dom';
import { Container, Row, Col, Card, Accordion, Button } from 'react-bootstrap';
function Notice() { function Notice() {
const [notices, setNotices] = useState([]); const [notices, setNotices] = useState([]);
...@@ -29,7 +30,6 @@ function Notice() { ...@@ -29,7 +30,6 @@ function Notice() {
if (res.status !== 201) { if (res.status !== 201) {
alert(res.data.error); alert(res.data.error);
} }
console.log(res.data);
setNotices(res.data); setNotices(res.data);
}) })
.catch(err => { .catch(err => {
...@@ -39,47 +39,24 @@ function Notice() { ...@@ -39,47 +39,24 @@ function Notice() {
return ( return (
<div> <div>
<Menu /> <Menu />
<div className="container-fluid"> <Container fluid>
<div className="row justify-content-center vw-100 vh-90"> <Row className="justify-content-center vw-100 vh-90">
<div className="col-md-7 col-12"> <Col md={7}>
<h2 className="p-3 border-bottom">공지사항 <Link to="/write"> 작성</Link></h2>
<h2 className="p-3 border-bottom">공지사항</h2> <Accordion>
{notices.map((notice, index) =>
<div id="accordion pt-1"> <Card>
<div class="card"> <Card.Header>
<div class="card-header" id="headingOne"> <Accordion.Toggle as={Button} variant="link" eventKey={index + 1}>{notice.notice_title} <span className="text-right">{dateForm(notice.post_date)}</span></Accordion.Toggle>
<h5 class="mb-0"> </Card.Header>
<button class="btn btn-link" data-toggle="collapse" data-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne"> <Accordion.Collapse eventKey={index + 1}>
Collapsible Group Item #1 <Card.Body>{notice.notice_content}</Card.Body>
</button> </Accordion.Collapse>
</h5> </Card>)}
</div> </Accordion>
</Col>
<div id="collapseOne" class="collapse show" aria-labelledby="headingOne" data-parent="#accordion"> </Row>
<div class="card-body"> </Container>
Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS.
</div>
</div>
</div>
{/* {notices.map((notice, index) =>
<div className="card">
<div className="card-header" id={"Hnotice_" + index}>
<div className="row card-link collapsed" data-toggle="collapse" data-target={"#notice_" + index} aria-expanded="false" aria-controls={"notice_" + index}>
<div className="col-6 p-0">{notice.notice_title}</div>
<div className="col-3 p-0 text-center">{notice.notice_author}</div>
<div className="col-3 p-0 text-right">{dateForm(notice.post_date)}</div>
</div>
</div>
<div id={"notice_" + index} aria-labelledby={"Hnotice_" + index} className="collapse" data-parent="#accordion">
<div className="card-body">{notice.notice_content}</div>
</div>
</div>
)} */}
</div>
</div>
</div >
</div >
</div> </div>
) )
} }
......
...@@ -2,7 +2,6 @@ import React, { useState } from 'react'; ...@@ -2,7 +2,6 @@ import React, { useState } from 'react';
import { Field, Formik } from 'formik'; import { Field, Formik } from 'formik';
import * as Yup from 'yup'; import * as Yup from 'yup';
import axios from 'axios'; import axios from 'axios';
import 'bootstrap/dist/css/bootstrap.css';
import { Link, Redirect } from 'react-router-dom'; import { Link, Redirect } from 'react-router-dom';
import styled from 'styled-components'; import styled from 'styled-components';
...@@ -40,7 +39,6 @@ function Signup() { ...@@ -40,7 +39,6 @@ function Signup() {
if (state) { if (state) {
return <Redirect to="/login" />; return <Redirect to="/login" />;
} }
return ( return (
<div className="vh-100"> <div className="vh-100">
<Nav className="navbar sticky-top navbar-expand-md"> <Nav className="navbar sticky-top navbar-expand-md">
...@@ -171,8 +169,7 @@ function Signup() { ...@@ -171,8 +169,7 @@ function Signup() {
placeholder="Input answer" /> placeholder="Input answer" />
</div> </div>
<button type="submit" className="btn btn-dark" disabled={isSubmitting}>회원가입</button> <button type="submit" className="btn btn-dark" disabled={isSubmitting}>회원가입</button>
<button class="btn btn-light"><Link to="/login">로그인</Link></button> <button class="btn btn-light"><Link to="/login">로그인하러 가기</Link></button>
<button class="btn btn-light"><Link to="/"></Link></button>
</form> </form>
)} )}
</Formik> </Formik>
......
import React, { useState, useEffect } from 'react';
import { Link, Redirect } from 'react-router-dom';
import Menu from '../Components/Menu';
import * as Yup from 'yup';
import axios from 'axios';
import { Container, Row, Col } from 'react-bootstrap';
import { Field, Formik } from 'formik';
function Write() {
const [submitData, setSubmitData] = useState(false);
const [state, setState] = useState(false);
if (state) {
return <Redirect to="/notice" />;
}
return (
<div>
<Menu />
<Container fluid>
<Row className="justify-content-center">
<Col md={12} xl={8} style={{ height: "35em" }}>
<Formik
initialValues={{ title: '', content: '' }}
validationSchema={Yup.object({
title: Yup.string()
.required('제목을 입력해주세요.'),
content: Yup.string()
.required('내용을 입력해주세요.'),
})}
onSubmit={(values, { setSubmitting }) => {
axios({
method: 'post',
url: '/writes',
data: values,
}).then(res => {
if (res.status === 404) return alert(res.data.error)
alert("공지 등록이 완료되었습니다.")
setState(true);
})
.catch(err => {
alert(err.error)
});
setTimeout(() => {
setSubmitting(false);
}, 400); // finish the cycle in handler
}}
>{({
errors,
touched,
handleSubmit,
getFieldProps, // contain values, handleChange, handleBlur
isSubmitting,
}) => (
<form onSubmit={handleSubmit} className="asd">
{/* col-sm-3 */}
<div className="form-group">
{/* mb-4 */}
<div className={touched.name && errors.name ? "text-danger" : ""}>제목</div>
<input className={(touched.name && errors.name ? 'form-control is-invalid' : "form-control")}
type="text"
title="title"
{...getFieldProps('title')}
placeholder="제목" />
</div>
<div className="form-group ">
{/* mb-4 */}
<div className={touched.name && errors.name ? "text-danger" : ""}>내용</div>
<input className={(touched.name && errors.name ? 'form-control is-invalid' : "form-control")}
type="text"
content="content"
{...getFieldProps('content')}
placeholder="내용" />
</div>
<button type="submit" className="btn btn-dark" disabled={isSubmitting}>공지 등록</button>
</form>
)}
</Formik>
</Col>
</Row>
</Container>
</div>
)
}
export default Write
...@@ -16,13 +16,14 @@ import Apply from './Pages/ApplyPage'; ...@@ -16,13 +16,14 @@ import Apply from './Pages/ApplyPage';
import Check from './Pages/CheckPage'; import Check from './Pages/CheckPage';
import Notice from './Pages/NoticePage'; import Notice from './Pages/NoticePage';
import ACheck from './Pages/ACheckPage'; import ACheck from './Pages/ACheckPage';
import Write from './Pages/WritePage';
axios.defaults.validateStatus = function (status) { axios.defaults.validateStatus = function (status) {
return status < 500; // default return status < 500; // default
} }
ReactDOM.render( ReactDOM.render(
<Router> <Router>
<Switch> <Switch>
<PrivateRoute exact path="/" component={Home} /> <PrivateRoute exact path="/" component={Home} />
<Route path="/login" component={Login} /> <Route path="/login" component={Login} />
...@@ -32,11 +33,12 @@ ReactDOM.render( ...@@ -32,11 +33,12 @@ ReactDOM.render(
<Route path="/change" component={Change} /> <Route path="/change" component={Change} />
<Route path="/apply/:id" component={Apply} /> <Route path="/apply/:id" component={Apply} />
<Route path="/check/:id" component={Check} /> <Route path="/check/:id" component={Check} />
<Route path="/write" component={Write} />
<Route path="/notice" component={Notice} /> <Route path="/notice" component={Notice} />
<Route path="/acheck/:id" component={ACheck} /> <Route path="/acheck/:id" component={ACheck} />
<Redirect path="/" to="/" />
<Redirect path="/home" to="/" /> <Redirect path="/home" to="/" />
<Redirect path="/change/:id" to="/change"/> <Redirect path="/change/:id" to="/change" />
<Redirect path="/notice" to="/notice" />
</Switch> </Switch>
</Router>, </Router>,
document.getElementById('root') document.getElementById('root')
......
const express = require('express');
// const path = require('path');
// const multer = require('multer');
// const fs = require('fs');
const Notice = require('../schemas/notice');
const router = express.Router();
router.post('/', function (req, res, next) {
console.log("writes req.body", req.body)
const notice = new Notice({
notice_title: req.body.title,
notice_author: "예진",
notice_content: req.body.content
});
console.log(notice);
notice.save()
.then((result) => {
console.log(result);
res.status(201).json(result);
})
.catch((err) => {
console.error(err);
next(err);
});
});
module.exports = router;
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment