Show invite info to user (#68)
This commit is contained in:
parent
3324bd960f
commit
2c3debfec6
@ -50,8 +50,10 @@ export class SignUpForm extends LiteElement {
|
||||
<div class="mb-5">
|
||||
${this.email
|
||||
? html`
|
||||
<span class="text-gray-400">${msg("Joining as")}</span>
|
||||
<span class="text-primary font-medium">${this.email}</span>
|
||||
<div style="font-size: var(--sl-input-label-font-size-medium)">
|
||||
${msg("Joining as")}
|
||||
</div>
|
||||
<div class="font-medium py-1">${this.email}</div>
|
||||
<input
|
||||
type="hidden"
|
||||
id="email"
|
||||
|
@ -289,12 +289,12 @@ export class App extends LiteElement {
|
||||
case "signUp": {
|
||||
if (!this.isAppSettingsLoaded) {
|
||||
return html`<div
|
||||
class="w-full md:bg-gray-100 flex items-center justify-center"
|
||||
class="w-full md:bg-gray-50 flex items-center justify-center"
|
||||
></div>`;
|
||||
}
|
||||
if (this.isRegistrationEnabled) {
|
||||
return html`<btrix-sign-up
|
||||
class="w-full md:bg-gray-100 flex items-center justify-center"
|
||||
class="w-full md:bg-gray-50 flex items-center justify-center"
|
||||
@navigate="${this.onNavigateTo}"
|
||||
@logged-in="${this.onLoggedIn}"
|
||||
@log-out="${this.onLogOut}"
|
||||
@ -307,7 +307,7 @@ export class App extends LiteElement {
|
||||
|
||||
case "verify":
|
||||
return html`<btrix-verify
|
||||
class="w-full md:bg-gray-100 flex items-center justify-center"
|
||||
class="w-full md:bg-gray-50 flex items-center justify-center"
|
||||
token="${this.viewState.params.token}"
|
||||
@navigate="${this.onNavigateTo}"
|
||||
@notify="${this.onNotify}"
|
||||
@ -318,7 +318,7 @@ export class App extends LiteElement {
|
||||
|
||||
case "join":
|
||||
return html`<btrix-join
|
||||
class="w-full md:bg-gray-100 flex items-center justify-center"
|
||||
class="w-full md:bg-gray-50 flex items-center justify-center"
|
||||
@navigate="${this.onNavigateTo}"
|
||||
@logged-in="${this.onLoggedIn}"
|
||||
token="${this.viewState.params.token}"
|
||||
@ -327,7 +327,7 @@ export class App extends LiteElement {
|
||||
|
||||
case "acceptInvite":
|
||||
return html`<btrix-accept-invite
|
||||
class="w-full md:bg-gray-100 flex items-center justify-center"
|
||||
class="w-full md:bg-gray-50 flex items-center justify-center"
|
||||
@navigate="${this.onNavigateTo}"
|
||||
@logged-in="${this.onLoggedIn}"
|
||||
@notify="${this.onNotify}"
|
||||
@ -340,7 +340,7 @@ export class App extends LiteElement {
|
||||
case "loginWithRedirect":
|
||||
case "forgotPassword":
|
||||
return html`<btrix-log-in
|
||||
class="w-full md:bg-gray-100 flex items-center justify-center"
|
||||
class="w-full md:bg-gray-50 flex items-center justify-center"
|
||||
@navigate=${this.onNavigateTo}
|
||||
@logged-in=${this.onLoggedIn}
|
||||
.authState=${this.authService.authState}
|
||||
@ -350,7 +350,7 @@ export class App extends LiteElement {
|
||||
|
||||
case "resetPassword":
|
||||
return html`<btrix-reset-password
|
||||
class="w-full md:bg-gray-100 flex items-center justify-center"
|
||||
class="w-full md:bg-gray-50 flex items-center justify-center"
|
||||
@navigate=${this.onNavigateTo}
|
||||
@logged-in=${this.onLoggedIn}
|
||||
.authState=${this.authService.authState}
|
||||
@ -431,7 +431,7 @@ export class App extends LiteElement {
|
||||
|
||||
renderNotFoundPage() {
|
||||
return html`<btrix-not-found
|
||||
class="w-full md:bg-gray-100 flex items-center justify-center"
|
||||
class="w-full md:bg-gray-50 flex items-center justify-center"
|
||||
></btrix-not-found>`;
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,8 @@
|
||||
import { state, property } from "lit/decorators.js";
|
||||
import { msg, localized } from "@lit/localize";
|
||||
import { msg, str, localized } from "@lit/localize";
|
||||
|
||||
import LiteElement, { html } from "../utils/LiteElement";
|
||||
import type { AuthState, LoggedInEvent } from "../utils/AuthService";
|
||||
import AuthService from "../utils/AuthService";
|
||||
import type { AuthState } from "../utils/AuthService";
|
||||
import { DASHBOARD_ROUTE } from "../routes";
|
||||
|
||||
@localized()
|
||||
@ -20,6 +19,17 @@ export class AcceptInvite extends LiteElement {
|
||||
@state()
|
||||
serverError?: string;
|
||||
|
||||
@state()
|
||||
private inviteInfo: {
|
||||
inviterEmail: string;
|
||||
inviterName: string;
|
||||
archiveName: string;
|
||||
} = {
|
||||
inviterEmail: "",
|
||||
inviterName: "",
|
||||
archiveName: "",
|
||||
};
|
||||
|
||||
connectedCallback(): void {
|
||||
if (this.token && this.email) {
|
||||
super.connectedCallback();
|
||||
@ -35,7 +45,9 @@ export class AcceptInvite extends LiteElement {
|
||||
}
|
||||
|
||||
firstUpdated() {
|
||||
if (!this.isLoggedIn) {
|
||||
if (this.isLoggedIn) {
|
||||
this.getInviteInfo();
|
||||
} else {
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("notify", {
|
||||
detail: {
|
||||
@ -60,7 +72,7 @@ export class AcceptInvite extends LiteElement {
|
||||
|
||||
if (this.serverError) {
|
||||
serverError = html`
|
||||
<div class="mb-5">
|
||||
<div>
|
||||
<btrix-alert id="formError" type="danger"
|
||||
>${this.serverError}</btrix-alert
|
||||
>
|
||||
@ -68,27 +80,69 @@ export class AcceptInvite extends LiteElement {
|
||||
`;
|
||||
}
|
||||
|
||||
const hasInviteInfo = Boolean(this.inviteInfo.inviterEmail);
|
||||
const placeholder = html`<span
|
||||
class="inline-block bg-gray-100 rounded-full"
|
||||
style="width: 6em"
|
||||
> </span
|
||||
>`;
|
||||
|
||||
if (serverError && !hasInviteInfo) {
|
||||
return serverError;
|
||||
}
|
||||
|
||||
return html`
|
||||
<article class="w-full max-w-sm grid gap-5">
|
||||
<article class="w-full p-5 grid gap-5 justify-center text-center">
|
||||
${serverError}
|
||||
|
||||
<main class="md:bg-white md:shadow-xl md:rounded-lg md:px-12 md:py-12">
|
||||
<h1 class="text-3xl text-center font-semibold mb-5">
|
||||
${msg("Join archive")}
|
||||
</h1>
|
||||
|
||||
<!-- TODO archive details -->
|
||||
<div class="mb-3 text-sm text-gray-400">
|
||||
${msg("Invited by ")}
|
||||
${this.inviteInfo.inviterName ||
|
||||
this.inviteInfo.inviterEmail ||
|
||||
placeholder}
|
||||
</div>
|
||||
<p class="text-xl font-semibold mb-5">
|
||||
${msg(
|
||||
html`You've been invited to join
|
||||
<span class="text-primary break-words"
|
||||
>${hasInviteInfo
|
||||
? this.inviteInfo.archiveName || msg("Browsertrix Cloud")
|
||||
: placeholder}</span
|
||||
>`
|
||||
)}
|
||||
</p>
|
||||
|
||||
<div class="text-center">
|
||||
<sl-button type="primary" @click=${this.onAccept}
|
||||
<sl-button class="mr-2" type="primary" @click=${this.onAccept}
|
||||
>${msg("Accept invitation")}</sl-button
|
||||
>
|
||||
<sl-button @click=${this.onDecline}>${msg("Decline")}</sl-button>
|
||||
</div>
|
||||
</main>
|
||||
</article>
|
||||
`;
|
||||
}
|
||||
|
||||
private async getInviteInfo() {
|
||||
if (!this.authState) return;
|
||||
|
||||
try {
|
||||
const data = await this.apiFetch(
|
||||
`/users/me/invite/${this.token}`,
|
||||
this.authState
|
||||
);
|
||||
|
||||
this.inviteInfo = {
|
||||
inviterEmail: data.inviterEmail,
|
||||
inviterName: data.inviterName,
|
||||
archiveName: data.archiveName,
|
||||
};
|
||||
} catch {
|
||||
this.serverError = msg("This invitation is not valid");
|
||||
}
|
||||
}
|
||||
|
||||
private async onAccept() {
|
||||
if (!this.authState || !this.isLoggedIn) {
|
||||
// TODO handle error
|
||||
@ -109,8 +163,7 @@ export class AcceptInvite extends LiteElement {
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("notify", {
|
||||
detail: {
|
||||
// TODO archive details
|
||||
message: msg("You've joined the archive."),
|
||||
message: msg(str`You've joined ${this.inviteInfo.archiveName}.`),
|
||||
type: "success",
|
||||
icon: "check2-circle",
|
||||
},
|
||||
@ -120,10 +173,26 @@ export class AcceptInvite extends LiteElement {
|
||||
this.navTo(DASHBOARD_ROUTE);
|
||||
} catch (err: any) {
|
||||
if (err.isApiError && err.message === "Invalid Invite Code") {
|
||||
this.serverError = msg("This invitation is not valid.");
|
||||
this.serverError = msg("This invitation is not valid");
|
||||
} else {
|
||||
this.serverError = msg("Something unexpected went wrong");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private onDecline() {
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("notify", {
|
||||
detail: {
|
||||
message: msg(
|
||||
str`You've declined to join ${this.inviteInfo.archiveName}.`
|
||||
),
|
||||
type: "info",
|
||||
icon: "info-circle",
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
this.navTo(DASHBOARD_ROUTE);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { state, property } from "lit/decorators.js";
|
||||
import { msg, localized } from "@lit/localize";
|
||||
import { msg, str, localized } from "@lit/localize";
|
||||
|
||||
import LiteElement, { html } from "../utils/LiteElement";
|
||||
import type { LoggedInEvent } from "../utils/AuthService";
|
||||
@ -14,7 +14,18 @@ export class Join extends LiteElement {
|
||||
email?: string;
|
||||
|
||||
@state()
|
||||
serverError?: string;
|
||||
private serverError?: string;
|
||||
|
||||
@state()
|
||||
private inviteInfo: {
|
||||
inviterEmail: string;
|
||||
inviterName: string;
|
||||
archiveName: string;
|
||||
} = {
|
||||
inviterEmail: "",
|
||||
inviterName: "",
|
||||
archiveName: "",
|
||||
};
|
||||
|
||||
connectedCallback(): void {
|
||||
if (this.token && this.email) {
|
||||
@ -24,16 +35,46 @@ export class Join extends LiteElement {
|
||||
}
|
||||
}
|
||||
|
||||
firstUpdated() {
|
||||
this.getInviteInfo();
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.serverError) {
|
||||
return html`<btrix-alert type="danger">${this.serverError}</btrix-alert>`;
|
||||
}
|
||||
|
||||
const hasInviteInfo = Boolean(this.inviteInfo.inviterEmail);
|
||||
const placeholder = html`<span
|
||||
class="inline-block bg-gray-100 rounded-full"
|
||||
style="width: 6em"
|
||||
> </span
|
||||
>`;
|
||||
|
||||
return html`
|
||||
<article class="w-full max-w-sm grid gap-5">
|
||||
<main class="md:bg-white md:shadow-xl md:rounded-lg md:px-12 md:py-12">
|
||||
<h1 class="text-3xl font-semibold mb-5">
|
||||
${msg("Join Browsertrix Cloud")}
|
||||
</h1>
|
||||
|
||||
<!-- TODO archive details if available -->
|
||||
<article class="w-full p-5 flex flex-col md:flex-row justify-center">
|
||||
<div class="max-w-sm md:mt-12 md:mr-12">
|
||||
<div class="mb-3 text-sm text-gray-400">
|
||||
${msg("Invited by ")}
|
||||
${this.inviteInfo.inviterName ||
|
||||
this.inviteInfo.inviterEmail ||
|
||||
placeholder}
|
||||
</div>
|
||||
<p class="text-xl md:text-3xl font-semibold mb-5">
|
||||
${msg(
|
||||
html`You've been invited to join
|
||||
<span class="text-primary break-words"
|
||||
>${hasInviteInfo
|
||||
? this.inviteInfo.archiveName || msg("Browsertrix Cloud")
|
||||
: placeholder}</span
|
||||
>`
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<main
|
||||
class="max-w-md md:bg-white md:shadow-xl md:rounded-lg md:px-12 md:py-12"
|
||||
>
|
||||
<btrix-sign-up-form
|
||||
email=${this.email!}
|
||||
inviteToken=${this.token!}
|
||||
@ -44,6 +85,24 @@ export class Join extends LiteElement {
|
||||
`;
|
||||
}
|
||||
|
||||
private async getInviteInfo() {
|
||||
const resp = await fetch(
|
||||
`/api/users/invite/${this.token}?email=${encodeURIComponent(this.email!)}`
|
||||
);
|
||||
|
||||
if (resp.status === 200) {
|
||||
const body = await resp.json();
|
||||
|
||||
this.inviteInfo = {
|
||||
inviterEmail: body.inviterEmail,
|
||||
inviterName: body.inviterName,
|
||||
archiveName: body.archiveName,
|
||||
};
|
||||
} else {
|
||||
this.serverError = msg("This invitation is not valid");
|
||||
}
|
||||
}
|
||||
|
||||
private onAuthenticated(event: LoggedInEvent) {
|
||||
this.dispatchEvent(
|
||||
AuthService.createLoggedInEvent({
|
||||
|
Loading…
Reference in New Issue
Block a user