diff --git a/server/controller/AdminController.ts b/server/controller/AdminController.ts index c8ef8f6..9973a3a 100644 --- a/server/controller/AdminController.ts +++ b/server/controller/AdminController.ts @@ -120,11 +120,13 @@ export default class AdminController_Auth$Admin extends Controller { adminBadgeViewModel.description = badge.Description; adminBadgeViewModel.imageUrl = badge.ImageUrl; adminBadgeViewModel.forUrl = badge.ForUrl; + adminBadgeViewModel.isSecret = badge.IsSecret; } else { adminBadgeViewModel.name = ""; adminBadgeViewModel.description = ""; adminBadgeViewModel.imageUrl = ""; adminBadgeViewModel.forUrl = ""; + adminBadgeViewModel.isSecret = false; } return this.view(adminBadgeViewModel); @@ -135,7 +137,7 @@ export default class AdminController_Auth$Admin extends Controller { return this.badRequest(); } - await BadgeService.SaveBadge(this.session.userId, parseInt(adminBadgeViewModel.id), adminBadgeViewModel.name ?? "", adminBadgeViewModel.description ?? "", adminBadgeViewModel.imageUrl ?? "", adminBadgeViewModel.forUrl ?? ""); + await BadgeService.SaveBadge(this.session.userId, parseInt(adminBadgeViewModel.id), adminBadgeViewModel.name ?? "", adminBadgeViewModel.description ?? "", adminBadgeViewModel.imageUrl ?? "", adminBadgeViewModel.forUrl ?? "", (adminBadgeViewModel.isSecret?.toString() ?? "") === "on"); return this.redirectToAction("badges"); } diff --git a/server/controller/HomeController.ts b/server/controller/HomeController.ts index dff13e5..d4896e1 100644 --- a/server/controller/HomeController.ts +++ b/server/controller/HomeController.ts @@ -1,7 +1,11 @@ import Controller from "./Controller"; +import FunkyArray from "funky-array"; import UserService from "../services/UserService"; import HomeViewModel from "../models/home/HomeViewModel"; import PartyService from "../services/PartyService"; +import BadgeService from "../services/BadgeService"; +import Badge from "../entities/Badge"; +import UserBadge from "../entities/UserBadge"; export default class HomeController extends Controller { public async Index_Get_AllowAnonymous() { @@ -14,12 +18,23 @@ export default class HomeController extends Controller { const parties = await PartyService.GetUserParties(this.session.userId); const activeUserParty = await UserService.GetActiveParty(this.session.userId); const unlockedBadges = await UserService.LoadUserBadges(this.session.userId); + const unlockedBadgesById = new FunkyArray(); + for (const unlockedBadge of unlockedBadges) { + unlockedBadgesById.set(unlockedBadge.BadgeId, unlockedBadge); + } + const badges = await BadgeService.LoadAll(); + const badgeById = new FunkyArray(); + for (const badge of badges) { + badgeById.set(badge.Id, badge); + } const homeViewModel: HomeViewModel = { user, parties, activeUserParty, - unlockedBadges + unlockedBadges, + unlockedBadgesById, + badgeById }; return this.view("home", homeViewModel); diff --git a/server/entities/Badge.ts b/server/entities/Badge.ts index c8d7fbb..29bcc0a 100644 --- a/server/entities/Badge.ts +++ b/server/entities/Badge.ts @@ -4,6 +4,7 @@ export default class Badge { public Description: string; public ImageUrl: string; public ForUrl: string; + public IsSecret: boolean; public CreatedByUserId: number; public CreatedDatetime: Date; public LastModifiedByUserId?: number; @@ -18,6 +19,7 @@ export default class Badge { this.Description = ""; this.ImageUrl = ""; this.ForUrl = ""; + this.IsSecret = false; this.CreatedByUserId = Number.MIN_VALUE; this.CreatedDatetime = new Date(0); this.IsDeleted = false; diff --git a/server/models/admin/AdminBadgeViewModel.ts b/server/models/admin/AdminBadgeViewModel.ts index e93a081..b370d6e 100644 --- a/server/models/admin/AdminBadgeViewModel.ts +++ b/server/models/admin/AdminBadgeViewModel.ts @@ -3,5 +3,6 @@ export default interface AdminBadgeViewModel { name?: string, description?: string, imageUrl?: string, - forUrl?: string + forUrl?: string, + isSecret?: boolean } \ No newline at end of file diff --git a/server/models/home/HomeViewModel.ts b/server/models/home/HomeViewModel.ts index 5e6671e..f74598f 100644 --- a/server/models/home/HomeViewModel.ts +++ b/server/models/home/HomeViewModel.ts @@ -1,3 +1,5 @@ +import Badge from "../../entities/Badge"; +import FunkyArray from "funky-array"; import Party from "../../entities/Party"; import User from "../../entities/User"; import UserBadge from "../../entities/UserBadge"; @@ -7,5 +9,7 @@ export default interface HomeViewModel { user: User, parties: Array, activeUserParty: UserParty | null, - unlockedBadges: Array + unlockedBadges: Array, + unlockedBadgesById: FunkyArray, + badgeById: FunkyArray } \ No newline at end of file diff --git a/server/repos/BadgeRepo.ts b/server/repos/BadgeRepo.ts index 8f4569d..6124dba 100644 --- a/server/repos/BadgeRepo.ts +++ b/server/repos/BadgeRepo.ts @@ -35,12 +35,12 @@ export default abstract class BadgeRepo { public static async insertUpdate(badge:Badge) { if (badge.Id === Number.MIN_VALUE) { - badge.Id = (await Database.Instance.query("INSERT Badge (Name, Description, ImageUrl, ForUrl, CreatedByUserId, CreatedDatetime, LastModifiedByUserId, LastModifiedDatetime, DeletedByUserId, DeletedDatetime, IsDeleted) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING Id;", [ - badge.Name, badge.Description, badge.ImageUrl, badge.ForUrl, badge.CreatedByUserId, badge.CreatedDatetime.getTime(), badge.LastModifiedByUserId ?? null, badge.LastModifiedDatetime?.getTime() ?? null, badge.DeletedByUserId ?? null, badge.DeletedDatetime?.getTime() ?? null, Number(badge.IsDeleted) + badge.Id = (await Database.Instance.query("INSERT Badge (Name, Description, ImageUrl, ForUrl, IsSecret, CreatedByUserId, CreatedDatetime, LastModifiedByUserId, LastModifiedDatetime, DeletedByUserId, DeletedDatetime, IsDeleted) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING Id;", [ + badge.Name, badge.Description, badge.ImageUrl, badge.ForUrl, Number(badge.IsSecret), badge.CreatedByUserId, badge.CreatedDatetime.getTime(), badge.LastModifiedByUserId ?? null, badge.LastModifiedDatetime?.getTime() ?? null, badge.DeletedByUserId ?? null, badge.DeletedDatetime?.getTime() ?? null, Number(badge.IsDeleted) ]))[0]["Id"]; } else { - await Database.Instance.query(`UPDATE Badge SET Name = ?, Description = ?, ImageUrl = ?, ForUrl = ?, CreatedByUserId = ?, CreatedDatetime = ?, LastModifiedByUserId = ?, LastModifiedDatetime = ?, DeletedByUserId = ?, DeletedDatetime = ?, IsDeleted = ? WHERE Id = ?`, [ - badge.Name, badge.Description, badge.ImageUrl, badge.ForUrl, badge.CreatedByUserId, badge.CreatedDatetime.getTime(), badge.LastModifiedByUserId ?? null, badge.LastModifiedDatetime?.getTime() ?? null, badge.DeletedByUserId ?? null, badge.DeletedDatetime?.getTime() ?? null, Number(badge.IsDeleted), badge.Id + await Database.Instance.query(`UPDATE Badge SET Name = ?, Description = ?, ImageUrl = ?, ForUrl = ?, IsSecret = ?, CreatedByUserId = ?, CreatedDatetime = ?, LastModifiedByUserId = ?, LastModifiedDatetime = ?, DeletedByUserId = ?, DeletedDatetime = ?, IsDeleted = ? WHERE Id = ?`, [ + badge.Name, badge.Description, badge.ImageUrl, badge.ForUrl, Number(badge.IsSecret), badge.CreatedByUserId, badge.CreatedDatetime.getTime(), badge.LastModifiedByUserId ?? null, badge.LastModifiedDatetime?.getTime() ?? null, badge.DeletedByUserId ?? null, badge.DeletedDatetime?.getTime() ?? null, Number(badge.IsDeleted), badge.Id ]); } @@ -54,11 +54,12 @@ function populateBadgeFromDB(badge:Badge, dbBadge:any) { badge.Description = dbBadge.Description; badge.ImageUrl = dbBadge.ImageUrl; badge.ForUrl = dbBadge.ForUrl; + badge.IsSecret = dbBadge.IsSecret[0] === 1; badge.CreatedByUserId = dbBadge.CreatedByUserId; badge.CreatedDatetime = new Date(dbBadge.CreatedDatetime); badge.LastModifiedByUserId = dbBadge.LastModifiedByUserId; badge.LastModifiedDatetime = RepoBase.convertNullableDatetimeIntToDate(dbBadge.LastModifiedDatetime); badge.DeletedByUserId = dbBadge.DeletedByUserId; badge.DeletedDatetime = RepoBase.convertNullableDatetimeIntToDate(dbBadge.DeletedDatetime); - badge.IsDeleted = dbBadge.IsDeleted === 1; + badge.IsDeleted = dbBadge.IsDeleted[0] === 1; } \ No newline at end of file diff --git a/server/repos/PartyRepo.ts b/server/repos/PartyRepo.ts index a9a6742..4d1f222 100644 --- a/server/repos/PartyRepo.ts +++ b/server/repos/PartyRepo.ts @@ -86,5 +86,5 @@ function populatePartyFromDB(party:Party, dbParty:any) { party.LastModifiedDatetime = RepoBase.convertNullableDatetimeIntToDate(dbParty.LastModifiedDatetime); party.DeletedByUserId = dbParty.DeletedByUserId; party.DeletedDatetime = RepoBase.convertNullableDatetimeIntToDate(dbParty.DeletedDatetime); - party.IsDeleted = dbParty.IsDeleted === 1; + party.IsDeleted = dbParty.IsDeleted[0] === 1; } \ No newline at end of file diff --git a/server/repos/UserBadgeRepo.ts b/server/repos/UserBadgeRepo.ts index e4b336d..752adfb 100644 --- a/server/repos/UserBadgeRepo.ts +++ b/server/repos/UserBadgeRepo.ts @@ -15,7 +15,7 @@ export default abstract class UserBadgeRepo { } public static async selectByUserId(userId:number) { - const dbUserBadge = await Database.Instance.query("SELECT * FROM UserBadge WHERE UserId = ? AND IsDeleted = 0 LIMIT 1", [ userId ]); + const dbUserBadge = await Database.Instance.query("SELECT * FROM UserBadge WHERE UserId = ? AND IsDeleted = 0", [ userId ]); const userBadges = new Array(); for (const row of dbUserBadge) { @@ -63,5 +63,5 @@ function populateUserBadgeFromDB(userBadge:UserBadge, dbUser:any) { userBadge.LastModifiedDatetime = RepoBase.convertNullableDatetimeIntToDate(dbUser.LastModifiedDatetime); userBadge.DeletedByUserId = dbUser.DeletedByUserId; userBadge.DeletedDatetime = RepoBase.convertNullableDatetimeIntToDate(dbUser.DeletedDatetime); - userBadge.IsDeleted = dbUser.IsDeleted === 1; + userBadge.IsDeleted = dbUser.IsDeleted[0] === 1; } \ No newline at end of file diff --git a/server/repos/UserPartyRepo.ts b/server/repos/UserPartyRepo.ts index 032ce2e..4bf7770 100644 --- a/server/repos/UserPartyRepo.ts +++ b/server/repos/UserPartyRepo.ts @@ -84,5 +84,5 @@ function populateUserPartyFromDB(userParty:UserParty, dbUserParty:any) { userParty.LastModifiedDatetime = RepoBase.convertNullableDatetimeIntToDate(dbUserParty.LastModifiedDatetime); userParty.DeletedByUserId = dbUserParty.DeletedByUserId; userParty.DeletedDatetime = RepoBase.convertNullableDatetimeIntToDate(dbUserParty.DeletedDatetime); - userParty.IsDeleted = dbUserParty.IsDeleted === 1; + userParty.IsDeleted = dbUserParty.IsDeleted[0] === 1; } \ No newline at end of file diff --git a/server/repos/UserRepo.ts b/server/repos/UserRepo.ts index d06481a..1cf12ec 100644 --- a/server/repos/UserRepo.ts +++ b/server/repos/UserRepo.ts @@ -77,12 +77,12 @@ function populateUserFromDB(user:User, dbUser:any) { user.PasswordHash = dbUser.PasswordHash; user.PasswordSalt = dbUser.PasswordSalt; user.APIKey = dbUser.APIKey; - user.HasUsedClient = dbUser.HasUsedClient === 1; + user.HasUsedClient = dbUser.HasUsedClient[0] === 1; user.CreatedByUserId = dbUser.CreatedByUserId; user.CreatedDatetime = new Date(dbUser.CreatedDatetime); user.LastModifiedByUserId = dbUser.LastModifiedByUserId; user.LastModifiedDatetime = RepoBase.convertNullableDatetimeIntToDate(dbUser.LastModifiedDatetime); user.DeletedByUserId = dbUser.DeletedByUserId; user.DeletedDatetime = RepoBase.convertNullableDatetimeIntToDate(dbUser.DeletedDatetime); - user.IsDeleted = dbUser.IsDeleted === 1; + user.IsDeleted = dbUser.IsDeleted[0] === 1; } \ No newline at end of file diff --git a/server/services/BadgeService.ts b/server/services/BadgeService.ts index 16454fd..57dd46c 100644 --- a/server/services/BadgeService.ts +++ b/server/services/BadgeService.ts @@ -4,7 +4,7 @@ import BadgeRepo from "../repos/BadgeRepo"; import BadgeCache from "../objects/BadgeCache"; export default abstract class BadgeService { - public static async SaveBadge(currentUserId:number, id:number | undefined, name:string, description:string, imageUrl: string, forUrl:string) { + public static async SaveBadge(currentUserId:number, id:number | undefined, name:string, description:string, imageUrl: string, forUrl:string, isSecret: boolean) { try { let badge = id ? await BadgeRepo.selectById(id) : null; if (badge === null) { @@ -16,10 +16,13 @@ export default abstract class BadgeService { badge.LastModifiedDatetime = new Date(); } + console.log(isSecret); + badge.Name = name; badge.Description = description; badge.ImageUrl = imageUrl; badge.ForUrl = forUrl; + badge.IsSecret = isSecret; badge = await BadgeRepo.insertUpdate(badge); diff --git a/server/views/admin/badge.ejs b/server/views/admin/badge.ejs index 9dfd17d..ba575af 100644 --- a/server/views/admin/badge.ejs +++ b/server/views/admin/badge.ejs @@ -42,12 +42,20 @@ " onerror="if (this.src != '/img/missing.png') this.src = '/img/missing.png';" width="32" height="32" /> -
+
" required />
+
+
+
+ /> + +
+
+
diff --git a/server/views/admin/badges.ejs b/server/views/admin/badges.ejs index c25463f..e6e545e 100644 --- a/server/views/admin/badges.ejs +++ b/server/views/admin/badges.ejs @@ -27,6 +27,7 @@   Name For URL + Secret   @@ -35,6 +36,7 @@ " width="32" height="32" /> <%= badge.Name %> <%= badge.ForUrl %> + <%= badge.IsSecret ? "Yes" : "No" %> Edit Delete diff --git a/server/views/base/footer.ejs b/server/views/base/footer.ejs index 110267f..a716a9a 100644 --- a/server/views/base/footer.ejs +++ b/server/views/base/footer.ejs @@ -1,5 +1,4 @@
- +
-
+

Your Parties

<% if (parties.length > 0) { %> @@ -66,11 +66,25 @@

Badges

- <% for (let i = 0; i < 71; i++) { %> - + <% for (const badgeKey of badgeById.keys) { %> + <% const badge = badgeById.get(badgeKey); const unlockedBadge = unlockedBadgesById.get(badgeKey); %> + <% if (unlockedBadge) { %> + "> + + + <% } else if (!badge.IsSecret) { %> + + + + <% } %> <% } %>
+ + <%- include("../base/footer") %> \ No newline at end of file