Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 29 additions & 2 deletions app/controllers/activity.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,35 @@
import { Request, Response } from 'express';
import mongoose from 'mongoose';

/**
* Show activities
*/
export const index = (req: Request, res: Response) => {
res.render('pages/activity', { title: 'Activities' });
export const index = async (req: Request, res: Response) => {
const Activity = mongoose.model('Activity');
const page = parseInt((req as any).query.page) || 0;
const perPage = 20;

try {
const activities = await (Activity as any)
.list({
criteria: {},
perPage: perPage,
page: page
})
.exec();

res.render('pages/activity', {
title: 'Activities',
activities: activities || [],
page: page,
pages: Math.ceil(await Activity.countDocuments() / perPage) || 1
});
} catch (err) {
res.render('pages/activity', {
title: 'Activities',
activities: [],
page: 0,
pages: 1
});
}
};
4 changes: 2 additions & 2 deletions app/controllers/tweets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const create = async (req: Request, res: Response): Promise<void> => {

try {
await tweet.save();
res.redirect('/tweets/' + tweet._id);
res.redirect('/');
} catch (err: any) {
res.status(400).json({ error: err.message });
}
Expand All @@ -42,7 +42,7 @@ export const update = async (req: Request, res: Response): Promise<void> => {

try {
await tweet.save();
res.redirect('/tweets/' + tweet._id);
res.redirect('/');
} catch (err: any) {
res.status(400).json({ error: err.message });
}
Expand Down
171 changes: 149 additions & 22 deletions app/controllers/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ export const user = async (req: Request, res: Response, next: any, id: string) =
const User = mongoose.model('User');

try {
const user = await (User as any).load({ criteria: { _id: id } });
const user = await (User as any).load({
criteria: { _id: id },
select: 'name username github followers following'
});
if (!user) return next(new Error('Failed to load User ' + id));
(req as any).profile = user;
next();
Expand All @@ -33,9 +36,19 @@ export const create = async (req: Request, res: Response) => {
return res.redirect('/users/' + user._id);
});
} catch (err: any) {
const Tweet = mongoose.model('Tweet');
const Analytics = mongoose.model('Analytics');

const tweetCount = await Tweet.countDocuments();
const userCount = await User.countDocuments();
const analyticsCount = await Analytics.countDocuments();

return res.render('pages/login', {
errors: err.errors,
user: user
user: user,
tweetCount: tweetCount,
userCount: userCount,
analyticsCount: analyticsCount
});
}
};
Expand All @@ -49,41 +62,122 @@ export const show = async (req: Request, res: Response) => {
const user = (req as any).profile;

try {
const count = await Tweet.countDocuments({ user: (req as any).profile._id });
// Get tweet count
const tweetCount = await Tweet.countDocuments({ user: user._id });

// Get actual tweets for this user
const tweets = await (Tweet as any)
.list({
criteria: { user: user._id },
perPage: 20,
page: 0
})
.exec();

// Get follower/following counts
const followerCount = user.followers ? user.followers.length : 0;
const followingCount = user.following ? user.following.length : 0;

res.render('pages/profile', {
title: user.name,
user: user,
tweets: count
tweets: tweets,
tweetCount: tweetCount,
followerCount: followerCount,
followingCount: followingCount
});
} catch (err) {
res.render('pages/profile', {
title: user.name,
user: user,
tweets: 0
tweets: [],
tweetCount: 0,
followerCount: 0,
followingCount: 0
});
}
};

/**
* Show followers
*/
export const showFollowers = (req: Request, res: Response) => {
export const showFollowers = async (req: Request, res: Response) => {
const User = mongoose.model('User');
const Tweet = mongoose.model('Tweet');
const user = (req as any).profile;
res.render('pages/followers', {
title: user.name + ' followers',
user: user
});

try {
// Populate followers
const populatedUser = await User.findById(user._id)
.populate('followers', 'name username github')
.exec();

const followers = populatedUser?.followers || [];

// Get counts for profile card
const tweetCount = await Tweet.countDocuments({ user: user._id });
const followerCount = user.followers ? user.followers.length : 0;
const followingCount = user.following ? user.following.length : 0;

res.render('pages/followers', {
title: user.name + ' followers',
user: user,
followers: followers,
tweetCount: tweetCount,
followerCount: followerCount,
followingCount: followingCount
});
} catch (err) {
res.render('pages/followers', {
title: user.name + ' followers',
user: user,
followers: [],
tweetCount: 0,
followerCount: 0,
followingCount: 0
});
}
};

/**
* Show following
*/
export const showFollowing = (req: Request, res: Response) => {
export const showFollowing = async (req: Request, res: Response) => {
const User = mongoose.model('User');
const Tweet = mongoose.model('Tweet');
const user = (req as any).profile;
res.render('pages/followers', {
title: user.name + ' following',
user: user
});

try {
// Populate following
const populatedUser = await User.findById(user._id)
.populate('following', 'name username github')
.exec();

const following = populatedUser?.following || [];

// Get counts for profile card
const tweetCount = await Tweet.countDocuments({ user: user._id });
const followerCount = user.followers ? user.followers.length : 0;
const followingCount = user.following ? user.following.length : 0;

res.render('pages/followers', {
title: user.name + ' following',
user: user,
followers: following, // Using 'followers' template variable for both
tweetCount: tweetCount,
followerCount: followerCount,
followingCount: followingCount
});
} catch (err) {
res.render('pages/followers', {
title: user.name + ' following',
user: user,
followers: [],
tweetCount: 0,
followerCount: 0,
followingCount: 0
});
}
};

/**
Expand All @@ -98,10 +192,23 @@ export const update = (req: Request, res: Response) => {
/**
* Delete user
*/
export const deleteUser = (req: Request, res: Response) => {
export const deleteUser = async (req: Request, res: Response) => {
const User = mongoose.model('User');
const Tweet = mongoose.model('Tweet');
const user = (req as any).profile;
// Implement delete logic
res.redirect('/');

try {
// Delete user's tweets
await Tweet.deleteMany({ user: user._id });
// Delete the user
await User.findByIdAndDelete(user._id);
// Logout and redirect
req.logout((err: any) => {
res.redirect('/login');
});
} catch (err) {
res.redirect('/');
}
};

/**
Expand All @@ -114,10 +221,30 @@ export const session = (req: Request, res: Response) => {
/**
* Login page
*/
export const login = (req: Request, res: Response) => {
res.render('pages/login', {
title: 'Login'
});
export const login = async (req: Request, res: Response) => {
const Tweet = mongoose.model('Tweet');
const User = mongoose.model('User');
const Analytics = mongoose.model('Analytics');

try {
const tweetCount = await Tweet.countDocuments();
const userCount = await User.countDocuments();
const analyticsCount = await Analytics.countDocuments();

res.render('pages/login', {
title: 'Login',
tweetCount: tweetCount,
userCount: userCount,
analyticsCount: analyticsCount
});
} catch (err) {
res.render('pages/login', {
title: 'Login',
tweetCount: 0,
userCount: 0,
analyticsCount: 0
});
}
};

/**
Expand Down
40 changes: 22 additions & 18 deletions app/views/chat/chat.pug
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
extends ../layouts/default

block content
.row.twitter-container
.col-xl-12.col-lg-12.first-column
.logged-user
.row.chatbox
- if (chats.length == 0)
h2 No chats sorry!
ul.chatlist
- if (chats)
each chat in chats
li
- if (chat.sender != null)
img(class='tweet__image', src=chat.sender.github.avatar_url)
p.chatMessage
a(class='sender', href="/users/" + chat.sender._id)
span.sender #{chat.sender.username}:
span.message #{chat.message}
p.msgtime #{moment(chat.createdAt).format("MMM D, YYYY [at] h:mm a")}

.max-w-4xl.mx-auto
.bg-yankees-blue.rounded-lg.border.border-black.overflow-hidden
.bg-jungle-dark.px-6.py-4.border-b.border-black
h2.text-xl.font-display.font-semibold.text-white Messages

.p-6
- if (chats.length == 0)
.text-center.py-12
i.far.fa-comments.text-6xl.text-grey-blue.mb-4
h2.text-xl.text-white.font-medium No messages yet
p.text-grey-blue.mt-2 Start a conversation with someone!
else
.space-y-4
each chat in chats
if (chat.sender != null)
.flex.gap-4.p-4.bg-jungle-dark.rounded-lg.border.border-black
img.w-10.h-10.rounded-full.border.border-black.flex-shrink-0(src=chat.sender.github.avatar_url)
.flex-1.min-w-0
.flex.items-center.gap-2.mb-1
a.text-twitter-blue.font-semibold(href="/users/" + chat.sender._id, class="hover:underline") #{chat.sender.username}
span.text-grey-blue.text-sm #{moment(chat.createdAt).format("MMM D, YYYY [at] h:mm a")}
p.text-white.break-words #{chat.message}
Loading