diff --git a/package-lock.json b/package-lock.json index 778951aec..7db454736 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15464,9 +15464,9 @@ "dev": true }, "node_modules/serialize-javascript": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", - "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dependencies": { "randombytes": "^2.1.0" } @@ -29160,9 +29160,9 @@ } }, "serialize-javascript": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", - "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "requires": { "randombytes": "^2.1.0" } diff --git a/src/components/Common/HeaderNav.tsx b/src/components/Common/HeaderNav.tsx index 88ee72ae7..3db12f9f0 100644 --- a/src/components/Common/HeaderNav.tsx +++ b/src/components/Common/HeaderNav.tsx @@ -1,5 +1,11 @@ import { IconProp } from "@fortawesome/fontawesome-svg-core"; -import { faArrowRightFromBracket, faChevronDown, faChevronUp } from "@fortawesome/free-solid-svg-icons"; +import { + faArrowRightFromBracket, + faBars, + faChevronDown, + faChevronUp, + faXmark, +} from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import EduIDButton from "components/Common/EduIDButton"; import { ACCOUNT_PATH, IDENTITY_PATH, SECURITY_PATH, START_PATH } from "components/IndexMain"; @@ -7,9 +13,11 @@ import { useAppSelector } from "eduid-hooks"; import React, { useEffect, useRef, useState } from "react"; import { FormattedMessage } from "react-intl"; import { NavLink } from "react-router-dom"; +import { HashLink } from "react-router-hash-link"; // export for use in tests export const activeClassName = "active"; +type ButtonKey = "start" | "identity" | "security" | "account"; export interface HeaderNavProps { handleLogout: () => void; @@ -37,11 +45,7 @@ function RenderUserName(props: RenderUserNameProps): JSX.Element | null { data-name={emails.filter((mail) => mail.primary)[0].email} > {emails.filter((mail) => mail.primary)[0].email} - {props.openMenu ? ( - - ) : ( - - )} + {props.openMenu ? : } ); } @@ -67,58 +71,186 @@ function useCloseMenuClickOutside(ref: React.RefObject, handler: () export function HeaderNav(props: HeaderNavProps): JSX.Element { const [openMenu, setOpenMenu] = useState(false); + const [isOpen, setIsOpen] = useState<{ [key in ButtonKey]: boolean }>({ + start: false, + identity: false, + security: false, + account: false, + }); const wrapperRef = useRef(null); + const toggleOpen = (button: ButtonKey) => { + setIsOpen((prevState) => ({ + ...prevState, + [button]: !prevState[button], + })); + }; + useCloseMenuClickOutside(wrapperRef, () => setOpenMenu(false)); return ( diff --git a/src/components/Common/MultiFactorAuthentication.tsx b/src/components/Common/MultiFactorAuthentication.tsx index 3df3a6c70..66af027ab 100644 --- a/src/components/Common/MultiFactorAuthentication.tsx +++ b/src/components/Common/MultiFactorAuthentication.tsx @@ -246,7 +246,7 @@ export function MultiFactorAuthentication(): React.ReactElement | null { if (!isPlatformAuthLoaded) return null; return ( <> -
+

