diff --git a/.circleci/config.yml b/.circleci/config.yml
new file mode 100644
index 0000000..8c5c850
--- /dev/null
+++ b/.circleci/config.yml
@@ -0,0 +1,126 @@
+version: 2.1
+only_tagged_versions: &only_tagged_versions
+ filters:
+ tags:
+ only: /^v.*/
+ branches:
+ ignore: /.*/
+commands:
+ add_missing_dependencies:
+ steps:
+ - run:
+ name: Add curl, git and make
+ command: |
+ apt-get update
+ apt-get install -y curl git make jq
+ - run:
+ name: Install Docker client
+ command: |
+ curl -fsSL https://get.docker.com -o get-docker.sh
+ sh get-docker.sh
+ rm -Rf get-docker.sh
+ docker --version
+ - run:
+ name: Install Docker Compose
+ command: |
+ curl -L https://github.com/docker/compose/releases/download/1.23.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
+ chmod +x /usr/local/bin/docker-compose
+ docker-compose --version
+ run_common_initial_steps:
+ steps:
+ - setup_remote_docker:
+ version: 18.06.0-ce
+ # Inactive for now... needs to be whitelisted (and/or OS), see https://circleci.com/docs/2.0/docker-layer-caching/
+ docker_layer_caching: true
+ - add_missing_dependencies
+ - checkout
+ - restore_cache:
+ keys:
+ - dependencies-{{ arch }}-{{ .Branch }}-{{ checksum "package.json" }}
+ - run:
+ name: Copy current dir to remote docker
+ # mount hack for cicleci: https://circleci.com/docs/2.0/building-docker-images/#mounting-folders
+ command: |
+ /bin/bash .make/utils/execute-in-docker.sh -s "${CIRCLE_PROJECT_REPONAME}" -o "--no-start"
+ docker cp . $(docker-compose ps -q ${CIRCLE_PROJECT_REPONAME}):/usr/src/app/
+ - run:
+ name: Copy ~/.ssh dir to remote docker
+ command: docker cp ~/.ssh $(docker-compose ps -q ${CIRCLE_PROJECT_REPONAME}):/root/
+ - run:
+ name: Install
+ command: make install
+ - run:
+ name: Copy node_modules dir from remote docker
+ # return node_modules hack for cicleci: https://circleci.com/docs/2.0/building-docker-images/#mounting-folders
+ command: docker cp $(docker-compose ps -q ${CIRCLE_PROJECT_REPONAME}):/usr/src/app/node_modules/ ./node_modules/
+ - save_cache:
+ paths:
+ - node_modules
+ key: dependencies-{{ arch }}-{{ .Branch }}-{{ checksum "package.json" }}
+defaults: &defaults
+ docker:
+ - image: ubuntu:18.04
+jobs:
+ test:
+ <<: *defaults
+ steps:
+ - run_common_initial_steps
+ - run:
+ name: Lint
+ command: make lint
+ - run:
+ name: Unit tests
+ # TODO temp hack that sets backend service url since unit tests as of now are no actual unit tests
+ command: BACKEND_SERVICE_URL="${AWS_SERVICE_URL}" make unit_tests
+ - run:
+ name: Verify build for production
+ command: BACKEND_SERVICE_URL="${AWS_SERVICE_URL}" make build
+ release:
+ <<: *defaults
+ steps:
+ - run_common_initial_steps
+ - run:
+ name: Semantic release
+ command: make semantic_release
+ publish:
+ <<: *defaults
+ steps:
+ - run_common_initial_steps
+ - run:
+ name: Publish to Docker Hub
+ command: |
+ TAG_BASE="byoritaly/${CIRCLE_PROJECT_REPONAME}:"
+ IMAGE_TAG=${TAG_BASE}$(cat package.json | jq -r .version)
+ TAGS=( $IMAGE_TAG )
+ if [ "$(git rev-parse HEAD)" == "$(git rev-parse master)" ]; then TAGS=( "${TAGS[@]}" "${TAG_BASE}latest" ); fi
+ docker login -u ${DOCKER_HUB_USER_ID} -p ${DOCKER_HUB_PWD}
+ for TAG in "${TAGS[@]}"; do
+ docker build -t ${TAG} .
+ docker push ${TAG}
+ done
+ docker logout
+workflows:
+ version: 2.1
+ # This runs on non-tag pushes
+ untagged:
+ jobs:
+ - test:
+ context: byor
+ - release:
+ context: byor
+ requires:
+ - test
+ filters:
+ branches:
+ only: master
+ # This only runs on deploy tags and not branches
+ tagged:
+ jobs:
+ - test:
+ <<: *only_tagged_versions
+ context: byor
+ - publish:
+ <<: *only_tagged_versions
+ context: byor
+ requires:
+ - test
diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..6787bc8
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,5 @@
+node_modules
+npm-debug.log
+.git
+dist
+Dockerfile
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..e89330a
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,13 @@
+# Editor configuration, see https://editorconfig.org
+root = true
+
+[*]
+charset = utf-8
+indent_style = space
+indent_size = 2
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[*.md]
+max_line_length = off
+trim_trailing_whitespace = false
diff --git a/.github/bug_report.md b/.github/bug_report.md
new file mode 100644
index 0000000..07fe4a4
--- /dev/null
+++ b/.github/bug_report.md
@@ -0,0 +1,36 @@
+**Describe the bug**
+A clear and concise description of what the bug is.
+
+**To Reproduce**
+Steps to reproduce the behavior:
+1. Go to '...'
+2. Click on '....'
+3. Scroll down to '....'
+4. See error
+
+**Expected behavior**
+A clear and concise description of what you expected to happen.
+
+**Actual behavior**
+What actually happens
+
+**Screenshots**
+If applicable, add screenshots to help explain your problem.
+
+**Desktop (please complete the following information):**
+ - OS: [e.g. iOS]
+ - Browser [e.g. chrome, safari]
+ - Version [e.g. 22]
+
+**Smartphone (please complete the following information):**
+ - Device: [e.g. iPhone6]
+ - OS: [e.g. iOS8.1]
+ - Browser [e.g. stock browser, safari]
+ - Version [e.g. 22]
+
+
+**Reproduces how often**
+What percentage of the time does it reproduce?
+
+**Additional context**
+Add any other context about the problem here.
\ No newline at end of file
diff --git a/.github/feature_request.md b/.github/feature_request.md
new file mode 100644
index 0000000..6e74a07
--- /dev/null
+++ b/.github/feature_request.md
@@ -0,0 +1,11 @@
+**Is your feature request related to a problem? Please describe.**
+A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
+
+**Describe the solution you'd like**
+A clear and concise description of what you want to happen.
+
+**Describe alternatives you've considered**
+A clear and concise description of any alternative solutions or features you've considered.
+
+**Additional context**
+Add any other context or screenshots about the feature request here.
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 0000000..1a3fad6
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,6 @@
+Thank you for your contribution to the byor-voting-web-app repo.
+Before submitting this PR, please make sure:
+
+- [ ] Your code builds clean without any errors or warnings
+- [ ] You are using approved terminology
+- [ ] You have added unit tests
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..30695d7
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,44 @@
+# See http://help.github.com/ignore-files/ for more about ignoring files.
+
+# compiled output
+/dist
+/tmp
+/out-tsc
+
+# dependencies
+/node_modules
+
+# profiling files
+chrome-profiler-events.json
+speed-measure-plugin.json
+
+# IDEs and editors
+/.idea
+.project
+.classpath
+.c9/
+*.launch
+.settings/
+*.sublime-workspace
+
+# IDE - VSCode
+.vscode/*
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
+
+# misc
+/.sass-cache
+/connect.lock
+/coverage
+/libpeerconnection.log
+npm-debug.log
+yarn-error.log
+testem.log
+/typings
+
+# System Files
+.DS_Store
+Thumbs.db
+commands.txt
diff --git a/.make/cd/deploy_aws.sh b/.make/cd/deploy_aws.sh
new file mode 100644
index 0000000..46ebf50
--- /dev/null
+++ b/.make/cd/deploy_aws.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+set -e;
+
+if [ -z "${CI}" ]; then
+ read -e -p "Please enter the target bucket [dev]: " inBucket;
+ read -e -p "Please enter your AWS access key id: " keyid;
+ read -e -p "Please enter your AWS secret access key (input hidden)" -s secretkey;
+ echo ""
+ read -e -p "Please enter your AWS region [us-east-1]: " inAwsRegion;
+else
+ inBucket="${AWS_SERVICE_STAGE}"
+ keyid="${AWS_ACCESS_KEY_ID}"
+ secretkey="${AWS_SECRET_ACCESS_KEY}"
+ inAwsRegion="${AWS_REGION}"
+fi
+
+bucket="${inBucket:-dev}"
+awsRegion="${inAwsRegion:-us-east-1}"
+
+echo "Deploying to bucket: ${bucket} and region: ${awsRegion}"
+
+credentials_file="/root/.aws/credentials"
+read -d '' final_command << EOF || true
+mkdir -p $(dirname ${credentials_file});
+touch ${credentials_file};
+echo '[default]' > ${credentials_file};
+echo 'aws_access_key_id=${keyid}' >> ${credentials_file};
+echo 'aws_secret_access_key=${secretkey}' >> ${credentials_file};
+aws s3 rm s3://${bucket}/ --recursive
+aws s3 cp dist/ng-build-your-own-radar s3://${bucket}/ --recursive
+EOF
+
+/bin/bash .make/utils/execute-in-docker.sh \
+-d "run" \
+-c "/bin/bash -c \"${final_command}\"" \
+-s "byor-app" \
+-o "--rm"
diff --git a/.make/cd/semantic_release.sh b/.make/cd/semantic_release.sh
new file mode 100644
index 0000000..848a513
--- /dev/null
+++ b/.make/cd/semantic_release.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+set -e;
+
+if [ -z "${CI}" ]; then
+ echo "Aborting since this command should be executed from CI/CD pipelines only"
+ exit 1;
+fi
+
+/bin/bash .make/utils/execute-in-docker.sh \
+-d "run" \
+-c "npm run semantic-release" \
+-s "byor-app" \
+-o "--rm"
diff --git a/.make/ci/all.sh b/.make/ci/all.sh
new file mode 100644
index 0000000..8a3810c
--- /dev/null
+++ b/.make/ci/all.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+set -e;
+
+export CI="true"
+
+make install
+make lint
+make unit_tests
+BACKEND_SERVICE_URL=http://localhost:3000/ RADAR_SERVICE_URL=https://radar.thoughtworks.com/ make build
diff --git a/.make/ci/build.sh b/.make/ci/build.sh
new file mode 100644
index 0000000..aaab198
--- /dev/null
+++ b/.make/ci/build.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+set -e;
+
+BACKEND_SERVICE_URL=$(/bin/bash ./.make/utils/get-backend-service-url.sh)
+RADAR_SERVICE_URL=$(/bin/bash ./.make/utils/get-radar-service-url.sh)
+
+echo "Taget backend service: ${BACKEND_SERVICE_URL}"
+echo "Taget radar service: ${RADAR_SERVICE_URL}"
+
+BACKEND_SERVICE_URL="${BACKEND_SERVICE_URL}" RADAR_SERVICE_URL="${RADAR_SERVICE_URL}" /bin/bash .make/utils/execute-in-docker.sh \
+-d "run" \
+-c "npm run build" \
+-s "byor-app" \
+-o "--rm"
diff --git a/.make/ci/install.sh b/.make/ci/install.sh
new file mode 100644
index 0000000..762a866
--- /dev/null
+++ b/.make/ci/install.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+set -e;
+
+/bin/bash .make/utils/execute-in-docker.sh \
+-c "npm install" \
+-s "byor-app" \
+-o "--build --exit-code-from byor-app"
diff --git a/.make/ci/lint.sh b/.make/ci/lint.sh
new file mode 100644
index 0000000..f44a750
--- /dev/null
+++ b/.make/ci/lint.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+set -e;
+
+fix=""
+if [ -z "${CI}" ]; then
+ read -e -p "Do you want to automatically try to fix lint errors? [y/N] " input_fix;
+ if [[ ${input_fix} == y ]]; then
+ fix=":fix"
+ fi
+fi
+
+full_command="npm run lint${fix}"
+echo "About to execute: ${full_command}"
+
+/bin/bash .make/utils/execute-in-docker.sh \
+-d "run" \
+-c "${full_command}" \
+-s "byor-app" \
+-o "--rm"
diff --git a/.make/ci/tests.sh b/.make/ci/tests.sh
new file mode 100644
index 0000000..4db9714
--- /dev/null
+++ b/.make/ci/tests.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+set -e;
+if [ -z $BACKEND_SERVICE_URL ]; then
+ export BACKEND_SERVICE_URL=http://host.docker.internal:3000/
+fi
+
+
+watch=""
+if [ -z "${CI}" ]; then
+ read -e -p "Do you want to run tests in watch mode? [Y/n] " input_watch;
+ if [[ ! ${input_watch} == n ]]; then
+ watch=":watch"
+ fi
+fi
+
+full_command="npm run ${test_script}${watch}"
+echo "About to execute: ${full_command}"
+
+case "${test_script}" in
+ test)
+ /bin/bash .make/utils/execute-in-docker.sh \
+ -c "${full_command}" \
+ -s "byor-app" \
+ -o "--exit-code-from byor-app";;
+ *)
+ echo "ERROR: ${test_script} is not supported"
+ exit 1;;
+esac
diff --git a/.make/development/check_for_secrets.sh b/.make/development/check_for_secrets.sh
new file mode 100644
index 0000000..0683dea
--- /dev/null
+++ b/.make/development/check_for_secrets.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+set -e;
+
+echo "About to run secret disclosure checks with Talisman..."
+docker run \
+ -it \
+ --rm \
+ -v "$PWD:/usr/src" \
+ -v /usr/src/node_modules/ \
+ -v /usr/src/.git/ \
+ -v /usr/src/dist \
+ byoritaly/talisman-checks-runner:0.4.6 \
+ /bin/bash -c "git init &> /dev/null && talisman --pattern \"**\""
+echo "...no secrets found, ok!"
diff --git a/.make/development/cleanup.sh b/.make/development/cleanup.sh
new file mode 100644
index 0000000..e300e68
--- /dev/null
+++ b/.make/development/cleanup.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+set -e;
+
+/bin/bash .make/utils/execute-in-docker.sh \
+-d "rm" \
+-o "-v -s -f"
+
+/bin/bash .make/utils/execute-in-docker.sh \
+-d "down" \
+-o "-v"
+
+read -e -p "Do you also want to remove all unused containers, volumes, networks and images (both dangling and unreferenced)? [y/N] " response;
+if [[ ${response} == y ]]; then
+ echo "Removing all unused containers, volumes, networks and images..."
+ docker system prune --volumes -f
+ echo "...done"
+fi
diff --git a/.make/development/execute_command.sh b/.make/development/execute_command.sh
new file mode 100644
index 0000000..9e9456b
--- /dev/null
+++ b/.make/development/execute_command.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+set -e;
+
+if [ -z "${command}" ]; then
+ read -e -p "Please enter command you wnat to execute: " input_command;
+ if [[ ! -n "${input_command// /}" ]]; then
+ echo "ERROR: command is empty!"
+ exit 1;
+ fi
+ command="${input_command}"
+fi
+
+echo "About to execute \"${command}\" in byor-app container"
+/bin/bash .make/utils/execute-in-docker.sh \
+-d "run" \
+-c "${command}" \
+-s "byor-app" \
+-o "--rm"
diff --git a/.make/development/start.sh b/.make/development/start.sh
new file mode 100644
index 0000000..2940cb6
--- /dev/null
+++ b/.make/development/start.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+set -e;
+
+BACKEND_SERVICE_URL=$(/bin/bash ./.make/utils/get-backend-service-url.sh)
+RADAR_SERVICE_URL=$(/bin/bash ./.make/utils/get-radar-service-url.sh)
+
+echo "Target backend service: ${BACKEND_SERVICE_URL}"
+echo "Target radar service: ${RADAR_SERVICE_URL}"
+
+BACKEND_SERVICE_URL="${BACKEND_SERVICE_URL}" RADAR_SERVICE_URL="${RADAR_SERVICE_URL}" /bin/bash ./.make/utils/execute-in-docker.sh \
+-c "npm run start" \
+-o "--exit-code-from byor-app"
diff --git a/.make/development/stop.sh b/.make/development/stop.sh
new file mode 100644
index 0000000..a2fa6c4
--- /dev/null
+++ b/.make/development/stop.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+set -e;
+
+/bin/bash ./.make/utils/execute-in-docker.sh \
+-d "down"
diff --git a/.make/utils/execute-in-docker.sh b/.make/utils/execute-in-docker.sh
new file mode 100644
index 0000000..0e1ed4a
--- /dev/null
+++ b/.make/utils/execute-in-docker.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+set -e
+
+docker_compose_files=( "docker-compose.yml" )
+services=( )
+docker_compose_command="up"
+while getopts ":c:f:s:o:d:" opt; do
+ case ${opt} in
+ c )
+ command=${OPTARG};;
+ o )
+ docker_compose_options=${OPTARG};;
+ f )
+ docker_compose_files=( "${docker_compose_files[@]}" "${OPTARG}" );;
+ s )
+ services=( "${services[@]}" "${OPTARG}" );;
+ d )
+ docker_compose_command=${OPTARG};;
+ \? )
+ echo "Invalid Option: -${OPTARG}" 1>&2
+ exit 1;;
+ : )
+ echo "Invalid Option: -${OPTARG} requires an argument" 1>&2
+ exit 1;;
+ esac
+done
+
+if [ ! -z "${CIRCLECI}" ]; then
+ docker_compose_files=( "${docker_compose_files[@]}" "docker-compose.circle-ci.yml" )
+fi
+
+files_option=""
+for docker_compose_file in "${docker_compose_files[@]}"; do
+ files_option="${files_option} --file ${docker_compose_file}"
+done
+
+services_string=""
+for service in "${services[@]}"; do
+ services_string="${services_string} ${service}"
+done
+
+if [[ ${docker_compose_command} == up ]]; then
+ docker-compose ${files_option} down
+fi
+
+APP_COMMAND="${command}" docker-compose ${files_option} ${docker_compose_command} ${docker_compose_options:-} ${services_string}
diff --git a/.make/utils/get-backend-service-url.sh b/.make/utils/get-backend-service-url.sh
new file mode 100644
index 0000000..52548dc
--- /dev/null
+++ b/.make/utils/get-backend-service-url.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+set -e;
+
+LOCAL_SERVICE_URL='http://localhost:3000/'
+TEST_MANUAL_SERVICE_URL='https://a818nmuza6.execute-api.us-east-1.amazonaws.com/manualTest/executeService/'
+if [ -z "${BACKEND_SERVICE_URL}" ]; then
+ PS3='Backend service URL: '
+ options=("Local (${LOCAL_SERVICE_URL})" "Dev (${TEST_MANUAL_SERVICE_URL})" "Custom")
+ select opt in "${options[@]}"
+ do
+ case $opt in
+ "Local (${LOCAL_SERVICE_URL})")
+ BACKEND_SERVICE_URL="${LOCAL_SERVICE_URL}"
+ break
+ ;;
+ "Dev (${TEST_MANUAL_SERVICE_URL})")
+ BACKEND_SERVICE_URL="${TEST_MANUAL_SERVICE_URL}"
+ break
+ ;;
+ "Custom")
+ read -e -p "Insert custom URL: " input_backend_url;
+ if [ -z ${input_backend_url} ]; then
+ echo "No URL was specified. Local (${LOCAL_SERVICE_URL}) will be used."
+ BACKEND_SERVICE_URL="${LOCAL_SERVICE_URL}"
+ else
+ BACKEND_SERVICE_URL="${input_backend_url}"
+ fi
+ break
+ ;;
+ *)
+ echo "invalid option $REPLY"
+ echo "No URL was specified. Local (${LOCAL_SERVICE_URL}) will be used."
+ BACKEND_SERVICE_URL="${LOCAL_SERVICE_URL}"
+ break
+ ;;
+ esac
+ done
+fi
+
+echo "${BACKEND_SERVICE_URL}"
diff --git a/.make/utils/get-radar-service-url.sh b/.make/utils/get-radar-service-url.sh
new file mode 100644
index 0000000..3da4411
--- /dev/null
+++ b/.make/utils/get-radar-service-url.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+set -e;
+
+TW_SERVICE_URL='https://radar.thoughtworks.com/'
+TEST_MANUAL_SERVICE_URL='http://build-your-own-radar.s3-website-us-east-1.amazonaws.com/'
+if [ -z "${RADAR_SERVICE_URL}" ]; then
+ PS3='Radar service URL: '
+ options=("Official (${TW_SERVICE_URL})" "Dev (${TEST_MANUAL_SERVICE_URL})" "Custom")
+ select opt in "${options[@]}"
+ do
+ case $opt in
+ "Official (${TW_SERVICE_URL})")
+ RADAR_SERVICE_URL="${TW_SERVICE_URL}"
+ break
+ ;;
+ "Dev (${TEST_MANUAL_SERVICE_URL})")
+ RADAR_SERVICE_URL="${TEST_MANUAL_SERVICE_URL}"
+ break
+ ;;
+ "Custom")
+ read -e -p "Insert custom URL: " input_radar_url;
+ if [ -z ${input_radar_url} ]; then
+ echo "No URL was specified. Official (${TW_SERVICE_URL}) will be used."
+ RADAR_SERVICE_URL="${TW_SERVICE_URL}"
+ else
+ RADAR_SERVICE_URL="${input_radar_url}"
+ fi
+ break
+ ;;
+ *)
+ echo "invalid option $REPLY"
+ echo "No URL was specified. Local (${LOCAL_SERVICE_URL}) will be used."
+ RADAR_SERVICE_URL="${LOCAL_SERVICE_URL}"
+ break
+ ;;
+ esac
+ done
+fi
+
+echo "${RADAR_SERVICE_URL}"
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 0000000..71c868c
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,10 @@
+{
+ "printWidth": 140,
+ "singleQuote": true,
+ "useTabs": false,
+ "tabWidth": 2,
+ "semi": true,
+ "bracketSpacing": true,
+ "arrowParens": "always",
+ "parser": "typescript"
+}
diff --git a/.talismanrc b/.talismanrc
new file mode 100644
index 0000000..bfe0201
--- /dev/null
+++ b/.talismanrc
@@ -0,0 +1,36 @@
+fileignoreconfig:
+- filename: package-lock.json
+ ignore_detectors: [filecontent]
+- filename: .git/hooks/pre-commit.sample
+ ignore_detectors: [filecontent]
+- filename: src/environments/environment.prod.ts
+ ignore_detectors: [filename]
+- filename: src/environments/environment.ts
+ ignore_detectors: [filename]
+- filename: README.md
+ checksum: cdcf339f63fd0e4612941c2d736f6441dcf18322b86a99af2c6d923644b28ebe
+ ignore_detectors: []
+- filename: src/app/utils/utils.spec.ts
+ checksum: 96f4f7aa4bd17b66037dcd3c066dfa5d1e11fa2d44ea6ba3f9d7ad02ec41bff8
+ ignore_detectors: []
+- filename: src/app/modules/login/login.component.ts
+ checksum: 0ac91d9d13996d2f4ddbf714fb797389d6cb621282440cee481a5f850b08e95f
+ ignore_detectors: []
+- filename: src/app/services/backend.service.spec.ts
+ checksum: 11106c6ac0ca3a2a4948a61c8537a9d13a9b47e7f595d79055383db9cf0ceecf
+ ignore_detectors: []
+- filename: docs/images/vote_process.gif
+ checksum: c3a82314b7db3029e5dd9b4226bde884f472561112b4287b5193eeeab1a7cf75
+ ignore_detectors: []
+- filename: docs/build_your_own_radar-welcome-deck.pdf
+ checksum: 354ebd10fca4b0a58f9bcd6d4f73c58814d4fdd8a2da2132ccf940633d34333f
+ ignore_detectors: []
+- filename: charts/byor-voting-web-app-0.1.0.tgz
+ checksum: 4c6848e370f6071f9eab827519447e043714dfb95097438a07110150913c6604
+ ignore_detectors: []
+- filename: charts/index.yaml
+ checksum: 9a353b823ee064904663633b97d6fe7122e05dc9150e1d049781b8d1d0f4bc69
+ ignore_detectors: []
+- filename: .make/cd/deploy_aws.sh
+ checksum: 909387524c726d40c9971b9a2550d783fd5308b356a8ee23eaf704ca6b0d98d3
+ ignore_detectors: []
\ No newline at end of file
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 0000000..78aab34
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,18 @@
+{
+ // Use IntelliSense to learn about possible attributes.
+ // Hover to view descriptions of existing attributes.
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "Current TS File",
+ "type": "node",
+ "request": "launch",
+ "args": ["${relativeFile}"],
+ "runtimeArgs": ["--nolazy", "-r", "ts-node/register"],
+ "sourceMaps": true,
+ "cwd": "${workspaceRoot}",
+ "protocol": "inspector"
+ },
+ ]
+}
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..ebfde9a
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+ "editor.formatOnSave": true,
+}
\ No newline at end of file
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..ba0ab5c
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,76 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as
+contributors and maintainers pledge to making participation in our project and
+our community a harassment-free experience for everyone, regardless of age, body
+size, disability, ethnicity, sex characteristics, gender identity and expression,
+level of experience, education, socio-economic status, nationality, personal
+appearance, race, religion, or sexual identity and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment
+include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or
+ advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic
+ address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+ professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable
+behavior and are expected to take appropriate and fair corrective action in
+response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or
+reject comments, commits, code, wiki edits, issues, and other contributions
+that are not aligned to this Code of Conduct, or to ban temporarily or
+permanently any contributor for other behaviors that they deem inappropriate,
+threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies within all project spaces, and it also applies when
+an individual is representing the project or its community in public spaces.
+Examples of representing a project or community include using an official
+project e-mail address, posting via an official social media account, or acting
+as an appointed representative at an online or offline event. Representation of
+a project may be further defined and clarified by project maintainers.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by joining [BYOR-VotingApp](https://spectrum.chat/byor-votingapp/) community on Spectrum
+ and sending a message to [@zigolab](https://spectrum.chat/users/zigolab). All
+complaints will be reviewed and investigated and will result in a response that
+is deemed necessary and appropriate to the circumstances. The project team is
+obligated to maintain confidentiality with regard to the reporter of an incident.
+Further details of specific enforcement policies may be posted separately.
+
+Project maintainers who do not follow or enforce the Code of Conduct in good
+faith may face temporary or permanent repercussions as determined by other
+members of the project's leadership.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
+available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
+
+[homepage]: https://www.contributor-covenant.org
+
+For answers to common questions about this code of conduct, see
+https://www.contributor-covenant.org/faq
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..2e4edde
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,302 @@
+# Contributing to byor-voting-web-app
+
+First of all, thanks for taking the time to contribute to the project!
+
+The following is a set of guidelines, not rules, for contributing. Feel free to propose changes to this document in a pull request.
+
+#### Table Of Contents
+
+[Code of Conduct](#code-of-conduct)
+
+[Support from the community](#support-from-the-community)
+
+[What should I know before I get started?](#what-should-i-know-before-i-get-started)
+- [BYOR](#byor)
+- [BYOR-VotingApp](#BYOR-VotingApp)
+- [Github Repositories](#github-repositories)
+
+[How Can I Contribute?](#how-can-i-contribute)
+- [Reporting Security Bugs](#reporting-security-bugs)
+- [Reporting Bugs](#reporting-bugs)
+- [Suggesting Enhancements](#suggesting-enhancements)
+- [Pull Requests](#pull-requests)
+
+[Guidelines](#guidelines)
+- [Git Commit Checks](#git-commit-checks)
+- [Release versioning](#release-versioning)
+- [Typescript Styleguide](#typescript-styleguide)
+- [Testing](#testing)
+- [Build the application for Production](#build-the-application-for-production)
+- [Build the docker image](#build-the-docker-image)
+
+[HOWTOs](#howtos)
+- [Running the application locally in watch mode](#running-the-application-locally-in-watch-mode)
+- [Manage application's container](#manage-applications-container)
+- [Running the application from production-grade docker image](#running-the-application-from-production-grade-docker-image)
+
+[Credits](#credits)
+
+## Code of Conduct
+
+This project and everyone participating in it is governed by the [Covenant Code of Conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code.
+
+## Support from the community
+
+You can find out more about how to get in touch with the community in [SUPPORT.md](SUPPORT.md)
+
+## What should I know before I get started?
+The BYOR-VotingApp is a companion app to [build-your-own-radar](https://github.com/thoughtworks/build-your-own-radar) project (aka BYOR).
+
+### BYOR
+Is a library that generates an interactive radar, inspired by [ThoughtWorks Technology Radar](http://thoughtworks.com/radar/).
+
+The radar creation exercise invites you to have a conversation across all organizational levels and review your entire technology portfolio. This enables you to:
+- Objectively assess what's working, and what it isn't
+- Pollinate innovation across teams and experiment accordingly
+- Balance the risk in your technology portfolio
+- Work out what kind of technology organization you want to be
+- Set a path for future success
+
+
+You can generate the radar:
+- running locally the BYOR project
+- submitting your blips in Google Sheet or csv format to the [BUILD YOUR OWN RADAR](https://radar.thoughtworks.com) page
+- running the [BYOR-VotingApp](#BYOR-VotingApp), collecting blips and generating the radar on the fly
+
+### BYOR-VotingApp
+The BYOR-VotingApp helps you to collect blips and to enable conversations during the radar creation exercise.
+
+The BYOR-VotingApp is a SPA (single page application) built with Angular 7 that interacts with a nodejs backend. Data is saved in a MongoDB database.
+
+You can use your MongoDb provider of choice or provision it through the scripts provided in the infrastructure project.
+
+### Github repositories
+
+There is a github respository for the [front-end](https://github.com/thoughtworks/byor-voting-web-app), one for the [back-end](https://github.com/thoughtworks/byor-voting-server), plus one for setting up the necessary [infrastructure](https://github.com/thoughtworks/byor-voting-infrastructure) on Kubernetes or AWS lambda.
+
+## How Can I Contribute?
+
+### Reporting Security Bugs
+
+Security bugs should not be reported as issues. You can find out more about how to report them correctly in [SECURITY.md](SECURITY.md)
+
+### Reporting Bugs
+
+When you are creating a bug report, please [include as many details as possible](#how-do-i-submit-a-good-bug-report). Fill out [the required template](.github/bug_report.md), the information it asks for helps us resolve issues faster.
+
+> **Note:** If you find a **Closed** issue that seems like it is the same thing that you're experiencing, open a new issue and include a link to the original issue in the body of your new one.
+
+#### Before Submitting A Bug Report
+
+- **Determine [which repository the problem should be reported in](#github-repositories)**.
+- **Perform a search in [issues](https://github.com/thoughtworks/byor-voting-web-app/issues)** to see if the problem has already been reported. If it has **and the issue is still open**, add a comment to the existing issue instead of opening a new one.
+
+#### How Do I Submit A (Good) Bug Report?
+
+Bugs are tracked as [GitHub issues](https://guides.github.com/features/issues/). After you've determined [which repository](#github-repositories) your bug is related to, create an issue on that repository and provide the following information by filling in [the template](bug_report.md):
+- **Use a clear and descriptive title** for the issue to identify the problem.
+- **Describe the exact steps which reproduce the problem** in as many details as possible.
+- **Don't just say what you did, but explain how you did it**.
+- **Provide specific examples to demonstrate the steps**. Include links to files or GitHub projects, or copy/pasteable snippets, which you use in those examples. If you're providing snippets in the issue, use [Markdown code blocks](https://help.github.com/articles/markdown-basics/#multiple-lines).
+- **Describe the behavior you observed after following the steps** and point out what exactly is the problem with that behavior.
+- **Explain which behavior you expected to see instead and why.**
+- **Include screenshots and animated GIFs** which show you following the described steps and clearly demonstrate the problem. You can use [this tool](https://www.cockos.com/licecap/) to record GIFs on macOS and Windows, and [this tool](https://github.com/colinkeenan/silentcast) or [this tool](https://github.com/GNOME/byzanz) on Linux.
+- **If the problem wasn't triggered by a specific action**, describe what you were doing before the problem happened and share more information using the guidelines below.
+
+Provide more context by answering these questions:
+
+* **Did the problem start happening recently** (e.g. after updating to a new version) or was this always a problem?
+* If the problem started happening recently, **can you reproduce the problem in an older version?** What's the most recent version in which the problem doesn't happen?
+* **Can you reliably reproduce the issue?** If not, provide details about how often the problem happens and under which conditions it normally happens.
+
+
+### Suggesting Enhancements
+
+When you are creating an enhancement suggestion, please [include as many details as possible](#how-do-i-submit-a-good-enhancement-suggestion). Fill in [the template](.github/feature_request.md), including the steps that you imagine you would take if the feature you're requesting existed.
+
+#### Before Submitting An Enhancement Suggestion
+
+* **Determine [which repository the enhancement should be suggested in](#github-repositories).**
+* **Perform a search in [issues](https://github.com/thoughtworks/byor-voting-web-app/issues)** to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one.
+
+#### How Do I Submit A (Good) Enhancement Suggestion?
+
+Enhancement suggestions are tracked as [GitHub issues](https://guides.github.com/features/issues/). After you've determined [which repository](#github-repositories) your enhancement suggestion is related to, create an issue on that repository and provide the following information:
+
+* **Use a clear and descriptive title** for the issue to identify the suggestion.
+* **Provide a step-by-step description of the suggested enhancement** in as many details as possible.
+* **Describe the current behavior** and **explain which behavior you expected to see instead** and why.
+* **Include screenshots and animated GIFs** which help you demonstrate the steps or point out the part of the application which the suggestion is related to. You can use [this tool](https://www.cockos.com/licecap/) to record GIFs on macOS and Windows, and [this tool](https://github.com/colinkeenan/silentcast) or [this tool](https://github.com/GNOME/byzanz) on Linux.
+
+### Pull Requests
+
+The process described here has several goals:
+
+- Maintain BYOR-VotingApp's quality
+- Fix problems that are important to users
+- Engage the community in working toward the best possible BYOR-VotingApp
+- Enable a sustainable system for BYOR-VotingApp's maintainers to review contributions
+
+Please follow these steps to have your contribution considered by the maintainers:
+
+1. Follow all instructions in [the template](.github/pull_request_template.md)
+2. Follow the [guidelines](#guidelines)
+3. After you submit your pull request, verify that all [status checks](https://help.github.com/articles/about-status-checks/) are passing What if the status checks are failing?If a status check is failing, and you believe that the failure is unrelated to your change, please leave a comment on the pull request explaining why you believe the failure is unrelated. A maintainer will re-run the status check for you. If we conclude that the failure was a false positive, then we will open an issue to track that problem with our status check suite.
+
+While the prerequisites above must be satisfied prior to having your pull request reviewed, the reviewer(s) may ask you to complete additional design work, tests, or other changes before your pull request can be ultimately accepted.
+
+
+## Guidelines
+
+### Git Commit Checks
+
+#### Secrets disclosure prevention
+
+A git pre-commit hook is automatically installed in the local repository via [Husky](https://github.com/typicode/husky) configuration.
+
+This pre-commit hook will run before any commit to scan the project files with [Talisman](https://github.com/thoughtworks/talisman), looking for things that seem suspicious, such as authorization tokens and private keys.
+
+In case there is any suspect of being about to commit some secrets, the commit will be aborted and a detailed report of the suspicious contents will be printed out on the console. Please refer to [Talisman offical documentation](https://github.com/thoughtworks/talisman) for more details about secrets disclosure prevention.
+
+#### Git Commit Messages
+
+Commit are handled with a precommit hook that enforces the commit message structure via [Commitizen](http://commitizen.github.io/cz-cli/).
+
+The adopted commit message structure is the [AngularJS's commit message convention](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#-git-commit-guidelines), also known as [conventional-changelog](https://github.com/conventional-changelog/conventional-changelog).
+
+### Release Versioning
+
+Releases are automated with the [semantic-release](https://semantic-release.gitbook.io/semantic-release/) script that gets executed for any set of commits successfully validated by CI/CD pipelines after a change is pushed to the [master branch](https://github.com/thoughtworks/byor-voting-web-app/tree/master). The semantic-release script takes care of:
+
+- setting the right application version number (based on commits' history and semantic versioning conventions) in package.json and package-lock.json files
+- updating the CHANGELOG.md file based on commits' history
+- pushing a new tag/release to the GitHub repository
+
+### Typescript Styleguide
+
+Typescript styleguide is defined as a set of lint rules.
+
+You can check if your code conforms to them by running:
+
+```shell
+make lint
+```
+
+If not executed in CI mode, the above command will prompt the user for trying to automatically fix linting errors.
+
+### Testing
+
+- **Unit tests** are executed via [Karma](https://karma-runner.github.io) by the following command:
+
+```shell
+make unit_tests
+```
+
+If not executed in CI mode, the above commands will prompt the user for executing tests in watch mode.
+
+- **E2E tests**: *TODO (make unit actual unit, add e2e and move not-unitable tests to e2e)*
+
+### Build the application for Production
+
+To build the app for production use:
+
+```shell
+make build
+```
+
+If no environment variables named `BACKEND_SERVICE_URL` and `RADAR_SERVICE_URL` exist in the current shell, the above command will interactively ask the user for the backend and radar service URL he/she wants to target.
+
+The build artifacts will be stored in the `dist/` directory.
+
+### Build the docker image
+
+```shell
+docker build -t byor-app:latest .
+```
+
+## HOWTOs
+
+### Running the application locally in watch mode
+
+#### Prerequisites
+
+- [GNU Bash](https://www.gnu.org/software/bash/)
+- [GNU Make](https://www.gnu.org/software/make/)
+- [Docker](https://www.docker.com/get-started)
+
+The commands to build, test and deploy the application are managed via `make`, which acts as a facility for executing npm scripts inside a docker container. Execute the following command from the root directory of the project to get the complete list of available make commands:
+
+```shell
+ make
+```
+
+#### First Run
+To use the application you will need a backend running, in local or somewhere elese.
+
+To run the application locally the first time you will need to build it with:
+
+```shell
+ make install
+```
+
+This may take a few minutes.
+
+#### Running web app in watch mode
+
+To start the local web app in watch mode:
+
+```shell
+ make dev_server_start
+```
+
+If no environment variable named `BACKEND_SERVICE_URL` is existing in the current shell, the above command will interactively ask the user for the backend service URL he/she wants to target.
+
+To see the application running, navigate to `http://localhost:4200/`.
+
+To stop the local web app:
+
+```shell
+make dev_server_stop
+```
+
+Clean up the local web app:
+
+```shell
+make dev_clean_up
+```
+
+### Manage application's container
+
+Any arbitrary command can be executed in the context of the application's container via the following command:
+
+```shell
+make execute_command
+```
+
+If no environment variable named `command` is defined in the current shell, the above command will prompt the user for the command to be executed.
+
+To avoid interactive command request, run:
+
+```shell
+command="echo 'replace this echo with real command'" make execute_command
+```
+
+This command can be used to execute Angular CLI commands inside the container, eg:
+
+```shell
+command="npm run ng -- generate service HelloWorld" make execute_command
+```
+
+### Running the application from production-grade docker image
+
+execute:
+
+```shell
+export BACKEND_SERVICE_URL='backend-service-url-here'
+export RADAR_SERVICE_URL='radar-service-url-here'
+export EXPOSED_APP_PORT='exposed-app-port-here'
+docker run -it --rm -p ${EXPOSED_APP_PORT}:80 -e BACKEND_SERVICE_URL -e RADAR_SERVICE_URL byor-app:latest
+```
+
+## Credits
+This guide has been built leveraging the examples found in [Gitub templates](https://help.github.com/en/articles/about-issue-and-pull-request-templates) and in [Atom repository](https://github.com/atom/atom).
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..5d51c21
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,37 @@
+ARG NODE_VERSION=10-alpine
+
+FROM byoritaly/byor-voting-base:${NODE_VERSION} AS dev
+
+# Install Chromium and Chromium ChromeDriver
+RUN apk add --update chromium chromium-chromedriver
+ENV CHROME_BIN="/usr/bin/chromium-browser"
+
+# Install AWS CLI
+RUN apk add --update make curl openssh python py-pip && \
+ pip install awscli --upgrade
+
+FROM node:${NODE_VERSION} AS build
+
+WORKDIR /usr/src/app
+
+COPY package*.json ./
+RUN npm ci
+
+COPY . .
+RUN BACKEND_SERVICE_URL="__BACKEND__SERVICE__URL__PLACEHOLDER__" RADAR_SERVICE_URL="__RADAR__SERVICE__URL__PLACEHOLDER__" npm run build
+
+FROM nginx:1.16-alpine AS prod
+
+ENV BACKEND_SERVICE_URL_PLACEHOLDER="__BACKEND__SERVICE__URL__PLACEHOLDER__" RADAR_SERVICE_URL_PLACEHOLDER="__RADAR__SERVICE__URL__PLACEHOLDER__" NGINX_BASE_DIR="/usr/share/nginx/html"
+
+COPY --from=build /usr/src/app/dist/ng-build-your-own-radar ${NGINX_BASE_DIR}
+
+COPY ./docker-nginx.conf /etc/nginx/conf.d/default.conf
+
+COPY ./docker-entrypoint.sh /
+
+EXPOSE 80
+
+ENTRYPOINT ["/bin/sh", "/docker-entrypoint.sh"]
+
+CMD ["nginx", "-g", "daemon off;"]
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..b67ae0b
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,61 @@
+SHELL:=/bin/bash
+.DEFAULT_GOAL:=help
+
+##@ Building
+
+.PHONY: install build
+
+install: ## Pulls and builds the necessary docker image and then runs npm install from within the container `byor-app`
+ @/bin/bash .make/ci/install.sh
+
+build: ## Builds the app for production use
+ @/bin/bash .make/ci/build.sh
+
+##@ CI
+
+.PHONY: lint unit_tests ci_all
+
+lint: ## Runs lint checks on TS files
+ @/bin/bash .make/ci/lint.sh
+
+unit_tests: ## Runs unit tests
+ @export test_script="test"; /bin/bash .make/ci/tests.sh
+
+ci_all: ## Runs all the following tasks in sequence: install, lint, unit tests, build
+ @/bin/bash .make/ci/all.sh
+
+##@ CD
+
+.PHONY: deploy semantic_release
+
+deploy: ## Deploys on AWS S3
+ @/bin/bash .make/cd/deploy_aws.sh
+
+semantic_release: ## Updates version based on commit messages, commits release notes and pushes release tags
+ @/bin/bash .make/cd/semantic_release.sh
+
+##@ Development
+
+.PHONY: check_for_secrets execute_command dev_server_start dev_server_stop dev_clean_up
+
+check_for_secrets: ## Scan local project files looking for dangerous secrets (this is also run as pre-commit hook)
+ @/bin/bash .make/development/check_for_secrets.sh
+
+execute_command: ## Executes an arbitrary command inside the application's container
+ @/bin/bash .make/development/execute_command.sh
+
+dev_server_start: ## Starts the local dev server
+ @/bin/bash .make/development/start.sh
+
+dev_server_stop: ## Stops the local dev server
+ @/bin/bash .make/development/stop.sh
+
+dev_clean_up: ## Cleans up the local application and its persistent data
+ @/bin/bash .make/development/cleanup.sh
+
+##@ Helpers
+
+.PHONY: help
+
+help: ## Display this help
+ @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-20s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..3d100d5
--- /dev/null
+++ b/README.md
@@ -0,0 +1,102 @@
+# BYOR-VotingApp [web-app]
+
+[](https://circleci.com/gh/byor-italy/byor-app) [](http://commitizen.github.io/cz-cli/) [](https://github.com/semantic-release/semantic-release)
+
+Welcome to the main repository for the **BYOR-VotingApp**!
+
+This repository contains the source code of the **web-app**, if you are looking for information about the **server** component please access [BYOR-VotingApp \[server\]](https://github.com/thoughtworks/byor-voting-server) repository. If you want to explore all the setup and deployment options, take a look at [BYOR-VotingApp \[infrastructure\]](https://github.com/thoughtworks/byor-voting-infrastructure) one.
+
+#### Table Of Contents
+
+[BUILD YOUR OWN RADAR (aka BYOR)](#build-your-own-radar-aka-byor)
+
+[BYOR-VotingApp](#byor-votingapp)
+- [Main features](#main-features)
+- [Running BYOR-VotingApp locally](#running-byor-votingapp-locally)
+- [Running BYOR-VotingApp on Kubernetes or AWS S3](#running-byor-votingapp-on-kubernetes-or-aws-s3)
+
+[Documentation](#documentation)
+
+[How to contribute to the project](#how-to-contribute-to-the-project)
+
+
+
+
+
+## BUILD YOUR OWN RADAR (aka BYOR)
+ThoughtWorks build its own Technology Radar twice a year.
+> you can find the latest edition [here](https://www.thoughtworks.com/radar).
+
+We found it so useful that we decided to share the process and build some tools to help every organization run their own radar creation exercise.
+> you can find more information about the process and how the tech radar works [here](https://www.thoughtworks.com/radar/byor).
+
+Building your own tech radar, invites you to have a conversation across all organizational levels and review your entire technology portfolio.
+
+This enables you to:
+- Objectively assess what's working, and what isn't
+- Pollinate innovation across teams and experiment accordingly
+- Balance the risk in your technology portfolio
+- Work out what kind of technology organization you want to be
+- Set a path for future success
+
+ThoughtWorks encourage you to run the radar twice a year to keep your organisation aware of the fast changing technologies landscape.
+
+
+## BYOR-VotingApp
+
+### Main features
+
+The BYOR-VotingApp comes preloaded with around 943 technologies to choose among and 1.860 blips evaluated by ThoughtWorks to compare with, extracted from TW TechRadar Vol1 up to Vol20.
+
+If you are planning to use the BYOR creation excercise, the BYOR-VotingApp can help you to:
+- [manage one or more BYOR sessions](docs/admin_guide.md#manage-voting-events)
+- load a predefined list of technologies to start with, or use the one already preloaded
+- let people add a new technology if missing
+- [let people vote up to 10 technologies (aka blips)](docs/user_guide.md#vote-for-a-technology)
+- let people write comments about blips
+- :warning: **[*TODO*]** identify technologies where people disagree on rings and a further decision is needed
+- [display the most voted technologies in real-time](docs/admin_guide.md#generate-an-event-word-cloud)
+- [display the final tech radar resulting from the votes collected from the participants of the event](docs/admin_guide.md#generate-an-event-tech-radar)
+- [show, for matching technologies, the ratings coming from the blips collected alognside with the ones published by ThoughtWorks](docs/admin_guide.md#thoughtworks-blips)
+
+All the Data is stored in a MongoDB database.
+
+### Running BYOR-VotingApp locally
+
+1) install [Docker](https://www.docker.com/get-started)
+1) open the terminal
+1) clone the project
+ ```shell
+ git clone https://github.com/thoughtworks/byor-voting-web-app.git
+ ```
+1) move into the project folder
+ ```shell
+ cd byor-voting-web-app
+ ```
+1) startup web app, server, and a local MongoDB
+ ```shell
+ docker-compose -f docker-compose.all.yml up
+ ```
+1) access the application front-end on [http://localhost:4201](http://localhost:4201)
+
+> if needed, application back-end is accessible on [http://localhost:3001](http://localhost:3001) and application's mongo database is accessible at `localhost:27019`
+
+> Please refer to [CONTRIBUTING.md](CONTRIBUTING.md) for more options on running the web app locally.
+
+> Please refer to [BYOR-VotingApp \[server\]](https://github.com/thoughtworks/byor-voting-server) Github repository for more options on running the server locally and connect to a MongoDB database.
+
+### Running BYOR-VotingApp on Kubernetes or AWS S3
+
+Please refer to [BYOR-VotingApp \[infrastructure\]](https://github.com/thoughtworks/byor-voting-infrastructure) Github repository for installing the application on Kubernetes or AWS S3.
+
+## Documentation
+
+In the docs folder you can find:
+- a [deck](docs/build_your_own_radar-welcome-deck.pdf
+) to share or present for explaining what the Tech Radar is and how to rate technologies.
+- the [user guide](docs/user_guide.md)
+- the [admin guide](docs/admin_guide.md)
+
+## How to contribute to the project
+
+Please refer to [CONTRIBUTING.md](CONTRIBUTING.md) for all the information about how to contribute.
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 0000000..9757375
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,12 @@
+# Reporting Security Issues
+
+The BYOR-VotingApp team and community take security bugs seriously. We appreciate your efforts to responsibly disclose your findings, and will make every effort to acknowledge your contributions.
+
+To report a security issue:
+
+1. join [BYOR-VotingApp](https://spectrum.chat/byor-votingapp/) community on Spectrum
+1. send a message to [@zigolab](https://spectrum.chat/users/zigolab) starting with "SECURITY BUG:"
+
+The BYOR-VotingApp team will send a response indicating the next steps in handling your report. After the initial reply to your report, the security team will keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance.
+
+Report security bugs in third-party modules to the person or team maintaining the module. You can also report a vulnerability through the [Node Security Project](https://nodesecurity.io/report).
diff --git a/SUPPORT.md b/SUPPORT.md
new file mode 100644
index 0000000..891934d
--- /dev/null
+++ b/SUPPORT.md
@@ -0,0 +1,9 @@
+# Support from the community
+
+If you're looking for support, reach out our [BYOR-VotingApp](https://spectrum.chat/byor-votingapp/) community on Spectrum.
+
+We have enable the following channels:
+
+- **[General](https://spectrum.chat/byor-votingapp/general)**: for open discussions about current state and future evolutions of the project
+- **[Build&Deploy](https://spectrum.chat/byor-votingapp/build-deploy)**: covering any issue about building and deploying the app
+- **[New Contributors](https://spectrum.chat/byor-votingapp/new-contributors)**: if you have just joined the project and are searching for help, try this channel first.
diff --git a/angular.json b/angular.json
new file mode 100644
index 0000000..1a6fe80
--- /dev/null
+++ b/angular.json
@@ -0,0 +1,141 @@
+{
+ "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
+ "version": 1,
+ "newProjectRoot": "projects",
+ "projects": {
+ "ng-build-your-own-radar": {
+ "root": "",
+ "sourceRoot": "src",
+ "projectType": "application",
+ "prefix": "byor",
+ "schematics": {
+ "@schematics/angular:component": {
+ "styleext": "scss"
+ }
+ },
+ "architect": {
+ "build": {
+ "builder": "ngx-build-plus:build",
+ "options": {
+ "outputPath": "dist/ng-build-your-own-radar",
+ "index": "src/index.html",
+ "main": "src/main.ts",
+ "polyfills": "src/polyfills.ts",
+ "tsConfig": "src/tsconfig.app.json",
+ "assets": [
+ "src/favicon.ico",
+ "src/assets",
+ "src/images"
+ ],
+ "styles": [
+ "src/styles.scss"
+ ],
+ "scripts": []
+ },
+ "configurations": {
+ "production": {
+ "fileReplacements": [
+ {
+ "replace": "src/environments/environment.ts",
+ "with": "src/environments/environment.prod.ts"
+ }
+ ],
+ "optimization": true,
+ "outputHashing": "all",
+ "sourceMap": false,
+ "extractCss": true,
+ "namedChunks": false,
+ "aot": true,
+ "extractLicenses": true,
+ "vendorChunk": false,
+ "buildOptimizer": true,
+ "budgets": [
+ {
+ "type": "initial",
+ "maximumWarning": "2mb",
+ "maximumError": "5mb"
+ }
+ ]
+ }
+ }
+ },
+ "serve": {
+ "builder": "ngx-build-plus:dev-server",
+ "options": {
+ "browserTarget": "ng-build-your-own-radar:build"
+ },
+ "configurations": {
+ "production": {
+ "browserTarget": "ng-build-your-own-radar:build:production"
+ }
+ }
+ },
+ "extract-i18n": {
+ "builder": "@angular-devkit/build-angular:extract-i18n",
+ "options": {
+ "browserTarget": "ng-build-your-own-radar:build"
+ }
+ },
+ "test": {
+ "builder": "ngx-build-plus:karma",
+ "options": {
+ "main": "src/test.ts",
+ "polyfills": "src/polyfills.ts",
+ "tsConfig": "src/tsconfig.spec.json",
+ "karmaConfig": "src/karma.conf.js",
+ "styles": [
+ "src/styles.scss"
+ ],
+ "scripts": [],
+ "assets": [
+ "src/favicon.ico",
+ "src/assets",
+ "src/images"
+ ]
+ }
+ },
+ "lint": {
+ "builder": "@angular-devkit/build-angular:tslint",
+ "options": {
+ "tsConfig": [
+ "src/tsconfig.app.json",
+ "src/tsconfig.spec.json"
+ ],
+ "exclude": [
+ "**/node_modules/**"
+ ]
+ }
+ }
+ }
+ },
+ "ng-build-your-own-radar-e2e": {
+ "root": "e2e/",
+ "projectType": "application",
+ "prefix": "",
+ "architect": {
+ "e2e": {
+ "builder": "@angular-devkit/build-angular:protractor",
+ "options": {
+ "protractorConfig": "e2e/protractor.conf.js",
+ "devServerTarget": "ng-build-your-own-radar:serve"
+ },
+ "configurations": {
+ "production": {
+ "devServerTarget": "ng-build-your-own-radar:serve:production"
+ }
+ }
+ },
+ "lint": {
+ "builder": "@angular-devkit/build-angular:tslint",
+ "options": {
+ "tsConfig": "e2e/tsconfig.e2e.json",
+ "exclude": [
+ "**/node_modules/**"
+ ]
+ }
+ }
+ }
+ }
+ },
+ "defaultProject": "ng-build-your-own-radar"
+}
diff --git a/charts/byor-voting-web-app-0.1.0.tgz b/charts/byor-voting-web-app-0.1.0.tgz
new file mode 100644
index 0000000..92a207a
Binary files /dev/null and b/charts/byor-voting-web-app-0.1.0.tgz differ
diff --git a/charts/byor-voting-web-app/.helmignore b/charts/byor-voting-web-app/.helmignore
new file mode 100644
index 0000000..50af031
--- /dev/null
+++ b/charts/byor-voting-web-app/.helmignore
@@ -0,0 +1,22 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/charts/byor-voting-web-app/Chart.yaml b/charts/byor-voting-web-app/Chart.yaml
new file mode 100644
index 0000000..08341b0
--- /dev/null
+++ b/charts/byor-voting-web-app/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: BYOR-VotingApp [web-app] helm chart
+name: byor-voting-web-app
+version: 0.1.0
diff --git a/charts/byor-voting-web-app/templates/deployment.yaml b/charts/byor-voting-web-app/templates/deployment.yaml
new file mode 100644
index 0000000..eed04fd
--- /dev/null
+++ b/charts/byor-voting-web-app/templates/deployment.yaml
@@ -0,0 +1,26 @@
+apiVersion: extensions/v1beta1
+kind: Deployment
+metadata:
+ name: {{ .Values.name }}
+ namespace: {{ .Values.namespace }}
+spec:
+ selector:
+ matchLabels:
+ app: {{ .Values.name }}
+ replicas: {{ .Values.replicaCount }}
+ template:
+ metadata:
+ labels:
+ app: {{ .Values.name }}
+ spec:
+ containers:
+ - name: {{ .Values.name }}
+ image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ ports:
+ - containerPort: {{ .Values.containerPort}}
+ env:
+ - name: BACKEND_SERVICE_URL
+ value: {{ .Values.backendServiceUrl }}
+ - name: RADAR_SERVICE_URL
+ value: {{ .Values.radarServiceUrl }}
\ No newline at end of file
diff --git a/charts/byor-voting-web-app/templates/service.yaml b/charts/byor-voting-web-app/templates/service.yaml
new file mode 100644
index 0000000..efea5e4
--- /dev/null
+++ b/charts/byor-voting-web-app/templates/service.yaml
@@ -0,0 +1,16 @@
+apiVersion: v1
+kind: Service
+metadata:
+ namespace: {{ .Values.namespace }}
+ name: {{ .Values.name }}
+ labels:
+ app: {{ .Values.name }}
+ service: {{ .Values.name }}
+spec:
+ selector:
+ app: {{ .Values.name }}
+ ports:
+ - name: http
+ port: {{ .Values.service.port }}
+ nodePort: {{ .Values.service.nodePort }}
+ type: {{ .Values.service.type }}
\ No newline at end of file
diff --git a/charts/byor-voting-web-app/values.local.yaml b/charts/byor-voting-web-app/values.local.yaml
new file mode 100644
index 0000000..a0cd275
--- /dev/null
+++ b/charts/byor-voting-web-app/values.local.yaml
@@ -0,0 +1,16 @@
+replicaCount: 1
+name: byor-voting-web-app
+namespace: byor
+image:
+ repository: byoritaly/byor-voting-web-app
+ tag: latest
+ pullPolicy: IfNotPresent
+
+containerPort: 80
+service:
+ port: 80
+ nodePort: 30080
+ type: NodePort
+ backendServiceUrl: 'http://localhost:30090/'
+ radarServiceUrl: 'https://radar.thoughtworks.com/'
+ replicaCount: 1
\ No newline at end of file
diff --git a/charts/byor-voting-web-app/values.yaml b/charts/byor-voting-web-app/values.yaml
new file mode 100644
index 0000000..8a80a59
--- /dev/null
+++ b/charts/byor-voting-web-app/values.yaml
@@ -0,0 +1,14 @@
+replicaCount: 1
+name: byor-voting-web-app
+namespace: byor
+image:
+ repository: byoritaly/byor-voting-web-app
+ tag: latest
+ pullPolicy: IfNotPresent
+
+containerPort: 80
+service:
+ port: 80
+ type: ClusterIP
+ backendServiceUrl: /api/
+ radarServiceUrl: 'https://radar.thoughtworks.com/'
\ No newline at end of file
diff --git a/charts/index.yaml b/charts/index.yaml
new file mode 100644
index 0000000..6abbe3d
--- /dev/null
+++ b/charts/index.yaml
@@ -0,0 +1,13 @@
+apiVersion: v1
+entries:
+ byor-voting-web-app:
+ - apiVersion: v1
+ appVersion: "1.0"
+ created: 2019-06-13T10:25:01.749495+02:00
+ description: BYOR-VotingApp [web-app] helm chart
+ digest: 2254feeedf2a40db5b60a1ea089c672894bdee38c3489b767a31f45a189b2858
+ name: byor-voting-web-app
+ urls:
+ - byor-voting-web-app-0.1.0.tgz
+ version: 0.1.0
+generated: 2019-06-13T10:25:01.748928+02:00
diff --git a/docker-compose.all.yml b/docker-compose.all.yml
new file mode 100644
index 0000000..ab3b89f
--- /dev/null
+++ b/docker-compose.all.yml
@@ -0,0 +1,34 @@
+version: '3.7'
+
+services:
+
+ mongo:
+ image: mongo:4.0
+ volumes:
+ - local_all_mongo_data:/data/db
+ ports:
+ - 27019:27017
+
+ byor-backend:
+ image: byoritaly/byor-backend:latest
+ depends_on:
+ - mongo
+ ports:
+ - 3001:3000
+ environment:
+ MONGO_URI: 'mongodb://mongo/'
+ MONGO_URI_ADMIN: 'mongodb://mongo/'
+ MONGO_DB_NAME: 'byor'
+
+ byor-app:
+ image: byoritaly/byor-app:latest
+ depends_on:
+ - byor-backend
+ ports:
+ - 4201:80
+ environment:
+ BACKEND_SERVICE_URL: 'http://localhost:3001/'
+ RADAR_SERVICE_URL: 'https://radar.thoughtworks.com/'
+
+volumes:
+ local_all_mongo_data:
diff --git a/docker-compose.circle-ci.yml b/docker-compose.circle-ci.yml
new file mode 100644
index 0000000..bb6cfe7
--- /dev/null
+++ b/docker-compose.circle-ci.yml
@@ -0,0 +1,14 @@
+version: '3.7'
+
+services:
+
+ byor-app:
+ volumes:
+ - byor_app_ssh:/root/.ssh
+ environment:
+ CI:
+ GITHUB_TOKEN:
+
+volumes:
+ byor_app:
+ byor_app_ssh:
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..894e7b4
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,25 @@
+version: '3.7'
+
+services:
+
+ byor-app:
+ build:
+ context: .
+ target: dev
+ image: byor-app
+ volumes:
+ - byor_app:/usr/src/app
+ ports:
+ - 4200:4200
+ environment:
+ BACKEND_SERVICE_URL:
+ RADAR_SERVICE_URL:
+ command: ${APP_COMMAND:-}
+
+volumes:
+ byor_app:
+ driver: local
+ driver_opts:
+ type: none
+ device: $PWD
+ o: bind
diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh
new file mode 100644
index 0000000..77f1e7d
--- /dev/null
+++ b/docker-entrypoint.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+set -e;
+
+echo "Backend service url is being set to: ${BACKEND_SERVICE_URL}"
+echo "Radar service url is being set to: ${RADAR_SERVICE_URL}"
+
+find ${NGINX_BASE_DIR} -type f | xargs sed -i "s|${BACKEND_SERVICE_URL_PLACEHOLDER}|${BACKEND_SERVICE_URL}|g"
+find ${NGINX_BASE_DIR} -type f | xargs sed -i "s|${RADAR_SERVICE_URL_PLACEHOLDER}|${RADAR_SERVICE_URL}|g"
+
+exec "$@"
diff --git a/docker-nginx.conf b/docker-nginx.conf
new file mode 100644
index 0000000..6d089a4
--- /dev/null
+++ b/docker-nginx.conf
@@ -0,0 +1,10 @@
+server {
+
+ listen 80;
+
+ location / {
+ root /usr/share/nginx/html;
+ try_files $uri $uri/ /index.html;
+ }
+
+}
diff --git a/docs/admin_guide.md b/docs/admin_guide.md
new file mode 100644
index 0000000..2253124
--- /dev/null
+++ b/docs/admin_guide.md
@@ -0,0 +1,114 @@
+# Admin Guide
+In this guide we will see how to login into the administration panel to manage voting sessions and check the generated radar.
+
+## Table of contents
+* [Before starting](#before-starting)
+* [Login into the administration panel](#login-into-the-administration-panel)
+* [Manage voting events](#manage-voting-events)
+ * [Create a new event](#create-a-new-event)
+ * [Open and close events to users votes](#open-and-close-events-to-users-votes)
+ * [Check voters](#check-voters)
+ * [Generate an event tech radar](#generate-an-event-tech-radar)
+ * [ThoughtWorks blips](#thoughtworks-blips)
+ * [Generate an event word cloud](#generate-an-event-word-cloud)
+
+## Before starting
+Before starting be sure to have an instance of the web app and the backend running. Refer to the [README](/README.md) file for more information on how to set it up.
+
+**In this guide we assume that you are running a local instance of the web app**, hence the URLs are all referring to localhost.
+If that's not the case please simply replace localhost with your domain of choice.
+
+## Login into the administration panel
+To login into the administration panel you can proceed in two ways:
+
+1. Navigate to [http://localhost:4200/admin](http://localhost:4200/admin)
+2. Navigate to [http://localhost:4200](http://localhost:4200) and click on the version number in the right bottom corner as highlighted in the following image:
+
+
+
+
+
+You should be prompted with a login form where you need to insert the administration credentials. The default credentials are:
+
+* **User:** abc
+* **Password:** 123
+
+
+
+
+
+If credentials are valid you will see the administration panel.
+
+## Manage voting events
+In this section we will see how to create and manage the details of your voting events.
+
+### Create a new event
+To create a new event simply follow these steps:
+
+1. Click on the **Name** input under the **New event** section
+2. Insert the event name
+3. Click on **Create** button
+
+The event will be created and you should see a confirmation message.
+
+The new event name will also be visibile from the dropdown list in the **Single event** section.
+
+### Open and close events to users votes
+When a new event is created it will still be not open to accept votes from users. This means that when a user open the web application, will not be able to select the event and express votes on it.
+
+To open an event to users votes you just need to:
+
+1. Select the name of the event that you want to open from the dropdown list in the **Single event** section
+2. A few buttons will appear. Click on **Open Event**
+
+
+
+The event will be opened and some control buttons will appear along with a confirmation message like in the following image:
+
+
+
+If you want to close you will just need to click on the **Close Event** button. An event can be opened and closed multiple times without any consequences on the votes.
+
+### Check voters
+To have a list of all the voters first and last name for a given event, follow these steps:
+
+1. Select an event name from the dropdown list in the **Single event** section
+2. If the event is open you will see a **Voters** button. Click on it
+3. You will see a page with the list of voters first and last name
+
+At the top of the page you will also have a **And the winner is...** button that allows you to randomly select a voter from the list in case you are running some kind of contest during the event. :smile:
+
+### Generate an event tech radar
+To generate the tech radar based on the votes of a specific event, follow these steps:
+
+1. Select an event name from the dropdown list in the **Single event** section
+2. If the event is open you will see a **Tech radar** button. Click on it
+3. A new page will be open, showing the ThoughtWorks tech radar based on users votes during the event
+
+
+
+
+
+It's also possible to generate a tech radar based on the votes generated through all the events opened so far by simply clicking on the **Tech radar** button in the **All events** section of the page.
+
+### ThoughtWorks blips
+In the generated tech radar, along with the blips resulting from votes collected during the event, you will also be able to see the official ThoughtWorks ratings for all those blips that matches the ones in the official tech radar
+
+
+
+
+
+### Generate an event word cloud
+It's possible to generate a word cloud based on the votes of a specific event following these steps:
+
+1. Select an event name from the dropdown list in the **Single event** section
+2. If the event is open you will see a **Word cloud** button. Click on it
+3. A new page will be open, showing the word cloud based on users votes during the event
+
+
+
+
+
+Blips names will have a different color based on their quadrant and a different size based on the number of times they were voted.
+
+It's also possible to generate a word cloud based on the votes generated through all the events opened so far by simply clicking on the **Word cloud** button in the **All events** section of the page.
\ No newline at end of file
diff --git a/docs/build_your_own_radar-welcome-deck.pdf b/docs/build_your_own_radar-welcome-deck.pdf
new file mode 100644
index 0000000..9050a45
Binary files /dev/null and b/docs/build_your_own_radar-welcome-deck.pdf differ
diff --git a/docs/images/admin_login_form.png b/docs/images/admin_login_form.png
new file mode 100644
index 0000000..3206fe9
Binary files /dev/null and b/docs/images/admin_login_form.png differ
diff --git a/docs/images/generated_tech_radar.png b/docs/images/generated_tech_radar.png
new file mode 100644
index 0000000..59ba6ac
Binary files /dev/null and b/docs/images/generated_tech_radar.png differ
diff --git a/docs/images/generated_word_cloud.png b/docs/images/generated_word_cloud.png
new file mode 100644
index 0000000..5fe2a68
Binary files /dev/null and b/docs/images/generated_word_cloud.png differ
diff --git a/docs/images/go_to_admin_login.png b/docs/images/go_to_admin_login.png
new file mode 100644
index 0000000..22d84a6
Binary files /dev/null and b/docs/images/go_to_admin_login.png differ
diff --git a/docs/images/open_event.png b/docs/images/open_event.png
new file mode 100644
index 0000000..56db429
Binary files /dev/null and b/docs/images/open_event.png differ
diff --git a/docs/images/opened_event.png b/docs/images/opened_event.png
new file mode 100644
index 0000000..a6ab7ff
Binary files /dev/null and b/docs/images/opened_event.png differ
diff --git a/docs/images/splash_screen.png b/docs/images/splash_screen.png
new file mode 100644
index 0000000..d004158
Binary files /dev/null and b/docs/images/splash_screen.png differ
diff --git a/docs/images/tw_blips.gif b/docs/images/tw_blips.gif
new file mode 100644
index 0000000..3a6721b
Binary files /dev/null and b/docs/images/tw_blips.gif differ
diff --git a/docs/images/vote_login.png b/docs/images/vote_login.png
new file mode 100644
index 0000000..b37e5e4
Binary files /dev/null and b/docs/images/vote_login.png differ
diff --git a/docs/images/vote_process.gif b/docs/images/vote_process.gif
new file mode 100644
index 0000000..23d8491
Binary files /dev/null and b/docs/images/vote_process.gif differ
diff --git a/docs/images/votes_bar.gif b/docs/images/votes_bar.gif
new file mode 100644
index 0000000..a1ea4e4
Binary files /dev/null and b/docs/images/votes_bar.gif differ
diff --git a/docs/user_guide.md b/docs/user_guide.md
new file mode 100644
index 0000000..b5b0563
--- /dev/null
+++ b/docs/user_guide.md
@@ -0,0 +1,51 @@
+# User Guide
+In this guide we will see how a user of the voting app can join an open event and express their votes.
+
+
+
+
+
+## Table of contents
+* [Before starting](#before-starting)
+* [Join an event](#join-an-event)
+* [Search for a specific technology](#search-for-a-specific-technology)
+* [Vote for a technology](#vote-for-a-technology)
+
+## Before starting
+**In this guide we assume that the instance we are referring to is a local one**, hence the URLs are all referring to localhost.
+If that's not the case please simply replace localhost with your domain of choice.
+
+## Join an event
+In order to start voting you will need to join an open event following these steps:
+
+1. Navigate to [http://localhost:4200](http://localhost:4200)
+2. In case more than one event is open, select the one you want to join from the dropdown list at the top of the page. Note that if one event is open, you will only see the event name without any dropdown list
+3. Insert your first and last name and click the **Start Session** button
+
+**Please note that you can join and vote for an event only once.**
+
+You will be prompted with the main voting page where you can search technologies and vote the ones that you prefer.
+
+## Search for a specific technology
+As soon as you join an event you will be prompted with a long list of technologies to choose from by scrolling them. However you may find more easy to directly search the ones that you're interested in.
+
+That's why the voting app allows you to search for a specific technology in two ways:
+
+1. **Search bar:** At the top of the page you can start typing the name of the technology that you are interested in and the list will be filtered automatically
+2. **Quadrant filters**: Under the search bar you will find four buttons that matches the ThoughtWorks Radar quadrants names: *Tools*, *Languages & Frameworks*, *Platforms*, *Techniques*. Clicking on one of these will filter the list of technologies showing only the ones that belongs to the selected quadrant
+
+## Vote for a technology
+You can vote for **up to 10 technologies** by following these steps:
+
+1. Click on the card with the name of the technology that you are interested in
+2. A dialog will be popup showing the technology name and four buttons that matches the ThoughtWorks Radar rings names: *Adopt*, *Assess*, *Trial* and *Hold*
+3. If unsure about the rings meanings you can click on the question mark icon in the top right corner of the dialog to have a quick description of them
+4. Select the ring where you think the technology belongs to
+
+Before submitting your votes you will be able to review them all by clicking on the bar at the bottom of the page
+
+