A modern Angie's List-style platform built with Django 5, Django REST Framework, TailwindCSS, Node.js, PostgreSQL, and Docker. Connect with local professionals for plumbing, electrical, cleaning, mechanics, and more.
- Search & Filter - Find professionals by skill, category, location (city/zip)
- Reviews & Ratings - Real customer reviews with 5-star ratings
- Verified Providers - Verified badge system for trusted professionals
- User Dashboard - Manage your profile and reviews
- Responsive Design - Beautiful UI with TailwindCSS
- Authentication - Complete login/register system
- REST API - Full API for providers, categories, and reviews
- Smart Matching Quiz - Interactive 5-step questionnaire to find your perfect provider match
- Emergency Mode - Find available providers for urgent jobs with real-time availability
- Side-by-Side Compare - Compare up to 3 providers at once (rating, pricing, experience, skills)
- Favorites System - Save providers to your favorites list for quick access
- Quote Request System - Request quotes from providers, track responses, and manage requests
- Provider Gallery/Portfolio - View provider work samples with lightbox image viewer
- Backend: Django 5 + Django REST Framework
- Frontend: Django Templates + TailwindCSS
- Database: PostgreSQL 16
- Containerization: Docker + Docker Compose
- CSS Framework: TailwindCSS 3.4
- Docker and Docker Compose installed
- Git
cd FindAPro
# Create environment file
cp env.sample .env
# Edit .env with your settings (or use defaults for development)# Build and start all containers
docker-compose up --build
# This will:
# - Start PostgreSQL database
# - Run Django migrations
# - Build TailwindCSS
# - Collect static files
# - Create a default superuser (admin/adminpassword)
# - Start the development server- Web App: http://localhost:8000
- Admin Panel: http://localhost:8000/admin
- API Root: http://localhost:8000/api/
Default superuser credentials:
- Username:
admin - Password:
adminpassword
- Python 3.12+
- Node.js 18+
- PostgreSQL 16
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt# Install Node dependencies
npm install
# Build TailwindCSS (one-time)
npm run build:css
# Or watch for changes during development
npm run watch:css# Create .env file
cp env.sample .env
# Edit .env with your database settings
# For local development, update POSTGRES_HOST to 'localhost'# Run migrations
python manage.py migrate
# Create superuser
python manage.py createsuperuser
# Collect static files
python manage.py collectstaticpython manage.py runserver# Start containers
docker-compose up
# Start in background
docker-compose up -d
# Stop containers
docker-compose down
# View logs
docker-compose logs -f web
# Run migrations
docker-compose exec web python manage.py migrate
# Create superuser
docker-compose exec web python manage.py createsuperuser
# Collect static files
docker-compose exec web python manage.py collectstatic
# Open Django shell
docker-compose exec web python manage.py shell
# Run management commands
docker-compose exec web python manage.py <command>
# Rebuild containers
docker-compose up --build# Build CSS (production)
npm run build:css
# Watch for changes (development)
npm run watch:cssWhen using Docker, the Tailwind watcher runs in a separate container automatically.
/- Homepage with search/providers/- Provider search and listing/providers/match/- Smart Matching Quiz/providers/emergency/- Emergency Mode/providers/compare/- Compare Providers/providers/categories/- Browse categories/providers/<slug>/- Provider detail page/accounts/login/- Login/accounts/register/- Register
/accounts/dashboard/- User dashboard/providers/favorites/- My favorites/providers/quotes/- My quote requests/providers/quotes/received/- Provider's received quotes/providers/<slug>/request-quote/- Request a quote
/admin/- Django admin panel
FindAPro/
├── apps/
│ ├── accounts/ # Custom user model, authentication
│ ├── providers/ # Service providers, categories, search
│ ├── reviews/ # User reviews on providers
│ └── core/ # Homepage, utilities, base views
├── config/ # Django project settings
├── templates/ # HTML templates
│ ├── base.html
│ ├── accounts/
│ ├── providers/
│ ├── reviews/
│ └── core/
├── static/
│ ├── src/ # TailwindCSS input
│ └── css/ # TailwindCSS output
├── scripts/ # Docker entrypoint scripts
├── Dockerfile
├── docker-compose.yml
├── requirements.txt
├── package.json
└── tailwind.config.js
Take an interactive 5-step quiz to find providers that match your needs:
- Select service category
- Enter your location
- Choose urgency level
- Select budget range
- Pick your priority (quality, speed, price, or reviews)
The algorithm scores providers based on your preferences and shows top matches with match percentages and reasons.
URL: /providers/match/
Find providers available for urgent jobs right now:
- Filters to only emergency-ready providers
- Shows "Available NOW" vs "Accepts Emergencies"
- Direct call buttons for immediate contact
- Emergency rate information displayed
URL: /providers/emergency/
Compare up to 3 providers simultaneously:
- Rating, reviews, pricing comparison
- Experience, location, verification status
- Skills and services offered
- Emergency availability
- Quick action buttons (View Profile, Request Quote, Call)
URL: /providers/compare/?ids=1,2,3
Save providers to your favorites:
- One-click save/unsave
- Dedicated favorites page
- Accessible from navigation
URL: /providers/favorites/
Request and manage quotes:
- Customers can request quotes from providers
- Providers can respond with pricing
- Track quote status (pending, quoted, accepted, declined)
- Support for emergency requests
URLs:
- Request:
/providers/<slug>/request-quote/ - My Quotes:
/providers/quotes/ - Provider Quotes:
/providers/quotes/received/
View provider portfolios:
- Multiple images per provider
- Featured image support
- Lightbox viewer for full-size images
- Captions and alt text for accessibility
Access: View on provider detail pages
GET /api/providers/ # List all providers
GET /api/providers/?category= # Filter by category
GET /api/providers/?city= # Filter by city
GET /api/providers/?zip= # Filter by zip code
GET /api/providers/?verified= # Filter verified only
GET /api/providers/<id>/ # Provider detail
GET /api/providers/featured/ # Featured providers
GET /api/providers/top_rated/ # Top rated providers
GET /api/categories/ # List all categories
GET /api/categories/<slug>/ # Category detail
GET /api/reviews/ # List reviews
POST /api/reviews/ # Create review (authenticated)
GET /api/reviews/<id>/ # Review detail
PUT /api/reviews/<id>/ # Update review (owner)
DELETE /api/reviews/<id>/ # Delete review (owner)
GET /api/reviews/my_reviews/ # Current user's reviews
- Extended Django AbstractUser
- User types: Customer, Service Provider
- Profile fields: phone, avatar, bio, city, state, zip_code
- name, slug, description, icon, image
- Basic: name, slug, description, tagline
- Category & Skills
- Contact: email, phone, website
- Location: address, city, state, zip_code
- Business: pricing_range, years_experience
- Media: image, logo
- Status: is_verified, is_active, is_featured
- Emergency: is_available_now, accepts_emergency, emergency_rate_info
- Computed: average_rating, review_count
- user, provider (FK)
- rating (1-5), title, comment
- would_recommend, service_date
- helpful_count
- user, provider (FK)
- Timestamp tracking
- provider (FK), image, caption, alt_text
- is_featured, order
- Gallery/portfolio images for providers
- user, provider (FK)
- Request: title, description, timeline, budget
- Contact: preferred_contact, phone
- Location: service_address, service_city, service_zip
- Status: pending, viewed, quoted, accepted, declined, expired
- Provider Response: quote_amount, quote_message, quoted_at
- is_emergency flag for urgent requests
| Variable | Description | Default |
|---|---|---|
| DEBUG | Debug mode | True |
| SECRET_KEY | Django secret key | (generate one) |
| ALLOWED_HOSTS | Allowed hosts | localhost,127.0.0.1 |
| POSTGRES_DB | Database name | findapro |
| POSTGRES_USER | Database user | findapro_user |
| POSTGRES_PASSWORD | Database password | findapro_password |
| POSTGRES_HOST | Database host | db (Docker) / localhost |
| POSTGRES_PORT | Database port | 5432 |
Populate the database with realistic mock data using the built-in command:
docker-compose exec web python manage.py populate_dataThis creates:
- 10 Service Categories (Plumbing, Electrical, Cleaning, HVAC, etc.)
- 10 Mock Users (username:
john_doe,jane_smith, etc. / password:password123) - 13 Service Providers with realistic details and descriptions
- 40-70 Reviews randomly distributed across providers
- Emergency-ready providers with availability settings
- Sample quote requests (if applicable)
Note: Gallery images need to be added manually through the Django Admin panel.
To reset and repopulate:
docker-compose exec web python manage.py flush --noinput
docker-compose exec web python manage.py migrate
docker-compose exec web python manage.py populate_dataYou can also add data manually through:
-
Django Admin (http://localhost:8000/admin)
- Login with
admin/adminpassword - Add categories first, then providers
- Reviews are added by registered users
- Login with
-
Django Shell - For custom data scripting:
docker-compose exec web python manage.py shellIf you see docker-credential-desktop: executable file not found:
# Edit Docker config to remove credential helper
echo '{"auths": {}, "currentContext": "desktop-linux"}' > ~/.docker/config.jsonCheck logs for errors:
docker-compose logs webEnsure PostgreSQL is healthy:
docker-compose ps # Should show "healthy" for dbRebuild CSS manually:
docker-compose exec web npm run build:css- Fork the repository
- Create a feature branch
- Make your changes
- Submit a pull request
MIT License - feel free to use this project for learning or as a starting point for your own marketplace.
