A full-stack dating application with real-time messaging, user matching, photo management, and an admin panel. Built with Angular 19 and ASP.NET Core 9.
- User Profiles — Register, login, and manage detailed profiles with photos, interests, location, and bio
- Photo Management — Upload multiple photos via Cloudinary with automatic cropping, set a main photo, and delete photos
- Likes & Matching — Like/unlike other users and browse who has liked you
- Real-Time Messaging — Instant messaging powered by SignalR with read receipts and unread counts
- Online Presence — See who's currently online with real-time status updates and toast notifications
- Member Filtering — Filter members by age range, gender, and sort by last active or newest
- Pagination — Server-side pagination across members, messages, and likes
- Admin Panel — Manage user roles and moderate photos (approve/reject) with role-based access
- Role-Based Authorization — Admin and Moderator roles with route guards and policy-based access
- Responsive UI — Bootstrap 5 with the Bootswatch Lux theme
| Technology | Purpose |
|---|---|
| ASP.NET Core 9 | Web API framework |
| Entity Framework Core 9 | ORM / Data access |
| SQL Server | Production database |
| SQLite | Development database |
| ASP.NET Core Identity | Authentication & role management |
| JWT Bearer Tokens | Stateless authentication |
| SignalR | Real-time WebSocket communication |
| Cloudinary | Cloud-based image storage |
| AutoMapper | Object-to-object mapping |
| Technology | Purpose |
|---|---|
| Angular 19 | SPA framework |
| TypeScript 5.7 | Language |
| Bootstrap 5 / Bootswatch | UI styling |
| Font Awesome 4.7 | Icons |
| @microsoft/signalr | Real-time client |
| ng-gallery / ngx-gallery | Image galleries |
| ng2-file-upload | File uploads |
| ngx-toastr | Toast notifications |
| ngx-spinner | Loading indicators |
| ngx-bootstrap | UI components (dropdowns, modals, tabs) |
- .NET 9 SDK
- Node.js 22+
- Angular CLI (
npm install -g @angular/cli) - SQL Server (or use SQLite for development)
- A Cloudinary account (free tier works)
git clone https://github.com/your-username/DatingApp.git
cd DatingAppUpdate API/appsettings.Development.json with your database connection string:
{
"ConnectionStrings": {
"DefaultConnection": "Server=localhost,1433;Database=DatingDB;User Id=SA;Password=YourPassword;TrustServerCertificate=True"
}
}Update API/appsettings.json with your Cloudinary credentials:
{
"CloudinarySettings": {
"CloudName": "your-cloud-name",
"ApiKey": "your-api-key",
"ApiSecret": "your-api-secret"
}
}cd API
dotnet restore
dotnet ef database update
dotnet runThe API will be available at https://localhost:7111.
cd client
npm install
ng serveThe client will be available at https://localhost:4200.
On first run, the application automatically seeds sample users from API/Data/UserSeedData.json and creates the default roles (Admin, Moderator).
DatingApp/
├── API/ # ASP.NET Core Web API
│ ├── Controllers/ # API endpoints
│ │ ├── AccountController # Registration & login
│ │ ├── UsersController # User profiles & photos
│ │ ├── MessagesController # Messaging
│ │ ├── LikesController # Like/unlike users
│ │ └── AdminController # User & photo management
│ ├── Data/ # EF Core DbContext, repositories, migrations, seed data
│ ├── DTOs/ # Data transfer objects
│ ├── Entities/ # Domain models (AppUser, Photo, Message, UserLike, etc.)
│ ├── Services/ # Business logic (Token generation, Photo uploads)
│ ├── Interfaces/ # Repository & service contracts
│ ├── SignalR/ # Real-time hubs (Presence, Messaging)
│ ├── Extensions/ # Service registration & helper extensions
│ ├── Helpers/ # AutoMapper profiles, pagination, Cloudinary settings
│ ├── Middleware/ # Global exception handling
│ └── Errors/ # Error response models
│
├── client/ # Angular 19 SPA
│ └── src/app/
│ ├── admin/ # Admin panel, photo moderation, user management
│ ├── members/ # Member list, detail, edit, cards, photo editor
│ ├── messages/ # Messaging UI
│ ├── lists/ # Likes list
│ ├── home/ # Landing page
│ ├── register/ # Registration form
│ ├── nav/ # Navigation bar
│ ├── _services/ # Angular services (account, members, messages, presence, likes)
│ ├── _models/ # TypeScript interfaces
│ ├── _guards/ # Route guards (auth, admin, unsaved changes)
│ ├── _interceptors/ # HTTP interceptors (JWT, errors, loading)
│ ├── _directives/ # Custom directives (hasRole)
│ ├── _forms/ # Reusable form components
│ ├── _resolvers/ # Route resolvers
│ └── errors/ # Error pages (404, 500)
│
└── .github/workflows/ # CI/CD (Azure deployment)
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/account/register |
Register a new user |
| POST | /api/account/login |
Login and receive JWT token |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/users |
Get paginated members (with filters) |
| GET | /api/users/{username} |
Get a member's profile |
| PUT | /api/users |
Update your profile |
| POST | /api/users/add-photo |
Upload a photo |
| PUT | /api/users/set-main-photo/{photoId} |
Set main profile photo |
| DELETE | /api/users/delete-photo/{photoId} |
Delete a photo |
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/messages |
Send a message |
| GET | /api/messages |
Get messages (inbox/outbox/unread) |
| GET | /api/messages/thread/{username} |
Get message thread with a user |
| GET | /api/messages/unread-count |
Get unread message count |
| DELETE | /api/messages/{id} |
Delete a message |
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/likes/{targetUserId} |
Toggle like on a user |
| GET | /api/likes/list |
Get IDs of users you've liked |
| GET | /api/likes |
Get paginated liked users |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/admin/users-with-roles |
Get all users with roles |
| POST | /api/admin/edit-roles/{username} |
Edit a user's roles |
| GET | /api/admin/photos-to-moderate |
Get unapproved photos |
| POST | /api/admin/approve-photo/{id} |
Approve a photo |
| POST | /api/admin/reject-photo/{id} |
Reject a photo |
| Hub | Endpoint | Purpose |
|---|---|---|
| Presence | /hubs/presence |
Online/offline status tracking |
| Message | /hubs/message |
Real-time messaging |
- Pattern: Repository + Unit of Work
- Backend: N-tier (Controllers → Services/Repositories → EF Core DbContext)
- Frontend: Component-based with Angular Signals for reactive state
- Authentication: JWT tokens stored in localStorage, attached via HTTP interceptor
- Real-Time: SignalR hubs for presence tracking and instant messaging
- Image Pipeline: Client upload → API → Cloudinary (500x500, face-cropped) → URL stored in DB
The project includes a GitHub Actions workflow for CI/CD deployment to Azure App Service.
The workflow (.github/workflows/main_bloom-dating-app.yml):
- Builds the Angular client into
API/wwwroot - Builds and publishes the .NET API
- Deploys to Azure Web Apps
- Register an account with your details (username, password, gender, date of birth, city, country)
- Browse members using filters for age, gender, and sorting preferences
- Like members you're interested in and check who has liked you
- Message other members in real-time — see when they're online and when messages are read
- Edit your profile — update your bio, interests, and photos
- Admin panel (if assigned Admin/Moderator role) — manage user roles and moderate photos
This project is licensed under the MIT License. See the LICENSE file for details.