browsertrix/frontend/src/pages/home.ts
2022-09-27 14:32:57 -07:00

179 lines
4.8 KiB
TypeScript

import { state, property } from "lit/decorators.js";
import { msg, localized } from "@lit/localize";
import type { AuthState } from "../utils/AuthService";
import type { CurrentUser } from "../types/user";
import type { ArchiveData } from "../utils/archives";
import LiteElement, { html } from "../utils/LiteElement";
@localized()
export class Home extends LiteElement {
@property({ type: Object })
authState?: AuthState;
@property({ type: Object })
userInfo?: CurrentUser;
@state()
private isInviteComplete?: boolean;
@state()
private archiveList?: ArchiveData[];
async firstUpdated() {
this.archiveList = await this.getArchives();
}
connectedCallback() {
if (this.authState) {
super.connectedCallback();
} else {
this.navTo("/log-in");
}
}
render() {
if (!this.userInfo || !this.archiveList) {
return html`
<div class="flex items-center justify-center my-24 text-3xl">
<sl-spinner></sl-spinner>
</div>
`;
}
let title: any;
let content: any;
if (this.userInfo.isAdmin === true) {
title = msg("Welcome");
content = this.renderLoggedInAdmin();
}
if (this.userInfo.isAdmin === false) {
title = msg("Archives");
content = this.renderLoggedInNonAdmin();
}
return html`
<div class="bg-white">
<header
class="w-full max-w-screen-lg mx-auto px-3 py-4 box-border md:py-8"
>
<h1 class="text-xl font-medium">${title}</h1>
</header>
<hr />
</div>
<main class="w-full max-w-screen-lg mx-auto px-3 py-4 box-border">
${content}
</main>
`;
}
private renderLoggedInAdmin() {
if (this.archiveList!.length) {
return html`
<section class="border rounded-lg bg-white p-4 md:p-6 mb-5">
<sl-form
@sl-submit=${(e: CustomEvent) => {
const id = e.detail.formData.get("crawlId");
this.navTo(`/crawls/crawl/${id}`);
}}
>
<div class="flex flex-wrap items-center">
<div
class="w-full md:w-min grow-0 mr-8 text-lg font-medium whitespace-nowrap"
>
${msg("Go to Crawl")}
</div>
<div class="grow mt-2 md:mt-0 md:mr-2">
<sl-input
name="crawlId"
placeholder=${msg("Enter Crawl ID")}
required
></sl-input>
</div>
<div class="grow-0 mt-2 md:mt-0 text-right">
<sl-button type="neutral" submit>
<sl-icon slot="prefix" name="arrow-right-circle"></sl-icon>
${msg("Go")}</sl-button
>
</div>
</div>
</sl-form>
</section>
<div class="grid grid-cols-3 gap-8">
<div class="col-span-3 md:col-span-2">
<section>
<h2 class="text-lg font-medium mb-3 mt-2">
${msg("All Archives")}
</h2>
<btrix-archives-list
.userInfo=${this.userInfo}
.archiveList=${this.archiveList}
></btrix-archives-list>
</section>
</div>
<div class="col-span-3 md:col-span-1 md:mt-12">
<section class="md:border md:rounded-lg md:bg-white p-3 md:p-8">
<h2 class="text-lg font-medium mb-4">${msg("Invite a User")}</h2>
${this.renderInvite()}
</section>
</div>
</div>
`;
}
return html`
<section class="border rounded-lg bg-white p-4 md:p-8 mb-5">
<p class="text-lg mb-4 text-neutral-600">
${msg("Invite users to start archiving.")}
</p>
${this.renderInvite()}
</section>
`;
}
private renderLoggedInNonAdmin() {
if (this.archiveList && !this.archiveList.length) {
return html`<div class="border rounded-lg bg-white p-4 md:p-8">
<p class="text-neutral-400 text-center">
${msg("You don't have any archives.")}
</p>
</div>`;
}
return html`
<btrix-archives-list
.userInfo=${this.userInfo}
.archiveList=${this.archiveList}
?skeleton=${!this.archiveList}
></btrix-archives-list>
`;
}
private renderInvite() {
if (this.isInviteComplete) {
return html`
<sl-button @click=${() => (this.isInviteComplete = false)}
>${msg("Send another invite")}</sl-button
>
`;
}
return html`
<btrix-invite-form
.authState=${this.authState}
@success=${() => (this.isInviteComplete = true)}
></btrix-invite-form>
`;
}
private async getArchives(): Promise<ArchiveData[]> {
const data = await this.apiFetch("/archives", this.authState!);
return data.archives;
}
}