SafeSpot is a modern, interactive web application that helps users check safety ratings, crime statistics, and reviews of any location before visiting. Built with Next.js, TypeScript, and Leaflet maps.
- Color-coded markers by safety level (Green = Safe, Yellow = Moderate, Red = Unsafe)
- Click-to-view detailed place information
- Real-time filtering and search
- Built with Leaflet for smooth map interactions
- Overall Safety Score (0-100) based on multi-factor Elo rating system
- Crime breakdown: Violent crime, property crime, accidents
- Infrastructure metrics: CCTV coverage, street lighting, police density
- Trend indicators: Improving, neutral, or declining safety trends
The safety score uses a sophisticated formula:
AttributeScore = 0.40 Γ SafetyScore +
0.30 Γ PopularityScore +
0.20 Γ ExperienceScore +
0.10 Γ TrendScore
PlaceElo = 1000 + 1400 Γ AttributeScore
FinalSafetyScore = AttributeScore Γ 100
- Safety-focused reviews with detailed ratings
- Tags: "lit", "unsafe at night", "high police presence", "pickpockets", etc.
- Multi-dimensional ratings: Safety, cleanliness, police response
- Safe Only - Show only high-rated locations
- Moderate - Mixed safety areas
- Trending - Places with improving safety
- Popular - High-traffic areas
- Real-time search - Find places by name
- Node.js 18+
- npm or yarn
- Clone or navigate to the project directory:
cd safespot- Install dependencies:
npm install- Run the development server:
npm run dev- Open your browser:
http://localhost:3000
The app will automatically reload when you make changes.
safespot/
βββ src/
β βββ app/ # Next.js app directory
β β βββ page.tsx # Main home page
β β βββ layout.tsx # Root layout
β β βββ globals.css # Global styles
β βββ components/ # Reusable React components
β β βββ InteractiveMap.tsx # Leaflet map with markers
β β βββ PlaceDetailPanel.tsx # Animated side panel
β β βββ SafetyScoreBar.tsx # Progress bar component
β β βββ CrimeInfoSection.tsx # Crime statistics display
β β βββ UserReviewSection.tsx # Reviews feed
β β βββ InfrastructureSection.tsx # Infrastructure metrics
β βββ utils/
β β βββ safetyCalculations.ts # Elo formula & scoring logic
β βββ types/
β β βββ index.ts # TypeScript interfaces
β βββ data/
β βββ places.json # Mock place data
βββ public/ # Static assets
βββ package.json # Dependencies
βββ tsconfig.json # TypeScript config
βββ tailwind.config.js # Tailwind CSS config
βββ next.config.js # Next.js config
- Apple-inspired modern, minimal aesthetic
- Glassmorphism with backdrop blur effects
- Smooth animations using Framer Motion
- Responsive design for mobile and desktop
- Gradient accents for visual hierarchy
- Safe: Green (#10b981)
- Moderate: Yellow/Orange (#f59e0b)
- Unsafe: Red (#ef4444)
- Primary: Blue to Purple gradient
- Background: Soft gray tones
Renders an interactive Leaflet map with color-coded safety markers.
Props:
places- Array of place objectsselectedPlace- Currently selected placeonPlaceSelect- Callback when marker is clicked
Animated side panel showing comprehensive place details with smooth slide-in animation.
Features:
- Gradient header based on safety tier
- Score breakdown with progress bars
- Crime statistics
- Infrastructure metrics
- User reviews feed
- Elo formula explanation
Reusable progress bar with gradient colors based on score value.
{
id: string;
name: string;
lat: number;
lng: number;
crime: {
violent: number; // 0-100
property: number; // 0-100
accident: number; // 0-100
};
infra: {
cctv: number; // 0-100
lighting: number; // 0-100
policeDensity: number; // 0-100
};
popularity: number; // 0-100
experience: number; // 0-100
trend: number; // -1 to +1
reviews: Review[];
}Edit src/data/places.json and add new place objects following the structure above.
Update weights in src/utils/safetyCalculations.ts:
const attributeScore =
0.4 * (safetyScore / 100) +
0.3 * (popularityScore / 100) +
0.2 * (experienceScore / 100) +
0.1 * (trendScore / 100);Update the tile layer URL in src/components/InteractiveMap.tsx to use different map styles (e.g., Mapbox, CartoDB).
To connect to a real backend:
- Replace JSON import in
src/app/page.tsx:
// Instead of:
import placesData from "@/data/places.json";
// Use:
const { data: places } = await fetch("/api/places");- Create API routes in
src/app/api/places/route.ts
- Next.js 14 - React framework with App Router
- TypeScript - Type-safe JavaScript
- Tailwind CSS - Utility-first CSS framework
- Leaflet - Open-source map library
- React Leaflet - React components for Leaflet
- Framer Motion - Animation library
- Lucide React - Beautiful icon set
SafeSpot is fully responsive:
- Desktop: Full map with side panel
- Tablet: Optimized layout with bottom sheet
- Mobile: Touch-friendly interface with full-screen details
- User authentication and personal safety reports
- Real-time crime data integration
- Community-driven reviews and ratings
- Route safety checker
- Night mode with different safety metrics
- Push notifications for safety alerts
- Export safety reports as PDF
- Multi-city support with auto-detection
This project is open source and available under the MIT License.
Contributions are welcome! Please feel free to submit a Pull Request.
- Map data Β© OpenStreetMap contributors
- Icons by Lucide
- Inspired by modern safety and travel apps
Built with β€οΈ for safer communities