Website: https://social.ducle.online Default account for guests:
- Email: [email protected]
- Password: guestofduc
This project is a modern Instagram-like social media platform built with Next.js 15 and MongoDB, focused on scalability, speed, and user experience.
It supports dynamic content such as posts, reels (short-form videos), comments, likes, follow requests, saved posts, and personalized notifications. Authenticated users can interact in real time, while admins can manage user accounts and content.
| Layer | Tools & Frameworks |
|---|---|
| Frontend | Next.js 15 App Router, Tailwind CSS, TypeScript, HeroUI |
| Authentication | Auth.js with Google OAuth & Custom Credentials Provider |
| Backend / API | Next.js Actions, Server Components, MongoDB, Mongoose |
| Data Fetching | @tanstack/react-query (Queries & Mutations), refetchInterval, infiniteQuery, virtual |
| Form Handling & Validation | Zod |
| Realtime/Notifications | In-app Notification System with support for Post, Comment, Like, Follow events |
| Caching & Optimization | React Query Cache, Client State Memoization |
| UI Libraries | HeroUI, Headless UI |
- Google OAuth and Credentials Login/Register via Auth.js
- Role-based access:
UservsAdmin - Verified and active status checks
- Follow request approval support (private profiles)
- Posts: Photo & video uploads with captions and privacy settings (
Public,Followers only, etc.) - Likes and Comments with real-time counters
- Each post includes metadata like view count, created time, and author info
-
Infinite Feed with support for:
- Dynamic pagination via
tanstack/react-query+tanstack/virtual - Reels-style feed for videos
refetchIntervalto load new posts when available
- Dynamic pagination via
-
Scroll virtualization for high performance rendering of large lists
-
Custom notification system supports:
- Likes
- Comments
- Follows (request and acceptance)
- Admin updates
-
Notifications stored in DB via a dedicated
Notificationmodel -
In-app real-time delivery & badge count
- Full-text search for users
- Explore tab with trending or suggested content
- Users can save posts to their private collection
- Admin dashboard with CRUD over:
- Users
- Role-based permissions to restrict access to sensitive functionality
- Written in TypeScript for safety and maintainability
- Modular schema design with Mongoose interfaces
- Uses Next.js Actions for colocated server logic
- Graceful error handling and rollback-safe updates
- Strongly typed with
Zodschemas for all forms (login, register, update profile)
username,email,fullName,bio,avatarUrl- Role, verification, and active status
- Flags for follow approval
- Countable fields:
postsCount,followersCount,followingCount
- Media (images/videos) with caption and privacy setting
- Linked to an author (User)
- Tracks
likeCount,commentCount, and timestamps
- Linked to a
PostandAuthor - Stores content and creation date
- Maps users to liked posts
- Users can save posts privately for future reference
- Follow request/acceptance logic
- Links between
followerandfollowing - Supports request state (
isAccepted)
-
Central system for all real-time events:
type: POST_LIKED, COMMENTED, FOLLOWED, etc.- Optional references to related post/comment/follow
isReadflag for UI handling
- Built with HeroUI and Tailwind CSS
- Responsive layouts for feed, reels, explore, and profile
- Admin and user dashboards
- Dark/light theme ready
- Modal-based post preview and profile viewer
A customizable carousel component to display multiple media items (images and videos) in a sliding interface.
-
Supports Images and Videos: Renders media based on their type (image or video).
-
Manual Slide Navigation: Includes next and previous buttons for navigating slides.
-
Dots Indicator: Visual dots show the current active slide and allow direct navigation.
-
Volume Control for Videos:
- Allows users to toggle sound on/off for videos.
- Stores volume preferences persistently in local storage (
VolumnType.ONorOFF).
-
Responsive Design: Adjustable width and aspect ratio via props (
widthAndAspect,itemWidthHeight). -
Looping Slides: Carousel navigation loops back at the start or end for continuous browsing.
Display multiple images or videos attached to a post, letting users swipe or click arrows to view all media.
A reels-style vertical feed that allows users to scroll through video posts infinitely, similar to TikTok or Instagram Reels.
-
Infinite Scroll Loading:
- Uses React Queryβs
useInfiniteQueryto fetch paginated posts dynamically. - Automatically fetches next page when scrolling reaches the last item.
- Uses React Queryβs
-
Scroll Navigation:
- Users scroll up/down with the mouse wheel to navigate between videos.
- Scroll debounce prevents rapid accidental changes.
-
Video Filtering:
- Filters media to only show video items for reel experience.
-
Comment List Toggle:
- Users can open and close the comment list for the current video.
-
Navigation Buttons:
- Provides arrow buttons for manual navigation up/down.
-
Performance Optimization:
- Uses memoization (
useMemo) to flatten and filter posts efficiently.
- Uses memoization (
A dedicated page where users can consume short video posts one by one by scrolling vertically.
Displays an individual video post in the reels feed with interactive social features.
-
Video Playback:
- Plays a single video with loop and autoplay.
- Sound toggle button for muting/unmuting video with persistence in local storage.
-
Post Interaction Buttons:
- Like button with real-time like count.
- Comment button to toggle the comment list visibility.
- Share button placeholder for sharing functionality.
-
User Profile Info:
- Displays author's avatar, username, and verification badge.
- Username links to the authorβs profile page.
- Follow button shown when viewing posts of other users.
-
Loading Placeholder:
- Shows skeleton UI while the post data is loading.
Render each video in the reels feed with all social interaction buttons and author info for a rich media experience.
The project defines a centralized routing system using the AppRouteManager object for cleaner navigation and maintainability.
| Route | Description |
|---|---|
/ |
Home (News Feed) |
/login |
Login page |
/register |
Registration page |
/welcome-new-member |
Welcome screen after successful registration |
/explore |
Explore content from all users |
/reels |
Instagram-style short video feed |
/posts/:postId |
View a specific post by ID |
| Route | Description |
|---|---|
/profile?userId={id} |
View a user's profile |
/profile?userId={id}&queryTab=saved |
View the saved posts of a user |
/user-settings/edit-profile |
Edit your profile |
/user-settings/privacy |
Manage privacy settings |
| Route | Description |
|---|---|
/admin |
Admin dashboard overview |
/admin/manage-users |
User management page |
/admin/manage-users/:userId |
View and manage specific user details |
π Some of these routes are protected and require user authentication or admin roles based on the Auth.js configuration and role-based permissions (e.g.,
Role.ADMIN).
All routes are programmatically accessible using the AppRouteManager object:
AppRouteManager.profile("abc123")
// -> "/profile?userId=abc123"
AppRouteManager.saved("abc123")
// -> "/profile?userId=abc123&queryTab=saved"
AppRouteManager.posts("xyz789")
// -> "/posts/xyz789"This helps avoid hardcoding route strings and provides type safety across the codebase.
Follow these steps to set up and run the Social Network project locally:
git clone https://github.com/le-minh-duc-dev/social-network.git
cd social-networkCreate a .env file in the root directory with the following structure. Replace the placeholder values with your actual credentials:
# === Site Info ===
NEXT_PUBLIC_BASE_URL=https://social.ducle.online
NEXT_PUBLIC_SITE_NAME=social.ducle.online
# === MongoDB ===
MONGODB_USERNAME=your_mongodb_username
MONGODB_PASSWORD=your_mongodb_password
MONGODB_DB=ducle_db
MONGODB_URI=mongodb+srv://your_mongodb_username:[email protected]/ducle_db?retryWrites=true&w=majority&appName=Cluster0
# === Authentication (NextAuth) ===
AUTH_SECRET=your_auth_secret
AUTH_GOOGLE_ID=your_google_oauth_client_id
AUTH_GOOGLE_SECRET=your_google_oauth_client_secret
# === Cloudinary (Image Uploads) ===
CLOUDINARY_KEY=your_cloudinary_key
CLOUDINARY_SECRET=your_cloudinary_secret
CLOUDINARY_CLOUD_NAME=your_cloud_name
NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME=your_cloud_name
CLOUDINARY_PRESET=your_preset
NEXT_PUBLIC_CLOUDINARY_PRESET=your_preset
# === Email Service (Resend) ===
RESEND_API_KEY=your_resend_api_keyInstall dependencies and start the development server:
npm install
npm run devVisit
http://localhost:3000in your browser to view the app.
Below are screenshots showcasing the main user interface of the chat system.
LΓͺ Minh Δα»©c Final year student at Can Tho University
- π Personal goal: Professional Java & Spring Developer
- π§ Passionate about clean code, scalable systems, and full-stack architecture
- βοΈ Contact: [email protected]





















