feat: add fediverse links & improve tests and CSS

This commit is contained in:
Franek 2025-03-29 19:55:01 +01:00
parent 13a29c5744
commit ddac821a2d
10 changed files with 124 additions and 57 deletions

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg fill="#000000" width="800px" height="800px" viewBox="0 0 24 24" role="img" xmlns="http://www.w3.org/2000/svg"><title>Pleroma icon</title><path d="M6.36 0A1.868 1.868 0 004.49 1.868V24h5.964V0zm7.113 0v12h4.168a1.868 1.868 0 001.868-1.868V0zm0 18.036V24h4.168a1.868 1.868 0 001.868-1.868v-4.096Z"/></svg>

After

Width:  |  Height:  |  Size: 427 B

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg fill="#000000" width="800px" height="800px" viewBox="0 0 24 24" role="img" xmlns="http://www.w3.org/2000/svg"><title>PeerTube icon</title><path d="M3,0v12l9-6L3,0z M3,12v12l9-6L3,12z M12,6v12l9-6L12,6z"/></svg>

After

Width:  |  Height:  |  Size: 334 B

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<g>
<path fill="none" d="M0 0H24V24H0z"/>
<path d="M12 2c5.523 0 10 4.477 10 10s-4.477 10-10 10S2 17.523 2 12 6.477 2 12 2zm1.031 6.099h-2.624c-.988 0-1.789.776-1.789 1.733v6.748l2.595-2.471h1.818c1.713 0 3.101-1.345 3.101-3.005s-1.388-3.005-3.1-3.005z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 502 B

View File

@ -3,6 +3,7 @@ import { useTheme } from "./style/themes.tsx";
import About from "./sections/about.tsx";
import Tools from "./sections/tools.tsx";
import Links from "./sections/links.tsx";
const App: React.FC = () => {
const { theme } = useTheme();
@ -10,6 +11,7 @@ const App: React.FC = () => {
return <ThemeProvider theme={theme}>
<Container>
<About />
<Links />
<Tools />
</Container>
</ThemeProvider>;

View File

@ -5,7 +5,8 @@ export type Props = {
content?: string,
icon?: string,
link?: string,
primary?: boolean
primary?: boolean,
disabled?: boolean,
} & React.ComponentProps<'div'>;
const Button: React.FC<Props> = ({
@ -14,14 +15,15 @@ const Button: React.FC<Props> = ({
link,
primary,
children,
disabled = false,
...props
}) => {
const item = <ButtonStyled {...props} className={classes({ link, primary })}>
const item = <ButtonStyled {...props} className={classes({ link, primary, disabled })}>
{icon && <img src={icon} alt="Button icon" />}
{content || children}
</ButtonStyled>;
return link ? <a href={link} target="_blank" rel="noreferrer">{item}</a> : item;
return (link && !disabled) ? <a href={link} target="_blank" rel="noreferrer">{item}</a> : item;
}
const ButtonStyled = styled.div`
@ -47,6 +49,7 @@ const ButtonStyled = styled.div`
&:hover, &.primary {
background: ${({ theme }) => theme.text};
color: ${({ theme }) => theme.secondary};
box-shadow: 0 0 5px ${({ theme }) => theme.text};
img {
filter: ${({ theme }) => (theme.type === 'dark' ? 'none' : 'invert()')};
@ -54,13 +57,18 @@ const ButtonStyled = styled.div`
}
&.primary:hover {
background: ${({ theme }) => theme.secondary};
background: transparent;
color: ${({ theme }) => theme.text};
img {
filter: ${({ theme }) => (theme.type === 'dark' ? 'invert()' : 'none')};
}
}
&.disabled {
opacity: 0.9;
cursor: not-allowed;
}
`;
export default Button;

View File

@ -61,9 +61,6 @@ const About: React.FC = () => {
"Evanescence"
])}
<p>yeah I know, I listen to a broad spectrum of music</p>
<h2>Some links...</h2>
{asCardStack(LINKS)}
</>;
}
@ -71,38 +68,4 @@ const Heading = styled.h1`
font-family: "Pacifico", serif;
`;
const LINKS = [
{
content: "PGP",
icon: "/icons/pgp.svg",
link: "/pgp.asc",
primary: true
},
{
content: "Uptime of my services",
icon: "/icons/uptime.svg",
link: "https://health.sador.me/status/aio"
},
{
content: "E-mail",
icon: "/icons/email.svg",
link: "mailto:contact@sador.me?subject=[sador.me] ..."
},
{
content: "Gitea",
icon: "/icons/gitea.svg",
link: "https://git.sador.me"
},
{
content: "Matrix",
icon: "/icons/matrix.svg",
link: "https://matrix.to/#/@boss:sador.me"
},
{
content: "Instagram",
icon: "/icons/instagram.svg",
link: "https://instagram.com/sadorowo"
}
];
export default About;

71
src/sections/links.tsx Normal file
View File

@ -0,0 +1,71 @@
import styled from "styled-components";
import { asCardStack } from "../components/card-stack";
const Links: React.FC = () => {
return <>
<h2>Fediverse!</h2>
{asCardStack(FEDIVERSE_LINKS)}
<h2>Some links...</h2>
{asCardStack(LINKS)}
</>;
}
const Heading = styled.h1`
font-family: "Pacifico", serif;
`;
const FEDIVERSE_LINKS = [
{
content: "Akkoma",
icon: "/icons/fediverse/akkoma.svg",
link: "https://akkoma.sador.me"
},
{
content: "Pixelfed",
icon: "/icons/fediverse/pixelfed.svg",
link: "https://pix.sador.me"
},
{
content: "PeerTube",
icon: "/icons/fediverse/peertube.svg",
link: "https://tube.sador.me"
}
].map(link => Object.assign(link, { primary: true }));
const LINKS = [
{
content: "PGP",
icon: "/icons/pgp.svg",
link: "/pgp.asc",
primary: true
},
{
content: "Uptime of my services",
icon: "/icons/uptime.svg",
link: "https://health.sador.me/status/aio"
},
{
content: "E-mail",
icon: "/icons/email.svg",
link: "mailto:contact@sador.me?subject=[sador.me] ..."
},
{
content: "Gitea",
icon: "/icons/gitea.svg",
link: "https://git.sador.me"
},
{
content: "Matrix",
icon: "/icons/matrix.svg",
link: "https://matrix.to/#/@boss:sador.me"
},
{
content: "Instagram (deactivated)",
icon: "/icons/instagram.svg",
disabled: true,
link: "https://instagram.com/sadorowo"
}
];
export default Links;

View File

@ -1,8 +1,8 @@
import { render, screen } from "@testing-library/react";
import App from "../App";
import About from "../sections/about";
test("renders hello text", () => {
render(<App />);
render(<About />);
const helloElement = screen.getByText(/hello/i);
expect(helloElement).toBeInTheDocument();
@ -10,37 +10,30 @@ test("renders hello text", () => {
describe("all sub-sections of about are visible", () => {
test("'some facts about me'", () => {
render(<App />);
render(<About />);
const section = screen.getByText(/some facts about me/i);
expect(section).toBeInTheDocument();
})
test("'i can...'", () => {
render(<App />);
render(<About />);
const section = screen.getByText(/i can.../i);
expect(section).toBeInTheDocument();
})
test("'my favourite music genres'", () => {
render(<App />);
render(<About />);
const section = screen.getByText(/my favourite music genres/i);
expect(section).toBeInTheDocument();
})
test("'bands/singers'", () => {
render(<App />);
render(<About />);
const section = screen.getByText(/bands\/singers/i);
expect(section).toBeInTheDocument();
})
test("'some links'", () => {
render(<App />);
const section = screen.getByText(/some links/i);
expect(section).toBeInTheDocument();
})
})

18
src/tests/links.test.js Normal file
View File

@ -0,0 +1,18 @@
import { render, screen } from "@testing-library/react";
import Links from "../sections/links";
describe("all sub-sections of links are visible", () => {
test("'Fediverse!'", () => {
render(<Links />);
const section = screen.getByText(/Fediverse!/i);
expect(section).toBeInTheDocument();
})
test("'some links'", () => {
render(<Links />);
const section = screen.getByText(/some links/i);
expect(section).toBeInTheDocument();
})
})

View File

@ -1,16 +1,16 @@
import { render, screen } from "@testing-library/react";
import App from "../App";
import Tools from "../sections/tools";
describe("all sub-sections of tools are visible", () => {
test("'languages that i use'", () => {
render(<App />);
render(<Tools />);
const section = screen.getByText(/languages that i use/i);
expect(section).toBeInTheDocument();
})
test("'my favourite tools'", () => {
render(<App />);
render(<Tools />);
const section = screen.getByText(/my favourite tools/i);
expect(section).toBeInTheDocument();