@@ -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> |