DEV;First working website with content

This commit is contained in:
Roman Jaroš 2022-07-05 22:06:40 +02:00
parent c254cd6273
commit 01d9d0d4a3
33 changed files with 6998 additions and 5403 deletions

View 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;

View 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;

View 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;

View 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;

View 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
View 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
View 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
View 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
View 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
View 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
View 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)
}

View 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;

View 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
View 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
View file

@ -0,0 +1,4 @@
export interface ISkill {
name: string;
level: "full" | "part";
}