diff --git a/app/components/lobbyside-staff-widget/index.hbs b/app/components/lobbyside-staff-widget/index.hbs
deleted file mode 100644
index 5947f43b45..0000000000
--- a/app/components/lobbyside-staff-widget/index.hbs
+++ /dev/null
@@ -1,3 +0,0 @@
-{{#if this.shouldShow}}
-
-{{/if}}
\ No newline at end of file
diff --git a/app/components/lobbyside-staff-widget/index.ts b/app/components/lobbyside-staff-widget/index.ts
deleted file mode 100644
index 6437fc7942..0000000000
--- a/app/components/lobbyside-staff-widget/index.ts
+++ /dev/null
@@ -1,64 +0,0 @@
-import Component from '@glimmer/component';
-import { service } from '@ember/service';
-import { action } from '@ember/object';
-import type AuthenticatorService from 'codecrafters-frontend/services/authenticator';
-
-const ALLOWED_USERNAMES = ['vishaag', 'dronaxis'];
-const LOBBYSIDE_SCRIPT_ID = 'lobbyside-staff-widget-script';
-
-export default class LobbysideStaffWidgetComponent extends Component {
- @service declare authenticator: AuthenticatorService;
-
- get shouldShow(): boolean {
- const user = this.authenticator.currentUser;
-
- if (!user) {
- return false;
- }
-
- return user.isStaff || ALLOWED_USERNAMES.includes(user.username);
- }
-
- @action
- insertScript(): void {
- if (document.getElementById(LOBBYSIDE_SCRIPT_ID)) {
- this.syncVisitorData();
-
- return;
- }
-
- const script = document.createElement('script');
- script.id = LOBBYSIDE_SCRIPT_ID;
- script.src = 'https://lobbyside.com/widget.js';
- script.dataset['companyId'] = '665ad94a-a863-4d0e-98e5-ff3eeac3f264';
- script.onload = () => this.syncVisitorData();
- document.body.appendChild(script);
- }
-
- @action
- removeScript(): void {
- const script = document.getElementById(LOBBYSIDE_SCRIPT_ID);
-
- if (script) {
- script.remove();
- }
- }
-
- private syncVisitorData(): void {
- const user = this.authenticator.currentUser;
-
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- if (!user || !(window as any)['Lobbyside']) {
- return;
- }
-
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- const lobbyside = (window as any).Lobbyside;
-
- lobbyside.setVisitor({
- email: user.primaryEmailAddress || '',
- name: user.name || user.githubName || '',
- github: user.githubUsername || '',
- });
- }
-}
diff --git a/app/components/lobbyside-widget/index.hbs b/app/components/lobbyside-widget/index.hbs
index 5947f43b45..01a00b947e 100644
--- a/app/components/lobbyside-widget/index.hbs
+++ b/app/components/lobbyside-widget/index.hbs
@@ -1,3 +1,3 @@
{{#if this.shouldShow}}
-
+
{{/if}}
\ No newline at end of file
diff --git a/app/components/lobbyside-widget/index.ts b/app/components/lobbyside-widget/index.ts
index e0bbf83f93..c85341dfe0 100644
--- a/app/components/lobbyside-widget/index.ts
+++ b/app/components/lobbyside-widget/index.ts
@@ -1,57 +1,81 @@
import Component from '@glimmer/component';
import { service } from '@ember/service';
import { action } from '@ember/object';
+import { userIsStaffOrAllowlisted } from 'codecrafters-frontend/utils/staff-allowlist';
import type AuthenticatorService from 'codecrafters-frontend/services/authenticator';
-const LOBBYSIDE_SCRIPT_ID = 'lobbyside-widget-script';
+declare global {
+ interface Window {
+ Lobbyside?: {
+ setVisitor(visitor: { email: string; name: string; github: string }): void;
+ };
+ }
+}
+
+export type LobbysideAudience = 'everyone' | 'staff';
+
+export interface LobbysideWidgetSignature {
+ Element: HTMLDivElement;
+ Args: {
+ widgetId: string;
+ audience?: LobbysideAudience;
+ };
+}
-export default class LobbysideWidgetComponent extends Component {
+export default class LobbysideWidgetComponent extends Component {
@service declare authenticator: AuthenticatorService;
+ get scriptId(): string {
+ return `lobbyside-widget-${this.args.widgetId}`;
+ }
+
get shouldShow(): boolean {
+ if ((this.args.audience ?? 'everyone') === 'staff') {
+ return userIsStaffOrAllowlisted(this.authenticator.currentUser);
+ }
+
return true;
}
@action
insertScript(): void {
- if (document.getElementById(LOBBYSIDE_SCRIPT_ID)) {
+ if (document.getElementById(this.scriptId)) {
this.syncVisitorData();
return;
}
const script = document.createElement('script');
- script.id = LOBBYSIDE_SCRIPT_ID;
+ script.id = this.scriptId;
script.src = 'https://lobbyside.com/widget.js';
- script.dataset['companyId'] = 'f6948b5a-eac2-4f92-8fce-54d4fb3bdaa4';
+ script.dataset['widgetId'] = this.args.widgetId;
script.onload = () => this.syncVisitorData();
document.body.appendChild(script);
}
@action
removeScript(): void {
- const script = document.getElementById(LOBBYSIDE_SCRIPT_ID);
-
- if (script) {
- script.remove();
- }
+ document.getElementById(this.scriptId)?.remove();
}
- private syncVisitorData(): void {
+ @action
+ syncVisitorData(): void {
const user = this.authenticator.currentUser;
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- if (!user || !(window as any)['Lobbyside']) {
+ if (!user || !window.Lobbyside) {
return;
}
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- const lobbyside = (window as any).Lobbyside;
-
- lobbyside.setVisitor({
+ window.Lobbyside.setVisitor({
email: user.primaryEmailAddress || '',
name: user.name || user.githubName || '',
github: user.githubUsername || '',
});
}
}
+
+declare module '@glint/environment-ember-loose/registry' {
+ export default interface Registry {
+ LobbysideWidget: typeof LobbysideWidgetComponent;
+ }
+}
diff --git a/app/services/beacon.ts b/app/services/beacon.ts
index 3d714560b1..b60a3fd632 100644
--- a/app/services/beacon.ts
+++ b/app/services/beacon.ts
@@ -2,6 +2,7 @@ import Service, { service } from '@ember/service';
import type RouterService from '@ember/routing/router-service';
import type RouteInfo from '@ember/routing/route-info';
import RouteInfoMetadata, { HelpscoutBeaconVisibility } from 'codecrafters-frontend/utils/route-info-metadata';
+import { userIsStaffOrAllowlisted } from 'codecrafters-frontend/utils/staff-allowlist';
import type AuthenticatorService from 'codecrafters-frontend/services/authenticator';
export default class HelpscoutBeaconService extends Service {
@@ -9,10 +10,8 @@ export default class HelpscoutBeaconService extends Service {
@service declare router: RouterService;
get shouldShowBeacon(): boolean {
- // Staff users and specific users see the Lobbyside widget instead of HelpScout
- const user = this.authenticator.currentUser;
-
- if (user?.isStaff || user?.username === 'vishaag' || user?.username === 'dronaxis') {
+ // Staff and allowlisted users see the Lobbyside widget instead of HelpScout
+ if (userIsStaffOrAllowlisted(this.authenticator.currentUser)) {
return false;
}
diff --git a/app/templates/application.hbs b/app/templates/application.hbs
index 67768c4202..40dcadeb22 100644
--- a/app/templates/application.hbs
+++ b/app/templates/application.hbs
@@ -22,8 +22,9 @@
{{/if}}
-
-
+
+
+
{{! Enable this to debug ember-animated animations }}
{{! }}
diff --git a/app/utils/staff-allowlist.ts b/app/utils/staff-allowlist.ts
new file mode 100644
index 0000000000..76f3732795
--- /dev/null
+++ b/app/utils/staff-allowlist.ts
@@ -0,0 +1,11 @@
+import type UserModel from 'codecrafters-frontend/models/user';
+
+export const STAFF_ALLOWLIST_USERNAMES = ['vishaag', 'dronaxis'];
+
+export function userIsStaffOrAllowlisted(user: UserModel | null | undefined): boolean {
+ if (!user) {
+ return false;
+ }
+
+ return user.isStaff || STAFF_ALLOWLIST_USERNAMES.includes(user.username);
+}