A modern social networking platform designed specifically for Wilfrid Laurier University students to connect, share updates, and collaborate academically.
WLU Connect is a university-focused social media platform that enables students to:
- Share posts and updates with the campus community
- Discover and register for club events
- Form and join course-specific study groups
- Build their academic network through following other students
- JWT-based authentication with secure access and refresh tokens
- Protected routes ensuring only authenticated users can post, comment, and interact
- Password hashing using bcrypt for secure credential storage
- Customizable profiles with bio, program of study, and profile pictures
- Image upload and cropping with Cloudinary integration
- Follow/unfollow system to build your campus network
- User statistics displaying follower count, following count, and total posts
- Pagination for efficient loading of user posts
- Rich post creation with text content and image attachments
- Post categorization with 6 types: General, Career, Academic, Question, Opportunity, Achievement
- Like system with real-time count updates
- Commenting system with nested replies and pagination
- Post deletion for content ownership
- Character limits to maintain post quality (500 characters)
- Image preview before posting
- Event discovery with search and faculty filtering
- Event registration with capacity management
- Event details including date, time, location, and club organizer
- Registration tracking showing current capacity and member list
- Course-based organization using course codes
- Flexible scheduling supporting both one-time sessions and recurring meetings
- Location tracking for physical or virtual meeting spaces
- Member capacity limits to maintain effective group sizes
- Join/leave functionality with instant updates
- Search and filter by course code, group name, or creator
- Group tabs to view all available groups or just your memberships
Frontend
react-easy-crop: Professional image cropping for profile picturesdate-fns/ Native Date: Date formatting and manipulation
Backend
jsonwebtoken: JWT token generation and verificationbcrypt: Password hashing and comparisonpg: PostgreSQL client for Node.jscors: Cross-origin resource sharingdotenv: Environment variable managementexpress-rate-limit: API rate limiting for security
Key Tables:
users: User accounts and profilesposts: User-generated contentcomments: Post comments and replieslikes: Post like trackingfollows: User follow relationshipsevents: Club events and activitiesevent_registrations: Event attendance trackingstudy_groups: Academic study groupsstudy_group_members: Study group memberships
User Login β Backend validates credentials β JWT issued
β
JWT stored in localStorage
β
All API requests include JWT in Authorization header
β
Backend middleware validates JWT β Route handler executes
User selects image β Image cropped in browser
β
Cropped file sent to backend
β
Backend receives file
β
Upload to Cloudinary
β
Cloudinary URL returned
β
URL saved in PostgreSQL
β
Frontend displays image from Cloudinary CDN
wlu-connect/
βββ client/ # Frontend React application
β βββ src/
β β βββ assets/ # Static assets (images, icons)
β β βββ components/ # Reusable UI components
β β β βββ Comment.tsx
β β β βββ CreatePost.tsx
β β β βββ EventCard.tsx
β β β βββ NavBar.tsx
β β β βββ Post.tsx
β β βββ context/ # React Context providers
β β β βββ AuthContext.tsx
β β βββ modals/ # Modal components
β β β βββ CreateGroupModal.tsx
β β β βββ GroupMembersModal.tsx
β β βββ pages/ # Page components
β β β βββ EditProfile.tsx
β β β βββ EventInfo.tsx
β β β βββ Events.tsx
β β β βββ FollowList.tsx
β β β βββ GroupStudy.tsx
β β β βββ Home.tsx
β β β βββ Login.tsx
β β β βββ Profile.tsx
β β β βββ ResendVerification.tsx
β β β βββ Signup.tsx
β β β βββ VerifyEmail.tsx
β β βββ types/ # TypeScript type definitions
β β β βββ comment.ts
β β β βββ event.ts
β β β βββ post.ts
β β β βββ profile.ts
β β β βββ search.ts
β β β βββ user.ts
β β βββ utils/ # Utility functions
β β βββ App.tsx # Main app component
β β βββ index.css # Global styles
β β βββ main.tsx # Entry point
β β βββ svg.d.ts # SVG type declarations
β βββ public/ # Static assets
β βββ .env.development # Development environment variables
β βββ index.html # HTML template
β βββ package.json
β
βββ server/ # Backend Express application
β βββ src/
β β βββ config/ # Configuration files
β β β βββ cloudinary.ts
β β β βββ database.ts
β β β βββ env.ts
β β βββ middleware/ # Express middleware
β β β βββ auth.ts
β β β βββ rateLimit.ts
β β βββ routes/ # API route handlers
β β β βββ auth.ts
β β β βββ clubs.ts
β β β βββ comments.ts
β β β βββ events.ts
β β β βββ likes.ts
β β β βββ posts.ts
β β β βββ search.ts
β β β βββ studyGroups.ts
β β β βββ upload.ts
β β β βββ users.ts
β β βββ types/ # TypeScript type definitions
β β β βββ express.d.ts
β β βββ utils/ # Utility functions
β β β βββ email.ts
β β βββ index.ts # Server entry point
β βββ requests/ # API request examples/tests
β βββ .env # Environment variables
β βββ package.json
β βββ tsconfig.json
β
βββ README.md
POST /auth/signup Create new user account
POST /auth/login Authenticate user
POST /auth/refresh Refresh access token
GET /users/me/profile Get current user profile
GET /users/:username Get user by username
GET /users/:username/complete Get complete profile data
PUT /users/:username Update user profile
POST /users/:username/follow Follow a user
DELETE /users/:username/follow Unfollow a user
GET /users/:username/follow/status Check follow status
GET /posts/all Get all posts (paginated)
GET /posts/:id Get single post
POST /posts Create new post
DELETE /posts/:id Delete post
GET /posts/:id/comments Get post comments
POST /posts/:id/comments Add comment
POST /likes/posts/:id/like Like a post
DELETE /likes/posts/:id/like Unlike a post
GET /likes/posts/:id/me Check if user liked post
GET /likes/posts/:id/count Get like count
GET /events/all Get all events
GET /events/:id Get event details
POST /events/:id/register Register for event
DELETE /events/:id/register Unregister from event
GET /events/:id/register/status Check registration status
GET /study-groups Get all study groups
GET /study-groups/:id Get group details
POST /study-groups Create study group
POST /study-groups/:id/join Join study group
DELETE /study-groups/:id/leave Leave study group
GET /study-groups/me/memberships Get user's groups
POST /upload/image Upload image to Cloudinary
- Password Hashing: Bcrypt with 10 salt rounds
- JWT Authentication: Secure token-based auth with refresh tokens
- Rate Limiting: Prevents abuse of upload and authentication endpoints
- CORS Configuration: Restricts cross-origin requests
- Input Validation: Prevents SQL injection and XSS attacks
- File Type Validation: Only allows image uploads (JPEG, PNG, GIF, WebP)
- File Size Limits: 5MB maximum for uploads
- Protected Routes: Middleware ensures authentication for sensitive operations
The React frontend is deployed on Vercel with automatic deployments from the main branch. Vercel handles the build process (npm run build) and serves the static assets through their global CDN.
Configuration:
- Build command:
npm run build - Output directory:
dist - Environment variables configured for API URL pointing to the Railway backend
The Express server and PostgreSQL database are both hosted on Railway, providing a unified backend infrastructure.
Setup:
- Node.js server deployed from the
/serverdirectory - PostgreSQL database provisioned through Railway's managed database service
- Environment variables configured for database connection, JWT secrets, and Cloudinary credentials
- Automatic deployments triggered on push to main branch
This project is an independent portfolio demonstration created by Hunter Shierman. It is not affiliated with, endorsed by, or associated with Wilfrid Laurier University. Any reference to "WLU" or "Wilfrid Laurier University" is for descriptive purposes only to indicate the target audience and inspiration for the platform.