diff --git a/src/configs/education.json b/src/configs/education.json index 5634de6..cea085c 100644 --- a/src/configs/education.json +++ b/src/configs/education.json @@ -14,19 +14,30 @@ "Automata and Grammars", { "Database Systems": [ - "be" + "be", + "fs" ] }, "Computer Network Services", - "Seminar on Functional Programming", + { + "Seminar on Functional Programming": [ + "fe", + "chain", + "data", + "func" + ] + }, { "Java": [ - "be" + "be", + "fs" ] }, { "C++ programming": [ - "be" + "be", + "fs", + "game" ] }, { @@ -36,7 +47,8 @@ }, { "Generative Design Programming": [ - "fe" + "fe", + "web" ] }, { @@ -55,7 +67,10 @@ "Followed up by learning the basics of microservice architecture and Spring Boot" ], "relevancy": [ - "be" + "be", + "fs", + "chain", + "game" ] } } diff --git a/src/configs/education.yaml b/src/configs/education.yaml index 071fa43..ebc1ad2 100644 --- a/src/configs/education.yaml +++ b/src/configs/education.yaml @@ -11,13 +11,13 @@ Masaryk University: - Algorithms and Data Structures I - Computability and Complexity - Automata and Grammars - - Database Systems: [be] + - Database Systems: [be, fs] - Computer Network Services - - Seminar on Functional Programming - - Java: [be] - - C++ programming: [be] + - Seminar on Functional Programming: [fe, chain, data, func] + - Java: [be, fs] + - C++ programming: [be, fs, game] - Principles of Low-Level Programming: [be] - - Generative Design Programming: [fe] + - Generative Design Programming: [fe, web] - Game Design I: [game] Hyperskill.org/JetBrains Academy: @@ -27,4 +27,4 @@ Hyperskill.org/JetBrains Academy: - Gained solid understanding of Kotlin through quizzes, a practice project, and reading through the language documentation - Refreshed knowledge of Object Oriented principles - Followed up by learning the basics of microservice architecture and Spring Boot - relevancy: [be] + relevancy: [be, fs, chain, game] diff --git a/src/configs/projects.json b/src/configs/projects.json index b7d1c60..1802f9d 100644 --- a/src/configs/projects.json +++ b/src/configs/projects.json @@ -1,8 +1,12 @@ { "Pie-Hub": { "relevancy": [ + "all", "fe", - "be" + "be", + "fs", + "data", + "maker" ], "date": { "start": 2021 @@ -26,6 +30,13 @@ ] }, "Rychly Portfolio": { + "relevancy": [ + "all", + "fe", + "fs", + "data", + "func" + ], "repo": "https://github.com/honzaflash/rychly-portfolio", "link": "https://honzaflash.github.io/rychly-portfolio/", "tech": [ @@ -48,12 +59,9 @@ ] }, "Game Development in Haskell": { + "relevancy": "any", "repo": "https://github.com/honzaflash/ba-thesis", "link": "https://is.muni.cz/th/zedur/?lang=en", - "relevancy": [ - "fe", - "be" - ], "date": { "finish": "May 2021" }, @@ -73,10 +81,11 @@ }, "Dynamics of Local Church": { "relevancy": [ + "all", "be", "fs", "data", - "fe" + "func" ], "date": { "finish": "May 2020" @@ -95,6 +104,14 @@ ] }, "pure-asteroids": { + "relevancy": [ + "all", + "be", + "fs", + "chain", + "data", + "func" + ], "repo": "https://github.com/honzaflash/ba-thesis/tree/main/pure-asteroids", "date": { "finish": "Apr 2021" @@ -110,6 +127,13 @@ ] }, "hAsteroids": { + "relevancy": [ + "all", + "be", + "fs", + "chain", + "func" + ], "repo": "https://github.com/honzaflash/ba-thesis/tree/main/hAsteroids", "date": { "finish": "Apr 2021" @@ -125,6 +149,10 @@ ] }, "3D printing": { + "relevancy": [ + "all", + "maker" + ], "link": "https://www.printables.com/@hFlash_383528/models", "date": { "start": "Nov 2022", diff --git a/src/configs/projects.yaml b/src/configs/projects.yaml index 4b3afd6..96ebcdd 100644 --- a/src/configs/projects.yaml +++ b/src/configs/projects.yaml @@ -1,5 +1,5 @@ Pie-Hub: - relevancy: [fe, be] + relevancy: [all, fe, be, fs, data, maker] date: start: 2021 tech: @@ -19,6 +19,7 @@ Pie-Hub: - Wired up a relay board to control appliances through software Rychly Portfolio: + relevancy: [all, fe, fs, data, func] repo: https://github.com/honzaflash/rychly-portfolio link: https://honzaflash.github.io/rychly-portfolio/ tech: @@ -38,9 +39,9 @@ Rychly Portfolio: - Simple bold design with accents in my favorite color Game Development in Haskell: + relevancy: any repo: https://github.com/honzaflash/ba-thesis link: https://is.muni.cz/th/zedur/?lang=en - relevancy: [fe, be] date: finish: May 2021 tech: @@ -56,7 +57,7 @@ Game Development in Haskell: - Wrote two versions of Asteroids in Haskell and compared them against each other and against a C++ implementation Dynamics of Local Church: - relevancy: [be, fs, data, fe] # 'fe' is there only temporarily because of a submitted application with a front-end link + relevancy: [all, be, fs, data, func] # 'fe' is there only temporarily because of a submitted application with a front-end link date: finish: May 2020 tech: @@ -71,6 +72,7 @@ Dynamics of Local Church: - Part of the assignment was a 7 page report and analysis of the behavior with visualization pure-asteroids: + relevancy: [all, be, fs, chain, data, func] repo: https://github.com/honzaflash/ba-thesis/tree/main/pure-asteroids date: finish: Apr 2021 @@ -83,6 +85,7 @@ pure-asteroids: - Keeps game entites compartmentalized allowing for **parallel processing** of world events hAsteroids: + relevancy: [all, be, fs, chain, func] repo: https://github.com/honzaflash/ba-thesis/tree/main/hAsteroids date: finish: Apr 2021 @@ -95,6 +98,7 @@ hAsteroids: - Game in Haskell built using the apecs library 3D printing: + relevancy: [all, maker] link: https://www.printables.com/@hFlash_383528/models date: start: Nov 2022 diff --git a/src/configs/skills.json b/src/configs/skills.json index fcabb00..81b2697 100644 --- a/src/configs/skills.json +++ b/src/configs/skills.json @@ -1,101 +1,149 @@ { "hard": { "advanced": { - "JavaScript": [ - "fe", - "be" - ], - "TypeScript": [ - "fe", - "be", - "chain" - ], - "Haskell": [ - "fe", - "be", - "chain" + "JavaScript": "any", + "TypeScript": "any", + "Functional React Components": [ + "func" ], + "Haskell": "any", "React": [ - "fe" + "fe", + "fs", + "all" ] }, "intermediate": { - "C++": [ - "be" + "C/C++": [ + "be", + "fs", + "all" ], "Python": [ - "be" + "be", + "fs", + "data", + "all" ], "Graphic Design": [ "fe", - "web" + "web", + "all" + ], + "lodash": [ + "func" + ], + "Haddock": [ + "func" + ], + "Haskell Stack tool": [ + "func" ], "Node.js": [ - "be" + "be", + "fs", + "data", + "chain", + "all" ], "HTML": [ - "fe" + "fe", + "web", + "fs", + "all" ], "CSS": [ - "fe" + "fe", + "web", + "fs", + "all" ], "Redux Toolkit": [ - "fe" + "fe", + "fs", + "all" ], "Material UI": [ - "fe" + "fe", + "fs", + "all" ], "Express.js": [ - "be" + "be", + "fs", + "all" ], "REST APIs": [ "fe", - "be" + "be", + "fs", + "all" ], "PostgreSQL": [ - "be" - ], - "Git": [ + "be", + "fs", "all" ], - "Jira/Atlassian": [ - "all" - ] + "Git": "any", + "Jira/Atlassian": "any" }, "familiar": { "Jest.js": [ - "fe" + "fe", + "fs", + "all" ], "jQuery": [ - "fe" + "fe", + "all" + ], + "NumPy": [ + "data" + ], + "Pandas": [ + "data" ], "Kotlin": [ "be", - "chain" + "fs", + "chain", + "func", + "all" ], "Java": [ - "be" + "be", + "fs", + "all" ], "Rust": [ "be", - "chain" + "fs", + "chain", + "func", + "all" ], "Go": [ "be", - "chain" + "fs", + "chain", + "all" ], "Kafka": [ - "be" - ], - "CI/CD": [ - "fe", - "be" + "be", + "fs", + "all" ], + "CI/CD": "any", "Mircoservices": [ - "be" + "be", + "fs", + "chain", + "all" ], "Spring Boot": [ - "be" + "be", + "fs", + "all" ] } }, diff --git a/src/configs/skills.yaml b/src/configs/skills.yaml index fd94b9c..b113b4e 100644 --- a/src/configs/skills.yaml +++ b/src/configs/skills.yaml @@ -1,33 +1,39 @@ hard: advanced: - JavaScript: [fe, be] - TypeScript: [fe, be, chain] - Haskell: [fe, be, chain] - React: [fe] + JavaScript: any + TypeScript: any + Functional React Components: [func] + Haskell: any + React: [fe, fs, all] intermediate: - C++: [be] - Python: [be] - Graphic Design: [fe, web] - Node.js: [be] - HTML: [fe] - CSS: [fe] - Redux Toolkit: [fe] - Material UI: [fe] - Express.js: [be] - REST APIs: [fe, be] - PostgreSQL: [be] - Git: [all] - Jira/Atlassian: [all] + C/C++: [be, fs, all] + Python: [be, fs, data, all] + Graphic Design: [fe, web, all] + lodash: [func] + Haddock: [func] + Haskell Stack tool: [func] + Node.js: [be, fs, data, chain, all] + HTML: [fe, web, fs, all] + CSS: [fe, web, fs, all] + Redux Toolkit: [fe, fs, all] + Material UI: [fe, fs, all] + Express.js: [be,fs, all] + REST APIs: [fe, be, fs, all] + PostgreSQL: [be, fs, all] + Git: any + Jira/Atlassian: any familiar: - Jest.js: [fe] - jQuery: [fe] - Kotlin: [be, chain] - Java: [be] - Rust: [be, chain] - Go: [be, chain] - Kafka: [be] - CI/CD: [fe, be] - Mircoservices: [be] - Spring Boot: [be] + Jest.js: [fe, fs, all] + jQuery: [fe, all] + NumPy: [data] + Pandas: [data] + Kotlin: [be, fs, chain, func, all] + Java: [be, fs, all] + Rust: [be, fs, chain, func, all] + Go: [be, fs, chain, all] + Kafka: [be, fs, all] + CI/CD: any + Mircoservices: [be, fs, chain, all] + Spring Boot: [be, fs, all] soft: [Love of learning, Problem solving, Attention to detail, Teamwork, Code ownership, Agile] diff --git a/src/configs/work.json b/src/configs/work.json index 02196f6..2a2425f 100644 --- a/src/configs/work.json +++ b/src/configs/work.json @@ -5,20 +5,46 @@ "from": "Jan 2022", "to": "Dec 2022", "description": [ - "Worked on two projects: covid-testing laboratory system (full stack) and a neo bank (front end)", + "Worked on two projects: covid-testing laboratory system (full stack) and a [neo bank web app](https://vacuumlabs.com/case-study/advance-intelligence/) (front end)", "Was promoted to a higher level both times my performance was evaluated because of my receptivity to criticism", "Suggested automating TypeScript type generation for our APIs and created the script for it. That made our app more type-safe, saved us time and made it easy to keep updating the types as the backend changed", - "Pushed for clear, expressive, and type-safe code through suggestions in reviews and sharing my knowledge of the TS type system in discussions improving our code quality", + { + "Helped with upholding high standard by pushing for clear, expressive, and type-safe code through suggestions in reviews and discussions": [ + "^func" + ] + }, + { + "Pushed for clear, expressive, and type-safe code in functional style through suggestions in reviews and discussions improving our code quality": [ + "func" + ] + }, + { + "Took part in defining code-style and shared my knowledge of making a good use of TypeScript": [ + "fe", + "fs", + "func", + "all" + ] + }, { "Built main account, saving accounts, and loan views with one common React component minimizing duplicate code while using type templates, and narrowing to keep everything clear and type-safe": [ - "fe" + "fe", + "fs", + "all" ] }, "Understood design requirements and resolved few misunderstandings before a wrong feature was implemented", "Was trusted to write extra documentation to ensure smooth project handover", { "Helped to refactor database relationships and wrote SQL database migrations when expanding the lab system to ensure better scalability and preserving all current production data. This allowed us to pivot to other kinds of testing in addition to covid-tests": [ - "be" + "be", + "fs", + "all" + ] + }, + { + "Became very interested in block-chain technology during that time as Vacuumlabs worked on many 'crypto' projects": [ + "chain" ] } ] @@ -30,9 +56,16 @@ "description": [ "Collaborated remotely with university teachers to create non-linear interactive stories for educational purposes", "Exceeded expectations by providing beautiful visuals suiting each story’s theme and extra functionality", + { + "Used creative problem solving and web design skills (JS, HTML, CSS) to fulfill requirements and creative vision despite technical limitations of the tool used for creating the games": [ + "^fe", + "^web" + ] + }, { "Used creative problem solving, web design (JS, HTML, CSS), and graphic design skills to fulfill requirements and creative vision despite technical limitations of the tool used for creating the games": [ - "fe" + "fe", + "web" ] }, "Created a custom tool that made developer experience much better" diff --git a/src/configs/work.yaml b/src/configs/work.yaml index 7d96ebb..6d2211d 100644 --- a/src/configs/work.yaml +++ b/src/configs/work.yaml @@ -4,14 +4,17 @@ Vacuumlabs: from: Jan 2022 to: Dec 2022 description: - - "Worked on two projects: covid-testing laboratory system (full stack) and a neo bank (front end)" + - "Worked on two projects: covid-testing laboratory system (full stack) and a [neo bank web app](https://vacuumlabs.com/case-study/advance-intelligence/) (front end)" - Was promoted to a higher level both times my performance was evaluated because of my receptivity to criticism - Suggested automating TypeScript type generation for our APIs and created the script for it. That made our app more type-safe, saved us time and made it easy to keep updating the types as the backend changed - - Pushed for clear, expressive, and type-safe code through suggestions in reviews and sharing my knowledge of the TS type system in discussions improving our code quality - - Built main account, saving accounts, and loan views with one common React component minimizing duplicate code while using type templates, and narrowing to keep everything clear and type-safe: [fe] + - Helped with upholding high standard by pushing for clear, expressive, and type-safe code through suggestions in reviews and discussions: [^func] + - Pushed for clear, expressive, and type-safe code in functional style through suggestions in reviews and discussions improving our code quality: [func] + - Took part in defining code-style and shared my knowledge of making a good use of TypeScript: [fe, fs, func, all] + - Built main account, saving accounts, and loan views with one common React component minimizing duplicate code while using type templates, and narrowing to keep everything clear and type-safe: [fe, fs, all] - Understood design requirements and resolved few misunderstandings before a wrong feature was implemented - Was trusted to write extra documentation to ensure smooth project handover - - Helped to refactor database relationships and wrote SQL database migrations when expanding the lab system to ensure better scalability and preserving all current production data. This allowed us to pivot to other kinds of testing in addition to covid-tests: [be] + - Helped to refactor database relationships and wrote SQL database migrations when expanding the lab system to ensure better scalability and preserving all current production data. This allowed us to pivot to other kinds of testing in addition to covid-tests: [be, fs, all] + - Became very interested in block-chain technology during that time as Vacuumlabs worked on many 'crypto' projects: [chain] Masaryk University: title: Web Developer and Designer @@ -20,5 +23,6 @@ Masaryk University: description: - Collaborated remotely with university teachers to create non-linear interactive stories for educational purposes - Exceeded expectations by providing beautiful visuals suiting each story’s theme and extra functionality - - Used creative problem solving, web design (JS, HTML, CSS), and graphic design skills to fulfill requirements and creative vision despite technical limitations of the tool used for creating the games: [fe] + - Used creative problem solving and web design skills (JS, HTML, CSS) to fulfill requirements and creative vision despite technical limitations of the tool used for creating the games: [^fe, ^web] + - Used creative problem solving, web design (JS, HTML, CSS), and graphic design skills to fulfill requirements and creative vision despite technical limitations of the tool used for creating the games: [fe, web] - Created a custom tool that made developer experience much better diff --git a/src/pages/LandingPage/FilterSelector.tsx b/src/pages/LandingPage/FilterSelector.tsx index b258ff9..a2e3395 100644 --- a/src/pages/LandingPage/FilterSelector.tsx +++ b/src/pages/LandingPage/FilterSelector.tsx @@ -11,10 +11,13 @@ const a11yProps = (index: number) => ({ const PAGE_PATH = '/landing' -const filterOpts = [ +export const filterOpts = [ { label: 'Full Stack', filter: 'full-stack' }, { label: 'Front End', filter: 'front-end' }, { label: 'Back End', filter: 'back-end' }, + { label: 'Block Chain', filter: 'block-chain' }, + { label: 'Functional', filter: 'func' }, + { label: 'Data Science', filter: 'data-science' }, ] as const export const FilterSelector = () => { diff --git a/src/pages/LandingPage/Skills.tsx b/src/pages/LandingPage/Skills.tsx index 3efd5ff..ad2a371 100644 --- a/src/pages/LandingPage/Skills.tsx +++ b/src/pages/LandingPage/Skills.tsx @@ -3,7 +3,7 @@ import { useParams } from 'react-router-dom' import _ from 'lodash' import rawSkills from '../../configs/skills.json' -import { RelevancyTags, relevancyPredicates } from './relevancyFiltering' +import { RelevancyTags, filterObjectsByRelevancy } from './relevancyFiltering' const SkillChipsBox = ({ skills, ...props }: ChipProps & { skills: { name: string }[] }) => ( @@ -17,9 +17,11 @@ const SkillChipsBox = ({ skills, ...props }: ChipProps & { skills: { name: strin export const Skills = () => { const { filter } = useParams() const skills = _.mapValues(rawSkills.hard, (ratedSkills, level) => - _.map( - _.pickBy(ratedSkills, relevancyPredicates[filter ?? '']), - (relevancy: RelevancyTags, name) => ({name, level, relevancy})), + filterObjectsByRelevancy( + _.map(ratedSkills, (relevancy: RelevancyTags, name) => ({name, level, relevancy})), + 'relevancy', + filter, + ), ) return ( diff --git a/src/pages/LandingPage/relevancyFiltering.ts b/src/pages/LandingPage/relevancyFiltering.ts index 4d8ad7e..6efdda7 100644 --- a/src/pages/LandingPage/relevancyFiltering.ts +++ b/src/pages/LandingPage/relevancyFiltering.ts @@ -1,26 +1,52 @@ import _ from 'lodash' import { getFirstKey, getFirstValue } from '../../utils' +import { filterOpts } from './FilterSelector' -export type RelevancyTags = ('fe' | 'be')[] +type RelevancyAbbreviations = 'fe' | 'be' | 'fs' | 'chain' | 'data' | 'func' | 'all' +const negationSign = '^' +type NegationSign = typeof negationSign +export type RelevancyTags = (RelevancyAbbreviations | `${NegationSign}${RelevancyAbbreviations}`)[] + +const tagsByFilterLabel: Record = { + 'front-end': 'fe', + 'back-end': 'be', + 'full-stack': 'fs', + 'block-chain': 'chain', + 'data-science': 'data', + 'func': 'func', + 'all': 'all', +} + +const isDefinedFilter = (filter?: string): filter is (keyof typeof tagsByFilterLabel) => + filter != undefined && filter in tagsByFilterLabel + +const filterToTag = (filter?: string) => tagsByFilterLabel[isDefinedFilter(filter) ? filter : 'all'] /** - * Object with relevancy predicates for filtering - * @keys filter parameter - * @values predicate function + * Function for relevancy filtering. + * If an item has no relevancy tags keep it always; + * If filter is `undefined` or not one of the predefined ones, use the 'all' filter. + * @param filter URL parameter + * @returns Predicate for relevancy filtering */ -export const relevancyPredicates: Record boolean) | undefined> = { - 'full-stack': (r) => r.includes('fe') || r.includes('be'), - 'front-end': (r) => r.includes('fe'), - 'back-end': (r) => r.includes('be'), -} as const +export const getRelevancyPredicate = (filter?: string): ((r: RelevancyTags | 'any' | undefined) => boolean) => + (r) => !r || r === 'any' || ( + r.includes(filterToTag(filter)) || + Boolean( + // if there are any negation tags... + r.find((tag) => tag.startsWith(negationSign)) && + // ...return true as long as there isn't a negation of the current filter tag + !r.find((tag) => tag === negationSign + filterToTag(filter)) + ) + ) /** String information that may or may not have relevancy tags attached */ export type MaybeTaggedString = string | { [str: string]: RelevancyTags } -/** For list of items that are rated and unrated. That means items are a string or objects with a single key */ +/** For list of items that are tagged or untagged. That means items are strings or objects with a single key */ export const filterStringsByRelevancy = (list: T[], filter: string | undefined) => - list.filter((item) => typeof item === 'string' || (relevancyPredicates[filter ?? '']?.(getFirstValue(item)) ?? true)) + list.filter((item) => typeof item === 'string' || getRelevancyPredicate(filter)(getFirstValue(item))) export const extractRelevantStrings = (list: T[]) => list.map((item) => typeof item === 'string' ? item : getFirstKey(item)) @@ -33,7 +59,4 @@ export const filterObjectsByRelevancy = o.filter((item) => ( - !_.get(item, path) - || (relevancyPredicates[filter ?? '']?.(_.get(item, path) as RelevancyTags) ?? true) - )) +) => o.filter((item) => getRelevancyPredicate(filter)(_.get(item, path) as RelevancyTags))