Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 302d3aa4ab | |||
| 0d74fd01bc | |||
| ea5fed1bf9 | |||
| 373f01c9c2 | |||
| df24388d95 |
Binary file not shown.
|
After Width: | Height: | Size: 280 KiB |
@@ -3,7 +3,7 @@ import { defineMessages, useIntl } from "react-intl";
|
||||
|
||||
import { Content } from "../common/Content";
|
||||
import { Headline, SubHeadline } from "../common/Headline";
|
||||
import { Spacer } from "../common/Spacer";
|
||||
import PageBreakAvoid from "../common/PageBreakAvoid";
|
||||
import { Paragraph } from "../common/Text";
|
||||
|
||||
const messages = defineMessages({
|
||||
@@ -25,44 +25,69 @@ const approxCurrentYears = {
|
||||
),
|
||||
};
|
||||
|
||||
const yourpassSkills = [
|
||||
const investbaySkills = [
|
||||
"DevOps",
|
||||
"Front-End Development",
|
||||
"Back-end Operations",
|
||||
"Software Development",
|
||||
"Kubernetes",
|
||||
"TypeScript",
|
||||
"Go",
|
||||
"Linux",
|
||||
"Linux Server",
|
||||
"Google Cloud Platform (GCP)",
|
||||
"Amazon Web Services (AWS)",
|
||||
"Gitlab",
|
||||
"Terraform",
|
||||
"Cloud infrastructure",
|
||||
"Cloud Applications",
|
||||
"Software Development Life Cycle (SDLC)",
|
||||
"Linux System Administration",
|
||||
"Back-End Web Development",
|
||||
"Git",
|
||||
"Go",
|
||||
"TypeScript",
|
||||
"Nix",
|
||||
"GraphQL",
|
||||
"gRPC",
|
||||
"PostgreSQL",
|
||||
"Node.js",
|
||||
"React.js",
|
||||
];
|
||||
|
||||
const yourpassSkills = [
|
||||
"DevOps",
|
||||
"Software as a Service (SaaS)",
|
||||
"Cloud Infrastructure",
|
||||
"Kubernetes",
|
||||
"Back-end Operations",
|
||||
"Linux System Administration",
|
||||
"Amazon Web Services (AWS)",
|
||||
"Amazon EKS",
|
||||
"Terraform",
|
||||
"Go (Programming Language)",
|
||||
"gRPC",
|
||||
"Front-End Development",
|
||||
"React.js",
|
||||
"Node.js",
|
||||
"TypeScript",
|
||||
"Nix",
|
||||
"Software Development Life Cycle (SDLC)",
|
||||
"Software Development",
|
||||
"Git",
|
||||
"PostgreSQL",
|
||||
];
|
||||
|
||||
const yoursystemSkills = [
|
||||
"DevOps",
|
||||
"Front-End Development",
|
||||
"Docker Swarm",
|
||||
"Linux System Administration",
|
||||
"Back-end Operations",
|
||||
"Front-End Development",
|
||||
"Amazon Web Services (AWS)",
|
||||
"Bash",
|
||||
"Linux Server",
|
||||
"Terraform",
|
||||
"Cloud Infrastructure",
|
||||
"Cloud Applications",
|
||||
"Go (Programming Language)",
|
||||
"TypeScript",
|
||||
"Node.js",
|
||||
"Software Development Life Cycle (SDLC)",
|
||||
"Software Development",
|
||||
"Kubernetes",
|
||||
"TypeScript",
|
||||
"Linux",
|
||||
"Linux Server",
|
||||
"Linux System Administration",
|
||||
"Back-End Web Development",
|
||||
"GraphQL",
|
||||
"Git",
|
||||
"Node.js",
|
||||
"Vue.js",
|
||||
"PHP",
|
||||
"Bash",
|
||||
"Amazon Web Services (AWS)",
|
||||
"Amazon EKS",
|
||||
];
|
||||
|
||||
const Experience: React.FC = () => {
|
||||
@@ -70,6 +95,7 @@ const Experience: React.FC = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageBreakAvoid>
|
||||
<Headline level={3}>INVESTBAY s.r.o.</Headline>
|
||||
<SubHeadline level={4}>DevOps Architect</SubHeadline>
|
||||
<Content>
|
||||
@@ -87,10 +113,12 @@ const Experience: React.FC = () => {
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
<strong>{intl.formatMessage(messages.skills)}:</strong>{" "}
|
||||
{yourpassSkills.join(" · ")}
|
||||
{investbaySkills.join(" · ")}
|
||||
</Paragraph>
|
||||
</Content>
|
||||
</PageBreakAvoid>
|
||||
|
||||
<PageBreakAvoid>
|
||||
<Headline level={3}>YOUR PASS s.r.o.</Headline>
|
||||
<SubHeadline level={4}>DevOps Engineer</SubHeadline>
|
||||
<Content>
|
||||
@@ -110,9 +138,9 @@ const Experience: React.FC = () => {
|
||||
{yourpassSkills.join(" · ")}
|
||||
</Paragraph>
|
||||
</Content>
|
||||
</PageBreakAvoid>
|
||||
|
||||
<Spacer />
|
||||
|
||||
<PageBreakAvoid>
|
||||
<Headline level={3}>YOUR SYSTEM s.r.o.</Headline>
|
||||
<SubHeadline level={4}>SysOps</SubHeadline>
|
||||
|
||||
@@ -148,7 +176,9 @@ const Experience: React.FC = () => {
|
||||
{yoursystemSkills.join(" · ")}
|
||||
</Paragraph>
|
||||
</Content>
|
||||
</PageBreakAvoid>
|
||||
|
||||
<PageBreakAvoid>
|
||||
<Headline level={3}>Past experience</Headline>
|
||||
<SubHeadline level={4}>Developer</SubHeadline>
|
||||
|
||||
@@ -167,6 +197,7 @@ const Experience: React.FC = () => {
|
||||
})}
|
||||
</Paragraph>
|
||||
</Content>
|
||||
</PageBreakAvoid>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React from "react";
|
||||
|
||||
import PageBreakAvoid from "../common/PageBreakAvoid";
|
||||
import { Spacer } from "../common/Spacer";
|
||||
import { Paragraph } from "../common/Text";
|
||||
|
||||
@@ -11,13 +12,13 @@ const Skill: React.FC<React.PropsWithChildren<SkillProps>> = (props) => {
|
||||
const { children, title } = props;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<PageBreakAvoid>
|
||||
<strong>{title}</strong>
|
||||
<Spacer />
|
||||
{React.Children.map(children, (c) => (
|
||||
<Paragraph>{c}</Paragraph>
|
||||
))}
|
||||
</div>
|
||||
</PageBreakAvoid>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import { useIntl } from "react-intl";
|
||||
|
||||
import { SubHeadline } from "../common/Headline";
|
||||
import { List, ListItem } from "../common/List";
|
||||
import PageBreakAvoid from "../common/PageBreakAvoid";
|
||||
import { Spacer } from "../common/Spacer";
|
||||
import { Paragraph } from "../common/Text";
|
||||
import Skill from "./Skill";
|
||||
@@ -69,12 +70,12 @@ const Skills: React.FC = () => {
|
||||
{intl.formatMessage({
|
||||
defaultMessage:
|
||||
"Deep knowledge of backend operations, mostly supporting web based applications using various technologies, programming languages and frameworks.",
|
||||
id: "Skills.backendDevelopment",
|
||||
id: "Skills.backendDevelopmentSum1",
|
||||
})}
|
||||
{intl.formatMessage({
|
||||
defaultMessage:
|
||||
"In recent years, the main focus was on Go to write tooling and backend services.",
|
||||
id: "Skills.backendDevelopment",
|
||||
id: "Skills.backendDevelopmentSum2",
|
||||
})}
|
||||
</Skill>
|
||||
<Skill title="Infrastructure operations">
|
||||
@@ -99,8 +100,10 @@ const Skills: React.FC = () => {
|
||||
<List>
|
||||
{otherSkills.map((s) => (
|
||||
<ListItem key={s.title}>
|
||||
<PageBreakAvoid>
|
||||
<strong>{s.title}</strong>
|
||||
{s.description && `: ${s.description}`}
|
||||
</PageBreakAvoid>
|
||||
</ListItem>
|
||||
))}
|
||||
</List>
|
||||
|
||||
@@ -38,8 +38,7 @@ const Summary: React.FC = () => {
|
||||
knowledge of KNX systems.
|
||||
</Paragraph>
|
||||
<Caption>
|
||||
-- This summary was graciously generated by an AI and then rewritten and
|
||||
adjusted by a human
|
||||
-- Summary graciously generated by an AI and curated by human
|
||||
</Caption>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -23,7 +23,7 @@ const Nav = styled("nav")({
|
||||
flex: "0 0 280px",
|
||||
width: 280,
|
||||
minHeight: "100%",
|
||||
padding: "3rem 2rem 2rem",
|
||||
padding: "0 2rem 2rem",
|
||||
|
||||
[hideNavigationMQ]: {
|
||||
display: "none",
|
||||
|
||||
@@ -1,27 +1,32 @@
|
||||
import styled from "@emotion/styled";
|
||||
import React, { useEffect, useRef } from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
|
||||
import profile from "../../assets/profile.jpg";
|
||||
import { CONTACT_EMAIL, CONTACT_PHONE } from "../../config/environment";
|
||||
import { Contact } from "../common/Contact";
|
||||
import { List, ListItem } from "../common/List";
|
||||
import { Spacer } from "../common/Spacer";
|
||||
import NavigationHeadline from "./NavigationHeadline";
|
||||
|
||||
const getTopOffset = (input: HTMLElement) => {
|
||||
let el: HTMLElement | Element | null = input;
|
||||
let o = 0;
|
||||
do {
|
||||
if (!(el instanceof HTMLElement)) {
|
||||
break;
|
||||
}
|
||||
const ProfileImg = styled("img")({
|
||||
borderRadius: "50%",
|
||||
border: "2px solid white",
|
||||
display: "block",
|
||||
margin: "0 auto",
|
||||
maxWidth: "100%",
|
||||
width: 150,
|
||||
});
|
||||
|
||||
if (!isNaN(el.offsetTop)) {
|
||||
o += el.offsetTop;
|
||||
}
|
||||
} while ((el = el.offsetParent));
|
||||
const navBottomPadding = 50;
|
||||
|
||||
return o;
|
||||
};
|
||||
const TopSpacer = styled("div")({
|
||||
height: 40,
|
||||
});
|
||||
|
||||
const StickyWrapper = styled("div")({
|
||||
position: "sticky",
|
||||
});
|
||||
|
||||
const MainNavigation: React.FC = () => {
|
||||
const intl = useIntl();
|
||||
@@ -34,49 +39,30 @@ const MainNavigation: React.FC = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
d.style.top = "0px";
|
||||
|
||||
let { height } = d.getBoundingClientRect();
|
||||
|
||||
const listener = () => {
|
||||
const visibleArea = navBottomPadding + height;
|
||||
if (window.innerHeight > visibleArea) {
|
||||
d.style.top = "0px";
|
||||
} else {
|
||||
d.style.top = `${window.innerHeight - visibleArea}px`;
|
||||
}
|
||||
};
|
||||
|
||||
const ro = new ResizeObserver((entries) => {
|
||||
if (entries[0]) {
|
||||
height = entries[0].contentRect.height;
|
||||
listener();
|
||||
}
|
||||
});
|
||||
|
||||
ro.observe(d);
|
||||
|
||||
let scrollPrev = window.scrollY;
|
||||
|
||||
const listener = () => {
|
||||
const down = scrollPrev < window.scrollY;
|
||||
scrollPrev = window.scrollY;
|
||||
const top = getTopOffset(d);
|
||||
|
||||
if (window.innerHeight > height) {
|
||||
d.style.marginTop = `${Math.max(window.scrollY, 0)}px`;
|
||||
return;
|
||||
}
|
||||
|
||||
if (down) {
|
||||
const delta = top + height;
|
||||
const wDelta = window.scrollY + window.innerHeight;
|
||||
|
||||
const diff = wDelta - delta;
|
||||
if (diff > 0) {
|
||||
const sizeDelta = Math.min(window.innerHeight - height, 0);
|
||||
d.style.marginTop = `${Math.max(top + diff + sizeDelta, 0)}px`;
|
||||
}
|
||||
} else {
|
||||
const delta = top;
|
||||
const wDelta = window.scrollY;
|
||||
|
||||
const diff = wDelta - delta;
|
||||
if (diff < 0) {
|
||||
d.style.marginTop = `${Math.max(top + diff, 0)}px`;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener("scroll", listener);
|
||||
window.addEventListener("scroll", listener, { passive: true });
|
||||
window.addEventListener("resize", listener, { passive: true });
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("scroll", listener);
|
||||
@@ -85,7 +71,10 @@ const MainNavigation: React.FC = () => {
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div ref={ref}>
|
||||
<StickyWrapper ref={ref}>
|
||||
<TopSpacer />
|
||||
<ProfileImg src={profile} alt="profile picture" />
|
||||
|
||||
<NavigationHeadline>
|
||||
{intl.formatMessage({
|
||||
defaultMessage: "Contact",
|
||||
@@ -149,7 +138,7 @@ const MainNavigation: React.FC = () => {
|
||||
id: "Navigation.experience",
|
||||
})}
|
||||
</NavigationHeadline>
|
||||
</div>
|
||||
</StickyWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import styled from "@emotion/styled";
|
||||
|
||||
const PageBreakAvoid = styled("div")({
|
||||
pageBreakInside: "avoid",
|
||||
});
|
||||
|
||||
export default PageBreakAvoid;
|
||||
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"target": "ES2020",
|
||||
"useDefineForClassFields": true,
|
||||
"lib": ["ES2021", "DOM", "DOM.Iterable"],
|
||||
"module": "ESNext",
|
||||
"skipLibCheck": true,
|
||||
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "Bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"moduleDetection": "force",
|
||||
"noEmit": true,
|
||||
"jsx": "react-jsx",
|
||||
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUncheckedSideEffectImports": true
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
@@ -1,23 +1,7 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"useDefineForClassFields": true,
|
||||
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
||||
"module": "ESNext",
|
||||
"skipLibCheck": true,
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
"jsx": "react",
|
||||
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
"include": ["src"]
|
||||
"files": [],
|
||||
"references": [
|
||||
{ "path": "./tsconfig.app.json" },
|
||||
{ "path": "./tsconfig.node.json" }
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"target": "ES2022",
|
||||
"lib": ["ES2023"],
|
||||
"module": "ESNext",
|
||||
"skipLibCheck": true,
|
||||
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "Bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"isolatedModules": true,
|
||||
"moduleDetection": "force",
|
||||
"noEmit": true,
|
||||
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUncheckedSideEffectImports": true
|
||||
},
|
||||
"include": ["vite.config.ts"]
|
||||
}
|
||||
@@ -7,10 +7,9 @@ import (
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"go.c3c.cz/cv/app/server/internal/version"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
|
||||
"go.c3c.cz/cv/app/server/internal/version"
|
||||
)
|
||||
|
||||
type FrontendConfigDef struct {
|
||||
|
||||
@@ -14,10 +14,9 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
||||
"go.c3c.cz/cv/app/server/internal/files"
|
||||
"go.c3c.cz/cv/app/server/internal/version"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type handler struct {
|
||||
@@ -67,7 +66,6 @@ func (h *handler) serveFile(w http.ResponseWriter, r *http.Request, modtime time
|
||||
gw.Reset(io.Discard)
|
||||
}
|
||||
err = gw.Close()
|
||||
|
||||
if err != nil {
|
||||
h.logger.Warn("Could not close gzip writer", zap.Error(err))
|
||||
return
|
||||
|
||||
@@ -10,9 +10,8 @@ import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
||||
"go.c3c.cz/cv/app/server/internal/files"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
+1
-3
@@ -8,12 +8,11 @@ import (
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
||||
"go.c3c.cz/cv/app/server/internal/config"
|
||||
"go.c3c.cz/cv/app/server/internal/httpserver"
|
||||
"go.c3c.cz/cv/app/server/internal/pprofserver"
|
||||
"go.c3c.cz/cv/app/server/internal/version"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -33,7 +32,6 @@ func main() {
|
||||
var err error
|
||||
|
||||
logger, err = config.LoggerConfig.Build()
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(notice)
|
||||
fmt.Println(version.CommitTime.Format("Committed at 2006/01/02 15:04:05 MST"))
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
{
|
||||
formatter = nix.formatter;
|
||||
|
||||
packages = nix.lib.forAllSystems (pkgs:
|
||||
packages = nix.lib.forAllSystems (
|
||||
pkgs:
|
||||
let
|
||||
version = "rev-${self.shortRev or self.dirtyShortRev}";
|
||||
package = builtins.fromJSON (builtins.readFile ./app/frontend/package.json);
|
||||
@@ -42,7 +43,9 @@
|
||||
"-w"
|
||||
"-X gopkg.c3c.cz/cv/app/server/internal/version.Tag=${version}"
|
||||
"-X gopkg.c3c.cz/cv/app/server/internal/version.Commit=${self.rev or self.dirtyRev}"
|
||||
"-X gopkg.c3c.cz/cv/app/server/internal/version.commitTime=${builtins.toString (self.lastModified or 0)}"
|
||||
"-X gopkg.c3c.cz/cv/app/server/internal/version.commitTime=${
|
||||
builtins.toString (self.lastModified or 0)
|
||||
}"
|
||||
];
|
||||
vendorHash = "sha256-44xcyVk5KcurQLkVJv1MeAj+Pfcu53664pvVgHdyv3E=";
|
||||
};
|
||||
@@ -70,6 +73,19 @@
|
||||
];
|
||||
|
||||
commands = [
|
||||
{
|
||||
# Override golangci-lint for vscode, because the extension incorrectly assumes usage of global binaries is preferred
|
||||
name = "golangci-lint";
|
||||
command = ''
|
||||
CMD=''${1:-}
|
||||
if [[ "$CMD" == "run" ]]; then
|
||||
shift
|
||||
${pkgs.golangci-lint}/bin/golangci-lint run --config ${nix.lib.golangci-config-file} $@
|
||||
else
|
||||
${pkgs.golangci-lint}/bin/golangci-lint $@
|
||||
fi
|
||||
'';
|
||||
}
|
||||
{
|
||||
name = "lint";
|
||||
help = "run linters";
|
||||
@@ -84,7 +100,7 @@
|
||||
help = "format & fix found issues";
|
||||
command = ''
|
||||
${nix.lib.cd_root}
|
||||
nix fmt .
|
||||
nix fmt ./*.nix
|
||||
${pkgs.golangci-lint}/bin/golangci-lint run --sort-results --out-format tab --config ${nix.lib.golangci-config-file} --fix --issues-exit-code 0 ./...
|
||||
npm --prefix app/frontend run fix
|
||||
'';
|
||||
|
||||
Reference in New Issue
Block a user