DEV;First working website with content
This commit is contained in:
parent
c254cd6273
commit
01d9d0d4a3
33 changed files with 6998 additions and 5403 deletions
43
src/components/AboutMe.tsx
Normal file
43
src/components/AboutMe.tsx
Normal file
|
@ -0,0 +1,43 @@
|
|||
import { Grid, GridCol } from "@treejs/components/Grid";
|
||||
import Image from "next/image";
|
||||
import { FC } from "react";
|
||||
import MyTitle from "../components/MyTitle";
|
||||
|
||||
const AboutMe: FC = () => {
|
||||
const age = Math.floor(
|
||||
((new Date() as any) - (new Date("1993-07-11") as any)) / 31557600000
|
||||
);
|
||||
|
||||
const work = Math.floor(
|
||||
((new Date() as any) - (new Date("2012-12-01") as any)) / 31557600000
|
||||
);
|
||||
|
||||
return (
|
||||
<Grid cols={6} className="mt-28">
|
||||
<GridCol colSpan={1} className="text-center">
|
||||
<Image
|
||||
src="/me.svg"
|
||||
alt="me"
|
||||
width={200}
|
||||
height={200}
|
||||
objectFit="contain"
|
||||
/>
|
||||
</GridCol>
|
||||
<GridCol colSpan={5} className="ml-10">
|
||||
<MyTitle left="Dobrý" right="Den" />
|
||||
<div className="mt-10">
|
||||
Jmenuji se <b>Roman Jaroš</b>.
|
||||
</div>
|
||||
<div className="mt-5">
|
||||
<p>
|
||||
Je mi <b>{age} let</b> a již <b>{work} let</b> se profesionálně
|
||||
věnuji vývoji a správě webových aplikací ☺️ .
|
||||
</p>
|
||||
<p>Od roku 2020 pracuji pouze na IČO.</p>
|
||||
</div>
|
||||
</GridCol>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
export default AboutMe;
|
74
src/components/Contact.tsx
Normal file
74
src/components/Contact.tsx
Normal file
|
@ -0,0 +1,74 @@
|
|||
import { Grid, GridCol } from "@treejs/components/Grid";
|
||||
import Image from "next/image";
|
||||
import { FC } from "react";
|
||||
import MyTitle from "./MyTitle";
|
||||
|
||||
const Contact: FC = () => {
|
||||
const age = Math.floor(
|
||||
((new Date() as any) - (new Date("1993-07-11") as any)) / 31557600000
|
||||
);
|
||||
|
||||
const work = Math.floor(
|
||||
((new Date() as any) - (new Date("2012-12-01") as any)) / 31557600000
|
||||
);
|
||||
|
||||
return (
|
||||
<Grid cols={6} className="mt-28">
|
||||
<GridCol colSpan={1} className="text-center">
|
||||
<Image
|
||||
src="/contact.svg"
|
||||
alt="contact"
|
||||
width={200}
|
||||
height={200}
|
||||
objectFit="contain"
|
||||
/>
|
||||
</GridCol>
|
||||
<GridCol colSpan={5} className="ml-10">
|
||||
<MyTitle left="Můj" right="Kontakt" />
|
||||
<div className="mt-10">
|
||||
<p className="mb-2">
|
||||
Obchodní nabídky prosím zasílejte{" "}
|
||||
<a href="mailto:sales@romanjaros.dev">sem</a>.
|
||||
</p>
|
||||
<p className="mb-2">
|
||||
Jiné dotazy prosím <a href="mailto:info@romanjaros.dev">sem</a>.
|
||||
</p>
|
||||
<p className="mt-4">
|
||||
<p>
|
||||
<a
|
||||
target="_blank"
|
||||
href="http://linkedin.com/in/roman-jaroš-16a687139"
|
||||
rel="noreferrer"
|
||||
>
|
||||
LinkedIn
|
||||
</a>
|
||||
</p>
|
||||
<p>
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://git.romanjaros.dev"
|
||||
rel="noreferrer"
|
||||
>
|
||||
Gitea (Git)
|
||||
</a>
|
||||
</p>
|
||||
</p>
|
||||
|
||||
<p className="mt-10">
|
||||
Pokud potřebujete zadat tiket na podporu, použijte prosím{" "}
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://helpdesk.romanjaros.dev/index.php?a=add"
|
||||
rel="noreferrer"
|
||||
>
|
||||
tento formulář
|
||||
</a>
|
||||
.
|
||||
</p>
|
||||
</div>
|
||||
</GridCol>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
export default Contact;
|
66
src/components/FullStory.tsx
Normal file
66
src/components/FullStory.tsx
Normal file
|
@ -0,0 +1,66 @@
|
|||
import { Grid, GridCol } from "@treejs/components/Grid";
|
||||
import Image from "next/image";
|
||||
import { isEmpty, isNil, map } from "ramda";
|
||||
import { FC, Fragment, useMemo } from "react";
|
||||
import { projects } from "../constants/projects";
|
||||
import MyTitle from "./MyTitle";
|
||||
|
||||
const FullStory: FC = () => {
|
||||
const projectsRender = useMemo(() => {
|
||||
let i = 0;
|
||||
return map((project) => {
|
||||
i++;
|
||||
return (
|
||||
<Fragment key={i}>
|
||||
<div className="border-timeline border-dotted border-l-4 pl-4 my-2">
|
||||
<p className="mb-2 font-bold">{project.name}</p>
|
||||
<p className="mb-2 font-thin">
|
||||
{project.dateFrom} - {project.dateTo}
|
||||
</p>
|
||||
<p>
|
||||
{project.desciption}
|
||||
{!isNil(project.link) ? (
|
||||
<>
|
||||
<a
|
||||
href={project.link}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="ml-1"
|
||||
>
|
||||
Odkaz na projekt
|
||||
</a>
|
||||
.
|
||||
</>
|
||||
) : null}
|
||||
</p>
|
||||
</div>
|
||||
{i === projects.length ? null : (
|
||||
<svg height="20" width="20" className="-ml-2">
|
||||
<circle cx="10" cy="10" r="9" fill="#B25068" />
|
||||
</svg>
|
||||
)}
|
||||
</Fragment>
|
||||
);
|
||||
}, projects);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Grid cols={6} className="mt-28">
|
||||
<GridCol colSpan={1} className="text-center">
|
||||
<Image
|
||||
src="/story.svg"
|
||||
alt="story"
|
||||
width={200}
|
||||
height={200}
|
||||
objectFit="contain"
|
||||
/>
|
||||
</GridCol>
|
||||
<GridCol colSpan={5} className="ml-10">
|
||||
<MyTitle left="Na" right="Projektech" />
|
||||
<div className="mt-10">{projectsRender}</div>
|
||||
</GridCol>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
export default FullStory;
|
25
src/components/MyTitle.tsx
Normal file
25
src/components/MyTitle.tsx
Normal file
|
@ -0,0 +1,25 @@
|
|||
import React, { FC } from "react";
|
||||
import cx from "classnames";
|
||||
|
||||
type IProps = {
|
||||
left: string;
|
||||
right: string;
|
||||
className?: string;
|
||||
};
|
||||
|
||||
const MyTitle: FC<IProps> = ({ left, right, className }) => {
|
||||
return (
|
||||
<div className={cx("mytitle", className)}>
|
||||
<span className="mytitle-left">
|
||||
{"<"}
|
||||
{left}
|
||||
</span>
|
||||
<span className="mytitle-right">
|
||||
{right}
|
||||
{" />"}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default MyTitle;
|
91
src/components/Services.tsx
Normal file
91
src/components/Services.tsx
Normal file
|
@ -0,0 +1,91 @@
|
|||
import { Grid, GridCol } from "@treejs/components/Grid";
|
||||
import Image from "next/image";
|
||||
import { FC, useMemo } from "react";
|
||||
import { skills } from "../constants/skills";
|
||||
import MyTitle from "./MyTitle";
|
||||
import { map } from "ramda";
|
||||
import { ISkill } from "../types/skills";
|
||||
|
||||
const Services: FC = () => {
|
||||
const renderSkills = useMemo(() => {
|
||||
let i = 0;
|
||||
return map((skillList: ISkill[]) => {
|
||||
let z = 0;
|
||||
const skills = map((skill: ISkill) => {
|
||||
z++;
|
||||
return (
|
||||
<li className="flex mb-1" key={z}>
|
||||
<svg height="10" width="10" className="mt-1.5 mr-2">
|
||||
<circle
|
||||
cx="5"
|
||||
cy="5"
|
||||
r="4"
|
||||
fill={skill.level === "full" ? "#90C8AC" : "#FFE7BF"}
|
||||
/>
|
||||
</svg>
|
||||
{skill.name}
|
||||
</li>
|
||||
);
|
||||
})(skillList);
|
||||
i++;
|
||||
return (
|
||||
<ol className="mt-2" key={i}>
|
||||
{skills}
|
||||
</ol>
|
||||
);
|
||||
})(skills);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Grid cols={6} className="mt-28">
|
||||
<GridCol colSpan={1} className="text-center">
|
||||
<Image
|
||||
src="/services.svg"
|
||||
alt="services"
|
||||
width={200}
|
||||
height={200}
|
||||
objectFit="contain"
|
||||
/>
|
||||
</GridCol>
|
||||
<GridCol colSpan={5} className="ml-10">
|
||||
<MyTitle left="Umím" right="Ovládat" />
|
||||
<Grid cols={4} className="mt-10">
|
||||
<GridCol>
|
||||
<b>Vývoj FE</b>
|
||||
{renderSkills[0]}
|
||||
</GridCol>
|
||||
<GridCol>
|
||||
<b>Vývoj BE</b>
|
||||
{renderSkills[1]}
|
||||
</GridCol>
|
||||
<GridCol>
|
||||
<b>Další</b>
|
||||
{renderSkills[2]}
|
||||
</GridCol>
|
||||
<GridCol>
|
||||
<b>Správa aplikací</b>
|
||||
{renderSkills[3]}
|
||||
</GridCol>
|
||||
</Grid>
|
||||
|
||||
<div className="flex mt-6 text-sm">
|
||||
<div className="flex">
|
||||
<svg height="10" width="10" className="mt-1.5 mr-2">
|
||||
<circle cx="5" cy="5" r="4" fill="#90C8AC" />
|
||||
</svg>
|
||||
používám na projektech
|
||||
</div>
|
||||
|
||||
<div className="flex ml-5">
|
||||
<svg height="10" width="10" className="mt-1.5 mr-2">
|
||||
<circle cx="5" cy="5" r="4" fill="#FFE7BF" />
|
||||
</svg>
|
||||
hraju si a učím se
|
||||
</div>
|
||||
</div>
|
||||
</GridCol>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
export default Services;
|
54
src/constants/projects.ts
Normal file
54
src/constants/projects.ts
Normal file
|
@ -0,0 +1,54 @@
|
|||
import { IProject } from "../types/projects";
|
||||
|
||||
export const projects: IProject[] = [
|
||||
{
|
||||
name: "doservislu.online",
|
||||
dateFrom: "březen 2020",
|
||||
dateTo: "současnost",
|
||||
link: "http://doservisu.online",
|
||||
desciption:
|
||||
"Tvorba frontendu veřejné aplikace pro možnost jednoduchého obsloužení zákazníka autoservisu. Z pohledu FE se jedná o sólo vývoj.",
|
||||
},
|
||||
{
|
||||
name: "Vývojář FE",
|
||||
dateFrom: "leden 2020",
|
||||
dateTo: "současnost",
|
||||
desciption:
|
||||
"Tvorba frontendu interní aplikace pro Generali Česká pojišťovna. Spolupráce na IČO. Stejný projekt jako když jsem pracoval jako zaměstnanec pod společností Softec s.r.o.. Rozšíření role o leadování ostatních FE vývojářů na projektu.",
|
||||
},
|
||||
{
|
||||
name: "treeJS",
|
||||
dateFrom: "březen 2019",
|
||||
dateTo: "současnost",
|
||||
link: "http://treejs.romanjaros.dev",
|
||||
desciption:
|
||||
"Mnou vytvářený framework pro jednodušší stavění nových aplikací. Jedná se o sadu React component, zjednodušení práce s formulářem nebo nadstavbu pro práci se styli.",
|
||||
},
|
||||
{
|
||||
name: "Vývojář FE",
|
||||
dateFrom: "říjen 2017",
|
||||
dateTo: "prosinec 2019",
|
||||
desciption:
|
||||
"Tvorba frontendu interní aplikace pro Českou pojišťovnu. Na projekt jsem byl dodán jako zaměstnanec společnosti Softec s.r.o. Má role na projektu bylo plnit zadání dle analýzi s týmem o velikost 8 lidí.",
|
||||
},
|
||||
{
|
||||
name: "Vývojář FE",
|
||||
dateFrom: "červen 2017",
|
||||
dateTo: "říjen 2017",
|
||||
desciption:
|
||||
"Tvorba frontentu interní aplikace pro ČMSS s týmem o velikosti 5 lidí.",
|
||||
},
|
||||
{
|
||||
name: "Vývojář FE pro Softec s.r.o.",
|
||||
dateFrom: "červen 2017",
|
||||
dateTo: "prosinec 2019",
|
||||
desciption: "Tvorba frontentu aplikací pro zákazníky.",
|
||||
},
|
||||
{
|
||||
name: "Fullstack vývojář v Dataprojekt s.r.o.",
|
||||
dateFrom: "prosinec 2012",
|
||||
dateTo: "květen 2017",
|
||||
desciption:
|
||||
"Vytvářel jsem webové aplikace přímo podle potřeb zákazníka. Od tvorby frontendu a beckendu, až po konzultace nebo instalace přímo u zákazníka.",
|
||||
},
|
||||
];
|
91
src/constants/skills.ts
Normal file
91
src/constants/skills.ts
Normal file
|
@ -0,0 +1,91 @@
|
|||
import { ISkill } from "../types/skills";
|
||||
|
||||
export const skills: ISkill[][] = [
|
||||
// Dev FE
|
||||
[
|
||||
{
|
||||
name: "React",
|
||||
level: "full",
|
||||
},
|
||||
{
|
||||
name: "Redux (i tookit)",
|
||||
level: "full",
|
||||
},
|
||||
{
|
||||
name: "Typescript",
|
||||
level: "full",
|
||||
},
|
||||
{
|
||||
name: "Ramda",
|
||||
level: "full",
|
||||
},
|
||||
{
|
||||
name: "Browser extensions",
|
||||
level: "full",
|
||||
},
|
||||
{
|
||||
name: "Tailwind",
|
||||
level: "full",
|
||||
},
|
||||
{
|
||||
name: "NextJS",
|
||||
level: "part",
|
||||
},
|
||||
],
|
||||
|
||||
// Dev BE
|
||||
[
|
||||
{
|
||||
name: "NodeJS",
|
||||
level: "full",
|
||||
},
|
||||
{
|
||||
name: "HapiJS",
|
||||
level: "full",
|
||||
},
|
||||
{
|
||||
name: "MongoDB",
|
||||
level: "part",
|
||||
},
|
||||
{
|
||||
name: "NextJS",
|
||||
level: "part",
|
||||
},
|
||||
],
|
||||
|
||||
// Others
|
||||
[
|
||||
{
|
||||
name: "GIT",
|
||||
level: "full",
|
||||
},
|
||||
{
|
||||
name: "NPM / Yarn",
|
||||
level: "full",
|
||||
},
|
||||
{
|
||||
name: "Jenkins (CI, CD)",
|
||||
level: "full",
|
||||
},
|
||||
{
|
||||
name: "SonarQube",
|
||||
level: "part",
|
||||
},
|
||||
],
|
||||
|
||||
// App maitenence
|
||||
[
|
||||
{
|
||||
name: "Docker",
|
||||
level: "full",
|
||||
},
|
||||
{
|
||||
name: "Caddy",
|
||||
level: "full",
|
||||
},
|
||||
{
|
||||
name: "Portainer",
|
||||
level: "part",
|
||||
},
|
||||
],
|
||||
];
|
38
src/pages/_app.tsx
Executable file
38
src/pages/_app.tsx
Executable file
|
@ -0,0 +1,38 @@
|
|||
import "../styles/globals.css";
|
||||
|
||||
import type { AppProps } from "next/app";
|
||||
import { useRouter } from "next/router";
|
||||
|
||||
import Skeleton from "@treejs/components/Skeleton";
|
||||
import store from "../redux/store";
|
||||
import { Provider } from "react-redux";
|
||||
|
||||
function PortolioApp({ Component, pageProps }: AppProps) {
|
||||
const router = useRouter();
|
||||
|
||||
return (
|
||||
<Provider store={store}>
|
||||
<Skeleton
|
||||
history={router}
|
||||
menuItems={{}}
|
||||
enabledMenu={{
|
||||
sidebar: false,
|
||||
user: false,
|
||||
}}
|
||||
components={{
|
||||
footer: (
|
||||
<div className="bg-slate-300 p-2 text-center">
|
||||
IČO 08738734 | DIČ CZ9307111946 | Jsem plátce DPH. Fyzická osoba
|
||||
zapsaná v živnostenském rejstříku v Karlových Varech (CZ0412) od
|
||||
02.12.2019. Tento web nepoužívá cookies.
|
||||
</div>
|
||||
),
|
||||
}}
|
||||
>
|
||||
<Component {...pageProps} />
|
||||
</Skeleton>
|
||||
</Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export default PortolioApp;
|
25
src/pages/index.tsx
Executable file
25
src/pages/index.tsx
Executable file
|
@ -0,0 +1,25 @@
|
|||
import type { NextPage } from "next";
|
||||
|
||||
import MyTitle from "../components/MyTitle";
|
||||
import AboutMe from "../components/AboutMe";
|
||||
import Services from "../components/Services";
|
||||
import Contact from "../components/Contact";
|
||||
import FullStory from "../components/FullStory";
|
||||
|
||||
const Home: NextPage = () => {
|
||||
return (
|
||||
<>
|
||||
<div className="mx-auto w-3/5">
|
||||
<div className="text-center mb-20">
|
||||
<MyTitle left="Roman" right="Developer" className="text-6xl" />
|
||||
</div>
|
||||
<AboutMe />
|
||||
<Services />
|
||||
<Contact />
|
||||
<FullStory />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Home;
|
25
src/redux/store.ts
Normal file
25
src/redux/store.ts
Normal file
|
@ -0,0 +1,25 @@
|
|||
import { combineReducers } from "redux";
|
||||
|
||||
import { MODAL_REDUCER_NAME } from "@treejs/components/Modal/constants";
|
||||
import modalReducer from "@treejs/components/Modal/reducer";
|
||||
import { TOASTER_REDUCER_NAME } from "@treejs/components/Toaster/constants";
|
||||
import toasterReducer from "@treejs/components/Toaster/reducer";
|
||||
import { ROOT_REDUCER_NAME } from "@treejs/constants/redux";
|
||||
import { configureStore } from "@reduxjs/toolkit";
|
||||
|
||||
type ITreejsReducer = {
|
||||
[MODAL_REDUCER_NAME]: typeof modalReducer;
|
||||
[TOASTER_REDUCER_NAME]: typeof toasterReducer;
|
||||
};
|
||||
|
||||
const store = configureStore({
|
||||
reducer: combineReducers({
|
||||
[ROOT_REDUCER_NAME]: combineReducers<ITreejsReducer>({
|
||||
[MODAL_REDUCER_NAME]: modalReducer,
|
||||
[TOASTER_REDUCER_NAME]: toasterReducer,
|
||||
}),
|
||||
}),
|
||||
devTools: process.env.NEXT_PUBLIC__IS_DEV === "true",
|
||||
});
|
||||
|
||||
export default store;
|
21
src/styles/globals.css
Executable file
21
src/styles/globals.css
Executable file
|
@ -0,0 +1,21 @@
|
|||
@import '@treejs/styles/global.css';
|
||||
|
||||
@import url('https://fonts.googleapis.com/css2?family=Quicksand:wght@300;400;500;700&display=swap');
|
||||
|
||||
body {
|
||||
@apply bg-white text-black text-sm;
|
||||
|
||||
font-family: 'Quicksand', sans-serif;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
:root {
|
||||
--color-primary: #28527a;
|
||||
--color-focus: theme('colors.gray.100');
|
||||
--color-active: #70a7db;
|
||||
--color-timeline: #F4E06D;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--color-active)
|
||||
}
|
21
src/styles/plugins/mytitle.js
Normal file
21
src/styles/plugins/mytitle.js
Normal file
|
@ -0,0 +1,21 @@
|
|||
const title = (theme) => ({
|
||||
".mytitle": {
|
||||
"font-size": "30px",
|
||||
"font-weight": "bold",
|
||||
"padding-top": "40px",
|
||||
|
||||
"&-left": {
|
||||
color: theme("colors.black"),
|
||||
},
|
||||
|
||||
"&-right": {
|
||||
color: theme("colors.primary.DEFAULT"),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = ({ addComponents, theme }) => {
|
||||
addComponents(title(theme));
|
||||
};
|
||||
|
||||
module.exports.title = title;
|
24
src/styles/tailwind.config.js
Normal file
24
src/styles/tailwind.config.js
Normal file
|
@ -0,0 +1,24 @@
|
|||
/** @type {import('tailwindcss').Config} */
|
||||
const path = require("path");
|
||||
|
||||
const plugin = require("tailwindcss/plugin");
|
||||
|
||||
module.exports = {
|
||||
presets: [require("@treejs/styles/tailwind.config")],
|
||||
content: [
|
||||
...require("@treejs/styles/tailwind.config").content,
|
||||
path.resolve(""), // path to place, where are used tailwind styles
|
||||
],
|
||||
safelist: require("@treejs/styles/tailwind.config").safelist,
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
timeline: "var(--color-timeline)",
|
||||
},
|
||||
},
|
||||
},
|
||||
variants: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [plugin(require("./plugins/mytitle"))],
|
||||
};
|
7
src/types/projects.ts
Normal file
7
src/types/projects.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
export interface IProject {
|
||||
name: string;
|
||||
dateFrom: string;
|
||||
dateTo: string;
|
||||
desciption: string;
|
||||
link?: string;
|
||||
}
|
4
src/types/skills.ts
Normal file
4
src/types/skills.ts
Normal file
|
@ -0,0 +1,4 @@
|
|||
export interface ISkill {
|
||||
name: string;
|
||||
level: "full" | "part";
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue