Commit e1796752 authored by Jiwon Yoon's avatar Jiwon Yoon
Browse files

Merge branch 'kimpen'

parents 7578fa34 3aafc3b2
PG_DATABASE=butterDB
PG_USER=butter
PG_PASSWORD=butter
\ No newline at end of file
...@@ -15,10 +15,10 @@ import TicketingPage from "./pages/TicketingPage"; ...@@ -15,10 +15,10 @@ import TicketingPage from "./pages/TicketingPage";
function App() { function App() {
return ( return (
<div className="" style={{ backgroundColor: "black" }}> // <div className="" style={{ backgroundColor: "black" }}>
<SubNav /> // <SubNav />
<Header /> // <Header />
<MainNav /> // <MainNav />
<Router> <Router>
<Switch> <Switch>
<Route exact path="/" component={HomePage} /> <Route exact path="/" component={HomePage} />
...@@ -30,7 +30,7 @@ function App() { ...@@ -30,7 +30,7 @@ function App() {
<Route path="/admin" component={AdminPage}/> <Route path="/admin" component={AdminPage}/>
</Switch> </Switch>
</Router> </Router>
</div> // </div>
); );
} }
......
...@@ -3,7 +3,7 @@ import KakaoMap from "../KakaoMap"; ...@@ -3,7 +3,7 @@ import KakaoMap from "../KakaoMap";
import styles from "./admin.module.scss"; import styles from "./admin.module.scss";
const CinemaEdit = () => { const CinemaEdit = () => {
const [cinemaInfo, setCinemaInfo] = useState({ cinema: "", transportation: "", parking: "", address: "" }) const [cinemaInfo, setCinemaInfo] = useState({ cinema: "", transportation: "", parking: "", keyword: "" })
const [search, setSearch] = useState("") const [search, setSearch] = useState("")
function handleChange(e) { function handleChange(e) {
...@@ -24,14 +24,14 @@ const CinemaEdit = () => { ...@@ -24,14 +24,14 @@ const CinemaEdit = () => {
<label for="parking" className="form-label">자가용/주차안내</label> <label for="parking" className="form-label">자가용/주차안내</label>
<textarea className={`form-control ${styles.shadowNone} ${styles.textarea}`} rows="7" id="parking" name="parking" onChange={handleChange}></textarea> <textarea className={`form-control ${styles.shadowNone} ${styles.textarea}`} rows="7" id="parking" name="parking" onChange={handleChange}></textarea>
</div> </div>
<label for="address" className="form-label">지도보기</label> <label for="keyword" className="form-label">지도보기</label>
<div className="input-group mb-3"> <div className="input-group mb-3">
<span className="input-group-text" id="currentMap"><i className="bi bi-geo-alt-fill"></i></span> <span className="input-group-text" id="currentMap"><i className="bi bi-geo-alt-fill"></i></span>
<input type="text" className={`form-control ${styles.shadowNone}`} id="address" name="address" aria-label="map" aria-describedby="currentMap" onChange={handleChange} /> <input type="text" className={`form-control ${styles.shadowNone}`} id="keyword" name="keyword" aria-label="map" aria-describedby="currentMap" onChange={handleChange} />
<button className="btn btn-dark" type="button" id="currentMap" onClick={() => setSearch(cinemaInfo.address)}><i className="bi bi-search"></i></button> <button className="btn btn-dark" type="button" id="currentMap" onClick={() => setSearch(cinemaInfo.keyword)}><i className="bi bi-search"></i></button>
</div> </div>
<div className="d-flex justify-content-center mb-5"> <div className="d-flex justify-content-center mb-5">
<KakaoMap address={search} /> <KakaoMap keyword={search} />
</div> </div>
</> </>
) )
......
import Search from "../Search"; import Search from "../Search";
import MovieTable from "../MovieTable"; import MovieTable from "../MovieTable";
import Pagination from "../Pagination"; import Pagination from "../Pagination";
import styles from "./admin.module.scss";
const MovieEdit = () => { const MovieEdit = () => {
return ( return (
...@@ -9,10 +10,10 @@ const MovieEdit = () => { ...@@ -9,10 +10,10 @@ const MovieEdit = () => {
<Search type="admin" /> <Search type="admin" />
</div> </div>
<MovieTable /> <MovieTable />
<div className="d-md-flex"> <div className="d-flex flex-wrap">
<Pagination /> <Pagination />
<div className="d-flex justify-content-end col-md-3 ms-md-auto my-1"> <div className="d-flex justify-content-end col-12 col-md-4 my-2">
<button type="button" className="btn btn-dark" style={{ width: "5em" }}>등록</button> <button type="button" className={`btn btn-dark ${styles.customBtn}`}>등록</button>
</div> </div>
</div> </div>
</> </>
......
...@@ -27,3 +27,13 @@ ...@@ -27,3 +27,13 @@
.textarea { .textarea {
resize: none; resize: none;
} }
.customBtn {
width: 5em;
&:hover {
border-color: #FEDC00;
background-color: #FEDC00;
color: #000;
}
}
\ No newline at end of file
import { useEffect, useRef } from "react";
const { kakao } = window;
const KakaoMap = ({ address }) => {
const kakaoMapDiv = useRef(null)
useEffect(() => {
const container = kakaoMapDiv.current
const options = {
center: new kakao.maps.LatLng(33.450701, 126.570667),
level: 3
};
const map = new kakao.maps.Map(container, options);
const geocoder = new kakao.maps.services.Geocoder();
geocoder.addressSearch(`${address}`, function (result, status) {
if (status === kakao.maps.services.Status.OK) {
const coords = new kakao.maps.LatLng(result[0].y, result[0].x);
const marker = new kakao.maps.Marker({
map: map,
position: coords
});
map.setCenter(coords);
} else if (address != '') {
alert("찾을 수 없는 주소입니다. 다시 입력해주세요.")
}
});
}, [address])
return (
<div ref={kakaoMapDiv} style={{ width: "500px", height: "400px" }}></div>
)
}
export default KakaoMap
\ No newline at end of file
import { useState, useEffect, useRef } from "react";
import styles from "./kakao-map.module.scss";
const { kakao } = window;
const KakaoMap = ({ keyword }) => {
const kakaoMapDiv = useRef(null)
const menu = useRef(null)
const searchList = useRef(null)
const page = useRef(null)
const [places, setPlaces] = useState([])
let markers = []
useEffect(() => {
const container = kakaoMapDiv.current
const options = {
center: new kakao.maps.LatLng(33.450701, 126.570667),
level: 3
};
const map = new kakao.maps.Map(container, options);
const ps = new kakao.maps.services.Places();
const infowindow = new kakao.maps.InfoWindow({ zIndex: 1 });
searchPlaces(keyword)
// 키워드 검색을 요청하는 함수입니다
function searchPlaces(keyword) {
if (!keyword.replace(/^\s+|\s+$/g, '')) {
alert('키워드를 입력해주세요.');
return false
}
// 장소검색 객체를 통해 키워드로 장소검색을 요청합니다
ps.keywordSearch(keyword, placesSearchCB);
}
// 장소검색이 완료됐을 때 호출되는 콜백함수 입니다
function placesSearchCB(data, status, pagination) {
if (status === kakao.maps.services.Status.OK) {
displayPlaces(data);
// 페이지 번호를 표출합니다
displayPagination(pagination);
// let bounds = new kakao.maps.LatLngBounds()
// for (let i = 0; i < data.length; i++) {
// displayMarker(data[i])
// bounds.extend(new kakao.maps.LatLng(data[i].y, data[i].x))
// }
// map.setBounds(bounds)
// // 페이지 목록 보여주는 displayPagination() 추가
// displayPagination(pagination)
// setPlaces(data)
} else if (status === kakao.maps.services.Status.ZERO_RESULT) {
alert('검색 결과가 존재하지 않습니다.');
return
} else if (status === kakao.maps.services.Status.ERROR) {
alert('검색 결과 중 오류가 발생했습니다.');
return
}
}
// 검색 결과 목록과 마커를 표출하는 함수입니다
function displayPlaces(places) {
let listEl = searchList.current,
menuEl = menu.current,
fragment = document.createDocumentFragment(),
bounds = new kakao.maps.LatLngBounds(),
listStr = '';
for (let i = 0; i < places.length; i++) {
// 마커를 생성하고 지도에 표시합니다
let placePosition = new kakao.maps.LatLng(places[i].y, places[i].x),
itemEl = getListItem(i, places[i]); // 검색 결과 항목 Element를 생성합니다
displayMarker(places[i], itemEl)
// 검색된 장소 위치를 기준으로 지도 범위를 재설정하기위해 LatLngBounds 객체에 좌표를 추가합니다
bounds.extend(placePosition);
fragment.appendChild(itemEl);
}
// 검색결과 항목들을 검색결과 목록 Elemnet에 추가합니다
listEl.appendChild(fragment);
menuEl.scrollTop = 0;
// 검색된 장소 위치를 기준으로 지도 범위를 재설정합니다
map.setBounds(bounds);
}
function displayMarker(place, itemEl) {
let marker = new kakao.maps.Marker({
map: map,
position: new kakao.maps.LatLng(place.y, place.x),
})
kakao.maps.event.addListener(marker, 'mouseover', function () {
infowindow.setContent('<div style="padding:5px;font-size:12px;">' + place.place_name + '</div>')
infowindow.open(map, marker)
})
kakao.maps.event.addListener(marker, 'mouseout', function () {
infowindow.close();
})
itemEl.onmouseover = function () {
infowindow.setContent('<div style="padding:5px;font-size:12px;">' + place.place_name + '</div>')
infowindow.open(map, marker)
};
itemEl.onmouseout = function () {
infowindow.close();
};
}
}, [keyword])
// 검색결과 목록 하단에 페이지번호를 표시는 함수입니다
function displayPagination(pagination) {
let paginationEl = page.current,
fragment = document.createDocumentFragment(),
i;
for (i = 1; i <= pagination.last; i++) {
let el = document.createElement('a');
el.href = "#";
el.innerHTML = i;
if (i === pagination.current) {
el.className = 'on';
} else {
el.onclick = (function (i) {
return function () {
pagination.gotoPage(i);
}
})(i);
}
fragment.appendChild(el);
}
paginationEl.appendChild(fragment);
}
// 검색결과 항목을 Element로 반환하는 함수입니다
function getListItem(index, places) {
let el = document.createElement('li'),
itemStr = '<span className="markerbg marker_' + (index + 1) + '"></span>' +
'<div className="info">' +
' <h5>' + places.place_name + '</h5>';
if (places.road_address_name) {
itemStr += ' <span>' + places.road_address_name + '</span>' +
' <span className="jibun gray">' + places.address_name + '</span>';
} else {
itemStr += ' <span>' + places.address_name + '</span>';
}
itemStr += ' <span className="tel">' + places.phone + '</span>' +
'</div>';
el.innerHTML = itemStr;
el.className = 'item';
return el;
}
// 마커를 생성하고 지도 위에 마커를 표시하는 함수입니다
// function addMarker(position, idx, title) {
// const imageSrc = 'https://t1.daumcdn.net/localimg/localimages/07/mapapidoc/marker_number_blue.png', // 마커 이미지 url, 스프라이트 이미지를 씁니다
// imageSize = new kakao.maps.Size(36, 37), // 마커 이미지의 크기
// imgOptions = {
// spriteSize: new kakao.maps.Size(36, 691), // 스프라이트 이미지의 크기
// spriteOrigin: new kakao.maps.Point(0, (idx * 46) + 10), // 스프라이트 이미지 중 사용할 영역의 좌상단 좌표
// offset: new kakao.maps.Point(13, 37) // 마커 좌표에 일치시킬 이미지 내에서의 좌표
// },
// markerImage = new kakao.maps.MarkerImage(imageSrc, imageSize, imgOptions),
// marker = new kakao.maps.Marker({
// position: position, // 마커의 위치
// image: markerImage
// });
// marker.setMap(map); // 지도 위에 마커를 표출합니다
// markers.push(marker); // 배열에 생성된 마커를 추가합니다
// return marker;
// }
return (
<>
<div ref={kakaoMapDiv} style={{ width: "500px", height: "400px" }}></div>
<div ref={menu} className="bg-white">
<div ref={searchList}></div>
{/* {places.map((item, i) => (
<div key={i} style={{ marginTop: '20px' }}>
<h5>{i + 1}. {item.place_name}</h5>
<div>
{item.road_address_name ? (
<div>
<span>{item.road_address_name}</span>
<span>{item.address_name}</span>
</div>
) : (
<span>{item.address_name}</span>
)}
<span>{item.phone}</span>
</div>
</div>
))} */}
<div ref={page}></div>
</div>
</>
)
}
export default KakaoMap
\ No newline at end of file
export { default } from "./KakaoMap"
\ No newline at end of file
...@@ -14,25 +14,27 @@ const MovieTable = () => { ...@@ -14,25 +14,27 @@ const MovieTable = () => {
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr className={styles.Row} data-bs-toggle="collapse" data-bs-target={"#movie"}> <tr className={styles.Row} data-bs-toggle="collapse" data-bs-target={"#movie1"}>
<td className={styles.dInLine}>블랙위도우</td> <td className="d-inline-block d-md-table-cell">블랙위도우</td>
<td data-label="- " className={`${styles.data} ${styles.dInLine}`}>케이트 쇼트랜드</td> <td data-label="- " className={`d-inline-block d-md-table-cell ${styles.data}`}>케이트 쇼트랜드</td>
<td className={styles.dNone}>O</td> <td className="d-none d-md-table-cell">O</td>
<td className={styles.dNone}>O</td> <td className="d-none d-md-table-cell">O</td>
<td className={styles.dNone}>X</td> <td className="d-none d-md-table-cell">X</td>
<td className={styles.dNone}>X</td> <td className="d-none d-md-table-cell">X</td>
</tr> </tr>
<tr> <tr className={styles.Row}>
<div className="collapse" id={"movie"}> <td colSpan="6" className="collapse" id={"movie1"}>
<td className={`${styles.data} ${styles.allDNone} ${styles.dInLine}`}>줄거리 - O</td> <div className={`d-inline-block d-md-none ${styles.word} mb-2`}>
<td className={`${styles.data} ${styles.allDNone} ${styles.dInLine}`}>포스터 - O</td> 줄거리 - O /
<td className={`${styles.data} ${styles.allDNone} ${styles.dInLine}`}>스틸컷 - X</td> 포스터 - O /
<td className={`${styles.data} ${styles.allDNone} ${styles.dInLine}`}>예고편 - X</td> 스틸컷 - X /
<div className="d-flex justify-content-end mt-1"> 예고편 - X
</div>
<div className="d-flex justify-content-end">
<button type="button" className="btn btn-primary mx-2">수정</button> <button type="button" className="btn btn-primary mx-2">수정</button>
<button type="button" className="btn btn-danger">삭제</button> <button type="button" className="btn btn-danger">삭제</button>
</div> </div>
</div> </td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
background: rgba(0, 0, 0, 0.075); background: rgba(0, 0, 0, 0.075);
} }
.allDNone { .word {
display: none; word-break: keep-all;
} }
@media screen and (max-width: 767px) { @media screen and (max-width: 767px) {
...@@ -15,10 +15,6 @@ ...@@ -15,10 +15,6 @@
border: 0; border: 0;
} }
& .dInLine {
display: inline-block;
}
& .Row { & .Row {
border-bottom: 2px solid; border-bottom: 2px solid;
......
const Pagination = () => { const Pagination = () => {
return ( return (
<nav className="col-md-3 ms-md-auto my-1" aria-label="Page navigation example"> <nav className="col-12 col-md-4 offset-md-4 my-2" aria-label="Page navigation">
<ul className="pagination justify-content-center mb-0"> <ul className="pagination justify-content-center mb-0">
<li className="page-item"> <li className="page-item">
<a className="page-link" href="#" aria-label="Previous"> <a className="page-link" href="#" aria-label="Previous">
......
...@@ -5,7 +5,7 @@ const Search = ({ type }) => { ...@@ -5,7 +5,7 @@ const Search = ({ type }) => {
return ( return (
<div className="d-flex"> <div className="d-flex">
<input className="form-control" type="text" id={type === "home" ? styles.searchWhite : styles.search} /> <input className="form-control" type="text" id={type === "home" ? styles.searchWhite : styles.search} />
<i className={`bi bi-search align-self-center ${type === "home" ? "text-white" : "mx-1"} ${styles.icon}`} style={{ fontSize: "1.3rem" }}></i> <i className={`bi bi-search align-self-center ${type === "home" ? "text-white" : "mx-2"} ${styles.icon}`} style={{ fontSize: "1.3rem" }}></i>
</div> </div>
) )
} }
......
...@@ -22,8 +22,13 @@ ...@@ -22,8 +22,13 @@
} }
#search { #search {
background: transparent;
border: none;
border-bottom: 2px solid #000;
border-radius: 0;
box-shadow: none; box-shadow: none;
-webkit-box-shadow: none; -webkit-box-shadow: none;
&:focus { &:focus {
-webkit-box-shadow: none; -webkit-box-shadow: none;
box-shadow: none; box-shadow: none;
......
{
"watch": ["server"],
"ext": "js,jsx,json",
"ignore": ["src/**/*.spec.js"],
"exec": "node ./server/index.js"
}
\ No newline at end of file
...@@ -180,6 +180,11 @@ ...@@ -180,6 +180,11 @@
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A=="
}, },
"buffer-writer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz",
"integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw=="
},
"busboy": { "busboy": {
"version": "0.2.14", "version": "0.2.14",
"resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz",
...@@ -389,6 +394,15 @@ ...@@ -389,6 +394,15 @@
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
"integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
}, },
"cookie-parser": {
"version": "1.4.5",
"resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.5.tgz",
"integrity": "sha512-f13bPUj/gG/5mDr+xLmSxxDsB9DQiTIfhJS/sqjrmfAWiAN+x2O4i/XguTL9yDZ+/IFDanJ+5x7hC4CXT9Tdzw==",
"requires": {
"cookie": "0.4.0",
"cookie-signature": "1.0.6"
}
},
"cookie-signature": { "cookie-signature": {
"version": "1.0.6", "version": "1.0.6",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
...@@ -462,6 +476,11 @@ ...@@ -462,6 +476,11 @@
"is-obj": "^2.0.0" "is-obj": "^2.0.0"
} }
}, },
"dotenv": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz",
"integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q=="
},
"dottie": { "dottie": {
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.2.tgz", "resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.2.tgz",
...@@ -1159,6 +1178,11 @@ ...@@ -1159,6 +1178,11 @@
} }
} }
}, },
"packet-reader": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz",
"integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ=="
},
"parseurl": { "parseurl": {
"version": "1.3.3", "version": "1.3.3",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
...@@ -1169,12 +1193,97 @@ ...@@ -1169,12 +1193,97 @@
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
}, },
"pg": {
"version": "8.6.0",
"resolved": "https://registry.npmjs.org/pg/-/pg-8.6.0.tgz",
"integrity": "sha512-qNS9u61lqljTDFvmk/N66EeGq3n6Ujzj0FFyNMGQr6XuEv4tgNTXvJQTfJdcvGit5p5/DWPu+wj920hAJFI+QQ==",
"requires": {
"buffer-writer": "2.0.0",
"packet-reader": "1.0.0",
"pg-connection-string": "^2.5.0",
"pg-pool": "^3.3.0",
"pg-protocol": "^1.5.0",
"pg-types": "^2.1.0",
"pgpass": "1.x"
}
},
"pg-connection-string": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz",
"integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ=="
},
"pg-hstore": {
"version": "2.3.4",
"resolved": "https://registry.npmjs.org/pg-hstore/-/pg-hstore-2.3.4.tgz",
"integrity": "sha512-N3SGs/Rf+xA1M2/n0JBiXFDVMzdekwLZLAO0g7mpDY9ouX+fDI7jS6kTq3JujmYbtNSJ53TJ0q4G98KVZSM4EA==",
"requires": {
"underscore": "^1.13.1"
}
},
"pg-int8": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
"integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw=="
},
"pg-pool": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.3.0.tgz",
"integrity": "sha512-0O5huCql8/D6PIRFAlmccjphLYWC+JIzvUhSzXSpGaf+tjTZc4nn+Lr7mLXBbFJfvwbP0ywDv73EiaBsxn7zdg=="
},
"pg-protocol": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.5.0.tgz",
"integrity": "sha512-muRttij7H8TqRNu/DxrAJQITO4Ac7RmX3Klyr/9mJEOBeIpgnF8f9jAfRz5d3XwQZl5qBjF9gLsUtMPJE0vezQ=="
},
"pg-types": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz",
"integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==",
"requires": {
"pg-int8": "1.0.1",
"postgres-array": "~2.0.0",
"postgres-bytea": "~1.0.0",
"postgres-date": "~1.0.4",
"postgres-interval": "^1.1.0"
}
},
"pgpass": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.4.tgz",
"integrity": "sha512-YmuA56alyBq7M59vxVBfPJrGSozru8QAdoNlWuW3cz8l+UX3cWge0vTvjKhsSHSJpo3Bom8/Mm6hf0TR5GY0+w==",
"requires": {
"split2": "^3.1.1"
}
},
"picomatch": { "picomatch": {
"version": "2.3.0", "version": "2.3.0",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
"integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==",
"dev": true "dev": true
}, },
"postgres-array": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
"integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA=="
},
"postgres-bytea": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz",
"integrity": "sha1-AntTPAqokOJtFy1Hz5zOzFIazTU="
},
"postgres-date": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz",
"integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q=="
},
"postgres-interval": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz",
"integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==",
"requires": {
"xtend": "^4.0.0"
}
},
"prepend-http": { "prepend-http": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
...@@ -1437,6 +1546,39 @@ ...@@ -1437,6 +1546,39 @@
"integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
"dev": true "dev": true
}, },
"split2": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz",
"integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==",
"requires": {
"readable-stream": "^3.0.0"
},
"dependencies": {
"readable-stream": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
}
},
"safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
},
"string_decoder": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
"requires": {
"safe-buffer": "~5.2.0"
}
}
}
},
"statuses": { "statuses": {
"version": "1.5.0", "version": "1.5.0",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
...@@ -1594,6 +1736,11 @@ ...@@ -1594,6 +1736,11 @@
"debug": "^2.2.0" "debug": "^2.2.0"
} }
}, },
"underscore": {
"version": "1.13.1",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.1.tgz",
"integrity": "sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g=="
},
"unique-string": { "unique-string": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz",
......
...@@ -3,9 +3,11 @@ ...@@ -3,9 +3,11 @@
"version": "1.0.0", "version": "1.0.0",
"description": "영화 예매 사이트", "description": "영화 예매 사이트",
"main": "index.js", "main": "index.js",
"type": "module",
"scripts": { "scripts": {
"start": "node dist/index.js",
"test": "echo \"Error: no test specified\" && exit 1", "test": "echo \"Error: no test specified\" && exit 1",
"dev": "nodemon index.js" "dev": "nodemon"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
...@@ -15,9 +17,13 @@ ...@@ -15,9 +17,13 @@
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"bcryptjs": "^2.4.3", "bcryptjs": "^2.4.3",
"cookie-parser": "^1.4.5",
"dotenv": "^10.0.0",
"express": "^4.17.1", "express": "^4.17.1",
"jsonwebtoken": "^8.5.1", "jsonwebtoken": "^8.5.1",
"multer": "^1.4.2", "multer": "^1.4.2",
"pg": "^8.6.0",
"pg-hstore": "^2.3.4",
"sequelize": "^6.6.4" "sequelize": "^6.6.4"
}, },
"devDependencies": { "devDependencies": {
......
import express from 'express'
import cookieParser from 'cookie-parser'
import mainRouter from './routes/index.js'
const app = express()
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
app.use(cookieParser())
app.use('/api', mainRouter)
export default app
\ No newline at end of file
const config = {
env: process.env.NODE_ENV === 'production' ? 'production' : 'development',
port: process.env.PORT || 3001,
// jwtSecret: 'dfkasf23i$efksdfks!',
jwtExpires: '7d',
cookieName: 'butterStudio',
cookieMaxAge: 60 * 60 * 24 * 7 * 1000,
}
export default config
\ No newline at end of file
const config = {
host: 'localhost',
username: process.env.PG_USER || 'butter',
password: process.env.PG_PASSWORD || 'butter',
database: process.env.PG_DATABASE || 'butterDB',
dialect: 'postgres',
pool: {
max: 10,
min: 0,
acquire: 30000,
idle: 10000,
}
}
export default config
\ No newline at end of file
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