{"componentChunkName":"component---src-templates-page-js","path":"/projects/2020/apick","result":{"data":{"markdownRemark":{"frontmatter":{"title":"Apick - EdTech startup","path":"/projects/2020/apick","excerpt":null,"tags":null,"liveUrl":"https://www.apick.com.br","sampleCode":"true","sourceCode":null,"coverImage":{"childImageSharp":{"fluid":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAMABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAMEBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAd2SsEjQ/8QAGRAAAwEBAQAAAAAAAAAAAAAAAAEDAhEh/9oACAEBAAEFAvSrqtQenMZ0/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAGBAAAwEBAAAAAAAAAAAAAAAAACIxESD/2gAIAQEABj8CEmD3j//EABkQAAIDAQAAAAAAAAAAAAAAAAABESFBMf/aAAgBAQABPyHqhcaVk60VWkTeGycCY//aAAwDAQACAAMAAAAQMO//xAAVEQEBAAAAAAAAAAAAAAAAAAAAEf/aAAgBAwEBPxBX/8QAFREBAQAAAAAAAAAAAAAAAAAAABH/2gAIAQIBAT8QR//EABoQAAMBAAMAAAAAAAAAAAAAAAERIQAxUWH/2gAIAQEAAT8QNEj7GH6BIULbhny4TYjgAEfmgNKcXLrKKTf/2Q==","aspectRatio":1.6666666666666667,"src":"/static/79f2f6bec98e30e092f03f19c27f7da2/ac25c/apick.jpg","srcSet":"/static/79f2f6bec98e30e092f03f19c27f7da2/f836f/apick.jpg 200w,\n/static/79f2f6bec98e30e092f03f19c27f7da2/2244e/apick.jpg 400w,\n/static/79f2f6bec98e30e092f03f19c27f7da2/ac25c/apick.jpg 777w","sizes":"(max-width: 777px) 100vw, 777px"}}}},"id":"da9cacbf-652a-54a3-ba53-a96002322b89","html":"<blockquote>\n<p>Hired as the one and only dev to build a marketplace for courses aimed for young adults in our dynamic economy.\nThe solution was to create a React App, with Google's Firebase Auth &#x26; Firestore as the database.\nThe company is within the top 10 regional survivors of Founder's Intitute seed program.</p>\n</blockquote>\n<blockquote>\n<p>Stack: React.js, Firebase, Firestore, Redux, Bootstrap, Scss, Node/Express.js</p>\n</blockquote>\n<p>Sample Code:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">SearchResult.js\n\nimport React, { useState, useEffect } from &quot;react&quot;\nimport { Link, useParams } from &quot;react-router-dom&quot;\nimport { connect } from &quot;react-redux&quot;\nimport { Alert } from &quot;react-bootstrap&quot;\n\n//context\nimport { useAuth } from &quot;../../contexts/AuthContext&quot;\n\n//components\nimport MetaDecorator from &quot;../MetaDecorator&quot;\nimport SuspenseFallback from &quot;../SuspenseFallback&quot;\nimport Pagination from &quot;./Pagination&quot;\nimport useMediaQuery from &quot;../useMediaQuery&quot;\n\n//icons\nimport { RiArrowGoBackLine } from &quot;react-icons/ri&quot;\nimport { CgClose } from &quot;react-icons/cg&quot;\n\n// styles\nimport styles from &quot;./SearchResult.module.scss&quot;\n\nconst SearchResult = ({ subjects, courses, isMobile }) =&gt; {\n\tconst params = useParams()\n\tconst _query = params.query\n\n\tconst { currentUser } = useAuth()\n\n\tconst [query, setQuery] = useState()\n\tconst [isProcessing, setIsProcessing] = useState(false)\n\tconst [isLoadingProps, setIsLoadingProps] = useState(true)\n\tconst [categoryParam, setCategoryParam] = useState(null)\n\tconst [subcategoryParam, setSubcategoryParam] = useState(null)\n\tconst [currentSubject, setCurrentSubject] = useState(null)\n\tconst [currentCourses, setCurrentCourses] = useState([])\n\tconst [matchCourses, setMatchCourses] = useState(null)\n\tconst [alert, setAlert] = useState(false)\n\n\tuseEffect(() =&gt; {\n\t\tif (!currentSubject) {\n\t\t\tsetIsProcessing(true)\n\t\t\tsetQuery(_query)\n\t\t} else if (_query.toLowerCase() !== currentSubject.toLowerCase()) {\n\t\t\tsetIsProcessing(true)\n\t\t\tsetQuery(_query)\n\t\t}\n\t}, [_query])\n\n\tuseEffect(() =&gt; {\n\t\tif (subjects.length &gt; 0 &amp;&amp; courses.length &gt; 0) {\n\t\t\tsetIsProcessing(true)\n\t\t\tsetIsLoadingProps(false)\n\t\t}\n\t}, [subjects, courses])\n\n\tconst isKeyWord = word =&gt; {\n\t\tconst filterCategoryParam = subjects.find(subject =&gt; {\n\t\t\treturn subject.category.toLowerCase() === word.toLowerCase()\n\t\t})\n\t\tif (filterCategoryParam) {\n\t\t\tsetCategoryParam(filterCategoryParam.category)\n\t\t\tsetSubcategoryParam(null)\n\t\t} else {\n\t\t\tconst subcategoriesArrays = subjects.map(subject =&gt; {\n\t\t\t\treturn subject.subcategories\n\t\t\t})\n\t\t\tconst subcategoriesDirty = subcategoriesArrays.flat(1)\n\n\t\t\tconst subcategories = subcategoriesDirty.filter(subcategoryDirty =&gt; {\n\t\t\t\treturn subcategoryDirty !== undefined\n\t\t\t})\n\n\t\t\tconst _subcategoryParam = subcategories.find(v =&gt; {\n\t\t\t\treturn v.toLowerCase() === word.toLowerCase()\n\t\t\t})\n\t\t\tif (_subcategoryParam) {\n\t\t\t\tsetSubcategoryParam(_subcategoryParam)\n\t\t\t\tsetCategoryParam(null)\n\t\t\t} else {\n\t\t\t\tsetSubcategoryParam(null)\n\t\t\t\tsetCategoryParam(null)\n\t\t\t\tsetCurrentSubject(`&quot;${query}&quot;`)\n\t\t\t}\n\t\t}\n\t}\n\tuseEffect(() =&gt; {\n\t\tif (courses &amp;&amp; courses.length &gt; 0 &amp;&amp; subjects &amp;&amp; subjects.length &gt; 0) {\n\t\t\t!isLoadingProps &amp;&amp; isKeyWord(query)\n\t\t}\n\t}, [isLoadingProps, query])\n\n\tuseEffect(() =&gt; {\n\t\tif (categoryParam) {\n\t\t\tsetCurrentSubject(categoryParam)\n\t\t\treturn\n\t\t}\n\t\tif (subcategoryParam) {\n\t\t\tsetCurrentSubject(subcategoryParam)\n\t\t\treturn\n\t\t}\n\t}, [categoryParam, subcategoryParam])\n\n\tconst searchQuery = query =&gt; {\n\t\tconst titles = []\n\t\tcourses.forEach(course =&gt; {\n\t\t\tif (course.title !== undefined) {\n\t\t\t\ttitles.push(course.title)\n\t\t\t}\n\t\t})\n\t\tconst matchTitles = titles.filter(title =&gt; title.toLowerCase().includes(query.toLowerCase()))\n\t\t// if part of any course title matched the query, return course(s)\n\t\tconst _matchCourses = courses.filter(course =&gt; matchTitles.includes(course.title))\n\t\t_matchCourses.push()\n\t\tif (_matchCourses) {\n\t\t\tsetMatchCourses(_matchCourses)\n\t\t\tconsole.log(&quot;matchCourses: &quot;, _matchCourses)\n\t\t} else {\n\t\t\tsetIsProcessing(false)\n\t\t}\n\t}\n\n\tuseEffect(() =&gt; {\n\t\tif (currentSubject === `&quot;${query}&quot;` &amp;&amp; !categoryParam &amp;&amp; !subcategoryParam &amp;&amp; courses &amp;&amp; courses.length &gt; 0) {\n\t\t\tsearchQuery(query)\n\t\t}\n\t}, [currentSubject])\n\n\tuseEffect(() =&gt; {\n\t\tif (categoryParam) {\n\t\t\tsetCurrentCourses(\n\t\t\t\tcourses.filter(course =&gt; {\n\t\t\t\t\treturn course.category === currentSubject\n\t\t\t\t})\n\t\t\t)\n\t\t}\n\t\tif (subcategoryParam) {\n\t\t\tsetCurrentCourses(\n\t\t\t\tcourses.filter(course =&gt; {\n\t\t\t\t\treturn course.subcategory === currentSubject\n\t\t\t\t})\n\t\t\t)\n\t\t}\n\t\tif (matchCourses) {\n\t\t\tsetCurrentCourses(matchCourses)\n\t\t}\n\t}, [currentSubject, matchCourses])\n\n\tuseEffect(() =&gt; {\n\t\tsetIsProcessing(false)\n\t}, [currentCourses])\n\n\tuseEffect(() =&gt; {\n\t\tif (isLoadingProps || isProcessing || currentUser) {\n\t\t\treturn\n\t\t}\n\t\tsetTimeout(() =&gt; {\n\t\t\tsetAlert(true)\n\t\t}, 2000)\n\t\tsetTimeout(() =&gt; {\n\t\t\tsetAlert(false)\n\t\t}, 8000)\n\t}, [isLoadingProps, isProcessing, currentUser])\n\n\tconst handleCloseIcon = () =&gt; {\n\t\tsetAlert(false)\n\t}\n\n\tconst abbreviateLongWords = sentence =&gt; {\n\t\t//check if letter is vowel\n\t\tconst isVowel = letter =&gt; {\n\t\t\tlet result = Boolean\n\t\t\tif (letter == &quot;A&quot; || letter == &quot;E&quot; || letter == &quot;I&quot; || letter == &quot;O&quot; || letter == &quot;U&quot;) {\n\t\t\t\tresult = true\n\t\t\t} else {\n\t\t\t\tresult = false\n\t\t\t}\n\t\t\treturn result\n\t\t}\n\t\t// conditions to reduce words or keep them original\n\t\tif (sentence.length &lt; 12) {\n\t\t\treturn sentence\n\t\t} else {\n\t\t\tconst sentenceWords = sentence.split(&quot; &quot;)\n\t\t\tconst reduceLongWords = sentenceWords.map(word =&gt; {\n\t\t\t\tif (word.length &gt; 14) {\n\t\t\t\t\tif (!isVowel(word[6])) {\n\t\t\t\t\t\treturn `${word.substring(0, 6)}.`\n\t\t\t\t\t} else if (!isVowel(word[7])) {\n\t\t\t\t\t\treturn `${word.substring(0, 7)}.`\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn `${word.substring(0, 8)}.`\n\t\t\t\t\t}\n\t\t\t\t} else if (word.length &gt; 10) {\n\t\t\t\t\tif (!isVowel(word[3])) {\n\t\t\t\t\t\treturn `${word.substring(0, 3)}.`\n\t\t\t\t\t} else if (!isVowel(word[4])) {\n\t\t\t\t\t\treturn `${word.substring(0, 4)}.`\n\t\t\t\t\t} else if (!isVowel(word[5])) {\n\t\t\t\t\t\treturn `${word.substring(0, 5)}.`\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn `${word.substring(0, 6)}.`\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\treturn word\n\t\t\t\t}\n\t\t\t})\n\t\t\tconst reassembleWords = reduceLongWords.join(&quot; &quot;)\n\t\t\treturn reassembleWords\n\t\t}\n\t}\n\n\t// Pagination Starts\n\tconst isDesktop = useMediaQuery(&quot;(min-width: 1350px)&quot;)\n\tconst isLaptop = useMediaQuery(&quot;(min-width: 1000px)&quot;)\n\tconst isIpad = useMediaQuery(&quot;(min-width: 800px)&quot;)\n\tconst isTablet = useMediaQuery(&quot;(min-width: 600px)&quot;)\n\n\tconst [pageNumber, setPageNumber] = useState(1)\n\tconst [itemsPerPage, setItemsPerPage] = useState(10)\n\n\t// change how many cards will render depending on the size of the screen\n\tuseEffect(() =&gt; {\n\t\tif (isDesktop) {\n\t\t\tsetItemsPerPage(10)\n\t\t\treturn\n\t\t} else if (isLaptop) {\n\t\t\tsetItemsPerPage(8)\n\t\t\treturn\n\t\t} else if (isIpad) {\n\t\t\tsetItemsPerPage(9)\n\t\t\treturn\n\t\t} else if (isTablet) {\n\t\t\tsetItemsPerPage(8)\n\t\t\treturn\n\t\t} else {\n\t\t\t// isMobile\n\t\t\tsetItemsPerPage(10)\n\t\t}\n\t}, [isLaptop, isTablet, isIpad, isDesktop])\n\n\tconst paginate = page =&gt; {\n\t\tsetPageNumber(page)\n\t\twindow.scrollTo(0, 0)\n\t}\n\t// Paginations Ends\n\n\treturn (\n\t\t&lt;div&gt;\n\t\t\t&lt;MetaDecorator title={currentSubject ? `Cursos de ${currentSubject}` : &quot;Buscador de Cursos&quot;} description={&quot;A Apick ajuda você a encontrar o seu curso ideal!&quot;} /&gt;\n\t\t\t&lt;section className={styles.main_container}&gt;\n\t\t\t\t&lt;div className=&quot;back-and-save&quot;&gt;\n\t\t\t\t\t&lt;Link to=&quot;/&quot;&gt;\n\t\t\t\t\t\t&lt;div className=&quot;back&quot;&gt;\n\t\t\t\t\t\t\t{&quot; &quot;}\n\t\t\t\t\t\t\t&lt;RiArrowGoBackLine /&gt;\n\t\t\t\t\t\t\t&lt;p&gt;Voltar&lt;/p&gt;\n\t\t\t\t\t\t&lt;/div&gt;\n\t\t\t\t\t&lt;/Link&gt;\n\t\t\t\t\t&lt;div className={styles.alertContainer}&gt;\n\t\t\t\t\t\t{alert &amp;&amp; (\n\t\t\t\t\t\t\t&lt;Alert variant=&quot;primary&quot; className={styles.alert}&gt;\n\t\t\t\t\t\t\t\t&lt;Link to=&quot;/criar-conta&quot;&gt;Crie uma conta para salvar seus cursos preferidos!&lt;/Link&gt;\n\t\t\t\t\t\t\t\t&lt;CgClose className={styles.closeIcon} onClick={handleCloseIcon} /&gt;\n\t\t\t\t\t\t\t&lt;/Alert&gt;\n\t\t\t\t\t\t)}\n\t\t\t\t\t&lt;/div&gt;\n\t\t\t\t&lt;/div&gt;\n\n\t\t\t\t{!isLoadingProps &amp;&amp; !isProcessing &amp;&amp; currentCourses ? (\n\t\t\t\t\t&lt;&gt;\n\t\t\t\t\t\t&lt;div className={styles.title}&gt;\n\t\t\t\t\t\t\t&lt;p style={{ marginRight: &quot;5px&quot; }}&gt;\n\t\t\t\t\t\t\t\tEncontramos {currentCourses.length} curso(s)\n\t\t\t\t\t\t\t\t{currentSubject &amp;&amp; (\n\t\t\t\t\t\t\t\t\t&lt;&gt;\n\t\t\t\t\t\t\t\t\t\t{&quot; &quot;}\n\t\t\t\t\t\t\t\t\t\tsobre\n\t\t\t\t\t\t\t\t\t\t&lt;strong&gt; {!isMobile ? currentSubject : abbreviateLongWords(currentSubject)}&lt;/strong&gt;\n\t\t\t\t\t\t\t\t\t&lt;/&gt;\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t:\n\t\t\t\t\t\t\t&lt;/p&gt;\n\t\t\t\t\t\t&lt;/div&gt;\n\n\t\t\t\t\t\t&lt;div&gt;{currentCourses &amp;&amp; currentCourses.length &gt; 0 ? &lt;Pagination currentCourses={currentCourses} pageNumber={pageNumber} itemsPerPage={itemsPerPage} paginate={paginate} /&gt; : &quot;Desculpe, não encontramos nenhum curso.&quot;}&lt;/div&gt;\n\n\t\t\t\t\t&lt;/&gt;\n\t\t\t\t) : (\n\t\t\t\t\t&lt;SuspenseFallback /&gt;\n\t\t\t\t)}\n\t\t\t&lt;/section&gt;\n\t\t&lt;/div&gt;\n\t)\n}\n\nconst mapStateToProps = state =&gt; {\n\treturn {\n\t\tcurrentSubject: state.currentSubject || [],\n\t}\n}\n\nexport default connect(mapStateToProps)(SearchResult)</code></pre></div>","excerpt":"Hired as the one and only dev to build a marketplace for courses aimed for young adults in our dynamic economy.\nThe solution was to create a…"}},"pageContext":{"type":"posts","next":{"frontmatter":{"path":"/projects/2021/empbank","title":"Empbank - FinTech startup","tags":null},"fileAbsolutePath":"/Users/felipesmaniotto/my-real-portfolio/src/posts/empbank.md"},"previous":null}},"staticQueryHashes":["1425477374","3128451518"]}