DEV Community

Cover image for 🏘️ CommuneXR – Turning Neighbors Into a Connected Community (Built in 48h)
Malika
Malika Subscriber

Posted on

🏘️ CommuneXR – Turning Neighbors Into a Connected Community (Built in 48h)

DEV Weekend Challenge: Community

🏘️ CommuneXR – Rebuilding Real Neighborhood Communities Through Technology

This is a submission for the DEV Weekend Challenge: Community


The Community

My neighborhood. My neighbors. The people on my street, in my building, at my local park.

I built this for the real, physical community I live in.

We live in the same place, but we rarely connect. Someone needs help fixing a bike, another person offers guitar lessons, someone else has tools to lend β€” but these needs and skills never meet.

CommuneXR transforms anonymous neighbors into a connected, supportive community.


What I Built

CommuneXR is a hyper-local platform that turns your neighborhood into a live map of mutual aid.

✨ Key Features

Feature Description
πŸ“ Interactive Map Real geolocation with React-Leaflet. Green markers for offers 🀝, red for needs πŸ†˜
πŸ’¬ Exchange System Structured lifecycle: proposed β†’ accepted β†’ completed with full accountability
πŸ† Gamification Engine Points (+10 per exchange) and 4 unlockable badges via Rails callbacks
πŸ“Š Personal Dashboard Track exchanges, view badges, monitor your community impact
πŸ”Ž Smart Filters Filter by type (offer/need) and category in real-time
πŸ”„ Exchange Management Accept, decline, or complete exchanges with instant UI feedback

πŸ† Badges System

Badge How to Earn
🌟 First Helper Complete your first exchange
🏑 Good Neighbor Complete 5 exchanges
🦸 Community Hero Complete 10 exchanges
πŸ”§ Skilled Helper Help in 3 different categories

Demo

▢️ Watch the 2:49 demo: https://youtu.be/DE8ptjoFxhw

πŸ“Έ Screenshots

Interactive Map Create Service
Map New Service
Service Details Dashboard
Details Dashboard

Code

Frontend Repository

git clone https://github.com/joupify/communeXR_front.git
cd communeXR_front
npm install
npm start
Enter fullscreen mode Exit fullscreen mode

πŸ”— GitHub: https://github.com/joupify/communeXR_front

Backend Repository

bash
git clone https://github.com/joupify/communeXR.git
cd communeXR
bundle install
rails db:create db:migrate db:seed
rails s -p 3000
Enter fullscreen mode Exit fullscreen mode

πŸ”— GitHub: https://github.com/joupify/communeXR

Project Structure

text
communeXR/
β”œβ”€β”€ backend/ # Rails API
β”‚ β”œβ”€β”€ app/models/
β”‚ β”œβ”€β”€ app/controllers/
β”‚ └── db/
└── frontend/ # React app
β”œβ”€β”€ src/components/
β”œβ”€β”€ src/pages/
└── public/

How I Built It

Tech Stack
Backend:

πŸŸ₯ Ruby on Rails 7 (API mode)
🐘 PostgreSQL for database
πŸ” Devise for authentication
πŸ“ Geocoder for location services
πŸš€ Render.com for deployment

Frontend:

βš›οΈ React 18 with Hooks
πŸ—ΊοΈ React-Leaflet + OpenStreetMap
🎨 Bootstrap 5 for styling
πŸ”„ React Router for navigation
πŸ“‘ Fetch API for REST calls
πŸš€ Render.com for deployment

Key Challenges Solved

πŸ—ΊοΈ Custom Map Markers

javascript
const getServiceIcon = (type) => L.divIcon({
  html: `<div style="
    background-color: ${type === 'offer' ? '#22c55e' : '#ef4444'};
    width: 40px; height: 40px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    font-size: 20px; border: 3px solid white;
  ">${type === 'offer' ? '🀝' : 'πŸ†˜'}</div>`,
  iconSize: [40, 40],
  iconAnchor: [20, 40],  // πŸ‘ˆ Key: anchor at bottom center
  popupAnchor: [0, -40]
});

Enter fullscreen mode Exit fullscreen mode

πŸ† Automatic Badge Attribution

ruby
# app/models/exchange.rb
after_update :check_badges, if: :completed?

def check_badges
  # First exchange β†’ "First Helper" badge
  if helper.helped_exchanges.completed.count == 1
    badge = Badge.find_by(name: "First Helper")
    UserBadge.find_or_create_by(user: helper, badge: badge)
  end

  # 5 exchanges β†’ "Good Neighbor" badge
  if helper.helped_exchanges.completed.count == 5
    badge = Badge.find_by(name: "Good Neighbor")
    UserBadge.find_or_create_by(user: helper, badge: badge)
  end

  # +10 points per completed exchange
  helper.increment!(:points, 10)
end

Enter fullscreen mode Exit fullscreen mode

πŸ”„ Exchange Lifecycle Management

ruby
# app/models/exchange.rb
enum status: { proposed: 0, accepted: 1, completed: 2, rejected: 3 }
Enter fullscreen mode Exit fullscreen mode

πŸ“Š Complex Nested JSON

ruby
# app/controllers/services_controller.rb
def show
  @service = Service.includes(:user, exchanges: [:requester, :helper]).find(params[:id])

  render json: @service.as_json(
    include: {
      user: { 
        only: [:id, :username, :points],
        include: { badges: { only: [:id, :name, :icon] } }
      },
      exchanges: { 
        include: { 
          requester: { only: [:id, :username] },
          helper: { only: [:id, :username] }
        } 
      }
    }
  )
end

Enter fullscreen mode Exit fullscreen mode

Deployment Architecture

  • Frontend: React app hosted on Render.com πŸš€
  • Backend: Rails API hosted on Render.com πŸš€
  • Database: PostgreSQL hosted on Render.com 🐘

All services are deployed on Render.com, with the frontend communicating with the backend via REST API calls.

Data Model

ruby
User
β”œβ”€β”€ has_many :services
β”œβ”€β”€ has_many :helped_exchanges (as helper)
β”œβ”€β”€ has_many :requested_exchanges (as requester)
β”œβ”€β”€ has_many :badges through: :user_badges
└── points :integer

Service
β”œβ”€β”€ service_type :offer or :need
β”œβ”€β”€ status :open / :in_progress / :closed
β”œβ”€β”€ latitude & longitude
└── belongs_to :User

Exchange
β”œβ”€β”€ belongs_to :service
β”œβ”€β”€ belongs_to :helper (User)
β”œβ”€β”€ belongs_to :requester (User)
β”œβ”€β”€ status :proposed / :accepted / :completed / :rejected
└── message :text

Enter fullscreen mode Exit fullscreen mode

πŸ“Š API Endpoints

Method  Endpoint    Description
GET /services   List all services
GET /services/:id   Get service details
POST    /services   Create a service
POST    /exchanges  Create an exchange
PATCH   /exchanges/:id  Update exchange status
GET /users/:id  Get user profile
GET /users/:id/exchanges    Get user exchanges

Enter fullscreen mode Exit fullscreen mode

Why This Matters

In a world of digital connections, we've lost touch with our physical neighbors.

CommuneXR brings back what matters:

🀝 Real help from real people
🌱 Stronger communities through sharing
🏘️ Safer neighborhoods when we know each other

This project is:
βœ… Full-stack and functional
βœ… Structured domain modeling with clean architecture
βœ… Real community problem solved
βœ… Gamified engagement engineered
βœ… Built in 48 hours

"Community is not a feature. It is infrastructure."

πŸš€ What's Next

⚑ Real-time chat with Action Cable
πŸ“± Mobile app with React Native
⭐ Trust & rating system for exchanges
πŸ“… Neighborhood event layer (meetups, garage sales...)
🌐 Multi-language support (i18n)
πŸ” Production-ready multi-user authentication

Links

Resource Link
🌍 Live App https://communexr-front.onrender.com
πŸŽ₯ Demo Video https://youtu.be/DE8ptjoFxhw
πŸ“ Frontend Repo https://github.com/joupify/communeXR_front
πŸ“ Backend Repo https://github.com/joupify/communeXR

πŸ™ Acknowledgments

πŸ‘₯ The DEV community – for this amazing challenge
πŸ—ΊοΈ Leaflet & OpenStreetMap – for the incredible mapping tools
🏘️ My neighbors – you know who you are!

Built in 48 hours with ❀️ for my neighborhood

Top comments (0)