A full-stack social media platform designed specifically for sports card collectors to share, buy, sell, and trade cards.
- User authentication (signup/login with JWT)
- User profiles with bio, location, and profile images
- Follow/unfollow other collectors
- Create posts with text and up to 10 card images
- Like and comment on posts
- Direct messaging between users
- Tag cards by sport, player, team, year, brand, and condition
- Advanced search by card attributes
- Three post types: Showcase, For Sale, For Trade
- Price listings for cards for sale
- Marketplace feed with filters
- Create multiple collections
- Add cards to collections with notes and values
- Track your card inventory
- Showcase your prized collections
- Home feed (posts from followed users)
- Explore feed (all posts, chronological)
- Marketplace feed (for sale/trade only)
- Node.js + Express
- SQLite database (better-sqlite3)
- JWT authentication
- Bcrypt password hashing
- Multer for file uploads
- React 18
- React Router for navigation
- Axios for API calls
- Tailwind CSS for styling
- Vite as build tool
cardboard/
├── server/
│ ├── routes/ # API routes
│ ├── middleware/ # Authentication middleware
│ ├── utils/ # Helper functions
│ ├── database.js # Database setup and schema
│ └── server.js # Main server file
├── client/
│ ├── src/
│ │ ├── components/ # React components
│ │ ├── pages/ # Page components
│ │ ├── context/ # Auth context
│ │ ├── utils/ # API utilities
│ │ ├── App.jsx # Main app component
│ │ └── main.jsx # React entry point
│ └── public/ # Static assets
├── uploads/ # User uploaded images
├── cardboard.db # SQLite database
└── package.json # Backend dependencies
- Node.js (v16 or higher)
- npm
- Clone the repository:
git clone <your-repo-url>
cd cardboard- Install backend dependencies:
npm install- Install frontend dependencies:
cd client
npm install
cd ..- Create environment file:
cp .env.example .env- Edit
.envand update the JWT_SECRET:
PORT=3000
JWT_SECRET=your-secure-random-secret-key
NODE_ENV=development
CLIENT_URL=http://localhost:5173
- Start the backend server:
npm run dev- In another terminal, start the frontend:
npm run client- Open your browser to http://localhost:5173
- Build the frontend:
npm run build- Start the production server:
npm start- The app will be available at http://localhost:3000
- Install PM2 globally:
sudo npm install -g pm2- Build the frontend:
npm run build- Start the app with PM2:
pm2 start server/server.js --name cardboard- Save PM2 configuration:
pm2 save
pm2 startup- Configure reverse proxy (nginx example):
server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}Update .env for production:
PORT=3000
JWT_SECRET=your-very-secure-production-secret
NODE_ENV=production
CLIENT_URL=https://your-domain.com
POST /api/auth/signup- Create new accountPOST /api/auth/login- Login to account
GET /api/users/:id- Get user profilePUT /api/users/:id- Update profilePOST /api/users/:id/profile-image- Upload profile imageGET /api/users/:id/posts- Get user's postsPOST /api/users/:id/follow- Follow userDELETE /api/users/:id/follow- Unfollow user
POST /api/posts- Create postGET /api/posts/:id- Get single postPUT /api/posts/:id- Update postDELETE /api/posts/:id- Delete postPOST /api/posts/:id/like- Like postDELETE /api/posts/:id/like- Unlike postGET /api/posts/:id/comments- Get commentsPOST /api/posts/:id/comments- Add comment
GET /api/feed/home- Home feed (following)GET /api/feed/explore- Explore feed (all)GET /api/feed/marketplace- Marketplace feed
GET /api/search/users?q=query- Search usersGET /api/search/posts?q=query&sport=...- Search posts
GET /api/messages/conversations- Get conversationsGET /api/messages/:userId- Get messages with userPOST /api/messages- Send message
GET /api/collections- Get user's collectionsPOST /api/collections- Create collectionGET /api/collections/:id- Get collection detailsPOST /api/collections/:id/cards- Add card to collection
The application uses SQLite with the following main tables:
users- User accountsposts- User posts/cardspost_images- Card imagespost_tags- Card metadata (sport, player, etc.)follows- User follow relationshipslikes- Post likescomments- Post commentsmessages- Direct messagescollections- User collectionscollection_cards- Cards in collections
- Passwords hashed with bcrypt (10 rounds)
- JWT tokens for authentication
- Protected routes requiring authentication
- File upload validation (type and size limits)
- SQL injection protection (parameterized queries)
- CORS enabled for frontend communication
MIT
For issues and questions, please open an issue on GitHub.