├── .editorconfig ├── .eslintignore ├── .eslintrc.json ├── .github ├── actions │ ├── install-js-dependencies │ │ └── action.yaml │ └── install-python-dependencies │ │ └── action.yaml └── workflows │ └── deploy.yaml ├── .gitignore ├── .idea ├── .gitignore ├── .name ├── encodings.xml ├── inspectionProfiles │ └── profiles_settings.xml ├── job.ivelum.com.iml ├── misc.xml ├── modules.xml ├── runConfigurations │ ├── build_production.xml │ ├── clean.xml │ ├── deploy.xml │ └── start_in_dev_mode.xml └── vcs.xml ├── .stylelintrc.json ├── LICENSE ├── README.md ├── assets ├── Allianz-guide-ru.pdf ├── flag-ru.png ├── flag-us.png ├── logo.eps ├── meetings-en.jpeg ├── meetings-ru.gif ├── t-shirt-1.png ├── t-shirt-2.jpg └── vault-boy.png ├── babel.config.json ├── challenges ├── frontend.md ├── php.md └── python.md ├── cloudformation.yaml ├── deploy ├── __init__.py ├── aws.py ├── settings.py └── utils.py ├── gatsby-browser.js ├── gatsby-config.js ├── gatsby-node.js ├── jsconfig.json ├── lambda-package ├── lambda_function.py └── requirements.txt ├── package.json ├── requirements.txt ├── run.py ├── setup.cfg ├── src ├── Jobs.js ├── _global.scss ├── _mixins.scss ├── _reset.scss ├── _typography.scss ├── _vars.scss ├── chat.js ├── components │ ├── About.jsx │ ├── ApplicationForm.jsx │ ├── ApplicationForm.module.scss │ ├── Benefits.jsx │ ├── Button.jsx │ ├── Button.module.scss │ ├── Contacts.jsx │ ├── Contacts.module.scss │ ├── ContentForm.jsx │ ├── CountryDropdown.jsx │ ├── Crisp.jsx │ ├── DeveloperForm.jsx │ ├── ExperienceRadioField.jsx │ ├── ExperienceRadioField.module.scss │ ├── ExternalLink.jsx │ ├── Field.jsx │ ├── Field.module.scss │ ├── FieldLabel.jsx │ ├── FieldLabel.module.scss │ ├── Footer.jsx │ ├── Footer.module.scss │ ├── FormErrorMessage.jsx │ ├── FormErrorMessage.module.scss │ ├── GithubButton.jsx │ ├── GithubButton.module.scss │ ├── GoogleForm.jsx │ ├── GoogleForm.module.css │ ├── HrLine.jsx │ ├── HrLine.module.scss │ ├── IndexVacancies.jsx │ ├── IndexVacancies.module.scss │ ├── InterviewProcess.jsx │ ├── JobPage.jsx │ ├── JobPage.module.scss │ ├── JobTextBlock.jsx │ ├── JobTextBlock.module.scss │ ├── PageTitle.jsx │ ├── PageTitle.module.scss │ ├── Row.jsx │ ├── Row.module.scss │ ├── SvgImage.jsx │ ├── TechLogos.jsx │ ├── TechLogos.module.scss │ ├── UXForm.jsx │ ├── WelcomeText.jsx │ ├── WelcomeText.module.scss │ ├── Youtube.jsx │ ├── Youtube.module.scss │ └── layout │ │ ├── Header.jsx │ │ ├── Header.module.scss │ │ ├── Layout.jsx │ │ ├── Layout.module.scss │ │ └── Metadata.jsx ├── fonts │ ├── PT-Mono_Bold.woff │ ├── PT-Mono_Bold.woff2 │ ├── PT-Mono_Regular.woff │ ├── PT-Mono_Regular.woff2 │ ├── Source-Sans_Bold.woff │ └── Source-Sans_Bold.woff2 ├── hooks │ └── use-site-metadata.js ├── images │ ├── aws.svg │ ├── body-background.jpg │ ├── cat.png │ ├── django.svg │ ├── docker.svg │ ├── flag-am.svg │ ├── flag-ge.svg │ ├── flag-kg.svg │ ├── flag-lt.svg │ ├── flag-md.svg │ ├── flag-ru.svg │ ├── flag-ua.svg │ ├── github-button.svg │ ├── graphql.svg │ ├── hi-ico.png │ ├── ico-angle-arrow.svg │ ├── ico-chat.svg │ ├── ico-long-arrow.svg │ ├── ico-mail.svg │ ├── ico-telegram.svg │ ├── ico-youtube.svg │ ├── kubernetes.svg │ ├── list-dot.svg │ ├── logo.svg │ ├── nextjs.svg │ ├── php.svg │ ├── python.svg │ ├── react.svg │ └── wordpress.svg └── pages │ ├── 404.jsx │ ├── content │ ├── form.jsx │ └── index.jsx │ ├── faq.jsx │ ├── frontend │ ├── form.jsx │ └── index.jsx │ ├── index.jsx │ ├── job-application-accepted.jsx │ ├── php │ ├── form.jsx │ └── index.jsx │ ├── python │ ├── form.jsx │ └── index.jsx │ ├── ux │ ├── form.jsx │ └── index.jsx │ └── wordpress │ ├── form.jsx │ └── index.jsx ├── static ├── apple-touch-icon.png ├── favicon.ico ├── icon-192.png ├── icon-512.png ├── icon.svg └── site.webmanifest └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | insert_final_newline = true 7 | 8 | [*.py] 9 | indent_style = space 10 | indent_size = 4 11 | max_line_length = 80 12 | 13 | [*.{html,j2,js,jsx,json,scss,yml,yaml}] 14 | indent_style = space 15 | indent_size = 2 16 | max_line_length = 80 17 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | /public 3 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true 4 | }, 5 | "extends": ["airbnb"], 6 | "parser": "@babel/eslint-parser", 7 | "rules": { 8 | "func-names": 0, 9 | "import/order": ["error", { 10 | "alphabetize": {"order": "asc"}, 11 | "groups": [ 12 | ["builtin", "external"], 13 | ["sibling", "parent", "internal"], 14 | "index" 15 | ], 16 | "newlines-between": "always", 17 | "pathGroups": [ 18 | { 19 | "pattern": "./*.scss", 20 | "group": "index" 21 | }, 22 | { 23 | "pattern": "../*.scss", 24 | "group": "index" 25 | }, 26 | { 27 | "pattern": "@/images/*.png", 28 | "group": "index" 29 | }, 30 | { 31 | "pattern": "@/images/*.svg", 32 | "group": "index" 33 | } 34 | ], 35 | "pathGroupsExcludedImportTypes": ["builtin", "external"] 36 | }], 37 | "jsx-a11y/anchor-is-valid": ["error", { 38 | "components": ["Link"], 39 | "specialLink": ["to"], 40 | "aspects": ["noHref", "invalidHref", "preferButton"] 41 | }], 42 | "jsx-a11y/click-events-have-key-events": [1], 43 | "jsx-a11y/label-has-associated-control": "off", 44 | "lines-between-class-members": ["error", "always", { 45 | "exceptAfterSingleLine": true 46 | }], 47 | "max-len": [2, 80, 4], 48 | "no-underscore-dangle": ["error", { 49 | "allow": ["_isMounted"] 50 | }], 51 | "no-unused-expressions": ["error", { 52 | "allowTernary": true 53 | }], 54 | "no-console": "error", 55 | "react/destructuring-assignment": "off", 56 | "react/jsx-one-expression-per-line": "off", 57 | "react/forbid-prop-types": [2, { "forbid": ["any"] }], 58 | "react/jsx-props-no-spreading": "off", 59 | "react/static-property-placement": ["off", "property assignment"] 60 | }, 61 | "settings": { 62 | "import/resolver": { 63 | "alias": { 64 | "map": [ 65 | ["@", "./src"] 66 | ], 67 | "extensions": [".js", ".jsx", ".png", "svg"] 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /.github/actions/install-js-dependencies/action.yaml: -------------------------------------------------------------------------------- 1 | name: 'Install js dependencies' 2 | runs: 3 | using: "composite" 4 | steps: 5 | - name: Get yarn cache directory path 6 | id: yarn-cache-dir-path 7 | run: echo "::set-output name=dir::$(yarn cache dir)" 8 | shell: bash 9 | - uses: actions/cache@v2 10 | id: yarn-cache 11 | with: 12 | path: ${{ steps.yarn-cache-dir-path.outputs.dir }} 13 | key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} 14 | restore-keys: | 15 | ${{ runner.os }}-yarn- 16 | - run: yarn --prefer-offline 17 | shell: bash 18 | -------------------------------------------------------------------------------- /.github/actions/install-python-dependencies/action.yaml: -------------------------------------------------------------------------------- 1 | name: 'Install Python dependencies' 2 | runs: 3 | using: "composite" 4 | steps: 5 | - name: update pip 6 | run: | 7 | pip install -U wheel 8 | pip install -U setuptools 9 | python -m pip install -U pip 10 | shell: bash 11 | - name: get pip cache dir 12 | id: pip-cache 13 | run: echo "::set-output name=dir::$(pip cache dir)" 14 | shell: bash 15 | - name: cache pip 16 | uses: actions/cache@v2 17 | with: 18 | path: ${{ steps.pip-cache.outputs.dir }} 19 | key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} 20 | - run: pip install -r requirements.txt 21 | shell: bash 22 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yaml: -------------------------------------------------------------------------------- 1 | name: Deploy 2 | on: 3 | push: 4 | branches: [master] 5 | workflow_dispatch: 6 | jobs: 7 | notify-build-start: 8 | if: ${{ github.event_name == 'push' }} 9 | runs-on: ubuntu-latest 10 | steps: 11 | # Send build notifications to Slack 12 | - uses: ivelum/github-action-slack-notify-build@v1.6.0 13 | id: slack 14 | with: 15 | channel_id: G054C3DPL 16 | status: STARTED 17 | color: '#ee9b00' 18 | env: 19 | SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} 20 | outputs: 21 | status_message_id: ${{ steps.slack.outputs.message_id }} 22 | 23 | lint: 24 | runs-on: ubuntu-latest 25 | steps: 26 | - uses: actions/checkout@v2 27 | - uses: actions/setup-node@v2 28 | with: 29 | node-version: '16' 30 | - uses: actions/setup-python@v2 31 | with: 32 | python-version: 3.9 33 | 34 | - uses: ./.github/actions/install-js-dependencies 35 | - uses: ./.github/actions/install-python-dependencies 36 | 37 | - run: yarn eslint 38 | - run: yarn stylelint 39 | - run: isort . 40 | - run: flake8 . 41 | 42 | # Send notification on check failure 43 | - name: Notify slack fail 44 | uses: ivelum/github-action-slack-notify-build@v1.6.0 45 | if: failure() 46 | env: 47 | SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} 48 | with: 49 | channel_id: G054C3DPL 50 | status: FAILED 51 | color: '#d7263d' 52 | 53 | deploy-app: 54 | needs: lint 55 | runs-on: ubuntu-latest 56 | steps: 57 | - uses: actions/checkout@v2 58 | - uses: actions/setup-node@v2 59 | with: 60 | node-version: '16' 61 | - uses: actions/setup-python@v2 62 | with: 63 | python-version: 3.9 64 | 65 | - uses: ./.github/actions/install-js-dependencies 66 | - uses: ./.github/actions/install-python-dependencies 67 | 68 | - run: yarn build 69 | - env: 70 | AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} 71 | AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} 72 | run: python run.py deploy-app 73 | 74 | # Send notification on build or deploy failure 75 | - name: Notify slack fail 76 | uses: ivelum/github-action-slack-notify-build@v1.6.0 77 | if: failure() 78 | env: 79 | SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} 80 | with: 81 | channel_id: G054C3DPL 82 | status: FAILED 83 | color: '#d7263d' 84 | 85 | deploy-lambda: 86 | needs: lint 87 | runs-on: ubuntu-latest 88 | steps: 89 | - uses: actions/checkout@v2 90 | - uses: actions/setup-python@v2 91 | with: 92 | python-version: 3.9 93 | 94 | - uses: ./.github/actions/install-python-dependencies 95 | - run: pip install --target lambda-package/dependencies -r lambda-package/requirements.txt 96 | 97 | - env: 98 | AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} 99 | AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} 100 | GOOGLE_API_SERVICE_ACCOUNT_INFO: ${{ secrets.GOOGLE_API_SERVICE_ACCOUNT_INFO }} 101 | GOOGLE_SPREADSHEET_ID: ${{ secrets.GOOGLE_SPREADSHEET_ID }} 102 | SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} 103 | PIPEDRIVE_TOKEN: ${{ secrets.PIPEDRIVE_TOKEN }} 104 | run: python run.py deploy-lambda 105 | 106 | # Send notification on build or deploy failure 107 | - name: Notify slack fail 108 | uses: ivelum/github-action-slack-notify-build@v1.6.0 109 | if: failure() 110 | env: 111 | SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} 112 | with: 113 | channel_id: G054C3DPL 114 | status: FAILED 115 | color: '#d7263d' 116 | 117 | notify-build-success: 118 | if: ${{ github.event_name == 'push' }} 119 | needs: [deploy-app, deploy-lambda, notify-build-start] 120 | runs-on: ubuntu-latest 121 | steps: 122 | # Send notification on build success 123 | - name: Notify slack success 124 | uses: ivelum/github-action-slack-notify-build@v1.6.0 125 | env: 126 | SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} 127 | with: 128 | message_id: ${{ needs.notify-build-start.outputs.status_message_id }} 129 | channel_id: G054C3DPL 130 | status: SUCCESS 131 | color: '#16db65' 132 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .cache/ 2 | .DS_Store 3 | node_modules/ 4 | public 5 | .venv 6 | lambda-package/dependencies/ 7 | lambda-package/lambda-package.zip 8 | 9 | # 10 | # See https://github.com/github/gitignore/blob/master/Global/JetBrains.gitignore 11 | # 12 | 13 | # User-specific stuff 14 | .idea/**/aws.xml 15 | .idea/**/workspace.xml 16 | .idea/**/tasks.xml 17 | .idea/**/usage.statistics.xml 18 | .idea/**/dictionaries 19 | .idea/**/shelf 20 | 21 | # Generated files 22 | .idea/$CACHE_FILE$ 23 | .idea/**/contentModel.xml 24 | 25 | # Sensitive or high-churn files 26 | .idea/**/dataSources/ 27 | .idea/**/dataSources.ids 28 | .idea/**/dataSources.local.xml 29 | .idea/**/sqlDataSources.xml 30 | .idea/**/dynamic.xml 31 | .idea/**/uiDesigner.xml 32 | .idea/**/dbnavigator.xml 33 | 34 | # File-based project format 35 | *.iws 36 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Datasource local storage ignored files 5 | /dataSources/ 6 | /dataSources.local.xml 7 | # Editor-based HTTP Client requests 8 | /httpRequests/ 9 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | job.ivelum.com -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/job.ivelum.com.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 13 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 10 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/runConfigurations/build_production.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |