A full-stack interactive map notes application built with HTML, CSS, JavaScript, PHP, and MySQL, powered by OpenStreetMap via Leaflet.
| Feature | Details |
|---|---|
| 🗺️ Interactive Map | OpenStreetMap + Leaflet with marker clustering |
| 📍 Click-to-Note | Click anywhere to drop a note (60-word max) |
| 🎵 Song Attachment | YouTube search OR paste any audio URL |
| 🔊 Auto-play | Song plays automatically when marker is clicked |
| 👤 Auth System | Register/Login with hashed passwords + sessions |
| 🖼️ Profile Photos | Upload avatar; shown as circular map markers |
| 🔎 Location Search | Nominatim geocoding with live autocomplete |
| ❤️ Likes | React to notes (logged-in users) |
| 🗑️ Delete | Authors can delete their own notes |
| 📱 Responsive | Mobile-friendly dark editorial design |
| 🔒 Security | PDO prepared statements, sanitization, file validation |
mapnotes/
├── index.html ← Main frontend (all HTML + CSS + JS)
├── api.php ← REST API backend
├── config.php ← DB config, session, helpers
├── schema.sql ← MySQL schema
├── .htaccess ← Apache routing + security
├── assets/
│ └── default-avatar.svg
└── uploads/ ← User profile images (auto-created)
- PHP 7.4+ with PDO, PDO_MySQL, GD extensions
- MySQL 5.7+ or MariaDB 10.2+
- Apache with mod_rewrite (XAMPP works perfectly)
mysql -u root -p < schema.sqlOr paste schema.sql into phpMyAdmin → SQL tab → Go.
define('DB_HOST', 'localhost');
define('DB_NAME', 'mapnotes');
define('DB_USER', 'root'); // ← your MySQL username
define('DB_PASS', ''); // ← your MySQL passwordFor in-app song search, add a free YouTube Data API v3 key:
- Go to https://console.developers.google.com
- Create a project → Enable "YouTube Data API v3"
- Create credentials → API Key
- Paste in
config.php:
define('YOUTUBE_API_KEY', 'YOUR_KEY_HERE');Without a key: Demo songs are shown — the app still works!
Copy the entire mapnotes/ folder to:
- Windows XAMPP:
C:\xampp\htdocs\mapnotes\ - macOS XAMPP:
/Applications/XAMPP/htdocs/mapnotes/ - Linux:
/var/www/html/mapnotes/or/opt/lampp/htdocs/mapnotes/
Make sure the uploads/ folder is writable:
chmod 755 uploads/Visit: http://localhost/mapnotes/
All requests go to api.php?action=<endpoint>.
| Endpoint | Method | Auth | Description |
|---|---|---|---|
auth/register |
POST | No | Create account |
auth/login |
POST | No | Sign in |
auth/logout |
GET | Yes | Sign out |
auth/me |
GET | No | Get session user |
notes/list |
GET | No | Get all notes |
notes/add |
POST | Yes | Add a note |
notes/delete |
POST | Yes | Delete own note |
upload/avatar |
POST (multipart) | Yes | Upload profile image |
songs/search?q= |
GET | No | YouTube song search |
likes/toggle |
POST | Yes | Like/unlike a note |
YouTube search (in-app):
- Searches YouTube Data API
- Returns video list; user selects
- Saved as YouTube embed URL
- Plays via iframe in popup
Paste URL (manual):
- Direct audio file URL (
.mp3,.ogg,.wav) - Or YouTube URL (
youtube.com/watch?v=...) - Plays via HTML5
<audio>or YouTube iframe
- All DB queries use PDO prepared statements
- Passwords hashed with bcrypt (
PASSWORD_BCRYPT, cost 12) - File uploads: MIME type checked with
finfo, extension validated - All text input:
strip_tags()+mb_substr() - Sessions:
httponlycookies, strict mode .htaccessblocks PHP execution inuploads/
| Problem | Fix |
|---|---|
| White page | Check PHP error log; verify DB credentials in config.php |
| Map not loading | Check internet connection |
| Avatar upload fails | chmod 755 uploads/ or create the folder manually |
| Song search returns demos | Add YouTube API key to config.php |
| 404 on API calls | Enable mod_rewrite in Apache; check .htaccess |
MIT — free to use and modify.