Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auth 2.0 extension #29

Merged
merged 20 commits into from
Dec 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Launch (web)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/GameLibrary/bin/Debug/net8.0/GameLibrary.dll",
"args": [],
"cwd": "${workspaceFolder}/GameLibrary",
"stopAtEntry": false,
"serverReadyAction": {
"action": "openExternally",
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"sourceFileMap": {
"/Views": "${workspaceFolder}/Views"
}
}
]
}
29 changes: 29 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/GameLibrary.sln",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary;ForceNoAlign"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/GameLibrary.sln",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary;ForceNoAlign"
],
"problemMatcher": "$msCompile"
}
]
}
31 changes: 28 additions & 3 deletions GameLibrary/Data/DbInitializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,16 @@ public static void Initialize(this IApplicationBuilder app)
var roleManager = services.GetRequiredService<RoleManager<Role>>();

// Apply any pending migrations
if (context.Database.GetPendingMigrations().Any())
try
{
context.Database.Migrate();
if (context.Database.GetPendingMigrations().Any())
{
context.Database.Migrate();
}
}
catch (Exception ex)
{
Console.WriteLine($"Migration error: {ex.Message}");
}

// Check if we already have games
Expand All @@ -42,7 +49,7 @@ public static void Initialize(this IApplicationBuilder app)
}

// Ensure roles are created
var roles = new[] { "Administrator", "User" };
var roles = new[] { "Administrator", "User", "Moderator" };
foreach (var role in roles)
{
if (!roleManager.RoleExistsAsync(role).Result)
Expand All @@ -68,6 +75,24 @@ public static void Initialize(this IApplicationBuilder app)
}
}

var moderatorUser = new User
{
Id = Guid.Parse("71a23c2d-f82e-4b47-a843-cfcadbd65a77"),
UserName = "[email protected]",
Email = "[email protected]",
EmailConfirmed = true
};

if (userManager.FindByNameAsync(moderatorUser.UserName).Result == null)
{
var result = userManager.CreateAsync(moderatorUser, "Password123!").Result;
if (result.Succeeded)
{
userManager.AddToRoleAsync(moderatorUser, "Moderator").Wait();
}
}


context.SaveChanges();

// Add test games
Expand Down
Binary file modified GameLibrary/Database.db-shm
Binary file not shown.
Binary file modified GameLibrary/Database.db-wal
Binary file not shown.
15 changes: 14 additions & 1 deletion GameLibrary/Migrations/20241123065457_Init.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
ο»Ώusing System;
ο»Ώ// Copyright 2024 Web.Tech. Group17
//
// Licensed under the Apache License, Version 2.0 (the "License"):
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable
Expand Down
8 changes: 0 additions & 8 deletions GameLibrary/Pages/About.cshtml

This file was deleted.

99 changes: 61 additions & 38 deletions GameLibrary/Pages/Account/Library.cshtml
Original file line number Diff line number Diff line change
@@ -1,29 +1,33 @@
@page
@model LibraryModel
@{
ViewData["Title"] = "My Game Library";
ViewData["Title"] = "Library";
}

<div class="container py-4">
<h1 class="text-warning mb-4">My Game Library</h1>

<!-- Filter Form -->
<div class="row mb-4">
<div class="col-md-8">
<div class="btn-group" role="group">
<button type="button" class="btn btn-outline-primary active" data-filter="all">All</button>
<button type="button" class="btn btn-outline-primary" data-filter="Playing">Playing</button>
<button type="button" class="btn btn-outline-primary" data-filter="Completed">Completed</button>
<button type="button" class="btn btn-outline-primary" data-filter="On Hold">On Hold</button>
<button type="button" class="btn btn-outline-primary" data-filter="Dropped">Dropped</button>
<button type="button" class="btn btn-outline-primary" data-filter="Plan to Play">Plan to Play</button>
</div>
<form method="get">
<div class="btn-group" role="group">
<button type="submit" name="filter" value="all" class="btn btn-outline-primary @(Model.Filter == "all" ? "active" : "")">All</button>
<button type="submit" name="filter" value="Playing" class="btn btn-outline-primary @(Model.Filter == "Playing" ? "active" : "")">Playing</button>
<button type="submit" name="filter" value="Completed" class="btn btn-outline-primary @(Model.Filter == "Completed" ? "active" : "")">Completed</button>
<button type="submit" name="filter" value="On Hold" class="btn btn-outline-primary @(Model.Filter == "On Hold" ? "active" : "")">On Hold</button>
<button type="submit" name="filter" value="Dropped" class="btn btn-outline-primary @(Model.Filter == "Dropped" ? "active" : "")">Dropped</button>
<button type="submit" name="filter" value="Plan to Play" class="btn btn-outline-primary @(Model.Filter == "Plan to Play" ? "active" : "")">Plan to Play</button>
</div>
</form>
</div>
</div>

