mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-09 15:05:44 +01:00
improved footer layout
This commit is contained in:
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 70 KiB |
BIN
scm-ui/ui-components/src/__resources__/marvin.jpg
Normal file
BIN
scm-ui/ui-components/src/__resources__/marvin.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
@@ -5,8 +5,11 @@ import { Binder, BinderContext } from "@scm-manager/ui-extensions";
|
|||||||
import { Me } from "@scm-manager/ui-types";
|
import { Me } from "@scm-manager/ui-types";
|
||||||
import { EXTENSION_POINT } from "../avatar/Avatar";
|
import { EXTENSION_POINT } from "../avatar/Avatar";
|
||||||
// @ts-ignore ignore unknown png
|
// @ts-ignore ignore unknown png
|
||||||
import avatar from "../__resources__/avatar.png";
|
import hitchhiker from "../__resources__/hitchhiker.png";
|
||||||
|
// @ts-ignore ignore unknown jpg
|
||||||
|
import marvin from "../__resources__/marvin.jpg";
|
||||||
import NavLink from "../navigation/NavLink";
|
import NavLink from "../navigation/NavLink";
|
||||||
|
import ExternalLink from "../navigation/ExternalLink";
|
||||||
|
|
||||||
const trillian: Me = {
|
const trillian: Me = {
|
||||||
name: "trillian",
|
name: "trillian",
|
||||||
@@ -16,15 +19,16 @@ const trillian: Me = {
|
|||||||
_links: {}
|
_links: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
const bindAvatar = (binder: Binder) => {
|
const bindAvatar = (binder: Binder, avatar: string) => {
|
||||||
binder.bind(EXTENSION_POINT, () => {
|
binder.bind(EXTENSION_POINT, () => {
|
||||||
return avatar;
|
return avatar;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const bindLinks = (binder: Binder) => {
|
const bindLinks = (binder: Binder) => {
|
||||||
binder.bind("footer.links", () => <a href="#">REST API</a>);
|
binder.bind("footer.information", () => <ExternalLink to="#" label="REST API" />);
|
||||||
binder.bind("footer.links", () => <a href="#">CLI</a>);
|
binder.bind("footer.information", () => <ExternalLink to="#" label="CLI" />);
|
||||||
|
binder.bind("footer.support", () => <ExternalLink to="#" label="FAQ" />);
|
||||||
binder.bind("profile.setting", () => <NavLink label="Authorized Keys" to="#" />);
|
binder.bind("profile.setting", () => <NavLink label="Authorized Keys" to="#" />);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -42,7 +46,7 @@ storiesOf("Layout|Footer", module)
|
|||||||
})
|
})
|
||||||
.add("With Avatar", () => {
|
.add("With Avatar", () => {
|
||||||
const binder = new Binder("avatar-story");
|
const binder = new Binder("avatar-story");
|
||||||
bindAvatar(binder);
|
bindAvatar(binder, hitchhiker);
|
||||||
return withBinder(binder);
|
return withBinder(binder);
|
||||||
})
|
})
|
||||||
.add("With Plugin Links", () => {
|
.add("With Plugin Links", () => {
|
||||||
@@ -52,7 +56,7 @@ storiesOf("Layout|Footer", module)
|
|||||||
})
|
})
|
||||||
.add("Full", () => {
|
.add("Full", () => {
|
||||||
const binder = new Binder("link-story");
|
const binder = new Binder("link-story");
|
||||||
bindAvatar(binder);
|
bindAvatar(binder, marvin);
|
||||||
bindLinks(binder);
|
bindLinks(binder);
|
||||||
return withBinder(binder);
|
return withBinder(binder);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import NavLink from "../navigation/NavLink";
|
|||||||
import FooterSection from "./FooterSection";
|
import FooterSection from "./FooterSection";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import { EXTENSION_POINT } from "../avatar/Avatar";
|
import { EXTENSION_POINT } from "../avatar/Avatar";
|
||||||
|
import ExternalLink from "../navigation/ExternalLink";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
me?: Me;
|
me?: Me;
|
||||||
@@ -50,10 +52,12 @@ const TitleWithAvatar: FC<TitleWithAvatarProps> = ({ me }) => (
|
|||||||
);
|
);
|
||||||
|
|
||||||
const Footer: FC<Props> = ({ me, version, links }) => {
|
const Footer: FC<Props> = ({ me, version, links }) => {
|
||||||
|
const [t] = useTranslation("commons");
|
||||||
const binder = useBinder();
|
const binder = useBinder();
|
||||||
if (!me) {
|
if (!me) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const extensionProps = { me, url: "/me", links };
|
const extensionProps = { me, url: "/me", links };
|
||||||
let meSectionTile;
|
let meSectionTile;
|
||||||
if (binder.hasExtension(EXTENSION_POINT)) {
|
if (binder.hasExtension(EXTENSION_POINT)) {
|
||||||
@@ -67,24 +71,18 @@ const Footer: FC<Props> = ({ me, version, links }) => {
|
|||||||
<section className="section container">
|
<section className="section container">
|
||||||
<div className="columns is-size-7">
|
<div className="columns is-size-7">
|
||||||
<FooterSection title={meSectionTile}>
|
<FooterSection title={meSectionTile}>
|
||||||
<NavLink to="#" label="Profile" />
|
<NavLink to="/me" label={t("footer.user.profile")} />
|
||||||
<NavLink to="#" label="Change Password" />
|
<NavLink to="/me/settings/password" label={t("profile.changePasswordNavLink")} />
|
||||||
<ExtensionPoint name="profile.setting" props={extensionProps} renderAll={true} />
|
<ExtensionPoint name="profile.setting" props={extensionProps} renderAll={true} />
|
||||||
</FooterSection>
|
</FooterSection>
|
||||||
<FooterSection title={<TitleWithIcon title="Information" icon="info-circle" />}>
|
<FooterSection title={<TitleWithIcon title={t("footer.information.title")} icon="info-circle" />}>
|
||||||
<a href="https://www.scm-manager.org/" target="_blank">
|
<ExternalLink to="https://www.scm-manager.org/" label={`SCM-Manager ${version}`} />
|
||||||
SCM-Manager {version}
|
<ExtensionPoint name="footer.information" props={extensionProps} renderAll={true} />
|
||||||
</a>
|
|
||||||
<ExtensionPoint name="footer.links" props={extensionProps} renderAll={true} />
|
|
||||||
</FooterSection>
|
</FooterSection>
|
||||||
<FooterSection title={<TitleWithIcon title="About" icon="external-link-alt" />}>
|
<FooterSection title={<TitleWithIcon title={t("footer.support.title")} icon="life-ring" />}>
|
||||||
<a href="https://www.scm-manager.org/" target="_blank">
|
<ExternalLink to="https://www.scm-manager.org/support/" label={t("footer.support.community")} />
|
||||||
Learn more
|
<ExternalLink to="https://cloudogu.com/en/scm-manager-enterprise/" label={t("footer.support.enterprise")} />
|
||||||
</a>
|
<ExtensionPoint name="footer.support" props={extensionProps} renderAll={true} />
|
||||||
<a target="_blank" href="https://cloudogu.com/">
|
|
||||||
Powered by Cloudogu
|
|
||||||
</a>
|
|
||||||
<ExtensionPoint name="footer.links" props={extensionProps} renderAll={true} />
|
|
||||||
</FooterSection>
|
</FooterSection>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@@ -18,11 +18,7 @@ const FooterSection: FC<Props> = ({ title, children }) => {
|
|||||||
return (
|
return (
|
||||||
<section className="column is-one-third">
|
<section className="column is-one-third">
|
||||||
<Title>{title}</Title>
|
<Title>{title}</Title>
|
||||||
<Menu>
|
<Menu>{children}</Menu>
|
||||||
{React.Children.map(children, (child, index) => (
|
|
||||||
<li key={index}>{child}</li>
|
|
||||||
))}
|
|
||||||
</Menu>
|
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
30
scm-ui/ui-components/src/navigation/ExternalLink.tsx
Normal file
30
scm-ui/ui-components/src/navigation/ExternalLink.tsx
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import React, { FC } from "react";
|
||||||
|
import classNames from "classnames";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
to: string;
|
||||||
|
icon?: string;
|
||||||
|
label: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const ExternalLink: FC<Props> = ({ to, icon, label }) => {
|
||||||
|
let showIcon;
|
||||||
|
if (icon) {
|
||||||
|
showIcon = (
|
||||||
|
<>
|
||||||
|
<i className={classNames(icon, "fa-fw")} />{" "}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<li>
|
||||||
|
<a target="_blank" href={to}>
|
||||||
|
{showIcon}
|
||||||
|
{label}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ExternalLink;
|
||||||
@@ -69,8 +69,12 @@ hr.header-with-actions {
|
|||||||
|
|
||||||
footer.footer {
|
footer.footer {
|
||||||
//height: 100px;
|
//height: 100px;
|
||||||
background-color: whitesmoke;
|
background-color: $white-ter;
|
||||||
padding: inherit;
|
padding: inherit;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: darken($blue, 15%);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. Import the rest of Bulma
|
// 6. Import the rest of Bulma
|
||||||
|
|||||||
@@ -86,5 +86,18 @@
|
|||||||
"passwordConfirmFailed": "Passwörter müssen identisch sein!",
|
"passwordConfirmFailed": "Passwörter müssen identisch sein!",
|
||||||
"submit": "Speichern",
|
"submit": "Speichern",
|
||||||
"changedSuccessfully": "Passwort erfolgreich geändert!"
|
"changedSuccessfully": "Passwort erfolgreich geändert!"
|
||||||
|
},
|
||||||
|
"footer": {
|
||||||
|
"user": {
|
||||||
|
"profile": "Profil"
|
||||||
|
},
|
||||||
|
"information": {
|
||||||
|
"title": "Information"
|
||||||
|
},
|
||||||
|
"support": {
|
||||||
|
"title": "Support",
|
||||||
|
"community": "Community",
|
||||||
|
"enterprise": "Enterprise"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,5 +87,18 @@
|
|||||||
"passwordConfirmFailed": "Passwords have to be identical",
|
"passwordConfirmFailed": "Passwords have to be identical",
|
||||||
"submit": "Submit",
|
"submit": "Submit",
|
||||||
"changedSuccessfully": "Password changed successfully"
|
"changedSuccessfully": "Password changed successfully"
|
||||||
|
},
|
||||||
|
"footer": {
|
||||||
|
"user": {
|
||||||
|
"profile": "Profile"
|
||||||
|
},
|
||||||
|
"information": {
|
||||||
|
"title": "Information"
|
||||||
|
},
|
||||||
|
"support": {
|
||||||
|
"title": "Support",
|
||||||
|
"community": "Community",
|
||||||
|
"enterprise": "Enterprise"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user