@@ -0,0 +1 @@ | |||||
node_modules |
@@ -0,0 +1,32 @@ | |||||
const Sequelize = require('sequelize') | |||||
const sequelize = new Sequelize('postgres://johntitor@localhost:5432/mydb') | |||||
sequelize.authenticate().then(() => { | |||||
console.log('Connection has been established successfully.') | |||||
}) | |||||
.catch(err => { | |||||
console.error('Unable to connect to the database:', err) | |||||
}) | |||||
const Posts = sequelize.define('posts', { | |||||
title: { | |||||
type: Sequelize.STRING, | |||||
allowNull: false | |||||
}, | |||||
username: { | |||||
type: Sequelize.STRING, | |||||
allowNull: false | |||||
}, | |||||
arttext: { | |||||
type: Sequelize.STRING, | |||||
allowNull: false | |||||
}, | |||||
}) | |||||
Posts.sync() | |||||
module.exports = {sequelize, Posts} |
@@ -0,0 +1,21 @@ | |||||
{ | |||||
"name": "examp", | |||||
"version": "1.0.0", | |||||
"description": "", | |||||
"main": "server.js", | |||||
"scripts": { | |||||
"devStart": "nodemon server.js" | |||||
}, | |||||
"author": "RinRi", | |||||
"license": "GPL-3.0-or-later", | |||||
"dependencies": { | |||||
"ejs": "^3.1.6", | |||||
"express": "^4.17.1", | |||||
"pg": "^8.6.0", | |||||
"pg-hstore": "^2.3.4", | |||||
"sequelize": "^6.6.4" | |||||
}, | |||||
"devDependencies": { | |||||
"nodemon": "^2.0.7" | |||||
} | |||||
} |
@@ -0,0 +1,32 @@ | |||||
const express = require('express') | |||||
const router = express.Router() | |||||
const {sequelize, Posts} = require("../db.js") | |||||
router.get('/', async (req, res) => { | |||||
const articles = await Posts.findAll() | |||||
page = 1 | |||||
if(req.query.page != undefined) | |||||
page = req.query.page | |||||
console.log(articles) | |||||
res.render("articles", { articles: articles, page: page, col: 2 }) | |||||
}) | |||||
router.get('/new', (req, res) => { | |||||
res.render("new") | |||||
}) | |||||
router.post('/', async (req, res) => { | |||||
try { | |||||
const newPost = new Posts(req.body) | |||||
await newPost.save() | |||||
res.redirect("/articles") | |||||
} catch(error) { | |||||
console.error(error) | |||||
} | |||||
}) | |||||
module.exports = router |
@@ -0,0 +1,16 @@ | |||||
const express = require('express') | |||||
const app = express() | |||||
const articleRouter = require('./routes/articles') | |||||
const sequelize = require('./db.js') | |||||
app.set('view engine', 'ejs') | |||||
app.use(express.urlencoded({ extended: false })) | |||||
app.get('/', (req, res) =>{ | |||||
res.render('index') | |||||
}) | |||||
app.use('/articles', articleRouter) | |||||
app.listen(5000) |
@@ -0,0 +1,33 @@ | |||||
<!DOCTYPE html> | |||||
<html lang="en"> | |||||
<head> | |||||
<meta charset="UTF-8"> | |||||
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | |||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> | |||||
<title>Main page</title> | |||||
</head> | |||||
<body> | |||||
<div class="container"> | |||||
<h1>Blog Articles Page <%= page %></h1> | |||||
<% | |||||
let pg = Number(page) | |||||
for(let i = articles.length - 1 - (pg-1)*col; i >= Math.max(0, articles.length - pg*col); --i) | |||||
{ %> | |||||
<div class="card mt-4"> | |||||
<div class="card-body"> | |||||
<h2 class="card-title"> <%= articles[i].title %> </h4> | |||||
<h7 class="card-subtitle text-muted mb-2"> <%= articles[i].username %> </h7> | |||||
<p class="card-text"> <%= articles[i].arttext %> </p> | |||||
</div> | |||||
</div> | |||||
<% } %> | |||||
<div class="mt-5"> | |||||
<a class="btn btn-primary <% if(pg <= 1){ %> disabled <% } %>" href="/articles?page=<%= pg-1 %>" > Previous Page</a> | |||||
<a class="btn btn-primary <% if(pg >= (articles.length)/2) { %> disabled <% } %>" href="/articles?page=<%= pg+1 %>" > Next Page</a> | |||||
</div> | |||||
</div> | |||||
</body> | |||||
</html> |
@@ -0,0 +1,23 @@ | |||||
<!DOCTYPE html> | |||||
<html lang="en"> | |||||
<head> | |||||
<meta charset="UTF-8"> | |||||
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | |||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> | |||||
<title>Main page</title> | |||||
</head> | |||||
<body> | |||||
<div class="container"> | |||||
<div class="wc-msg" style="text-align: center; margin-top: 3rem;"> | |||||
<h1>Welcome!</h1> | |||||
</div> | |||||
<div class="des-msg" style="text-align: center; margin-top: 1rem;"> | |||||
<a class="btn btn-primary" href="/articles/new">Create new article</a> | |||||
<a class="btn btn-secondary" href="/articles">Articles</a> | |||||
</div> | |||||
</div> | |||||
</body> | |||||
</html> |
@@ -0,0 +1,56 @@ | |||||
<!DOCTYPE html> | |||||
<html lang="en"> | |||||
<head> | |||||
<meta charset="UTF-8"> | |||||
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | |||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> | |||||
<title>Main page</title> | |||||
</head> | |||||
<body> | |||||
<div class="container"> | |||||
<div style="margin-top: 3rem;"> | |||||
<h1>New article</h1> | |||||
<form action="/articles" method="POST"> | |||||
<div class="form-group mt-2"> | |||||
<label for="title">Title</label> | |||||
<input required type="text" name="title" id="title" class="form-control"> | |||||
</div> | |||||
<div class="form-group mt-2"> | |||||
<label for="username">Username</label> | |||||
<input required type="text" name="username" id="username" class="form-control" onkeyup="validateUsername()"> | |||||
</div> | |||||
<div class="form-group mt-2"> | |||||
<label for="arttext">Article Text</label> | |||||
<input required type="text" name="arttext" id="arttext" class="form-control"> | |||||
</div> | |||||
<div class="mt-4"> | |||||
<a href="/" class="btn btn-secondary">Cancel</a> | |||||
<button id="save" class="btn btn-primary">Save</button> | |||||
</div> | |||||
</form> | |||||
</div> | |||||
</div> | |||||
<script> | |||||
function validateUsername(){ | |||||
let username = document.getElementById("username").value | |||||
var usernameRegex = /^[a-zA-Z]+$/ | |||||
if(usernameRegex.test(username) && username.length != 0 ) | |||||
{ | |||||
document.getElementById("save").classList.remove("disabled") | |||||
} | |||||
else | |||||
{ | |||||
document.getElementById("save").classList.add("disabled") | |||||
} | |||||
} | |||||
console.log('asdad') | |||||
validateUsername() | |||||
</script> | |||||
</body> | |||||
</html> |