Skip to content

Commit

Permalink
Restyled welcome page(s)
Browse files Browse the repository at this point in the history
  • Loading branch information
oharsta committed Sep 21, 2023
1 parent acaddfe commit fccc0ac
Show file tree
Hide file tree
Showing 15 changed files with 272 additions and 497 deletions.
11 changes: 0 additions & 11 deletions welcome/src/components/Header.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,11 @@ import {UserMenu} from "./UserMenu";
import {Link} from "react-router-dom";
import {useAppStore} from "../stores/AppStore";
import I18n from "../locale/I18n";
import {AUTHORITIES, isUserAllowed} from "../utils/UserRole";
import {stopEvent} from "../utils/Utils";

export const Header = () => {

const {user, config} = useAppStore(state => state);
const actions = [];
if (user && user.id && isUserAllowed(AUTHORITIES.INVITER, user)) {
actions.push({
href: "switch", perform: e => {
stopEvent(e);
window.location.href = `${config.serverWelcomeUrl}/api/v1/users/switch?app=access`
}, name: I18n.t("header.links.switchApp", {app: I18n.t("header.links.access")})
})
}

return (
<div className="header-container">
<div className="header-inner">
Expand Down
34 changes: 34 additions & 0 deletions welcome/src/components/RoleCard.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React from "react";
import "./RoleCard.scss";
import Logo from "./Logo";
import I18n from "../locale/I18n";
import {MoreLessText} from "./MoreLessText";
import {Button, Card, CardType, Chip, ChipType} from "@surfnet/sds";

export const RoleCard = ({role, provider, index, isNew = false}) => {

const logo = provider.data.metaDataFields["logo:0:url"];
const children =
<div key={index} className="user-role">
<Logo src={logo} alt={"provider"} className={"provider"}/>
<section className={"user-role-info"}>
<p>{provider.data.metaDataFields[`name:${I18n.locale}`]} ({provider.data.metaDataFields[`OrganizationName:${I18n.locale}`]})</p>
<h3>{role.name}</h3>
<MoreLessText txt={role.description}/>
</section>
<div className={"launch"}>
<Button txt={I18n.t("proceed.launch")} onClick={() => {
window.location.href = role.landingPage;
}}/>
</div>

</div>;
return (
<div className={`card-container ${isNew ? "is-new" : ""}`}>
{isNew &&
<Chip label={I18n.t("proceed.new")} type={ChipType.Status_error}/>
}
<Card key={index} cardType={CardType.Big} children={children}/>
</div>
);
}
57 changes: 57 additions & 0 deletions welcome/src/components/RoleCard.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
@import "../styles/vars";

.card-container {

&.is-new {
position: relative;

.sds--chips {
position: absolute;
top: -16px;
left: -22px;
}

.sds--card {
box-shadow: 0 0.2rem 0.2rem 0 var(--sds--color--blue--400);
background-color: var(--sds--color--gray--100);
border: 0.0625rem solid var(--sds--color--blue--500);
}

}

.user-role {
display: flex;
align-items: center;

@media (max-width: 680px) {
flex-direction: column;
}

img, svg {
height: 56px;
width: auto;
margin-right: 35px;
border-radius: $br;

@media (max-width: 680px) {
margin: 0 auto 20px 0;
}
}

.launch {
margin-left: auto;

@media (max-width: 680px) {
margin: 20px auto 0 0;
}

}


.user-role-info {
h3 {
margin: 10px 0;
}
}
}
}
101 changes: 10 additions & 91 deletions welcome/src/components/User.js
Original file line number Diff line number Diff line change
@@ -1,116 +1,35 @@
import React, {useEffect, useRef, useState} from "react";
import React from "react";
import "./User.scss";
import InputField from "./InputField";
import {dateFromEpoch} from "../utils/Date";
import {highestAuthority} from "../utils/UserRole";
import I18n from "../locale/I18n";
import Logo from "./Logo";
import {Button, Card, CardType} from "@surfnet/sds";
import {Card, CardType} from "@surfnet/sds";
import {isEmpty} from "../utils/Utils";
import {RoleMetaData} from "./RoleMetaData";
import {ReactComponent as SearchIcon} from "@surfnet/sds/icons/functional-icons/search.svg";
import {providerInfo} from "../utils/Manage";
import {MoreLessText} from "./MoreLessText";
import {RoleCard} from "./RoleCard";

export const User = ({user}) => {
const searchRef = useRef();

const [query, setQuery] = useState("");
const attribute = (index, name, isDate = false) => {
const attr = user[name];
return (
<InputField noInput={true}
key={index}
disabled={true}
value={attr ? (isDate ? dateFromEpoch(attr) : attr) : "-"}
name={I18n.t(`users.${name}`)}/>
)
}

useEffect(() => {
if (searchRef && searchRef.current) {
searchRef.current.focus();
}
}, [searchRef])
export const User = ({user, invitationRoles = []}) => {

const renderUserRole = (userRole, index) => {
const role = userRole.role;
const provider = providerInfo(user.providers.find(data => data.id === role.manageId));
const logo = provider.data.metaDataFields["logo:0:url"];
const children =
<div key={index} className={"user-role"}>
<Logo src={logo} alt={"provider"} className={"provider"}/>
<section className={"user-role-info"}>
<h3>{role.name}</h3>
<MoreLessText txt={role.description}/>
<RoleMetaData role={role} user={user} provider={provider}/>
</section>
<div className={"launch"}>
<Button txt={I18n.t("proceed.launch")} onClick={() => {
window.href = role.landingPage;
}}/>
</div>
</div>;
return (
<Card cardType={CardType.Big} children={children} key={index}/>
<RoleCard role={role} provider={provider} index={index}/>
);
}

const renderSearch = () => {
return (
<div className={`search standalone`}>
<div className={"sds--text-field sds--text-field--has-icon"}>
<div className="sds--text-field--shape">
<div className="sds--text-field--input-and-icon">
<input className={"sds--text-field--input"}
type="search"
onChange={e => setQuery(e.target.value)}
value={query}
ref={searchRef}
placeholder={I18n.t(`users.applicationsSearchPlaceHolder`)}/>
<span className="sds--text-field--icon">
<SearchIcon/>
</span>
</div>
</div>
</div>
</div>
)
};

const filterUserRole = userRole => {
if (isEmpty(query)) {
return true;
}
const queryLower = query.toLowerCase();
const role = userRole.role;
return role.name.toLowerCase().indexOf(queryLower) > -1 ||
role.description.toLowerCase().indexOf(queryLower) > -1
};

user.highestAuthority = highestAuthority(user);
const attributes = [];
const rolesToExclude = invitationRoles.map(invitationRole => invitationRole.role.id);
const filteredUserRoles = user.userRoles
.filter(filterUserRole).filter(userRole => user.superUser || userRole.authority === "GUEST");
.filter(userRole => user.superUser || userRole.authority === "GUEST")
.filter(userRole => !rolesToExclude.includes(userRole.role.id));
return (
<section className={"user"}>
{attributes.map((attr, index) => attribute(index, attr[0], attr[1]))}

<h3 className={"title span-row "}>{I18n.t("users.roles")}</h3>
<>
{isEmpty(user.userRoles) && <p className={"span-row "}>{I18n.t("users.noRolesInfo")}</p>}
{!isEmpty(user.userRoles) &&
<>
<div className="roles-search span-row">
<p >
{I18n.t(`users.rolesInfo`, {name: user.name})}
</p>
{renderSearch()}
</div>
{filteredUserRoles
.map((userRole, index) => renderUserRole(userRole, index))}
{filteredUserRoles.length === 0 &&
<p>{I18n.t(`users.noRolesFound`)}</p>}
</>}
</section>
</>
);
}
93 changes: 0 additions & 93 deletions welcome/src/components/User.scss
Original file line number Diff line number Diff line change
@@ -1,94 +1 @@
@import "../styles/vars";

section.user {
display: grid;
grid-template-columns: [first] 1fr [second] 1fr;
column-gap: 50px;

@media (max-width: $medium) {
grid-template-columns: [first] 1fr;
padding: 0 15px;
}

.span-row {
grid-column: 1 / -1;

}

p.span-row {
margin-bottom: 25px;
}

h3.title {
margin: 20px 0 10px 0;
}

.sds--card {
margin-bottom: 40px;

.launch {
margin-left: auto;

@media (max-width: 680px) {
margin: 20px auto 0 0;
}

}

}

.roles-search {
display: flex;
align-items: center;
padding: 0 0 20px 0;
min-height: 40px;
justify-content: space-between;

@media (max-width: $medium) {
flex-direction: column;
align-items: normal;
}

.search {
position: relative;
display: flex;
margin-left: auto;

@media (max-width: $medium) {
margin-left: 0;
margin-top: 20px;

.sds--text-field, .sds--text-field--shape {
width: 100%;
}
}

input[type=search] {
flex-grow: 2;
min-width: 360px;

@media (max-width: $medium) {
min-width: 0;
}
}

.sds--text-field--icon svg {
width: calc(15em / 16);
height: calc(15em / 16)
}

}

}

.user-role {
display: flex;

img, svg {
height: 56px;
width: auto;
margin-right: 35px;
border-radius: $br;
}
}
}
Loading

0 comments on commit fccc0ac

Please sign in to comment.