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