diff --git a/src/components/Dashboard/AccountId.tsx b/src/components/Dashboard/AccountId.tsx index 52b3f1744..c9da200ba 100644 --- a/src/components/Dashboard/AccountId.tsx +++ b/src/components/Dashboard/AccountId.tsx @@ -24,7 +24,7 @@ export function AccountId(): JSX.Element { export function AccountIdDisplay(): JSX.Element { return ( -
+

diff --git a/src/components/Dashboard/AccountLinking.tsx b/src/components/Dashboard/AccountLinking.tsx index b4361381c..f5186a1f5 100644 --- a/src/components/Dashboard/AccountLinking.tsx +++ b/src/components/Dashboard/AccountLinking.tsx @@ -3,7 +3,7 @@ import { FormattedMessage } from "react-intl"; export function AccountLinking() { return ( -
+

diff --git a/src/components/Dashboard/ChangePasswordDisplay.tsx b/src/components/Dashboard/ChangePasswordDisplay.tsx index c7c54a15b..87c0ad843 100644 --- a/src/components/Dashboard/ChangePasswordDisplay.tsx +++ b/src/components/Dashboard/ChangePasswordDisplay.tsx @@ -16,7 +16,7 @@ function ChangePasswordDisplay() { } } return ( -
+

diff --git a/src/components/Dashboard/DeleteAccount.tsx b/src/components/Dashboard/DeleteAccount.tsx index ca0da1c5d..20ab39c08 100644 --- a/src/components/Dashboard/DeleteAccount.tsx +++ b/src/components/Dashboard/DeleteAccount.tsx @@ -18,7 +18,7 @@ export default function DeleteAccount(): JSX.Element | null { } return ( -
+

diff --git a/src/components/Dashboard/Emails.tsx b/src/components/Dashboard/Emails.tsx index 857c36377..16cf72504 100644 --- a/src/components/Dashboard/Emails.tsx +++ b/src/components/Dashboard/Emails.tsx @@ -109,7 +109,7 @@ function Emails() { } return ( -
+

diff --git a/src/components/Dashboard/Identity.tsx b/src/components/Dashboard/Identity.tsx index 80d7534d9..7f6ce3efa 100644 --- a/src/components/Dashboard/Identity.tsx +++ b/src/components/Dashboard/Identity.tsx @@ -108,7 +108,7 @@ function IdentityContent(): JSX.Element { -
+
{identities?.is_verified ? (

diff --git a/src/components/Dashboard/Ladok.tsx b/src/components/Dashboard/Ladok.tsx index 4f0800850..a1243064b 100644 --- a/src/components/Dashboard/Ladok.tsx +++ b/src/components/Dashboard/Ladok.tsx @@ -29,9 +29,9 @@ const LadokContainer = (): JSX.Element => { useEffect(() => setSwitchChecked(isLinked), [isLinked]); return ( -
+

- +

diff --git a/src/components/Dashboard/Language.tsx b/src/components/Dashboard/Language.tsx index e662b7517..ed1f30212 100644 --- a/src/components/Dashboard/Language.tsx +++ b/src/components/Dashboard/Language.tsx @@ -36,7 +36,7 @@ export function LanguagePreference() { } return ( -

+

@@ -58,7 +58,7 @@ export function LanguagePreference() {
- +
{language_list.map((option: string[]) => { diff --git a/src/components/Dashboard/PersonalDataParent.tsx b/src/components/Dashboard/PersonalDataParent.tsx index 00940e3d3..9e486f7ff 100644 --- a/src/components/Dashboard/PersonalDataParent.tsx +++ b/src/components/Dashboard/PersonalDataParent.tsx @@ -114,10 +114,10 @@ function PersonalDataParent() { }; return ( -
+

- +

diff --git a/src/components/Dashboard/Recommendations.tsx b/src/components/Dashboard/Recommendations.tsx index ce2d5878a..cce23e7a6 100644 --- a/src/components/Dashboard/Recommendations.tsx +++ b/src/components/Dashboard/Recommendations.tsx @@ -197,7 +197,7 @@ export function Recommendations(): JSX.Element | null { } return ( -
+

diff --git a/src/styles/_Header.scss b/src/styles/_Header.scss index 43f2578b2..b2c9f5736 100644 --- a/src/styles/_Header.scss +++ b/src/styles/_Header.scss @@ -22,6 +22,29 @@ header { } .header-nav { + // sub menu + .submenu-collapse { + max-height: 500px; + overflow: hidden; + transition: max-height 0.2s ease; + margin: 0 0.75rem 1rem 1.5rem; + + ul { + li { + padding: 0.5rem 0; + line-height: 1.2; + a { + font-size: $txt-sm; + color: $txt-gray; + } + } + } + } + .submenu-close { + max-height: 0; + margin-bottom: 0; + } + button { @media (max-width: $bp-sm) { span { @@ -35,7 +58,7 @@ header { } } - ul { + ul li { a { color: $txt-black; @@ -56,10 +79,14 @@ header { font-family: $inter-light; background: none; box-shadow: none; - padding: 0 1.125rem; + padding: 0 1rem; + display: flex; + align-items: center; svg { padding-left: 0.75rem; + font-size: 1.5rem; + width: 24px; } } @@ -67,12 +94,36 @@ header { display: none; min-width: 250px; + @media (max-width: $bp-xs) { + min-width: calc(100% - #{2 * $margin}); + left: $margin; + } + ul { text-align: left; - } - .btn-close { - align-self: flex-end; + .flex-between { + padding-left: 0.75rem; + margin-top: 3px; + margin-bottom: 3px; + &:has(a.active) { + background-color: $body-gray; + border-radius: 1.5rem; + } + + button { + background-color: transparent; + box-shadow: none; + padding: 0 0.75rem; + + svg { + color: $txt-gray; + } + &:hover svg { + color: $txt-orange; + } + } + } } &.active { @@ -86,8 +137,11 @@ header { background-color: $white; box-shadow: 0 -6px 17px rgb(89 89 89 / 7%); border-radius: 10px; - padding: 20px; - right: 20px; + padding: 0.75rem; + right: $margin; + max-width: 20rem; + overflow-y: auto; + max-height: 90vh; .btn-link svg { padding-right: 5px; @@ -101,12 +155,16 @@ header { height: 2.7rem; justify-content: left; line-height: 1.2; - width: 100%; &:nth-child(4) { border-bottom: 1px solid $border-gray; } } + .logout-button-wrapper { + margin: 0.5rem 0.75rem; + padding-top: 0.5rem; + border-top: 1px solid $border-gray; + } } } } diff --git a/src/translation/extractedMessages.json b/src/translation/extractedMessages.json index 64aa6c5b3..f57bcd3d6 100644 --- a/src/translation/extractedMessages.json +++ b/src/translation/extractedMessages.json @@ -617,6 +617,9 @@ "developer_comment": "Security keys list - paragraph", "string": "This is a list of names of maker and models of external security keys that kan be used for eduID at present:" }, + "Close": { + "string": "Close" + }, "Cnpo0l": { "developer_comment": "profile username display title", "string": "Username" @@ -999,6 +1002,10 @@ "developer_comment": "platform authn device help text", "string": "The device you are currently using" }, + "MGhoaU": { + "developer_comment": "Language", + "string": "Language" + }, "Mcx0Ut": { "developer_comment": "what is accessibility report - paragraph 2", "string": "It is of outmost importance to us that as many as possible are able to use the service in a convenient and safe manner and is one of the many ways eduID is always striving to improve." @@ -1444,6 +1451,10 @@ "developer_comment": "eidas proofing help text", "string": "To use this option you will need to first create a digital ID in the {freja_eid_link} app." }, + "VweyRk": { + "developer_comment": "Ladok account linking", + "string": "ESI information" + }, "W0anmW": { "developer_comment": "account eduid - list item 3-3", "string": "If you are using a passkey for your login, don't save it on the same key chain as your password." @@ -1476,6 +1487,10 @@ "developer_comment": "login eduid - security key list item 1", "string": "Press the \"Use my security key\" button and follow the instructions, which will vary depending on your key." }, + "WogNGU": { + "developer_comment": "Identity sub menu", + "string": "Verify Identity" + }, "WtORfS": { "developer_comment": "status overview paragraph1", "string": "The strength and usage of your eduID can be improved by following the steps listed below." @@ -1636,6 +1651,10 @@ "developer_comment": "what is bankid - paragraph", "string": "BankID is a widely used electronic verification system, available to holders of a Swedish personal identification number, an approved Swedish ID document (e.g. passport, drivers license or ID card) and connected to a bank in Sweden." }, + "aXZyf1": { + "developer_comment": "Names & Display Name", + "string": "Names & Display Name" + }, "actions.action-completed": { "string": "Success" }, @@ -2823,10 +2842,6 @@ "developer_comment": "Login username input", "string": "Welcome back, {username}!" }, - "qIGw46": { - "developer_comment": "pd main title", - "string": "Names & Display Name" - }, "qJmOW9": { "developer_comment": "explanation text for letter proofing", "string": "When you have received the letter, proceed by clicking the button below." @@ -2882,10 +2897,6 @@ "developer_comment": "Assurance levels with your eduID - paragraph7", "string": "Note: this is a generalization and could change, complete information as to what is required of your eduID must be provided by the connecting services." }, - "rT3vhi": { - "developer_comment": "Dashboard nav tab name", - "string": "Security" - }, "rdd33t": { "developer_comment": "what is international - paragraph 1", "string": "Freja is an eID based on an identity verification platform using biometric passports, combined with the users mobile device to create a verified digital identity than can be used remotely." @@ -3130,10 +3141,6 @@ "developer_comment": "settings eduid - list item 2-1", "string": "To change the default language for eduID you can log in to eduID and select your preference using the Language radio buttons under Account." }, - "t2g4sA": { - "developer_comment": "Ladok account linking", - "string": "Ladok information" - }, "tAcT/R": { "string": "BankID" }, @@ -3295,10 +3302,6 @@ "developer_comment": "SAML login finished", "string": "You can try to login again using the button below, but it is very likely that the service you are logging in to will reject the request and you will have to start over." }, - "x6V8oh": { - "developer_comment": "Language radio group legend", - "string": "Language" - }, "x8ZGkQ": { "developer_comment": "Assurance levels with your eduID - paragraph2em", "string": "AL1 (unconfirmed user) / RAF Low"