parent
316a91f612
commit
76e5ceb864
@ -5,8 +5,8 @@
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@shoelace-style/shoelace": "^2.0.0-beta.61",
|
||||
"axios": "^0.22.0",
|
||||
"daisyui": "^1.14.2",
|
||||
"lit": "^2.0.0",
|
||||
"lit-element-router": "^2.0.3",
|
||||
"path-parser": "^6.1.0",
|
||||
@ -29,6 +29,7 @@
|
||||
"@web/test-runner": "^0.13.22",
|
||||
"@web/test-runner-playwright": "^0.8.8",
|
||||
"autoprefixer": "^10.3.6",
|
||||
"copy-webpack-plugin": "^9.1.0",
|
||||
"css-loader": "^6.3.0",
|
||||
"dotenv": "^10.0.0",
|
||||
"eslint": "^8.2.0",
|
||||
|
@ -1,3 +1,4 @@
|
||||
import "./shoelace";
|
||||
import { LogInPage } from "./pages/log-in";
|
||||
import { MyAccountPage } from "./pages/my-account";
|
||||
import { ArchivePage } from "./pages/archive-info";
|
||||
@ -6,6 +7,7 @@ import LiteElement, { html } from "./utils/LiteElement";
|
||||
import APIRouter from "./utils/APIRouter";
|
||||
import type { ViewState, NavigateEvent } from "./utils/APIRouter";
|
||||
import type { AuthState } from "./types/auth";
|
||||
import theme from "./theme";
|
||||
|
||||
// ===========================================================================
|
||||
export class App extends LiteElement {
|
||||
@ -81,19 +83,20 @@ export class App extends LiteElement {
|
||||
|
||||
renderNavBar() {
|
||||
return html`
|
||||
<div class="navbar shadow-lg bg-neutral text-neutral-content">
|
||||
<style>
|
||||
${theme}
|
||||
</style>
|
||||
|
||||
<div class="flex p-3 shadow-lg bg-white text-neutral-content">
|
||||
<div class="flex-1 px-2 mx-2">
|
||||
<a
|
||||
href="/"
|
||||
class="link link-hover text-lg font-bold"
|
||||
@click="${this.navLink}"
|
||||
<a href="/" class="text-lg font-bold" @click="${this.navLink}"
|
||||
>Browsertrix Cloud</a
|
||||
>
|
||||
</div>
|
||||
<div class="flex-none">
|
||||
${this.authState
|
||||
? html` <a
|
||||
class="link link-hover font-bold px-4"
|
||||
class="font-bold px-4"
|
||||
href="/my-account"
|
||||
@click="${this.navLink}"
|
||||
>My Account</a
|
||||
|
@ -13,40 +13,32 @@ export class LogInPage extends LiteElement {
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<div class="hero min-h-screen bg-blue-400">
|
||||
<div
|
||||
class="text-center hero-content bg-base-200 shadow-2xl rounded-xl px-16 py-8"
|
||||
>
|
||||
<div class="flex items-center justify-center min-h-screen bg-blue-400">
|
||||
<div class="bg-white shadow-2xl rounded-xl px-12 py-12">
|
||||
<div class="max-w-md">
|
||||
<form action="" @submit="${this.onSubmit}">
|
||||
<div class="form-control">
|
||||
<label class="label">
|
||||
<span class="label-text">User</span>
|
||||
</label>
|
||||
<input
|
||||
id="username"
|
||||
<sl-form @sl-submit="${this.onSubmit}">
|
||||
<div class="mb-5">
|
||||
<sl-input
|
||||
name="username"
|
||||
type="text"
|
||||
label="Username"
|
||||
placeholder="Username"
|
||||
class="input input-bordered"
|
||||
/>
|
||||
required
|
||||
>
|
||||
</sl-input>
|
||||
</div>
|
||||
<div class="form-control">
|
||||
<label class="label">
|
||||
<span class="label-text">Password</span>
|
||||
</label>
|
||||
<input
|
||||
id="password"
|
||||
<div class="mb-5">
|
||||
<sl-input
|
||||
name="password"
|
||||
type="password"
|
||||
label="Password"
|
||||
placeholder="Password"
|
||||
class="input input-bordered"
|
||||
/>
|
||||
required
|
||||
>
|
||||
</sl-input>
|
||||
</div>
|
||||
<div class="form-control py-4">
|
||||
<button class="btn btn-primary" type="submit">Log In</button>
|
||||
</div>
|
||||
</form>
|
||||
<sl-button class="w-full" type="primary" submit>Log in</sl-button>
|
||||
</sl-form>
|
||||
|
||||
<div id="login-error" class="text-red-600">${this.loginError}</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -54,19 +46,16 @@ export class LogInPage extends LiteElement {
|
||||
`;
|
||||
}
|
||||
|
||||
async onSubmit(event: Event) {
|
||||
event.preventDefault();
|
||||
async onSubmit(event: { detail: { formData: FormData } }) {
|
||||
const { formData } = event.detail;
|
||||
|
||||
const username = (this.querySelector("#username") as HTMLInputElement)!
|
||||
.value;
|
||||
const username = formData.get("username") as string;
|
||||
const password = formData.get("password") as string;
|
||||
|
||||
const params = new URLSearchParams();
|
||||
params.set("grant_type", "password");
|
||||
params.set("username", username);
|
||||
params.set(
|
||||
"password",
|
||||
(this.querySelector("#password") as HTMLInputElement)!.value
|
||||
);
|
||||
params.set("password", password);
|
||||
|
||||
const headers = { "Content-Type": "application/x-www-form-urlencoded" };
|
||||
|
||||
|
8
frontend/src/shoelace.ts
Normal file
8
frontend/src/shoelace.ts
Normal file
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Cherry-picked Shoelace components
|
||||
* https://shoelace.style
|
||||
*/
|
||||
import "@shoelace-style/shoelace/dist/themes/light.css";
|
||||
import "@shoelace-style/shoelace/dist/components/button/button";
|
||||
import "@shoelace-style/shoelace/dist/components/form/form";
|
||||
import "@shoelace-style/shoelace/dist/components/input/input";
|
12
frontend/src/theme.ts
Normal file
12
frontend/src/theme.ts
Normal file
@ -0,0 +1,12 @@
|
||||
/**
|
||||
* https://github.com/shoelace-style/shoelace/blob/current/src/themes/light.styles.ts
|
||||
*/
|
||||
import { css } from "lit";
|
||||
|
||||
const theme = css`
|
||||
:root {
|
||||
/* TODO add custom variables here */
|
||||
}
|
||||
`;
|
||||
|
||||
export default theme;
|
@ -1,4 +1,53 @@
|
||||
// Use Shoelace CSS variables in Tailwind theme for consistency
|
||||
function makeTheme() {
|
||||
// Map color palettes:
|
||||
const colors = [
|
||||
"gray",
|
||||
"red",
|
||||
"yellow",
|
||||
"green",
|
||||
"blue",
|
||||
"indigo",
|
||||
"purple",
|
||||
"pink",
|
||||
];
|
||||
// Map color grading:
|
||||
const colorGrades = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900];
|
||||
|
||||
const makeColorPalette = (color) =>
|
||||
colorGrades.reduce((acc, v) => ({
|
||||
...acc,
|
||||
[v]: `var(--sl-color-${color}-${v})`,
|
||||
}));
|
||||
|
||||
return {
|
||||
colors: colors.map(makeColorPalette),
|
||||
fontFamily: {
|
||||
sans: `var(--sl-font-sans)`,
|
||||
serif: `var(--sl-font-serif)`,
|
||||
},
|
||||
borderRadius: {
|
||||
sm: `var(--sl-border-radius-small)`,
|
||||
DEFAULT: `var(--sl-border-radius-medium)`,
|
||||
md: `var(--sl-border-radius-medium)`,
|
||||
lg: `var(--sl-border-radius-large)`,
|
||||
xl: `var(--sl-border-radius-x-large)`,
|
||||
},
|
||||
boxShadow: {
|
||||
sm: `var(--sl-shadow-small)`,
|
||||
DEFAULT: `var(--sl-shadow-medium)`,
|
||||
md: `var(--sl-shadow-medium)`,
|
||||
lg: `var(--sl-shadow-large)`,
|
||||
xl: `var(--sl-shadow-x-large)`,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
theme: {
|
||||
extend: makeTheme(),
|
||||
},
|
||||
|
||||
mode: "jit",
|
||||
|
||||
purge: {
|
||||
@ -7,7 +56,7 @@ module.exports = {
|
||||
safelist: [/data-theme$/],
|
||||
},
|
||||
},
|
||||
plugins: [require("daisyui")],
|
||||
|
||||
extract: {
|
||||
include: ["./src/**/*.{ts,js}"],
|
||||
},
|
||||
|
@ -1,6 +1,7 @@
|
||||
// webpack.config.js
|
||||
const path = require("path");
|
||||
const ESLintPlugin = require("eslint-webpack-plugin");
|
||||
const CopyPlugin = require("copy-webpack-plugin");
|
||||
|
||||
const isDevServer = process.env.WEBPACK_SERVE;
|
||||
|
||||
@ -76,5 +77,18 @@ module.exports = {
|
||||
// enable to auto-fix source files:
|
||||
// fix: true
|
||||
}),
|
||||
|
||||
new CopyPlugin({
|
||||
patterns: [
|
||||
// Copy Shoelace assets to dist/shoelace
|
||||
{
|
||||
from: path.resolve(
|
||||
__dirname,
|
||||
"node_modules/@shoelace-style/shoelace/dist/assets"
|
||||
),
|
||||
to: path.resolve(__dirname, "dist/shoelace/assets"),
|
||||
},
|
||||
],
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
@ -85,6 +85,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@import-maps/resolve/-/resolve-1.0.1.tgz#1e9fcadcf23aa0822256a329aabca241879d37c9"
|
||||
integrity sha512-tWZNBIS1CoekcwlMuyG2mr0a1Wo5lb5lEHwwWvZo+5GLgr3e9LLDTtmgtCWEwBpXMkxn9D+2W9j2FY6eZQq0tA==
|
||||
|
||||
"@lit-labs/react@^1.0.1":
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@lit-labs/react/-/react-1.0.1.tgz#35f4a8fe12501f79e3973b408e67aa75dcd45ff4"
|
||||
integrity sha512-ShvoOB34Oj0ZkSnlWdGIWzSiEBP1MUY81nC3nAsNoWqbYMS2F/EskGzwSQj7mCKNznUCbmpB272AvSMwejm3Nw==
|
||||
|
||||
"@lit/reactive-element@^1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@lit/reactive-element/-/reactive-element-1.0.0.tgz#7b6e6a85709cda0370c47e425ac2f3b553696a4b"
|
||||
@ -116,6 +121,11 @@
|
||||
"@nodelib/fs.scandir" "2.1.5"
|
||||
fastq "^1.6.0"
|
||||
|
||||
"@popperjs/core@^2.7.0":
|
||||
version "2.10.2"
|
||||
resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.10.2.tgz#0798c03351f0dea1a5a4cabddf26a55a7cbee590"
|
||||
integrity sha512-IXf3XA7+XyN7CP9gGh/XB0UxVMlvARGEgGXLubFICsUMGz6Q+DU+i4gGlpOxTjKvXjkJDJC8YdqdKkDj9qZHEQ==
|
||||
|
||||
"@rollup/plugin-node-resolve@^11.0.1":
|
||||
version "11.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz#82aa59397a29cd4e13248b106e6a4a1880362a60"
|
||||
@ -137,6 +147,23 @@
|
||||
estree-walker "^1.0.1"
|
||||
picomatch "^2.2.2"
|
||||
|
||||
"@shoelace-style/animations@^1.1.0":
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@shoelace-style/animations/-/animations-1.1.0.tgz#17539abafd6dcbf2a79e089e1593175e9f7835b5"
|
||||
integrity sha512-Be+cahtZyI2dPKRm8EZSx3YJQ+jLvEcn3xzRP7tM4tqBnvd/eW/64Xh0iOf0t2w5P8iJKfdBbpVNE9naCaOf2g==
|
||||
|
||||
"@shoelace-style/shoelace@^2.0.0-beta.61":
|
||||
version "2.0.0-beta.61"
|
||||
resolved "https://registry.yarnpkg.com/@shoelace-style/shoelace/-/shoelace-2.0.0-beta.61.tgz#9ad34b16e2c9c1e304b970ff5793705026b134d8"
|
||||
integrity sha512-kt9r0HM5MiN3UU8rZ4QYjSdfqgyqVCp0FeSRu3L/HFSj18Ggl5kQ21bP1Up/1URFVJ/webfJ2Jrp4swbHdjYAA==
|
||||
dependencies:
|
||||
"@lit-labs/react" "^1.0.1"
|
||||
"@popperjs/core" "^2.7.0"
|
||||
"@shoelace-style/animations" "^1.1.0"
|
||||
color "^3.1.3"
|
||||
lit "^2.0.2"
|
||||
qr-creator "^1.0.0"
|
||||
|
||||
"@types/accepts@*":
|
||||
version "1.3.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/accepts/-/accepts-1.3.5.tgz#c34bec115cfc746e04fe5a059df4ce7e7b391575"
|
||||
@ -1266,7 +1293,7 @@ co@^4.6.0:
|
||||
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
|
||||
integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=
|
||||
|
||||
color-convert@^1.9.0:
|
||||
color-convert@^1.9.0, color-convert@^1.9.3:
|
||||
version "1.9.3"
|
||||
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
|
||||
integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
|
||||
@ -1298,6 +1325,14 @@ color-string@^1.6.0:
|
||||
color-name "^1.0.0"
|
||||
simple-swizzle "^0.2.2"
|
||||
|
||||
color@^3.1.3:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/color/-/color-3.2.1.tgz#3544dc198caf4490c3ecc9a790b54fe9ff45e164"
|
||||
integrity sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==
|
||||
dependencies:
|
||||
color-convert "^1.9.3"
|
||||
color-string "^1.6.0"
|
||||
|
||||
color@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/color/-/color-4.0.1.tgz#21df44cd10245a91b1ccf5ba031609b0e10e7d67"
|
||||
@ -1423,6 +1458,18 @@ cookies@~0.8.0:
|
||||
depd "~2.0.0"
|
||||
keygrip "~1.1.0"
|
||||
|
||||
copy-webpack-plugin@^9.1.0:
|
||||
version "9.1.0"
|
||||
resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-9.1.0.tgz#2d2c460c4c4695ec0a58afb2801a1205256c4e6b"
|
||||
integrity sha512-rxnR7PaGigJzhqETHGmAcxKnLZSR5u1Y3/bcIv/1FnqXedcL/E2ewK7ZCNrArJKCiSv8yVXhTqetJh8inDvfsA==
|
||||
dependencies:
|
||||
fast-glob "^3.2.7"
|
||||
glob-parent "^6.0.1"
|
||||
globby "^11.0.3"
|
||||
normalize-path "^3.0.0"
|
||||
schema-utils "^3.1.1"
|
||||
serialize-javascript "^6.0.0"
|
||||
|
||||
core-util-is@~1.0.0:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85"
|
||||
@ -1477,11 +1524,6 @@ cssesc@^3.0.0:
|
||||
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
|
||||
integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==
|
||||
|
||||
daisyui@^1.14.2:
|
||||
version "1.14.2"
|
||||
resolved "https://registry.yarnpkg.com/daisyui/-/daisyui-1.14.2.tgz#4f8569244b8798374d5717035f7017d5fc0c0621"
|
||||
integrity sha512-ER4k58JMUYF4EUDg3GgpaWPdvq6FYnMfetV2JXOEWAPNQVWs4jHtdhehFUdg7M1Lae9GGobb0roW3LuEmD/PuA==
|
||||
|
||||
debounce@^1.2.0:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.1.tgz#38881d8f4166a5c5848020c11827b834bcb3e0a5"
|
||||
@ -2230,7 +2272,7 @@ globals@^13.6.0, globals@^13.9.0:
|
||||
dependencies:
|
||||
type-fest "^0.20.2"
|
||||
|
||||
globby@^11.0.1, globby@^11.0.4:
|
||||
globby@^11.0.1, globby@^11.0.3, globby@^11.0.4:
|
||||
version "11.0.4"
|
||||
resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5"
|
||||
integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==
|
||||
@ -2945,6 +2987,15 @@ lit@^2.0.0:
|
||||
lit-element "^3.0.0"
|
||||
lit-html "^2.0.0"
|
||||
|
||||
lit@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/lit/-/lit-2.0.2.tgz#5e6f422924e0732258629fb379556b6d23f7179c"
|
||||
integrity sha512-hKA/1YaSB+P+DvKWuR2q1Xzy/iayhNrJ3aveD0OQ9CKn6wUjsdnF/7LavDOJsKP/K5jzW/kXsuduPgRvTFrFJw==
|
||||
dependencies:
|
||||
"@lit/reactive-element" "^1.0.0"
|
||||
lit-element "^3.0.0"
|
||||
lit-html "^2.0.0"
|
||||
|
||||
loader-runner@^4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384"
|
||||
@ -3690,6 +3741,11 @@ purgecss@^4.0.3:
|
||||
postcss "^8.2.1"
|
||||
postcss-selector-parser "^6.0.2"
|
||||
|
||||
qr-creator@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/qr-creator/-/qr-creator-1.0.0.tgz#f350a8f0b5be02bd1fc1ef133a038a06ef8bc5ef"
|
||||
integrity sha512-C0cqfbS1P5hfqN4NhsYsUXePlk9BO+a45bAQ3xLYjBL3bOIFzoVEjs79Fado9u9BPBD3buHi3+vY+C8tHh4qMQ==
|
||||
|
||||
qs@6.7.0:
|
||||
version "6.7.0"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc"
|
||||
|
Loading…
Reference in New Issue
Block a user