<!-- Game List -->
<div class="row row-cols-1 row-cols-md-3 g-4">
@foreach (var item in Model.LibraryItems)
{
<div class="col game-item" data-status="@item.Status">
<div class="col game-item">
<div class="card h-100 bg-primary-subtle">
<img src="@item.Game.ImageUrl" class="card-img-top" alt="@item.Game.Title" style="height: 200px; object-fit: cover;">
<div class="card-body">
Expand Down Expand Up @@ -77,34 +81,53 @@
</div>
</div>

@section Styles {
<link rel="stylesheet" href="~/css/user/library.css" />
}

@section Scripts {
<script>
document.addEventListener('DOMContentLoaded', function() {
const filterButtons = document.querySelectorAll('[data-filter]');
const gameItems = document.querySelectorAll('.game-item');
<style>
.game-item .card {
transition: transform 0.2s;
}

filterButtons.forEach(button => {
button.addEventListener('click', () => {
const filter = button.dataset.filter;

// Update active button
filterButtons.forEach(btn => btn.classList.remove('active'));
button.classList.add('active');
.game-item .card:hover {
transform: translateY(-5px);
}

// Filter games
gameItems.forEach(item => {
if (filter === 'all' || item.dataset.status === filter) {
item.style.display = '';
} else {
item.style.display = 'none';
}
});
});
});
});
</script>
}
.rating {
margin-top: 0.5rem;
}

.rating .fa-star {
color: #ffc107;
}

.btn-group .btn {
transition: all 0.2s;
}

.btn-group .btn:hover {
transform: translateY(-2px);
}

.badge {
margin-right: 0.5rem;
}

.dropdown-item.active {
background-color: var(--bs-primary);
color: white;
}

/* Filter buttons */
.btn-group[role="group"] .btn {
border-radius: 0;
}

.btn-group[role="group"] .btn:first-child {
border-top-left-radius: 0.375rem;
border-bottom-left-radius: 0.375rem;
}

.btn-group[role="group"] .btn:last-child {
border-top-right-radius: 0.375rem;
border-bottom-right-radius: 0.375rem;
}
</style>
47 changes: 18 additions & 29 deletions GameLibrary/Pages/Account/Library.cshtml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,11 @@ public class LibraryModel : PageModel
{
private readonly ApplicationDbContext _context;
private readonly UserManager<User> _userManager;
private readonly ILogger<LibraryModel> _logger;

public LibraryModel(ApplicationDbContext context, UserManager<User> userManager, ILogger<LibraryModel> logger)
public LibraryModel(ApplicationDbContext context, UserManager<User> userManager)
{
_context = context;
_userManager = userManager;
_logger = logger;
}

public class LibraryItemViewModel
Expand All @@ -45,20 +43,31 @@ public class LibraryItemViewModel
}

public List<LibraryItemViewModel> LibraryItems { get; set; } = [];
public string Filter { get; set; } = "all";

public async Task<IActionResult> OnGetAsync()
public async Task<IActionResult> OnGetAsync(string? filter)
{
var user = await _userManager.GetUserAsync(User);
if (user == null)
{
return NotFound();
}

// Default filter
Filter = filter ?? "all";

// Get user's library items with related game data
var libraryItems = await _context.UserLibraries
var libraryItemsQuery = _context.UserLibraries
.Include(ul => ul.Game)
.Where(ul => ul.UserId == user.Id)
.ToListAsync();
.Where(ul => ul.UserId == user.Id);

// Apply filter if necessary
if (Filter != "all")
{
libraryItemsQuery = libraryItemsQuery.Where(ul => ul.Status == Filter);
}

var libraryItems = await libraryItemsQuery.ToListAsync();

// Get user's favorites
var favorites = await _context.UserFavorites
Expand All @@ -73,34 +82,14 @@ public async Task<IActionResult> OnGetAsync()
.ToDictionaryAsync(g => g.Key, g => g.OrderByDescending(r => r.CreatedAt).First().Rating);

// Build view models
LibraryItems = libraryItems.Select(li => new LibraryItemViewModel
LibraryItems = libraryItems.ConvertAll(li => new LibraryItemViewModel
{
Game = li.Game,
Status = li.Status,
IsFavorite = favorites.Contains(li.GameId),
Rating = ratings.GetValueOrDefault(li.GameId)
}).ToList();
});

return Page();
}

public async Task<IActionResult> OnPostUpdateStatusAsync(Guid gameId, string status)
{
var user = await _userManager.GetUserAsync(User);
if (user == null)
{
return NotFound();
}

var libraryItem = await _context.UserLibraries
.FirstOrDefaultAsync(ul => ul.UserId == user.Id && ul.GameId == gameId);

if (libraryItem != null)
{
libraryItem.Status = status;
await _context.SaveChangesAsync();
}

return RedirectToPage();
}
}
10 changes: 10 additions & 0 deletions GameLibrary/Pages/Account/Manage/ManageNavPages.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ public static class ManageNavPages
/// </summary>
public static string TwoFactorAuthentication => "TwoFactorAuthentication";

/// <summary>
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
/// </summary>
public static string RoleTools => "RoleTools";

/// <summary>
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
Expand Down Expand Up @@ -120,6 +125,11 @@ public static class ManageNavPages
/// </summary>
public static string TwoFactorAuthenticationNavClass(ViewContext viewContext) => PageNavClass(viewContext, TwoFactorAuthentication);

/// <summary>
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
/// </summary>
public static string RoleToolsNavClass(ViewContext viewContext) => PageNavClass(viewContext, RoleTools);

/// <summary>
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
Expand Down
Loading