Web front-end for DigiVault — a digital course marketplace. This solution contains two ASP.NET Core MVC applications: a customer-facing public portal and an internal administration panel (intranet). Both communicate with the DigiVault API over HTTP.
🚧 This project is a work in progress. Some views and features are still being implemented.
| App | URL | Notes |
|---|---|---|
| DigiVault.PortalWWW | https://digivaultportal.onrender.com/Account/Login | Customer portal |
| DigiVault.Intranet | https://digivaultintranet.onrender.com | Admin panel — full CRUD |
| DigiVaultAPI | https://digivaultapi.onrender.com/swagger | REST API + Swagger UI |
Both apps are hosted on Render's free tier. The first request after a period of inactivity may take up to 50 seconds (cold start).
| Project | Description |
|---|---|
DigiVault.PortalWWW |
Public-facing customer portal — browse courses, manage cart and wishlist, view orders, log in |
DigiVault.Intranet |
Internal administration panel — full CRUD for users, courses, categories, orders, notifications, reports, and settings |
Both projects live in the same solution (DigiVaultWeb.sln) and target .NET 9.
| Technology | Version |
|---|---|
| ASP.NET Core MVC | 9.0 |
| Razor Views | — |
| System.IdentityModel.Tokens.Jwt | 8.17.0 |
| Session-based auth (JWT stored server-side) | — |
HttpClient + named client (DigiVaultAPI) |
built-in |
DigiVaultWeb/
├── DigiVault.PortalWWW/ # Customer portal
│ ├── Controllers/
│ │ ├── AccountController.cs # Login / logout (JWT → session)
│ │ ├── HomeController.cs # Home page — popular / newest / top-rated courses
│ │ ├── CoursesController.cs # Course catalogue + course detail with reviews
│ │ ├── CartController.cs # Shopping cart (stub view)
│ │ ├── WishlistController.cs # Wishlist (stub view)
│ │ └── MyVaultController.cs # Purchased courses (stub view)
│ ├── Models/ # ViewModels and API DTOs
│ │ ├── CoursesIndexViewModel.cs
│ │ ├── CourseDetailViewModel.cs
│ │ ├── HomeViewModel.cs
│ │ ├── LoginViewModel.cs
│ │ ├── PagedResult.cs
│ │ └── ...
│ ├── Services/
│ │ └── ApiService.cs # Typed HttpClient wrapper — GET / POST helpers with JWT header
│ ├── Views/ # Razor views (one folder per controller)
│ ├── wwwroot/ # Static assets (CSS, JS, images)
│ ├── appsettings.json # ApiSettings:BaseUrl
│ └── Program.cs # DI: HttpClient, session, ApiService
│
├── DigiVault.Intranet/ # Internal admin panel
│ ├── Controllers/
│ │ ├── AccountController.cs # Login / logout (JWT → session)
│ │ ├── DashboardController.cs
│ │ ├── UsersController.cs # User list, detail, create, edit, ban/unban
│ │ ├── CoursesController.cs # Course list, detail, soft delete
│ │ ├── CategoriesController.cs # Full CRUD for categories
│ │ ├── OrdersController.cs # Order list, detail, cancel order / remove item
│ │ ├── NotificationsController.cs # Notification list, send notification
│ │ ├── ReportsController.cs # Report list, resolve report
│ │ └── SettingsController.cs # Platform settings (commission rate)
│ ├── Views/
│ ├── wwwroot/
│ ├── appsettings.json
│ └── Program.cs
│
├── DigiVaultWeb.sln
└── global.json
- .NET 9 SDK
- A running instance of the DigiVault API (see its README for setup)
The portal needs to know where the API is. Open DigiVault.PortalWWW/appsettings.json and set ApiSettings:BaseUrl:
{
"ApiSettings": {
"BaseUrl": "http://localhost:5052"
}
}Note: Do not store secrets (API keys, passwords) in
appsettings.json. Useappsettings.Development.json(excluded from git) or environment variables for anything sensitive.
| Key | Description |
|---|---|
ApiSettings:BaseUrl |
Base URL of the DigiVaultAPI instance |
# 1. Clone the repository
git clone https://github.com/your-org/DigiVaultWeb.git
cd DigiVaultWeb
# 2. Make sure the DigiVault API is running (see its README)
# 3. Run the public portal
dotnet run --project DigiVault.PortalWWW
# 4. Run the intranet (separate terminal)
dotnet run --project DigiVault.IntranetDefault ports (may vary by launch profile):
| App | Local URL | Live URL |
|---|---|---|
| PortalWWW | http://localhost:5000 |
https://digivaultportal.onrender.com |
| Intranet | http://localhost:5001 |
https://digivaultintranet.onrender.com |
Check
Properties/launchSettings.jsonin each project for the exact ports configured in your environment.
Requires a valid session (JWT token obtained after login). All routes redirect to
/Account/Loginif the session is missing.
| Route | Description |
|---|---|
GET /Account/Login |
Login form |
POST /Account/Login |
Authenticate via API → store JWT in session |
GET /Account/Logout |
Clear session and redirect to login |
GET /Home |
Home page — popular, newest, and top-rated course carousels |
GET /Courses |
Paginated course catalogue with search, category filter, and sort |
GET /Courses/Detail/{id} |
Course detail with reviews |
GET /Cart |
Shopping cart (view stub — in progress) |
GET /Wishlist |
Wishlist (view stub — in progress) |
GET /MyVault |
Purchased courses (view stub — in progress) |
Requires login with a
Worker(admin) account. All routes redirect to/Account/Loginif the session is missing.Live: https://digivaultintranet.onrender.com — log in with
admin/admin
| Route | Description |
|---|---|
GET /Account/Login |
Admin login form |
POST /Account/Login |
Authenticate via API → store JWT in session |
GET /Account/Logout |
Clear session and redirect to login |
GET /Dashboard |
Admin dashboard |
GET /Categories |
Category list |
POST /Categories/Create |
Create a new category (modal) |
POST /Categories/Edit/{id} |
Update a category (modal) |
POST /Categories/Delete/{id} |
Delete a category |
GET /Users |
Paginated user list with search |
GET /Users/Detail/{id} |
User detail — profile, created and purchased courses |
POST /Users/Create |
Create a new user account (modal) |
POST /Users/Edit/{id} |
Update user role and status (modal) |
POST /Users/SetActive/{id} |
Activate a user |
POST /Users/SetNotActive/{id} |
Deactivate (ban) a user |
GET /Courses |
Paginated course list including hidden courses |
GET /Courses/Detail/{id} |
Course detail with reports count |
POST /Courses/Delete/{id} |
Soft-delete a course |
GET /Orders |
Paginated order list with date filter |
GET /Orders/Detail/{id} |
Order detail with item list |
POST /Orders/Delete/{id} |
Cancel an order and refund the user |
POST /Orders/RemoveItem/{orderId}/{courseId} |
Remove a single item from an order |
GET /Notifications |
Notification list |
POST /Notifications/Send |
Send a notification to a user (modal) |
GET /Reports |
Report list |
POST /Reports/Resolve/{id} |
Mark a report as resolved |
GET /Settings |
Platform settings (commission rate) |
POST /Settings/UpdateCommission |
Update the platform commission rate |
The portal uses session-based authentication backed by JWT:
- The user submits credentials on the login form.
AccountControllercallsPOST /api/auth/loginon the DigiVaultAPI.- The returned JWT token is stored in the server-side session (
HttpContext.Session). ApiServicereads the token from the session and attaches it asAuthorization: Bearer <token>on every outgoing API request.- The user's first name is decoded directly from the JWT claims for display in the UI.
No cookies carry the raw JWT — the token lives exclusively in the server-side session.
| Login | Password | Role | Notes |
|---|---|---|---|
test |
test |
User | Has balance, orders, and purchased courses |
test2 |
test |
User | |
admin |
admin |
Worker | Can also log in to the portal |
| Login | Password | Role |
|---|---|---|
admin |
admin |
Worker (Admin) |
Only accounts with the
Workerrole can access the Intranet. Logging in with aUseraccount will result in a 403 error from the API.See the DigiVault API README for the full list of seeded accounts.
This project is open-source and available under the MIT License.