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
- Provider Profile Creation - Multi-step profile builder for professionals to join and create business profiles
- Business Hours Management - Set weekly business hours for each day of the week
- Service Areas - Define coverage zones with ZIP codes and radius
- Certifications & Licenses - Optional certification tracking with verification documents
- Profile Completeness Tracking - Real-time completion percentage with 50% minimum to go live
- 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
/providers/join/- Join as a professional (landing page)/providers/profile/create/- Multi-step profile creation wizard/providers/profile/preview/- Preview profile before submission/providers/profile/status/- View profile status and completion/providers/profile/edit/- Edit existing provider profile
/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
Comprehensive multi-step profile builder for professionals:
5-Step Creation Process:
- Basic Information - Business name, category, tagline, description, skills
- Contact & Location - Email, phone, website, full address
- Business Details - Pricing range, years of experience, business hours, service areas
- Media & Portfolio - Logo upload, main image, gallery images
- Availability & Emergency - Availability status, emergency acceptance, rate information
Key Features:
- Draft Mode - Save progress and complete later
- Progress Tracking - Real-time completion percentage with visual progress bar
- 50% Minimum - Must complete at least 50% of profile to submit
- Immediate Activation - Profiles go live immediately upon submission (no approval needed)
- Business Hours - Set weekly schedule for each day (open/close times or closed)
- Service Areas - Add multiple service locations with ZIP codes and radius
- Certifications - Optional certification tracking (admin verification available)
Registration Flow:
- New users can select "Service Provider" during registration โ automatically redirected to profile creation
- Existing users can click "Join as Pro" from navigation or homepage
- One profile per user (enforced)
URLs:
- Join:
/providers/join/ - Create:
/providers/profile/create/ - Status:
/providers/profile/status/ - Edit:
/providers/profile/edit/
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
- Properties: is_provider, is_customer, has_provider_profile, full_name
- 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, is_draft
- Approval: approval_status (draft, approved, rejected, suspended), approved_at, submitted_for_review_at
- Emergency: is_available_now, accepts_emergency, emergency_rate_info
- Computed: average_rating, review_count, completion_percentage
- Methods: can_submit(), calculate_completion_percentage()
- 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
- provider (OneToOne FK)
- Monday-Sunday: open, close, closed (for each day)
- notes (additional availability information)
- provider (FK)
- zip_code, city, state
- radius_miles (service radius in miles)
- is_primary (primary service location flag)
- created_at
- provider (FK)
- name, issuing_organization, license_number
- issue_date, expiry_date
- verification_document (file upload)
- is_verified (admin verified flag)
- created_at, updated_at
- Property: is_expired (checks expiry date)
| 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.
