A modern, full-stack social media platform.
Asra
- User registration with bcrypt password hashing
- Secure login/logout with express-session
- Protected routes (redirect to login if not authenticated)
- Session persists for 7 days
- Full profile page with name, bio, location, and avatar
- Edit profile page
- Follower / following counts
- User's posts displayed on their profile
- Create text posts (up to 500 characters)
- Home feed showing all posts in reverse chronological order
- Post detail view
- Delete your own posts
- Character counter while writing
- Add comments on any post
- See all comments on the post detail page
- Delete your own comments
- Character limit (300 chars)
- Like and unlike posts with a single click (AJAX — no page reload)
- One like per user per post (enforced in database)
- Real-time like count update
- Visual heart animation on like
- Follow / unfollow other users (AJAX — no page reload)
- Follower and following counts on profile pages
- Cannot follow yourself
- "People to Follow" suggestions in sidebar
- Browse all users
- Search users by name or username
- User cards showing posts, followers, following
- Follow directly from explore page
- Dark mode first with light mode toggle (persists via localStorage)
- Glassmorphism cards
- Gradient backgrounds and accent glow effects
- Smooth animations and micro-interactions
- Responsive layout (mobile, tablet, desktop)
- Mobile bottom navigation
- Post creation modal
- Toast notifications
- Keyboard shortcuts (N = new post, Esc = close modal)
| Layer | Technology |
|---|---|
| Frontend | HTML5, CSS3, JavaScript (ES6+) |
| Template Engine | EJS (Embedded JavaScript) |
| Backend | Node.js + Express.js |
| Database | SQLite (via better-sqlite3) |
| Authentication | express-session + bcrypt |
| Styling | Custom CSS (no frameworks) |
ModernConnect/
├── app.js # Entry point — Express app setup
├── package.json
│
├── database/
│ ├── db.js # SQLite connection + table creation
│ └── seed.js # Demo data seeder
│
├── routes/
│ ├── auth.js # /register, /login, /logout
│ ├── posts.js # /feed, /posts, /posts/:id
│ ├── comments.js # /posts/:id/comments, /comments/:id/delete
│ ├── likes.js # /posts/:id/like (toggle)
│ ├── follows.js # /users/:id/follow (toggle)
│ └── profile.js # /profile/:username, /explore
│
├── middleware/
│ └── auth.js # requireLogin, redirectIfLoggedIn
│
├── views/
│ ├── partials/
│ │ ├── head.ejs # <html> + <head> + CSS link
│ │ ├── navbar.ejs # Top navigation bar
│ │ ├── sidebar.ejs # Left sidebar (logged-in pages)
│ │ ├── footer.ejs # Mobile nav + JS link + </body></html>
│ │ └── post-card.ejs # Reusable post card component
│ ├── landing.ejs # Public landing/home page
│ ├── login.ejs # Login form
│ ├── register.ejs # Registration form
│ ├── feed.ejs # Main home feed
│ ├── profile.ejs # User profile page
│ ├── edit-profile.ejs # Edit profile form
│ ├── explore.ejs # Discover users
│ ├── post-detail.ejs # Single post with comments
│ └── 404.ejs # Not found page
│
└── public/
├── css/
│ └── style.css # All styles (dark mode, glass, responsive)
└── js/
└── main.js # AJAX likes/follows, modal, theme toggle
| Column | Type | Description |
|---|---|---|
| id | INTEGER PK | Auto-increment |
| username | TEXT UNIQUE | @handle, lowercase |
| TEXT UNIQUE | User email | |
| password | TEXT | bcrypt hash |
| full_name | TEXT | Display name |
| bio | TEXT | Short bio |
| location | TEXT | City, Country |
| avatar_color | TEXT | HEX color for avatar |
| created_at | DATETIME | Registration timestamp |
| Column | Type | Description |
|---|---|---|
| id | INTEGER PK | Auto-increment |
| user_id | INTEGER FK | References users.id |
| content | TEXT | Post text (max 500 chars) |
| created_at | DATETIME | Post timestamp |
| Column | Type | Description |
|---|---|---|
| id | INTEGER PK | Auto-increment |
| post_id | INTEGER FK | References posts.id |
| user_id | INTEGER FK | References users.id |
| content | TEXT | Comment text |
| created_at | DATETIME | Comment timestamp |
| Column | Type | Description |
|---|---|---|
| id | INTEGER PK | Auto-increment |
| post_id | INTEGER FK | References posts.id |
| user_id | INTEGER FK | References users.id |
| created_at | DATETIME | Like timestamp |
| UNIQUE | (post_id, user_id) | Prevents duplicate likes |
| Column | Type | Description |
|---|---|---|
| id | INTEGER PK | Auto-increment |
| follower_id | INTEGER FK | The user who follows |
| following_id | INTEGER FK | The user being followed |
| created_at | DATETIME | Follow timestamp |
| UNIQUE | (follower_id, following_id) | Prevents duplicate follows |
- Node.js v18 or higher
- npm v8 or higher
-
Clone the repository
git clone https://github.com/YOUR_USERNAME/ModernConnect.git cd CodeAlpha_ModernConnect -
Install dependencies
npm install
-
Seed demo data (optional but recommended)
npm run seed
-
Start the server
npm start
-
Open in browser
http://localhost:3000
After seeding, you can log in with any of these:
| Username | Password |
|---|---|
asra |
demo123 |
alex_dev |
demo123 |
zara_codes |
demo123 |
sam_tech |
demo123 |
- User submits register form → server validates → bcrypt hashes password → saves to DB
req.session.userIdis set → user is "logged in"- On every request,
requireLoginmiddleware checksreq.session.userId - Logout:
req.session.destroy()→ redirect to landing
- User clicks heart button →
toggleLike()inmain.jsfires POST /posts/:id/likeis called (JSON response)- Server checks if like exists → inserts or deletes
- Returns
{ liked, count }→ button UI updates instantly (no page reload)
- User clicks Follow →
toggleFollow()fires POST /users/:id/follow→ server checks if follow exists- Inserts or deletes from
followstable - Returns
{ following, followers }→ button and counter update instantly
- User submits comment form on
/posts/:idpage - Server validates → inserts into
commentstable - Redirect back to same post page → comment appears
This project was built as Task 3 — Social Media Platform for the CodeAlpha Full Stack Development Internship.
Repository: ModernConnect
*Built by Asra *