Compare commits
14 Commits
fe774158ff
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
c023856981 | ||
|
f2762a02f9 | ||
|
0305c721ba | ||
|
78f5b7acec | ||
|
5435ba2d45 | ||
|
bb72b9d1d5 | ||
|
44b14487bf | ||
|
4f15826cba | ||
|
c34df3560f | ||
|
d5ff307fba | ||
|
34177d6b2d | ||
ebdacff5bc | |||
|
a347e79ded | ||
|
da1ef02782 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -116,3 +116,4 @@ dist
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
||||
|
||||
database/socialbot.db
|
||||
|
6
app.js
6
app.js
@ -4,17 +4,19 @@ var path = require('path');
|
||||
var cookieParser = require('cookie-parser');
|
||||
var bodyParser = require('body-parser');
|
||||
var logger = require('morgan');
|
||||
const fileUpload = require('express-fileupload');
|
||||
|
||||
var indexRouter = require('./routes/index');
|
||||
var usersRouter = require('./routes/user');
|
||||
var messagesRouter = require('./routes/message');
|
||||
var loginRouter = require('./routes/login');
|
||||
var registerRouter = require('./routes/register');
|
||||
var followRouter = require('./routes/follow');
|
||||
|
||||
var app = express();
|
||||
|
||||
const db = require('./models');
|
||||
//db.sequelize.sync({ force: true });
|
||||
// db.sequelize.sync({ force: true });
|
||||
db.sequelize.sync();
|
||||
|
||||
// view engine setup
|
||||
@ -26,6 +28,7 @@ app.use(express.json());
|
||||
app.use(express.urlencoded({ extended: false }));
|
||||
app.use(cookieParser());
|
||||
app.use(bodyParser.urlencoded({ extended: true }));
|
||||
app.use(fileUpload());
|
||||
app.use(express.static(path.join(__dirname, 'public')));
|
||||
|
||||
app.use('/', indexRouter);
|
||||
@ -33,6 +36,7 @@ app.use('/user', usersRouter);
|
||||
app.use('/message', messagesRouter);
|
||||
app.use('/login', loginRouter);
|
||||
app.use('/register', registerRouter);
|
||||
app.use('/follow', followRouter);
|
||||
|
||||
// catch 404 and forward to error handler
|
||||
app.use(function(req, res, next) {
|
||||
|
Binary file not shown.
39
migrations/20220301193849-modify_users_add_fields.js
Normal file
39
migrations/20220301193849-modify_users_add_fields.js
Normal file
@ -0,0 +1,39 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
async up (queryInterface, Sequelize) {
|
||||
/**
|
||||
* Add altering commands here.
|
||||
*
|
||||
* Example:
|
||||
* await queryInterface.createTable('users', { id: Sequelize.INTEGER });
|
||||
*/
|
||||
await queryInterface.addColumn(
|
||||
'Users',
|
||||
'avatar',
|
||||
{
|
||||
type: Sequelize.BLOB,
|
||||
allowNull: true,
|
||||
},
|
||||
);
|
||||
await queryInterface.addColumn(
|
||||
'Users',
|
||||
'bio',
|
||||
{
|
||||
type: Sequelize.TEXT,
|
||||
allowNull: true,
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
async down (queryInterface, Sequelize) {
|
||||
/**
|
||||
* Add reverting commands here.
|
||||
*
|
||||
* Example:
|
||||
* await queryInterface.dropTable('users');
|
||||
*/
|
||||
await queryInterface.removeColumn('Users', 'avatar');
|
||||
await queryInterface.removeColumn('Users', 'bio');
|
||||
}
|
||||
};
|
@ -28,6 +28,7 @@ fs
|
||||
db.Message.belongsTo(db.User, {through: 'UserMessages'});
|
||||
db.User.hasMany(db.Session);
|
||||
db.Session.belongsTo(db.User);
|
||||
db.User.belongsToMany(db.User, {as: 'follow', through: 'UserFollows'});
|
||||
|
||||
Object.keys(db).forEach(modelName => {
|
||||
if (db[modelName].associate) {
|
||||
|
@ -16,7 +16,9 @@ module.exports = (sequelize, DataTypes) => {
|
||||
User.init({
|
||||
name: DataTypes.STRING,
|
||||
password: DataTypes.STRING,
|
||||
email: DataTypes.STRING
|
||||
email: DataTypes.STRING,
|
||||
avatar: DataTypes.BLOB,
|
||||
bio: DataTypes.STRING
|
||||
}, {
|
||||
sequelize,
|
||||
modelName: 'User',
|
||||
|
4104
package-lock.json
generated
4104
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -7,10 +7,13 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"body-parser": "^1.19.1",
|
||||
"connect-busboy": "^1.0.0",
|
||||
"cookie-parser": "~1.4.4",
|
||||
"debug": "~2.6.9",
|
||||
"ejs": "~2.6.1",
|
||||
"express": "~4.16.1",
|
||||
"express-busboy": "^8.0.0",
|
||||
"express-fileupload": "^1.3.1",
|
||||
"http-errors": "~1.6.3",
|
||||
"morgan": "~1.9.1",
|
||||
"sequelize": "^6.15.0",
|
||||
|
@ -1,5 +1,9 @@
|
||||
/*
|
||||
! tailwindcss v3.0.18 | MIT License | https://tailwindcss.com
|
||||
/*
|
||||
npx tailwindcss -i ./src/style.css -o ./public/stylesheets/style.css --watch
|
||||
*/
|
||||
|
||||
/*
|
||||
! tailwindcss v3.0.18 | MIT License | https://tailwindcss.com
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -562,6 +566,10 @@ Ensure the default browser behavior of the `hidden` attribute.
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.inline-flex {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
@ -574,6 +582,14 @@ Ensure the default browser behavior of the `hidden` attribute.
|
||||
height: 9rem;
|
||||
}
|
||||
|
||||
.h-12 {
|
||||
height: 3rem;
|
||||
}
|
||||
|
||||
.h-24 {
|
||||
height: 6rem;
|
||||
}
|
||||
|
||||
.max-h-40 {
|
||||
max-height: 10rem;
|
||||
}
|
||||
@ -594,6 +610,14 @@ Ensure the default browser behavior of the `hidden` attribute.
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.w-12 {
|
||||
width: 3rem;
|
||||
}
|
||||
|
||||
.w-24 {
|
||||
width: 6rem;
|
||||
}
|
||||
|
||||
.max-w-lg {
|
||||
max-width: 32rem;
|
||||
}
|
||||
@ -852,16 +876,6 @@ Ensure the default browser behavior of the `hidden` attribute.
|
||||
color: rgb(37 99 235 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.text-gray-300 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(209 213 219 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.text-gray-800 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(31 41 55 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.text-gray-500 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(107 114 128 / var(--tw-text-opacity));
|
||||
|
38
routes/follow.js
Normal file
38
routes/follow.js
Normal file
@ -0,0 +1,38 @@
|
||||
var express = require('express');
|
||||
var router = express.Router();
|
||||
var db = require('../models');
|
||||
var User = db.User;
|
||||
var Messages = db.Messages;
|
||||
var Session = db.Session;
|
||||
var lib = require('../lib');
|
||||
|
||||
/* GET home page. */
|
||||
router.get('/add/:id', async function(req, res, next) {
|
||||
var id = req.params.id;
|
||||
console.log(req.cookies.sessionid);
|
||||
var sessionId = req.cookies.sessionid;
|
||||
var user = await lib.getAuthUser(sessionId);
|
||||
if(user) {
|
||||
var follow = await user.addFollow(id);
|
||||
res.send(follow);
|
||||
} else {
|
||||
res.redirect('/login');
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/get', async function(req, res, next) {
|
||||
var id = req.params.id;
|
||||
console.log(req.cookies.sessionid);
|
||||
var sessionId = req.cookies.sessionid;
|
||||
var user = await lib.getAuthUser(sessionId);
|
||||
if(user) {
|
||||
var follow = await user.getFollow({
|
||||
attributes: ['id']
|
||||
});
|
||||
res.send(follow);
|
||||
} else {
|
||||
res.redirect('/login');
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
@ -2,21 +2,63 @@ var express = require('express');
|
||||
var router = express.Router();
|
||||
var db = require('../models');
|
||||
var User = db.User;
|
||||
var Messages = db.Messages;
|
||||
var Session = db.Session;
|
||||
var lib = require('../lib');
|
||||
var Op = db.Sequelize.Op;
|
||||
|
||||
/* GET home page. */
|
||||
router.get('/', async function(req, res, next) {
|
||||
router.get('/me', async function(req, res, next) {
|
||||
console.log(req.cookies.sessionid);
|
||||
var sessionId = req.cookies.sessionid;
|
||||
var user = await lib.getAuthUser(sessionId);
|
||||
if(user) {
|
||||
var messages = await user.getMessages();
|
||||
res.render('index', { auth:user, messages:messages });
|
||||
var messages = await user.getMessages({
|
||||
order: [
|
||||
['id', 'DESC'],
|
||||
],
|
||||
limit: 10
|
||||
});
|
||||
var messageCount = await user.countMessages();
|
||||
res.render('me', { auth:user, messages:messages, messageCount:messageCount });
|
||||
} else {
|
||||
res.redirect('/login');
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
router.get('/', async function(req, res, next) {
|
||||
var sessionId = req.cookies.sessionid;
|
||||
var user = await lib.getAuthUser(sessionId);
|
||||
if(user) {
|
||||
var follows = await user.getFollow({
|
||||
attributes: {
|
||||
include: [
|
||||
'id',
|
||||
]
|
||||
}
|
||||
});
|
||||
var userList = [];
|
||||
userList.push(user.id);
|
||||
follows.forEach(element => {
|
||||
userList.push(element.id);
|
||||
});
|
||||
var userMessages = await db.Message.findAll({
|
||||
include: User,
|
||||
where: {
|
||||
'$User.id$': {
|
||||
[Op.in]: userList
|
||||
}
|
||||
},
|
||||
order: [
|
||||
['updatedAt', 'DESC']
|
||||
]
|
||||
});
|
||||
//console.log(await userMessages[0].getUsers());
|
||||
res.render('index', {auth:user, messages:userMessages, messageCount:3});
|
||||
} else {
|
||||
res.redirect('/login');
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
@ -35,4 +35,9 @@ router.post('/', async function(req, res, next) {
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/logout', function(req, res, next) {
|
||||
res.clearCookie('sessionid');
|
||||
res.redirect('/login');
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
@ -2,17 +2,106 @@ var express = require('express');
|
||||
const db = require('../models');
|
||||
var router = express.Router();
|
||||
var lib = require('../lib');
|
||||
var Message = db.Message;
|
||||
var User = db.User;
|
||||
var Op = db.Sequelize.Op;
|
||||
|
||||
async function getAllMessages(user) {
|
||||
if(user) {
|
||||
var follows = await user.getFollow();
|
||||
var timelineMessages = [];
|
||||
for(var i = 0; i < follows.length; i++) {
|
||||
timelineMessages[i] = follows[i]
|
||||
timelineMessages[i].messages = [];
|
||||
var messages = await follows[i].getMessages();
|
||||
for(var j = 0; j < messages.length; j++) {
|
||||
timelineMessages[i].messages.push(messages[j]);
|
||||
}
|
||||
}
|
||||
//var messages = fore
|
||||
return timelineMessages;
|
||||
}
|
||||
}
|
||||
|
||||
/* POST a new message */
|
||||
router.post('/add', async function(req, res, next) {
|
||||
var sessionId = req.cookies.sessionid;
|
||||
var user = await lib.getAuthUser(sessionId);
|
||||
if(user) {
|
||||
user.createMessage({ body: req.body.body });
|
||||
var message = await user.createMessage({ body: req.body.body });
|
||||
console.log(message);
|
||||
message.setUser(user);
|
||||
res.redirect('/');
|
||||
} else {
|
||||
res.redirect('/login');
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/timeline', async function(req, res, next) {
|
||||
var sessionId = req.cookies.sessionid;
|
||||
var user = await lib.getAuthUser(sessionId);
|
||||
var timeline = await getAllMessages(user);
|
||||
res.send(timeline);
|
||||
});
|
||||
|
||||
router.get('/timeline2', async function(req, res, next) {
|
||||
var sessionId = req.cookies.sessionid;
|
||||
var user = await lib.getAuthUser(sessionId);
|
||||
if(user) {
|
||||
var follows = await user.getFollow();
|
||||
var userList = [];
|
||||
follows.forEach(element => {
|
||||
userList.push(element.id);
|
||||
});
|
||||
var userMessages = await db.User.findAll({
|
||||
include: Message,
|
||||
//required: true,
|
||||
where: {
|
||||
id: userList,
|
||||
'$Messages.createdAt$': {
|
||||
[Op.like]: '2022%',
|
||||
}
|
||||
},
|
||||
|
||||
});
|
||||
res.send(userMessages);
|
||||
} else {
|
||||
res.redirect('/login');
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/timeline3', async function(req, res, next) {
|
||||
var sessionId = req.cookies.sessionid;
|
||||
var user = await lib.getAuthUser(sessionId);
|
||||
if(user) {
|
||||
var follows = await user.getFollow({
|
||||
attributes: {
|
||||
include: [
|
||||
'id',
|
||||
]
|
||||
}
|
||||
});
|
||||
var userList = [];
|
||||
userList.push(user.id);
|
||||
follows.forEach(element => {
|
||||
userList.push(element.id);
|
||||
});
|
||||
var userMessages = await db.Message.findAll({
|
||||
include: User,
|
||||
where: {
|
||||
'$User.id$': {
|
||||
[Op.in]: userList
|
||||
}
|
||||
},
|
||||
order: [
|
||||
['updatedAt', 'DESC']
|
||||
]
|
||||
});
|
||||
//console.log(await userMessages[0].getUsers());
|
||||
res.send(userMessages);
|
||||
} else {
|
||||
res.redirect('/login');
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
@ -2,30 +2,82 @@ var express = require('express');
|
||||
const db = require('../models');
|
||||
var router = express.Router();
|
||||
var User = db.User;
|
||||
var lib = require('../lib');
|
||||
|
||||
/* GET users listing. */
|
||||
router.get('/', async function(req, res, next) {
|
||||
var users = await User.findAll();
|
||||
res.send(users);
|
||||
router.get('/profile/:username', async function(req, res, next) {
|
||||
var test = 123;
|
||||
var sessionId = req.cookies.sessionid;
|
||||
var search = req.params.username;
|
||||
var auth = await lib.getAuthUser(sessionId);
|
||||
if(auth) {
|
||||
var user = await User.findOne({
|
||||
where: {
|
||||
name: search,
|
||||
}
|
||||
});
|
||||
if(user) {
|
||||
var messages = await user.getMessages();
|
||||
var messageCount = await user.countMessages();
|
||||
res.render('user', {auth:auth, user:user, messages:messages, messageCount:messageCount});
|
||||
} else {
|
||||
res.redirect('/');
|
||||
}
|
||||
} else {
|
||||
res.redirect('/login');
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
router.get('/get/:id', async function(req, res, next) {
|
||||
var users = await User.findByPk (req.params.id);
|
||||
res.send(users);
|
||||
router.get('/settings', async function(req, res, next) {
|
||||
var sessionId = req.cookies.sessionid;
|
||||
var auth = await lib.getAuthUser(sessionId);
|
||||
if(auth) {
|
||||
res.render('settings', { auth:auth });
|
||||
} else {
|
||||
res.redirect('/login');
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
router.put('/update/:id', async function(req, res, next) {
|
||||
var users = await User.update({'email':'eve@uplink.si'}, {where:{'ID':req.params.id}});
|
||||
res.send(users);
|
||||
router.post('/settings', async function(req, res, next) {
|
||||
var sessionId = req.cookies.sessionid;
|
||||
var auth = await lib.getAuthUser(sessionId);
|
||||
var newData = {};
|
||||
if(req.body.bio != '') {
|
||||
newData.bio = req.body.bio;
|
||||
}
|
||||
if(req.body.name != '') {
|
||||
newData.name = req.body.name;
|
||||
}
|
||||
if(req.files) {
|
||||
if(req.files.avatar.data) {
|
||||
newData.avatar = req.files.avatar.data;
|
||||
}
|
||||
}
|
||||
if(auth) {
|
||||
console.log(req);
|
||||
console.log(req.files);
|
||||
await auth.update(newData);
|
||||
res.redirect('/user/settings');
|
||||
} else {
|
||||
res.redirect('/login');
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/new', async function(req, res, next) {
|
||||
var users = await User.create({'name':'EVE2', 'email':'eve@2uplink.si', 'password':'some-random-password'});
|
||||
res.send(users);
|
||||
});
|
||||
|
||||
router.get('/add', function(req, res, next) {
|
||||
res.send('respond with a resource');
|
||||
router.get('/avatar/:id', async function(req, res, next) {
|
||||
var user = await db.User.findOne({
|
||||
where: {
|
||||
id: req.params.id
|
||||
}
|
||||
});
|
||||
res.contentType('image/png');
|
||||
if(user.avatar) {
|
||||
res.end(Buffer.from(user.avatar.buffer, 'base64'));
|
||||
} else {
|
||||
res.send();
|
||||
}
|
||||
//res.send(user.avatar.buffer);
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
46
seeders/20220213160925-users.js
Normal file
46
seeders/20220213160925-users.js
Normal file
@ -0,0 +1,46 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
async up (queryInterface, Sequelize) {
|
||||
/**
|
||||
* Add seed commands here.
|
||||
*
|
||||
* Example:
|
||||
* await queryInterface.bulkInsert('People', [{
|
||||
* name: 'John Doe',
|
||||
* isBetaMember: false
|
||||
* }], {});
|
||||
*/
|
||||
await queryInterface.bulkInsert('users', [
|
||||
{id: null, name: 'John Doe', email: 'John.Doe@email.com', password: 'password', createdAt: '2021-02-09 22:16:34.901 +00:00', updatedAt: '2022-02-09 22:16:34.901 +00:00'},
|
||||
{name: 'Valentin', password: 'random-password', email: 'valentin@uplink.si', createdAt: '2021-02-09 22:16:34.901 +00:00', updatedAt: '2022-02-09 22:16:34.901 +00:00'},
|
||||
{name: 'Helena', password: 'random-password', email: 'helena@uplink.si', createdAt: '2021-02-09 22:16:34.901 +00:00', updatedAt: '2022-02-09 22:16:34.901 +00:00'},
|
||||
{name: 'Oto', password: 'random-password', email: 'oto@uplink.si', createdAt: '2021-02-09 22:16:34.901 +00:00', updatedAt: '2022-02-09 22:16:34.901 +00:00'},
|
||||
{name: 'Peter', password: 'random-password', email: 'peter@uplink.si', createdAt: '2021-02-09 22:16:34.901 +00:00', updatedAt: '2022-02-09 22:16:34.901 +00:00'},
|
||||
{name: 'Igor', password: 'random-password', email: 'igor@uplink.si', createdAt: '2021-02-09 22:16:34.901 +00:00', updatedAt: '2022-02-09 22:16:34.901 +00:00'},
|
||||
{name: 'Matic', password: 'random-password', email: 'matic@uplink.si', createdAt: '2021-02-09 22:16:34.901 +00:00', updatedAt: '2022-02-09 22:16:34.901 +00:00'},
|
||||
{name: 'Jože', password: 'random-password', email: 'joze@uplink.si', createdAt: '2021-02-09 22:16:34.901 +00:00', updatedAt: '2022-02-09 22:16:34.901 +00:00'},
|
||||
{name: 'Marko', password: 'random-password', email: 'marko@uplink.si', createdAt: '2021-02-09 22:16:34.901 +00:00', updatedAt: '2022-02-09 22:16:34.901 +00:00'},
|
||||
{name: 'Marija', password: 'random-password', email: 'marija@uplink.si', createdAt: '2021-02-09 22:16:34.901 +00:00', updatedAt: '2022-02-09 22:16:34.901 +00:00'},
|
||||
{name: 'Brigita', password: 'random-password', email: 'brigita@uplink.si', createdAt: '2021-02-09 22:16:34.901 +00:00', updatedAt: '2022-02-09 22:16:34.901 +00:00'},
|
||||
{name: 'Andrej', password: 'random-password', email: 'andrej@uplink.si', createdAt: '2021-02-09 22:16:34.901 +00:00', updatedAt: '2022-02-09 22:16:34.901 +00:00'},
|
||||
{name: 'Jaka', password: 'random-password', email: 'jaka@uplink.si', createdAt: '2021-02-09 22:16:34.901 +00:00', updatedAt: '2022-02-09 22:16:34.901 +00:00'},
|
||||
{name: 'Natalija', password: 'random-password', email: 'natalija@uplink.si', createdAt: '2021-02-09 22:16:34.901 +00:00', updatedAt: '2022-02-09 22:16:34.901 +00:00'},
|
||||
{name: 'Lotta', password: 'random-password', email: 'lotta@uplink.si', createdAt: '2021-02-09 22:16:34.901 +00:00', updatedAt: '2022-02-09 22:16:34.901 +00:00'},
|
||||
{name: 'Sven', password: 'random-password', email: 'sven@uplink.si', createdAt: '2021-02-09 22:16:34.901 +00:00', updatedAt: '2022-02-09 22:16:34.901 +00:00'},
|
||||
{name: 'Bjorn', password: 'random-password', email: 'bjorn@uplink.si', createdAt: '2021-02-09 22:16:34.901 +00:00', updatedAt: '2022-02-09 22:16:34.901 +00:00'},
|
||||
{name: 'Lars', password: 'random-password', email: 'lars@uplink.si', createdAt: '2021-02-09 22:16:34.901 +00:00', updatedAt: '2022-02-09 22:16:34.901 +00:00'},
|
||||
{name: 'Matjaž', password: 'random-password', email: 'matjaz.m@uplink.si', createdAt: '2021-02-09 22:16:34.901 +00:00', updatedAt: '2022-02-09 22:16:34.901 +00:00'},
|
||||
], {});
|
||||
},
|
||||
|
||||
async down (queryInterface, Sequelize) {
|
||||
/**
|
||||
* Add commands to revert seed here.
|
||||
*
|
||||
* Example:
|
||||
* await queryInterface.bulkDelete('People', null, {});
|
||||
*/
|
||||
//await queryInterface.bulkDelete('Users', null, {});
|
||||
}
|
||||
};
|
@ -1,3 +1,7 @@
|
||||
/*
|
||||
npx tailwindcss -i ./src/style.css -o ./public/stylesheets/style.css --watch
|
||||
*/
|
||||
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
@ -32,38 +32,14 @@
|
||||
</form>
|
||||
<div class="flex items-center justify-between mt-5">
|
||||
<div class="flex items-center">
|
||||
<img src="/images/avatar_48.png" alt="<%= auth.name %>" class="rounded-md mr-2">
|
||||
<img src="/user/avatar/<%- auth.id %>" alt="<%= auth.name %>" class="rounded-md mr-2">
|
||||
<div>
|
||||
<div class="w-full font-bold text-sm"><%= auth.name %></div>
|
||||
<div class="w-full text-sm text-gray-400"><%= auth.email %></div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<button type="button" data-dropdown-toggle="dropdown" id="profileDropdownButton" class="bg-gray-700 rounded-md mx-2 px-2 focus:text-blue-400 text-lg font-bold" aria-expanded="true" aria-haspopup="true"><i class="fa fa-angle-down"></i></button>
|
||||
|
||||
<!-- This is an example component -->
|
||||
<div class="max-w-lg mx-auto">
|
||||
<!-- Dropdown menu -->
|
||||
<div class="hidden dark:bg-gray-700 dark:text-white z-50 list-none divide-y divide-gray-100 rounded-md shadow my-4" id="dropdown">
|
||||
<ul class="py-1" aria-labelledby="dropdown">
|
||||
<li>
|
||||
<a href="#" class="text-sm hover:bg-gray-600 text-white block px-3 py-1">Dashboard</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="text-sm hover:bg-gray-600 text-white block px-3 py-1">Settings</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="text-sm hover:bg-gray-600 text-white block px-3 py-1">Earnings</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="text-sm hover:bg-gray-600 text-white block px-3 py-1">Sign out</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<script src="/scripts/flowbite.js"></script>
|
||||
|
||||
|
||||
<%- include('partials/_user_dropdown.ejs') %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="my-5">
|
||||
@ -74,8 +50,8 @@
|
||||
<hr class="my-4">
|
||||
<div class="flex justify-end">
|
||||
<button
|
||||
class="place-content-end bg-blue-600 py-2 px-5 rounded-md mr-3 focus:outline-none focus:shadow-outline"
|
||||
type="submit">TOOT!</button>
|
||||
class="place-content-end bg-blue-600 py-2 px-5 rounded-md mr-3 focus:outline-none focus:shadow-outline font-bold"
|
||||
type="submit">Send</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@ -85,7 +61,7 @@
|
||||
class="lg:flex-1 lg:mx-3 max-w-xl min-w-md dark:bg-gray-600 dark:text-white scrollbar-thin scrollbar-thumb-gray-900 scrollbar-track-gray-700 overflow-y-scroll">
|
||||
<div class="lg:h-screen">
|
||||
<div class="bg-gray-900 text-white p-4 flex justify-between w-full z-50"">
|
||||
<div><i class=" fa fa-home mr-2"></i>Home</div>
|
||||
<div><a href="/"><i class=" fa fa-home mr-2"></i>Home</a></div>
|
||||
<div><i class="fa fa-sliders"></i></div>
|
||||
</div>
|
||||
<div class="max-h-40 overflow-y-hidden align-bottom">
|
||||
@ -93,7 +69,7 @@
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<div class="flex-shrink-0 max-h-10 relative -top-10 px-4">
|
||||
<img src="/images/avatar_94.png" alt="<%= auth.name %>" class="rounded-md overflow-visible">
|
||||
<img src="/user/avatar/<%= auth.id %>" alt="<%= auth.name %>" class="rounded-md overflow-visible w-24 h-24">
|
||||
</div>
|
||||
<div class="flex items-center pt-3 px-2 mx-2">
|
||||
<button class="bg-blue-600 py-2 px-5 rounded-md mr-3 focus:outline-none focus:shadow-outline"
|
||||
@ -110,55 +86,20 @@
|
||||
<p class="text-sm text-gray-400"><%= auth.email %></p>
|
||||
</div>
|
||||
<div class="text-sm text-gray-400 mt-3">
|
||||
<div class="my-4"><p><%= auth.bio %></p></div>
|
||||
<p>Joined <%= auth.createdAt %></p>
|
||||
<div class="flex">
|
||||
<div class="pr-5"><span class="text-white"><%= messages.length %></span> Posts</div>
|
||||
<div class="pr-5"><span class="text-white"><%= messageCount %></span> Posts</div>
|
||||
<div class="pr-5"><span class="text-white">3</span> Following</div>
|
||||
<div class="pr-5"><span class="text-white">7</span> Followers</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<%- include('partials/_toot', {auth:auth, messages:messages}) %>
|
||||
<%- include('partials/_messages', {messages:messages}) %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="lg:w-72 lg:overflow-y-hidden">
|
||||
<ul class="p-5">
|
||||
<li>
|
||||
<a class="font-bold text-lg mb-4 block"><i class="fa fa-home mr-2"></i>Home</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="font-bold text-lg mb-4 block"><i class="fa fa-bell mr-2"></i>Notifications</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="font-bold text-lg mb-4 block"><i class="fa fa-group mr-2"></i>Local</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="font-bold text-lg mb-4 block"><i class="fa fa-globe mr-2"></i>Federated</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="font-bold text-lg mb-4 block"><i class="fa fa-envelope mr-2"></i>Direct messages</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="font-bold text-lg mb-4 block"><i class="fa fa-star mr-2"></i>Favourites</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="font-bold text-lg mb-4 block"><i class="fa fa-bookmark mr-2"></i>Bookmarks</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="font-bold text-lg mb-4 block"><i class="fa fa-list mr-2"></i>Lists</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="font-bold text-lg mb-4 block"><i class="fa fa-address-book mr-2"></i>Profile directory</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="font-bold text-lg mb-4 block"><i class="fa fa-cog mr-2"></i>Preferences</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="font-bold text-lg mb-4 block"><i class="fa fa-group mr-2"></i>Follows and followers</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<%- include('partials/_sidebar_menu.ejs') %>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
@ -17,13 +17,13 @@
|
||||
<div class="mt-4">
|
||||
<div>
|
||||
<label class="block" for="email">Email<label>
|
||||
<input name="email" type="text" placeholder="Email"
|
||||
class="w-full px-4 py-2 mt-2 border rounded-md focus:outline-none focus:ring-1 focus:ring-blue-600">
|
||||
<input name="email" type="text" placeholder="Email"
|
||||
class="w-full px-4 py-2 mt-2 border rounded-md focus:outline-none focus:ring-1 focus:ring-blue-600">
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<label class="block">Password<label>
|
||||
<input name="password" type="password" placeholder="Password"
|
||||
class="w-full px-4 py-2 mt-2 border rounded-md focus:outline-none focus:ring-1 focus:ring-blue-600">
|
||||
<input name="password" type="password" placeholder="Password"
|
||||
class="w-full px-4 py-2 mt-2 border rounded-md focus:outline-none focus:ring-1 focus:ring-blue-600">
|
||||
</div>
|
||||
<div class="flex items-baseline justify-between">
|
||||
<button type="submit" class="px-6 py-2 mt-4 text-white bg-blue-600 rounded-lg hover:bg-blue-900">Login</button>
|
||||
|
108
views/me.ejs
Normal file
108
views/me.ejs
Normal file
@ -0,0 +1,108 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="dark">
|
||||
|
||||
<head>
|
||||
<title>Social Robot</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="/stylesheets/style.css">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/fork-awesome@1.2.0/css/fork-awesome.min.css"
|
||||
integrity="sha256-XoaMnoYC5TH6/+ihMEnospgm0J1PM/nioxbOUdnM8HY=" crossorigin="anonymous">
|
||||
</head>
|
||||
|
||||
<body class="bg-white dark:bg-gray-800 dark:text-white">
|
||||
<div class="lg:px-24 mx-auto">
|
||||
|
||||
<div class="lg:flex justify-center">
|
||||
<div class="lg:w-72 lg:overflow-y-hidden">
|
||||
<form method="GET">
|
||||
<div class="relative text-gray-600 focus-within:text-gray-400">
|
||||
<span class="absolute inset-y-0 left-0 flex items-center pl-2">
|
||||
<button type="submit" class="p-1 focus:outline-none focus:shadow-outline">
|
||||
<svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
viewBox="0 0 24 24" class="w-6 h-6">
|
||||
<path d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</span>
|
||||
<input type="search" name="q"
|
||||
class="w-full py-2 text-sm dark:text-white dark:bg-gray-900 pl-10 focus:outline-none dark:focus:bg-white dark:focus:text-gray-900"
|
||||
placeholder="Search..." autocomplete="off">
|
||||
</div>
|
||||
</form>
|
||||
<div class="flex items-center justify-between mt-5">
|
||||
<div class="flex items-center">
|
||||
<img src="/user/avatar/<%- auth.id %>" alt="<%= auth.name %>" class="rounded-md mr-2">
|
||||
<div>
|
||||
<div class="w-full font-bold text-sm"><%= auth.name %></div>
|
||||
<div class="w-full text-sm text-gray-400"><%= auth.email %></div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<%- include('partials/_user_dropdown.ejs') %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="my-5">
|
||||
<form method="POST" action="/message/add">
|
||||
<textarea
|
||||
class="w-full h-36 p-1 dark:text-white dark:bg-gray-900 focus:outline-none dark:focus:bg-white dark:focus:text-gray-900 text-sm"
|
||||
name="body" id="body" cols="20" placeholder="What's on your mind?"></textarea>
|
||||
<hr class="my-4">
|
||||
<div class="flex justify-end">
|
||||
<button
|
||||
class="place-content-end bg-blue-600 py-2 px-5 rounded-md mr-3 focus:outline-none focus:shadow-outline font-bold"
|
||||
type="submit">Send</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="lg:flex-1 lg:mx-3 max-w-xl min-w-md dark:bg-gray-600 dark:text-white scrollbar-thin scrollbar-thumb-gray-900 scrollbar-track-gray-700 overflow-y-scroll">
|
||||
<div class="lg:h-screen">
|
||||
<div class="bg-gray-900 text-white p-4 flex justify-between w-full z-50"">
|
||||
<div><a href="/"><i class=" fa fa-home mr-2"></i>Home</a></div>
|
||||
<div><i class="fa fa-sliders"></i></div>
|
||||
</div>
|
||||
<div class="max-h-40 overflow-y-hidden align-bottom">
|
||||
<img class="object-none object-center" src="/images/19187755.jpg" alt="paralax">
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<div class="flex-shrink-0 max-h-10 relative -top-10 px-4">
|
||||
<img src="/user/avatar/<%= auth.id %>" alt="<%= auth.name %>" class="rounded-md overflow-visible w-24 h-24">
|
||||
</div>
|
||||
<div class="flex items-center pt-3 px-2 mx-2">
|
||||
<button class="bg-blue-600 py-2 px-5 rounded-md mr-3 focus:outline-none focus:shadow-outline"
|
||||
type="submit">Follow</button>
|
||||
<button
|
||||
class="bg-gray-600 border border-b-gray-400 py-2 px-5 rounded-md focus:outline-none focus:shadow-outline shadow-xl"
|
||||
type="submit"><i class="fa fa-ellipsis-v"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="p-4">
|
||||
<div>
|
||||
<h4 class="font-bold"><%= auth.name %></h4>
|
||||
<p class="text-sm text-gray-400"><%= auth.email %></p>
|
||||
</div>
|
||||
<div class="text-sm text-gray-400 mt-3">
|
||||
<div class="my-4"><p><%= auth.bio %></p></div>
|
||||
<p>Joined <%= auth.createdAt %></p>
|
||||
<div class="flex">
|
||||
<div class="pr-5"><span class="text-white"><%= messageCount %></span> Posts</div>
|
||||
<div class="pr-5"><span class="text-white">3</span> Following</div>
|
||||
<div class="pr-5"><span class="text-white">7</span> Followers</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<%- include('partials/_toot', {auth:auth, messages:messages}) %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%- include('partials/_sidebar_menu.ejs') %>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
25
views/partials/_messages.ejs
Normal file
25
views/partials/_messages.ejs
Normal file
@ -0,0 +1,25 @@
|
||||
<!-- _messages.ejs -->
|
||||
<% for(var i = 0; i < messages.length; i++) {%>
|
||||
|
||||
<div class="dark:bg-gray-700 flex p-4 border-b border-b-gray-400">
|
||||
<div class="mr-4 flex-shrink-0">
|
||||
<img src="/user/avatar/<%- messages[i].User.id %>" alt="<%= auth.name %>" class="rounded-md w-12 h-12">
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<h5 class="font-bold mb-4">
|
||||
<a href="/user/profile/<%= messages[i].User.name %>"><%= messages[i].User.name %></a>
|
||||
</h5>
|
||||
|
||||
<p>
|
||||
<% messages[i].body.split('\n').forEach(line => { %>
|
||||
<%= line %><br>
|
||||
<% }) %>
|
||||
</p>
|
||||
</div>
|
||||
<div class="text-xs text-gray-500 mt-3">Posted on: <%= messages[i].createdAt %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<% } %>
|
38
views/partials/_sidebar_menu.ejs
Normal file
38
views/partials/_sidebar_menu.ejs
Normal file
@ -0,0 +1,38 @@
|
||||
<!-- _sidebar_menu.ejs -->
|
||||
<div class="lg:w-72 lg:overflow-y-hidden">
|
||||
<ul class="p-5">
|
||||
<li>
|
||||
<a href="/" class="font-bold text-lg mb-4 block"><i class="fa fa-home mr-2"></i>Home</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="font-bold text-lg mb-4 block"><i class="fa fa-bell mr-2"></i>Notifications</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="font-bold text-lg mb-4 block"><i class="fa fa-group mr-2"></i>Local</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="font-bold text-lg mb-4 block"><i class="fa fa-globe mr-2"></i>Federated</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="font-bold text-lg mb-4 block"><i class="fa fa-envelope mr-2"></i>Direct messages</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="font-bold text-lg mb-4 block"><i class="fa fa-star mr-2"></i>Favourites</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="font-bold text-lg mb-4 block"><i class="fa fa-bookmark mr-2"></i>Bookmarks</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="font-bold text-lg mb-4 block"><i class="fa fa-list mr-2"></i>Lists</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="font-bold text-lg mb-4 block"><i class="fa fa-address-book mr-2"></i>Profile directory</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="font-bold text-lg mb-4 block"><i class="fa fa-cog mr-2"></i>Preferences</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="font-bold text-lg mb-4 block"><i class="fa fa-group mr-2"></i>Follows and followers</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
@ -1,17 +1,20 @@
|
||||
<% for(var i=messages.length - 1; i>= 0; i--) {%>
|
||||
<!-- _toot.ejs -->
|
||||
<% for(var i = 0; i < messages.length; i++) {%>
|
||||
|
||||
<div class="dark:bg-gray-700 flex p-4 border-b border-b-gray-400">
|
||||
<div class="mr-4 flex-shrink-0">
|
||||
<img src="/images/avatar_48.png" alt="<%= auth.name %>" class="rounded-md">
|
||||
<img src="/user/avatar/<%- auth.id %>" alt="<%= auth.name %>" class="rounded-md w-12 h-12">
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<h5 class="font-bold mb-4">
|
||||
<%= auth.name %>
|
||||
<a href="/user/profile/<%= auth.name %>"><%= auth.name %></a>
|
||||
</h5>
|
||||
|
||||
<p>
|
||||
<%= messages[i].body%>
|
||||
<% messages[i].body.split('\n').forEach(line => { %>
|
||||
<%= line %><br>
|
||||
<% }) %>
|
||||
</p>
|
||||
</div>
|
||||
<div class="text-xs text-gray-500 mt-3">Posted on: <%= messages[i].createdAt %>
|
||||
|
27
views/partials/_user_dropdown.ejs
Normal file
27
views/partials/_user_dropdown.ejs
Normal file
@ -0,0 +1,27 @@
|
||||
<!-- _user_dropdown.ejs -->
|
||||
<button type="button" data-dropdown-toggle="dropdown" id="profileDropdownButton"
|
||||
class="bg-gray-700 rounded-md mx-2 px-2 focus:text-blue-400 text-lg font-bold" aria-expanded="true"
|
||||
aria-haspopup="true"><i class="fa fa-angle-down"></i></button>
|
||||
|
||||
<!-- This is an example component -->
|
||||
<div class="max-w-lg mx-auto">
|
||||
<!-- Dropdown menu -->
|
||||
<div class="hidden dark:bg-gray-700 dark:text-white z-50 list-none divide-y divide-gray-100 rounded-md shadow my-4"
|
||||
id="dropdown">
|
||||
<ul class="py-1" aria-labelledby="dropdown">
|
||||
<li>
|
||||
<a href="/me" class="text-sm hover:bg-gray-600 text-white block px-3 py-1">Profile</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/user/settings" class="text-sm hover:bg-gray-600 text-white block px-3 py-1">Settings</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="text-sm hover:bg-gray-600 text-white block px-3 py-1">Earnings</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/login/logout" class="text-sm hover:bg-gray-600 text-white block px-3 py-1">Sign out</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<script src="/scripts/flowbite.js"></script>
|
25
views/partials/_user_timeline.ejs
Normal file
25
views/partials/_user_timeline.ejs
Normal file
@ -0,0 +1,25 @@
|
||||
<!-- _user_timeline.ejs -->
|
||||
<% for(var i = 0; i < messages.length; i++) {%>
|
||||
|
||||
<div class="dark:bg-gray-700 flex p-4 border-b border-b-gray-400">
|
||||
<div class="mr-4 flex-shrink-0">
|
||||
<img src="/user/avatar/<%- user.id %>" alt="<%= user.name %>" class="rounded-md w-12 h-12">
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<h5 class="font-bold mb-4">
|
||||
<a href="/user/profile/<%= user.name %>"><%= user.name %></a>
|
||||
</h5>
|
||||
|
||||
<p>
|
||||
<% messages[i].body.split('\n').forEach(line => { %>
|
||||
<%= line %><br>
|
||||
<% }) %>
|
||||
</p>
|
||||
</div>
|
||||
<div class="text-xs text-gray-500 mt-3">Posted on: <%= messages[i].createdAt %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<% } %>
|
@ -17,18 +17,18 @@
|
||||
<div class="mt-4">
|
||||
<div>
|
||||
<label class="block" for="username">Name<label>
|
||||
<input name="username" type="text" placeholder="Name"
|
||||
class="w-full px-4 py-2 mt-2 border rounded-md focus:outline-none focus:ring-1 focus:ring-blue-600">
|
||||
<input name="username" type="text" placeholder="Name"
|
||||
class="w-full px-4 py-2 mt-2 border rounded-md focus:outline-none focus:ring-1 focus:ring-blue-600">
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<label class="block" for="email">Email<label>
|
||||
<input name="email" type="text" placeholder="Email"
|
||||
class="w-full px-4 py-2 mt-2 border rounded-md focus:outline-none focus:ring-1 focus:ring-blue-600">
|
||||
<input name="email" type="text" placeholder="Email"
|
||||
class="w-full px-4 py-2 mt-2 border rounded-md focus:outline-none focus:ring-1 focus:ring-blue-600">
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<label class="block">Password<label>
|
||||
<input name="password" type="password" placeholder="Password"
|
||||
class="w-full px-4 py-2 mt-2 border rounded-md focus:outline-none focus:ring-1 focus:ring-blue-600">
|
||||
<input name="password" type="password" placeholder="Password"
|
||||
class="w-full px-4 py-2 mt-2 border rounded-md focus:outline-none focus:ring-1 focus:ring-blue-600">
|
||||
</div>
|
||||
<div class="flex items-baseline justify-between">
|
||||
<button type="submit" class="px-6 py-2 mt-4 text-white bg-blue-600 rounded-lg hover:bg-blue-900">Register</button>
|
||||
|
130
views/settings.ejs
Normal file
130
views/settings.ejs
Normal file
@ -0,0 +1,130 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="dark">
|
||||
|
||||
<head>
|
||||
<title>Social Robot</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="/stylesheets/style.css">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/fork-awesome@1.2.0/css/fork-awesome.min.css"
|
||||
integrity="sha256-XoaMnoYC5TH6/+ihMEnospgm0J1PM/nioxbOUdnM8HY=" crossorigin="anonymous">
|
||||
</head>
|
||||
|
||||
<body class="bg-white dark:bg-gray-800 dark:text-white">
|
||||
<div class="lg:px-24 mx-auto">
|
||||
|
||||
<div class="lg:flex justify-center">
|
||||
<div class="lg:w-72 lg:overflow-y-hidden">
|
||||
<form method="GET">
|
||||
<div class="relative text-gray-600 focus-within:text-gray-400">
|
||||
<span class="absolute inset-y-0 left-0 flex items-center pl-2">
|
||||
<button type="submit" class="p-1 focus:outline-none focus:shadow-outline">
|
||||
<svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
viewBox="0 0 24 24" class="w-6 h-6">
|
||||
<path d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</span>
|
||||
<input type="search" name="q"
|
||||
class="w-full py-2 text-sm dark:text-white dark:bg-gray-900 pl-10 focus:outline-none dark:focus:bg-white dark:focus:text-gray-900"
|
||||
placeholder="Search..." autocomplete="off">
|
||||
</div>
|
||||
</form>
|
||||
<div class="flex items-center justify-between mt-5">
|
||||
<div class="flex items-center">
|
||||
<img src="/user/avatar/<%- auth.id %>" alt="<%= auth.name %>" class="rounded-md mr-2">
|
||||
<div>
|
||||
<div class="w-full font-bold text-sm"><%= auth.name %></div>
|
||||
<div class="w-full text-sm text-gray-400"><%= auth.email %></div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<%- include('partials/_user_dropdown.ejs') %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="my-5">
|
||||
<form method="POST" action="/message/add">
|
||||
<textarea
|
||||
class="w-full h-36 p-1 dark:text-white dark:bg-gray-900 focus:outline-none dark:focus:bg-white dark:focus:text-gray-900 text-sm"
|
||||
name="body" id="body" cols="20" placeholder="What's on your mind?"></textarea>
|
||||
<hr class="my-4">
|
||||
<div class="flex justify-end">
|
||||
<button
|
||||
class="place-content-end bg-blue-600 py-2 px-5 rounded-md mr-3 focus:outline-none focus:shadow-outline font-bold"
|
||||
type="submit">Send</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="lg:flex-1 lg:mx-3 max-w-xl min-w-md dark:bg-gray-600 dark:text-white scrollbar-thin scrollbar-thumb-gray-900 scrollbar-track-gray-700 overflow-y-scroll">
|
||||
<div class="lg:h-screen">
|
||||
<div class="bg-gray-900 text-white p-4 flex justify-between w-full z-50"">
|
||||
<div><a href="/"><i class=" fa fa-home mr-2"></i>Home</a></div>
|
||||
<div><i class="fa fa-sliders"></i></div>
|
||||
</div>
|
||||
<div class="max-h-40 overflow-y-hidden align-bottom">
|
||||
<img class="object-none object-center" src="/images/19187755.jpg" alt="paralax">
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<div class="flex-shrink-0 max-h-10 relative -top-10 px-4">
|
||||
<img src="/user/avatar/<%= auth.id %>" alt="<%= auth.name %>" class="rounded-md overflow-visible w-24 h-24">
|
||||
</div>
|
||||
<div class="flex items-center pt-3 px-2 mx-2">
|
||||
<button class="bg-blue-600 py-2 px-5 rounded-md mr-3 focus:outline-none focus:shadow-outline"
|
||||
type="submit">Follow</button>
|
||||
<button
|
||||
class="bg-gray-600 border border-b-gray-400 py-2 px-5 rounded-md focus:outline-none focus:shadow-outline shadow-xl"
|
||||
type="submit"><i class="fa fa-ellipsis-v"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="p-4">
|
||||
<div>
|
||||
<h4 class="font-bold"><%= auth.name %></h4>
|
||||
<p class="text-sm text-gray-400"><%= auth.email %></p>
|
||||
</div>
|
||||
<div class="text-sm text-gray-400 mt-3">
|
||||
<div class="my-4"><p><%= auth.bio %></p></div>
|
||||
<p>Joined <%= auth.createdAt %></p>
|
||||
<div class="flex">
|
||||
<div class="pr-5"><span class="text-white">12</span> Posts</div>
|
||||
<div class="pr-5"><span class="text-white">3</span> Following</div>
|
||||
<div class="pr-5"><span class="text-white">7</span> Followers</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- dodaj -->
|
||||
<div class="p-4">
|
||||
<form action="/user/settings" method="POST" enctype="multipart/form-data">
|
||||
<div class="my-4 w-full">
|
||||
<label for="name">Name:</label>
|
||||
<input value="<%= auth.name %>" class="dark:text-white dark:bg-gray-900 focus:outline-none dark:focus:bg-white dark:focus:text-gray-900 text-sm" type="text" name="name" id="name">
|
||||
</div>
|
||||
<div class="my-4">
|
||||
<input type="file" name="avatar" id="avatar" >
|
||||
</div>
|
||||
<div class="my-4">
|
||||
<textarea
|
||||
class="w-full h-36 p-1 dark:text-white dark:bg-gray-900 focus:outline-none dark:focus:bg-white dark:focus:text-gray-900 text-sm"
|
||||
name="bio" id="body" cols="20" placeholder="A little bit about me"><%= auth.bio%></textarea>
|
||||
</div>
|
||||
<div class="my-4">
|
||||
<button
|
||||
class="place-content-end bg-blue-600 py-2 px-5 rounded-md mr-3 focus:outline-none focus:shadow-outline font-bold"
|
||||
type="submit">Save</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%- include('partials/_sidebar_menu.ejs') %>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
118
views/user.ejs
Normal file
118
views/user.ejs
Normal file
@ -0,0 +1,118 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="dark">
|
||||
|
||||
<head>
|
||||
<title>Social Robot</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="/stylesheets/style.css">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/fork-awesome@1.2.0/css/fork-awesome.min.css"
|
||||
integrity="sha256-XoaMnoYC5TH6/+ihMEnospgm0J1PM/nioxbOUdnM8HY=" crossorigin="anonymous">
|
||||
</head>
|
||||
|
||||
<body class="bg-white dark:bg-gray-800 dark:text-white">
|
||||
<div class="lg:px-24 mx-auto">
|
||||
|
||||
<div class="lg:flex justify-center">
|
||||
<div class="lg:w-72 lg:overflow-y-hidden">
|
||||
<form method="GET">
|
||||
<div class="relative text-gray-600 focus-within:text-gray-400">
|
||||
<span class="absolute inset-y-0 left-0 flex items-center pl-2">
|
||||
<button type="submit" class="p-1 focus:outline-none focus:shadow-outline">
|
||||
<svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
viewBox="0 0 24 24" class="w-6 h-6">
|
||||
<path d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</span>
|
||||
<input type="search" name="q"
|
||||
class="w-full py-2 text-sm dark:text-white dark:bg-gray-900 pl-10 focus:outline-none dark:focus:bg-white dark:focus:text-gray-900"
|
||||
placeholder="Search..." autocomplete="off">
|
||||
</div>
|
||||
</form>
|
||||
<div class="flex items-center justify-between mt-5">
|
||||
<div class="flex items-center">
|
||||
<img src="/user/avatar/<%- auth.id %>" alt="<%= auth.name %>" class="rounded-md mr-2">
|
||||
<div>
|
||||
<div class="w-full font-bold text-sm"><%= auth.name %></div>
|
||||
<div class="w-full text-sm text-gray-400"><%= auth.email %></div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<%- include('partials/_user_dropdown.ejs') %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="my-5">
|
||||
<form method="POST" action="/message/add">
|
||||
<textarea
|
||||
class="w-full h-36 p-1 dark:text-white dark:bg-gray-900 focus:outline-none dark:focus:bg-white dark:focus:text-gray-900 text-sm"
|
||||
name="body" id="body" cols="20" placeholder="What's on your mind?"></textarea>
|
||||
<hr class="my-4">
|
||||
<div class="flex justify-end">
|
||||
<button
|
||||
class="place-content-end bg-blue-600 py-2 px-5 rounded-md mr-3 focus:outline-none focus:shadow-outline font-bold"
|
||||
type="submit">Send</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="lg:flex-1 lg:mx-3 max-w-xl min-w-md dark:bg-gray-600 dark:text-white scrollbar-thin scrollbar-thumb-gray-900 scrollbar-track-gray-700 overflow-y-scroll">
|
||||
<div class="lg:h-screen">
|
||||
<div class="bg-gray-900 text-white p-4 flex justify-between w-full z-50"">
|
||||
<div><a href="/"><i class=" fa fa-home mr-2"></i>Home</a></div>
|
||||
<div><i class="fa fa-sliders"></i></div>
|
||||
</div>
|
||||
<div class="max-h-40 overflow-y-hidden align-bottom">
|
||||
<img class="object-none object-center" src="/images/19187755.jpg" alt="paralax">
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<div class="flex-shrink-0 max-h-10 relative -top-10 px-4">
|
||||
<img src="/user/avatar/<%= user.id %>" alt="<%= user.name %>" class="rounded-md overflow-visible w-24 h-24">
|
||||
</div>
|
||||
<div class="flex items-center pt-3 px-2 mx-2">
|
||||
<a class="bg-blue-600
|
||||
py-2
|
||||
px-5
|
||||
rounded-md
|
||||
mr-3
|
||||
focus:outline-none
|
||||
focus:shadow-outline
|
||||
|
||||
inline-flex
|
||||
items-center
|
||||
"
|
||||
href="/follow/add/<%= user.id %>">Follow</a>
|
||||
<button
|
||||
class="bg-gray-600 border border-b-gray-400 py-2 px-5 rounded-md focus:outline-none focus:shadow-outline shadow-xl"
|
||||
type="submit"><i class="fa fa-ellipsis-v"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="p-4">
|
||||
<div>
|
||||
<h4 class="font-bold"><%= user.name %></h4>
|
||||
<p class="text-sm text-gray-400"><%= user.email %></p>
|
||||
</div>
|
||||
<div class="text-sm text-gray-400 mt-3">
|
||||
<div class="my-4"><p><%= user.bio %></p></div>
|
||||
<p>Joined <%= user.createdAt %></p>
|
||||
<div class="flex">
|
||||
<div class="pr-5"><span class="text-white"><%= messageCount %></span> Posts</div>
|
||||
<div class="pr-5"><span class="text-white">3</span> Following</div>
|
||||
<div class="pr-5"><span class="text-white">7</span> Followers</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<%- include('partials/_user_timeline', {user:user, messages:messages}) %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%- include('partials/_sidebar_menu.ejs') %>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
Reference in New Issue
Block a user