refactor and split into components