A full-stack web application for managing reminders with browser notifications. Built with Laravel 12, React, TypeScript, Inertia.js, Docker, and MySQL.
I've prepared a seeder to dive directly into app features with a demo user.
Creedentials: User: test@example.com Password: password
This application demonstrates a complete modern web development stack with:
- Backend: Laravel 12 with REST API
- Frontend: React + TypeScript with Inertia.js
- Styling: Tailwind CSS
- Database: MySQL 8.0
- Containerization: Docker + Docker Compose
- Notifications: Web Notifications API
| Layer | Technology |
|---|---|
| Backend | Laravel 12, PHP 8.3 |
| Frontend | React 18, TypeScript, Inertia.js |
| Styling | Tailwind CSS |
| Database | MySQL 8.0 |
| Containerization | Docker, Docker Compose |
| Build Tool | Vite |
| Package Manager | Composer, npm |
- ✅ User Authentication (Register/Login/Logout)
- ✅ Create, Read, Update, Delete Reminders
- ✅ Set Due Dates and Times
- ✅ Browser Notifications (Web Notifications API)
- ✅ Responsive UI with Tailwind CSS
- ✅ Full TypeScript Type Safety
- ✅ Dockerized Setup (No Local PHP/MySQL Setup Required)
Before you begin, ensure you have installed:
- Docker: Download
- Docker Compose: Included with Docker Desktop
- PowerShell (Windows) or Terminal (Mac/Linux)
- Text Editor: VS Code, Sublime, or any editor
No need to install PHP, MySQL, or Node.js locally - Docker handles everything!
cd your-projects-foldergit clone <repository-url>
cd reminder-appCopy the example environment file:
copy .env.example .envOr manually create .env with:
APP_NAME="Reminder App"
APP_ENV=local
APP_DEBUG=true
APP_URL=http://localhost
APP_KEY=
APP_CIPHER=AES-256-CBC
LOG_CHANNEL=stack
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=reminder_db
DB_USERNAME=reminder_user
DB_PASSWORD=reminder_password
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=cookiedocker-compose up -dThis starts three containers:
reminder_app(Laravel + PHP-FPM)reminder_db(MySQL)reminder_nginx(Nginx Web Server)
Check status:
docker-compose psdocker-compose exec app composer install docker-compose exec app php artisan key:generateVerify your .env file now has APP_KEY=base64:...
docker-compose exec app php artisan migrateYou should see:
Migrating: 2024_01_01_000000_create_users_table
Migrated: 2024_01_01_000000_create_users_table
Migrating: 2024_01_01_000001_create_reminders_table
Migrated: 2024_01_01_000001_create_reminders_table
Optional: I have prepared a Reminder seeder demo to take a quick trip
docker-compose exec app php artisan db:seedYou should see:
Database\Seeders\ReminderSeeder .... RUNNING
Database\Seeders\ReminderSeeder .... DONE
Install Frontend dependencies
docker-compose exec app npm iNow, you are ready to build Frontend Assets
docker-compose exec app npm run buildWait for completion. You should see ✓ built in XXXms
Open your browser and visit:
http://localhost
You'll be redirected to the login page.
Once installed, here's the typical workflow:
# Start app
docker-compose up -d
# Build assets (after code changes)
docker-compose exec app npm run build
# View logs
docker-compose logs -f app
# Stop appdocker-compose downreminder-app/
├── app/ # Laravel application code
│ ├── Models/
│ │ ├── User.php # User model
│ │ └── Reminder.php # Reminder model
│ ├── Http/
│ │ ├── Controllers/
│ │ │ ├── AuthController.php # Auth logic
│ │ │ └── ReminderController.php # CRUD logic
│ │ └── Middleware/
│ │ └── HandleInertiaRequests.php
│ └── Policies/
│ └── ReminderPolicy.php # Authorization
├── database/
│ ├── migrations/ # Database schemas
│ └── seeders/ # Database seeders
├── resources/
│ ├── js/
│ │ ├── app.tsx # React app entry point
│ │ ├── Pages/ # Inertia pages
│ │ │ ├── Auth/
│ │ │ │ ├── Login.tsx
│ │ │ │ └── Register.tsx
│ │ │ └── Reminders/
│ │ │ ├── Index.tsx
│ │ │ ├── Create.tsx
│ │ │ └── Edit.tsx
│ │ ├── Layouts/
│ │ │ └── AppLayout.tsx # Main layout
│ │ ├── Components/
│ │ │ └── ReminderForm.tsx # Reminder form
│ │ └── types/
│ │ └── index.ts # TypeScript types
│ ├── css/
│ │ └── app.css # Tailwind CSS
│ └── views/
│ └── app.blade.php # Main Blade template
├── routes/
│ └── web.php # Web routes
├── docker/
│ └── nginx.conf # Nginx configuration
├── Dockerfile # Docker image config
├── docker-compose.yml # Docker services
├── vite.config.ts # Vite build config
├── tsconfig.json # TypeScript config
├── tailwind.config.js # Tailwind config
└── .env # Environment variables
- Visit
http://localhost - Click "Register"
- Enter name, email, and password
- Click "Register"
- You're automatically logged in and redirected to reminders page
- Click "+ Create Reminder"
- Fill in:
- Title: Reminder name (required)
- Description: Additional details (optional)
- Due Date & Time: When the reminder should trigger
- Click "Create Reminder"
- You'll be redirected to the reminders list
- On the reminders page, click "Edit" on any reminder
- Update the details
- Click "Update Reminder"
- Click "Delete" on any reminder
- Confirm deletion
- Notifications are requested when you first log in
- Allow notifications in your browser
- When a reminder is due, you'll see a browser notification
- Note: Works on localhost; requires HTTPS in production
| Command | Purpose |
|---|---|
docker-compose up -d |
Start all containers |
docker-compose down |
Stop all containers |
docker-compose ps |
View container status |
docker-compose logs -f app |
View Laravel logs |
docker-compose exec app bash |
Access app container shell |
docker-compose restart app |
Restart app container |
docker-compose build --no-cache |
Rebuild images |
Changes to PHP/Laravel files auto-reload. No restart needed.
Watch for React/TypeScript changes:
docker-compose exec app npm run devAssets rebuild automatically. Refresh your browser to see changes.
# Run migrations
docker-compose exec app php artisan migrate
# Reset database
docker-compose exec app php artisan migrate:fresh
# Access database shell
docker-compose exec db mysql -u reminder_user -p reminder_db
# Password: reminder_password# Clear all caches
docker-compose exec app php artisan cache:clear
# Tinker (interactive shell)
docker-compose exec app php artisan tinker
# Create new model
docker-compose exec app php artisan make:model ModelName
# Create new controller
docker-compose exec app php artisan make:controller ControllerNameEdit docker-compose.yml:
nginx:
ports:
- "8080:80" # Change to 8080:80Then access: http://localhost:8080
Unsupported cipher or incorrect key length
Generate the key:
docker-compose exec app php artisan key:generateEnsure reminder_db container is running:
docker-compose ps
docker-compose logs dbRebuild assets:
docker-compose exec app npm run buildVerify migrations ran:
docker-compose exec app php artisan migrateCheck logs:
docker-compose logs app
docker-compose logs dbOn Windows, ensure Docker Desktop is running and you're using PowerShell.
| Method | Route | Purpose |
|---|---|---|
| GET | / |
Redirect to reminders/login |
| GET | /login |
Login form |
| POST | /login |
Handle login |
| GET | /register |
Register form |
| POST | /register |
Handle registration |
| POST | /logout |
Handle logout |
| GET | /reminders |
List all reminders |
| GET | /reminders/create |
Create form |
| POST | /reminders |
Store reminder |
| GET | /reminders/{id}/edit |
Edit form |
| PUT | /reminders/{id} |
Update reminder |
| DELETE | /reminders/{id} |
Delete reminder |
- Reminders are sorted by
due_atfor optimal query performance - Notifications check every minute (configurable interval)
- MySQL indexes on
user_idanddue_atfor fast queries - Vite bundles and minifies frontend assets
- Browser caches static assets
- CSRF token protection on all forms
- Password hashing with bcrypt
- User authorization checks (can only edit/delete own reminders)
- SQL injection protection via Laravel ORM
- XSS protection via React/Inertia
To deploy to production:
- Set
APP_ENV=productionin.env - Set
APP_DEBUG=false - Use HTTPS (required for notifications)
- Configure proper database backups
- Use environment variables for sensitive data
- Deploy with a service like Vercel, Heroku, or your own VPS
- Create a feature branch:
git checkout -b feature/your-feature - Make changes and test locally
- Commit:
git commit -m "Add feature description" - Push:
git push origin feature/your-feature - Create a Pull Request
This project follows:
- PHP Standards: PSR-12 coding standards
- TypeScript: Strict mode enabled
- Prettier: Code formatting
- ESLint: JavaScript linting
This project is open source and available under the MIT License.
For issues or questions:
- Check the Troubleshooting section
- Review Laravel docs: https://laravel.com/docs
- Review Inertia docs: https://inertiajs.com/
- Review React docs: https://react.dev
Happy Reminding! 🚀