mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 17:48:07 +00:00
fix: linting for login-quality
This commit is contained in:
2
.github/workflows/login-quality.yml
vendored
2
.github/workflows/login-quality.yml
vendored
@@ -52,7 +52,7 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
- name: Run login quality checks with Turbo
|
||||
run: pnpm turbo lint test:unit --filter=./login
|
||||
run: pnpm turbo test:unit --filter=@zitadel/login
|
||||
env:
|
||||
# latest if branch is main, otherwise image version which is the pull request number
|
||||
LOGIN_BAKE_CLI: depot bake
|
||||
|
@@ -7,8 +7,8 @@ module.exports = {
|
||||
"@next/next/no-img-element": "off",
|
||||
"react/no-unescaped-entities": "off",
|
||||
"no-unused-vars": "off",
|
||||
"@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }],
|
||||
"no-undef": "off"
|
||||
"@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_" }],
|
||||
"no-undef": "off",
|
||||
},
|
||||
parserOptions: {
|
||||
ecmaVersion: "latest",
|
||||
|
@@ -5,7 +5,7 @@
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"dev:turbo": "next dev --turbopack",
|
||||
"test:unit": "pnpm vitest",
|
||||
"test:unit": "pnpm vitest --run",
|
||||
"test:unit:standalone": "pnpm test:unit",
|
||||
"test:unit:watch": "pnpm test:unit --watch",
|
||||
"lint": "pnpm exec next lint && pnpm exec prettier --check .",
|
||||
|
@@ -4,8 +4,8 @@ export default {
|
||||
useTabs: false,
|
||||
semi: true,
|
||||
singleQuote: false,
|
||||
trailingComma: 'all',
|
||||
trailingComma: "all",
|
||||
bracketSpacing: true,
|
||||
arrowParens: 'always',
|
||||
plugins: ["prettier-plugin-organize-imports", "prettier-plugin-tailwindcss"]
|
||||
arrowParens: "always",
|
||||
plugins: ["prettier-plugin-organize-imports", "prettier-plugin-tailwindcss"],
|
||||
};
|
||||
|
@@ -5,41 +5,49 @@
|
||||
* This script converts the monorepo version to a standalone version
|
||||
*/
|
||||
|
||||
import fs from 'fs/promises';
|
||||
import { execSync } from 'child_process';
|
||||
import { execSync } from "child_process";
|
||||
import fs from "fs/promises";
|
||||
|
||||
const FILES_TO_REMOVE = [
|
||||
// Turbo is not needed for standalone builds since there are no workspace dependencies
|
||||
{ file: 'turbo.json', backup: 'turbo.monorepo.backup.json' }
|
||||
{ file: "turbo.json", backup: "turbo.monorepo.backup.json" },
|
||||
];
|
||||
|
||||
async function prepareStandalone() {
|
||||
console.log('🔧 Preparing standalone version...\n');
|
||||
console.log("🔧 Preparing standalone version...\n");
|
||||
|
||||
const args = process.argv.slice(2);
|
||||
const shouldInstall = args.includes('--install');
|
||||
const shouldInstall = args.includes("--install");
|
||||
|
||||
try {
|
||||
// Step 1: Copy package.standalone.json to package.json
|
||||
console.log('📦 Setting up package.json...');
|
||||
const packageStandaloneExists = await fs.access('package.standalone.json').then(() => true).catch(() => false);
|
||||
console.log("📦 Setting up package.json...");
|
||||
const packageStandaloneExists = await fs
|
||||
.access("package.standalone.json")
|
||||
.then(() => true)
|
||||
.catch(() => false);
|
||||
|
||||
if (packageStandaloneExists) {
|
||||
// Backup current package.json
|
||||
await fs.copyFile('package.json', 'package.monorepo.backup.json');
|
||||
console.log(' 💾 Backed up package.json → package.monorepo.backup.json');
|
||||
await fs.copyFile("package.json", "package.monorepo.backup.json");
|
||||
console.log(
|
||||
" 💾 Backed up package.json → package.monorepo.backup.json",
|
||||
);
|
||||
|
||||
// Copy standalone version
|
||||
await fs.copyFile('package.standalone.json', 'package.json');
|
||||
console.log(' ✅ package.standalone.json → package.json');
|
||||
await fs.copyFile("package.standalone.json", "package.json");
|
||||
console.log(" ✅ package.standalone.json → package.json");
|
||||
} else {
|
||||
throw new Error('package.standalone.json not found!');
|
||||
throw new Error("package.standalone.json not found!");
|
||||
}
|
||||
|
||||
// Step 2: Remove unnecessary files for standalone
|
||||
console.log('🗑️ Removing monorepo-specific files...');
|
||||
console.log("🗑️ Removing monorepo-specific files...");
|
||||
for (const item of FILES_TO_REMOVE) {
|
||||
const fileExists = await fs.access(item.file).then(() => true).catch(() => false);
|
||||
const fileExists = await fs
|
||||
.access(item.file)
|
||||
.then(() => true)
|
||||
.catch(() => false);
|
||||
|
||||
if (fileExists) {
|
||||
// Backup current file
|
||||
@@ -56,27 +64,28 @@ async function prepareStandalone() {
|
||||
|
||||
// Step 3: Install dependencies if requested
|
||||
if (shouldInstall) {
|
||||
console.log('\n📥 Installing dependencies...');
|
||||
console.log("\n📥 Installing dependencies...");
|
||||
try {
|
||||
execSync('pnpm install', { stdio: 'inherit' });
|
||||
console.log(' ✅ Dependencies installed successfully');
|
||||
execSync("pnpm install", { stdio: "inherit" });
|
||||
console.log(" ✅ Dependencies installed successfully");
|
||||
} catch (error) {
|
||||
console.warn(' ⚠️ pnpm install failed, you may need to run it manually');
|
||||
console.warn(
|
||||
" ⚠️ pnpm install failed, you may need to run it manually",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
console.log('\n🎉 Standalone preparation complete!');
|
||||
console.log(' ✨ Turbo removed - using standard npm scripts');
|
||||
console.log('\n📋 Next steps:');
|
||||
console.log("\n🎉 Standalone preparation complete!");
|
||||
console.log(" ✨ Turbo removed - using standard npm scripts");
|
||||
console.log("\n📋 Next steps:");
|
||||
if (!shouldInstall) {
|
||||
console.log(' 1. Run: pnpm install');
|
||||
console.log(" 1. Run: pnpm install");
|
||||
}
|
||||
console.log(' 2. Run: pnpm run dev');
|
||||
console.log(' 3. Start developing!\n');
|
||||
|
||||
console.log(" 2. Run: pnpm run dev");
|
||||
console.log(" 3. Start developing!\n");
|
||||
} catch (error) {
|
||||
console.error('\n❌ Failed to prepare standalone version:', error.message);
|
||||
console.error('Please check the error above and try again.\n');
|
||||
console.error("\n❌ Failed to prepare standalone version:", error.message);
|
||||
console.error("Please check the error above and try again.\n");
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
@@ -10,7 +10,7 @@ import {
|
||||
} from "@/lib/zitadel";
|
||||
import { UserPlusIcon } from "@heroicons/react/24/outline";
|
||||
import { Organization } from "@zitadel/proto/zitadel/org/v2/org_pb";
|
||||
import { getLocale } from "next-intl/server";
|
||||
// import { getLocale } from "next-intl/server";
|
||||
import { headers } from "next/headers";
|
||||
import Link from "next/link";
|
||||
|
||||
@@ -33,7 +33,7 @@ export default async function Page(props: {
|
||||
searchParams: Promise<Record<string | number | symbol, string | undefined>>;
|
||||
}) {
|
||||
const searchParams = await props.searchParams;
|
||||
const locale = getLocale();
|
||||
// const locale = getLocale();
|
||||
|
||||
const requestId = searchParams?.requestId;
|
||||
const organization = searchParams?.organization;
|
||||
@@ -78,11 +78,11 @@ export default async function Page(props: {
|
||||
<Translated i18nKey="description" namespace="accounts" />
|
||||
</p>
|
||||
|
||||
<div className="flex flex-col w-full space-y-2">
|
||||
<div className="flex w-full flex-col space-y-2">
|
||||
<SessionsList sessions={sessions} requestId={requestId} />
|
||||
<Link href={`/loginname?` + params}>
|
||||
<div className="flex flex-row items-center py-3 px-4 hover:bg-black/10 dark:hover:bg-white/10 rounded-md transition-all">
|
||||
<div className="w-8 h-8 mr-4 flex flex-row justify-center items-center rounded-full bg-black/5 dark:bg-white/5">
|
||||
<div className="flex flex-row items-center rounded-md px-4 py-3 transition-all hover:bg-black/10 dark:hover:bg-white/10">
|
||||
<div className="mr-4 flex h-8 w-8 flex-row items-center justify-center rounded-full bg-black/5 dark:bg-white/5">
|
||||
<UserPlusIcon className="h-5 w-5" />
|
||||
</div>
|
||||
<span className="text-sm">
|
||||
|
@@ -18,7 +18,7 @@ import {
|
||||
listAuthenticationMethodTypes,
|
||||
} from "@/lib/zitadel";
|
||||
import { Session } from "@zitadel/proto/zitadel/session/v2/session_pb";
|
||||
import { getLocale } from "next-intl/server";
|
||||
// import { getLocale } from "next-intl/server";
|
||||
import { headers } from "next/headers";
|
||||
import { redirect } from "next/navigation";
|
||||
|
||||
@@ -26,7 +26,7 @@ export default async function Page(props: {
|
||||
searchParams: Promise<Record<string | number | symbol, string | undefined>>;
|
||||
}) {
|
||||
const searchParams = await props.searchParams;
|
||||
const locale = getLocale();
|
||||
// const locale = getLocale();
|
||||
|
||||
const { loginName, requestId, organization, sessionId } = searchParams;
|
||||
|
||||
@@ -193,7 +193,7 @@ export default async function Page(props: {
|
||||
|
||||
{loginSettings?.allowExternalIdp && !!identityProviders.length && (
|
||||
<>
|
||||
<div className="py-3 flex flex-col">
|
||||
<div className="flex flex-col py-3">
|
||||
<p className="ztdl-p text-center">
|
||||
<Translated i18nKey="linkWithIDP" namespace="authenticator" />
|
||||
</p>
|
||||
|
@@ -27,13 +27,13 @@ export default async function RootLayout({
|
||||
<Suspense
|
||||
fallback={
|
||||
<div
|
||||
className={`relative min-h-screen bg-background-light-600 dark:bg-background-dark-600 flex flex-col justify-center`}
|
||||
className={`relative flex min-h-screen flex-col justify-center bg-background-light-600 dark:bg-background-dark-600`}
|
||||
>
|
||||
<div className="relative mx-auto max-w-[440px] py-8 w-full">
|
||||
<div className="relative mx-auto w-full max-w-[440px] py-8">
|
||||
<Skeleton>
|
||||
<div className="h-40"></div>
|
||||
</Skeleton>
|
||||
<div className="flex flex-row justify-end py-4 items-center space-x-4">
|
||||
<div className="flex flex-row items-center justify-end space-x-4 py-4">
|
||||
<Theme />
|
||||
</div>
|
||||
</div>
|
||||
@@ -42,11 +42,11 @@ export default async function RootLayout({
|
||||
>
|
||||
<LanguageProvider>
|
||||
<div
|
||||
className={`relative min-h-screen bg-background-light-600 dark:bg-background-dark-600 flex flex-col justify-center`}
|
||||
className={`relative flex min-h-screen flex-col justify-center bg-background-light-600 dark:bg-background-dark-600`}
|
||||
>
|
||||
<div className="relative mx-auto max-w-[440px] py-8 w-full ">
|
||||
<div className="relative mx-auto w-full max-w-[440px] py-8">
|
||||
{children}
|
||||
<div className="flex flex-row justify-end py-4 items-center space-x-4">
|
||||
<div className="flex flex-row items-center justify-end space-x-4 py-4">
|
||||
<LanguageSwitcher />
|
||||
<Theme />
|
||||
</div>
|
||||
|
@@ -79,7 +79,7 @@ export default async function Page(props: {
|
||||
></UsernameForm>
|
||||
|
||||
{identityProviders && loginSettings?.allowExternalIdp && (
|
||||
<div className="w-full pt-6 pb-4">
|
||||
<div className="w-full pb-4 pt-6">
|
||||
<SignInWithIdp
|
||||
identityProviders={identityProviders}
|
||||
requestId={requestId}
|
||||
|
@@ -72,7 +72,7 @@ export default async function Page(props: {
|
||||
<Translated i18nKey="description" namespace="logout" />
|
||||
</p>
|
||||
|
||||
<div className="flex flex-col w-full space-y-2">
|
||||
<div className="flex w-full flex-col space-y-2">
|
||||
<SessionsClearList
|
||||
sessions={sessions}
|
||||
logoutHint={logoutHint}
|
||||
|
@@ -54,7 +54,7 @@ export default async function Page(props: {
|
||||
<span>
|
||||
<Translated i18nKey="set.info.description" namespace="passkey" />
|
||||
<a
|
||||
className="text-primary-light-500 dark:text-primary-dark-500 hover:text-primary-light-300 hover:dark:text-primary-dark-300"
|
||||
className="text-primary-light-500 hover:text-primary-light-300 dark:text-primary-dark-500 hover:dark:text-primary-dark-300"
|
||||
target="_blank"
|
||||
href="https://zitadel.com/docs/guides/manage/user/reg-create-user#with-passwordless"
|
||||
>
|
||||
|
@@ -117,7 +117,7 @@ export default async function Page(props: {
|
||||
|
||||
{loginSettings?.allowExternalIdp && !!identityProviders.length && (
|
||||
<>
|
||||
<div className="py-3 flex flex-col items-center">
|
||||
<div className="flex flex-col items-center py-3">
|
||||
<p className="ztdl-p text-center">
|
||||
<Translated i18nKey="orUseIDP" namespace="register" />
|
||||
</p>
|
||||
|
@@ -136,7 +136,7 @@ export default async function Page(props: { searchParams: Promise<any> }) {
|
||||
)}
|
||||
|
||||
{id && send && (
|
||||
<div className="py-4 w-full">
|
||||
<div className="w-full py-4">
|
||||
<Alert type={AlertType.INFO}>
|
||||
<Translated i18nKey="verify.codeSent" namespace="verify" />
|
||||
</Alert>
|
||||
|
@@ -11,7 +11,7 @@ export function AddressBar({ domain }: Props) {
|
||||
const pathname = usePathname();
|
||||
|
||||
return (
|
||||
<div className="flex items-center space-x-2 p-3.5 lg:px-5 lg:py-3 overflow-hidden">
|
||||
<div className="flex items-center space-x-2 overflow-hidden p-3.5 lg:px-5 lg:py-3">
|
||||
<div className="text-gray-600">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@@ -27,7 +27,7 @@ export function AddressBar({ domain }: Props) {
|
||||
</svg>
|
||||
</div>
|
||||
<div className="flex space-x-1 text-sm font-medium">
|
||||
<div className="max-w-[150px] px-2 overflow-hidden text-gray-500 text-ellipsis">
|
||||
<div className="max-w-[150px] overflow-hidden text-ellipsis px-2 text-gray-500">
|
||||
<span className="whitespace-nowrap">{domain}</span>
|
||||
</div>
|
||||
{pathname ? (
|
||||
|
@@ -26,7 +26,7 @@ export function Alert({ children, type = AlertType.ALERT }: Props) {
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
"flex flex-row items-center justify-center border rounded-md py-2 pr-2 scroll-px-40",
|
||||
"flex scroll-px-40 flex-row items-center justify-center rounded-md border py-2 pr-2",
|
||||
{
|
||||
[yellow]: type === AlertType.ALERT,
|
||||
[neutral]: type === AlertType.INFO,
|
||||
@@ -34,12 +34,12 @@ export function Alert({ children, type = AlertType.ALERT }: Props) {
|
||||
)}
|
||||
>
|
||||
{type === AlertType.ALERT && (
|
||||
<ExclamationTriangleIcon className="flex-shrink-0 h-5 w-5 mr-2 ml-2" />
|
||||
<ExclamationTriangleIcon className="ml-2 mr-2 h-5 w-5 flex-shrink-0" />
|
||||
)}
|
||||
{type === AlertType.INFO && (
|
||||
<InformationCircleIcon className="flex-shrink-0 h-5 w-5 mr-2 ml-2" />
|
||||
<InformationCircleIcon className="ml-2 mr-2 h-5 w-5 flex-shrink-0" />
|
||||
)}
|
||||
<span className="text-sm w-full ">{children}</span>
|
||||
<span className="w-full text-sm">{children}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@@ -27,7 +27,7 @@ export function AppAvatar({ appName, imageUrl, shadow }: AvatarProps) {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`w-[100px] h-[100px] flex justify-center items-center cursor-default pointer-events-none group-focus:outline-none group-focus:ring-2 transition-colors duration-200 dark:group-focus:ring-offset-blue bg-primary-light-500 text-primary-light-contrast-500 hover:bg-primary-light-400 hover:dark:bg-primary-dark-500 group-focus:ring-primary-light-200 dark:group-focus:ring-primary-dark-400 dark:bg-primary-dark-300 dark:text-primary-dark-contrast-300 dark:text-blue rounded-full ${
|
||||
className={`dark:group-focus:ring-offset-blue dark:text-blue pointer-events-none flex h-[100px] w-[100px] cursor-default items-center justify-center rounded-full bg-primary-light-500 text-primary-light-contrast-500 transition-colors duration-200 hover:bg-primary-light-400 group-focus:outline-none group-focus:ring-2 group-focus:ring-primary-light-200 dark:bg-primary-dark-300 dark:text-primary-dark-contrast-300 hover:dark:bg-primary-dark-500 dark:group-focus:ring-primary-dark-400 ${
|
||||
shadow ? "shadow" : ""
|
||||
}`}
|
||||
style={resolvedTheme === "light" ? avatarStyleLight : avatarStyleDark}
|
||||
@@ -37,11 +37,11 @@ export function AppAvatar({ appName, imageUrl, shadow }: AvatarProps) {
|
||||
height={48}
|
||||
width={48}
|
||||
alt="avatar"
|
||||
className="w-full h-full border border-divider-light dark:border-divider-dark rounded-full"
|
||||
className="h-full w-full rounded-full border border-divider-light dark:border-divider-dark"
|
||||
src={imageUrl}
|
||||
/>
|
||||
) : (
|
||||
<span className={`uppercase text-3xl`}>{credentials}</span>
|
||||
<span className={`text-3xl uppercase`}>{credentials}</span>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
@@ -35,12 +35,12 @@ export const TOTP = (alreadyAdded: boolean, link: string) => {
|
||||
<LinkWrapper key={link} alreadyAdded={alreadyAdded} link={link}>
|
||||
<div
|
||||
className={clsx(
|
||||
"font-medium flex items-center",
|
||||
"flex items-center font-medium",
|
||||
alreadyAdded ? "opacity-50" : "",
|
||||
)}
|
||||
>
|
||||
<svg
|
||||
className="h-8 w-8 transform -translate-x-[2px] mr-4 fill-current text-black dark:text-white"
|
||||
className="mr-4 h-8 w-8 -translate-x-[2px] transform fill-current text-black dark:text-white"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
@@ -63,7 +63,7 @@ export const U2F = (alreadyAdded: boolean, link: string) => {
|
||||
<LinkWrapper key={link} alreadyAdded={alreadyAdded} link={link}>
|
||||
<div
|
||||
className={clsx(
|
||||
"font-medium flex items-center",
|
||||
"flex items-center font-medium",
|
||||
alreadyAdded ? "" : "",
|
||||
)}
|
||||
>
|
||||
@@ -73,7 +73,7 @@ export const U2F = (alreadyAdded: boolean, link: string) => {
|
||||
viewBox="0 0 24 24"
|
||||
strokeWidth="1.5"
|
||||
stroke="currentColor"
|
||||
className="w-8 h-8 mr-4"
|
||||
className="mr-4 h-8 w-8"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
@@ -97,12 +97,12 @@ export const EMAIL = (alreadyAdded: boolean, link: string) => {
|
||||
<LinkWrapper key={link} alreadyAdded={alreadyAdded} link={link}>
|
||||
<div
|
||||
className={clsx(
|
||||
"font-medium flex items-center",
|
||||
"flex items-center font-medium",
|
||||
alreadyAdded ? "" : "",
|
||||
)}
|
||||
>
|
||||
<svg
|
||||
className="w-8 h-8 mr-4"
|
||||
className="mr-4 h-8 w-8"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
@@ -132,12 +132,12 @@ export const SMS = (alreadyAdded: boolean, link: string) => {
|
||||
<LinkWrapper key={link} alreadyAdded={alreadyAdded} link={link}>
|
||||
<div
|
||||
className={clsx(
|
||||
"font-medium flex items-center",
|
||||
"flex items-center font-medium",
|
||||
alreadyAdded ? "" : "",
|
||||
)}
|
||||
>
|
||||
<svg
|
||||
className="w-8 h-8 mr-4"
|
||||
className="mr-4 h-8 w-8"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
@@ -166,7 +166,7 @@ export const PASSKEYS = (alreadyAdded: boolean, link: string) => {
|
||||
<LinkWrapper key={link} alreadyAdded={alreadyAdded} link={link}>
|
||||
<div
|
||||
className={clsx(
|
||||
"font-medium flex items-center",
|
||||
"flex items-center font-medium",
|
||||
alreadyAdded ? "" : "",
|
||||
)}
|
||||
>
|
||||
@@ -176,7 +176,7 @@ export const PASSKEYS = (alreadyAdded: boolean, link: string) => {
|
||||
viewBox="0 0 24 24"
|
||||
strokeWidth="1.5"
|
||||
stroke="currentColor"
|
||||
className="w-8 h-8 mr-4"
|
||||
className="mr-4 h-8 w-8"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
@@ -200,12 +200,12 @@ export const PASSWORD = (alreadyAdded: boolean, link: string) => {
|
||||
<LinkWrapper key={link} alreadyAdded={alreadyAdded} link={link}>
|
||||
<div
|
||||
className={clsx(
|
||||
"font-medium flex items-center",
|
||||
"flex items-center font-medium",
|
||||
alreadyAdded ? "" : "",
|
||||
)}
|
||||
>
|
||||
<svg
|
||||
className="w-8 h-7 mr-4 fill-current"
|
||||
className="mr-4 h-7 w-8 fill-current"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
@@ -225,9 +225,9 @@ export const PASSWORD = (alreadyAdded: boolean, link: string) => {
|
||||
|
||||
function Setup() {
|
||||
return (
|
||||
<div className="transform absolute right-2 top-0">
|
||||
<div className="absolute right-2 top-0 transform">
|
||||
<StateBadge evenPadding={true} state={BadgeState.Success}>
|
||||
<CheckIcon className="w-4 h-4" />
|
||||
<CheckIcon className="h-4 w-4" />
|
||||
</StateBadge>
|
||||
</div>
|
||||
);
|
||||
|
@@ -34,20 +34,18 @@ export function AuthenticationMethodRadio({
|
||||
className={({ active, checked }) =>
|
||||
`${
|
||||
active
|
||||
? "ring-2 ring-opacity-60 ring-primary-light-500 dark:ring-white/20"
|
||||
? "ring-2 ring-primary-light-500 ring-opacity-60 dark:ring-white/20"
|
||||
: ""
|
||||
}
|
||||
${
|
||||
} ${
|
||||
checked
|
||||
? "bg-background-light-400 dark:bg-background-dark-400 ring-2 ring-primary-light-500 dark:ring-primary-dark-500"
|
||||
? "bg-background-light-400 ring-2 ring-primary-light-500 dark:bg-background-dark-400 dark:ring-primary-dark-500"
|
||||
: "bg-background-light-400 dark:bg-background-dark-400"
|
||||
}
|
||||
h-full flex-1 relative border boder-divider-light dark:border-divider-dark flex cursor-pointer rounded-lg px-5 py-4 focus:outline-none hover:shadow-lg dark:hover:bg-white/10`
|
||||
} boder-divider-light relative flex h-full flex-1 cursor-pointer rounded-lg border px-5 py-4 hover:shadow-lg focus:outline-none dark:border-divider-dark dark:hover:bg-white/10`
|
||||
}
|
||||
>
|
||||
{({ active, checked }) => (
|
||||
<>
|
||||
<div className="flex flex-col items-center w-full text-sm">
|
||||
<div className="flex w-full flex-col items-center text-sm">
|
||||
{method === "passkey" && (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@@ -55,7 +53,7 @@ export function AuthenticationMethodRadio({
|
||||
viewBox="0 0 24 24"
|
||||
strokeWidth="1.5"
|
||||
stroke="currentColor"
|
||||
className="w-8 h-8 mb-3"
|
||||
className="mb-3 h-8 w-8"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
@@ -66,7 +64,7 @@ export function AuthenticationMethodRadio({
|
||||
)}
|
||||
{method === "password" && (
|
||||
<svg
|
||||
className="w-8 h-8 mb-3 fill-current"
|
||||
className="mb-3 h-8 w-8 fill-current"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
|
@@ -64,16 +64,16 @@ export function Avatar({
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`w-full h-full flex-shrink-0 flex justify-center items-center cursor-default pointer-events-none group-focus:outline-none group-focus:ring-2 transition-colors duration-200 dark:group-focus:ring-offset-blue bg-primary-light-500 text-primary-light-contrast-500 hover:bg-primary-light-400 hover:dark:bg-primary-dark-500 group-focus:ring-primary-light-200 dark:group-focus:ring-primary-dark-400 dark:bg-primary-dark-300 dark:text-primary-dark-contrast-300 dark:text-blue rounded-full ${
|
||||
className={`dark:group-focus:ring-offset-blue dark:text-blue pointer-events-none flex h-full w-full flex-shrink-0 cursor-default items-center justify-center rounded-full bg-primary-light-500 text-primary-light-contrast-500 transition-colors duration-200 hover:bg-primary-light-400 group-focus:outline-none group-focus:ring-2 group-focus:ring-primary-light-200 dark:bg-primary-dark-300 dark:text-primary-dark-contrast-300 hover:dark:bg-primary-dark-500 dark:group-focus:ring-primary-dark-400 ${
|
||||
shadow ? "shadow" : ""
|
||||
} ${
|
||||
size === "large"
|
||||
? "h-20 w-20 font-normal"
|
||||
: size === "base"
|
||||
? "w-[38px] h-[38px] font-bold"
|
||||
? "h-[38px] w-[38px] font-bold"
|
||||
: size === "small"
|
||||
? "!w-[32px] !h-[32px] font-bold text-[13px]"
|
||||
: "w-12 h-12"
|
||||
? "!h-[32px] !w-[32px] text-[13px] font-bold"
|
||||
: "h-12 w-12"
|
||||
}`}
|
||||
style={resolvedTheme === "light" ? avatarStyleLight : avatarStyleDark}
|
||||
>
|
||||
@@ -82,7 +82,7 @@ export function Avatar({
|
||||
height={48}
|
||||
width={48}
|
||||
alt="avatar"
|
||||
className="w-full h-full border border-divider-light dark:border-divider-dark rounded-full"
|
||||
className="h-full w-full rounded-full border border-divider-light dark:border-divider-dark"
|
||||
src={imageUrl}
|
||||
/>
|
||||
) : (
|
||||
|
@@ -33,8 +33,7 @@ export const getButtonClasses = (
|
||||
color: ButtonColors,
|
||||
) =>
|
||||
clsx({
|
||||
"box-border font-normal leading-36px text-14px inline-flex items-center rounded-md focus:outline-none transition-colors transition-shadow duration-300":
|
||||
true,
|
||||
"box-border font-normal leading-36px text-14px inline-flex items-center rounded-md focus:outline-none transition-colors transition-shadow duration-300": true,
|
||||
"shadow hover:shadow-xl active:shadow-xl disabled:border-none disabled:bg-gray-300 disabled:text-gray-600 disabled:shadow-none disabled:cursor-not-allowed disabled:dark:bg-gray-800 disabled:dark:text-gray-900":
|
||||
variant === ButtonVariants.Primary,
|
||||
"bg-primary-light-500 dark:bg-primary-dark-500 hover:bg-primary-light-400 hover:dark:bg-primary-dark-400 text-primary-light-contrast-500 dark:text-primary-dark-contrast-500":
|
||||
|
@@ -149,7 +149,7 @@ export function ChangePasswordForm({
|
||||
|
||||
return (
|
||||
<form className="w-full">
|
||||
<div className="pt-4 grid grid-cols-1 gap-4 mb-4">
|
||||
<div className="mb-4 grid grid-cols-1 gap-4 pt-4">
|
||||
<div className="">
|
||||
<TextInput
|
||||
type="password"
|
||||
@@ -202,7 +202,7 @@ export function ChangePasswordForm({
|
||||
onClick={handleSubmit(submitChange)}
|
||||
data-testid="submit-button"
|
||||
>
|
||||
{loading && <Spinner className="h-5 w-5 mr-2" />}{" "}
|
||||
{loading && <Spinner className="mr-2 h-5 w-5" />}{" "}
|
||||
<Translated i18nKey="change.submit" namespace="password" />
|
||||
</Button>
|
||||
</div>
|
||||
|
@@ -36,7 +36,7 @@ export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
|
||||
|
||||
return (
|
||||
<div className="relative flex items-start">
|
||||
<div className="flex items-center h-5">
|
||||
<div className="flex h-5 items-center">
|
||||
<div className="box-sizing block">
|
||||
<input
|
||||
ref={ref}
|
||||
@@ -48,7 +48,7 @@ export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
|
||||
disabled={disabled}
|
||||
type="checkbox"
|
||||
className={classNames(
|
||||
"form-checkbox rounded border-gray-300 text-primary-light-500 dark:text-primary-dark-500 shadow-sm focus:border-indigo-300 focus:ring focus:ring-offset-0 focus:ring-indigo-200 focus:ring-opacity-50",
|
||||
"form-checkbox rounded border-gray-300 text-primary-light-500 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50 focus:ring-offset-0 dark:text-primary-dark-500",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
@@ -25,7 +25,7 @@ export function ChooseAuthenticatorToLogin({
|
||||
<Translated i18nKey="chooseAlternativeMethod" namespace="idp" />
|
||||
</div>
|
||||
)}
|
||||
<div className="grid grid-cols-1 gap-5 w-full pt-4">
|
||||
<div className="grid w-full grid-cols-1 gap-5 pt-4">
|
||||
{authMethods.includes(AuthenticationMethodType.PASSWORD) &&
|
||||
loginSettings?.allowUsernamePassword &&
|
||||
PASSWORD(false, "/password?" + params)}
|
||||
|
@@ -37,7 +37,7 @@ export function ChooseAuthenticatorToSetup({
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
<div className="grid grid-cols-1 gap-5 w-full pt-4">
|
||||
<div className="grid w-full grid-cols-1 gap-5 pt-4">
|
||||
{!authMethods.includes(AuthenticationMethodType.PASSWORD) &&
|
||||
loginSettings.allowUsernamePassword &&
|
||||
PASSWORD(false, "/password/set?" + params)}
|
||||
|
@@ -58,7 +58,7 @@ export function ChooseSecondFactorToSetup({
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="grid grid-cols-1 gap-5 w-full pt-4">
|
||||
<div className="grid w-full grid-cols-1 gap-5 pt-4">
|
||||
{loginSettings.secondFactors.map((factor) => {
|
||||
switch (factor) {
|
||||
case SecondFactorType.OTP:
|
||||
@@ -94,7 +94,7 @@ export function ChooseSecondFactorToSetup({
|
||||
</div>
|
||||
{!force && (
|
||||
<button
|
||||
className="transition-all text-sm hover:text-primary-light-500 dark:hover:text-primary-dark-500"
|
||||
className="text-sm transition-all hover:text-primary-light-500 dark:hover:text-primary-dark-500"
|
||||
onClick={async () => {
|
||||
const resp = await skipMFAAndContinueWithNextUrl({
|
||||
userId,
|
||||
|
@@ -34,7 +34,7 @@ export function ChooseSecondFactor({
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="grid grid-cols-1 gap-5 w-full pt-4">
|
||||
<div className="grid w-full grid-cols-1 gap-5 pt-4">
|
||||
{userMethods.map((method, i) => {
|
||||
return (
|
||||
<div key={"method-" + i}>
|
||||
|
@@ -47,10 +47,10 @@ export function ConsentScreen({
|
||||
const scopes = scope?.filter((s) => !!s);
|
||||
|
||||
return (
|
||||
<div className="pt-4 w-full flex flex-col items-center space-y-4">
|
||||
<ul className="list-disc space-y-2 w-full">
|
||||
<div className="flex w-full flex-col items-center space-y-4 pt-4">
|
||||
<ul className="w-full list-disc space-y-2">
|
||||
{scopes?.length === 0 && (
|
||||
<span className="w-full text-sm flex flex-row items-center bg-background-light-400 dark:bg-background-dark-400 border border-divider-light py-2 px-4 rounded-md transition-all">
|
||||
<span className="flex w-full flex-row items-center rounded-md border border-divider-light bg-background-light-400 px-4 py-2 text-sm transition-all dark:bg-background-dark-400">
|
||||
<Translated i18nKey="device.scope.openid" namespace="device" />
|
||||
</span>
|
||||
)}
|
||||
@@ -65,7 +65,7 @@ export function ConsentScreen({
|
||||
return (
|
||||
<li
|
||||
key={s}
|
||||
className="w-full text-sm flex flex-row items-center bg-background-light-400 dark:bg-background-dark-400 border border-divider-light py-2 px-4 rounded-md transition-all"
|
||||
className="flex w-full flex-row items-center rounded-md border border-divider-light bg-background-light-400 px-4 py-2 text-sm transition-all dark:bg-background-dark-400"
|
||||
>
|
||||
<span>{resolvedDescription}</span>
|
||||
</li>
|
||||
@@ -73,7 +73,7 @@ export function ConsentScreen({
|
||||
})}
|
||||
</ul>
|
||||
|
||||
<p className="ztdl-p text-xs text-left">
|
||||
<p className="ztdl-p text-left text-xs">
|
||||
<Translated
|
||||
i18nKey="request.disclaimer"
|
||||
namespace="device"
|
||||
@@ -95,7 +95,7 @@ export function ConsentScreen({
|
||||
variant={ButtonVariants.Secondary}
|
||||
data-testid="deny-button"
|
||||
>
|
||||
{loading && <Spinner className="h-5 w-5 mr-2" />}
|
||||
{loading && <Spinner className="mr-2 h-5 w-5" />}
|
||||
<Translated i18nKey="device.request.deny" namespace="device" />
|
||||
</Button>
|
||||
<span className="flex-grow"></span>
|
||||
|
@@ -27,7 +27,7 @@ export function CopyToClipboard({ value }: Props) {
|
||||
<button
|
||||
id="tooltip-ctc"
|
||||
type="button"
|
||||
className=" text-primary-light-500 dark:text-primary-dark-500"
|
||||
className="text-primary-light-500 dark:text-primary-dark-500"
|
||||
onClick={() => setCopied(true)}
|
||||
>
|
||||
{!copied ? (
|
||||
|
@@ -85,7 +85,7 @@ export function DeviceCodeForm({ userCode }: { userCode?: string }) {
|
||||
onClick={handleSubmit(submitCodeAndContinue)}
|
||||
data-testid="submit-button"
|
||||
>
|
||||
{loading && <Spinner className="h-5 w-5 mr-2" />}{" "}
|
||||
{loading && <Spinner className="mr-2 h-5 w-5" />}{" "}
|
||||
<Translated i18nKey="verify.submit" namespace="verify" />
|
||||
</Button>
|
||||
</div>
|
||||
|
@@ -17,7 +17,7 @@ export function DynamicTheme({
|
||||
}) {
|
||||
return (
|
||||
<ThemeWrapper branding={branding}>
|
||||
<div className="rounded-lg bg-background-light-400 dark:bg-background-dark-500 px-8 py-12">
|
||||
<div className="rounded-lg bg-background-light-400 px-8 py-12 dark:bg-background-dark-500">
|
||||
<div className="mx-auto flex flex-col items-center space-y-4">
|
||||
<div className="relative flex flex-row items-center justify-center gap-8">
|
||||
{branding && (
|
||||
|
@@ -26,15 +26,15 @@ export const BaseButton = forwardRef<
|
||||
ref={ref}
|
||||
disabled={formStatus.pending}
|
||||
className={clsx(
|
||||
"flex-1 transition-all cursor-pointer flex flex-row items-center bg-background-light-400 text-text-light-500 dark:bg-background-dark-500 dark:text-text-dark-500 border border-divider-light hover:border-black dark:border-divider-dark hover:dark:border-white focus:border-primary-light-500 focus:dark:border-primary-dark-500 outline-none rounded-md px-4 text-sm",
|
||||
"flex flex-1 cursor-pointer flex-row items-center rounded-md border border-divider-light bg-background-light-400 px-4 text-sm text-text-light-500 outline-none transition-all hover:border-black focus:border-primary-light-500 dark:border-divider-dark dark:bg-background-dark-500 dark:text-text-dark-500 hover:dark:border-white focus:dark:border-primary-dark-500",
|
||||
props.className,
|
||||
)}
|
||||
>
|
||||
<div className="flex-1 justify-between flex items-center gap-4">
|
||||
<div className="flex-1 flex flex-row items-center">
|
||||
<div className="flex flex-1 items-center justify-between gap-4">
|
||||
<div className="flex flex-1 flex-row items-center">
|
||||
{props.children}
|
||||
</div>
|
||||
{formStatus.pending && <Loader2Icon className="w-4 h-4 animate-spin" />}
|
||||
{formStatus.pending && <Loader2Icon className="h-4 w-4 animate-spin" />}
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
|
@@ -12,7 +12,7 @@ export const SignInWithApple = forwardRef<
|
||||
|
||||
return (
|
||||
<BaseButton {...restProps} ref={ref}>
|
||||
<div className="h-12 w-12 flex items-center justify-center">
|
||||
<div className="flex h-12 w-12 items-center justify-center">
|
||||
<div className="h-6 w-6">
|
||||
<svg viewBox="0 0 170 170" fill="currentColor">
|
||||
<title>Apple Logo</title>
|
||||
|
@@ -12,13 +12,13 @@ export const SignInWithAzureAd = forwardRef<
|
||||
|
||||
return (
|
||||
<BaseButton {...restProps} ref={ref}>
|
||||
<div className="h-12 p-[10px] w-12 flex items-center justify-center">
|
||||
<div className="flex h-12 w-12 items-center justify-center p-[10px]">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="21"
|
||||
height="21"
|
||||
viewBox="0 0 21 21"
|
||||
className="w-full h-full"
|
||||
className="h-full w-full"
|
||||
>
|
||||
<path fill="#f25022" d="M1 1H10V10H1z"></path>
|
||||
<path fill="#00a4ef" d="M1 11H10V20H1z"></path>
|
||||
|
@@ -11,7 +11,7 @@ function GitHubLogo() {
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 1024 1024"
|
||||
className="h-8 w-8 hidden dark:block"
|
||||
className="hidden h-8 w-8 dark:block"
|
||||
>
|
||||
<path
|
||||
fill="#fafafa"
|
||||
@@ -24,7 +24,7 @@ function GitHubLogo() {
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 1024 1024"
|
||||
className="h-8 w-8 block dark:hidden"
|
||||
className="block h-8 w-8 dark:hidden"
|
||||
>
|
||||
<path
|
||||
fill="#1B1F23"
|
||||
|
@@ -12,7 +12,7 @@ export const SignInWithGitlab = forwardRef<
|
||||
|
||||
return (
|
||||
<BaseButton {...restProps} ref={ref}>
|
||||
<div className="h-12 w-12 flex items-center justify-center">
|
||||
<div className="flex h-12 w-12 items-center justify-center">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={25}
|
||||
|
@@ -12,7 +12,7 @@ export const SignInWithGoogle = forwardRef<
|
||||
|
||||
return (
|
||||
<BaseButton {...restProps} ref={ref}>
|
||||
<div className="h-12 w-12 flex items-center justify-center">
|
||||
<div className="flex h-12 w-12 items-center justify-center">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlSpace="preserve"
|
||||
|
@@ -27,12 +27,9 @@ export type TextInputProps = DetailedHTMLProps<
|
||||
|
||||
const styles = (error: boolean, disabled: boolean) =>
|
||||
clsx({
|
||||
"h-[40px] mb-[2px] rounded p-[7px] bg-input-light-background dark:bg-input-dark-background transition-colors duration-300 grow":
|
||||
true,
|
||||
"border border-input-light-border dark:border-input-dark-border hover:border-black hover:dark:border-white focus:border-primary-light-500 focus:dark:border-primary-dark-500":
|
||||
true,
|
||||
"focus:outline-none focus:ring-0 text-base text-black dark:text-white placeholder:italic placeholder-gray-700 dark:placeholder-gray-700":
|
||||
true,
|
||||
"h-[40px] mb-[2px] rounded p-[7px] bg-input-light-background dark:bg-input-dark-background transition-colors duration-300 grow": true,
|
||||
"border border-input-light-border dark:border-input-dark-border hover:border-black hover:dark:border-white focus:border-primary-light-500 focus:dark:border-primary-dark-500": true,
|
||||
"focus:outline-none focus:ring-0 text-base text-black dark:text-white placeholder:italic placeholder-gray-700 dark:placeholder-gray-700": true,
|
||||
"border border-warn-light-500 dark:border-warn-dark-500 hover:border-warn-light-500 hover:dark:border-warn-dark-500 focus:border-warn-light-500 focus:dark:border-warn-dark-500":
|
||||
error,
|
||||
"pointer-events-none text-gray-500 dark:text-gray-800 border border-input-light-border dark:border-input-dark-border hover:border-light-hoverborder hover:dark:border-hoverborder cursor-default":
|
||||
@@ -60,7 +57,7 @@ export const TextInput = forwardRef<HTMLInputElement, TextInputProps>(
|
||||
return (
|
||||
<label className="relative flex flex-col text-12px text-input-light-label dark:text-input-dark-label">
|
||||
<span
|
||||
className={`leading-3 mb-1 ${
|
||||
className={`mb-1 leading-3 ${
|
||||
error ? "text-warn-light-500 dark:text-warn-dark-500" : ""
|
||||
}`}
|
||||
>
|
||||
@@ -81,12 +78,12 @@ export const TextInput = forwardRef<HTMLInputElement, TextInputProps>(
|
||||
/>
|
||||
|
||||
{suffix && (
|
||||
<span className="z-30 absolute right-[3px] bottom-[22px] transform translate-y-1/2 bg-background-light-500 dark:bg-background-dark-500 p-2 rounded-sm">
|
||||
<span className="absolute bottom-[22px] right-[3px] z-30 translate-y-1/2 transform rounded-sm bg-background-light-500 p-2 dark:bg-background-dark-500">
|
||||
@{suffix}
|
||||
</span>
|
||||
)}
|
||||
|
||||
<div className="leading-14.5px h-14.5px text-warn-light-500 dark:text-warn-dark-500 flex flex-row items-center text-12px">
|
||||
<div className="leading-14.5px h-14.5px flex flex-row items-center text-12px text-warn-light-500 dark:text-warn-dark-500">
|
||||
<span>{error ? error : " "}</span>
|
||||
</div>
|
||||
|
||||
|
@@ -37,13 +37,13 @@ export function LanguageSwitcher() {
|
||||
<Listbox value={selected} onChange={handleChange}>
|
||||
<ListboxButton
|
||||
className={clsx(
|
||||
"relative block w-full rounded-lg bg-black/5 dark:bg-white/5 py-1.5 pr-8 pl-3 text-left text-sm/6 text-black dark:text-white",
|
||||
"relative block w-full rounded-lg bg-black/5 py-1.5 pl-3 pr-8 text-left text-sm/6 text-black dark:bg-white/5 dark:text-white",
|
||||
"focus:outline-none data-[focus]:outline-2 data-[focus]:-outline-offset-2 data-[focus]:outline-white/25",
|
||||
)}
|
||||
>
|
||||
{selected.name}
|
||||
<ChevronDownIcon
|
||||
className="group pointer-events-none absolute top-2.5 right-2.5 size-4"
|
||||
className="group pointer-events-none absolute right-2.5 top-2.5 size-4"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</ListboxButton>
|
||||
@@ -51,7 +51,7 @@ export function LanguageSwitcher() {
|
||||
anchor="bottom"
|
||||
transition
|
||||
className={clsx(
|
||||
"w-[var(--button-width)] rounded-xl border border-black/5 dark:border-white/5 bg-background-light-500 dark:bg-background-dark-500 p-1 [--anchor-gap:var(--spacing-1)] focus:outline-none",
|
||||
"w-[var(--button-width)] rounded-xl border border-black/5 bg-background-light-500 p-1 [--anchor-gap:var(--spacing-1)] focus:outline-none dark:border-white/5 dark:bg-background-dark-500",
|
||||
"transition duration-100 ease-in data-[leave]:data-[closed]:opacity-0",
|
||||
)}
|
||||
>
|
||||
@@ -59,7 +59,7 @@ export function LanguageSwitcher() {
|
||||
<ListboxOption
|
||||
key={lang.code}
|
||||
value={lang}
|
||||
className="group flex cursor-default items-center gap-2 rounded-lg py-1.5 px-3 select-none data-[focus]:bg-black/10 dark:data-[focus]:bg-white/10"
|
||||
className="group flex cursor-default select-none items-center gap-2 rounded-lg px-3 py-1.5 data-[focus]:bg-black/10 dark:data-[focus]:bg-white/10"
|
||||
>
|
||||
<CheckIcon className="invisible size-4 group-data-[selected]:visible" />
|
||||
<div className="text-sm/6 text-black dark:text-white">
|
||||
|
@@ -100,7 +100,7 @@ export function LDAPUsernamePasswordForm({ idpId, link }: Props) {
|
||||
onClick={handleSubmit(submitUsernamePassword)}
|
||||
data-testid="submit-button"
|
||||
>
|
||||
{loading && <Spinner className="h-5 w-5 mr-2" />}
|
||||
{loading && <Spinner className="mr-2 h-5 w-5" />}
|
||||
<Translated i18nKey="submit" namespace="ldap" />
|
||||
</Button>
|
||||
</div>
|
||||
|
@@ -220,14 +220,14 @@ export function LoginOTP({
|
||||
{["email", "sms"].includes(method) && (
|
||||
<Alert type={AlertType.INFO}>
|
||||
<div className="flex flex-row">
|
||||
<span className="flex-1 mr-auto text-left">
|
||||
<span className="mr-auto flex-1 text-left">
|
||||
<Translated i18nKey="verify.noCodeReceived" namespace="otp" />
|
||||
</span>
|
||||
<button
|
||||
aria-label="Resend OTP Code"
|
||||
disabled={loading}
|
||||
type="button"
|
||||
className="ml-4 text-primary-light-500 dark:text-primary-dark-500 hover:dark:text-primary-dark-400 hover:text-primary-light-400 cursor-pointer disabled:cursor-default disabled:text-gray-400 dark:disabled:text-gray-700"
|
||||
className="ml-4 cursor-pointer text-primary-light-500 hover:text-primary-light-400 disabled:cursor-default disabled:text-gray-400 dark:text-primary-dark-500 hover:dark:text-primary-dark-400 dark:disabled:text-gray-700"
|
||||
onClick={() => {
|
||||
setLoading(true);
|
||||
updateSessionForOTPChallenge()
|
||||
@@ -275,7 +275,7 @@ export function LoginOTP({
|
||||
})}
|
||||
data-testid="submit-button"
|
||||
>
|
||||
{loading && <Spinner className="h-5 w-5 mr-2" />}{" "}
|
||||
{loading && <Spinner className="mr-2 h-5 w-5" />}{" "}
|
||||
<Translated i18nKey="verify.submit" namespace="otp" />
|
||||
</Button>
|
||||
</div>
|
||||
|
@@ -271,7 +271,7 @@ export function LoginPasskey({
|
||||
}}
|
||||
data-testid="submit-button"
|
||||
>
|
||||
{loading && <Spinner className="h-5 w-5 mr-2" />}{" "}
|
||||
{loading && <Spinner className="mr-2 h-5 w-5" />}{" "}
|
||||
<Translated i18nKey="verify.submit" namespace="passkey" />
|
||||
</Button>
|
||||
</div>
|
||||
|
@@ -19,7 +19,7 @@ const check = (
|
||||
viewBox="0 0 24 24"
|
||||
strokeWidth={1.5}
|
||||
stroke="currentColor"
|
||||
className="w-6 h-6 las la-check text-green-500 dark:text-green-500 mr-2 text-lg"
|
||||
className="las la-check mr-2 h-6 w-6 text-lg text-green-500 dark:text-green-500"
|
||||
role="img"
|
||||
>
|
||||
<title>Matches</title>
|
||||
@@ -32,7 +32,7 @@ const check = (
|
||||
);
|
||||
const cross = (
|
||||
<svg
|
||||
className="w-6 h-6 las la-times text-warn-light-500 dark:text-warn-dark-500 mr-2 text-lg"
|
||||
className="las la-times mr-2 h-6 w-6 text-lg text-warn-light-500 dark:text-warn-dark-500"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
|
@@ -124,7 +124,7 @@ export function PasswordForm({
|
||||
/>
|
||||
{!loginSettings?.hidePasswordReset && (
|
||||
<button
|
||||
className="transition-all text-sm hover:text-primary-light-500 dark:hover:text-primary-dark-500"
|
||||
className="text-sm transition-all hover:text-primary-light-500 dark:hover:text-primary-dark-500"
|
||||
onClick={() => resetPasswordAndContinue()}
|
||||
type="button"
|
||||
disabled={loading}
|
||||
@@ -167,7 +167,7 @@ export function PasswordForm({
|
||||
onClick={handleSubmit(submitPassword)}
|
||||
data-testid="submit-button"
|
||||
>
|
||||
{loading && <Spinner className="h-5 w-5 mr-2" />}{" "}
|
||||
{loading && <Spinner className="mr-2 h-5 w-5" />}{" "}
|
||||
<Translated i18nKey="verify.submit" namespace="password" />
|
||||
</Button>
|
||||
</div>
|
||||
|
@@ -23,7 +23,7 @@ export function PrivacyPolicyCheckboxes({ legal, onChange }: Props) {
|
||||
|
||||
return (
|
||||
<>
|
||||
<p className="flex flex-row items-center text-text-light-secondary-500 dark:text-text-dark-secondary-500 mt-4 text-sm">
|
||||
<p className="mt-4 flex flex-row items-center text-sm text-text-light-secondary-500 dark:text-text-dark-secondary-500">
|
||||
<Translated i18nKey="agreeTo" namespace="register" />
|
||||
{legal?.helpLink && (
|
||||
<span>
|
||||
@@ -34,7 +34,7 @@ export function PrivacyPolicyCheckboxes({ legal, onChange }: Props) {
|
||||
viewBox="0 0 24 24"
|
||||
strokeWidth={1.5}
|
||||
stroke="currentColor"
|
||||
className="ml-1 w-5 h-5"
|
||||
className="ml-1 h-5 w-5"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
|
@@ -96,7 +96,7 @@ export function RegisterFormIDPIncomplete({
|
||||
|
||||
return (
|
||||
<form className="w-full">
|
||||
<div className="grid grid-cols-2 gap-4 mb-4">
|
||||
<div className="mb-4 grid grid-cols-2 gap-4">
|
||||
<div className="">
|
||||
<TextInput
|
||||
type="firstname"
|
||||
@@ -147,7 +147,7 @@ export function RegisterFormIDPIncomplete({
|
||||
onClick={handleSubmit(submitAndRegister)}
|
||||
data-testid="submit-button"
|
||||
>
|
||||
{loading && <Spinner className="h-5 w-5 mr-2" />}{" "}
|
||||
{loading && <Spinner className="mr-2 h-5 w-5" />}{" "}
|
||||
<Translated i18nKey="submit" namespace="register" />
|
||||
</Button>
|
||||
</div>
|
||||
|
@@ -124,7 +124,7 @@ export function RegisterForm({
|
||||
const [tosAndPolicyAccepted, setTosAndPolicyAccepted] = useState(false);
|
||||
return (
|
||||
<form className="w-full">
|
||||
<div className="grid grid-cols-2 gap-4 mb-4">
|
||||
<div className="mb-4 grid grid-cols-2 gap-4">
|
||||
<div className="">
|
||||
<TextInput
|
||||
type="firstname"
|
||||
@@ -170,7 +170,7 @@ export function RegisterForm({
|
||||
loginSettings.allowUsernamePassword &&
|
||||
loginSettings.passkeysType == PasskeysType.ALLOWED && (
|
||||
<>
|
||||
<p className="mt-4 ztdl-p mb-6 block text-left">
|
||||
<p className="ztdl-p mb-6 mt-4 block text-left">
|
||||
<Translated i18nKey="selectMethod" namespace="register" />
|
||||
</p>
|
||||
|
||||
@@ -211,14 +211,14 @@ export function RegisterForm({
|
||||
const usePasswordToContinue: boolean =
|
||||
loginSettings?.allowUsernamePassword &&
|
||||
loginSettings?.passkeysType == PasskeysType.ALLOWED
|
||||
? !!!(selected === methods[0]) // choose selection if both available
|
||||
? !(selected === methods[0]) // choose selection if both available
|
||||
: !!loginSettings?.allowUsernamePassword; // if password is chosen
|
||||
// set password as default if only password is allowed
|
||||
return submitAndContinue(values, usePasswordToContinue);
|
||||
})}
|
||||
data-testid="submit-button"
|
||||
>
|
||||
{loading && <Spinner className="h-5 w-5 mr-2" />}
|
||||
{loading && <Spinner className="mr-2 h-5 w-5" />}
|
||||
<Translated i18nKey="submit" namespace="register" />
|
||||
</Button>
|
||||
</div>
|
||||
|
@@ -211,7 +211,7 @@ export function RegisterPasskey({
|
||||
onClick={handleSubmit(submitRegisterAndContinue)}
|
||||
data-testid="submit-button"
|
||||
>
|
||||
{loading && <Spinner className="h-5 w-5 mr-2" />}{" "}
|
||||
{loading && <Spinner className="mr-2 h-5 w-5" />}{" "}
|
||||
<Translated i18nKey="set.submit" namespace="passkey" />
|
||||
</Button>
|
||||
</div>
|
||||
|
@@ -216,7 +216,7 @@ export function RegisterU2f({
|
||||
onClick={submitRegisterAndContinue}
|
||||
data-testid="submit-button"
|
||||
>
|
||||
{loading && <Spinner className="h-5 w-5 mr-2" />}{" "}
|
||||
{loading && <Spinner className="mr-2 h-5 w-5" />}{" "}
|
||||
<Translated i18nKey="set.submit" namespace="u2f" />
|
||||
</Button>
|
||||
</div>
|
||||
|
@@ -15,7 +15,7 @@ export function SelfServiceMenu({ sessionId }: { sessionId: string }) {
|
||||
// }
|
||||
|
||||
return (
|
||||
<div className="w-full flex flex-col space-y-2">
|
||||
<div className="flex w-full flex-col space-y-2">
|
||||
{list.map((menuitem, index) => {
|
||||
return (
|
||||
<SelfServiceItem
|
||||
@@ -34,7 +34,7 @@ const SelfServiceItem = ({ name, link }: { name: string; link: string }) => {
|
||||
<Link
|
||||
prefetch={false}
|
||||
href={link}
|
||||
className="w-full group flex flex-row items-center bg-background-light-400 dark:bg-background-dark-400 border border-divider-light hover:shadow-lg dark:hover:bg-white/10 py-2 px-4 rounded-md transition-all"
|
||||
className="group flex w-full flex-row items-center rounded-md border border-divider-light bg-background-light-400 px-4 py-2 transition-all hover:shadow-lg dark:bg-background-dark-400 dark:hover:bg-white/10"
|
||||
>
|
||||
{name}
|
||||
</Link>
|
||||
|
@@ -52,7 +52,7 @@ export function SessionClearItem({
|
||||
reload();
|
||||
});
|
||||
}}
|
||||
className="group flex flex-row items-center bg-background-light-400 dark:bg-background-dark-400 border border-divider-light hover:shadow-lg dark:hover:bg-white/10 py-2 px-4 rounded-md transition-all"
|
||||
className="group flex flex-row items-center rounded-md border border-divider-light bg-background-light-400 px-4 py-2 transition-all hover:shadow-lg dark:bg-background-dark-400 dark:hover:bg-white/10"
|
||||
>
|
||||
<div className="pr-4">
|
||||
<Avatar
|
||||
@@ -64,11 +64,11 @@ export function SessionClearItem({
|
||||
|
||||
<div className="flex flex-col items-start overflow-hidden">
|
||||
<span className="">{session.factors?.user?.displayName}</span>
|
||||
<span className="text-xs opacity-80 text-ellipsis">
|
||||
<span className="text-ellipsis text-xs opacity-80">
|
||||
{session.factors?.user?.loginName}
|
||||
</span>
|
||||
{valid ? (
|
||||
<span className="text-xs opacity-80 text-ellipsis">
|
||||
<span className="text-ellipsis text-xs opacity-80">
|
||||
{verifiedAt && (
|
||||
<Translated
|
||||
i18nKey="verfiedAt"
|
||||
@@ -79,7 +79,7 @@ export function SessionClearItem({
|
||||
</span>
|
||||
) : (
|
||||
verifiedAt && (
|
||||
<span className="text-xs opacity-80 text-ellipsis">
|
||||
<span className="text-ellipsis text-xs opacity-80">
|
||||
expired{" "}
|
||||
{session.expirationDate &&
|
||||
moment(timestampDate(session.expirationDate)).fromNow()}
|
||||
@@ -90,14 +90,14 @@ export function SessionClearItem({
|
||||
|
||||
<span className="flex-grow"></span>
|
||||
<div className="relative flex flex-row items-center">
|
||||
<div className="mr-6 px-2 py-[2px] text-xs hidden group-hover:block transition-all text-warn-light-500 dark:text-warn-dark-500 bg-[#ff0000]/10 dark:bg-[#ff0000]/10 rounded-full flex items-center justify-center">
|
||||
<div className="mr-6 flex hidden items-center justify-center rounded-full bg-[#ff0000]/10 px-2 py-[2px] text-xs text-warn-light-500 transition-all group-hover:block dark:bg-[#ff0000]/10 dark:text-warn-dark-500">
|
||||
<Translated i18nKey="clear" namespace="logout" />
|
||||
</div>
|
||||
|
||||
{valid ? (
|
||||
<div className="absolute h-2 w-2 bg-green-500 rounded-full mx-2 transform right-0 transition-all"></div>
|
||||
<div className="absolute right-0 mx-2 h-2 w-2 transform rounded-full bg-green-500 transition-all"></div>
|
||||
) : (
|
||||
<div className="absolute h-2 w-2 bg-red-500 rounded-full mx-2 transform right-0 transition-all"></div>
|
||||
<div className="absolute right-0 mx-2 h-2 w-2 transform rounded-full bg-red-500 transition-all"></div>
|
||||
)}
|
||||
</div>
|
||||
</button>
|
||||
|
@@ -102,7 +102,7 @@ export function SessionItem({
|
||||
}
|
||||
}
|
||||
}}
|
||||
className="group flex flex-row items-center bg-background-light-400 dark:bg-background-dark-400 border border-divider-light hover:shadow-lg dark:hover:bg-white/10 py-2 px-4 rounded-md transition-all"
|
||||
className="group flex flex-row items-center rounded-md border border-divider-light bg-background-light-400 px-4 py-2 transition-all hover:shadow-lg dark:bg-background-dark-400 dark:hover:bg-white/10"
|
||||
>
|
||||
<div className="pr-4">
|
||||
<Avatar
|
||||
@@ -114,16 +114,16 @@ export function SessionItem({
|
||||
|
||||
<div className="flex flex-col items-start overflow-hidden">
|
||||
<span className="">{session.factors?.user?.displayName}</span>
|
||||
<span className="text-xs opacity-80 text-ellipsis">
|
||||
<span className="text-ellipsis text-xs opacity-80">
|
||||
{session.factors?.user?.loginName}
|
||||
</span>
|
||||
{valid ? (
|
||||
<span className="text-xs opacity-80 text-ellipsis">
|
||||
<span className="text-ellipsis text-xs opacity-80">
|
||||
{verifiedAt && moment(timestampDate(verifiedAt)).fromNow()}
|
||||
</span>
|
||||
) : (
|
||||
verifiedAt && (
|
||||
<span className="text-xs opacity-80 text-ellipsis">
|
||||
<span className="text-ellipsis text-xs opacity-80">
|
||||
expired{" "}
|
||||
{session.expirationDate &&
|
||||
moment(timestampDate(session.expirationDate)).fromNow()}
|
||||
@@ -135,13 +135,13 @@ export function SessionItem({
|
||||
<span className="flex-grow"></span>
|
||||
<div className="relative flex flex-row items-center">
|
||||
{valid ? (
|
||||
<div className="absolute h-2 w-2 bg-green-500 rounded-full mx-2 transform right-0 group-hover:right-6 transition-all"></div>
|
||||
<div className="absolute right-0 mx-2 h-2 w-2 transform rounded-full bg-green-500 transition-all group-hover:right-6"></div>
|
||||
) : (
|
||||
<div className="absolute h-2 w-2 bg-red-500 rounded-full mx-2 transform right-0 group-hover:right-6 transition-all"></div>
|
||||
<div className="absolute right-0 mx-2 h-2 w-2 transform rounded-full bg-red-500 transition-all group-hover:right-6"></div>
|
||||
)}
|
||||
|
||||
<XCircleIcon
|
||||
className="hidden group-hover:block h-5 w-5 transition-all opacity-50 hover:opacity-100"
|
||||
className="hidden h-5 w-5 opacity-50 transition-all hover:opacity-100 group-hover:block"
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
@@ -188,18 +188,18 @@ export function SetPasswordForm({
|
||||
|
||||
return (
|
||||
<form className="w-full">
|
||||
<div className="pt-4 grid grid-cols-1 gap-4 mb-4">
|
||||
<div className="mb-4 grid grid-cols-1 gap-4 pt-4">
|
||||
{codeRequired && (
|
||||
<Alert type={AlertType.INFO}>
|
||||
<div className="flex flex-row">
|
||||
<span className="flex-1 mr-auto text-left">
|
||||
<span className="mr-auto flex-1 text-left">
|
||||
<Translated i18nKey="set.noCodeReceived" namespace="password" />
|
||||
</span>
|
||||
<button
|
||||
aria-label="Resend OTP Code"
|
||||
disabled={loading}
|
||||
type="button"
|
||||
className="ml-4 text-primary-light-500 dark:text-primary-dark-500 hover:dark:text-primary-dark-400 hover:text-primary-light-400 cursor-pointer disabled:cursor-default disabled:text-gray-400 dark:disabled:text-gray-700"
|
||||
className="ml-4 cursor-pointer text-primary-light-500 hover:text-primary-light-400 disabled:cursor-default disabled:text-gray-400 dark:text-primary-dark-500 hover:dark:text-primary-dark-400 dark:disabled:text-gray-700"
|
||||
onClick={() => {
|
||||
resendCode();
|
||||
}}
|
||||
@@ -277,7 +277,7 @@ export function SetPasswordForm({
|
||||
onClick={handleSubmit(submitPassword)}
|
||||
data-testid="submit-button"
|
||||
>
|
||||
{loading && <Spinner className="h-5 w-5 mr-2" />}{" "}
|
||||
{loading && <Spinner className="mr-2 h-5 w-5" />}{" "}
|
||||
<Translated i18nKey="set.submit" namespace="password" />
|
||||
</Button>
|
||||
</div>
|
||||
|
@@ -108,7 +108,7 @@ export function SetRegisterPasswordForm({
|
||||
|
||||
return (
|
||||
<form className="w-full">
|
||||
<div className="pt-4 grid grid-cols-1 gap-4 mb-4">
|
||||
<div className="mb-4 grid grid-cols-1 gap-4 pt-4">
|
||||
<div className="">
|
||||
<TextInput
|
||||
type="password"
|
||||
@@ -161,7 +161,7 @@ export function SetRegisterPasswordForm({
|
||||
onClick={handleSubmit(submitRegister)}
|
||||
data-testid="submit-button"
|
||||
>
|
||||
{loading && <Spinner className="h-5 w-5 mr-2" />}{" "}
|
||||
{loading && <Spinner className="mr-2 h-5 w-5" />}{" "}
|
||||
<Translated i18nKey="password.submit" namespace="register" />
|
||||
</Button>
|
||||
</div>
|
||||
|
@@ -76,8 +76,8 @@ export function SignInWithIdp({
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex flex-col w-full space-y-2 text-sm">
|
||||
<p className="text-center ztdl-p">
|
||||
<div className="flex w-full flex-col space-y-2 text-sm">
|
||||
<p className="ztdl-p text-center">
|
||||
<Translated i18nKey="orSignInWith" namespace="idp" />
|
||||
</p>
|
||||
{!!identityProviders.length && identityProviders?.map(renderIDPButton)}
|
||||
|
@@ -2,7 +2,7 @@ import { ReactNode } from "react";
|
||||
|
||||
export function Skeleton({ children }: { children?: ReactNode }) {
|
||||
return (
|
||||
<div className="skeleton py-12 px-8 rounded-lg bg-background-light-600 dark:bg-background-dark-600 flex flex-row items-center justify-center">
|
||||
<div className="skeleton flex flex-row items-center justify-center rounded-lg bg-background-light-600 px-8 py-12 dark:bg-background-dark-600">
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
|
@@ -4,7 +4,7 @@ export const Spinner: FC<{ className?: string }> = ({ className = "" }) => {
|
||||
return (
|
||||
<svg
|
||||
role="status"
|
||||
className={`${className} inline-block animate-spin fill-primary-light-500 dark:fill-primary-dark-500 text-black/10 dark:text-white/10`}
|
||||
className={`${className} inline-block animate-spin fill-primary-light-500 text-black/10 dark:fill-primary-dark-500 dark:text-white/10`}
|
||||
viewBox="0 0 100 101"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
@@ -16,8 +16,7 @@ export type StateBadgeProps = {
|
||||
|
||||
const getBadgeClasses = (state: BadgeState, evenPadding: boolean) =>
|
||||
clsx({
|
||||
"w-fit border-box h-18.5px flex flex-row items-center whitespace-nowrap tracking-wider leading-4 items-center justify-center px-2 py-2px text-12px rounded-full shadow-sm":
|
||||
true,
|
||||
"w-fit border-box h-18.5px flex flex-row items-center whitespace-nowrap tracking-wider leading-4 items-center justify-center px-2 py-2px text-12px rounded-full shadow-sm": true,
|
||||
"bg-state-success-light-background text-state-success-light-color dark:bg-state-success-dark-background dark:text-state-success-dark-color ":
|
||||
state === BadgeState.Success,
|
||||
"bg-state-neutral-light-background text-state-neutral-light-color dark:bg-state-neutral-dark-background dark:text-state-neutral-dark-color":
|
||||
|
@@ -23,7 +23,7 @@ export const Tab = ({
|
||||
return (
|
||||
<Link
|
||||
href={href}
|
||||
className={clsx("mt-2 mr-2 rounded-lg px-3 py-1 text-sm font-medium", {
|
||||
className={clsx("mr-2 mt-2 rounded-lg px-3 py-1 text-sm font-medium", {
|
||||
"bg-gray-700 text-gray-100 hover:bg-gray-500 hover:text-white":
|
||||
!isActive,
|
||||
"bg-blue-500 text-white": isActive,
|
||||
|
@@ -21,23 +21,23 @@ export function Theme() {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`h-fit relative grid grid-cols-2 rounded-full border border-divider-light dark:border-divider-dark p-1`}
|
||||
className={`relative grid h-fit grid-cols-2 rounded-full border border-divider-light p-1 dark:border-divider-dark`}
|
||||
>
|
||||
<button
|
||||
className={`h-8 w-8 rounded-full flex flex-row items-center justify-center hover:opacity-100 transition-all ${
|
||||
className={`flex h-8 w-8 flex-row items-center justify-center rounded-full transition-all hover:opacity-100 ${
|
||||
isDark ? "bg-black/10 dark:bg-white/10" : "opacity-60"
|
||||
}`}
|
||||
onClick={() => setTheme("dark")}
|
||||
>
|
||||
<MoonIcon className="h-4 w-4 flex-shrink-0 text-xl rounded-full" />
|
||||
<MoonIcon className="h-4 w-4 flex-shrink-0 rounded-full text-xl" />
|
||||
</button>
|
||||
<button
|
||||
className={`h-8 w-8 rounded-full flex flex-row items-center justify-center hover:opacity-100 transition-all ${
|
||||
className={`flex h-8 w-8 flex-row items-center justify-center rounded-full transition-all hover:opacity-100 ${
|
||||
!isDark ? "bg-black/10 dark:bg-white/10" : "opacity-60"
|
||||
}`}
|
||||
onClick={() => setTheme("light")}
|
||||
>
|
||||
<SunIcon className="h-6 w-6 flex-shrink-0 text-xl rounded-full" />
|
||||
<SunIcon className="h-6 w-6 flex-shrink-0 rounded-full text-xl" />
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
|
@@ -105,14 +105,14 @@ export function TotpRegister({
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex flex-col items-center ">
|
||||
<div className="flex flex-col items-center">
|
||||
{uri && (
|
||||
<>
|
||||
<QRCodeSVG
|
||||
className="rounded-md w-40 h-40 p-2 bg-white my-4"
|
||||
className="my-4 h-40 w-40 rounded-md bg-white p-2"
|
||||
value={uri}
|
||||
/>
|
||||
<div className="mb-4 w-96 flex text-sm my-2 border rounded-lg px-4 py-2 pr-2 border-divider-light dark:border-divider-dark">
|
||||
<div className="my-2 mb-4 flex w-96 rounded-lg border border-divider-light px-4 py-2 pr-2 text-sm dark:border-divider-dark">
|
||||
<Link href={uri} target="_blank" className="flex-1 overflow-x-auto">
|
||||
{uri}
|
||||
</Link>
|
||||
@@ -145,7 +145,7 @@ export function TotpRegister({
|
||||
onClick={handleSubmit(continueWithCode)}
|
||||
data-testid="submit-button"
|
||||
>
|
||||
{loading && <Spinner className="h-5 w-5 mr-2" />}
|
||||
{loading && <Spinner className="mr-2 h-5 w-5" />}
|
||||
<Translated i18nKey="set.submit" namespace="otp" />
|
||||
</Button>
|
||||
</div>
|
||||
|
@@ -42,14 +42,14 @@ export function UserAvatar({
|
||||
loginName={loginName ?? ""}
|
||||
/>
|
||||
</div>
|
||||
<span className="ml-4 pr-4 text-14px max-w-[250px] text-ellipsis overflow-hidden">
|
||||
<span className="ml-4 max-w-[250px] overflow-hidden text-ellipsis pr-4 text-14px">
|
||||
{loginName}
|
||||
</span>
|
||||
<span className="flex-grow"></span>
|
||||
{showDropdown && (
|
||||
<Link
|
||||
href={"/accounts?" + params}
|
||||
className="ml-4 flex items-center justify-center p-1 hover:bg-black/10 dark:hover:bg-white/10 rounded-full mr-1 transition-all"
|
||||
className="ml-4 mr-1 flex items-center justify-center rounded-full p-1 transition-all hover:bg-black/10 dark:hover:bg-white/10"
|
||||
>
|
||||
<ChevronDownIcon className="h-4 w-4" />
|
||||
</Link>
|
||||
|
@@ -110,7 +110,7 @@ export function UsernameForm({
|
||||
/>
|
||||
{allowRegister && (
|
||||
<button
|
||||
className="transition-all text-sm hover:text-primary-light-500 dark:hover:text-primary-dark-500"
|
||||
className="text-sm transition-all hover:text-primary-light-500 dark:hover:text-primary-dark-500"
|
||||
onClick={() => {
|
||||
const registerParams = new URLSearchParams();
|
||||
if (organization) {
|
||||
@@ -147,7 +147,7 @@ export function UsernameForm({
|
||||
disabled={loading || !formState.isValid}
|
||||
onClick={handleSubmit((e) => submitLoginName(e, organization))}
|
||||
>
|
||||
{loading && <Spinner className="h-5 w-5 mr-2" />}
|
||||
{loading && <Spinner className="mr-2 h-5 w-5" />}
|
||||
<Translated i18nKey="submit" namespace="loginname" />
|
||||
</Button>
|
||||
</div>
|
||||
|
@@ -114,14 +114,14 @@ export function VerifyForm({
|
||||
<form className="w-full">
|
||||
<Alert type={AlertType.INFO}>
|
||||
<div className="flex flex-row">
|
||||
<span className="flex-1 mr-auto text-left">
|
||||
<span className="mr-auto flex-1 text-left">
|
||||
<Translated i18nKey="verify.noCodeReceived" namespace="verify" />
|
||||
</span>
|
||||
<button
|
||||
aria-label="Resend Code"
|
||||
disabled={loading}
|
||||
type="button"
|
||||
className="ml-4 text-primary-light-500 dark:text-primary-dark-500 hover:dark:text-primary-dark-400 hover:text-primary-light-400 cursor-pointer disabled:cursor-default disabled:text-gray-400 dark:disabled:text-gray-700"
|
||||
className="ml-4 cursor-pointer text-primary-light-500 hover:text-primary-light-400 disabled:cursor-default disabled:text-gray-400 dark:text-primary-dark-500 hover:dark:text-primary-dark-400 dark:disabled:text-gray-700"
|
||||
onClick={() => {
|
||||
resendCode();
|
||||
}}
|
||||
@@ -158,7 +158,7 @@ export function VerifyForm({
|
||||
onClick={handleSubmit(fcn)}
|
||||
data-testid="submit-button"
|
||||
>
|
||||
{loading && <Spinner className="h-5 w-5 mr-2" />}
|
||||
{loading && <Spinner className="mr-2 h-5 w-5" />}
|
||||
<Translated i18nKey="verify.submit" namespace="verify" />
|
||||
</Button>
|
||||
</div>
|
||||
|
@@ -314,7 +314,7 @@ export async function getMostRecentCookieWithLoginname<T>({
|
||||
if (stringifiedCookie?.value) {
|
||||
const sessions: SessionCookie<T>[] = JSON.parse(stringifiedCookie?.value);
|
||||
let filtered = sessions.filter((cookie) => {
|
||||
return !!loginName ? cookie.loginName === loginName : true;
|
||||
return loginName ? cookie.loginName === loginName : true;
|
||||
});
|
||||
|
||||
if (organization) {
|
||||
|
@@ -145,7 +145,7 @@ export async function verifyPasskeyRegistration(command: VerifyPasskeyCommand) {
|
||||
|
||||
// if no name is provided, try to generate one from the user agent
|
||||
let passkeyName = command.passkeyName;
|
||||
if (!!!passkeyName) {
|
||||
if (!passkeyName) {
|
||||
const headersList = await headers();
|
||||
const userAgentStructure = { headers: headersList };
|
||||
const { browser, device, os } = userAgent(userAgentStructure);
|
||||
|
@@ -67,7 +67,7 @@ export async function verifyU2F(command: VerifyU2FCommand) {
|
||||
}
|
||||
|
||||
let passkeyName = command.passkeyName;
|
||||
if (!!!passkeyName) {
|
||||
if (!passkeyName) {
|
||||
const headersList = await headers();
|
||||
const userAgentStructure = { headers: headersList };
|
||||
const { browser, device, os } = userAgent(userAgentStructure);
|
||||
|
@@ -8,11 +8,11 @@
|
||||
@layer base {
|
||||
h1,
|
||||
.ztdl-h1 {
|
||||
@apply text-2xl text-center;
|
||||
@apply text-center text-2xl;
|
||||
}
|
||||
|
||||
.ztdl-p {
|
||||
@apply text-sm text-center text-text-light-secondary-500 dark:text-text-dark-secondary-500 text-center;
|
||||
@apply text-center text-sm text-text-light-secondary-500 dark:text-text-dark-secondary-500;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -9,14 +9,26 @@ let themeColors = {
|
||||
link: { light: { contrast: {} }, dark: { contrast: {} } },
|
||||
};
|
||||
|
||||
const shades = ["50", "100", "200", "300", "400", "500", "600", "700", "800", "900"];
|
||||
const shades = [
|
||||
"50",
|
||||
"100",
|
||||
"200",
|
||||
"300",
|
||||
"400",
|
||||
"500",
|
||||
"600",
|
||||
"700",
|
||||
"800",
|
||||
"900",
|
||||
];
|
||||
const themes = ["light", "dark"];
|
||||
const types = ["background", "primary", "warn", "text", "link"];
|
||||
|
||||
types.forEach((type) => {
|
||||
themes.forEach((theme) => {
|
||||
shades.forEach((shade) => {
|
||||
themeColors[type][theme][shade] = `var(--theme-${theme}-${type}-${shade})`;
|
||||
themeColors[type][theme][shade] =
|
||||
`var(--theme-${theme}-${type}-${shade})`;
|
||||
themeColors[type][theme][`contrast-${shade}`] =
|
||||
`var(--theme-${theme}-${type}-contrast-${shade})`;
|
||||
themeColors[type][theme][`secondary-${shade}`] =
|
||||
|
1
login/apps/login/test-setup.ts
Normal file
1
login/apps/login/test-setup.ts
Normal file
@@ -0,0 +1 @@
|
||||
import "@testing-library/jest-dom/vitest";
|
@@ -7,6 +7,6 @@ export default defineConfig({
|
||||
test: {
|
||||
include: ["src/**/*.test.ts", "src/**/*.test.tsx"],
|
||||
environment: "jsdom",
|
||||
setupFiles: ["@testing-library/jest-dom/vitest"],
|
||||
setupFiles: ["./test-setup.ts"],
|
||||
},
|
||||
});
|
||||
|
2
login/test-setup.ts
Normal file
2
login/test-setup.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
// Test setup file to handle jest-dom configuration
|
||||
import "@testing-library/jest-dom";
|
Reference in New Issue
Block a user