A minimal MVP photo voting web app for consenting adult participants. Rate profiles on a scale of 1-10 and see how they rank on the leaderboard.
⚠️ Important Disclaimer: This is a demo prototype only. Use exclusively with fictional placeholder profiles (default) or consenting adult participants who explicitly opt in. See Safety & Ethics for details.
- Features
- Screenshots
- Tech Stack
- Getting Started
- Project Structure
- Pages & Routes
- Data Models
- Scripts
- Safety & Ethics
- Contributing
- License
- Tinder-style Voting — Swipe through profiles and rate them 1-10 with a beautiful card-based UI
- Leaderboard Rankings — See profiles ranked by average score with a podium-style top 3 display
- Vote Deduplication — Browser session tracking prevents duplicate votes on the same profile
- Responsive Design — Works seamlessly on mobile and desktop devices
- Fictional Profiles — Ships with 15 demo profiles using DiceBear avatars (no real photos)
- Privacy-First — No authentication required, no personal data collected
| Voting Page | Leaderboard |
|---|---|
| Rate profiles 1-10 in a Tinder-style card interface | See top-ranked profiles with scores |
| Technology | Purpose |
|---|---|
| Next.js 14 | React framework with App Router |
| TypeScript | Type-safe JavaScript |
| Prisma | Database ORM & migrations |
| SQLite | Lightweight file-based database |
| Tailwind CSS | Utility-first CSS framework |
| DiceBear | Procedural avatar generation |
- Node.js 18+ — Download here
- npm or yarn — Comes with Node.js
-
Clone the repository
git clone https://github.com/robinslevel/rateus.git cd rateus/heartrank -
Install dependencies
npm install
-
One-command setup (generates Prisma client, creates database, seeds demo data)
npm run setup
This runs:
prisma generate— Generate the Prisma clientprisma db push— Create SQLite database and tablesseed— Populate 15 fictional demo profiles
-
Start the development server
npm run dev
-
Open in browser
Visit http://localhost:3000
heartrank/
├── prisma/
│ ├── schema.prisma # Database schema (Profile, Vote models)
│ └── seed.ts # Demo profile seeding script
├── public/ # Static assets
├── src/
│ ├── app/
│ │ ├── globals.css # Global styles + Tailwind
│ │ ├── layout.tsx # Root layout with header/footer
│ │ ├── page.tsx # Home: Voting page
│ │ ├── about/
│ │ │ └── page.tsx # About & disclaimer page
│ │ └── leaderboard/
│ │ └── page.tsx # Rankings page
│ └── lib/
│ ├── mockData.ts # Client-side mock data for static deployment
│ └── prisma.ts # Prisma client singleton
├── package.json
├── tailwind.config.js
├── tsconfig.json
└── next.config.js
| Route | Page | Description |
|---|---|---|
/ |
Voting | Rate profiles 1-10 in a Tinder-style card UI. Shows profile photo, name, age, location, bio, and interest tags. |
/leaderboard |
Rankings | View ranked profiles by average score. Top 3 displayed in podium format with gold/silver/bronze styling. |
/about |
About | Important disclaimer, how the app works, technical details, and safety principles. |
| Field | Type | Description |
|---|---|---|
id |
String | Unique identifier (CUID) |
name |
String | Display name |
age |
Int | Age in years |
bio |
String | Profile description |
location |
String | City, State |
interests |
String | Comma-separated tags |
imageUrl |
String | Profile photo URL (DiceBear) |
createdAt |
DateTime | Creation timestamp |
votes |
Vote[] | Related votes |
| Field | Type | Description |
|---|---|---|
id |
String | Unique identifier (CUID) |
score |
Int | Rating 1-10 |
sessionId |
String | Browser session for deduplication |
createdAt |
DateTime | Vote timestamp |
profileId |
String | Foreign key to Profile |
Constraint: One vote per profile per session (@@unique([profileId, sessionId]))
| Command | Description |
|---|---|
npm run dev |
Start development server on port 3000 |
npm run build |
Create production build |
npm run start |
Start production server |
npm run setup |
Full setup: generate + push + seed |
npm run db:generate |
Generate Prisma client |
npm run db:push |
Push schema to database |
npm run db:seed |
Seed demo profiles |
npm run db:studio |
Open Prisma Studio (database GUI) |
✅ Fictional placeholder profiles (ships by default)
✅ Consenting adult participants who explicitly opt-in
✅ Private friend groups with mutual agreement
❌ Rating photos of real people without explicit consent
❌ Photos of minors under any circumstances
❌ Scraped photos from social media or other sources
❌ Judging strangers or non-consenting individuals
- No authentication — No accounts or personal data collected
- No face recognition — No biometric analysis
- Session-based voting — Browser cookies only, no user tracking
- Local database — All data stays on your machine (SQLite)
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is for educational and demonstration purposes only. Use responsibly and ethically.
Built with ❤️ for responsible, consensual fun