diff --git a/frontend/index.html b/frontend/index.html index 6dd149a..52c287f 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -4,12 +4,6 @@ Tranquil PDS - - - diff --git a/frontend/src/lib/toast.svelte.ts b/frontend/src/lib/toast.svelte.ts index b077bae..6803039 100644 --- a/frontend/src/lib/toast.svelte.ts +++ b/frontend/src/lib/toast.svelte.ts @@ -5,7 +5,6 @@ export interface Toast { type: ToastType; message: string; duration: number; - dismissing?: boolean; } let nextId = 0; @@ -33,14 +32,7 @@ export function showToast( } export function dismissToast(id: number): void { - const toast = toasts.find((t) => t.id === id); - if (!toast || toast.dismissing) return; - - toasts = toasts.map((t) => t.id === id ? { ...t, dismissing: true } : t); - - setTimeout(() => { - toasts = toasts.filter((t) => t.id !== id); - }, 150); + toasts = toasts.filter((t) => t.id !== id); } export function clearAllToasts(): void { diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json index ae95b30..21fcd59 100644 --- a/frontend/src/locales/en.json +++ b/frontend/src/locales/en.json @@ -266,7 +266,7 @@ "appPasswords": { "create": "Create", "name": "Name", - "namePlaceholder": "App name (eg., Graysky)", + "namePlaceholder": "App name (eg. Witchsky)", "created": "App Password Created", "createdMessage": "Copy this password now. You won't be able to see it again.", "noPasswords": "No app passwords yet", @@ -334,7 +334,7 @@ "adding": "Adding...", "noPasskeys": "No passkeys registered", "passkeyName": "Passkey name", - "passkeyNamePlaceholder": "eg., MacBook Pro, iPhone", + "passkeyNamePlaceholder": "eg. yubikey, phone", "rename": "Rename", "deletePasskey": "Delete", "deletePasskeyConfirm": "Delete passkey \"{name}\"? You won't be able to use it to sign in anymore.", @@ -762,7 +762,7 @@ "externalDidPlaceholder": "did:web:yourdomain.com", "externalDidHint": "Serve DID document at", "passkeyName": "Passkey Name", - "passkeyNamePlaceholder": "MacBook Touch ID", + "passkeyNamePlaceholder": "eg. yubikey, phone", "passkeyNameHint": "Optional identifier", "setupPasskey": "Create Passkey", "passkeyDescription": "Register a passkey for this account", @@ -1038,7 +1038,7 @@ "title": "Set Up Your Passkey", "desc": "Your email has been verified. Now set up your passkey for secure, passwordless login.", "nameLabel": "Passkey Name (optional)", - "namePlaceholder": "eg., MacBook Pro, iPhone", + "namePlaceholder": "eg. yubikey, phone", "nameHint": "A friendly name to identify this passkey", "instructions": "Click the button below to register your passkey. Your device will prompt you to use biometrics (fingerprint, Face ID) or a security key.", "register": "Register Passkey", diff --git a/frontend/src/locales/fi.json b/frontend/src/locales/fi.json index 20d45fa..0b68cd2 100644 --- a/frontend/src/locales/fi.json +++ b/frontend/src/locales/fi.json @@ -278,7 +278,7 @@ "byController": "Hallinnoijan luoma", "create": "Luo", "name": "Nimi", - "namePlaceholder": "Sovelluksen nimi (esim. Graysky)", + "namePlaceholder": "Sovelluksen nimi (esim. Witchsky)", "deleteConfirm": "Peruuta sovelluksen salasana \"{name}\"?", "deleted": "Sovelluksen salasana peruutettu", "loadFailed": "Sovellusten salasanojen lataus epäonnistui", @@ -334,7 +334,7 @@ "adding": "Lisätään...", "noPasskeys": "Ei rekisteröityjä pääsyavaimia", "passkeyName": "Pääsyavaimen nimi", - "passkeyNamePlaceholder": "esim. MacBook Pro, iPhone", + "passkeyNamePlaceholder": "esim. yubikey, puhelin", "rename": "Nimeä uudelleen", "deletePasskey": "Poista", "deletePasskeyConfirm": "Poista pääsyavain \"{name}\"? Et voi enää käyttää sitä kirjautumiseen.", @@ -758,7 +758,7 @@ }, "identityType": "Identiteettityyppi", "identityTypeHint": "Valitse, miten hajautettua identiteettiäsi hallitaan.", - "passkeyNamePlaceholder": "esim. MacBook Touch ID", + "passkeyNamePlaceholder": "esim. yubikey, puhelin", "passkeyNameHint": "Ystävällinen nimi tämän pääsyavaimen tunnistamiseksi", "createPasskey": "Luo pääsyavain", "didPlcRecommended": "did:plc (Suositeltava)", @@ -1037,7 +1037,7 @@ "title": "Määritä pääsyavaimesi", "desc": "Sähköpostisi on vahvistettu. Määritä nyt pääsyavaimesi turvallista, salasanatonta kirjautumista varten.", "nameLabel": "Pääsyavaimen nimi (valinnainen)", - "namePlaceholder": "esim. MacBook Pro, iPhone", + "namePlaceholder": "esim. yubikey, puhelin", "nameHint": "Kutsumanimi tämän pääsyavaimen tunnistamiseen", "instructions": "Klikkaa alla olevaa painiketta rekisteröidäksesi pääsyavaimesi. Laitteesi pyytää käyttämään biometriikkaa (sormenjälki, Face ID) tai suojausavainta.", "register": "Rekisteröi pääsyavain", diff --git a/frontend/src/locales/ja.json b/frontend/src/locales/ja.json index 691302a..8d5754c 100644 --- a/frontend/src/locales/ja.json +++ b/frontend/src/locales/ja.json @@ -278,7 +278,7 @@ "byController": "管理者作成", "create": "作成", "name": "名前", - "namePlaceholder": "アプリ名(例:Graysky)", + "namePlaceholder": "アプリ名(例:Witchsky)", "deleteConfirm": "アプリパスワード「{name}」を取り消しますか?", "deleted": "アプリパスワードを取り消しました", "loadFailed": "アプリパスワードの読み込みに失敗しました", @@ -334,7 +334,7 @@ "adding": "追加中...", "noPasskeys": "登録されたパスキーはありません", "passkeyName": "パスキー名", - "passkeyNamePlaceholder": "例: MacBook Pro、iPhone", + "passkeyNamePlaceholder": "例: yubikey、スマホ", "rename": "名前変更", "deletePasskey": "削除", "deletePasskeyConfirm": "パスキー「{name}」を削除しますか?サインインに使用できなくなります。", @@ -758,7 +758,7 @@ }, "identityType": "アイデンティティタイプ", "identityTypeHint": "分散型アイデンティティの管理方法を選択してください。", - "passkeyNamePlaceholder": "例:MacBook Touch ID", + "passkeyNamePlaceholder": "例: yubikey、スマホ", "passkeyNameHint": "このパスキーを識別するための名前", "createPasskey": "パスキーを作成", "didPlcRecommended": "did:plc(推奨)", @@ -1037,7 +1037,7 @@ "title": "パスキーを設定", "desc": "メールが確認されました。安全なパスワードレスログインのためにパスキーを設定してください。", "nameLabel": "パスキー名(任意)", - "namePlaceholder": "例:MacBook Pro、iPhone", + "namePlaceholder": "例: yubikey、スマホ", "nameHint": "このパスキーを識別するためのわかりやすい名前", "instructions": "下のボタンをクリックしてパスキーを登録してください。デバイスが生体認証(指紋、Face ID)またはセキュリティキーの使用を促します。", "register": "パスキーを登録", diff --git a/frontend/src/locales/ko.json b/frontend/src/locales/ko.json index e7d3305..5767992 100644 --- a/frontend/src/locales/ko.json +++ b/frontend/src/locales/ko.json @@ -278,7 +278,7 @@ "byController": "컨트롤러 생성", "create": "생성", "name": "이름", - "namePlaceholder": "앱 이름 (예: Graysky)", + "namePlaceholder": "앱 이름 (예: Witchsky)", "deleteConfirm": "앱 비밀번호 \"{name}\"을(를) 취소하시겠습니까?", "deleted": "앱 비밀번호가 취소되었습니다", "loadFailed": "앱 비밀번호 로딩 실패", @@ -334,7 +334,7 @@ "adding": "추가 중...", "noPasskeys": "등록된 패스키가 없습니다", "passkeyName": "패스키 이름", - "passkeyNamePlaceholder": "예: MacBook Pro, iPhone", + "passkeyNamePlaceholder": "예: yubikey, 휴대폰", "rename": "이름 변경", "deletePasskey": "삭제", "deletePasskeyConfirm": "패스키 \"{name}\"을(를) 삭제하시겠습니까? 더 이상 로그인에 사용할 수 없습니다.", @@ -758,7 +758,7 @@ }, "identityType": "아이덴티티 유형", "identityTypeHint": "분산 아이덴티티 관리 방법을 선택하세요.", - "passkeyNamePlaceholder": "예: MacBook Touch ID", + "passkeyNamePlaceholder": "예: yubikey, 휴대폰", "passkeyNameHint": "이 패스키를 식별할 수 있는 이름", "createPasskey": "패스키 생성", "didPlcRecommended": "did:plc (권장)", @@ -1037,7 +1037,7 @@ "title": "패스키 설정", "desc": "이메일이 인증되었습니다. 안전한 비밀번호 없는 로그인을 위해 패스키를 설정하세요.", "nameLabel": "패스키 이름 (선택사항)", - "namePlaceholder": "예: MacBook Pro, iPhone", + "namePlaceholder": "예: yubikey, 휴대폰", "nameHint": "이 패스키를 식별하기 위한 이름", "instructions": "아래 버튼을 클릭하여 패스키를 등록하세요. 기기에서 생체 인식(지문, Face ID) 또는 보안 키 사용을 요청합니다.", "register": "패스키 등록", diff --git a/frontend/src/locales/sv.json b/frontend/src/locales/sv.json index 37f91e4..494d7be 100644 --- a/frontend/src/locales/sv.json +++ b/frontend/src/locales/sv.json @@ -278,7 +278,7 @@ "byController": "Av controller", "create": "Skapa", "name": "Namn", - "namePlaceholder": "Appnamn (t.ex. Graysky)", + "namePlaceholder": "Appnamn (t.ex. Witchsky)", "deleteConfirm": "Återkalla applösenord \"{name}\"?", "deleted": "Applösenord återkallat", "loadFailed": "Kunde inte ladda applösenord", @@ -334,7 +334,7 @@ "adding": "Lägger till...", "noPasskeys": "Inga nycklar registrerade", "passkeyName": "Nyckelnamn", - "passkeyNamePlaceholder": "t.ex. MacBook Pro, iPhone", + "passkeyNamePlaceholder": "t.ex. yubikey, telefon", "rename": "Byt namn", "deletePasskey": "Radera", "deletePasskeyConfirm": "Radera nyckel \"{name}\"? Du kommer inte att kunna använda den för att logga in längre.", @@ -758,7 +758,7 @@ }, "identityType": "Identitetstyp", "identityTypeHint": "Välj hur din decentraliserade identitet ska hanteras.", - "passkeyNamePlaceholder": "t.ex. MacBook Touch ID", + "passkeyNamePlaceholder": "t.ex. yubikey, telefon", "passkeyNameHint": "Ett vänligt namn för att identifiera denna nyckel", "createPasskey": "Skapa nyckel", "didPlcRecommended": "did:plc (Rekommenderas)", @@ -1037,7 +1037,7 @@ "title": "Konfigurera din passkey", "desc": "Din e-post har verifierats. Konfigurera nu din passkey för säker, lösenordslös inloggning.", "nameLabel": "Passkey-namn (valfritt)", - "namePlaceholder": "t.ex. MacBook Pro, iPhone", + "namePlaceholder": "t.ex. yubikey, telefon", "nameHint": "Ett vänligt namn för att identifiera denna passkey", "instructions": "Klicka på knappen nedan för att registrera din passkey. Din enhet kommer att uppmana dig att använda biometri (fingeravtryck, Face ID) eller en säkerhetsnyckel.", "register": "Registrera passkey", diff --git a/frontend/src/locales/zh.json b/frontend/src/locales/zh.json index 18f3f06..352b6bc 100644 --- a/frontend/src/locales/zh.json +++ b/frontend/src/locales/zh.json @@ -278,7 +278,7 @@ "byController": "由控制者创建", "create": "创建", "name": "名称", - "namePlaceholder": "应用名称(如 Graysky)", + "namePlaceholder": "应用名称(如 Witchsky)", "deleteConfirm": "撤销应用专用密码「{name}」?", "deleted": "应用专用密码已撤销", "loadFailed": "加载应用专用密码失败", @@ -334,7 +334,7 @@ "adding": "添加中...", "noPasskeys": "未注册通行密钥", "passkeyName": "通行密钥名称", - "passkeyNamePlaceholder": "如 MacBook Pro、iPhone", + "passkeyNamePlaceholder": "如 yubikey、手机", "rename": "重命名", "deletePasskey": "删除", "deletePasskeyConfirm": "删除通行密钥「{name}」?您将无法再使用它登录。", @@ -761,7 +761,7 @@ "externalDidPlaceholder": "did:web:yourdomain.com", "externalDidHint": "您需要在以下地址提供 DID 文档", "passkeyName": "通行密钥名称", - "passkeyNamePlaceholder": "MacBook Touch ID", + "passkeyNamePlaceholder": "如 yubikey、手机", "passkeyNameHint": "可选标识", "createPasskey": "创建通行密钥", "errors": { @@ -1037,7 +1037,7 @@ "title": "设置您的通行密钥", "desc": "您的邮箱已验证。现在设置通行密钥以实现安全的无密码登录。", "nameLabel": "通行密钥名称(可选)", - "namePlaceholder": "例如:MacBook Pro、iPhone", + "namePlaceholder": "如 yubikey、手机", "nameHint": "用于识别此通行密钥的友好名称", "instructions": "点击下方按钮注册您的通行密钥。您的设备将提示您使用生物识别(指纹、面容ID)或安全密钥。", "register": "注册通行密钥", diff --git a/frontend/src/main.ts b/frontend/src/main.ts index 6ef7a3a..99fef30 100644 --- a/frontend/src/main.ts +++ b/frontend/src/main.ts @@ -1,4 +1,7 @@ import "./styles/base.css"; +import "./styles/pages.css"; +import "./styles/dashboard.css"; +import "./styles/migration.css"; import App from "./App.svelte"; import { mount } from "svelte"; diff --git a/frontend/src/styles/tokens.css b/frontend/src/styles/tokens.css index b8d3611..8b4bdc7 100644 --- a/frontend/src/styles/tokens.css +++ b/frontend/src/styles/tokens.css @@ -28,11 +28,6 @@ --leading-normal: 1.5; --leading-relaxed: 1.75; - --radius-sm: 3px; - --radius-md: 4px; - --radius-lg: 6px; - --radius-xl: 8px; - --width-xs: 360px; --width-sm: 480px; --width-md: 760px; @@ -42,11 +37,7 @@ --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05); --shadow-md: 0 2px 8px rgba(0, 0, 0, 0.1); --shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.15); - --shadow-focus: 0 0 0 2px var(--accent-muted); - - --transition-fast: 0.1s ease; - --transition-normal: 0.15s ease; - --transition-slow: 0.25s ease; + --shadow-focus: 0 0 0 2px var(--secondary-muted); --z-modal: 1000; --overlay-bg: rgba(0, 0, 0, 0.5); @@ -91,6 +82,12 @@ --warning-border: #d4a03c; --warning-text: #856404; + --danger-bg: #c00; + --danger-bg-hover: #a00; + + --info-bg: #e0f2fe; + --info-text: #0369a1; + --border-color-light: var(--border-dark); } @@ -133,5 +130,11 @@ --warning-bg: #1f1a0f; --warning-border: #3d351a; --warning-text: #c6b87b; + + --danger-bg: #ff8a8a; + --danger-bg-hover: #ff6b6b; + + --info-bg: #0c2d48; + --info-text: #7bc6f0; } } diff --git a/frontend/src/tests/oauth-registration.test.ts b/frontend/src/tests/oauth-registration.test.ts index 2876749..aca1e6c 100644 --- a/frontend/src/tests/oauth-registration.test.ts +++ b/frontend/src/tests/oauth-registration.test.ts @@ -149,10 +149,10 @@ describe("OAuth Registration Flow", () => { const Register = (await import("../routes/Register.svelte")) .default; - render(Register); + const { container } = render(Register); await waitFor(() => { - expect(screen.getByText(/loading/i)).toBeInTheDocument(); + expect(container.querySelector(".loading")).toBeInTheDocument(); }); });