서준혁

Merge Frontend and Backend

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
# Next.js build output
.next
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and *not* Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <https://unlicense.org>
......@@ -16,6 +16,8 @@ app.use(express.urlencoded({ extended: true }))
// 터미널창 연결방법 mongo 'mongodb+srv://hellowhales:qogudtjr`12@cluster0.7gz7l.mongodb.net/myFirstDatabase?retryWrites=true&w=majority';
// db.festivals.find({"title":"가무악극으로 만나는 토요 상설공연"}) 검색방법
//https://www.mongodb.com/try/download/database-tools?tck=docs_databasetools 여기서 mongoexport 실행을 위한 tool 다운받아서 Program files/mongodb/bin 폴더 안에 넣어줘야 함
MongoClient.connect(url, (error, client) => { // 서버열때 url 사용 mongoDB와 연결시키기
if (error) return console.log(error);
db = client.db('myFirstDatabase'); // 클러스터의 데이터베이스를 db변수에 저장
......@@ -27,14 +29,21 @@ MongoClient.connect(url, (error, client) => { // 서버열때 url 사용 mongoDB
app.get('/festivalList', (req, res) => { // localhost:3000/festivalList 입력하면 list.ejs에 저장한 형식대로 정보 불러와짐
//디비에 저장된 festivals 라는 collection안의 데이터(제목 또는 내용 등)를 꺼내기
db.collection('festivals').find().toArray((err, rslt) => { //DB에서 데이터를 찾음 festivals라는 collection안의 데이터를 꺼내게 됨
if (err) throw err;
console.log(rslt);
res.render('list.ejs', { posts: rslt }); // 찾은 데이터를 ejs 파일에 넣음
});
});
// 서버 연결하고 mongoexport 설치 후 mongoexport -d myFirstDatabase -c festivals -o festivalList.json /pretty 'mongodb+srv://hellowhales:qogudtjr`12@cluster0.7gz7l.mongodb.net/myFirstDatabase?retryWrites=true&w=majority' 명령
// 이용해서 myFirstDatabase라는 Db 안에서 festivals라는 collection 안의 데이터를 festivalList.json 파일로 export 해옴.
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
const { mongo } = require('mongoose');
......@@ -72,17 +81,6 @@ app.use(function (err, req, res, next) {
/*
app.get('*', function (req, res) {
//DB에서 json형태의 데이터를 유저가 접속하자마자 바로 불러와서 frontend에 뿌려주기
// 렌더링할 때 frontend로 변수 뿌려주기
res.render("asd.html");
});
*/
module.exports = app;
......
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var app = express();
const mongodb = require('mongodb');
const MongoClient = mongodb.MongoClient;
const url = 'mongodb+srv://hellowhales:qogudtjr`12@cluster0.7gz7l.mongodb.net/myFirstDatabase?retryWrites=true&w=majority';
let db;
app.use(express.urlencoded({ extended: true }))
// 터미널창 연결방법 mongo 'mongodb+srv://hellowhales:qogudtjr`12@cluster0.7gz7l.mongodb.net/myFirstDatabase?retryWrites=true&w=majority';
// db.festivals.find({"title":"가무악극으로 만나는 토요 상설공연"}) 검색방법
//https://www.mongodb.com/try/download/database-tools?tck=docs_databasetools 여기서 mongoexport 실행을 위한 tool 다운받아서 Program files/mongodb/bin 폴더 안에 넣어줘야 함
MongoClient.connect(url, (error, client) => { // 서버열때 url 사용 mongoDB와 연결시키기
if (error) return console.log(error);
db = client.db('myFirstDatabase'); // 클러스터의 데이터베이스를 db변수에 저장
app.listen(3001, () => {
console.log('3001 port on');
});
});
app.get('/festivalList', (req, res) => { // localhost:3000/festivalList 입력하면 list.ejs에 저장한 형식대로 정보 불러와짐
//디비에 저장된 festivals 라는 collection안의 데이터(제목 또는 내용 등)를 꺼내기
db.collection('festivals').find().toArray((err, rslt) => { //DB에서 데이터를 찾음 festivals라는 collection안의 데이터를 꺼내게 됨
if (err) throw err;
console.log(rslt);
res.render('list.ejs', { posts: rslt }); // 찾은 데이터를 ejs 파일에 넣음
});
});
// 서버 연결하고 mongoexport 설치 후 mongoexport -d myFirstDatabase -c festivals -o festivalList.json /pretty 'mongodb+srv://hellowhales:qogudtjr`12@cluster0.7gz7l.mongodb.net/myFirstDatabase?retryWrites=true&w=majority' 명령
// 이용해서 myFirstDatabase라는 Db 안에서 festivals라는 collection 안의 데이터를 festivalList.json 파일로 export 해옴.
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
const { mongo } = require('mongoose');
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs'); // express에서 view엔진을 ejs로 설정하는과정
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
// catch 404 and forward to error handler
app.use(function (req, res, next) {
next(createError(404));
});
// error handler
app.use(function (err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
//유저 로그인할때 모든 여행지에 대한 정보를 DB에서 싹다 불러옴 페이지 렌더링할때 data 뿌려줌
\ No newline at end of file
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('tft:server');
var http = require('http');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}
.DS_Store
thumbs.db
*.log
node_modules/
\ No newline at end of file
This diff could not be displayed because it is too large.
{
"name": "tft",
"version": "0.0.0",
"private": true,
"name": "svelte-base",
"version": "1.0.0",
"description": "Basic svelte and express template I use for my application",
"main": "server.js",
"scripts": {
"start": "node ./bin/www"
"build": "webpack",
"release": "cross-env NODE_ENV=production webpack",
"server": "node server.js",
"start": "npm run build & npm run server",
"dev": "nodemon --watch ./src -e svelte,js,json --exec npm start"
},
"repository": {
"type": "git",
"url": "git+https://github.com/Bigaston/svelte-base.git"
},
"author": "Bigaston",
"license": "UNLICENSED",
"bugs": {
"url": "https://github.com/Bigaston/svelte-base/issues"
},
"homepage": "https://github.com/Bigaston/svelte-base#readme",
"dependencies": {
"cookie-parser": "~1.4.4",
"debug": "~2.6.9",
"ejs": "~2.6.1",
"express": "~4.16.1",
"http-errors": "~1.6.3",
"morgan": "~1.9.1"
"express": "^4.17.1",
"jquery": "^3.6.0",
"nodemon": "^2.0.15",
"socket.io": "^4.3.2",
"socket.io-client": "^4.3.2"
},
"devDependencies": {
"cross-env": "^7.0.2",
"css-loader": "^3.5.2",
"style-loader": "^1.1.3",
"svelte": "^3.20.1",
"svelte-loader": "^2.13.6",
"webpack": "^4.42.1",
"webpack-cli": "^3.3.11"
}
}
......
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
html, body {
position: relative;
width: 100%;
height: 100%;
}
body {
color: #333;
margin: 0;
padding: 8px;
box-sizing: border-box;
font-family: '맑은 고딕 Semilight', "AppleSDGothicNeo-Regular", 'Malgun Gothic', '맑은 고딕', "dotum", '돋움', sans-serif;
}
a {
color: rgb(0,100,200);
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
a:visited {
color: rgb(0,80,160);
}
label {
display: block;
}
input, button, select, textarea {
font-family: inherit;
font-size: inherit;
-webkit-padding: 0.4em 0;
padding: 0.4em;
margin: 0 0 0.5em 0;
box-sizing: border-box;
border: 1px solid #ccc;
border-radius: 2px;
}
input:disabled {
color: #ccc;
}
button {
color: #333;
background-color: #f4f4f4;
outline: none;
}
button:disabled {
color: #999;
}
button:not(:disabled):active {
background-color: #ddd;
}
button:focus {
border-color: #666;
}
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset='utf-8'>
<meta name='viewport' content='width=device-width,initial-scale=1'>
<link rel='icon' type='image/png' href='/public/favicon.png'>
<link rel='stylesheet' href='/public/global.css'>
</head>
<body>
<noscript>
<p>This website need JavaScript to work</p>
</noscript>
<main></main>
<script type="text/javascript" src="//dapi.kakao.com/v2/maps/sdk.js?appkey=046d27f1430524731d3ec6870f0c8923"></script>
<script src='./public/build/bundle.js'></script>
</body>
</html>
body {
padding: 50px;
font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
}
a {
color: #00B7FF;
}
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
module.exports = router;
var express = require('express');
var router = express.Router();
/* GET users listing. */
router.get('/', function(req, res, next) {
res.send('respond with a resource');
});
module.exports = router;
const express = require('express')
const path = require("path")
var app = express()
const PORT = 1697;
app.use("/public", express.static('./public'));
app.get("/*", (req, res) => {
res.sendFile(path.join(__dirname, "./public/index.html"))
})
var serv = app.listen(PORT, () => console.log(`Serveur lauched on port ${PORT}`))
<script>
import Menu from './Menu.svelte';
import Backtotop from './SideItems/Backtotop.svelte';
import Map from './Map.svelte';
import Article from './Articles.svelte';
import { AllFestas } from './Stores/AllFestas';
import jQuery from 'jquery';
import { DisplayedFestas } from './Stores/DisplayedFestas';
function LoadFestas() {
let url = "http://api.visitkorea.or.kr/openapi/service/rest/KorService/areaBasedList?ServiceKey=2lFkvQJYgzOOhwUKiUt8aZVNpd1PpBOf%2FfMNW17cl25DE0GUEDddeR9iGnuSUpggjUoIUgamfhcvnKQ3eH1dAw%3D%3D&contentTypeId=15&areaCode=&sigunguCode=&cat1=&cat2=&cat3=&listYN=Y&MobileOS=ETC&MobileApp=TourAPI3.0_Guide&arrange=A&numOfRows=12&pageNo=1&_type=json";
jQuery.getJSON(url, (json) => {
AllFestas.set(json.response.body.items.item);
});
}
</script>
<style>
div {
text-align: left;
box-sizing: border-box;
display: block;
}
:global(body) {
padding: 0;
margin: 0;
align-items: center;
align-content: center;
text-align: center;
justify-content: center;
}
:global(html) {
scroll-behavior: smooth;
}
</style>
<svelte:window on:load|once={LoadFestas}></svelte:window>
<div>
<Menu/>
<Map/>
<Backtotop/>
<Article/>
</div>
\ No newline at end of file
<style>
.article{
font-family: 맑은고딕, Malgun Gothic, dotum, gulim, sans-serif;
font-size: 24pt;
padding:10vw;
text-align: center;
display: flex;
}
.wbg{
background-color: #ffffff;
}
.gbg{
background-color: #edeff2;
}
.article img {
display: inline-block;
max-width: 500px;
width: 20vw;
margin-left: 4vw;
margin-right: 4vw;
}
.article .text {
display: inline-block;
width: 50vw;
}
.contents{
display: flex;
align-items: center;
}
</style>
<script>
</script>
<div class="article wbg" id="article1">
<div class="contents">
<img src="./public/TFTlogo.png" alt=":)">
<div class="text">
<h3>TFT에 오신 걸 환영합니다!</h3>
Travel & Festival with Temperature<br>
각종 행사 정보와 날씨 정보를 한눈에 알 수 있는 서비스입니다.
</div>
</div>
</div>
<div class="article gbg" id="article2">
<div class="contents">
<div class="text">
<h3>손쉬운 행사 탐색</h3>
TFT를 통해 전국에서 개최중인 행사와 축제를<br>
한 눈에 확인할 수 있습니다.
</div>
<img src="./public/exploremap.png" alt=";(">
</div>
</div>
<div class="article wbg" id="article3">
<div class="contents">
<img src="./public/infofesta.png" alt=":)">
<div class="text">
<h3>행사 정보 확인</h3>
지도에 표시된 마커를 클릭하여<br>
행사 정보를 확인할 수 있습니다.
</div>
</div>
</div>
<div class="article gbg" id="article4">
<div class="contents">
<div class="text">
사용된 기술 스택은 다음과 같습니다.<br><br>
WEB : NodeJS / Express / Svelte<br>
Database : MongoDB<br>
API Handler : NodeJS / RequestJS<br>
Docker
</div>
<img src="./public/stacks.png" alt=";(">
</div>
</div>
\ No newline at end of file
export let COORDINATES = {
"미선택" : {
"미선택" : [ 127.46862435619565, 36.003837243591676, 13 ]
},
"서울특별시" : {
"미선택" : [ 126.95401910605827, 37.53467856968404, 9],
"종로구" : [ 126.9773171, 37.59492045, 7],
"중구" : [ 126.9959683, 37.56014287, 7],
"용산구" : [ 126.9799076, 37.53138556, 7],
"성동구" : [ 127.0410588, 37.55103004, 7],
"광진구" : [ 127.0857458, 37.54672166, 7],
"동대문구" : [ 127.0548482, 37.58195725, 7],
"중랑구" : [ 127.0928839, 37.59781902, 7],
"성북구" : [ 127.0175783, 37.60570143, 7],
"강북구" : [ 127.0111848, 37.64347732, 7],
"도봉구" : [ 127.032367, 37.66910528, 7],
"노원구" : [ 127.0750336, 37.65251633, 7],
"은평구" : [ 126.9270283, 37.61921535, 7],
"서대문구" : [ 126.9390632, 37.57778646, 7],
"마포구" : [ 126.908264, 37.55931222, 7],
"양천구" : [ 126.8554792, 37.52478964, 7],
"강서구" : [ 126.8228036, 37.56123594, 7],
"구로구" : [ 126.8563021, 37.49440412, 7],
"금천구" : [ 126.9008177, 37.46056912, 7],
"영등포구" : [ 126.9101694, 37.52230985, 7],
"동작구" : [ 126.9516402, 37.49887636, 7],
"관악구" : [ 126.9453355, 37.46737656, 7],
"서초구" : [ 127.0312084, 37.47329793, 7],
"강남구" : [ 127.0629749, 37.49664584, 7],
"송파구" : [ 127.1152911, 37.50562076, 7],
"강동구" : [ 127.1470146, 37.55045136, 7]
},
"부산광역시" : {
"미선택" : [ 129.0315402, 35.10547796 , 9],
"중구" : [ 129.0315402, 35.10547796, 7],
"서구" : [ 129.0149128, 35.10296452, 7],
"동구" : [ 129.0445861, 35.1291866, 7],
"영도구" : [ 129.0648202, 35.07865091, 7],
"부산진구" : [ 129.0430601, 35.16524533, 7],
"동래구" : [ 129.0792188, 35.20621201, 7],
"남구" : [ 129.0940042, 35.12613858, 7],
"북구" : [ 129.0234651, 35.22925311, 7],
"해운대구" : [ 129.1535891, 35.19385742, 7],
"사하구" : [ 128.9743481, 35.0893528, 7],
"금정구" : [ 129.09153, 35.25889463, 7],
"강서구" : [ 128.8924423, 35.13837168, 7],
"연제구" : [ 129.0829344, 35.18241804, 7],
"수영구" : [ 129.1111625, 35.16133249, 7],
"사상구" : [ 128.9865939, 35.15803505, 7],
"기장군" : [ 129.224475, 35.24135 , 7],
},
"대구광역시" : {
"미선택" : [ 128.5936057, 35.86653525 , 9],
"중구" : [ 128.5936057, 35.86653525, 7],
"동구" : [ 128.6856499, 35.93444401, 7],
"서구" : [ 128.5496976, 35.87500168, 7],
"남구" : [ 128.5853297, 35.83517828, 7],
"북구" : [ 128.5772056, 35.92892764, 7],
"수성구" : [ 128.6612732, 35.83384974, 7],
"달서구" : [ 128.529204, 35.82748641, 7],
"달성군" : [ 128.4982969, 35.7596109, 7],
},
"인천광역시" : {
"미선택" : [ 126.66832787491965, 37.45983498861199, 10],
"중구" : [ 126.4828638, 37.46909379, 7],
"동구" : [ 126.6395434, 37.48319411, 7],
"미추홀구" : [ 126.6646576, 37.45259376, 7],
"연수구" : [ 126.6494242, 37.39619493, 7],
"남동구" : [ 126.7264666, 37.43135604, 7],
"부평구" : [ 126.7212083, 37.49666082, 7],
"계양구" : [ 126.7347032, 37.55729939, 7],
"서구" : [ 126.6563686, 37.55783907, 7],
"남구" : [ 126.6502972, 37.46369169, 7],
"강화군" : [ 126.45730005738866, 37.68192191125021, 9],
"옹진군" : [ 126.6388889, 37.443725 , 7],
},
"광주광역시" : {
"미선택" : [ 126.9494622, 35.11738405, 9],
"동구" : [ 126.9494622, 35.11738405, 7],
"서구" : [ 126.8507245, 35.13569669, 7],
"남구" : [ 126.8567385, 35.09405737, 7],
"북구" : [ 126.9254668, 35.19324913, 7],
"광산구" : [ 126.752903, 35.16504314, 7],
},
"대전광역시" : {
"미선택" : [ 127.4750627, 36.32396534, 9],
"동구" : [ 127.4750627, 36.32396534, 7],
"중구" : [ 127.4110567, 36.28087229, 7],
"서구" : [ 127.3451254, 36.28026323, 7],
"유성구" : [ 127.333298, 36.37682167, 7],
"대덕구" : [ 127.4401591, 36.41219042, 7],
},
"울산광역시" : {
"미선택" : [ 129.3082427, 35.5710483, 9],
"중구" : [ 129.3082427, 35.5710483, 7],
"남구" : [ 129.3281901, 35.51605166, 7],
"동구" : [ 129.4260695, 35.52558, 7],
"북구" : [ 129.3798015, 35.6100624, 7],
"울주군" : [ 129.1868265, 35.54669692, 7],
},
"세종특별자치시" : {
"세종특별자치시" : [ 127.258722, 36.56072897, 9]
},
"경기도" : {
"미선택" : [ 127.39154661008746, 37.427936253223265, 11],
"수원시" : [ 127.0122222, 37.30101111, 9 ],
"성남시" : [ 127.1477194, 37.44749167, 9 ],
"의정부시" : [ 127.0684277, 37.73619293, 9 ],
"안양시" : [ 126.9533556, 37.3897, 9 ],
"부천시" : [ 126.7887094, 37.5042629, 9 ],
"광명시" : [ 126.8646995, 37.44516419, 9 ],
"평택시" : [ 126.9877522, 37.0118376 ],
"동두천시" : [ 127.0779034, 37.91654298, 9 ],
"안산시" : [ 126.8468194, 37.29851944, 9 ],
"고양시" : [ 126.7770556, 37.65590833, 9 ],
"과천시" : [ 127.0026802, 37.43384612, 9 ],
"구리시" : [ 127.1312301, 37.59922784, 9 ],
"남양주시" : [ 127.2436444, 37.66255685, 9 ],
"오산시" : [ 127.0513236, 37.16329326, 9 ],
"시흥시" : [ 126.7884122, 37.38940556, 9 ],
"군포시" : [ 126.9211378, 37.34348472, 9 ],
"의왕시" : [ 126.9896417, 37.36239655, 9 ],
"하남시" : [ 127.205944, 37.5228201 ],
"용인시" : [ 127.2038444, 37.23147778, 9 ],
"파주시" : [ 126.8108037, 37.85624554, 9 ],
"이천시" : [ 127.4809313, 37.2098301 ],
"안성시" : [ 127.3027607, 37.03502502, 9 ],
"김포시" : [ 126.6263868, 37.68179015, 9 ],
"화성시" : [ 126.8748706, 37.16523209, 9 ],
"광주시" : [ 127.3011721, 37.40312001, 9 ],
"양주시" : [ 127.0011552, 37.80869566, 9 ],
"포천시" : [ 127.2504236, 37.96989231, 9 ],
"여주시" : [ 127.6156731, 37.30250497, 9 ],
"가평군" : [ 127.450192, 37.81856681, 9 ],
"양평군" : [ 127.5791946, 37.51803657, 9 ],
"연천군" : [ 127.0770667, 38.09336389, 9 ],
},
"강원도" : {
"미선택" : [ 127.12317975612937, 36.016711825127636, 11],
"춘천시" : [ 127.7399546, 37.88984997, 9 ],
"원주시" : [ 127.9295396, 37.30825853, 9 ],
"강릉시" : [ 128.8322214, 37.70920125, 9 ],
"동해시" : [ 129.055639, 37.50672984, 9 ],
"태백시" : [ 128.9800625, 37.17236519, 9 ],
"속초시" : [ 128.5195498, 38.1760275, 9 ],
"삼척시" : [ 129.1674889, 37.44708611, 9 ],
"홍천군" : [ 128.074507, 37.74486679, 9 ],
"횡성군" : [ 128.0770646, 37.5091607, 9 ],
"영월군" : [ 128.4999342, 37.20404507, 9 ],
"평창군" : [ 128.4827677, 37.55699072, 9 ],
"정선군" : [ 128.7390663, 37.37878577, 9 ],
"철원군" : [ 127.398991, 38.23902719, 9 ],
"화천군" : [ 127.6852023, 38.13843323, 9 ],
"양구군" : [ 128.000222, 38.17567667, 9 ],
"인제군" : [ 128.2647172, 38.06477754, 9 ],
"고성군" : [ 128.4110731, 38.36284879, 9 ],
"양양군" : [ 128.5949493, 38.00453158, 9 ],
},
"충청북도" : {
"미선택" : [ 127.79255408173366, 36.77775337994217, 11],
"청주시" : [ 127.5117306, 36.58399722, 9 ],
"충주시" : [ 127.8955587, 37.01523811, 9 ],
"제천시" : [ 128.1409071, 37.06007228, 9 ],
"보은군" : [ 127.7293296, 36.48995371, 9 ],
"옥천군" : [ 127.6565891, 36.32045893, 9 ],
"영동군" : [ 127.8142658, 36.15967356, 9 ],
"증평군" : [ 127.6046043, 36.78649107, 9 ],
"진천군" : [ 127.4404342, 36.87102031, 9 ],
"괴산군" : [ 127.8295825, 36.76968609, 9 ],
"음성군" : [ 127.6141838, 36.97625907, 9 ],
"단양군" : [ 128.3878861, 36.99451168, 9 ],
},
"충청남도" : {
"미선택" : [ 127.35233920735703, 36.45690483533581, 11],
"천안시" : [ 127.1524667, 36.804125, 9 ],
"공주시" : [ 127.0751478, 36.47990652, 9 ],
"보령시" : [ 126.5942136, 36.34031922, 9 ],
"아산시" : [ 126.980082, 36.80735134, 9 ],
"서산시" : [ 126.463562, 36.78409691, 9 ],
"당진시" : [ 126.6302528, 36.89075 , 9 ],
"논산시" : [ 127.1577061, 36.19090514, 9 ],
"계룡시" : [ 127.2344204, 36.29160368, 9 ],
"금산군" : [ 127.4782928, 36.11903032, 9 ],
"서천군" : [ 126.7049244, 36.10661218, 9 ],
"청양군" : [ 126.853086, 36.43059194, 9 ],
"홍성군" : [ 126.6258234, 36.57009036, 9 ],
"예산군" : [ 126.7842651, 36.67064001, 9 ],
"태안군" : [ 126.2808032, 36.70386085, 9 ],
"부여군" : [ 126.9118639, 36.27282222, 9 ],
},
"전라북도" : {
"미선택" : [ 127.07737136324491, 35.63605805905352, 11],
"전주시" : [ 127.1219194, 35.80918889, 9 ],
"익산시" : [ 126.989503, 36.02314348, 9 ],
"정읍시" : [ 126.9058697, 35.6026358, 9 ],
"남원시" : [ 127.4419364, 35.42253429, 9 ],
"군산시" : [ 126.7388444, 35.96464167, 9 ],
"김제시" : [ 126.8948294, 35.80671465, 9 ],
"완주군" : [ 127.2152214, 35.91876217, 9 ],
"진안군" : [ 127.4300802, 35.82889325, 9 ],
"무주군" : [ 127.7129494, 35.93937729, 9 ],
"장수군" : [ 127.5443403, 35.65753552, 9 ],
"임실군" : [ 127.2366564, 35.5982329, 9 ],
"순창군" : [ 127.0900463, 35.43362681, 9 ],
"고창군" : [ 126.6160791, 35.44819175, 9 ],
"부안군" : [ 126.6444614, 35.67792233, 9 ],
},
"전라남도" : {
"미선택" : [ 126.9842629432299, 34.805397241331605, 11],
"목포시" : [ 126.3918464, 34.80376301, 9 ],
"여수시" : [ 127.6535295, 34.69839004, 9 ],
"순천시" : [ 127.3891379, 34.99477437, 9 ],
"나주시" : [ 126.7204163, 34.98859351, 9 ],
"광양시" : [ 127.6551052, 35.02193047, 9 ],
"담양군" : [ 126.9952608, 35.29155078, 9 ],
"곡성군" : [ 127.2635431, 35.21663483, 9 ],
"구례군" : [ 127.5030878, 35.23679742, 9 ],
"고흥군" : [ 127.3146561, 34.59855727, 9 ],
"보성군" : [ 127.1621881, 34.81440563, 9 ],
"화순군" : [ 127.0335393, 35.00825383, 9 ],
"장흥군" : [ 126.9215255, 34.67668231, 9 ],
"강진군" : [ 126.7721471, 34.62048424, 9 ],
"영암군" : [ 126.6307699, 34.79957499, 9 ],
"무안군" : [ 126.4257885, 34.95327665, 9 ],
"함평군" : [ 126.5356108, 35.11269517, 9 ],
"영광군" : [ 126.4531334, 35.27849439, 9 ],
"장성군" : [ 126.7685691, 35.32960098, 9 ],
"완도군" : [ 126.7769747, 34.29559715, 9 ],
"진도군" : [ 126.2151837, 34.43942431, 9 ],
"신안군" : [ 126.0495583, 34.81262298, 9 ],
"해남군" : [ 126.6012889, 34.57043611, 9 ],
},
"경상북도" : {
"미선택" : [ 128.81204394329464, 36.353709379365114, 11],
"포항시" : [ 129.3616667, 36.00568611, 9 ],
"경주시" : [ 129.235873, 35.826691, 9 ],
"김천시" : [ 128.0778448, 36.06051569, 9 ],
"안동시" : [ 128.7800407, 36.58030946, 9 ],
"구미시" : [ 128.3554644, 36.20734109, 9 ],
"영주시" : [ 128.5976539, 36.87055896, 9 ],
"영천시" : [ 128.9426073, 36.01581613, 9 ],
"상주시" : [ 128.0669903, 36.42955021, 9 ],
"문경시" : [ 128.1486973, 36.69080984, 9 ],
"경산시" : [ 128.809053, 35.83410302, 9 ],
"군위군" : [ 128.6481186, 36.17011731, 9 ],
"의성군" : [ 128.6149052, 36.36201086, 9 ],
"청송군" : [ 129.0574327, 36.35707112, 9 ],
"영양군" : [ 129.145057, 36.69647487, 9 ],
"영덕군" : [ 129.3173817, 36.48249776, 9 ],
"청도군" : [ 128.7865755, 35.67292328, 9 ],
"고령군" : [ 128.3067568, 35.73721147, 9 ],
"성주군" : [ 128.233394, 35.90724515, 9 ],
"칠곡군" : [ 128.4625866, 36.01551093, 9 ],
"예천군" : [ 128.4224645, 36.65391037, 9 ],
"봉화군" : [ 128.9129168, 36.93415717, 9 ],
"울진군" : [ 129.312205, 36.90408324, 9 ],
"울릉군" : [ 130.8641677, 37.50196388, 9 ],
},
"경상남도" : {
"미선택" : [ 128.53769042792499, 35.44400982880079, 11],
"창원시" : [ 128.6401544, 35.2540033 , 9 ],
"진주시" : [ 128.1297644, 35.20514752 , 9 ],
"통영시" : [ 128.3741039, 34.8294728 , 9 ],
"사천시" : [ 128.0376567, 35.04971902 , 9 ],
"김해시" : [ 128.8452254, 35.27216917 , 9 ],
"밀양시" : [ 128.7896424, 35.49850039 , 9 ],
"거제시" : [ 128.6231604, 34.8704778 , 9 ],
"양산시" : [ 129.0410367, 35.40190499 , 9 ],
"의령군" : [ 128.2771012, 35.39245631 , 9 ],
"함안군" : [ 128.430905, 35.29101218 , 9 ],
"창녕군" : [ 128.4930122, 35.50827649 , 9 ],
"고성군" : [ 128.2906976, 35.01630929 , 9 ],
"남해군" : [ 127.9411169, 34.81831061 , 9 ],
"하동군" : [ 127.7789218, 35.13838231 , 9 ],
"산청군" : [ 127.8843644, 35.36863784 , 9 ],
"함양군" : [ 127.7220744, 35.55172723 , 9 ],
"거창군" : [ 127.9041319, 35.73261316 , 9 ],
"합천군" : [ 128.1415535, 35.57666246 , 9 ],
},
"제주특별자치도" : {
"미선택" : [ 126.5808984756216, 33.357067644200384, 10],
"제주시" : [ 126.5294524, 33.44212371, 9 ],
"서귀포시" : [ 126.5812981, 33.32493064, 9 ],
}
}
\ No newline at end of file
export let DISTRICTS = {
"name": "korea-administrative-district",
"version": "20160125",
"url": "https://github.com/cosmosfarm/korea-administrative-district",
"data":[
{"미선택":[
"미선택"
]},
{"서울특별시":[
"미선택", "종로구", "중구", "용산구", "성동구", "광진구", "동대문구", "중랑구", "성북구", "강북구", "도봉구", "노원구", "은평구", "서대문구", "마포구", "양천구", "강서구", "구로구", "금천구", "영등포구", "동작구", "관악구", "서초구", "강남구", "송파구", "강동구"
]},
{"부산광역시":[
"미선택", "중구", "서구", "동구", "영도구", "부산진구", "동래구", "남구", "북구", "강서구", "해운대구", "사하구", "금정구", "연제구", "수영구", "사상구", "기장군"
]},
{"인천광역시":[
"미선택", "중구", "동구", "남구", "연수구", "남동구", "부평구", "계양구", "서구", "강화군", "옹진군"
]},
{"대구광역시":[
"미선택", "중구", "동구", "서구", "남구", "북구", "수성구", "달서구", "달성군"
]},
{"광주광역시":[
"미선택", "동구", "서구", "남구", "북구", "광산구"
]},
{"대전광역시":[
"미선택", "동구", "중구", "서구", "유성구", "대덕구"
]},
{"울산광역시":[
"미선택", "중구", "남구", "동구", "북구", "울주군"
]},
{"세종특별자치시":[
"미선택", "세종특별자치시"
]},
{"경기도":[
"미선택", "가평군", "고양시", "과천시", "광명시", "광주시", "구리시", "군포시", "김포시", "남양주시", "동두천시", "부천시", "성남시", "수원시", "시흥시", "안산시", "안성시", "안양시", "양주시", "양평군", "여주시", "연천군", "오산시", "용인시", "의왕시", "의정부시", "이천시", "파주시", "평택시", "포천시", "하남시", "화성시"
]},
{"강원도":[
"미선택", "원주시", "춘천시", "강릉시", "동해시", "속초시", "삼척시", "홍천군", "태백시", "철원군", "횡성군", "평창군", "영월군", "정선군", "인제군", "고성군", "양양군", "화천군", "양구군"
]},
{"충청북도":[
"미선택", "청주시", "충주시", "제천시", "보은군", "옥천군", "영동군", "증평군", "진천군", "괴산군", "음성군", "단양군"
]},
{"충청남도":[
"미선택", "천안시", "공주시", "보령시", "아산시", "서산시", "논산시", "계룡시", "당진시", "금산군", "부여군", "서천군", "청양군", "홍성군", "예산군", "태안군"
]},
{"경상북도":[
"미선택", "포항시", "경주시", "김천시", "안동시", "구미시", "영주시", "영천시", "상주시", "문경시", "경산시", "군위군", "의성군", "청송군", "영양군", "영덕군", "청도군", "고령군", "성주군", "칠곡군", "예천군", "봉화군", "울진군", "울릉군"
]},
{"경상남도":[
"미선택", "창원시", "김해시", "진주시", "양산시", "거제시", "통영시", "사천시", "밀양시", "함안군", "거창군", "창녕군", "고성군", "하동군", "합천군", "남해군", "함양군", "산청군", "의령군"
]},
{"전라북도":[
"미선택", "전주시", "익산시", "군산시", "정읍시", "완주군", "김제시", "남원시", "고창군", "부안군", "임실군", "순창군", "진안군", "장수군", "무주군"
]},
{"전라남도":[
"미선택", "여수시", "순천시", "목포시", "광양시", "나주시", "무안군", "해남군", "고흥군", "화순군", "영암군", "영광군", "완도군", "담양군", "장성군", "보성군", "신안군", "장흥군", "강진군", "함평군", "진도군", "곡성군", "구례군"
]},
{"제주특별자치도":[
"미선택", "제주시", "서귀포시"
]}
]
}
\ No newline at end of file
<style>
#map_bg {
box-sizing: border-box;
justify-content: center;
display: flex;
height: 100vh;
background-color:#edeff2;
}
#map {
margin-top: 50px;
box-sizing: border-box;
display: flex;
height: 80vh;
width: 60vw;
background-color:#edeff2;
border-radius: 10px;
border: 1px solid black;
box-shadow: 0 10px 20px rgb(0 0 0 / 15%);
}
</style>
<script>
import Info from './SideItems/Info.svelte';
import Festalist from './SideItems/Festalist.svelte';
import Arealist from './SideItems/Arealist.svelte';
import { COORDINATES } from "./Data/coordinates";
import { DisplayedFestas } from "./Stores/DisplayedFestas";
var {kakao} = window;
var ShowArea = false;
var ShowFesta = false;
var ShowInfo = false;
var Festa = {};
var markers = [];
var infowindows = [];
var map;
function createMap() {
var mapContainer = document.getElementById('map'), // 지도를 표시할 div
mapOption = {
center: new kakao.maps.LatLng(36.46682, 127.37865), // 지도의 중심좌표
level: 12, // 지도의 확대 레벨
mapTypeId : kakao.maps.MapTypeId.ROADMAP // 지도종류
};
markers= [];
map = new kakao.maps.Map(mapContainer, mapOption); // 카카오 지도
}
$: drawMarkers($DisplayedFestas);
function drawMarkers (data) {
let len = data.length >= 9 ? 9 : data.length;
markers.forEach( mk => {
mk.setMap(null);
});
infowindows.forEach( iw => {
iw.close();
});
markers, infowindows = [], [];
for(var i = 0; i < len; i++){
// 지도에 마커를 생성하고 표시한다
let marker = new kakao.maps.Marker({
position: new kakao.maps.LatLng(data[i].mapy, data[i].mapx), // 마커의 좌표
map: map // 마커를 표시할 지도 객체
});
let infowindow = new kakao.maps.InfoWindow({
content : '<div style="padding:5px;white-space:nowrap;">' + data[i].title + '</div>' // 인포윈도우에 표시할 내용
});
infowindow.open(map, marker);
// 마커 클릭 시 이벤트
let showInfo = function(festa) {
return function() {
Festa = festa;
ShowInfo = true;
console.log(Festa);
}
};
kakao.maps.event.addListener(marker, 'click', showInfo(data[i]));
infowindows.push(infowindow);
markers.push(marker);
};
}
function moveTo(district, city) {
let [x, y, level] = COORDINATES[district][city];
var moveLatLon = new kakao.maps.LatLng(y, x);
map.setLevel(level);
map.panTo(moveLatLon);
}
function closeBars() {
ShowArea = false;
ShowFesta = false;
ShowInfo = false;
}
</script>
<svelte:window on:load={createMap}></svelte:window>
<Festalist bind:sidebar_show={ShowFesta}/>
<Arealist bind:sidebar_show={ShowArea} {moveTo}/>
<Info bind:sidebar_show={ShowInfo} bind:festa={Festa}/>
<div id="map_bg">
<div id="map"></div>
</div>
<script>
import Menuitems from './Menuitems.svelte'
// 메뉴 바 항목들
const navItems = [
{ label: "TFT 소개", href: "#article1" },
{ label: "행사 탐색", href: "#article2" },
{ label: "행사 정보", href: "#article3" },
{ label: "기술 스택", href: "#article4" }
];
</script>
<style>
nav {
background-color: #edeff2;
font-family: "Helvetica Neue", "Helvetica", "Arial", sans-serif;
height: 70px;
/* width: 50vw; */
top: 0;
}
.inner {
max-width: 700px;
padding-left: 10px;
padding-right: 10px;
margin: auto;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
height: 100%;
}
.logo img{
display: flex;
width: 120px;
left: 20px;
top: 15px;
margin-right: 400px;
}
.navbar-list {
display: flex;
padding: 0;
width: 100%;
justify-content: space-between;
margin: 0;
}
</style>
<nav id="nav">
<div class="inner">
<div class="logo"><img alt="Logo" src="./public/TFTlogo.png"></div>
<ul class='navbar-list'>
{#each navItems as item}
<Menuitems {item}/>
{/each}
</ul>
</div>
</nav>
\ No newline at end of file
<style>
li {
display: flex;
list-style-type: none;
position: relative;
margin-left: 50px;
height: 45px;
white-space: nowrap;
align-items: center;
}
li:before {
content: "";
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 1px;
}
a {
color: #000000;
text-decoration: none;
display: inline-flex;
padding: 0 10px;
font-size: 20px;
}
@media only screen and (max-width: 767px) {
a {
display: none;
}
}
.onmouse {
text-decoration: underline;
}
</style>
<script>
export let item;
let onmouse;
function enter() {
onmouse = true;
}
function leave() {
onmouse = false;
}
</script>
<li on:mouseenter={enter} on:mouseleave={leave} >
<a href={item.href} class:onmouse>{item.label}</a>
</li>
\ No newline at end of file
<script>
import { fly } from 'svelte/transition'
import SideBar from './SideBar.svelte';
var icon_show = true;
var sidebar_show = false;
function showBar() {
sidebar_show = true;
}
function hide() {
if (window.scrollY < 400) {
icon_show = true;
} else {
icon_show = false;
sidebar_show = false;
}
}
import { DISTRICTS } from '../Data/district'
import { District, City, Changed } from '../Stores/DistrictStore'
export var moveTo;
let curDisrict = {"미선택" : ["미선택"]};
let curCity = "미선택";
$: if(Object.keys(curDisrict)[0] != "미선택") {
District.set(Object.keys(curDisrict)[0]);
} else {
District.set("");
};
$: if(curCity != "미선택") {
City.set(curCity);
} else {
City.set("");
}
function setDistrict(district) {
curDisrict = district;
if(Object.keys(curDisrict)[0] == "세종특별자치시")
curCity = "세종특별자치시";
else
curCity = "미선택";
moveTo(Object.keys(curDisrict)[0], curCity);
Changed.set(true);
}
function setCity(city) {
curCity = city;
moveTo(Object.keys(curDisrict)[0], curCity);
Changed.set(true);
}
</script>
<style>
.sidebtn {
border-radius: 5px;
border: 0px;
width: 70px;
height: 70px;
position: fixed;
left: -20px;
top: 120px;
padding-right: 10px;
text-align: right;
background-color: #b71c1c;
color: #ffffff;
box-shadow: 0 10px 20px rgb(0 0 0 / 15%);
}
.sidebtn:focus {
background-color: #ef5350;
}
.sidebtn:hover {
background-color: #d32f2f;
}
.areas {
display: flex;
border-bottom: #999999 solid 1px;
width: 100%;
flex-wrap: wrap;
justify-content: space-evenly;
}
.areatitle {
display: inline-block;
text-align:center;
width: 200px;
}
.district {
display: inline-block;
text-align:center;
width: 125px;
margin: 5px;
border: 1px solid black;
border-radius: 5px;
padding-top: 5px;
padding-bottom: 5px;
}
.district:hover {
background-color: #ffebee;
}
.district:focus {
background-color: #ffcdd2;
}
.district.selected{
background-color: #ffcdd2;
}
.city {
display: inline-block;
text-align:center;
width: 125px;
margin: 5px;
border: 1px solid black;
border-radius: 5px;
padding-top: 5px;
padding-bottom: 5px;
}
.city:hover {
background-color: #ffebee;
}
.city:focus {
background-color: #ffcdd2;
}
.city.selected{
background-color: #ffcdd2;
}
</style>
<svelte:window on:scroll={hide}></svelte:window>
{#if (icon_show)}
<button class="sidebtn"
transition:fly="{{ x : -50, duration : 400}}"
on:click={showBar}>
지역<br>선택
</button>
{/if}
<SideBar bind:show={sidebar_show}>
<div class="areas">
<div class="areatitle">광역시/도</div>
{#each DISTRICTS.data as d}
<div class="{Object.keys(curDisrict)[0] == Object.keys(d)[0] ? 'district selected' : 'district'}"
on:click={() => {setDistrict(d)}}>
{Object.keys(d)[0]}
</div><br>
{/each}
</div><br>
<div class="areas">
<div class="areatitle">시/군/구</div>
{#each curDisrict[Object.keys(curDisrict)[0]] as c}
<div class="{curCity == c ? 'city selected' : 'city'}"
on:click={() => {setCity(c)}}>
{c}
</div><br>
{/each}
</div>
</SideBar>
\ No newline at end of file
<script>
import { fly } from 'svelte/transition'
let show = false;
function scrollUp() {
document.body.scrollIntoView({behavior: "smooth"})
}
function hide() {
if (window.scrollY > 60) {
show = true
} else {
show = false
}
}
</script>
<style>
#backtotop {
border-radius: 100%;
width: 50px;
height: 50px;
position: fixed;
right: 4%;
bottom: 10%;
}
</style>
<svelte:window on:scroll={hide}></svelte:window>
{#if (show)}
<button id="backtotop"
transition:fly="{{ y : 200, duration:400}}"
on:click={scrollUp}>
</button>
{/if}
\ No newline at end of file
<script>
import { fly } from 'svelte/transition'
import SideBar from './SideBar.svelte';
let icon_show = true;
let sidebar_show = false;
function showBar() {
sidebar_show = true;
}
function hide() {
if (window.scrollY < 400) {
icon_show = true;
} else {
icon_show = false;
sidebar_show = false;
}
}
import { District, City, Changed } from '../Stores/DistrictStore';
import { AllFestas } from "../Stores/AllFestas";
import { DisplayedFestas } from "../Stores/DisplayedFestas";
let festaChecked = [];
$: festaList = $AllFestas.filter( v => {
if(v.addr1) {
let district = v.addr1.split(" ")[0];
let city = v.addr1.split(" ")[1];
return ($District === "" || district === $District) &&
($City === "" || city === $City);
} else {
return false;
}
});
$: festaParsed = festaList.map( (v, i) => {
return { "id" : i, "title" : v.title, "addr1" : v.addr1, "contentid" : v.contentid, "checked" : false }
});
$: if ($Changed) {
let len = festaList.length >= 9 ? 9 : festaList.length;
festaChecked = [];
for(let i = 0; i < len; i++)
check(i);
}
$: DisplayedFestas.set(festaChecked);
function check(idx) {
if (!festaParsed[idx].checked) {
if(festaChecked.length <= 8) {
festaParsed[idx].checked = true;
festaChecked = festaChecked.concat(festaList[idx]);
} else {
alert("9개 이상 선택하실 수 없습니다.");
}
} else {
festaParsed[idx].checked = false;
festaChecked = festaChecked.filter( v => {
return v.contentid !== festaParsed[idx].contentid;
});
}
}
</script>
<style>
.sidebtn {
border-radius: 5px;
border: 0px;
width: 70px;
height: 70px;
position: fixed;
left: -20px;
top: 200px;
padding-right: 10px;
text-align: right;
background-color: #e65100;
color: #ffffff;
box-shadow: 0 10px 20px rgb(0 0 0 / 15%);
}
.sidebtn:focus {
background-color: #f57c00;
}
.sidebtn:hover {
background-color: #ef6c00;
}
.festa {
border: 1px solid #aaa;
border-radius: 2px;
box-shadow: 2px 2px 8px rgba(0,0,0,0.1);
padding: 2px;
margin-bottom: 5px;
}
.festa:hover {
background-color: #fff3e0;
}
.festa:focus {
background-color: #ffe0b2;
}
.selected {
background-color: #ffe0b2;
border: 1px solid #aaa;
border-radius: 2px;
box-shadow: 2px 2px 8px rgba(0,0,0,0.1);
padding: 2px;
margin-bottom: 5px;
}
.title {
font-weight: bold;
border-bottom: 2px solid #ff3e00;
}
.addr {
display: flex;
align-items: center;
}
.addr img {
width: 20px;
height: 20px;
}
</style>
<svelte:window on:scroll={hide}></svelte:window>
{#if (icon_show)}
<button class="sidebtn"
transition:fly="{{ x : -50, duration : 400}}"
on:click={showBar}>
행사<br>목록
</button>
{/if}
<SideBar bind:show={sidebar_show}>
{#if festaParsed.length > 0}
{#each festaParsed as festa}
<div class="{festa.checked ? "selected" : "festa"}"
on:click={() => {check(festa.id)}}>
<div class="title">{festa.title}</div>
<div class="addr"><img alt="pin" src="/public/map-pin.png"><div>{festa.addr1}</div></div>
</div>
{/each}
{:else}
개최되는 축제가 없습니다.
{/if}
</SideBar>
\ No newline at end of file
<script>
import SideBar from "./SideBar.svelte"
export let festa;
export let sidebar_show = false;
let side = "right";
function hide() {
if (window.scrollY > 400) {
sidebar_show = false;
}
}
</script>
<style>
.title {
font-size: 18pt;
font-weight: bold;
text-align: center;
}
.content {
padding: 0.5rem 0.5rem 0.5rem;
text-align: center;
}
.info img {
max-height: 20rem;
}
</style>
<svelte:window on:scroll={hide}></svelte:window>
<SideBar bind:show={sidebar_show} {side}>
<div class="info">
<div class="title">{festa.title}</div>
<img alt="festaImg" src={festa.firstimage}><br>
<div class="content">
개최지 : {festa.addr1}<br>
전화번호 : {festa.tel}<br>
<!-- 행사 시작일 : {festa.startdate}<br>
행사 시작일 : {festa.enddate}<br>
날씨 : {festa.weather 어쩌구} -->
</div>
</div>
</SideBar>
<script>
import { fly } from 'svelte/transition';
export let show = true;
export let side = "left";
</script>
<style>
.nav {
overflow-y: auto;
overflow-x: hidden;
}
.left {
position: fixed;
top: 0;
left: 0;
height: 100%;
border-right: 1px solid #aaa;
background: #fff;
overflow-y: auto;
width: 330px;
z-index: 900;
white-space: pre-line;
}
.right {
position: fixed;
top: 0;
right: 0;
height: 100%;
border-left: 1px solid #aaa;
background: #fff;
overflow-y: auto;
width: 560px;
z-index: 900;
}
.navtop {
display: flex;
width: 100%;
height: 60px;
background-color: white;
font-size: 30pt;
color: #AAAAAA;
justify-content: right;
padding: 5px 5px 5px;
border-bottom: #999999 solid 1px;
}
.bg {
position: fixed;
display: block;
width: 100vw;
height: 100vw;
left: 0;
top: 0;
background-color: rgba(0, 0, 0, 10%);
z-index: 800;
}
.navitems {
display: flex;
flex-direction: column
}
.left .navitems {
padding: 2rem 1rem 0.6rem;
}
</style>
{#if show}
{#if side == "right"}
<div class="bg" on:click={() => {show = false;}}></div>
{/if}
<nav class={"nav " + side} transition:fly={{x: (side == "left" ? -400 : 600), opacity: 1, duration: 800}}>
{#if side == "left"}
<div class="navtop" on:click={() => {show = false;}}
style="justify-content:{side == "left" ? "right" : "left"}; cursor:pointer;">
{ side == "left" ? "<" : ">" }
</div>
{/if}
<div class="navitems">
<slot>
</slot>
</div>
</nav>
{/if}
\ No newline at end of file
import { writable } from 'svelte/store';
function create() {
const { subscribe, set } = writable([]);
return {
subscribe,
set: (e) => set(e),
}
}
export const AllFestas = create();
\ No newline at end of file
import { writable } from 'svelte/store';
function create() {
const { subscribe, set} = writable([]);
return {
subscribe,
set: (e) => set(e),
}
}
export const DisplayedFestas = create();
\ No newline at end of file
import { writable } from 'svelte/store';
export const District = writable("미선택");
export const City = writable("미선택");
export const Changed = writable("true");
\ No newline at end of file
import App from './App.svelte';
const app = new App({
target: document.body,
props: {
// name: 'world'
}
});
export default app;
\ No newline at end of file
<h1><%= message %></h1>
<h2><%= error.status %></h2>
<pre><%= error.stack %></pre>
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<h1><%= title %></h1>
<p>Welcome to <%= title %></p>
</body>
</html>
const path = require('path');
const mode = process.env.NODE_ENV || 'development';
const prod = mode === 'production';
module.exports = {
entry: {
bundle: ['./src/main.js']
},
resolve: {
alias: {
svelte: path.resolve('node_modules', 'svelte')
},
extensions: ['.mjs', '.js', '.svelte'],
mainFields: ['svelte', 'browser', 'module', 'main']
},
output: {
path: __dirname + '/public/build',
filename: '[name].js',
chunkFilename: '[name].[id].js'
},
module: {
rules: [
{
test: /\.svelte$/,
use: {
loader: 'svelte-loader',
options: {
emitCss: true,
hotReload: true
}
}
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
},
mode,
plugins: [],
devtool: prod ? false: 'source-map'
};