diff --git a/frontend/elements/src/components/form/Button.tsx b/frontend/elements/src/components/form/Button.tsx
index f09f96171..8b827ff80 100644
--- a/frontend/elements/src/components/form/Button.tsx
+++ b/frontend/elements/src/components/form/Button.tsx
@@ -8,6 +8,7 @@ import styles from "./styles.sass";
import LoadingSpinner from "../icons/LoadingSpinner";
import Icon, { IconName } from "../icons/Icon";
import { AppContext, UIAction } from "../../contexts/AppProvider";
+import LastUsed from "./LastUsed";
type Props = {
uiAction?: UIAction;
@@ -19,6 +20,7 @@ type Props = {
isSuccess?: boolean;
disabled?: boolean;
autofocus?: boolean;
+ showLastUsed?: boolean;
onClick?: (event: Event) => void;
icon?: IconName;
};
@@ -30,6 +32,7 @@ const Button = ({
secondary,
dangerous,
autofocus,
+ showLastUsed,
onClick,
icon,
...props
@@ -93,7 +96,10 @@ const Button = ({
{icon ? (
) : null}
- {children}
+
+ {children}
+ {showLastUsed ? : null}
+
);
diff --git a/frontend/elements/src/components/form/LastUsed.tsx b/frontend/elements/src/components/form/LastUsed.tsx
new file mode 100644
index 000000000..f7eb31b75
--- /dev/null
+++ b/frontend/elements/src/components/form/LastUsed.tsx
@@ -0,0 +1,11 @@
+import cx from "classnames";
+import styles from "./styles.sass";
+import { useContext } from "preact/compat";
+import { TranslateContext } from "@denysvuika/preact-translate";
+
+const LastUsed = () => {
+ const { t } = useContext(TranslateContext);
+ return {t("labels.lastUsed")};
+};
+
+export default LastUsed;
diff --git a/frontend/elements/src/components/form/styles.sass b/frontend/elements/src/components/form/styles.sass
index a06af2580..c6d05411e 100644
--- a/frontend/elements/src/components/form/styles.sass
+++ b/frontend/elements/src/components/form/styles.sass
@@ -32,7 +32,7 @@
white-space: nowrap
width: 100%
min-width: variables.$button-min-width
- height: variables.$item-height
+ min-height: variables.$item-height
outline: none
cursor: pointer
transition: 0.1s ease-out
@@ -68,7 +68,7 @@
color: variables.$color
background: variables.$background-color
border-color: variables.$color
- justify-content: left
+ justify-content: flex-start
&.secondary:hover
color: variables.$color
@@ -92,7 +92,18 @@
flex-grow: 0
width: auto
+// Last Used Styles
+.lastUsed
+ color: variables.$color-shade-1
+ font-size: smaller
+
// Input Styles
+.caption
+ flex-grow: 1
+ flex-wrap: wrap
+ display: flex
+ justify-content: space-between
+ align-items: baseline
.inputWrapper
flex-grow: 1
diff --git a/frontend/elements/src/components/icons/styles.sass b/frontend/elements/src/components/icons/styles.sass
index 87736406e..c7f8e3357 100644
--- a/frontend/elements/src/components/icons/styles.sass
+++ b/frontend/elements/src/components/icons/styles.sass
@@ -50,6 +50,7 @@
height: 100%
margin: 0 5px
justify-content: inherit
+ flex-wrap: inherit
&.centerContent
justify-content: center
diff --git a/frontend/elements/src/i18n/bn.ts b/frontend/elements/src/i18n/bn.ts
index 36bf51a51..3954a1a3a 100644
--- a/frontend/elements/src/i18n/bn.ts
+++ b/frontend/elements/src/i18n/bn.ts
@@ -149,6 +149,7 @@ export const bn: Translation = {
authenticatorAppAdd: "সেট আপ করুন",
configured: "কনফিগার করা হয়েছে",
useAnotherMethod: "আরেকটি পদ্ধতি ব্যবহার করুন",
+ lastUsed: "সর্বশেষ ব্যবহৃত",
},
errors: {
somethingWentWrong:
diff --git a/frontend/elements/src/i18n/de.ts b/frontend/elements/src/i18n/de.ts
index dd12a77e0..ea8f32316 100644
--- a/frontend/elements/src/i18n/de.ts
+++ b/frontend/elements/src/i18n/de.ts
@@ -155,6 +155,7 @@ export const de: Translation = {
authenticatorAppAdd: "Einrichten",
configured: "konfiguriert",
useAnotherMethod: "Eine andere Methode verwenden",
+ lastUsed: "Zuletzt verwendet",
},
errors: {
somethingWentWrong:
diff --git a/frontend/elements/src/i18n/en.ts b/frontend/elements/src/i18n/en.ts
index e2f5da77a..b81b862a4 100644
--- a/frontend/elements/src/i18n/en.ts
+++ b/frontend/elements/src/i18n/en.ts
@@ -150,6 +150,7 @@ export const en: Translation = {
authenticatorAppAdd: "Set up",
configured: "configured",
useAnotherMethod: "Use another method",
+ lastUsed: "Last used",
},
errors: {
somethingWentWrong:
diff --git a/frontend/elements/src/i18n/fr.ts b/frontend/elements/src/i18n/fr.ts
index cab8e5fa2..f6bb0f990 100644
--- a/frontend/elements/src/i18n/fr.ts
+++ b/frontend/elements/src/i18n/fr.ts
@@ -155,6 +155,7 @@ export const fr: Translation = {
authenticatorAppAdd: "Configurer",
configured: "configuré",
useAnotherMethod: "Utiliser une autre méthode",
+ lastUsed: "Dernière utilisation",
},
errors: {
somethingWentWrong:
diff --git a/frontend/elements/src/i18n/it.ts b/frontend/elements/src/i18n/it.ts
index 492fc5eb6..b4e88967c 100644
--- a/frontend/elements/src/i18n/it.ts
+++ b/frontend/elements/src/i18n/it.ts
@@ -151,6 +151,7 @@ export const it: Translation = {
authenticatorAppAdd: "Imposta",
configured: "configurato",
useAnotherMethod: "Usa un altro metodo",
+ lastUsed: "Ultimo utilizzo",
},
errors: {
somethingWentWrong: "Si è verificato un errore tecnico. Riprova più tardi.",
diff --git a/frontend/elements/src/i18n/pt-BR.ts b/frontend/elements/src/i18n/pt-BR.ts
index 198bb037c..c21dac37c 100644
--- a/frontend/elements/src/i18n/pt-BR.ts
+++ b/frontend/elements/src/i18n/pt-BR.ts
@@ -154,6 +154,7 @@ export const ptBR: Translation = {
authenticatorAppAdd: "Configurar",
configured: "configurado",
useAnotherMethod: "Usar outro método",
+ lastUsed: "Último uso",
},
errors: {
somethingWentWrong:
diff --git a/frontend/elements/src/i18n/translations.ts b/frontend/elements/src/i18n/translations.ts
index 8574f55a0..fd902a8e0 100644
--- a/frontend/elements/src/i18n/translations.ts
+++ b/frontend/elements/src/i18n/translations.ts
@@ -138,6 +138,7 @@ export interface Translation {
currentSession: string;
newSecurityKeyName: string;
createSecurityKey: string;
+ lastUsed: string;
};
errors: {
somethingWentWrong: string;
diff --git a/frontend/elements/src/i18n/zh.ts b/frontend/elements/src/i18n/zh.ts
index f70c7d195..e6e17b300 100644
--- a/frontend/elements/src/i18n/zh.ts
+++ b/frontend/elements/src/i18n/zh.ts
@@ -146,6 +146,7 @@ export const zh: Translation = {
authenticatorAppAdd: "设置",
configured: "已配置",
useAnotherMethod: "使用其他方法",
+ lastUsed: "最后使用",
},
errors: {
somethingWentWrong: "发生技术错误。请稍后再试。",
diff --git a/frontend/elements/src/pages/LoginInitPage.tsx b/frontend/elements/src/pages/LoginInitPage.tsx
index 0b4b1da93..bcc8ff1b7 100644
--- a/frontend/elements/src/pages/LoginInitPage.tsx
+++ b/frontend/elements/src/pages/LoginInitPage.tsx
@@ -40,6 +40,7 @@ const LoginInitPage = (props: Props) => {
setUIState,
stateHandler,
hidePasskeyButtonOnLogin,
+ lastLogin,
} = useContext(AppContext);
const [identifierType, setIdentifierType] = useState(null);
@@ -240,6 +241,7 @@ const LoginInitPage = (props: Props) => {
}
disabled={!isWebAuthnSupported}
icon={"passkey"}
+ showLastUsed={lastLogin?.login_method == "passkey"}
>
{t("labels.signInPasskey")}
@@ -258,6 +260,10 @@ const LoginInitPage = (props: Props) => {
secondary
// @ts-ignore
icon={v.value}
+ showLastUsed={
+ lastLogin?.login_method == "third_party" &&
+ lastLogin?.third_party_provider == v.value
+ }
>
{t("labels.signInWith", { provider: v.name })}
diff --git a/frontend/elements/src/pages/LoginMethodChooser.tsx b/frontend/elements/src/pages/LoginMethodChooser.tsx
index 00f6ca283..c0436cf83 100644
--- a/frontend/elements/src/pages/LoginMethodChooser.tsx
+++ b/frontend/elements/src/pages/LoginMethodChooser.tsx
@@ -22,7 +22,8 @@ interface Props {
const LoginMethodChooserPage = (props: Props) => {
const { t } = useContext(TranslateContext);
- const { hanko, setLoadingAction, stateHandler } = useContext(AppContext);
+ const { hanko, setLoadingAction, stateHandler, lastLogin } =
+ useContext(AppContext);
const { flowState } = useFlowState(props.state);
const onPasswordSelectSubmit = async (event: Event) => {
@@ -63,7 +64,11 @@ const LoginMethodChooserPage = (props: Props) => {
hidden={!flowState.actions.continue_to_passcode_confirmation?.(null)}
onSubmit={onPasscodeSelectSubmit}
>
-