{"id":177,"date":"2023-05-09T03:51:13","date_gmt":"2023-05-09T03:51:13","guid":{"rendered":"https:\/\/chenminghao.co\/?page_id=177"},"modified":"2023-10-06T01:59:29","modified_gmt":"2023-10-06T01:59:29","slug":"experience","status":"publish","type":"page","link":"https:\/\/chenminghao.co\/index.php\/experience\/","title":{"rendered":"Experience"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">My Experience Timeline<\/h2>\n\n\n\n<!DOCTYPE html>\n<html>\n    <head>\n        <style>\n            .dots-wrapper {\n                position: absolute;\n                top: 0;\n                left: 0;\n                z-index: 10;\n                width: 100%;\n            }\n            .dots-button {\n                width: 15px;\n                height: 15px;\n                border-radius: 50%;\n                background-color: black;\n                border: none;\n                cursor: pointer;\n            }\n            .container-column {\n                display: flex;\n                flex-direction: column;\n                justify-content: center;\n                align-items: center;\n                position: relative;\n            }\n            .container-row {\n                display: flex;\n                flex-direction: row;\n                justify-content: center;\n                align-items: center;\n                position: relative;\n            }\n            .full-width {\n                width: 100%;\n            }\n            .timeline-main {\n                min-width: 500px;\n                position: relative;\n            }\n            .timeline-main::after {\n                content: \"\";\n                position: absolute;\n                top: 50%;\n                left: 0;\n                width: 100%;\n                height: 5px;\n                border-radius: 2px;\n                background-color: black;\n                transform: translateY(-50%);\n                z-index: -1;\n            }\n            .timeline-sub {\n                padding-top: 10px;\n                padding-bottom: 10px;\n                position: relative;\n            }\n            .timeline-sub:hover {\n                cursor: pointer;\n            }\n            .timeline-sub > .line {\n                content: \"\";\n                position: absolute;\n                top: 50%;\n                left: 0;\n                width: 100%;\n                height: 1px;\n                background-color: #818181;\n                transform: translateY(-50%);\n                z-index: -1;\n            }\n            .timeline-sub:hover > .line {\n                background-color: black;\n            }\n        <\/style>\n        <script type=\"text\/javascript\">\n            window.addEventListener('resize', configurePage);\n\n            const DATE1 = new Date(2020, 01);\n            const DATE2 = new Date(Date.now()); \n\n            const EXPERIENCES = {\n                'claris': {\n                    start: new Date(2022, 05),\n                    end: new Date(2023, 08),\n                    title: \"SWE Intern | Claris, an apple company\",\n                    blurb: \"Over two summers, I joined Claris, a wholly-owned subsidiary of Apple which provides low-code solutions to create custom app solutions, automate workflows, and streamline integrations.\\\n                        During my first summer working on the front-end (UI\/UX) team, I developed end-to-end critical path tests using Cypress to ensure the quality of future releases.\\\n                        This included work with internal cloud infrastructure tools (similar to AWS S3), as well as Docker for use with CI\/CD pipelines.\\\n                        I also learned to work within a team in an agile corporate software development environment.\\\n                        My second summer, I enhanced the critical path test suite and built out a full testing framework, from pull request to code acceptance.\\\n                        I also constructed web hosting infrastructure from the ground up by starting VMs, configuring VPCs, setting security policies, and creating DNS CNAME records.\"\n                },\n                'biostat': {\n                    start: new Date(2020, 10),\n                    end: null,\n                    title: \"Website Maintenance and Graphic Design | UCLA Department of Biostatistics\",\n                    blurb: \"During my time at the UCLA Department of Biostatistics, I managed department website content using Drupal and designed flyers with Adobe Illustrator.\"\n                },\n                'db': {\n                    start: new Date(2021, 02),\n                    end: new Date(2023, 05),\n                    title: \"Full-Stack Web Development | UCLA Daily Bruin\",\n                    blurb: \"In fall of 2021, I joined the Daily Bruin as a software development intern on their Internal Tools team. Using React, Django, and more, I helped develop software for internal use by other Daily Bruin staff.\"\n                }\n            };\n\n            function configurePage() {\n                \/\/ Get widths\n                let timelineWidth = document.getElementById('timeline-main').offsetWidth;\n                let allButtons = document.getElementsByClassName('dots-button');\n\n                const PX_PER_TIME = timelineWidth \/ (DATE2 - DATE1);\n\n                \/\/ Place year markers\n                let yearLabels = [], yearMarkers = [];\n                for (const [i, year] of ([...Array(DATE2.getFullYear() - DATE1.getFullYear() + 1).keys()].map(i => i + DATE1.getFullYear())).entries()) {\n                    thisOffset = Math.floor((new Date(year, 01, 01) - DATE1) * PX_PER_TIME);\n                    prevOffset = Math.floor((new Date(year - 1, 01, 01) - DATE1) * PX_PER_TIME);\n\n                    yearLabels.push(\n                        `<div \n                            class=\"container-column\"\n                            style=\"margin-left: ${i == 0 ? 0 : thisOffset - prevOffset - 50}px; margin-right: ${i == (DATE2.getFullYear() - DATE1.getFullYear()) ? (DATE2 - new Date(year, 01, 01)) * PX_PER_TIME: 0}px;\"\n                        >\n                            <span style=\"width: 50px;\">${year}<\/span>\n                        <\/div>`\n                    );\n                    yearMarkers.push(\n                        `<div \n                            class=\"container-row\"\n                            style=\"margin-left: ${i == 0 ? 0 : thisOffset - prevOffset - 5}px; margin-right: ${i == (DATE2.getFullYear() - DATE1.getFullYear()) ? (DATE2 - new Date(year, 01, 01)) * PX_PER_TIME: 0}px;\"\n                        >\n                            <span style=\"width: 5px;\">|<\/span>\n                        <\/div>`\n                    );\n                }\n\n                document.getElementById('year-labels').innerHTML = yearLabels.join('\\n');\n                document.getElementById('year-markers').innerHTML = yearMarkers.join('\\n');\n\n                \/\/ Map experiences\n                let experienceBars = [];\n                for (const [barName, exp] of Object.entries(EXPERIENCES)) {\n                    let endDate = exp.end;\n                    if (exp.end === null)\n                        endDate = DATE2;\n\n                    experienceBars.push(\n                        `<div \n                            class=\"container-row\"\n                            style=\"margin-left: ${Math.floor((exp.start - DATE1) * PX_PER_TIME)}px; margin-right: ${Math.floor((DATE2 - endDate) * PX_PER_TIME)}px\"\n                        >\n                            <div \n                                class=\"timeline-sub\" \n                                id=\"timeline-main\"\n                                style=\"width: ${Math.floor((endDate - exp.start) * PX_PER_TIME)}px\"\n                                onclick=\"_expBarActivate(event.target, '${barName}')\"\n                            >\n                                <div class=\"line\"><\/div>\n                            <\/div>\n                        <\/div>`\n                    );\n                }\n\n                document.getElementById('experience-bar-wrapper').innerHTML = experienceBars.join('\\n');\n            }\n\n            \/\/ Helper function, activates when an experience bar is clicked\n            function _expBarActivate(el, barName) {\n                \/\/ Set all other lines to default\n                document.querySelectorAll('.line').forEach(e => e.style.backgroundColor = null);\n\n                \/\/ Set this line to black\n                el.getElementsByClassName('line')[0].style.backgroundColor = 'black';\n\n                \/\/ Update content\n                let exp = EXPERIENCES[barName];\n                document.getElementById('content-heading').innerHTML = \n                    `<h4 style=\"margin-bottom: 0px;\">\n                        ${exp.title}\n                    <\/h4>\n                    <br \/>\n                    <p style=\"margin-top: 0px;\">\n                        ${__dateify(exp.start)} - ${exp.end === null ? __dateify(DATE2) : __dateify(exp.end)}\n                    <\/p>`;\n\n                document.getElementById('content-block').innerHTML = `<p>${exp.blurb}<\/p>`;\n\n                function __dateify(date) {\n                    return `${date.getUTCFullYear()}.${String(date.getUTCMonth() + 1).padStart(2, '0')}`;\n                }\n            }\n        <\/script>\n    <\/head>\n    <body onload=\"configurePage()\">\n        <div style=\"\">\n            <div class=\"container-column full-width\">\n                <div class=\"container-row\" id=\"year-labels\">\n                <\/div>\n                <div class=\"container-row\" style=\"margin-bottom: 20px;\">\n                    <div class=\"timeline-main\" id=\"timeline-main\">\n                        <div class=\"container-row full-width\" id=\"year-markers\"><\/div>\n                    <\/div>\n                <\/div>\n                <div class=\"container-column full-width\" id=\"experience-bar-wrapper\"><\/div>\n                <div style=\"padding-top: 50px;\"><\/div>\n                <div class=\"container-column full-width\" style=\"align-items: flex-start\">\n                    <span id=\"content-heading\"><\/span>\n                    <span id=\"content-block\"><\/span>\n                <\/div>\n            <\/div>\n        <\/div>\n    <\/body>\n<\/html>\n","protected":false},"excerpt":{"rendered":"<p>My Experience Timeline<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":""},"_links":{"self":[{"href":"https:\/\/chenminghao.co\/index.php\/wp-json\/wp\/v2\/pages\/177"}],"collection":[{"href":"https:\/\/chenminghao.co\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/chenminghao.co\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/chenminghao.co\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/chenminghao.co\/index.php\/wp-json\/wp\/v2\/comments?post=177"}],"version-history":[{"count":25,"href":"https:\/\/chenminghao.co\/index.php\/wp-json\/wp\/v2\/pages\/177\/revisions"}],"predecessor-version":[{"id":219,"href":"https:\/\/chenminghao.co\/index.php\/wp-json\/wp\/v2\/pages\/177\/revisions\/219"}],"wp:attachment":[{"href":"https:\/\/chenminghao.co\/index.php\/wp-json\/wp\/v2\/media?parent=177"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}