Commit 32dcbf22 authored by Ha YeaJin's avatar Ha YeaJin
Browse files

pages

parent 2a21eaec
......@@ -9,6 +9,9 @@ var usersRouter = require('./routes/users');
var app = express();
const port = 3030;
app.listen(port, () => console.log(port));
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
......
......@@ -2545,6 +2545,14 @@
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.1.tgz",
"integrity": "sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA=="
},
"axios": {
"version": "0.20.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.20.0.tgz",
"integrity": "sha512-ANA4rr2BDcmmAQLOKft2fufrtuvlqR+cXNNinUmvfeSNCOF98PZL+7M/v1zIdGo7OLjEA9J2gXJL+j4zGsl0bA==",
"requires": {
"follow-redirects": "^1.10.0"
}
},
"axobject-query": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz",
......@@ -4399,6 +4407,11 @@
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
"integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ="
},
"deepmerge": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz",
"integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA=="
},
"default-gateway": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz",
......@@ -5965,6 +5978,11 @@
}
}
},
"fn-name": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/fn-name/-/fn-name-3.0.0.tgz",
"integrity": "sha512-eNMNr5exLoavuAMhIUVsOKF79SWd/zG104ef6sxBTSw+cZc6BXdQXDvYcGvp0VbxVVSp1XDUNoz7mg1xMtSznA=="
},
"follow-redirects": {
"version": "1.13.0",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz",
......@@ -6020,6 +6038,32 @@
"mime-types": "^2.1.12"
}
},
"formik": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/formik/-/formik-2.1.5.tgz",
"integrity": "sha512-bWpo3PiqVDYslvrRjTq0Isrm0mFXHiO33D8MS6t6dWcqSFGeYF52nlpCM2xwOJ6tRVRznDkL+zz/iHPL4LDuvQ==",
"requires": {
"deepmerge": "^2.1.1",
"hoist-non-react-statics": "^3.3.0",
"lodash": "^4.17.14",
"lodash-es": "^4.17.14",
"react-fast-compare": "^2.0.1",
"scheduler": "^0.18.0",
"tiny-warning": "^1.0.2",
"tslib": "^1.10.0"
},
"dependencies": {
"scheduler": {
"version": "0.18.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.18.0.tgz",
"integrity": "sha512-agTSHR1Nbfi6ulI0kYNK0203joW2Y5W4po4l+v03tOoiJKpTBbxpNhWDvqc/4IcOw+KLmSiQLTasZ4cab2/UWQ==",
"requires": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1"
}
}
}
},
"forwarded": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
......@@ -8055,6 +8099,11 @@
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
},
"lodash-es": {
"version": "4.17.15",
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.15.tgz",
"integrity": "sha512-rlrc3yU3+JNOpZ9zj5pQtxnx2THmvRykwL4Xlxoa8I9lHBlVbbyPhgyPMioxVZ4NqyxaVVtaJnzsyOidQIhyyQ=="
},
"lodash._reinterpolate": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz",
......@@ -10415,6 +10464,11 @@
"react-is": "^16.8.1"
}
},
"property-expr": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.4.tgz",
"integrity": "sha512-sFPkHQjVKheDNnPvotjQmm3KD3uk1fWKUN7CrpdbwmUx3CrG3QiM8QpTSimvig5vTXmTvjz7+TDvXOI9+4rkcg=="
},
"proxy-addr": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
......@@ -10811,6 +10865,11 @@
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.7.tgz",
"integrity": "sha512-TAv1KJFh3RhqxNvhzxj6LeT5NWklP6rDr2a0jaTfsZ5wSZWHOGeqQyejUp3xxLfPt2UpyJEcVQB/zyPcmonNFA=="
},
"react-fast-compare": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz",
"integrity": "sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw=="
},
"react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
......@@ -12536,6 +12595,11 @@
"resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
"integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw=="
},
"synchronous-promise": {
"version": "2.0.13",
"resolved": "https://registry.npmjs.org/synchronous-promise/-/synchronous-promise-2.0.13.tgz",
"integrity": "sha512-R9N6uDkVsghHePKh1TEqbnLddO2IY25OcsksyFp/qBe7XYd0PVbKEWxhcdMhpLzE1I6skj5l4aEZ3CRxcbArlA=="
},
"table": {
"version": "5.4.6",
"resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz",
......@@ -12835,6 +12899,11 @@
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
"integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
},
"toposort": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz",
"integrity": "sha1-riF2gXXRVZ1IvvNUILL0li8JwzA="
},
"tough-cookie": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
......@@ -14100,6 +14169,20 @@
"camelcase": "^5.0.0",
"decamelize": "^1.2.0"
}
},
"yup": {
"version": "0.29.3",
"resolved": "https://registry.npmjs.org/yup/-/yup-0.29.3.tgz",
"integrity": "sha512-RNUGiZ/sQ37CkhzKFoedkeMfJM0vNQyaz+wRZJzxdKE7VfDeVKH8bb4rr7XhRLbHJz5hSjoDNwMEIaKhuMZ8gQ==",
"requires": {
"@babel/runtime": "^7.10.5",
"fn-name": "~3.0.0",
"lodash": "^4.17.15",
"lodash-es": "^4.17.11",
"property-expr": "^2.0.2",
"synchronous-promise": "^2.0.13",
"toposort": "^2.0.2"
}
}
}
}
......@@ -6,12 +6,15 @@
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.5.0",
"@testing-library/user-event": "^7.2.1",
"axios": "^0.20.0",
"bootstrap": "^4.5.2",
"formik": "^2.1.5",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-router-dom": "^5.2.0",
"react-scripts": "3.4.3",
"styled-components": "^5.2.0"
"styled-components": "^5.2.0",
"yup": "^0.29.3"
},
"scripts": {
"start": "react-scripts start",
......@@ -19,6 +22,7 @@
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"proxy": "http://localhost:3030",
"eslintConfig": {
"extends": "react-app"
},
......
import React, { useState, useEffect } from 'react';
import { Link } from 'react-router-dom';
import styled from 'styled-components';
const Nav = styled.nav`
background-color: #981e1e;
`
function Menu() {
return (
<Nav className="navbar sticky-top navbar-expand-md">
<Link to="/home" className="navbar-brand">대관 서비스</Link>
<button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar" aria-controls="collapsibleNavbar">
<span className="navbar-toggler-icon"></span>
</button>
<div className="collapse navbar-collapse" id="collapsibleNavbar">
<ul className="navbar-nav">
<li className="nav-item">
<Link to="/home" className="nav-link">대관 현황</Link>
</li>
<li className="nav-item">
<Link to="/apply" className="nav-link">대관 신청</Link>
</li>
<li className="nav-item">
<Link to="/check" className="nav-link">대관 확인/취소</Link>
</li>
<li className="nav-item">
<Link to="/notice" className="nav-link">공지사항</Link>
</li>
</ul>
</div>
</Nav>
)
}
export default Menu
\ No newline at end of file
import React, { useState, useEffect } from 'react';
import Menu from '../Components/Menu';
function Apply() {
return (
<div>
<Menu />
<div className="container">apply
</div>
</div>
)
}
export default Apply
\ No newline at end of file
import React, { useState, useEffect } from 'react';
import Menu from '../Components/Menu';
function Check() {
return (
<div>
<Menu />
<div className="container">check
</div>
</div>
)
}
export default Check
\ No newline at end of file
import React, { } from 'react';
function Home() {
return (
<div>
<h2>asdkj;alsdkj</h2>
</div>
)
}
export default Home
\ No newline at end of file
import React, { useState, useEffect } from 'react';
import Menu from '../Components/Menu';
function Home() {
return (
<div>
<Menu />
<div className="container">
home
</div>
</div>
)
}
export default Home
\ No newline at end of file
import React, { } from 'react';
import styled from 'styled-components';
import { Link } from 'react-router-dom';
const Log = styled.div`
background-color: #981e1e;
`
const Logo = styled.div`
background-color: #E76A6A;
`
function Login() {
return (
<div className="container">
<div className="row">
<Logo className="col-md-5 col-12">
<h2>고려대학교</h2>
<h4>대관 시스템</h4>
</Logo>
<Log className="col-md-7 col-12">
<form encType='multipart/form-data' className="mt-4" style={{ height: "100%" }}>
<div className="form-group">
<label for="title_input">학번</label>
<input className="form-control" id="title_input" name="title" type="text" required />
</div>
<div className="form-group">
<label for="author_input">비밀번호</label>
<input className="form-control" id="author_input" name="author" type="text" required />
</div>
<div className="form-group">
<Link to="/home">
<button className="btn" type="submit">로그인</button>
</Link>
</div>
</form>
</Log>
</div>
</div>
)
}
export default Login
\ No newline at end of file
import React, { } from 'react';
import styled from 'styled-components';
import { Link } from 'react-router-dom';
import { Formik } from 'formik';
import * as Yup from 'yup';
const Log = styled.div`
background-color: #981e1e;
`
const Logo = styled.div`
background-color: #E76A6A;
`
function Login() {
return (
<div className="container-fluid">
<div className="row">
<Logo className="col-md-5 col-12">
<h2>고려대학교</h2>
<h4>대관 시스템</h4>
</Logo>
<Log className="col-md-7 col-12">
<Formik
initialValues={{ email: '', password: '' }}
validationSchema={Yup.object({
email: Yup.string()
.email('이메일형식이 유효하지 않습니다.')
.required('이메일을 입력해주세요.'),
password: Yup.string()
.required('비밀번호를 입력해주세요.')
.min(8, '8자 이상 입력해주세요.'),
})}
onSubmit={(values, { setSubmitting }) => {
// axios({
// method: 'post',
// url: '/login',
// data: values,
// }).then(res => {
// if (res.status === 404) return alert(res.data.error)
alert("로그인이 완료되었습니다!")
// localStorage.setItem('token', res.data.token);
// localStorage.setItem('id', res.data.users._id);
// 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,
}) => (
<div className="row justify-content-center align-items-center">
<form onSubmit={handleSubmit} className="col-sm-3">
<div className="form-group mb-4">
<input
className={(touched.email && errors.email ? 'form-control is-invalid' : "form-control")}
type="email"
name="email"
{...getFieldProps('email')}
placeholder="Input Email"
/>
{touched.email && errors.email ? (
<div className="invalid-feedback text-left">{errors.email}</div>
) : null}
</div>
<div className="form-group mb-4">
<input
className={(touched.password && errors.password ? 'form-control is-invalid' : "form-control")}
type="password"
name="password"
{...getFieldProps('password')}
placeholder="Input Password"
/>
{touched.password && errors.password ? (
<div className="invalid-feedback text-left">{errors.password}</div>
) : null}
</div>
<button type="submit" className="btn btn-dark" disabled={isSubmitting}>
Login
</button>
<button>
<Link to="/home">gha</Link></button>
<Link to="/signup">비밀번호를 잊으셨나요?</Link>
<div></div>
<Link to="/signup">회원이 아니신가요?</Link>
</form>
</div>
)}
</Formik>
</Log>
</div>
</div>
)
}
export default Login
\ No newline at end of file
import React, { useState, useEffect } from 'react';
import Menu from '../Components/Menu';
function Notice() {
return (
<div>
<Menu />
<div className="container">notice
</div>
</div>
)
}
export default Notice
\ No newline at end of file
import React, { useState } from 'react';
import { Formik } from 'formik';
import * as Yup from 'yup';
import axios from 'axios';
import 'bootstrap/dist/css/bootstrap.css';
import { Link, Redirect } from 'react-router-dom';
function Signup() {
// const [state, setState] = useState(false);
// if (state) {
// return <Redirect to="/login" />;
// }
return (
<div className="d-flex flex-column justify-content-between vh-100">
<Formik
initialValues={{ name: '', email: '', password: '', password2: '', address: '', }}
validationSchema={Yup.object({
name: Yup.string()
.required('이름을 입력해주세요.'),
email: Yup.string()
.email('이메일형식이 유효하지 않습니다.')
.required('이메일을 입력해주세요.'),
password: Yup.string()
.required('비밀번호를 입력해주세요.')
.min(8, '8자 이상 입력해주세요.'),
password2: Yup.string()
.required('비밀번호를 다시 입력해주세요.')
.min(8, '8자 이상 입력해주세요.')
.oneOf([Yup.ref("password"), null], '비밀번호가 일치하지 않습니다.'),
address: Yup.string()
.required('주소를 입력해주세요.')
})}
onSubmit={(values, { setSubmitting }) => {
// axios({
// method: 'post',
// url: '/users',
// 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,
}) => (
<div className="row justify-content-center align-items-center">
<form onSubmit={handleSubmit} className="col-sm-3">
<div className="form-group mb-4">
<input
className={(touched.name && errors.name ? 'form-control is-invalid' : "form-control")}
type="text"
name="name"
{...getFieldProps('name')}
placeholder="Input Name" />
{touched.name && errors.name ? (
<div className="invalid-feedback text-left">{errors.name}</div>
) : null}
</div>
<div className="form-group mb-4">
<input
className={(touched.email && errors.email ? 'form-control is-invalid' : "form-control")}
type="email"
name="email"
{...getFieldProps('email')}
placeholder="Input Email"
/>
{touched.email && errors.email ? (
<div className="invalid-feedback text-left">{errors.email}</div>
) : null}
</div>
<div className="form-group mb-4">
<input
className={(touched.address && errors.address ? 'form-control is-invalid' : "form-control")}
type="text"
name="address"
{...getFieldProps('address')}
placeholder="Input Address" />
{touched.address && errors.address ? (
<div className="invalid-feedback text-left">{errors.address}</div>
) : null}
</div>
<div className="form-group mb-4">
<input
className={(touched.password && errors.password ? 'form-control is-invalid' : "form-control")}
type="password"
name="password"
{...getFieldProps('password')}
placeholder="Input Password"
/>
{touched.password && errors.password ? (
<div className="invalid-feedback text-left">{errors.password}</div>
) : null}
</div>
<div className="form-group mb-4">
<input
className={(touched.password2 && errors.password2 ? 'form-control is-invalid' : "form-control")}
type="password"
name="password2"
{...getFieldProps('password2')}
placeholder="Input Confirm Password"
/>
{touched.password2 && errors.password2 ? (
<div className="invalid-feedback text-left">{errors.password2}</div>
) : null}
</div>
<button type="submit" className="btn btn-dark" disabled={isSubmitting}>
Sign Up
</button>
<button>
<Link to="/">gha</Link></button>
</form>
</div>
)}
</Formik>
</div>
);
}
export default Signup;
......@@ -4,14 +4,22 @@ import * as serviceWorker from './serviceWorker';
import { BrowserRouter as Router, Route, Redirect, Switch } from 'react-router-dom';
import 'bootstrap/dist/css/bootstrap.css';
import Login from './Pages/Login';
import Home from './Pages/Home';
import Login from './Pages/LoginPage';
import Home from './Pages/HomePage';
import Signup from './Pages/SignupPage';
import Apply from './Pages/ApplyPage';
import Check from './Pages/CheckPage';
import Notice from './Pages/NoticePage';
ReactDOM.render(
<Router>
<Switch>
<Route exact path="/" component={Login} />
<Route path="/home" component={Home} />
<Route path="/signup" component={Signup} />
<Route path="/apply" component={Apply} />
<Route path="/check" component={Check} />
<Route path="/notice" component={Notice} />
</Switch>
</Router>,
document.getElementById('root')
......
This diff is collapsed.
......@@ -6,10 +6,13 @@
"start": "node ./bin/www"
},
"dependencies": {
"bcrypt": "^5.0.0",
"cookie-parser": "~1.4.4",
"debug": "~2.6.9",
"dotenv": "^8.2.0",
"express": "~4.16.1",
"http-errors": "~1.6.3",
"jsonwebtoken": "^8.5.1",
"mongoose": "^5.10.5",
"morgan": "~1.9.1",
"pug": "2.0.0-beta11"
......
const mongoose = require('mongoose');
module.exports = () => {
const connect = () => {
if (process.env.NODE_ENV !== 'production') {
mongoose.set('debug', true);
}
mongoose.connect('mongodb://rkyoung7:rkdud127@localhost:27017/admin', {
dbName: 'KU_Rental',
}, (error) => {
if (error) {
console.log('몽고디비 연결 에러', error);
} else {
console.log('몽고디비 연결 성공');
}
});
};
connect();
mongoose.connection.on('error', (error) => {
console.error('몽고디비 연결 에러', error);
});
mongoose.connection.on('disconnected', () => {
console.error('몽고디비 연결이 끊겼습니다. 연결을재시도합니다.');
connect();
});
require('./user');
require('./reserve');
};
const mongoose = require('mongoose');
const { Schema } = mongoose;
const reserveSchema = new Schema({
date: {
type: String,
},
time: {
type: String,
},
room:{
type: String,
},
name: { //대표자 이름
type: String,
},
id:{
type: Number,
},
reason: {
type: String,
},
member: {
type: String,
},
approve: {
type: Boolean,
},
num: {
type: Number,
},
});
module.exports = mongoose.model('Reserve', reserveSchema);
const mongoose = require('mongoose');
const bcrypt = require("bcrypt");
const saltRounds = 10;
const { Schema } = mongoose;
const userSchema = new Schema({
name: {
type: String,
required: true,
},
password: {
type: String,
},
id: {
type: Number,
required: true,
},
});
userSchema.pre("save", function (next) {
let user = this; //User모델 자체를 가르킴.
//model 안의 paswsword가 변경 또는 생성될 때 암호화
if (user.isModified("password")) {
bcrypt.genSalt(saltRounds, function (err, salt) {
if (err) return next(err);
bcrypt.hash(user.password, salt, function (err, hash) {
if (err) return next(err);
user.password = hash;
next();
});
});
} else {
next();
}
});
module.exports = mongoose.model('User', userSchema);
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