SpinWheeler is an interactive "Spin the Wheel" game platform that allows users to create, publish, and share custom spin wheels with friends, communities, or audiences. Players can join a game via a unique link or Game ID and spin for rewards.
- Create custom wheels with unlimited segments
- Assign rewards (points, items, prizes) to each segment
- Publish & share games via a unique Game ID or link
- Live preview of wheel during creation
- Public spins with fun animations
- Spin history tracking
- Firebase-powered backend for real-time data
- Responsive design with Tailwind CSS
- Frontend: Vite + React + Tailwind CSS
- Backend: Firebase Firestore + Firebase Auth
- State Management: React Context API
- Deployment: Vercel / Netlify
spinwheeler/
│
├── public/ # Static assets (favicon, logo, etc.)
├── src/
│ ├── assets/ # Images, icons, fonts
│ ├── components/ # Reusable UI components
│ │ ├── Button.jsx
│ │ ├── InputField.jsx
│ │ ├── Wheel.jsx # The wheel component
│ │ ├── Modal.jsx
│ │ └── Navbar.jsx
│ │
│ ├── pages/ # Full-page components (routing targets)
│ │ ├── Landing.jsx
│ │ ├── CreateGame.jsx
│ │ ├── Rewards.jsx
│ │ ├── Publish.jsx
│ │ ├── SpinGame.jsx
│ │ └── NotFound.jsx
│ │
│ ├── hooks/ # Custom hooks
│ │ ├── useWheelSpin.js
│ │ └── useGameData.js
│ │
│ ├── context/ # React Context API for global state
│ │ ├── GameContext.jsx
│ │
│ ├── services/ # API calls, backend interaction
│ │ ├── gameService.js
│ │
│ ├── utils/ # Utility functions
│ │ ├── randomizeArray.js
│ │ └── validateInput.js
│ │
│ ├── App.jsx
│ ├── main.jsx
│ └── index.css # Tailwind base styles
│
├── tailwind.config.js
├── package.json
└── vite.config.js
{
"games": {
"gameId_abc123": {
"title": "My First Wheel",
"creatorId": "user_001",
"createdAt": "2025-08-15T10:15:00Z",
"status": "published",
"segments": [
{
"label": "Run",
"color": "#FF5733",
"reward": {
"type": "points",
"value": 50
}
}
],
"spins": {
"spin_001": {
"userId": "guest",
"timestamp": "2025-08-15T10:30:00Z",
"result": {
"label": "Run",
"reward": {
"type": "points",
"value": 50
}
}
}
}
}
}
}rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId} {
allow read: if request.auth != null;
allow create: if request.auth != null && request.auth.uid == userId;
allow update, delete: if request.auth != null && request.auth.uid == userId;
}
match /games/{gameId} {
allow read: if resource.data.status == "published" ||
(request.auth != null && request.auth.uid == resource.data.creatorId);
allow create: if request.auth != null;
allow update, delete: if request.auth != null &&
request.auth.uid == resource.data.creatorId;
match /spins/{spinId} {
allow create: if get(/databases/$(database)/documents/games/$(gameId))
.data.status == "published";
allow read: if get(/databases/$(database)/documents/games/$(gameId))
.data.status == "published" ||
(request.auth != null &&
request.auth.uid == get(/databases/$(database)/documents/games/$(gameId))
.data.creatorId);
}
}
}
}git clone https://github.com/yourusername/spinwheeler.git
cd spinwheelernpm install- Create a Firebase project in the Firebase Console
- Enable Firestore & Authentication
- Add your Firebase config to
.env:
VITE_FIREBASE_API_KEY=your_api_key
VITE_FIREBASE_AUTH_DOMAIN=your_project.firebaseapp.com
VITE_FIREBASE_PROJECT_ID=your_project_id
VITE_FIREBASE_STORAGE_BUCKET=your_project.appspot.com
VITE_FIREBASE_MESSAGING_SENDER_ID=your_sender_id
VITE_FIREBASE_APP_ID=your_app_idnpm run devThis project is licensed under the MIT License.
Abdulsamad Sadiq
Passionate blockchain developer & builder 🚀