├── .gitignore
├── .idea
└── jsLibraryMappings.xml
├── LICENSE
├── README.md
├── backend
├── README.md
├── config
│ ├── app_dev.json
│ ├── app_prod.json
│ ├── app_stag.json
│ ├── app_test.json
│ └── index.js
├── index.js
├── knexfile.js
├── package.json
├── server.js
├── src
│ ├── controllers
│ │ ├── AuthController.js
│ │ ├── OrganisationController.js
│ │ ├── ProjectController.js
│ │ ├── ProjectRevisionController.js
│ │ ├── UserController.js
│ │ └── UserSessionController.js
│ ├── db
│ │ ├── index.js
│ │ ├── migrations
│ │ │ └── 20150920121341_initial.js
│ │ ├── models
│ │ │ ├── Organisation.js
│ │ │ ├── OrganisationUser.js
│ │ │ ├── Project.js
│ │ │ ├── ProjectEnvInfo.js
│ │ │ ├── ProjectFile.js
│ │ │ ├── ProjectRevision.js
│ │ │ ├── ProjectRole.js
│ │ │ ├── ProjectTeam.js
│ │ │ ├── ProjectUser.js
│ │ │ ├── Team.js
│ │ │ ├── TeamRole.js
│ │ │ ├── TeamUser.js
│ │ │ ├── User.js
│ │ │ └── UserSession.js
│ │ ├── schemas
│ │ │ └── schema.js
│ │ ├── seeds
│ │ │ ├── data.json
│ │ │ ├── data_team.json
│ │ │ └── init.js
│ │ └── utils
│ │ │ └── dbUtil.js
│ ├── plugins
│ │ └── .gitkeep
│ ├── routes
│ │ └── v1
│ │ │ ├── auth.js
│ │ │ ├── organisations.js
│ │ │ ├── projects.js
│ │ │ └── users.js
│ └── services
│ │ ├── AuthService.js
│ │ ├── OrganisationService.js
│ │ └── ProjectService.js
└── test
│ ├── .gitkeep
│ ├── integration
│ └── controllers
│ │ ├── auth.js
│ │ ├── organisation.js
│ │ ├── project.js
│ │ └── user.js
│ └── unit
│ └── services
│ ├── organisation.js
│ └── project.js
├── design
├── builder
│ ├── Gruntfile.js
│ ├── README.md
│ ├── app
│ │ ├── builder-step-1.html
│ │ ├── builder-step-2.html
│ │ ├── builder-step-3.html
│ │ ├── builder-step-4.html
│ │ ├── builder-step-5.html
│ │ ├── builder-step-6.html
│ │ ├── builder-step-7.html
│ │ ├── dashboard-company.html
│ │ ├── dashboard-individual.html
│ │ ├── favicon.ico
│ │ ├── images
│ │ │ ├── after.png
│ │ │ ├── avatar.png
│ │ │ ├── before.png
│ │ │ ├── header.jpg
│ │ │ ├── logo.png
│ │ │ ├── option-dropdown.png
│ │ │ ├── screenshot-background.jpg
│ │ │ ├── screenshot.png
│ │ │ └── screenshot@2x.png
│ │ ├── index.html
│ │ ├── login.html
│ │ ├── register-company.html
│ │ ├── register-individual.html
│ │ ├── register.html
│ │ └── styles
│ │ │ ├── components
│ │ │ ├── button.scss
│ │ │ ├── comparison.scss
│ │ │ ├── content.scss
│ │ │ ├── flexbox.scss
│ │ │ ├── footer.scss
│ │ │ ├── form.scss
│ │ │ ├── header.scss
│ │ │ ├── icon-block.scss
│ │ │ ├── image-builder.scss
│ │ │ ├── list.scss
│ │ │ ├── menu.scss
│ │ │ ├── page-title.scss
│ │ │ ├── plan.scss
│ │ │ ├── responsive.scss
│ │ │ ├── screenshot.scss
│ │ │ ├── section.scss
│ │ │ ├── spacer.scss
│ │ │ ├── sub-content.scss
│ │ │ ├── sub-menu.scss
│ │ │ └── wrapper.scss
│ │ │ ├── config.scss
│ │ │ ├── general
│ │ │ ├── base.scss
│ │ │ ├── reset.scss
│ │ │ └── typography.scss
│ │ │ ├── lib
│ │ │ └── bootstrap-grid.scss
│ │ │ ├── main.scss
│ │ │ └── mixins
│ │ │ ├── responsive.scss
│ │ │ └── transition.scss
│ ├── bower.json
│ ├── dist
│ │ ├── builder-step-1.html
│ │ ├── builder-step-2.html
│ │ ├── builder-step-3.html
│ │ ├── builder-step-4.html
│ │ ├── builder-step-5.html
│ │ ├── builder-step-6.html
│ │ ├── builder-step-7.html
│ │ ├── dashboard-company.html
│ │ ├── dashboard-individual.html
│ │ ├── favicon.9c8b2c34.ico
│ │ ├── images
│ │ │ ├── after.05b33e94.png
│ │ │ ├── avatar.d75d42ca.png
│ │ │ ├── before.62605ac2.png
│ │ │ ├── header.ab829a6e.jpg
│ │ │ ├── logo.363f07b8.png
│ │ │ ├── option-dropdown.a34aaed1.png
│ │ │ ├── screenshot-background.3c42b64a.jpg
│ │ │ ├── screenshot.5761ec41.png
│ │ │ └── screenshot@2x.9b390fb5.png
│ │ ├── index.html
│ │ ├── login.html
│ │ ├── register-company.html
│ │ ├── register-individual.html
│ │ ├── register.html
│ │ └── scripts
│ │ │ └── vendor
│ │ │ └── modernizr.1cb556bb.js
│ ├── package.json
│ └── test
│ │ ├── index.html
│ │ └── spec
│ │ └── test.js
├── frontpage
│ ├── Gruntfile.js
│ ├── app
│ │ ├── builder-step-1.html
│ │ ├── builder-step-2.html
│ │ ├── builder-step-3.html
│ │ ├── builder-step-4.html
│ │ ├── builder-step-5.html
│ │ ├── builder-step-6.html
│ │ ├── builder-step-7.html
│ │ ├── favicon.ico
│ │ ├── images
│ │ │ ├── after.png
│ │ │ ├── avatar.png
│ │ │ ├── before.png
│ │ │ ├── header.jpg
│ │ │ ├── logo.png
│ │ │ ├── option-dropdown.png
│ │ │ ├── screenshot-background.jpg
│ │ │ ├── screenshot.png
│ │ │ └── screenshot@2x.png
│ │ ├── index.html
│ │ ├── login.html
│ │ └── styles
│ │ │ ├── components
│ │ │ ├── button.scss
│ │ │ ├── comparison.scss
│ │ │ ├── content.scss
│ │ │ ├── flexbox.scss
│ │ │ ├── footer.scss
│ │ │ ├── header.scss
│ │ │ ├── icon-block.scss
│ │ │ ├── image-builder.scss
│ │ │ ├── list.scss
│ │ │ ├── menu.scss
│ │ │ ├── page-title.scss
│ │ │ ├── plan.scss
│ │ │ ├── screenshot.scss
│ │ │ ├── section.scss
│ │ │ ├── spacer.scss
│ │ │ ├── sub-content.scss
│ │ │ ├── sub-menu.scss
│ │ │ └── wrapper.scss
│ │ │ ├── config.scss
│ │ │ ├── general
│ │ │ ├── base.scss
│ │ │ ├── reset.scss
│ │ │ └── typography.scss
│ │ │ ├── lib
│ │ │ └── bootstrap-grid.scss
│ │ │ ├── main.scss
│ │ │ ├── mixins
│ │ │ ├── responsive.scss
│ │ │ └── transition.scss
│ │ │ └── style.css
│ ├── bower.json
│ ├── dist
│ │ ├── builder-step-1.html
│ │ ├── builder-step-2.html
│ │ ├── builder-step-3.html
│ │ ├── builder-step-4.html
│ │ ├── builder-step-5.html
│ │ ├── builder-step-6.html
│ │ ├── builder-step-7.html
│ │ ├── favicon.ba8ce5ed.ico
│ │ ├── images
│ │ │ ├── after.05b33e94.png
│ │ │ ├── avatar.d75d42ca.png
│ │ │ ├── before.62605ac2.png
│ │ │ ├── header.ab829a6e.jpg
│ │ │ ├── logo.df56c44c.png
│ │ │ ├── option-dropdown.a34aaed1.png
│ │ │ ├── screenshot-background.3c42b64a.jpg
│ │ │ ├── screenshot.5761ec41.png
│ │ │ └── screenshot@2x.9b390fb5.png
│ │ ├── index.html
│ │ ├── login.html
│ │ └── scripts
│ │ │ └── vendor
│ │ │ └── modernizr.1cb556bb.js
│ ├── package.json
│ └── test
│ │ ├── index.html
│ │ └── spec
│ │ └── test.js
└── launch-page
│ ├── favicon.ico
│ ├── images
│ ├── after.png
│ ├── avatar.png
│ ├── before.png
│ ├── brewr.png
│ ├── header.jpg
│ ├── logo.png
│ ├── option-dropdown.png
│ ├── screenshot-background.jpg
│ ├── screenshot.png
│ └── screenshot@2x.png
│ ├── index.html
│ └── styles
│ ├── components
│ ├── button.scss
│ ├── comparison.scss
│ ├── content.scss
│ ├── flexbox.scss
│ ├── footer.scss
│ ├── header.scss
│ ├── icon-block.scss
│ ├── image-builder.scss
│ ├── list.scss
│ ├── menu.scss
│ ├── page-title.scss
│ ├── plan.scss
│ ├── screenshot.scss
│ ├── section.scss
│ ├── spacer.scss
│ ├── sub-content.scss
│ ├── sub-menu.scss
│ └── wrapper.scss
│ ├── config.scss
│ ├── general
│ ├── base.scss
│ ├── reset.scss
│ └── typography.scss
│ ├── lib
│ └── bootstrap-grid.scss
│ ├── main.css
│ ├── main.scss
│ ├── mixins
│ ├── responsive.scss
│ └── transition.scss
│ └── prepros.cfg
├── frontend
├── .babelrc
├── .editorconfig
├── .eslintrc
├── .gitignore
├── README.md
├── bower.json
├── package.json
├── server.js
├── src
│ ├── actions
│ │ ├── AuthActions.js
│ │ ├── AuthServerActions.js
│ │ ├── BuilderActions.js
│ │ ├── DockerHubActions.js
│ │ ├── OrganisationActions.js
│ │ ├── OrganisationServerActions.js
│ │ ├── ProjectActions.js
│ │ └── ProjectServerActions.js
│ ├── components
│ │ ├── App
│ │ │ ├── App.js
│ │ │ ├── App.scss
│ │ │ └── package.json
│ │ ├── BaseComponent.js
│ │ ├── elements
│ │ │ ├── AssignableMemberList
│ │ │ │ ├── AssignableMemberList.js
│ │ │ │ ├── AssignableMemberList.scss
│ │ │ │ └── avatar.png
│ │ │ ├── Builder
│ │ │ │ ├── Builder.js
│ │ │ │ ├── Builder.scss
│ │ │ │ ├── option-dropdown-accent.png
│ │ │ │ ├── option-dropdown-success.png
│ │ │ │ ├── option-dropdown.png
│ │ │ │ ├── package.json
│ │ │ │ ├── step1.js
│ │ │ │ ├── step2.js
│ │ │ │ ├── step3.js
│ │ │ │ ├── step4.js
│ │ │ │ ├── step5.js
│ │ │ │ └── step6.js
│ │ │ ├── Button
│ │ │ │ ├── Button.js
│ │ │ │ ├── Button.scss
│ │ │ │ └── package.json
│ │ │ ├── CRUDList
│ │ │ │ ├── CRUDList.js
│ │ │ │ ├── CRUDList.scss
│ │ │ │ └── package.json
│ │ │ ├── DistributionPicker
│ │ │ │ ├── DistributionItem.js
│ │ │ │ ├── DistributionPicker.js
│ │ │ │ ├── DistributionPicker.scss
│ │ │ │ └── package.json
│ │ │ ├── Divider
│ │ │ │ ├── Divider.js
│ │ │ │ ├── Divider.scss
│ │ │ │ └── package.json
│ │ │ ├── DockerHubSearch
│ │ │ │ ├── DockerHubSearch.js
│ │ │ │ ├── DockerHubSearch.scss
│ │ │ │ └── package.json
│ │ │ ├── DockerfileViewer
│ │ │ │ ├── DockerfileViewer.js
│ │ │ │ ├── DockerfileViewer.scss
│ │ │ │ └── package.json
│ │ │ ├── Dropdown
│ │ │ │ ├── Dropdown.js
│ │ │ │ ├── Dropdown.scss
│ │ │ │ ├── option-dropdown-accent.png
│ │ │ │ ├── option-dropdown-success.png
│ │ │ │ ├── option-dropdown.png
│ │ │ │ └── package.json
│ │ │ ├── DropdownMenu
│ │ │ │ ├── DropdownMenu.js
│ │ │ │ ├── DropdownMenu.scss
│ │ │ │ ├── DropdownMenuItem.js
│ │ │ │ ├── caret_down.png
│ │ │ │ └── package.json
│ │ │ ├── FlexContainer
│ │ │ │ ├── FlexContainer.js
│ │ │ │ ├── FlexContainer.scss
│ │ │ │ └── package.json
│ │ │ ├── Footer
│ │ │ │ ├── Footer.js
│ │ │ │ ├── Footer.scss
│ │ │ │ └── package.json
│ │ │ ├── Form
│ │ │ │ ├── Form.js
│ │ │ │ ├── Form.scss
│ │ │ │ └── package.json
│ │ │ ├── HeaderSmall
│ │ │ │ ├── HeaderSmall.js
│ │ │ │ ├── HeaderSmall.scss
│ │ │ │ └── package.json
│ │ │ ├── Image
│ │ │ │ ├── Image.js
│ │ │ │ ├── Image.scss
│ │ │ │ └── package.json
│ │ │ ├── InlineContainer
│ │ │ │ ├── InlineContainer.js
│ │ │ │ ├── InlineContainer.scss
│ │ │ │ └── package.json
│ │ │ ├── Input
│ │ │ │ ├── Input.js
│ │ │ │ ├── Input.scss
│ │ │ │ └── package.json
│ │ │ ├── List
│ │ │ │ ├── List.js
│ │ │ │ ├── List.scss
│ │ │ │ └── package.json
│ │ │ ├── ListItem
│ │ │ │ ├── Constants.js
│ │ │ │ ├── ListItem.js
│ │ │ │ ├── ListItem.scss
│ │ │ │ └── package.json
│ │ │ ├── ListItemMove
│ │ │ │ ├── Constants.js
│ │ │ │ ├── ListItemMove.js
│ │ │ │ ├── ListItemMove.scss
│ │ │ │ └── package.json
│ │ │ ├── Logo
│ │ │ │ ├── Logo.js
│ │ │ │ ├── Logo.scss
│ │ │ │ ├── logo.png
│ │ │ │ └── package.json
│ │ │ ├── MemberList
│ │ │ │ ├── MemberList.js
│ │ │ │ ├── MemberList.scss
│ │ │ │ └── avatar.png
│ │ │ ├── Panel
│ │ │ │ ├── Panel.js
│ │ │ │ ├── Panel.scss
│ │ │ │ └── package.json
│ │ │ ├── ProjectFileTable
│ │ │ │ └── ProjectFileTable.js
│ │ │ ├── ProjectRevisionTable
│ │ │ │ └── ProjectRevisionTable.js
│ │ │ ├── SideMenu
│ │ │ │ ├── SideMenu.js
│ │ │ │ ├── SideMenu.scss
│ │ │ │ ├── SideMenuContainer.js
│ │ │ │ ├── SideMenuItem.js
│ │ │ │ └── package.json
│ │ │ ├── TabContainer
│ │ │ │ ├── TabContainer.js
│ │ │ │ ├── TabContainer.scss
│ │ │ │ ├── TabItem.js
│ │ │ │ └── package.json
│ │ │ ├── Table
│ │ │ │ ├── Table.js
│ │ │ │ ├── Table.scss
│ │ │ │ ├── TableButtons.js
│ │ │ │ ├── TableButtons.scss
│ │ │ │ ├── index.js
│ │ │ │ └── package.json
│ │ │ ├── TextBox
│ │ │ │ ├── TextBox.js
│ │ │ │ ├── TextBox.scss
│ │ │ │ └── package.json
│ │ │ ├── Tooltip
│ │ │ │ ├── Tooltip.js
│ │ │ │ ├── Tooltip.scss
│ │ │ │ └── package.json
│ │ │ ├── ValidateInput
│ │ │ │ └── ValidateInput.js
│ │ │ └── Wizard
│ │ │ │ ├── Wizard.js
│ │ │ │ ├── Wizard.scss
│ │ │ │ ├── WizardItem.js
│ │ │ │ └── package.json
│ │ ├── layouts
│ │ │ ├── DashboardLayout
│ │ │ │ ├── DashboardLayout.js
│ │ │ │ ├── DashboardLayout.scss
│ │ │ │ └── package.json
│ │ │ └── MainLayout
│ │ │ │ ├── MainLayout.js
│ │ │ │ ├── MainLayout.scss
│ │ │ │ └── package.json
│ │ ├── pages
│ │ │ ├── Builder
│ │ │ │ ├── Builder.js
│ │ │ │ ├── Builder.scss
│ │ │ │ └── package.json
│ │ │ ├── Dashboard
│ │ │ │ ├── Dashboard.js
│ │ │ │ ├── Dashboard.scss
│ │ │ │ └── package.json
│ │ │ ├── Home
│ │ │ │ ├── Home.js
│ │ │ │ ├── Home.scss
│ │ │ │ ├── after.png
│ │ │ │ ├── before.png
│ │ │ │ ├── header.jpg
│ │ │ │ ├── logo.png
│ │ │ │ ├── option-dropdown.png
│ │ │ │ ├── package.json
│ │ │ │ ├── screenshot-background.jpg
│ │ │ │ ├── screenshot.png
│ │ │ │ └── screenshot@2x.png
│ │ │ ├── Login
│ │ │ │ ├── Login.js
│ │ │ │ ├── Login.scss
│ │ │ │ └── package.json
│ │ │ ├── Logout
│ │ │ │ ├── Logout.js
│ │ │ │ └── package.json
│ │ │ ├── Members
│ │ │ │ ├── Members.js
│ │ │ │ └── package.json
│ │ │ ├── NotFound
│ │ │ │ ├── NotFound.js
│ │ │ │ └── package.json
│ │ │ ├── Project
│ │ │ │ ├── Project.js
│ │ │ │ ├── Project.scss
│ │ │ │ ├── avatar.png
│ │ │ │ └── package.json
│ │ │ ├── ProjectEditImage
│ │ │ │ ├── ProjectEditImage.js
│ │ │ │ ├── ProjectEditImage.scss
│ │ │ │ └── package.json
│ │ │ └── Register
│ │ │ │ ├── Register.js
│ │ │ │ ├── Register.scss
│ │ │ │ └── package.json
│ │ └── variables.css
│ ├── constants
│ │ ├── ActionTypes.js
│ │ ├── DockerHubConstants.js
│ │ ├── LoginConstants.js
│ │ ├── ProjectConstants.js
│ │ └── RegisterConstants.js
│ ├── css
│ │ ├── colors.js
│ │ ├── colors.scss
│ │ └── dimensions.scss
│ ├── dispatchers
│ │ └── AppDispatcher.js
│ ├── index.js
│ ├── index.tpl.html
│ ├── routes.js
│ ├── services
│ │ ├── DockerHubService.js
│ │ ├── ProjectService.js
│ │ ├── RouterContainer.js
│ │ └── TeamService.js
│ ├── stores
│ │ ├── AuthStore.js
│ │ ├── BaseStore.js
│ │ ├── DashboardStore.js
│ │ ├── DockerHubStore.js
│ │ ├── OrganisationStore.js
│ │ ├── ProjectEditImageStore.js
│ │ └── ProjectStore.js
│ ├── utils
│ │ ├── AuthAPIUtils.js
│ │ ├── OrganisationAPIUtils.js
│ │ └── ProjectAPIUtils.js
│ └── validators
│ │ ├── Validator.js
│ │ └── constraints
│ │ ├── ConfirmConstraint.js
│ │ ├── Constraint.js
│ │ ├── EmailConstraint.js
│ │ ├── IsRequiredConstraint.js
│ │ └── LengthConstraint.js
├── webpack.config.js
└── webpack.production.config.js
└── project
├── .editorconfig
├── .gitignore
├── .sailsrc
├── Gruntfile.js
├── README.md
├── api
├── controllers
│ ├── .gitkeep
│ ├── AuthController.js
│ ├── OrganisationController.js
│ ├── ProjectController.js
│ ├── ProjectRevisionController.js
│ ├── UserController.js
│ └── UserSessionController.js
├── models
│ ├── .gitkeep
│ ├── Organisation.js
│ ├── OrganisationUser.js
│ ├── Project.js
│ ├── ProjectEnvInfo.js
│ ├── ProjectFile.js
│ ├── ProjectRevision.js
│ ├── ProjectUser.js
│ ├── User.js
│ └── UserSession.js
├── policies
│ └── isAuthenticated.js
├── responses
│ ├── badRequest.js
│ ├── created.js
│ ├── forbidden.js
│ ├── notFound.js
│ ├── ok.js
│ ├── serverError.js
│ └── unauthorized.js
└── services
│ ├── .gitkeep
│ └── AuthService.js
├── app.js
├── assets
├── favicon.ico
├── images
│ └── .gitkeep
├── js
│ └── dependencies
│ │ └── sails.io.js
├── robots.txt
├── styles
│ └── importer.less
└── templates
│ └── .gitkeep
├── config
├── blueprints.js
├── bootstrap.js
├── connections.js
├── cors.js
├── csrf.js
├── env
│ ├── development.js
│ └── production.js
├── globals.js
├── http.js
├── i18n.js
├── locales
│ ├── _README.md
│ ├── de.json
│ ├── en.json
│ ├── es.json
│ └── fr.json
├── log.js
├── models.js
├── passport.js
├── policies.js
├── routes.js
├── session.js
├── sockets.js
└── views.js
├── package.json
├── tasks
├── README.md
├── config
│ ├── clean.js
│ ├── coffee.js
│ ├── concat.js
│ ├── copy.js
│ ├── cssmin.js
│ ├── jst.js
│ ├── less.js
│ ├── sails-linker.js
│ ├── sync.js
│ ├── uglify.js
│ └── watch.js
├── pipeline.js
└── register
│ ├── build.js
│ ├── buildProd.js
│ ├── compileAssets.js
│ ├── default.js
│ ├── linkAssets.js
│ ├── linkAssetsBuild.js
│ ├── linkAssetsBuildProd.js
│ ├── prod.js
│ └── syncAssets.js
├── test
└── fixtures
│ ├── organisation.json
│ ├── organisationuser.json
│ ├── project.json
│ ├── projectuser.json
│ └── user.json
└── views
├── 403.ejs
├── 404.ejs
├── 500.ejs
├── homepage.ejs
└── layout.ejs
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 |
5 | # Runtime data
6 | pids
7 | *.pid
8 | *.seed
9 |
10 | # Directory for instrumented libs generated by jscoverage/JSCover
11 | lib-cov
12 |
13 | # Coverage directory used by tools like istanbul
14 | coverage
15 |
16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
17 | .grunt
18 |
19 | # node-waf configuration
20 | .lock-wscript
21 |
22 | # Compiled binary addons (http://nodejs.org/api/addons.html)
23 | build/Release
24 |
25 | # Dependency directory
26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
27 | node_modules
28 |
29 | # Stupid temp dir
30 | .tmp
31 |
--------------------------------------------------------------------------------
/.idea/jsLibraryMappings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Introduction
2 | Brewr was designed as a tool to automatically manage your development environment. The vision was that a company would be able to sign-up and generate their "local development environments" through an easy to use GUI editor. Once that was done companies could then add developers to the project so that they could download and use the environment on their computer through the push of a button.
3 |
4 | Once updates were available for a certain image, the app should then download them and automatically install them without any downtime on the developer his/her pc.
5 |
6 | # Why it was halted
7 | The project was halted because of the lack of time, the idea together with the dashboard was developed and coded by [Xavier Geerinck (@XavierGeerinck)](https://twitter.com/XavierGeerinck), most of the design work was done by [Jesper Lindström](https://twitter.com/jesperlindstrom). After a few months my brother came along to help [Maxim Geerinck](https://twitter.com/c4d3r).
8 |
9 | I am sad to disband this project because I think it still has a lot of potential, but I hope that someone else willl pick it up and eventually transform it in a startup. I however do hope that once this happens I will get to see credits towards me for the initial idea.
10 |
--------------------------------------------------------------------------------
/backend/config/app_dev.json:
--------------------------------------------------------------------------------
1 | {
2 | "database": {
3 | "client": "postgresql",
4 | "connection": {
5 | "database": "brewr",
6 | "user": "postgres",
7 | "password": "root",
8 | "port": 5432,
9 | "host": "localhost"
10 | },
11 | "pool": {
12 | "min": 2,
13 | "max": 10
14 | },
15 | "migrations": {
16 | "tableName": "knex_migrations",
17 | "directory": "./src/db/migrations"
18 | },
19 | "seeds": {
20 | "directory": "./src/db/seeds"
21 | }
22 | },
23 | "server": {
24 | "ip": "0.0.0.0",
25 | "port": 8000,
26 | "cors_client_origins": [ "*" ],
27 | "cors_headers": [ "Authorization", "Content-Type", "If-None-Match", "Bearer", "x-http-method-override" ],
28 | "cors_methods": [ "GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS" ],
29 | "cors_credentials": true,
30 | "is_debug": true,
31 | "enable_docs": true
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/backend/config/app_prod.json:
--------------------------------------------------------------------------------
1 | {
2 | "database": {
3 | "client": "postgresql",
4 | "connection": {
5 | "database": "brewr",
6 | "user": "postgres",
7 | "password": "root",
8 | "port": 5432,
9 | "host": "localhost"
10 | },
11 | "pool": {
12 | "min": 2,
13 | "max": 10
14 | },
15 | "migrations": {
16 | "tableName": "knex_migrations",
17 | "directory": "./src/db/migrations"
18 | },
19 | "seeds": {
20 | "directory": "./src/db/seeds"
21 | }
22 | },
23 | "server": {
24 | "ip": "0.0.0.0",
25 | "port": 8000,
26 | "cors_client_origins": [ "*" ],
27 | "cors_headers": [ "Authorization", "Content-Type", "If-None-Match", "Bearer", "x-http-method-override" ],
28 | "cors_methods": [ "GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS" ],
29 | "cors_credentials": true,
30 | "is_debug": true,
31 | "enable_docs": false
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/backend/config/app_stag.json:
--------------------------------------------------------------------------------
1 | {
2 | "database": {
3 | "client": "postgresql",
4 | "connection": {
5 | "database": "brewr",
6 | "user": "postgres",
7 | "password": "root",
8 | "port": 5432,
9 | "host": "localhost"
10 | },
11 | "pool": {
12 | "min": 2,
13 | "max": 10
14 | },
15 | "migrations": {
16 | "tableName": "knex_migrations",
17 | "directory": "./src/db/migrations"
18 | },
19 | "seeds": {
20 | "directory": "./src/db/seeds"
21 | }
22 | },
23 | "server": {
24 | "ip": "0.0.0.0",
25 | "port": 8000,
26 | "cors_client_origins": [ "*" ],
27 | "cors_headers": [ "Authorization", "Content-Type", "If-None-Match", "Bearer", "x-http-method-override" ],
28 | "cors_methods": [ "GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS" ],
29 | "cors_credentials": true,
30 | "is_debug": true,
31 | "enable_docs": false
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/backend/config/app_test.json:
--------------------------------------------------------------------------------
1 | {
2 | "database": {
3 | "client": "postgresql",
4 | "connection": {
5 | "database": "brewr",
6 | "user": "postgres",
7 | "password": "root",
8 | "port": 5432,
9 | "host": "localhost"
10 | },
11 | "pool": {
12 | "min": 2,
13 | "max": 10
14 | },
15 | "migrations": {
16 | "tableName": "knex_migrations",
17 | "directory": "./src/db/migrations"
18 | },
19 | "seeds": {
20 | "directory": "./src/db/seeds"
21 | }
22 | },
23 | "server": {
24 | "ip": "0.0.0.0",
25 | "port": 8000,
26 | "cors_client_origins": [ "*" ],
27 | "cors_headers": [ "Authorization", "Content-Type", "If-None-Match", "Bearer", "x-http-method-override" ],
28 | "cors_methods": [ "GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS" ],
29 | "cors_credentials": true,
30 | "is_debug": false,
31 | "enable_docs": true
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/backend/config/index.js:
--------------------------------------------------------------------------------
1 | var defaultenv = 'dev';
2 | var allowed = ['dev', 'stag', 'prod', 'test'];
3 |
4 | var config;
5 |
6 | if ((allowed.indexOf(process.argv[2]) === -1) && !process.env.NODE_ENV) {
7 | config = require(process.cwd() + '/config/app_dev');
8 | } else {
9 | config = require(process.cwd() + '/config/app_' + (process.env.NODE_ENV || process.argv[2] || defaultenv));
10 | }
11 |
12 | module.exports = config;
13 |
--------------------------------------------------------------------------------
/backend/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // Server require
4 | var server = require('./server');
5 | var config = require('./config');
6 |
7 | // Start
8 | server.start(function (err) {
9 | if (err) {
10 | throw err;
11 | }
12 |
13 | console.log('Server started on ' + config.server.ip + ':' + config.server.port);
14 | server.log(['info', 'server'], 'Server started on ' + config.server.ip + ':' + config.server.port);
15 | });
16 |
--------------------------------------------------------------------------------
/backend/knexfile.js:
--------------------------------------------------------------------------------
1 | var config = require('./config');
2 | module.exports = config.database
3 |
--------------------------------------------------------------------------------
/backend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "main": "./index.js",
3 | "name": "Brewr-Backend",
4 | "private": true,
5 | "version": "0.0.0",
6 | "dependencies": {
7 | "async": "^1.4.2",
8 | "bcrypt": "0.8.5",
9 | "bluebird": "^2.10.0",
10 | "bookshelf": "^0.8.2",
11 | "boom": "^2.8.0",
12 | "code": "^1.5.0",
13 | "dogwater": "^1.0.1",
14 | "hapi": "^10.0.0",
15 | "hapi-auth-bearer-simple": "^1.2.3",
16 | "inert": "^3.1.0",
17 | "joi": "^6.7.0",
18 | "knex": "^0.8.6",
19 | "lab": "^6.1.0",
20 | "lodash": "^3.10.1",
21 | "lout": "^7.2.0",
22 | "node-uuid": "^1.4.3",
23 | "pg": "^4.4.1",
24 | "require-all": "^1.1.0",
25 | "sails-postgresql": "^0.10.16",
26 | "underscore": "^1.8.3",
27 | "uuid": "^2.0.1",
28 | "vision": "^3.0.0"
29 | },
30 | "scripts": {
31 | "test": "lab -a code -v -t 90 -m 6000"
32 | },
33 | "devDependencies": {
34 | "code": "^1.5.0",
35 | "lab": "^5.18.1"
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/backend/src/controllers/ProjectRevisionController.js:
--------------------------------------------------------------------------------
1 | /**
2 | * ProjectRevisionController
3 | *
4 | * @description :: Server-side logic for managing projectrevisions
5 | * @help :: See http://sailsjs.org/#!/documentation/concepts/Controllers
6 | */
7 |
8 | module.exports = {
9 |
10 | };
11 |
12 |
--------------------------------------------------------------------------------
/backend/src/controllers/UserSessionController.js:
--------------------------------------------------------------------------------
1 | /**
2 | * UserSessionController
3 | *
4 | * @description :: Server-side logic for managing usersessions
5 | * @help :: See http://sailsjs.org/#!/documentation/concepts/Controllers
6 | */
7 |
8 | exports.getCurrent = function (request, reply) {
9 | // TODO
10 | };
11 |
12 | exports.getAll = function (request, reply) {
13 | // TODO
14 | };
15 |
16 | exports.removeByToken = function (request, reply) {
17 | // TODO
18 | };
19 |
20 | exports.removeAll = function (request, reply) {
21 | // TODO
22 | };
23 |
--------------------------------------------------------------------------------
/backend/src/db/index.js:
--------------------------------------------------------------------------------
1 | var config = require('../../config');
2 | var knex = require('knex')(config.database);
3 | var bookshelf = require('bookshelf')(knex);
4 |
5 | // Load the visibility plugin so that we can hide fields with hidden: []
6 | bookshelf.plugin('visibility');
7 |
8 | // Load the registry plugin so that we register the models first
9 | bookshelf.plugin('registry');
10 |
11 | bookshelf.plugin('virtuals');
12 |
13 | module.exports = bookshelf;
14 |
--------------------------------------------------------------------------------
/backend/src/db/models/Organisation.js:
--------------------------------------------------------------------------------
1 | var Bookshelf = require('../');
2 | var uuid = require('node-uuid');
3 | var User = require('./User');
4 | var OrganisationUser = require('./OrganisationUser');
5 | var ProjectUser = require('./ProjectUser');
6 | var Project = require('./Project');
7 |
8 | var Organisation = Bookshelf.model('Organisation', {
9 | tableName: 'organisation',
10 | hasTimestamps: true, // Define that we update the created_at and updated_at on change
11 | hidden: [ ],
12 |
13 | // On creation, set uuid
14 | initialize: function(params) {
15 | this.on('saving', this._generateUUID);
16 | },
17 |
18 | _generateUUID: function (model, attrs, options) {
19 | if (model.isNew()) {
20 | model.set('uuid', uuid.v4());
21 | }
22 | },
23 |
24 | owner: function () {
25 | return this.belongsTo('User');
26 | },
27 | created_by: function() {
28 | return this.belongsTo('User', 'created_by');
29 | },
30 | projects: function () {
31 | return this.hasMany('Project');
32 | },
33 | users: function () {
34 | return this.belongsToMany('User', 'organisation_user', 'organisation_id', 'user_id').withPivot('is_manager');;
35 | }
36 | });
37 |
38 | module.exports = Organisation;
39 |
--------------------------------------------------------------------------------
/backend/src/db/models/OrganisationUser.js:
--------------------------------------------------------------------------------
1 | var Bookshelf = require('../');
2 | var User = require('./User');
3 | var Organisation = require('./Organisation');
4 |
5 | var OrganisationUser = Bookshelf.model('OrganisationUser', {
6 | tableName: 'organisation_user',
7 | idAttribute: [ 'user_id', 'organisation_id' ],
8 | organisation: function () {
9 | return this.belongsTo('Organisation');
10 | },
11 | user: function() {
12 | return this.belongsTo('User');
13 | }
14 | });
15 |
16 | module.exports = OrganisationUser;
17 |
--------------------------------------------------------------------------------
/backend/src/db/models/Project.js:
--------------------------------------------------------------------------------
1 | var Bookshelf = require('../');
2 | var User = require('./User');
3 | var ProjectRevision = require('./ProjectRevision');
4 | var Organisation = require('./Organisation');
5 |
6 | var Project = Bookshelf.model('Project', {
7 | tableName: 'project',
8 | hasTimestamps: true, // Define that we update the created_at and updated_at on change
9 | hidden: [ 'users' ],
10 | virtuals: {
11 | members: function () {
12 | var members = this.related('users');
13 | members.push(this.related('created_by'));
14 | return members;
15 | }
16 | },
17 | owner: function () {
18 | return this.belongsTo('User');
19 | },
20 | created_by: function() {
21 | return this.belongsTo('User', 'created_by');
22 | },
23 | users: function () {
24 | return this.belongsToMany('User', 'project_user', 'project_id', 'user_id').withPivot('is_manager');
25 | },
26 |
27 | revisions: function () {
28 | return this.hasMany('ProjectRevision');
29 | },
30 | organisation: function () {
31 | return this.belongsTo('Organisation');
32 | },
33 |
34 | // many-to-many
35 | projectTeams: function() {
36 | return this.hasMany('ProjectTeam');
37 | },
38 | projectUsers: function () {
39 | return this.hasMany('ProjectUser');
40 | },
41 | });
42 |
43 | module.exports = Project;
44 |
--------------------------------------------------------------------------------
/backend/src/db/models/ProjectEnvInfo.js:
--------------------------------------------------------------------------------
1 | var Bookshelf = require('../');
2 | var ProjectRevision = require('./ProjectRevision');
3 |
4 | var ProjectEnvInfo = Bookshelf.model('ProjectEnvInfo', {
5 | tableName: 'project_env_info',
6 | // A projectEnvInfo always belongs to one or more revisions (more if not changed)
7 | projectRevision: function () {
8 | return this.hasMany('ProjectRevision');
9 | }
10 | });
11 |
12 | module.exports = ProjectEnvInfo;
13 |
--------------------------------------------------------------------------------
/backend/src/db/models/ProjectFile.js:
--------------------------------------------------------------------------------
1 | var Bookshelf = require('../');
2 | var User = require('./User');
3 | var ProjectRevision = require('./ProjectRevision');
4 |
5 | var ProjectFile = Bookshelf.model('ProjectFile', {
6 | tableName: 'project_file',
7 | projectRevisions: function () {
8 | // model jointable col1 col2
9 | return this.belongsToMany('ProjectRevision', 'project_revision_file', 'project_revision_id', 'project_file_id');
10 | },
11 | added_by: function () {
12 | return this.belongsTo('User');
13 | }
14 | });
15 |
16 | module.exports = ProjectFile;
17 |
--------------------------------------------------------------------------------
/backend/src/db/models/ProjectRevision.js:
--------------------------------------------------------------------------------
1 | var Bookshelf = require('../');
2 | var Project = require('./Project');
3 | var ProjectFile = require('./ProjectFile');
4 | var ProjectUser = require('./ProjectUser');
5 |
6 | var ProjectRevision = Bookshelf.model('ProjectRevision', {
7 | tableName: 'project_revision',
8 | hasTimestamps: true, // Define that we update the created_at and updated_at on change
9 | users: function () {
10 | return this.belongsToMany('ProjectUser');
11 | },
12 | project: function () {
13 | return this.belongsTo('Project');
14 | },
15 | // Many to many, a file can belong to multiple revs since we can reuse them if not changed
16 | projectFiles: function () {
17 | // model jointable col1 col2
18 | return this.belongsToMany('ProjectFile', 'project_revision_file', 'project_file_id', 'project_revision_id');
19 | },
20 | // A projectRevision always has an environmentInfo
21 | projectEnvInfo: function () {
22 | return this.belongsTo('ProjectEnvInfo');
23 | }
24 | });
25 |
26 | module.exports = ProjectRevision;
27 |
--------------------------------------------------------------------------------
/backend/src/db/models/ProjectRole.js:
--------------------------------------------------------------------------------
1 | var Bookshelf = require('../')
2 | , User = require('./User')
3 | , Project = require('./Project');
4 |
5 | var ProjectRole = Bookshelf.model('ProjectRole', {
6 | tableName: 'project_role',
7 | hasTimestamps: true,
8 | project: function() {
9 | return this.belongsTo('Project');
10 | },
11 | user: function() {
12 | return this.belongsTo('User');
13 | }
14 | });
15 |
16 | module.exports = ProjectRole;
--------------------------------------------------------------------------------
/backend/src/db/models/ProjectTeam.js:
--------------------------------------------------------------------------------
1 | var Bookshelf = require('../')
2 | , User = require('./User')
3 | , Team = require('./Team');
4 |
5 | var ProjectTeam = Bookshelf.model('ProjectTeam', {
6 | tableName: 'project_team',
7 | idAttribute: [ 'user_id', 'team_id' ],
8 | project: function () {
9 | return this.belongsTo('Project');
10 | },
11 | team: function() {
12 | return this.belongsTo('Team');
13 | }
14 | });
15 |
16 | module.exports = ProjectTeam;
17 |
--------------------------------------------------------------------------------
/backend/src/db/models/ProjectUser.js:
--------------------------------------------------------------------------------
1 | var Bookshelf = require('../');
2 | var User = require('./User');
3 | var Project = require('./Project');
4 |
5 | var ProjectUser = Bookshelf.model('ProjectUser', {
6 | tableName: 'project_user',
7 | idAttribute: [ 'user_id', 'project_id' ],
8 | project: function () {
9 | return this.belongsTo('Project');
10 | },
11 | user: function() {
12 | return this.belongsTo('User');
13 | }
14 | });
15 |
16 | module.exports = ProjectUser;
17 |
--------------------------------------------------------------------------------
/backend/src/db/models/Team.js:
--------------------------------------------------------------------------------
1 | var Bookschelf = require('../')
2 | , User = require('./User')
3 | , Organisation = require('./Organisation')
4 | , Project = require('./Project')
5 | , ProjectTeam = require('./ProjectTeam');
6 |
7 | var Team = Bookschelf.model('Team', {
8 |
9 | tableName: 'team',
10 | hasTimestamps: true,
11 | team_leader: function() {
12 | return this.belongsTo('User');
13 | },
14 | organisation: function() {
15 | return this.belongsTo('Organisation');
16 | },
17 | created_by: function() {
18 | return this.belongsTo('User');
19 | },
20 |
21 | // many-to-many
22 | projectTeams: function() {
23 | return this.hasMany('ProjectTeam');
24 | },
25 |
26 | // one-to-many
27 | members: function(){
28 | return this.belongsToMany('User');
29 | },
30 | projects: function() {
31 | return this.belongsToMany('Project');
32 | }
33 | });
34 |
35 | module.exports = Team;
--------------------------------------------------------------------------------
/backend/src/db/models/TeamRole.js:
--------------------------------------------------------------------------------
1 | var Bookshelf = require('../')
2 | , User = require('./User')
3 | , Team = require('./Team');
4 |
5 | var TeamRole = Bookshelf.model('TeamRole', {
6 | tableName: 'team_role',
7 | hasTimestamps: true,
8 | team: function() {
9 | return this.belongsTo('Team');
10 | },
11 | user: function() {
12 | return this.belongsTo('User');
13 | }
14 | });
15 |
16 | module.exports = TeamRole;
--------------------------------------------------------------------------------
/backend/src/db/models/TeamUser.js:
--------------------------------------------------------------------------------
1 | var Bookshelf = require('../')
2 | , User = require('./User')
3 | , Team = require('./Team');
4 |
5 | var TeamUser= Bookshelf.model('TeamUser', {
6 | tableName: 'team_user',
7 |
8 | // many-to-one
9 | team: function () {
10 | return this.belongsTo('Team');
11 | },
12 | user: function() {
13 | return this.belongsTo('User');
14 | }
15 | });
16 |
17 | module.exports = TeamUser;
18 |
--------------------------------------------------------------------------------
/backend/src/db/models/UserSession.js:
--------------------------------------------------------------------------------
1 | var Bookshelf = require('../');
2 | var User = require('./User');
3 |
4 | var UserSession = Bookshelf.Model.extend({
5 | tableName: 'user_session',
6 | hasTimestamps: true, // Define that we update the created_at and updated_at on change
7 | user: function () {
8 | return this.belongsTo('User');
9 | }
10 | });
11 |
12 | module.exports = Bookshelf.model('UserSession', UserSession);
13 |
--------------------------------------------------------------------------------
/backend/src/db/seeds/init.js:
--------------------------------------------------------------------------------
1 | var data = require('./data.json');
2 | var async = require('async');
3 | var dbUtil = require('../utils/dbUtil');
4 |
5 | exports.seed = function(knex, Promise) {
6 | return dbUtil.truncate().then(function() { return dbUtil.seed(); });
7 | };
8 |
--------------------------------------------------------------------------------
/backend/src/plugins/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/backend/src/plugins/.gitkeep
--------------------------------------------------------------------------------
/backend/test/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/backend/test/.gitkeep
--------------------------------------------------------------------------------
/backend/test/unit/services/project.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // TEST SETUP
4 | var Code = require('Code');
5 | var Lab = require('lab');
6 | var Hapi = require('hapi');
7 |
8 | var lab = exports.lab = Lab.script();
9 | var it = lab.it;
10 | var expect = Code.expect;
11 |
12 | // Test specific
13 | var config = require(process.cwd() + '/config');
14 | var dbUtil = require(process.cwd() + '/src/db/utils/dbUtil.js');
15 | var server = require(process.cwd() + '/server');
16 | var fixtures = require(process.cwd() + '/src/db/seeds/data.json');
17 |
18 | var ProjectService = require(process.cwd() + '/src/services/ProjectService');
19 |
20 | lab.experiment('[Services] Project', function() {
21 | lab.beforeEach(function (done) {
22 | return dbUtil.truncate().then(dbUtil.seed).then(function() { done(); });
23 | });
24 |
25 | lab.after(function (done) {
26 | return dbUtil.truncate().then(function() { done(); });
27 | });
28 |
29 |
30 | // =====================
31 | // BASIC PROJECT
32 | // =====================
33 | it('A new project should be created with a uuid', function (done) {
34 | done();
35 | });
36 |
37 | it('getting a project should return a uuid as it\'s id', function (done) {
38 | done();
39 | });
40 | });
41 |
--------------------------------------------------------------------------------
/design/builder/README.md:
--------------------------------------------------------------------------------
1 | # Setup
2 | 1. `npm install`
3 | 2. `grunt serve --force`
4 |
--------------------------------------------------------------------------------
/design/builder/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/builder/app/favicon.ico
--------------------------------------------------------------------------------
/design/builder/app/images/after.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/builder/app/images/after.png
--------------------------------------------------------------------------------
/design/builder/app/images/avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/builder/app/images/avatar.png
--------------------------------------------------------------------------------
/design/builder/app/images/before.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/builder/app/images/before.png
--------------------------------------------------------------------------------
/design/builder/app/images/header.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/builder/app/images/header.jpg
--------------------------------------------------------------------------------
/design/builder/app/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/builder/app/images/logo.png
--------------------------------------------------------------------------------
/design/builder/app/images/option-dropdown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/builder/app/images/option-dropdown.png
--------------------------------------------------------------------------------
/design/builder/app/images/screenshot-background.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/builder/app/images/screenshot-background.jpg
--------------------------------------------------------------------------------
/design/builder/app/images/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/builder/app/images/screenshot.png
--------------------------------------------------------------------------------
/design/builder/app/images/screenshot@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/builder/app/images/screenshot@2x.png
--------------------------------------------------------------------------------
/design/builder/app/styles/components/comparison.scss:
--------------------------------------------------------------------------------
1 | #comparison {
2 | margin-top: $spacing;
3 | margin-left: auto;
4 | margin-right: auto;
5 | max-width: 800px;
6 |
7 | img {
8 | margin-top: $spacing;
9 | }
10 |
11 | h4 {
12 | font-weight: normal;
13 | font-size: 24px;
14 | margin-top: $spacing;
15 | margin-bottom: $spacing / 2;
16 |
17 | .success {
18 | color: $colorSuccess;
19 | }
20 | }
21 |
22 | p {
23 | line-height: 1.5;
24 | font-size: 18px;
25 | opacity: 0.7;
26 | }
27 |
28 | .line {
29 | width: 2px;
30 | background-color: #dedede;
31 | height: 110px;
32 | margin-right: auto;
33 | margin-left: auto;
34 | }
35 |
36 | .vs {
37 | padding: 20px;
38 | font-weight: bold;
39 | color: #999;
40 | }
41 | }
--------------------------------------------------------------------------------
/design/builder/app/styles/components/content.scss:
--------------------------------------------------------------------------------
1 | .content {
2 | h1 {
3 | background-color: $colorPrimaryLightShade1;
4 | margin: 0;
5 | padding: 10px 20px;
6 | color: $colorTextHeader;
7 | display: block;
8 | text-transform: uppercase;
9 | color: $colorTextTitle;
10 | font-size: 20px;
11 | font-weight: normal;
12 |
13 | #step {
14 | float: right;
15 | font-size: 12px;
16 | line-height: 22px;
17 | }
18 | }
19 | }
20 |
21 | .content > .container {
22 | height: 100%;
23 | margin-left: 200px;
24 | position: relative;
25 | }
26 |
27 | @media screen and (max-width: 600px) {
28 | .content > .container {
29 | height: 100%;
30 | margin-left: 50px;
31 | position: relative;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/design/builder/app/styles/components/flexbox.scss:
--------------------------------------------------------------------------------
1 | .flex-container {
2 | width: 100%;
3 | padding: 0;
4 | // margin: 0 30px 30px 30px;
5 | list-style: none;
6 |
7 | -ms-box-orient: horizontal;
8 | display: -webkit-box;
9 | display: -moz-box;
10 | display: -ms-flexbox;
11 | display: -moz-flex;
12 | display: -webkit-flex;
13 | display: flex;
14 |
15 | // Space between gives margin within boxes
16 | -webkit-justify-content: space-between;
17 | justify-content: space-between;
18 |
19 | align-items: center;
20 | flex-flow: wrap;
21 | }
22 |
23 | .flex-container > .container {
24 | padding-right: 0;
25 | width: 100%;
26 | }
27 |
28 | .flex-item {
29 | margin: 10px;
30 |
31 | color: white;
32 | font-weight: bold;
33 | font-size: 14px;
34 | text-align: center;
35 |
36 | flex-grow: 3;
37 |
38 | padding: 10px;
39 | }
40 |
--------------------------------------------------------------------------------
/design/builder/app/styles/components/footer.scss:
--------------------------------------------------------------------------------
1 | footer {
2 | padding: $spacing;
3 | background-color: $colorText;
4 | color: #fff;
5 | height: 120px;
6 | width: 100%;
7 | height: auto;
8 | bottom: 0;
9 |
10 | z-index: 1;
11 | position: absolute;
12 |
13 | .logo {
14 | background-image: url(../images/logo.png);
15 | background-size: 166px 40px;
16 | display: block;
17 | width: 166px;
18 | height: 40px;
19 | float: left;
20 | }
21 |
22 | .links {
23 | a {
24 | color: #fff;
25 | opacity: 0.5;
26 | padding: 12px;
27 | display: inline-block;
28 | text-decoration: none;
29 |
30 | &:hover {
31 | opacity: 1;
32 | }
33 | }
34 |
35 | .divider {
36 | height: 10px;
37 | width: 1px;
38 | background-color: #fff;
39 | opacity: 0.2;
40 | display: inline-block;
41 | }
42 | }
43 |
44 | .circle {
45 | color: #fff;
46 | width: 36px;
47 | height: 36px;
48 | border: 2px solid #fff;
49 | display: inline-block;
50 | text-align: center;
51 | border-radius: 50%;
52 | line-height: 34px;
53 | margin-left: 10px;
54 | margin-top: 3px;
55 |
56 | &:hover {
57 | background-color: #fff;
58 | color: $colorText;
59 | }
60 | }
61 | }
62 |
63 | #license {
64 | background-color: darken($colorText, 3%);
65 | padding: $spacing/2;
66 | text-align: center;
67 | color: #555;
68 | font-size: 12px;
69 |
70 | a {
71 | color: #555;
72 | text-decoration: none;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/design/builder/app/styles/components/form.scss:
--------------------------------------------------------------------------------
1 | input {
2 | width: 100%;
3 | padding: 10px 10px;
4 | font-weight: normal;
5 | color: $colorBlack;
6 | display: inline-block;
7 | box-sizing: border-box;
8 | border: 1px solid $colorBoxBorder;
9 | margin-bottom: 20px;
10 | }
11 |
12 | label {
13 | color: $colorBlack;
14 | text-align: left;
15 | font-weight: normal;
16 | margin-bottom: 10px;
17 | display: block;
18 | text-transform: uppercase;
19 | font-size: 16px;
20 | }
21 |
--------------------------------------------------------------------------------
/design/builder/app/styles/components/icon-block.scss:
--------------------------------------------------------------------------------
1 | .icon-block {
2 | .circle {
3 | font-size: 42px;
4 | border: 6px solid #000;
5 | display: inline-block;
6 | height: 120px;
7 | width: 120px;
8 | line-height: 112px;
9 | border-radius: 50%;
10 |
11 |
12 | &.accent {
13 | border-color: $colorAccent;
14 | color: $colorAccent;
15 | }
16 |
17 | &.success {
18 | border-color: $colorSuccess;
19 | color: $colorSuccess;
20 | }
21 |
22 | &.info {
23 | border-color: $colorInfo;
24 | color: $colorInfo;
25 | }
26 | }
27 |
28 | h3 {
29 | font-size: 24px;
30 | margin-top: $spacing/2;
31 | margin-bottom: $spacing/4;
32 | }
33 |
34 | p.subtitle {
35 | max-width: 320px;
36 | margin-right: auto;
37 | margin-left: auto;
38 | }
39 |
40 | // Crappy centering workarounds
41 | i.fa-play {
42 | margin-right: -10px;
43 | }
44 | }
--------------------------------------------------------------------------------
/design/builder/app/styles/components/list.scss:
--------------------------------------------------------------------------------
1 | .sub-content li {
2 | background-color: white;
3 | font-size: 14px;
4 | border-top: 1px solid $colorBoxBorder;
5 | border-left: 1px solid $colorBoxBorder;
6 | border-right: 1px solid $colorBoxBorder;
7 | text-align: left;
8 | height: 35px;
9 | position: relative;
10 | line-height: 35px;
11 | padding-left: 10px;
12 |
13 | a {
14 | width: 35px;
15 | line-height: 35px;
16 | padding: 0;
17 | text-align: center;
18 | top: 0;
19 | }
20 |
21 | a:first-child {
22 | margin-left: -10px; // negate the padding-left
23 | border-right: 1px solid $colorBoxBorder;
24 | background-color: $colorLeftListPart;
25 | color: $colorLeftListPartText;
26 | left: 0;
27 | display: inline-block;
28 | position: initial;
29 | margin-right: 10px;
30 | }
31 |
32 | a:last-child {
33 | margin: 0;
34 | border-right: none;
35 | border-left: 1px solid $colorBoxBorder;
36 | right: 0;
37 | position: absolute;
38 | left: initial;
39 | }
40 | }
41 |
42 | .sub-content li:last-child {
43 | border-top: 1px solid $colorBoxBorder;
44 | border-bottom: 1px solid $colorBoxBorder;
45 | }
46 |
--------------------------------------------------------------------------------
/design/builder/app/styles/components/menu.scss:
--------------------------------------------------------------------------------
1 | nav {
2 | //position: fixed;
3 | position: absolute;
4 | width: 100%;
5 | top: 0;
6 | padding-top: $spacing;
7 | padding-bottom: $spacing;
8 |
9 | .logo {
10 | background-image: url(../images/logo.png);
11 | background-size: 166px 40px;
12 | display: block;
13 | width: 166px;
14 | height: 40px;
15 | float: left;
16 | margin-left: 10px;
17 | }
18 |
19 | ul {
20 | float: right;
21 |
22 | li {
23 | list-style: none;
24 | display: inline-block;
25 |
26 | a {
27 | display: block;
28 | color: #fff;
29 | margin-left: $spacing/2;
30 | font-size: 16px;
31 | text-decoration: none;
32 | font-weight: bold;
33 | letter-spacing: 1px;
34 | }
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/design/builder/app/styles/components/page-title.scss:
--------------------------------------------------------------------------------
1 | .page-title {
2 | h1 {
3 | background-color: $colorPrimaryLightShade2;
4 | margin: 0;
5 | padding: 10px 20px 10px 240px;
6 | display: block;
7 | color: $colorTextTitle;
8 | font-size: 20px;
9 | font-weight: normal;
10 | letter-spacing: 1px;
11 |
12 | #step {
13 | float: right;
14 | font-size: 12px;
15 | line-height: 22px;
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/design/builder/app/styles/components/plan.scss:
--------------------------------------------------------------------------------
1 | .plan {
2 | background-color: #fff;
3 | width: 360px;
4 | text-align: center;
5 | display: inline-block;
6 | color: $colorText;
7 | border-radius: 3px;
8 | margin-left: 10px;
9 | margin-right: 10px;
10 |
11 | li {
12 | list-style: none;
13 | text-align: left;
14 | font-weight: bold;
15 | line-height: 2;
16 |
17 | &.disabled {
18 | color: #999;
19 | }
20 |
21 | i {
22 | margin-right: 10px;
23 | }
24 | }
25 |
26 | .title {
27 | font-size: 24px;
28 | font-weight: bold;
29 | margin-top: $spacing/2;
30 | }
31 |
32 | .subtitle {
33 | font-size: 18px;
34 | margin-top: 3px;
35 | margin-bottom: $spacing/2;
36 | }
37 |
38 | .price {
39 | background-color: $colorPrimaryHighlight;
40 | color: #fff;
41 | padding: $spacing/2;
42 | font-size: 22px;
43 | font-weight: bold;
44 |
45 | &.success {
46 | background-color: $colorSuccess;
47 | }
48 |
49 | small {
50 | font-size: 14px;
51 | }
52 | }
53 |
54 | .button {
55 | margin-bottom: $spacing / 2;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/design/builder/app/styles/components/screenshot.scss:
--------------------------------------------------------------------------------
1 | #screenshot {
2 | background-color: $colorPrimary;
3 | background-image: url(../images/screenshot-background.jpg);
4 | background-size: cover;
5 | background-position: center bottom;
6 | padding-top: $spacing * 2;
7 | color: #fff;
8 | overflow: hidden;
9 |
10 | p.subtitle {
11 | max-width: 520px;
12 | font-size: 18px;
13 | margin-right: auto;
14 | margin-left: auto;
15 | line-height: 1.5;
16 | opacity: 0.6;
17 | }
18 | }
19 |
20 | #screenshot-image {
21 | background-image: url(../images/screenshot.png);
22 | background-size: 770px 474px;
23 | width: 770px;
24 | height: 474px;
25 | margin-right: auto;
26 | margin-left: auto;
27 | margin-top: $spacing;
28 |
29 | @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
30 | background-image: url(../images/screenshot@2x.png);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/design/builder/app/styles/components/section.scss:
--------------------------------------------------------------------------------
1 | section {
2 | background-color: $colorBackground;
3 |
4 | &.padding {
5 | padding: $spacing;
6 | }
7 |
8 | &.padding-double {
9 | padding: $spacing * 2;
10 | }
11 |
12 | &.centered {
13 | text-align: center;
14 | }
15 |
16 | &.accent {
17 | background-color: $colorAccent;
18 | color: #fff;
19 | }
20 |
21 | &.dark {
22 | background-color: $colorSecondary;
23 | color: #fff;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/design/builder/app/styles/components/spacer.scss:
--------------------------------------------------------------------------------
1 | .spacer {
2 | height: $spacing;
3 | }
4 |
5 | .spacer-half {
6 | height: $spacing / 2;
7 | }
8 |
9 | .spacer-double {
10 | height: $spacing * 2;
11 | }
12 |
13 | .padding {
14 | padding: $spacing;
15 | }
16 |
17 | .padding-half {
18 | padding: $spacing / 2;
19 | }
--------------------------------------------------------------------------------
/design/builder/app/styles/components/sub-content.scss:
--------------------------------------------------------------------------------
1 | .sub-content {
2 | margin: 0 auto;
3 |
4 | h1 {
5 | color: $colorText;
6 | background-color: transparent;
7 | font-size: 18px;
8 | text-transform: none;
9 | text-align: center;
10 | margin-bottom: 20px;
11 | width: 100%;
12 | }
13 |
14 | h2 {
15 | color: $colorBlack;
16 | text-align: left;
17 | font-weight: normal;
18 | margin-bottom: 10px;
19 | display: block;
20 | text-transform: uppercase;
21 | font-size: 16px;
22 | }
23 |
24 | ul {
25 | padding: 0;
26 | display: block;
27 | list-style: none;
28 | color: $colorText;
29 | font-weight: normal;
30 | font-size: 14px;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/design/builder/app/styles/components/wrapper.scss:
--------------------------------------------------------------------------------
1 | .wrapper {
2 | position: relative;
3 | padding-bottom: 120px; // Footer
4 | padding-top: 100px; // Header
5 | min-height:100%;
6 | }
7 |
8 | .wrapper-no-header {
9 | position: relative;
10 | padding-bottom: 120px; // Footer
11 | min-height:100%;
12 | }
13 |
--------------------------------------------------------------------------------
/design/builder/app/styles/config.scss:
--------------------------------------------------------------------------------
1 | // Colors
2 | $colorWhite: #FFFFFF;
3 | $colorBlack: #000000;
4 |
5 | $colorHelpBox: #333333;
6 | $colorHelpIcon: #333333;
7 | $colorHelpIconHover: #999999;
8 |
9 | $colorBackground: #F5F5F5;
10 |
11 | $colorPrimaryLightShade1: #2a3c50;
12 | $colorPrimaryLightShade2: #32465d;
13 | $colorPrimaryLightShade3: #39506A;
14 | $colorPrimary: #233141;
15 | $colorPrimaryDarkShade1: #151E28;
16 | $colorPrimaryDarkShade2: #1D2835;
17 |
18 | $colorMenuItem: #d3d6d9;
19 | $colorMenuItemActive: #56789f;
20 |
21 | $colorBoxBorder: #cccccc;
22 |
23 | $colorButtonNext: #f15843;
24 | $colorButtonNextHover: #ff604b;
25 | $colorLeftListPart: #F7F7F7;
26 | $colorLeftListPartText: #6C6C6C;
27 |
28 | $colorSecondary: #1c2632;
29 | $colorAccent: #f15843;
30 | $colorSuccess: #41b222;
31 | $colorLight: #999999;
32 | $colorText: #101010;
33 | $colorTextHeader: #32465d;
34 | $colorTextTitle: #ffffff;
35 | $colorBlue: #227ab2;
36 | $colorSuccess: #41b222;
37 | $colorInfo: #227ab2;
38 | $colorPrimaryHighlight: #3a4856;
39 | $colorBgDropdown: #E9E9E9;
40 |
41 | // Generic
42 | $spacing: 40px;
43 |
--------------------------------------------------------------------------------
/design/builder/app/styles/general/base.scss:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: sans-serif;
3 | font-size: 16px;
4 | color: $colorText;
5 | background-color: $colorBackground;
6 | }
7 |
8 | a {
9 | color: $colorAccent;
10 | }
11 |
12 | .accent a {
13 | color: #fff;
14 | }
15 |
--------------------------------------------------------------------------------
/design/builder/app/styles/general/reset.scss:
--------------------------------------------------------------------------------
1 | html, body {
2 | height: 100%;
3 | }
4 |
5 | * {
6 | margin: 0;
7 | padding: 0;
8 | box-sizing: border-box;
9 | }
10 |
11 | .clearfix {
12 | clear: both;
13 | }
14 |
15 | *:focus {
16 | outline: none;
17 | }
--------------------------------------------------------------------------------
/design/builder/app/styles/general/typography.scss:
--------------------------------------------------------------------------------
1 | h2 {
2 | font-size: 36px;
3 | font-weight: normal;
4 | letter-spacing: 1px;
5 | margin-bottom: $spacing/2;
6 |
7 | &.smaller {
8 | font-size: 28px;
9 | }
10 | }
11 |
12 | body {
13 | font-family: "Open Sans", sans-serif;
14 | }
15 |
16 | h1 {
17 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
18 | }
19 |
20 | .subtitle {
21 | font-size: 18px;
22 | opacity: 0.6;
23 | line-height: 1.5;
24 | }
25 |
26 | section .subtitle {
27 | max-width: 600px;
28 | margin-right: auto;
29 | margin-left: auto;
30 | }
31 |
32 | .bold {
33 | font-weight: bold;
34 | }
35 |
36 | .small {
37 | font-size: 14px;
38 | }
39 |
40 | .align-left {
41 | text-align: left;
42 | }
43 |
44 | .align-center {
45 | text-align: center;
46 | }
47 |
48 | .align-right {
49 | text-align: right;
50 | }
51 |
52 | .text-accent {
53 | color: $colorAccent;
54 | }
55 |
56 | .text-info {
57 | color: $colorInfo;
58 | }
59 |
60 | .text-success {
61 | color: $colorSuccess;
62 | }
63 |
64 | .text-disabled {
65 | color: #777;
66 | }
67 |
--------------------------------------------------------------------------------
/design/builder/app/styles/main.scss:
--------------------------------------------------------------------------------
1 | // Configuration
2 | @import 'config';
3 |
4 | // Third party dependencies
5 | @import 'lib/bootstrap-grid';
6 |
7 | // General
8 | @import 'general/reset';
9 | @import 'general/base';
10 | @import 'general/typography';
11 |
12 | // Mixins
13 | @import 'mixins/transition';
14 | @import 'mixins/responsive';
15 |
16 | // UI components
17 | @import 'components/header';
18 | @import 'components/menu';
19 | @import 'components/button';
20 | @import 'components/section';
21 | @import 'components/icon-block';
22 | @import 'components/screenshot';
23 | @import 'components/spacer';
24 | @import 'components/footer';
25 | @import 'components/plan';
26 | @import 'components/comparison';
27 | @import 'components/flexbox';
28 | @import 'components/image-builder';
29 | @import 'components/sub-menu';
30 | @import 'components/list';
31 | @import 'components/content';
32 | @import 'components/sub-content';
33 | @import 'components/page-title';
34 | @import 'components/wrapper';
35 | @import 'components/form';
36 | @import 'components/responsive';
37 |
--------------------------------------------------------------------------------
/design/builder/app/styles/mixins/responsive.scss:
--------------------------------------------------------------------------------
1 | // $xs: ~"screen and (max-width: 768px)";
2 | // $sm: ~"screen and (max-width: 992px)";
3 | // $md: ~"screen and (min-width: 992px)";
4 | $xs: "(screen and (max-width: 768px))";
5 | $sm: "(screen and (max-width: 992px))";
6 | $md: "(screen and (min-width: 992px))";
7 |
--------------------------------------------------------------------------------
/design/builder/app/styles/mixins/transition.scss:
--------------------------------------------------------------------------------
1 | .transition {
2 | transition: 0.5 all linear;
3 | -webkit-transition: 0.5 all linear;
4 | -moz-transition: 0.5 all linear;
5 | -ms-transition: 0.5 all linear;
6 | -o-transition: 0.5 all linear;
7 | }
8 |
--------------------------------------------------------------------------------
/design/builder/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "brewr-builder",
3 | "private": true,
4 | "dependencies": {
5 | "modernizr": "~2.8.3"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/design/builder/dist/favicon.9c8b2c34.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/builder/dist/favicon.9c8b2c34.ico
--------------------------------------------------------------------------------
/design/builder/dist/images/after.05b33e94.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/builder/dist/images/after.05b33e94.png
--------------------------------------------------------------------------------
/design/builder/dist/images/avatar.d75d42ca.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/builder/dist/images/avatar.d75d42ca.png
--------------------------------------------------------------------------------
/design/builder/dist/images/before.62605ac2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/builder/dist/images/before.62605ac2.png
--------------------------------------------------------------------------------
/design/builder/dist/images/header.ab829a6e.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/builder/dist/images/header.ab829a6e.jpg
--------------------------------------------------------------------------------
/design/builder/dist/images/logo.363f07b8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/builder/dist/images/logo.363f07b8.png
--------------------------------------------------------------------------------
/design/builder/dist/images/option-dropdown.a34aaed1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/builder/dist/images/option-dropdown.a34aaed1.png
--------------------------------------------------------------------------------
/design/builder/dist/images/screenshot-background.3c42b64a.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/builder/dist/images/screenshot-background.3c42b64a.jpg
--------------------------------------------------------------------------------
/design/builder/dist/images/screenshot.5761ec41.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/builder/dist/images/screenshot.5761ec41.png
--------------------------------------------------------------------------------
/design/builder/dist/images/screenshot@2x.9b390fb5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/builder/dist/images/screenshot@2x.9b390fb5.png
--------------------------------------------------------------------------------
/design/builder/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "devDependencies": {
4 | "autoprefixer-core": "^5.2.1",
5 | "grunt": "^0.4.5",
6 | "grunt-babel": "^5.0.0",
7 | "grunt-browser-sync": "^2.1.2",
8 | "grunt-concurrent": "^1.0.0",
9 | "grunt-contrib-clean": "^0.6.0",
10 | "grunt-contrib-concat": "^0.5.1",
11 | "grunt-contrib-copy": "^0.8.0",
12 | "grunt-contrib-cssmin": "^0.12.2",
13 | "grunt-contrib-htmlmin": "^0.4.0",
14 | "grunt-contrib-imagemin": "^0.9.3",
15 | "grunt-contrib-uglify": "^0.8.0",
16 | "grunt-contrib-watch": "^0.6.1",
17 | "grunt-eslint": "^16.0.0",
18 | "grunt-filerev": "^2.2.0",
19 | "grunt-mocha": "^0.4.12",
20 | "grunt-modernizr": "^0.6.0",
21 | "grunt-newer": "^1.1.0",
22 | "grunt-postcss": "^0.5.3",
23 | "grunt-sass": "^1.0.0",
24 | "grunt-svgmin": "^2.0.1",
25 | "grunt-usemin": "^3.0.0",
26 | "grunt-wiredep": "^2.0.0",
27 | "jit-grunt": "^0.9.1",
28 | "time-grunt": "^1.1.0"
29 | },
30 | "engines": {
31 | "node": ">=0.10.0"
32 | },
33 | "scripts": {
34 | "test": "grunt test"
35 | },
36 | "eslintConfig": {
37 | "env": {
38 | "node": true,
39 | "browser": true,
40 | "mocha": true
41 | },
42 | "rules": {
43 | "quotes": [
44 | 2,
45 | "single"
46 | ]
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/design/builder/test/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Mocha Spec Runner
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
18 |
19 |
20 |
21 |
22 |
23 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/design/builder/test/spec/test.js:
--------------------------------------------------------------------------------
1 | (function () {
2 | 'use strict';
3 |
4 | describe('Give it some context', function () {
5 | describe('maybe a bit more context here', function () {
6 | it('should run here few assertions', function () {
7 |
8 | });
9 | });
10 | });
11 | })();
12 |
--------------------------------------------------------------------------------
/design/frontpage/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/frontpage/app/favicon.ico
--------------------------------------------------------------------------------
/design/frontpage/app/images/after.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/frontpage/app/images/after.png
--------------------------------------------------------------------------------
/design/frontpage/app/images/avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/frontpage/app/images/avatar.png
--------------------------------------------------------------------------------
/design/frontpage/app/images/before.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/frontpage/app/images/before.png
--------------------------------------------------------------------------------
/design/frontpage/app/images/header.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/frontpage/app/images/header.jpg
--------------------------------------------------------------------------------
/design/frontpage/app/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/frontpage/app/images/logo.png
--------------------------------------------------------------------------------
/design/frontpage/app/images/option-dropdown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/frontpage/app/images/option-dropdown.png
--------------------------------------------------------------------------------
/design/frontpage/app/images/screenshot-background.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/frontpage/app/images/screenshot-background.jpg
--------------------------------------------------------------------------------
/design/frontpage/app/images/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/frontpage/app/images/screenshot.png
--------------------------------------------------------------------------------
/design/frontpage/app/images/screenshot@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/frontpage/app/images/screenshot@2x.png
--------------------------------------------------------------------------------
/design/frontpage/app/styles/components/comparison.scss:
--------------------------------------------------------------------------------
1 | #comparison {
2 | margin-top: $spacing;
3 | margin-left: auto;
4 | margin-right: auto;
5 | max-width: 800px;
6 |
7 | img {
8 | margin-top: $spacing;
9 | }
10 |
11 | h4 {
12 | font-weight: normal;
13 | font-size: 24px;
14 | margin-top: $spacing;
15 | margin-bottom: $spacing / 2;
16 |
17 | .success {
18 | color: $colorSuccess;
19 | }
20 | }
21 |
22 | p {
23 | line-height: 1.5;
24 | font-size: 18px;
25 | opacity: 0.7;
26 | }
27 |
28 | .line {
29 | width: 2px;
30 | background-color: #dedede;
31 | height: 110px;
32 | margin-right: auto;
33 | margin-left: auto;
34 | }
35 |
36 | .vs {
37 | padding: 20px;
38 | font-weight: bold;
39 | color: #999;
40 | }
41 | }
--------------------------------------------------------------------------------
/design/frontpage/app/styles/components/content.scss:
--------------------------------------------------------------------------------
1 | .content {
2 | h1 {
3 | background-color: $colorPrimaryLightShade1;
4 | margin: 0;
5 | padding: 10px 20px;
6 | color: $colorTextHeader;
7 | display: block;
8 | text-transform: uppercase;
9 | color: $colorTextTitle;
10 | font-size: 20px;
11 | font-weight: normal;
12 |
13 | #step {
14 | float: right;
15 | font-size: 12px;
16 | line-height: 22px;
17 | }
18 | }
19 | }
20 |
21 | .content > .container {
22 | height: 100%;
23 | margin-left: 200px;
24 | position: relative;
25 | }
26 |
--------------------------------------------------------------------------------
/design/frontpage/app/styles/components/flexbox.scss:
--------------------------------------------------------------------------------
1 | .flex-container {
2 | width: 100%;
3 | padding: 0;
4 | // margin: 0 30px 30px 30px;
5 | list-style: none;
6 |
7 | -ms-box-orient: horizontal;
8 | display: -webkit-box;
9 | display: -moz-box;
10 | display: -ms-flexbox;
11 | display: -moz-flex;
12 | display: -webkit-flex;
13 | display: flex;
14 |
15 | // Space between gives margin within boxes
16 | -webkit-justify-content: space-between;
17 | justify-content: space-between;
18 |
19 | align-items: center;
20 | flex-flow: wrap;
21 | }
22 |
23 | .flex-container > .container {
24 | padding-right: 0;
25 | width: 100%;
26 | }
27 |
28 | .flex-item {
29 | margin: 10px;
30 |
31 | color: white;
32 | font-weight: bold;
33 | font-size: 14px;
34 | text-align: center;
35 |
36 | flex-grow: 3;
37 |
38 | padding: 10px;
39 |
40 | input {
41 | width: 100%;
42 | padding: 10px 10px;
43 | font-weight: normal;
44 | color: $colorBlack;
45 | display: inline-block;
46 | box-sizing: border-box;
47 | border: 1px solid $colorBoxBorder;
48 | margin-bottom: 20px;
49 | }
50 |
51 | label {
52 | color: $colorBlack;
53 | text-align: left;
54 | font-weight: normal;
55 | margin-bottom: 10px;
56 | display: block;
57 | text-transform: uppercase;
58 | font-size: 16px;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/design/frontpage/app/styles/components/footer.scss:
--------------------------------------------------------------------------------
1 | footer {
2 | padding: $spacing;
3 | background-color: $colorText;
4 | color: #fff;
5 |
6 | .logo {
7 | background-image: url(../images/logo.png);
8 | background-size: 166px 40px;
9 | display: block;
10 | width: 166px;
11 | height: 40px;
12 | float: left;
13 | }
14 |
15 | .links {
16 | a {
17 | color: #fff;
18 | opacity: 0.5;
19 | padding: 12px;
20 | display: inline-block;
21 | text-decoration: none;
22 |
23 | &:hover {
24 | opacity: 1;
25 | }
26 | }
27 |
28 | .divider {
29 | height: 10px;
30 | width: 1px;
31 | background-color: #fff;
32 | opacity: 0.2;
33 | display: inline-block;
34 | }
35 | }
36 |
37 | .circle {
38 | color: #fff;
39 | width: 36px;
40 | height: 36px;
41 | border: 2px solid #fff;
42 | display: inline-block;
43 | text-align: center;
44 | border-radius: 50%;
45 | line-height: 34px;
46 | margin-left: 10px;
47 | margin-top: 3px;
48 |
49 | &:hover {
50 | background-color: #fff;
51 | color: $colorText;
52 | }
53 | }
54 | }
55 |
56 | #license {
57 | background-color: darken($colorText, 3%);
58 | padding: $spacing/2;
59 | text-align: center;
60 | color: #555;
61 | font-size: 12px;
62 |
63 | a {
64 | color: #555;
65 | text-decoration: none;
66 | }
67 | }
--------------------------------------------------------------------------------
/design/frontpage/app/styles/components/icon-block.scss:
--------------------------------------------------------------------------------
1 | .icon-block {
2 | .circle {
3 | font-size: 42px;
4 | border: 6px solid #000;
5 | display: inline-block;
6 | height: 120px;
7 | width: 120px;
8 | line-height: 112px;
9 | border-radius: 50%;
10 |
11 |
12 | &.accent {
13 | border-color: $colorAccent;
14 | color: $colorAccent;
15 | }
16 |
17 | &.success {
18 | border-color: $colorSuccess;
19 | color: $colorSuccess;
20 | }
21 |
22 | &.info {
23 | border-color: $colorInfo;
24 | color: $colorInfo;
25 | }
26 | }
27 |
28 | h3 {
29 | font-size: 24px;
30 | margin-top: $spacing/2;
31 | margin-bottom: $spacing/4;
32 | }
33 |
34 | p.subtitle {
35 | max-width: 320px;
36 | margin-right: auto;
37 | margin-left: auto;
38 | }
39 |
40 | // Crappy centering workarounds
41 | i.fa-play {
42 | margin-right: -10px;
43 | }
44 | }
--------------------------------------------------------------------------------
/design/frontpage/app/styles/components/list.scss:
--------------------------------------------------------------------------------
1 | .sub-content li {
2 | background-color: white;
3 | font-size: 14px;
4 | border-top: 1px solid $colorBoxBorder;
5 | border-left: 1px solid $colorBoxBorder;
6 | border-right: 1px solid $colorBoxBorder;
7 | text-align: left;
8 | height: 35px;
9 | position: relative;
10 | line-height: 35px;
11 | padding-left: 10px;
12 |
13 | a {
14 | width: 35px;
15 | line-height: 35px;
16 | padding: 0;
17 | text-align: center;
18 | top: 0;
19 | }
20 |
21 | a:first-child {
22 | margin-left: -10px; // negate the padding-left
23 | border-right: 1px solid $colorBoxBorder;
24 | background-color: $colorLeftListPart;
25 | color: $colorLeftListPartText;
26 | left: 0;
27 | display: inline-block;
28 | position: initial;
29 | margin-right: 10px;
30 | }
31 |
32 | a:last-child {
33 | margin: 0;
34 | border-right: none;
35 | border-left: 1px solid $colorBoxBorder;
36 | right: 0;
37 | position: absolute;
38 | left: initial;
39 | }
40 | }
41 |
42 | .sub-content li:last-child {
43 | border-top: 1px solid $colorBoxBorder;
44 | border-bottom: 1px solid $colorBoxBorder;
45 | }
46 |
--------------------------------------------------------------------------------
/design/frontpage/app/styles/components/menu.scss:
--------------------------------------------------------------------------------
1 | nav {
2 | //position: fixed;
3 | position: absolute;
4 | width: 100%;
5 | top: 0;
6 | padding-top: $spacing;
7 | padding-bottom: $spacing;
8 |
9 | .logo {
10 | background-image: url(../images/logo.png);
11 | background-size: 166px 40px;
12 | display: block;
13 | width: 166px;
14 | height: 40px;
15 | float: left;
16 | }
17 |
18 | ul {
19 | float: right;
20 |
21 | li {
22 | list-style: none;
23 | display: inline-block;
24 |
25 | a {
26 | display: block;
27 | color: #fff;
28 | margin-left: $spacing/2;
29 | font-size: 16px;
30 | text-decoration: none;
31 | font-weight: bold;
32 | letter-spacing: 1px;
33 | }
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/design/frontpage/app/styles/components/page-title.scss:
--------------------------------------------------------------------------------
1 | .page-title {
2 | h1 {
3 | background-color: $colorPrimaryLightShade2;
4 | margin: 0;
5 | padding: 10px 20px 10px 240px;
6 | display: block;
7 | color: $colorTextTitle;
8 | font-size: 20px;
9 | font-weight: normal;
10 | letter-spacing: 1px;
11 |
12 | #step {
13 | float: right;
14 | font-size: 12px;
15 | line-height: 22px;
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/design/frontpage/app/styles/components/plan.scss:
--------------------------------------------------------------------------------
1 | .plan {
2 | background-color: #fff;
3 | width: 280px;
4 | text-align: center;
5 | display: inline-block;
6 | color: $colorText;
7 | border-radius: 3px;
8 | margin-left: 10px;
9 | margin-right: 10px;
10 |
11 | li {
12 | list-style: none;
13 | text-align: left;
14 | font-weight: bold;
15 | line-height: 2;
16 |
17 | &.disabled {
18 | color: #999;
19 | }
20 |
21 | i {
22 | margin-right: 10px;
23 | }
24 | }
25 |
26 | .title {
27 | font-size: 24px;
28 | font-weight: bold;
29 | margin-top: $spacing/2;
30 | }
31 |
32 | .subtitle {
33 | font-size: 18px;
34 | margin-top: 3px;
35 | margin-bottom: $spacing/2;
36 | }
37 |
38 | .price {
39 | background-color: $colorPrimaryHighlight;
40 | color: #fff;
41 | padding: $spacing/2;
42 | font-size: 22px;
43 | font-weight: bold;
44 |
45 | &.success {
46 | background-color: $colorSuccess;
47 | }
48 |
49 | small {
50 | font-size: 14px;
51 | }
52 | }
53 |
54 | .button {
55 | margin-bottom: $spacing / 2;
56 | }
57 | }
--------------------------------------------------------------------------------
/design/frontpage/app/styles/components/screenshot.scss:
--------------------------------------------------------------------------------
1 | #screenshot {
2 | background-color: $colorPrimary;
3 | background-image: url(../images/screenshot-background.jpg);
4 | background-size: cover;
5 | background-position: center bottom;
6 | padding-top: $spacing * 2;
7 | color: #fff;
8 | overflow: hidden;
9 |
10 | p.subtitle {
11 | max-width: 520px;
12 | font-size: 18px;
13 | margin-right: auto;
14 | margin-left: auto;
15 | line-height: 1.5;
16 | opacity: 0.6;
17 | }
18 | }
19 |
20 | #screenshot-image {
21 | background-image: url(../images/screenshot.png);
22 | background-size: 770px 474px;
23 | width: 770px;
24 | height: 474px;
25 | margin-right: auto;
26 | margin-left: auto;
27 | margin-top: $spacing;
28 |
29 | @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
30 | background-image: url(../images/screenshot@2x.png);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/design/frontpage/app/styles/components/section.scss:
--------------------------------------------------------------------------------
1 | section {
2 | background-color: $colorBackground;
3 |
4 | &.padding {
5 | padding: $spacing;
6 | }
7 |
8 | &.padding-double {
9 | padding: $spacing * 2;
10 | }
11 |
12 | &.centered {
13 | text-align: center;
14 | }
15 |
16 | &.accent {
17 | background-color: $colorAccent;
18 | color: #fff;
19 | }
20 |
21 | &.dark {
22 | background-color: $colorSecondary;
23 | color: #fff;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/design/frontpage/app/styles/components/spacer.scss:
--------------------------------------------------------------------------------
1 | .spacer {
2 | height: $spacing;
3 | }
4 |
5 | .spacer-half {
6 | height: $spacing / 2;
7 | }
8 |
9 | .spacer-double {
10 | height: $spacing * 2;
11 | }
12 |
13 | .padding {
14 | padding: $spacing;
15 | }
16 |
17 | .padding-half {
18 | padding: $spacing / 2;
19 | }
--------------------------------------------------------------------------------
/design/frontpage/app/styles/components/sub-content.scss:
--------------------------------------------------------------------------------
1 | .sub-content {
2 | margin: 0 auto;
3 |
4 | h1 {
5 | color: $colorText;
6 | background-color: transparent;
7 | font-size: 18px;
8 | text-transform: none;
9 | text-align: center;
10 | margin-bottom: 20px;
11 | width: 100%;
12 | }
13 |
14 | h2 {
15 | color: $colorBlack;
16 | text-align: left;
17 | font-weight: normal;
18 | margin-bottom: 10px;
19 | display: block;
20 | text-transform: uppercase;
21 | font-size: 16px;
22 | }
23 |
24 | ul {
25 | padding: 0;
26 | display: block;
27 | list-style: none;
28 | color: $colorText;
29 | font-weight: normal;
30 | font-size: 14px;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/design/frontpage/app/styles/components/wrapper.scss:
--------------------------------------------------------------------------------
1 | .wrapper {
2 | position: relative;
3 | }
4 |
--------------------------------------------------------------------------------
/design/frontpage/app/styles/config.scss:
--------------------------------------------------------------------------------
1 | // Colors
2 | $colorWhite: #FFFFFF;
3 | $colorBlack: #000000;
4 |
5 | $colorHelpBox: #333333;
6 | $colorHelpIcon: #333333;
7 | $colorHelpIconHover: #999999;
8 |
9 | $colorBackground: #F5F5F5;
10 |
11 | $colorPrimaryLightShade1: #2a3c50;
12 | $colorPrimaryLightShade2: #32465d;
13 | $colorPrimaryLightShade3: #39506A;
14 | $colorPrimary: #233141;
15 | $colorPrimaryDarkShade1: #151E28;
16 | $colorPrimaryDarkShade2: #1D2835;
17 |
18 | $colorMenuItem: #d3d6d9;
19 | $colorMenuItemActive: #56789f;
20 |
21 | $colorBoxBorder: #cccccc;
22 |
23 | $colorButtonNext: #f15843;
24 | $colorButtonNextHover: #ff604b;
25 | $colorLeftListPart: #F7F7F7;
26 | $colorLeftListPartText: #6C6C6C;
27 |
28 | $colorSecondary: #1c2632;
29 | $colorAccent: #f15843;
30 | $colorSuccess: #41b222;
31 | $colorLight: #999999;
32 | $colorText: #101010;
33 | $colorTextHeader: #32465d;
34 | $colorTextTitle: #ffffff;
35 | $colorBlue: #227ab2;
36 | $colorSuccess: #41b222;
37 | $colorInfo: #227ab2;
38 | $colorPrimaryHighlight: #3a4856;
39 |
40 | // Generic
41 | $spacing: 40px;
42 |
--------------------------------------------------------------------------------
/design/frontpage/app/styles/general/base.scss:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: sans-serif;
3 | font-size: 16px;
4 | color: $colorText;
5 | background-color: darken($colorText, 3%);
6 | }
7 |
8 | a {
9 | color: $colorAccent;
10 | }
11 |
12 | .accent a {
13 | color: #fff;
14 | }
--------------------------------------------------------------------------------
/design/frontpage/app/styles/general/reset.scss:
--------------------------------------------------------------------------------
1 | html, body {
2 | height: 100%;
3 | }
4 |
5 | * {
6 | margin: 0;
7 | padding: 0;
8 | box-sizing: border-box;
9 | }
10 |
11 | .clearfix {
12 | clear: both;
13 | }
14 |
15 | *:focus {
16 | outline: none;
17 | }
--------------------------------------------------------------------------------
/design/frontpage/app/styles/general/typography.scss:
--------------------------------------------------------------------------------
1 | h2 {
2 | font-size: 36px;
3 | font-weight: normal;
4 | letter-spacing: 1px;
5 | margin-bottom: $spacing/2;
6 |
7 | &.smaller {
8 | font-size: 28px;
9 | }
10 | }
11 |
12 | body {
13 | font-family: "Open Sans", sans-serif;
14 | }
15 |
16 | h1 {
17 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
18 | }
19 |
20 | .subtitle {
21 | font-size: 18px;
22 | opacity: 0.6;
23 | line-height: 1.5;
24 | }
25 |
26 | section .subtitle {
27 | max-width: 600px;
28 | margin-right: auto;
29 | margin-left: auto;
30 | }
31 |
32 | .bold {
33 | font-weight: bold;
34 | }
35 |
36 | .small {
37 | font-size: 14px;
38 | }
39 |
40 | .align-left {
41 | text-align: left;
42 | }
43 |
44 | .align-center {
45 | text-align: center;
46 | }
47 |
48 | .align-right {
49 | text-align: right;
50 | }
51 |
52 | .text-accent {
53 | color: $colorAccent;
54 | }
55 |
56 | .text-info {
57 | color: $colorInfo;
58 | }
59 |
60 | .text-success {
61 | color: $colorSuccess;
62 | }
63 |
64 | .text-disabled {
65 | color: #777;
66 | }
67 |
--------------------------------------------------------------------------------
/design/frontpage/app/styles/main.scss:
--------------------------------------------------------------------------------
1 | // Configuration
2 | @import 'config';
3 |
4 | // Third party dependencies
5 | @import 'lib/bootstrap-grid';
6 |
7 | // General
8 | @import 'general/reset';
9 | @import 'general/base';
10 | @import 'general/typography';
11 |
12 | // Mixins
13 | @import 'mixins/transition';
14 | @import 'mixins/responsive';
15 |
16 | // UI components
17 | @import 'components/header';
18 | @import 'components/menu';
19 | @import 'components/button';
20 | @import 'components/section';
21 | @import 'components/icon-block';
22 | @import 'components/screenshot';
23 | @import 'components/spacer';
24 | @import 'components/footer';
25 | @import 'components/plan';
26 | @import 'components/comparison';
27 | @import 'components/flexbox';
28 | @import 'components/image-builder';
29 | @import 'components/sub-menu';
30 | @import 'components/list';
31 | @import 'components/content';
32 | @import 'components/sub-content';
33 | @import 'components/page-title';
34 | @import 'components/wrapper';
35 |
--------------------------------------------------------------------------------
/design/frontpage/app/styles/mixins/responsive.scss:
--------------------------------------------------------------------------------
1 | // $xs: ~"screen and (max-width: 768px)";
2 | // $sm: ~"screen and (max-width: 992px)";
3 | // $md: ~"screen and (min-width: 992px)";
4 | $xs: "(screen and (max-width: 768px))";
5 | $sm: "(screen and (max-width: 992px))";
6 | $md: "(screen and (min-width: 992px))";
7 |
--------------------------------------------------------------------------------
/design/frontpage/app/styles/mixins/transition.scss:
--------------------------------------------------------------------------------
1 | .transition {
2 | transition: 0.5 all linear;
3 | -webkit-transition: 0.5 all linear;
4 | -moz-transition: 0.5 all linear;
5 | -ms-transition: 0.5 all linear;
6 | -o-transition: 0.5 all linear;
7 | }
8 |
--------------------------------------------------------------------------------
/design/frontpage/app/styles/style.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/frontpage/app/styles/style.css
--------------------------------------------------------------------------------
/design/frontpage/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "brewr-builder",
3 | "private": true,
4 | "dependencies": {
5 | "modernizr": "~2.8.3"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/design/frontpage/dist/favicon.ba8ce5ed.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/frontpage/dist/favicon.ba8ce5ed.ico
--------------------------------------------------------------------------------
/design/frontpage/dist/images/after.05b33e94.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/frontpage/dist/images/after.05b33e94.png
--------------------------------------------------------------------------------
/design/frontpage/dist/images/avatar.d75d42ca.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/frontpage/dist/images/avatar.d75d42ca.png
--------------------------------------------------------------------------------
/design/frontpage/dist/images/before.62605ac2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/frontpage/dist/images/before.62605ac2.png
--------------------------------------------------------------------------------
/design/frontpage/dist/images/header.ab829a6e.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/frontpage/dist/images/header.ab829a6e.jpg
--------------------------------------------------------------------------------
/design/frontpage/dist/images/logo.df56c44c.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/frontpage/dist/images/logo.df56c44c.png
--------------------------------------------------------------------------------
/design/frontpage/dist/images/option-dropdown.a34aaed1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/frontpage/dist/images/option-dropdown.a34aaed1.png
--------------------------------------------------------------------------------
/design/frontpage/dist/images/screenshot-background.3c42b64a.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/frontpage/dist/images/screenshot-background.3c42b64a.jpg
--------------------------------------------------------------------------------
/design/frontpage/dist/images/screenshot.5761ec41.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/frontpage/dist/images/screenshot.5761ec41.png
--------------------------------------------------------------------------------
/design/frontpage/dist/images/screenshot@2x.9b390fb5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/frontpage/dist/images/screenshot@2x.9b390fb5.png
--------------------------------------------------------------------------------
/design/frontpage/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "devDependencies": {
4 | "autoprefixer-core": "^5.2.1",
5 | "grunt": "^0.4.5",
6 | "grunt-babel": "^5.0.0",
7 | "grunt-browser-sync": "^2.1.2",
8 | "grunt-concurrent": "^1.0.0",
9 | "grunt-contrib-clean": "^0.6.0",
10 | "grunt-contrib-concat": "^0.5.1",
11 | "grunt-contrib-copy": "^0.8.0",
12 | "grunt-contrib-cssmin": "^0.12.2",
13 | "grunt-contrib-htmlmin": "^0.4.0",
14 | "grunt-contrib-imagemin": "^0.9.3",
15 | "grunt-contrib-uglify": "^0.8.0",
16 | "grunt-contrib-watch": "^0.6.1",
17 | "grunt-eslint": "^16.0.0",
18 | "grunt-filerev": "^2.2.0",
19 | "grunt-mocha": "^0.4.12",
20 | "grunt-modernizr": "^0.6.0",
21 | "grunt-newer": "^1.1.0",
22 | "grunt-postcss": "^0.5.3",
23 | "grunt-sass": "^1.0.0",
24 | "grunt-svgmin": "^2.0.1",
25 | "grunt-usemin": "^3.0.0",
26 | "grunt-wiredep": "^2.0.0",
27 | "jit-grunt": "^0.9.1",
28 | "time-grunt": "^1.1.0"
29 | },
30 | "engines": {
31 | "node": ">=0.10.0"
32 | },
33 | "scripts": {
34 | "test": "grunt test"
35 | },
36 | "eslintConfig": {
37 | "env": {
38 | "node": true,
39 | "browser": true,
40 | "mocha": true
41 | },
42 | "rules": {
43 | "quotes": [
44 | 2,
45 | "single"
46 | ]
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/design/frontpage/test/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Mocha Spec Runner
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
18 |
19 |
20 |
21 |
22 |
23 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/design/frontpage/test/spec/test.js:
--------------------------------------------------------------------------------
1 | (function () {
2 | 'use strict';
3 |
4 | describe('Give it some context', function () {
5 | describe('maybe a bit more context here', function () {
6 | it('should run here few assertions', function () {
7 |
8 | });
9 | });
10 | });
11 | })();
12 |
--------------------------------------------------------------------------------
/design/launch-page/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/launch-page/favicon.ico
--------------------------------------------------------------------------------
/design/launch-page/images/after.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/launch-page/images/after.png
--------------------------------------------------------------------------------
/design/launch-page/images/avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/launch-page/images/avatar.png
--------------------------------------------------------------------------------
/design/launch-page/images/before.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/launch-page/images/before.png
--------------------------------------------------------------------------------
/design/launch-page/images/brewr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/launch-page/images/brewr.png
--------------------------------------------------------------------------------
/design/launch-page/images/header.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/launch-page/images/header.jpg
--------------------------------------------------------------------------------
/design/launch-page/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/launch-page/images/logo.png
--------------------------------------------------------------------------------
/design/launch-page/images/option-dropdown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/launch-page/images/option-dropdown.png
--------------------------------------------------------------------------------
/design/launch-page/images/screenshot-background.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/launch-page/images/screenshot-background.jpg
--------------------------------------------------------------------------------
/design/launch-page/images/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/launch-page/images/screenshot.png
--------------------------------------------------------------------------------
/design/launch-page/images/screenshot@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/design/launch-page/images/screenshot@2x.png
--------------------------------------------------------------------------------
/design/launch-page/styles/components/comparison.scss:
--------------------------------------------------------------------------------
1 | #comparison {
2 | margin-top: $spacing;
3 | margin-left: auto;
4 | margin-right: auto;
5 | max-width: 800px;
6 |
7 | img {
8 | margin-top: $spacing;
9 | }
10 |
11 | h4 {
12 | font-weight: normal;
13 | font-size: 24px;
14 | margin-top: $spacing;
15 | margin-bottom: $spacing / 2;
16 |
17 | .success {
18 | color: $colorSuccess;
19 | }
20 | }
21 |
22 | p {
23 | line-height: 1.5;
24 | font-size: 18px;
25 | opacity: 0.7;
26 | }
27 |
28 | .line {
29 | width: 2px;
30 | background-color: #dedede;
31 | height: 110px;
32 | margin-right: auto;
33 | margin-left: auto;
34 | }
35 |
36 | .vs {
37 | padding: 20px;
38 | font-weight: bold;
39 | color: #999;
40 | }
41 | }
--------------------------------------------------------------------------------
/design/launch-page/styles/components/content.scss:
--------------------------------------------------------------------------------
1 | .content {
2 | h1 {
3 | background-color: $colorPrimaryLightShade1;
4 | margin: 0;
5 | padding: 10px 20px;
6 | color: $colorTextHeader;
7 | display: block;
8 | text-transform: uppercase;
9 | color: $colorTextTitle;
10 | font-size: 20px;
11 | font-weight: normal;
12 |
13 | #step {
14 | float: right;
15 | font-size: 12px;
16 | line-height: 22px;
17 | }
18 | }
19 | }
20 |
21 | .content > .container {
22 | height: 100%;
23 | margin-left: 200px;
24 | position: relative;
25 | }
26 |
--------------------------------------------------------------------------------
/design/launch-page/styles/components/flexbox.scss:
--------------------------------------------------------------------------------
1 | .flex-container {
2 | width: 100%;
3 | padding: 0;
4 | // margin: 0 30px 30px 30px;
5 | list-style: none;
6 |
7 | -ms-box-orient: horizontal;
8 | display: -webkit-box;
9 | display: -moz-box;
10 | display: -ms-flexbox;
11 | display: -moz-flex;
12 | display: -webkit-flex;
13 | display: flex;
14 |
15 | // Space between gives margin within boxes
16 | -webkit-justify-content: space-between;
17 | justify-content: space-between;
18 |
19 | align-items: center;
20 | flex-flow: wrap;
21 | }
22 |
23 | .flex-container > .container {
24 | padding-right: 0;
25 | width: 100%;
26 | }
27 |
28 | .flex-item {
29 | margin: 10px;
30 |
31 | color: white;
32 | font-weight: bold;
33 | font-size: 14px;
34 | text-align: center;
35 |
36 | flex-grow: 3;
37 |
38 | padding: 10px;
39 |
40 | input {
41 | width: 100%;
42 | padding: 10px 10px;
43 | font-weight: normal;
44 | color: $colorBlack;
45 | display: inline-block;
46 | box-sizing: border-box;
47 | border: 1px solid $colorBoxBorder;
48 | margin-bottom: 20px;
49 | }
50 |
51 | label {
52 | color: $colorBlack;
53 | text-align: left;
54 | font-weight: normal;
55 | margin-bottom: 10px;
56 | display: block;
57 | text-transform: uppercase;
58 | font-size: 16px;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/design/launch-page/styles/components/footer.scss:
--------------------------------------------------------------------------------
1 | footer {
2 | padding: $spacing;
3 | background-color: $colorText;
4 | color: #fff;
5 |
6 | .logo {
7 | background-image: url(../images/logo.png);
8 | background-size: 166px 40px;
9 | display: block;
10 | width: 166px;
11 | height: 40px;
12 | float: left;
13 | }
14 |
15 | .links {
16 | a {
17 | color: #fff;
18 | opacity: 0.5;
19 | padding: 12px;
20 | display: inline-block;
21 | text-decoration: none;
22 |
23 | &:hover {
24 | opacity: 1;
25 | }
26 | }
27 |
28 | .divider {
29 | height: 10px;
30 | width: 1px;
31 | background-color: #fff;
32 | opacity: 0.2;
33 | display: inline-block;
34 | }
35 | }
36 |
37 | .circle {
38 | color: #fff;
39 | width: 36px;
40 | height: 36px;
41 | border: 2px solid #fff;
42 | display: inline-block;
43 | text-align: center;
44 | border-radius: 50%;
45 | line-height: 34px;
46 | margin-left: 10px;
47 | margin-top: 3px;
48 |
49 | &:hover {
50 | background-color: #fff;
51 | color: $colorText;
52 | }
53 | }
54 | }
55 |
56 | #license {
57 | background-color: darken($colorText, 3%);
58 | padding: $spacing/2;
59 | text-align: center;
60 | color: #555;
61 | font-size: 12px;
62 |
63 | a {
64 | color: #555;
65 | text-decoration: none;
66 | }
67 | }
--------------------------------------------------------------------------------
/design/launch-page/styles/components/icon-block.scss:
--------------------------------------------------------------------------------
1 | .icon-block {
2 | .circle {
3 | font-size: 42px;
4 | border: 6px solid #000;
5 | display: inline-block;
6 | height: 120px;
7 | width: 120px;
8 | line-height: 112px;
9 | border-radius: 50%;
10 |
11 |
12 | &.accent {
13 | border-color: $colorAccent;
14 | color: $colorAccent;
15 | }
16 |
17 | &.success {
18 | border-color: $colorSuccess;
19 | color: $colorSuccess;
20 | }
21 |
22 | &.info {
23 | border-color: $colorInfo;
24 | color: $colorInfo;
25 | }
26 | }
27 |
28 | h3 {
29 | font-size: 24px;
30 | margin-top: $spacing/2;
31 | margin-bottom: $spacing/4;
32 | }
33 |
34 | p.subtitle {
35 | max-width: 320px;
36 | margin-right: auto;
37 | margin-left: auto;
38 | }
39 |
40 | // Crappy centering workarounds
41 | i.fa-play {
42 | margin-right: -10px;
43 | }
44 | }
--------------------------------------------------------------------------------
/design/launch-page/styles/components/list.scss:
--------------------------------------------------------------------------------
1 | .sub-content li {
2 | background-color: white;
3 | font-size: 14px;
4 | border-top: 1px solid $colorBoxBorder;
5 | border-left: 1px solid $colorBoxBorder;
6 | border-right: 1px solid $colorBoxBorder;
7 | text-align: left;
8 | height: 35px;
9 | position: relative;
10 | line-height: 35px;
11 | padding-left: 10px;
12 |
13 | a {
14 | width: 35px;
15 | line-height: 35px;
16 | padding: 0;
17 | text-align: center;
18 | top: 0;
19 | }
20 |
21 | a:first-child {
22 | margin-left: -10px; // negate the padding-left
23 | border-right: 1px solid $colorBoxBorder;
24 | background-color: $colorLeftListPart;
25 | color: $colorLeftListPartText;
26 | left: 0;
27 | display: inline-block;
28 | position: initial;
29 | margin-right: 10px;
30 | }
31 |
32 | a:last-child {
33 | margin: 0;
34 | border-right: none;
35 | border-left: 1px solid $colorBoxBorder;
36 | right: 0;
37 | position: absolute;
38 | left: initial;
39 | }
40 | }
41 |
42 | .sub-content li:last-child {
43 | border-top: 1px solid $colorBoxBorder;
44 | border-bottom: 1px solid $colorBoxBorder;
45 | }
46 |
--------------------------------------------------------------------------------
/design/launch-page/styles/components/menu.scss:
--------------------------------------------------------------------------------
1 | nav {
2 | //position: fixed;
3 | position: absolute;
4 | width: 100%;
5 | top: 0;
6 | padding-top: $spacing;
7 | padding-bottom: $spacing;
8 |
9 | .logo {
10 | background-image: url(../images/logo.png);
11 | background-size: 166px 40px;
12 | display: block;
13 | width: 166px;
14 | height: 40px;
15 | float: left;
16 | }
17 |
18 | ul {
19 | float: right;
20 |
21 | li {
22 | list-style: none;
23 | display: inline-block;
24 |
25 | a {
26 | display: block;
27 | color: #fff;
28 | margin-left: $spacing/2;
29 | font-size: 16px;
30 | text-decoration: none;
31 | font-weight: bold;
32 | letter-spacing: 1px;
33 | }
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/design/launch-page/styles/components/page-title.scss:
--------------------------------------------------------------------------------
1 | .page-title {
2 | h1 {
3 | background-color: $colorPrimaryLightShade2;
4 | margin: 0;
5 | padding: 10px 20px 10px 240px;
6 | display: block;
7 | color: $colorTextTitle;
8 | font-size: 20px;
9 | font-weight: normal;
10 | letter-spacing: 1px;
11 |
12 | #step {
13 | float: right;
14 | font-size: 12px;
15 | line-height: 22px;
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/design/launch-page/styles/components/plan.scss:
--------------------------------------------------------------------------------
1 | .plan {
2 | background-color: #fff;
3 | width: 280px;
4 | text-align: center;
5 | display: inline-block;
6 | color: $colorText;
7 | border-radius: 3px;
8 | margin-left: 10px;
9 | margin-right: 10px;
10 |
11 | li {
12 | list-style: none;
13 | text-align: left;
14 | font-weight: bold;
15 | line-height: 2;
16 |
17 | &.disabled {
18 | color: #999;
19 | }
20 |
21 | i {
22 | margin-right: 10px;
23 | }
24 | }
25 |
26 | .title {
27 | font-size: 24px;
28 | font-weight: bold;
29 | margin-top: $spacing/2;
30 | }
31 |
32 | .subtitle {
33 | font-size: 18px;
34 | margin-top: 3px;
35 | margin-bottom: $spacing/2;
36 | }
37 |
38 | .price {
39 | background-color: $colorPrimaryHighlight;
40 | color: #fff;
41 | padding: $spacing/2;
42 | font-size: 22px;
43 | font-weight: bold;
44 |
45 | &.success {
46 | background-color: $colorSuccess;
47 | }
48 |
49 | small {
50 | font-size: 14px;
51 | }
52 | }
53 |
54 | .button {
55 | margin-bottom: $spacing / 2;
56 | }
57 | }
--------------------------------------------------------------------------------
/design/launch-page/styles/components/screenshot.scss:
--------------------------------------------------------------------------------
1 | #screenshot {
2 | background-color: $colorPrimary;
3 | background-image: url(../images/screenshot-background.jpg);
4 | background-size: cover;
5 | background-position: center bottom;
6 | padding-top: $spacing * 2;
7 | color: #fff;
8 | overflow: hidden;
9 |
10 | p.subtitle {
11 | max-width: 520px;
12 | font-size: 18px;
13 | margin-right: auto;
14 | margin-left: auto;
15 | line-height: 1.5;
16 | opacity: 0.6;
17 | }
18 | }
19 |
20 | #screenshot-image {
21 | background-image: url(../images/screenshot.png);
22 | background-size: 770px 474px;
23 | width: 770px;
24 | height: 474px;
25 | margin-right: auto;
26 | margin-left: auto;
27 | margin-top: $spacing;
28 |
29 | @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
30 | background-image: url(../images/screenshot@2x.png);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/design/launch-page/styles/components/section.scss:
--------------------------------------------------------------------------------
1 | section {
2 | background-color: $colorBackground;
3 |
4 | &.padding {
5 | padding: $spacing;
6 | }
7 |
8 | &.padding-double {
9 | padding: $spacing * 2;
10 | }
11 |
12 | &.centered {
13 | text-align: center;
14 | }
15 |
16 | &.accent {
17 | background-color: $colorAccent;
18 | color: #fff;
19 | }
20 |
21 | &.dark {
22 | background-color: $colorSecondary;
23 | color: #fff;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/design/launch-page/styles/components/spacer.scss:
--------------------------------------------------------------------------------
1 | .spacer {
2 | height: $spacing;
3 | }
4 |
5 | .spacer-half {
6 | height: $spacing / 2;
7 | }
8 |
9 | .spacer-double {
10 | height: $spacing * 2;
11 | }
12 |
13 | .padding {
14 | padding: $spacing;
15 | }
16 |
17 | .padding-half {
18 | padding: $spacing / 2;
19 | }
--------------------------------------------------------------------------------
/design/launch-page/styles/components/sub-content.scss:
--------------------------------------------------------------------------------
1 | .sub-content {
2 | margin: 0 auto;
3 |
4 | h1 {
5 | color: $colorText;
6 | background-color: transparent;
7 | font-size: 18px;
8 | text-transform: none;
9 | text-align: center;
10 | margin-bottom: 20px;
11 | width: 100%;
12 | }
13 |
14 | h2 {
15 | color: $colorBlack;
16 | text-align: left;
17 | font-weight: normal;
18 | margin-bottom: 10px;
19 | display: block;
20 | text-transform: uppercase;
21 | font-size: 16px;
22 | }
23 |
24 | ul {
25 | padding: 0;
26 | display: block;
27 | list-style: none;
28 | color: $colorText;
29 | font-weight: normal;
30 | font-size: 14px;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/design/launch-page/styles/components/wrapper.scss:
--------------------------------------------------------------------------------
1 | .wrapper {
2 | position: relative;
3 | }
4 |
--------------------------------------------------------------------------------
/design/launch-page/styles/config.scss:
--------------------------------------------------------------------------------
1 | // Colors
2 | $colorWhite: #FFFFFF;
3 | $colorBlack: #000000;
4 |
5 | $colorHelpBox: #333333;
6 | $colorHelpIcon: #333333;
7 | $colorHelpIconHover: #999999;
8 |
9 | $colorBackground: #F5F5F5;
10 |
11 | $colorPrimaryLightShade1: #2a3c50;
12 | $colorPrimaryLightShade2: #32465d;
13 | $colorPrimaryLightShade3: #39506A;
14 | $colorPrimary: #233141;
15 | $colorPrimaryDarkShade1: #151E28;
16 | $colorPrimaryDarkShade2: #1D2835;
17 |
18 | $colorMenuItem: #d3d6d9;
19 | $colorMenuItemActive: #56789f;
20 |
21 | $colorBoxBorder: #cccccc;
22 |
23 | $colorButtonNext: #f15843;
24 | $colorButtonNextHover: #ff604b;
25 | $colorLeftListPart: #F7F7F7;
26 | $colorLeftListPartText: #6C6C6C;
27 |
28 | $colorSecondary: #1c2632;
29 | $colorAccent: #f15843;
30 | $colorSuccess: #41b222;
31 | $colorLight: #999999;
32 | $colorText: #101010;
33 | $colorTextHeader: #32465d;
34 | $colorTextTitle: #ffffff;
35 | $colorBlue: #227ab2;
36 | $colorSuccess: #41b222;
37 | $colorInfo: #227ab2;
38 | $colorPrimaryHighlight: #3a4856;
39 |
40 | // Generic
41 | $spacing: 40px;
42 |
--------------------------------------------------------------------------------
/design/launch-page/styles/general/base.scss:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: sans-serif;
3 | font-size: 16px;
4 | color: $colorText;
5 | background-color: darken($colorText, 3%);
6 | }
7 |
8 | a {
9 | color: $colorAccent;
10 | }
11 |
12 | .accent a {
13 | color: #fff;
14 | }
--------------------------------------------------------------------------------
/design/launch-page/styles/general/reset.scss:
--------------------------------------------------------------------------------
1 | html, body {
2 | height: 100%;
3 | }
4 |
5 | * {
6 | margin: 0;
7 | padding: 0;
8 | box-sizing: border-box;
9 | }
10 |
11 | .clearfix {
12 | clear: both;
13 | }
14 |
15 | *:focus {
16 | outline: none;
17 | }
--------------------------------------------------------------------------------
/design/launch-page/styles/general/typography.scss:
--------------------------------------------------------------------------------
1 | h2 {
2 | font-size: 36px;
3 | font-weight: normal;
4 | letter-spacing: 1px;
5 | margin-bottom: $spacing/2;
6 |
7 | &.smaller {
8 | font-size: 28px;
9 | }
10 | }
11 |
12 | body {
13 | font-family: "Open Sans", sans-serif;
14 | }
15 |
16 | h1 {
17 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
18 | }
19 |
20 | .subtitle {
21 | font-size: 18px;
22 | opacity: 0.6;
23 | line-height: 1.5;
24 | }
25 |
26 | section .subtitle {
27 | max-width: 600px;
28 | margin-right: auto;
29 | margin-left: auto;
30 | }
31 |
32 | .bold {
33 | font-weight: bold;
34 | }
35 |
36 | .small {
37 | font-size: 14px;
38 | }
39 |
40 | .align-left {
41 | text-align: left;
42 | }
43 |
44 | .align-center {
45 | text-align: center;
46 | }
47 |
48 | .align-right {
49 | text-align: right;
50 | }
51 |
52 | .text-accent {
53 | color: $colorAccent;
54 | }
55 |
56 | .text-info {
57 | color: $colorInfo;
58 | }
59 |
60 | .text-success {
61 | color: $colorSuccess;
62 | }
63 |
64 | .text-disabled {
65 | color: #777;
66 | }
67 |
--------------------------------------------------------------------------------
/design/launch-page/styles/main.scss:
--------------------------------------------------------------------------------
1 | // Configuration
2 | @import 'config';
3 |
4 | // Third party dependencies
5 | @import 'lib/bootstrap-grid';
6 |
7 | // General
8 | @import 'general/reset';
9 | @import 'general/base';
10 | @import 'general/typography';
11 |
12 | // Mixins
13 | @import 'mixins/transition';
14 | @import 'mixins/responsive';
15 |
16 | // UI components
17 | @import 'components/header';
18 | @import 'components/menu';
19 | @import 'components/button';
20 | @import 'components/section';
21 | @import 'components/icon-block';
22 | @import 'components/screenshot';
23 | @import 'components/spacer';
24 | @import 'components/footer';
25 | @import 'components/plan';
26 | @import 'components/comparison';
27 | @import 'components/flexbox';
28 | @import 'components/image-builder';
29 | @import 'components/sub-menu';
30 | @import 'components/list';
31 | @import 'components/content';
32 | @import 'components/sub-content';
33 | @import 'components/page-title';
34 | @import 'components/wrapper';
35 |
--------------------------------------------------------------------------------
/design/launch-page/styles/mixins/responsive.scss:
--------------------------------------------------------------------------------
1 | // $xs: ~"screen and (max-width: 768px)";
2 | // $sm: ~"screen and (max-width: 992px)";
3 | // $md: ~"screen and (min-width: 992px)";
4 | $xs: "(screen and (max-width: 768px))";
5 | $sm: "(screen and (max-width: 992px))";
6 | $md: "(screen and (min-width: 992px))";
7 |
--------------------------------------------------------------------------------
/design/launch-page/styles/mixins/transition.scss:
--------------------------------------------------------------------------------
1 | .transition {
2 | transition: 0.5 all linear;
3 | -webkit-transition: 0.5 all linear;
4 | -moz-transition: 0.5 all linear;
5 | -ms-transition: 0.5 all linear;
6 | -o-transition: 0.5 all linear;
7 | }
8 |
--------------------------------------------------------------------------------
/frontend/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "stage": 2,
3 | "env": {
4 | "development": {
5 | "plugins": ["react-transform"],
6 | "extra": {
7 | "react-transform": {
8 | "transforms": [
9 | {
10 | "transform": "react-transform-hmr",
11 | "imports": ["react"],
12 | "locals": ["module"]
13 | }
14 | ]
15 | }
16 | }
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/frontend/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 |
12 | [*.md]
13 | trim_trailing_whitespace = false
14 |
--------------------------------------------------------------------------------
/frontend/.gitignore:
--------------------------------------------------------------------------------
1 | /bower_components/
2 | /dist/
3 | /node_modules/
4 |
--------------------------------------------------------------------------------
/frontend/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "frontend",
3 | "version": "0.1.0",
4 | "dependencies": {}
5 | }
6 |
7 |
--------------------------------------------------------------------------------
/frontend/src/actions/BuilderActions.js:
--------------------------------------------------------------------------------
1 | import AppDispatcher from '../dispatchers/AppDispatcher.js';
2 | import * as actionTypes from '../constants/ActionTypes';
3 | import * as ProjectAPIUtils from '../utils/ProjectAPIUtils';
4 |
5 | class BuilderActions {
6 | static saveProject(token, organisationUUID, project) {
7 | // Dispatch the login event on the view
8 | AppDispatcher.handleViewAction({
9 | type: actionTypes.REQUEST_BUILDER_SAVE_PROJECT,
10 | project: project,
11 | organisationUUID: organisationUUID
12 | });
13 |
14 | // login the user
15 | ProjectAPIUtils.create(token, organisationUUID, project.meta, project.files, project.envInfo);
16 | }
17 | }
18 |
19 | export default BuilderActions;
20 |
--------------------------------------------------------------------------------
/frontend/src/actions/DockerHubActions.js:
--------------------------------------------------------------------------------
1 | import AppDispatcher from '../dispatchers/AppDispatcher.js';
2 | import * as types from '../constants/ActionTypes';
3 |
4 | export function setRepositories(repositories) {
5 | AppDispatcher.handleViewAction({
6 | type: types.DOCKER_HUB_FETCH_REPOSITORIES,
7 | repositories: repositories
8 | });
9 | }
10 |
--------------------------------------------------------------------------------
/frontend/src/actions/OrganisationServerActions.js:
--------------------------------------------------------------------------------
1 | import AppDispatcher from '../dispatchers/AppDispatcher';
2 | import * as actionTypes from '../constants/ActionTypes';
3 |
4 | // Normal Responses
5 | export function receiveGetOrganisationMembersResponse(response) {
6 | AppDispatcher.handleServerAction({
7 | type: actionTypes.RESPONSE_ORGANISATION_MEMBERS,
8 | response: response
9 | });
10 | }
11 |
12 | export function receiveGetOrganisationMembersErrorResponse(err) {
13 | AppDispatcher.handleServerAction({
14 | type: actionTypes.RESPONSE_ORGANISATION_MEMBERS_ERROR,
15 | error: err
16 | });
17 | }
18 |
--------------------------------------------------------------------------------
/frontend/src/actions/ProjectServerActions.js:
--------------------------------------------------------------------------------
1 | import AppDispatcher from '../dispatchers/AppDispatcher';
2 | import * as actionTypes from '../constants/ActionTypes';
3 | import * as ProjectConstants from '../constants/ProjectConstants';
4 |
5 | // Normal Responses
6 | export function receiveProjectResponse(response) {
7 | AppDispatcher.handleServerAction({
8 | type: actionTypes.RESPONSE_PROJECT,
9 | response: response
10 | });
11 | }
12 |
13 | export function receiveProjectImageResponse(response) {
14 | AppDispatcher.handleServerAction({
15 | type: actionTypes.RESPONSE_PROJECT_IMAGE,
16 | response: response
17 | });
18 | }
19 |
20 | // Errors
21 | export function receiveProjectErrorResponse(err) {
22 | AppDispatcher.handleServerAction({
23 | type: actionTypes.RESPONSE_PROJECT_ERROR,
24 | error: err
25 | });
26 | }
27 |
28 | export function assignMemberResponse(response) {
29 | AppDispatcher.handleServerAction({
30 | type: ProjectConstants.PROJECT_ASSIGN_MEMBER,
31 | response: response
32 | });
33 | }
34 |
--------------------------------------------------------------------------------
/frontend/src/components/App/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "App",
3 | "version": "0.0.0",
4 | "private": true,
5 | "main": "./App.js"
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/BaseComponent.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by Maxim on 17/08/2015.
3 | */
4 | import React from 'react';
5 |
6 |
7 | export default class BaseComponent extends React.Component {
8 |
9 | // bind functions to it's component by using this._bind('functionName', 'functionName2', ...) on extending
10 | // With React.createClass, every non-lifecycle method is auto bound to component instance, not with ES6!
11 | _bind(...methods) {
12 | methods.forEach((method) => this[method] = this[method].bind(this));
13 | }
14 | }
--------------------------------------------------------------------------------
/frontend/src/components/elements/AssignableMemberList/avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/frontend/src/components/elements/AssignableMemberList/avatar.png
--------------------------------------------------------------------------------
/frontend/src/components/elements/Builder/Builder.scss:
--------------------------------------------------------------------------------
1 | @import '../../../css/colors';
2 |
3 | .BuilderStep1Page Button {
4 | margin: 20px 0 10px 0;
5 | float: right;
6 | }
7 |
8 | .BuilderPage-HelpIcon {
9 | font-size: 13px;
10 | position: absolute;
11 | margin-left: 5px;
12 | font-weight: bold;
13 | }
14 |
15 | .BuilderPage-HelpIcon:hover {
16 | cursor: pointer;
17 | }
18 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/Builder/option-dropdown-accent.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/frontend/src/components/elements/Builder/option-dropdown-accent.png
--------------------------------------------------------------------------------
/frontend/src/components/elements/Builder/option-dropdown-success.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/frontend/src/components/elements/Builder/option-dropdown-success.png
--------------------------------------------------------------------------------
/frontend/src/components/elements/Builder/option-dropdown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/frontend/src/components/elements/Builder/option-dropdown.png
--------------------------------------------------------------------------------
/frontend/src/components/elements/Builder/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Builder",
3 | "version": "0.0.0",
4 | "private": true,
5 | "main": "./Builder.js"
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/Button/Button.scss:
--------------------------------------------------------------------------------
1 | @import '../../../css/colors';
2 |
3 | .Button {
4 | border-radius: 4px;
5 | border: 2px solid $color-primary;
6 | background-color: $color-primary;
7 | color: $color-primary;
8 | display: inline-block;
9 | text-decoration: none;
10 | padding: 9px 15px;
11 | font-size: 16px;
12 | font-weight: bold;
13 | cursor: pointer;
14 | }
15 |
16 | .Button-Form {
17 | border-radius: 0px;
18 | padding: 5px 10px;
19 | font-size: 14px;
20 | }
21 |
22 | .Button-Color-Orange {
23 | background-color: $color-accent;
24 | color: $color-white;
25 | border-color: $color-accent-shade-darker-1;
26 | }
27 |
28 | .Button-Color-Orange:hover {
29 | background-color: $color-accent-shade-lighter-1;
30 | color: $color-white;
31 | border-color: $color-accent;
32 | }
33 |
34 | .Button-Color-White {
35 | background-color: $color-white;
36 | color: $color-primary;
37 | border-color: $color-white;
38 | }
39 |
40 | .Button-Inline {
41 | display: inline-block;
42 | }
43 |
44 | .Button-DragIcon {
45 | cursor: move;
46 | }
47 |
48 | .Button-Align-Right {
49 | float: right;
50 | }
51 |
52 | .Button-Align-Left {
53 | float: left;
54 | }
55 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/Button/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Button",
3 | "version": "0.0.0",
4 | "private": true,
5 | "main": "./Button.js"
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/CRUDList/CRUDList.scss:
--------------------------------------------------------------------------------
1 | @import '../../../css/colors';
2 |
3 | .CRUDList h1 {
4 | font-size: 14px;
5 | letter-spacing: 1px;
6 | }
7 |
8 | /*.CRUDList form .Input {
9 | width: calc(100% - 80px);
10 | }*/
11 |
12 | .CRUDList form .Button {
13 | width: 80px;
14 | border: 1px solid rgba(0, 0, 0, 0.07);
15 | }
16 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/CRUDList/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "CRUDList",
3 | "version": "0.0.0",
4 | "private": true,
5 | "main": "./CRUDList.js"
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/DistributionPicker/DistributionPicker.scss:
--------------------------------------------------------------------------------
1 | @import '../../../css/colors';
2 |
3 | .DistributionPicker-FlexContainer {
4 | display: flex;
5 | flex-wrap: wrap;
6 | }
7 |
8 | .DistributionPicker-PickDistribution:hover {
9 | cursor: pointer;
10 | }
11 |
12 | .DistributionPicker-PickDistribution {
13 | background-color: #FFFFFF;
14 | border: 1px solid #cccccc;
15 |
16 | margin: 20px;
17 | font-weight: bold;
18 | font-size: 14px;
19 | text-align: center;
20 | padding: 10px;
21 | flex-grow: 3;
22 | border-radius: 3px;
23 | }
24 |
25 | .DistributionPicker-PickDistribution h1 {
26 | font-size: 24px;
27 | margin: 0 0 5px 0;
28 | }
29 |
30 | .DistributionPicker-PickDistribution img {
31 | height: 64px;
32 | max-width: 150px;
33 | margin: 0 auto;
34 | padding: 10px 0 10px 0;
35 | display: block;
36 | }
37 |
38 | .DistributionPicker-PickDistribution-Selected {
39 | border: 1px solid $color-success;
40 | color: $color-success;
41 | }
42 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/DistributionPicker/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "DistributionPicker",
3 | "version": "0.0.0",
4 | "private": true,
5 | "main": "./DistributionPicker.js"
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/Divider/Divider.js:
--------------------------------------------------------------------------------
1 | import styles from './Divider.scss';
2 |
3 | import React, { PropTypes } from 'react';
4 | import cx from 'classnames';
5 |
6 | class Divider extends React.Component {
7 | render() {
8 | var className = cx(
9 | styles['Divider'],
10 | this.props.align === 'horizontal' ? styles['Divider-Horizontal'] : null,
11 | this.props.align === 'vertical' ? styles['Divider-Vertical'] : null,
12 | );
13 |
14 | return (
15 |
16 | {
17 | this.props.text ?
18 | {this.props.text}
19 | : undefined
20 | }
21 |
22 | );
23 | }
24 | };
25 |
26 | Divider.propTypes = {
27 | text: PropTypes.string,
28 | align: PropTypes.string
29 | };
30 |
31 | Divider.defaultProps = {
32 | text: '',
33 | align: 'horizontal'
34 | };
35 |
36 | export default Divider;
37 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/Divider/Divider.scss:
--------------------------------------------------------------------------------
1 | @import '../../../css/colors';
2 |
3 | .Divider {
4 | text-align: center;
5 | }
6 |
7 | .Divider span {
8 | background: #FFF;
9 | text-transform: uppercase;
10 | font-weight: bold;
11 | }
12 |
13 | .Divider {
14 | text-align: center;
15 | }
16 |
17 | .Divider-Horizontal {
18 | border-bottom: 1px solid $colorBorder;
19 | width: 100%;
20 | line-height: 0.1em;
21 | margin: 20px 0;
22 | }
23 |
24 | .Divider-Vertical {
25 | border-right: 1px solid $colorBorder;
26 | width: 1px;
27 | height: 20px;
28 | display: inline-block;
29 | float: left;
30 | margin-top: 25px;
31 | }
32 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/Divider/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Divider",
3 | "version": "0.0.0",
4 | "private": true,
5 | "main": "./Divider"
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/DockerHubSearch/DockerHubSearch.js:
--------------------------------------------------------------------------------
1 | import styles from './DockerHubSearch.scss';
2 |
3 | import React, { PropTypes } from 'react';
4 | import DockerHubService from '../../../services/DockerHubService';
5 |
6 | export default class DockerHubSearch extends React.Component {
7 | constructor(props) {
8 | super(props);
9 |
10 | this.state = {
11 | repositories: []
12 | };
13 | }
14 |
15 | handleChange(e) {
16 | console.log(e.target.value);
17 | DockerHubService.fetchRepositories(e.target.value)
18 | .catch(function(err) {
19 | console.log('error fetching repositories');
20 | });
21 | }
22 |
23 | render() {
24 | return (
25 |
26 |
27 |
28 | );
29 | }
30 | };
31 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/DockerHubSearch/DockerHubSearch.scss:
--------------------------------------------------------------------------------
1 | @import '../../../css/colors';
2 |
3 | .DockerHubSearch {
4 | margin: 0 auto;
5 | width: 30%;
6 | }
7 |
8 | .DockerHubSearch input {
9 | width: 100%;
10 | padding: 10px 10px;
11 | font-weight: normal;
12 | color: $color-black;
13 | display: inline-block;
14 | box-sizing: border-box;
15 | border: 1px solid #cccccc;
16 | }
17 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/DockerHubSearch/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "DockerHubSearch",
3 | "version": "0.0.0",
4 | "private": true,
5 | "main": "./DockerHubSearch"
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/DockerfileViewer/DockerfileViewer.scss:
--------------------------------------------------------------------------------
1 | @import '../../../css/colors';
2 |
3 | .DockerfileViewer-Dockerfile {
4 | background-color: $color-terminal;
5 | min-height: 100px;
6 | border-radius: 3px;
7 | padding: 10px 15px;
8 | color: $color-terminal-text;
9 | text-shadow: 0 0 1px $color-terminal-text-shadow;
10 | overflow-x: scroll;
11 | }
12 |
13 | .DockerfileViewer-Dockerfile > div {
14 | margin-bottom: 10px;
15 | }
16 |
17 | .DockerfileViewer-Dockerfile > div:last-child {
18 | margin-bottom: 0px;
19 | }
20 |
21 | .DockerfileViewer-StartupParams {
22 | background-color: $color-terminal;
23 | min-height: 100px;
24 | border-radius: 3px;
25 | padding: 10px 15px;
26 | color: $color-terminal-text;
27 | text-shadow: 0 0 1px $color-terminal-text-shadow;
28 | }
29 |
30 | .DockerfileViewer-StartupParams > div {
31 | margin-bottom: 10px;
32 | }
33 |
34 | .DockerfileViewer-StartupParams > div:last-child {
35 | margin-bottom: 0px;
36 | }
37 |
38 | .DockerfileViewer-StartupScript {
39 | background-color: $color-terminal;
40 | min-height: 100px;
41 | border-radius: 3px;
42 | padding: 10px 15px;
43 | color: $color-terminal-text;
44 | text-shadow: 0 0 1px $color-terminal-text-shadow;
45 | }
46 |
47 | .DockerfileViewer-StartupScript > div {
48 | margin-bottom: 10px;
49 | }
50 |
51 | .DockerfileViewer-StartupScript > div:last-child {
52 | margin-bottom: 0px;
53 | }
54 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/DockerfileViewer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "DockerfileViewer",
3 | "version": "0.0.0",
4 | "private": true,
5 | "main": "./DockerfileViewer.js"
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/Dropdown/Dropdown.js:
--------------------------------------------------------------------------------
1 | import fa from 'font-awesome/css/font-awesome.css';
2 | import styles from './Dropdown.scss';
3 |
4 | import React, {PropTypes } from 'react';
5 | import cx from 'classnames';
6 |
7 | class Dropdown extends React.Component {
8 | handleChange (el) {
9 | this.props.onChange(this.refs.dropdownOption.getDOMNode().value);
10 | }
11 |
12 | render() {
13 | var self = this;
14 | var options = [];
15 |
16 | this.props.items.forEach((item, index) => {
17 | options.push();
18 | });
19 |
20 | var className = cx(
21 | styles['Dropdown'],
22 | this.props.isSelected ? 'Dropdown-Selected' : null
23 | );
24 |
25 | return (
26 |
27 |
30 |
31 | );
32 | }
33 | };
34 |
35 | Dropdown.propTypes = {
36 | items: PropTypes.array,
37 | isSelected: PropTypes.bool, // Is the current selectdown box selected (different color)
38 | onChange: PropTypes.func
39 | };
40 |
41 | Dropdown.defaultProps = {
42 | items: [],
43 | isSelected: false
44 | };
45 |
46 | export default Dropdown;
47 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/Dropdown/Dropdown.scss:
--------------------------------------------------------------------------------
1 | @import '../../../css/colors';
2 |
3 | .Dropdown select {
4 | margin: 0;
5 | width: 90%;
6 | background: url("./option-dropdown.png") no-repeat right #FFF;
7 | color: $color-black;
8 | border: 0;
9 | border-radius: 0;
10 | -webkit-appearance: none;
11 | height: 34px;
12 | line-height: 1;
13 | font-size: 12px;
14 | font-weight: normal;
15 | padding: 5px 25px 5px 10px;
16 | }
17 |
18 | .Dropdown-Selected {
19 | color: $color-success !important;
20 | }
21 |
22 | .Dropdown-Selected select {
23 | background: url("./option-dropdown-success.png") no-repeat right #FFF !important;
24 | color: $color-success !important;
25 | text-align: center;
26 | }
27 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/Dropdown/option-dropdown-accent.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/frontend/src/components/elements/Dropdown/option-dropdown-accent.png
--------------------------------------------------------------------------------
/frontend/src/components/elements/Dropdown/option-dropdown-success.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/frontend/src/components/elements/Dropdown/option-dropdown-success.png
--------------------------------------------------------------------------------
/frontend/src/components/elements/Dropdown/option-dropdown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/frontend/src/components/elements/Dropdown/option-dropdown.png
--------------------------------------------------------------------------------
/frontend/src/components/elements/Dropdown/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Dropdown",
3 | "version": "0.0.0",
4 | "private": true,
5 | "main": "./Dropdown"
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/DropdownMenu/DropdownMenuItem.js:
--------------------------------------------------------------------------------
1 | import styles from './DropdownMenu.scss';
2 | import React, { PropTypes } from 'react';
3 |
4 | class DropdownMenuItem extends React.Component {
5 | constructor(props) {
6 | super(props);
7 | }
8 |
9 | _handleOnClick() {
10 | if (this.props.onClick) {
11 | this.props.onClick(this.props.children);
12 | }
13 |
14 | // perform a fake click so it closes the menu
15 | document.body.click();
16 | }
17 |
18 | render() {
19 | return (
20 |
21 | {this.props.children}
22 |
23 | );
24 | }
25 | };
26 |
27 | DropdownMenuItem.propTypes = {
28 | onClick: PropTypes.func
29 | };
30 |
31 | DropdownMenuItem.defaultProps = {
32 | onClick: function () {}
33 | };
34 |
35 | export default DropdownMenuItem;
36 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/DropdownMenu/caret_down.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/frontend/src/components/elements/DropdownMenu/caret_down.png
--------------------------------------------------------------------------------
/frontend/src/components/elements/DropdownMenu/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "DropdownMenu",
3 | "version": "0.0.0",
4 | "private": true,
5 | "main": "./DropdownMenu.js"
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/FlexContainer/FlexContainer.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import styles from "./FlexContainer.scss";
3 |
4 | export default class FlexContainer extends React.Component {
5 | constructor(props) {
6 | super(props);
7 | }
8 |
9 | render() {
10 | return (
11 |
12 | {this.props.children}
13 |
14 | )
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/FlexContainer/FlexContainer.scss:
--------------------------------------------------------------------------------
1 | @import '../../../css/colors';
2 |
3 | .FlexContainer {
4 | display: flex;
5 | flex-wrap: wrap;
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/FlexContainer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "FlexContainer",
3 | "private": true,
4 | "version": "0.0.0",
5 | "main": "./FlexContainer.js"
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/Footer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Footer",
3 | "version": "0.0.0",
4 | "private": true,
5 | "main": "./Footer.js"
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/Form/Form.js:
--------------------------------------------------------------------------------
1 | import styles from './Form.scss';
2 | import React, { PropTypes } from 'react';
3 | import cx from 'classnames';
4 |
5 | class Form extends React.Component {
6 | constructor(props) {
7 | super(props);
8 | }
9 |
10 | render() {
11 | return (
12 |
15 | );
16 | }
17 | };
18 |
19 | Form.propTypes = {
20 |
21 | };
22 |
23 | Form.defaultProps = {
24 |
25 | };
26 |
27 | export default Form;
28 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/Form/Form.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/frontend/src/components/elements/Form/Form.scss
--------------------------------------------------------------------------------
/frontend/src/components/elements/Form/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Form",
3 | "main": "./Form.js",
4 | "private": true,
5 | "version": "0.0.0"
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/HeaderSmall/HeaderSmall.scss:
--------------------------------------------------------------------------------
1 | @import '../../../css/colors';
2 |
3 | .HeaderSmall {
4 | background: $color-primary;
5 | color: #fff;
6 | }
7 |
8 | .container {
9 | margin: 0 auto;
10 | padding: 20px 40px;
11 | }
12 |
13 | .Navigation {
14 | float: right;
15 | margin-top: 10px;
16 | }
17 |
18 | .Navigation a {
19 | color: #fff;
20 | margin-left: 20px;
21 | font-size: 16px;
22 | font-weight: bold;
23 | letter-spacing: 1px;
24 | text-decoration: none;
25 | }
26 |
27 | .Logo {
28 | float: left;
29 | height: auto;
30 | }
31 |
32 | .clear {
33 | clear: both;
34 | }
35 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/HeaderSmall/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "HeaderSmall",
3 | "version": "0.0.0",
4 | "private": true,
5 | "main": "./HeaderSmall.js"
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/Image/Image.js:
--------------------------------------------------------------------------------
1 | import styles from './Image.scss';
2 | import React, { PropTypes } from 'react';
3 |
4 | class Image extends React.Component {
5 | constructor(props) {
6 | super(props);
7 | }
8 |
9 | render() {
10 | return (
11 |
14 | )
15 | }
16 | }
17 |
18 | Image.defaultProps = {
19 | src: "",
20 | defaultSrc: ""
21 | };
22 |
23 | Image.propTypes = {
24 | src: PropTypes.string,
25 | defaultSrc: PropTypes.string
26 | };
27 |
28 | export default Image;
29 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/Image/Image.scss:
--------------------------------------------------------------------------------
1 | .main {
2 | height: 40px;
3 | width: 40px;
4 | }
5 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/Image/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Image",
3 | "version": "0.0.0",
4 | "main": "./Image.js",
5 | "private": true
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/InlineContainer/InlineContainer.js:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react';
2 | import './InlineContainer.scss';
3 |
4 | export default React.createClass({
5 | propTypes: {
6 | },
7 |
8 | getDefaultProps() {
9 | return {
10 | }
11 | },
12 |
13 | render() {
14 | return {this.props.children}
;
15 | }
16 | });
17 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/InlineContainer/InlineContainer.scss:
--------------------------------------------------------------------------------
1 | @import '../../../css/colors';
2 |
3 | .Inline-Container > * {
4 | display: inline-block;
5 | }
6 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/InlineContainer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "InlineContainer",
3 | "version": "0.0.0",
4 | "private": true,
5 | "main": "./InlineContainer.js"
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/Input/Input.scss:
--------------------------------------------------------------------------------
1 | @import '../../../css/colors';
2 |
3 | .Input label {
4 | display: block;
5 | font-size: 14px;
6 | font-weight: normal;
7 | letter-spacing: 1px;
8 | }
9 |
10 | .Input input {
11 | margin: 0 auto;
12 | padding: 7px 10px;
13 | width: 100%;
14 | margin: 2px 0 15px 0;
15 | border: 1px solid $colorBorder;
16 | }
17 |
18 | .validation-error {
19 | border: 1px solid red;
20 | color: red;
21 | }
22 |
23 | .validation-errors > li{
24 | font-style: italic;
25 | color: red;
26 | }
27 |
28 | .Input-Inline {
29 | display: inline-block;
30 | }
31 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/Input/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Input",
3 | "version": "0.0.0",
4 | "private": true,
5 | "main": "./Input.js"
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/List/List.js:
--------------------------------------------------------------------------------
1 | import styles from './List.scss';
2 |
3 | import React, { PropTypes } from 'react';
4 |
5 | class List extends React.Component {
6 | render() {
7 | return (
8 |
9 | {this.props.children}
10 |
11 | );
12 | }
13 | };
14 |
15 | export default List;
16 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/List/List.scss:
--------------------------------------------------------------------------------
1 | @import '../../../css/colors';
2 |
3 | .List {
4 | list-style: none;
5 | padding: 0;
6 | }
7 |
8 | .List li {
9 | border-bottom: none;
10 | position: relative;
11 | display: flex;
12 | align-items: stretch;
13 | background-color: $colorContainer;
14 | margin: 5px 0;
15 | border: 1px solid $colorBorder;
16 | border-radius: 5px;
17 | }
18 |
19 | .List li > span {
20 | padding: 7px 10px;
21 | align-self: center;
22 | }
23 |
24 | .List Button:first-child {
25 | color: $color-white-shade-darker-5;
26 | background-color: $colorContainer;
27 | border: none;
28 | }
29 |
30 | .List Button:last-child {
31 | margin-left: auto;
32 | }
33 |
34 | .List Button {
35 | text-align: center;
36 | width: 38px;
37 | }
38 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/List/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "List",
3 | "version": "0.0.0",
4 | "private": true,
5 | "main": "./List"
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/ListItem/Constants.js:
--------------------------------------------------------------------------------
1 | export default {
2 | LIST_ITEM: 'list_item'
3 | };
4 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/ListItem/ListItem.js:
--------------------------------------------------------------------------------
1 | import styles from './ListItem.scss';
2 | import fa from 'font-awesome/css/font-awesome.css';
3 |
4 | import React, { PropTypes } from 'react';
5 | import Button from '../Button';
6 | import { ItemTypes } from './Constants';
7 | import cx from 'classnames';
8 |
9 | const style = {
10 |
11 | };
12 |
13 | const Types = {
14 | LIST_ITEM: 'list_item'
15 | };
16 |
17 | class ListItem extends React.Component {
18 | constructor (props) {
19 | super(props);
20 | }
21 |
22 | handleRemove() {
23 | this.props.onClickRemove(this.props.id);
24 | }
25 |
26 | render() {
27 | const { value, canRemove } = this.props;
28 |
29 | return (
30 |
31 | {value}
32 | {this.props.children}
33 | {canRemove ?
35 | );
36 | }
37 | };
38 |
39 | ListItem.propTypes = {
40 | value: PropTypes.string,
41 | canRemove: PropTypes.bool,
42 | id: PropTypes.number,
43 | onClickRemove: PropTypes.func
44 | };
45 |
46 | ListItem.defaultProps = {
47 | value: '',
48 | canRemove: false,
49 | id: null,
50 | onClickRemove: function () {}
51 | };
52 |
53 | export default ListItem;
54 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/ListItem/ListItem.scss:
--------------------------------------------------------------------------------
1 | @import '../../../css/colors';
2 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/ListItem/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ListItem",
3 | "version": "0.0.0",
4 | "private": true,
5 | "main": "./ListItem"
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/ListItemMove/Constants.js:
--------------------------------------------------------------------------------
1 | export default {
2 | LIST_ITEM: 'list_item'
3 | };
4 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/ListItemMove/ListItemMove.scss:
--------------------------------------------------------------------------------
1 | @import '../../../css/colors';
2 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/ListItemMove/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ListItemMove",
3 | "version": "0.0.0",
4 | "private": true,
5 | "main": "./ListItemMove"
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/Logo/Logo.js:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react';
2 | import cx from 'classnames';
3 | import styles from './Logo.scss';
4 |
5 | class Logo extends React.Component {
6 | render() {
7 | // var classes = cx({
8 | // styles.Logo: true,
9 | // styles['Align-Right']: this.props.align === 'right',
10 | // styles['Align-Left']: this.props.align === 'left',
11 | // });
12 |
13 | return (
14 |
15 |
16 | {this.props.name}
17 |
18 | );
19 | }
20 |
21 | }
22 |
23 | Logo.defaultProps = {
24 | name: "Brewr",
25 | align: ""
26 | };
27 |
28 | Logo.propTypes = {
29 | name: PropTypes.string,
30 | align: PropTypes.string
31 | };
32 |
33 | export default Logo;
34 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/Logo/Logo.scss:
--------------------------------------------------------------------------------
1 | @import '../../../css/colors';
2 |
3 | .Logo {
4 | text-decoration: none;
5 | }
6 |
7 | .img {
8 | }
9 |
10 | .txt {
11 | text-align: center;
12 | vertical-align: middle;
13 | margin-left: 10px;
14 | color: $color-white;
15 | font-size: 32px;
16 | letter-spacing: 1px;
17 | font-weight: bold;
18 | float: right;
19 | }
20 |
21 | .Align-Left {
22 | float: left;
23 | }
24 |
25 | .Align-Right {
26 | float: right;
27 | }
28 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/Logo/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/frontend/src/components/elements/Logo/logo.png
--------------------------------------------------------------------------------
/frontend/src/components/elements/Logo/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Logo",
3 | "version": "0.0.0",
4 | "private": true,
5 | "main": "./Logo.js"
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/MemberList/avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/frontend/src/components/elements/MemberList/avatar.png
--------------------------------------------------------------------------------
/frontend/src/components/elements/Panel/Panel.scss:
--------------------------------------------------------------------------------
1 | @import '../../../css/colors';
2 |
3 | .Panel {
4 | width: auto;
5 | display: block;
6 | padding: 20px 50px;
7 | flex-grow: 3;
8 | }
9 |
10 | .Panel h1 {
11 | font-size: 18px;
12 | letter-spacing: 2px;
13 | }
14 |
15 | .Panel-Half {
16 | min-width: 50%;
17 | }
18 |
19 | .Panel-A-Third {
20 | min-width: 33.3%;
21 | }
22 |
23 | .Panel-Full {
24 | min-width: 100%;
25 | }
26 |
27 | .Panel-HelpIcon {
28 | font-size: 14px;
29 | margin: 0 0 0 5px;
30 | position: absolute;
31 | }
32 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/Panel/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Panel",
3 | "private": true,
4 | "version": "0.0.0",
5 | "main": "./Panel.js"
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/ProjectFileTable/ProjectFileTable.js:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react';
2 | import BaseComponent from '../../BaseComponent';
3 |
4 | export default class ProjectFileTable extends BaseComponent {
5 |
6 | //TODO: make project revision table component
7 |
8 | constructor() {
9 | super();
10 | }
11 |
12 | render() {
13 |
14 | const { files } = this.props;
15 |
16 | return (
17 |
18 |
19 |
20 | { files.map(r => {
21 | /*return (
22 |
23 | {r.revision_number} |
24 | {r.created_at} |
25 |
26 | );*/
27 | })}
28 |
29 |
30 |
31 | )
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/ProjectRevisionTable/ProjectRevisionTable.js:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react';
2 | import BaseComponent from '../../BaseComponent';
3 |
4 | export default class ProjectRevisionTable extends BaseComponent {
5 |
6 | //TODO: make project revision table component
7 |
8 | constructor() {
9 | super();
10 | }
11 |
12 | render() {
13 |
14 | const { revisions } = this.props;
15 |
16 | return (
17 |
18 |
19 | { revisions.map(r => {
20 | return (
21 |
22 | {r.revision_number} |
23 | {r.created_at} |
24 | |
25 |
26 | );
27 | })}
28 |
29 |
30 | )
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/SideMenu/SideMenu.js:
--------------------------------------------------------------------------------
1 | import styles from './SideMenu.scss';
2 | import fa from 'font-awesome/css/font-awesome.css';
3 |
4 | import React, { PropTypes } from 'react';
5 | import { Link } from 'react-router';
6 | import cx from 'classnames';
7 | import SideMenuContainer from './SideMenuContainer';
8 | import SideMenuItem from './SideMenuItem';
9 |
10 | class SideMenu extends React.Component {
11 | constructor(props) {
12 | super(props);
13 | }
14 |
15 | render() {
16 | const { title } = this.props;
17 |
18 | return (
19 |
20 | {
21 | title ?
22 |
23 | {title}
24 |
25 | : undefined
26 | }
27 |
28 |
29 |
30 | );
31 | }
32 | };
33 |
34 | SideMenu.propTypes = {
35 | title: PropTypes.string
36 | };
37 |
38 | SideMenu.defaultProps = {
39 | title: ""
40 | };
41 |
42 | SideMenu.SideMenuContainer = SideMenuContainer;
43 | SideMenu.SideMenuItem = SideMenuItem;
44 |
45 | export default SideMenu;
46 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/SideMenu/SideMenuItem.js:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react';
2 | import { Link } from 'react-router';
3 | import cx from 'classnames';
4 |
5 | class SideMenuItem extends React.Component {
6 | constructor(props) {
7 | super(props);
8 | }
9 |
10 | render() {
11 | const { link, isStickBottom } = this.props;
12 | var className = cx({
13 | 'SideMenuItem': true,
14 | 'SideMenuItem-Active': window.location && window.location.hash.indexOf(link) !== -1,
15 | 'SideMenuItem-StickBottom': isStickBottom
16 | });
17 |
18 | return (
19 |
20 | {
21 | link ?
22 | {this.props.children}
23 | : this.props.children
24 | }
25 |
26 | );
27 | }
28 | };
29 |
30 | SideMenuItem.propTypes = {
31 | link: PropTypes.string,
32 | isStickBottom: PropTypes.bool
33 | };
34 |
35 | SideMenuItem.defaultProps = {
36 | link: null,
37 | isStickBottom: false
38 | };
39 |
40 | export default SideMenuItem;
41 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/SideMenu/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "SideMenu",
3 | "version": "0.0.0",
4 | "private": true,
5 | "main": "./SideMenu.js"
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/TabContainer/TabContainer.scss:
--------------------------------------------------------------------------------
1 | @import '../../../css/colors';
2 |
3 | .TabContainer {
4 |
5 | }
6 |
7 | .TabContainer-Tabs {
8 | list-style: none;
9 | margin: 0;
10 | padding: 0;
11 | border-bottom: 1px solid #ddd;
12 | margin-bottom: 15px;
13 | }
14 |
15 | .TabContainer-Tab-Selected {
16 | border: 1px solid #ddd;
17 | border-bottom-color: transparent !important;
18 | }
19 |
20 | .TabContainer-Tab-Selected a {
21 | color: $color-text-selected !important;
22 | }
23 |
24 | .TabContainer-Tabs li {
25 | display: inline-block;
26 | padding: 5px 10px;
27 |
28 | margin-bottom: -1px; /* Hack to remove the border */
29 | }
30 |
31 | .TabContainer-Tabs li a {
32 | letter-spacing: 1px;
33 | color: $color-text;
34 | text-decoration: none;
35 | }
36 |
37 | .TabContainer-Tabs li:hover {
38 | color: $color-text-hover;
39 | cursor: pointer;
40 | }
41 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/TabContainer/TabItem.js:
--------------------------------------------------------------------------------
1 | import "./TabContainer.scss";
2 | import React, { PropTypes } from 'react';
3 |
4 | class TabItem extends React.Component {
5 | constructor(props) {
6 | super(props);
7 | }
8 |
9 | render() {
10 | return (
11 |
12 | {this.props.children}
13 |
14 | )
15 | }
16 | };
17 |
18 | TabItem.propTypes = {
19 | title: PropTypes.string
20 | };
21 |
22 | TabItem.defaultProps = {
23 | title: ""
24 | };
25 |
26 | export default TabItem;
27 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/TabContainer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "TabContainer",
3 | "version": "0.0.0",
4 | "private": true,
5 | "main": "./TabContainer.js"
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/Table/Table.js:
--------------------------------------------------------------------------------
1 | import styles from './Table.scss';
2 | import React, { PropTypes } from 'react';
3 | import cx from 'classnames';
4 |
5 | class Table extends React.Component {
6 | constructor(props) {
7 | super(props);
8 | }
9 |
10 | render() {
11 | return (
12 |
13 | {this.props.children}
14 |
15 | );
16 | }
17 | }
18 |
19 | Table.defaultProps = {
20 | };
21 |
22 | Table.propTypes = {
23 | };
24 |
25 | export default Table;
26 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/Table/Table.scss:
--------------------------------------------------------------------------------
1 | @import '../../../css/dimensions';
2 | @import '../../../css/colors';
3 |
4 | .Table {
5 | width: 100%;
6 | height: 100%;
7 | border-radius: 3px;
8 | border: 1px solid rgba(0, 0, 0, 0.05);
9 | font-size: $dimensionTextSmaller;
10 | }
11 |
12 | .Table > thead {
13 | background-color: rgba(0, 0, 0, 0.05);
14 | text-weight: bold;
15 | }
16 |
17 | .Table tr {
18 | border: 1px solid rgba(0, 0, 0, 0.05);
19 | }
20 |
21 | .Table > thead td {
22 | padding: 10px 8px;
23 | }
24 |
25 | .Table > tbody td {
26 | padding: 10px 8px;
27 | }
28 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/Table/TableButtons.js:
--------------------------------------------------------------------------------
1 | import styles from './TableButtons.scss';
2 | import React, { PropTypes } from 'react';
3 | import cx from 'classnames';
4 |
5 | class TableButtons extends React.Component {
6 | constructor(props) {
7 | super(props);
8 | }
9 |
10 | render() {
11 | return (
12 |
13 | {this.props.children}
14 |
15 | );
16 | }
17 | };
18 |
19 | TableButtons.propTypes = {
20 |
21 | };
22 |
23 | TableButtons.defaultProps = {
24 |
25 | };
26 |
27 | export default TableButtons;
28 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/Table/TableButtons.scss:
--------------------------------------------------------------------------------
1 | .TableButtons {
2 | padding: 10px 0;
3 | }
4 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/Table/index.js:
--------------------------------------------------------------------------------
1 | import Table from './Table';
2 | import TableButtons from './TableButtons';
3 |
4 | export default {
5 | Table: Table,
6 | TableButtons: TableButtons
7 | }
8 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/Table/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Table",
3 | "version": "0.0.0",
4 | "main": "./index.js",
5 | "private": true
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/TextBox/TextBox.js:
--------------------------------------------------------------------------------
1 | import styles from './TextBox.scss';
2 | import React, { PropTypes } from 'react';
3 |
4 | class TextBox extends React.Component {
5 | render () {
6 | return (
7 |
8 | {
9 | this.props.maxLines > 1 ?
10 | :
11 |
12 | }
13 |
14 | );
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/TextBox/TextBox.scss:
--------------------------------------------------------------------------------
1 | @import '../../../css/colors';
2 |
3 | .TextBox { }
4 | .TextBox-input { }
5 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/TextBox/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "TextBox",
3 | "version": "0.0.0",
4 | "private": true,
5 | "main": "./TextBox.js"
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/Tooltip/Tooltip.js:
--------------------------------------------------------------------------------
1 | import styles from './Tooltip.scss';
2 | import React, { PropTypes } from 'react';
3 | import cx from 'classnames';
4 |
5 | class Tooltip extends React.Component {
6 | constructor(props) {
7 | super(props);
8 | }
9 |
10 | render() {
11 |
12 | var className = cx(
13 | styles['Tooltip'],
14 | this.props.placement === 'right' ? styles['Tooltip-Right'] : null,
15 | this.props.placement === 'bottom' ? styles['Tooltip-Bottom'] : null,
16 | this.props.placement === 'left' ? styles['Tooltip-Left'] : null,
17 | this.props.placement === 'top' ? styles['Tooltip-Top'] : null
18 | );
19 |
20 | return (
21 |
22 | {this.props.children}
23 |
24 | );
25 | }
26 | };
27 |
28 | Tooltip.propTypes = {
29 | text: PropTypes.string,
30 | placement: PropTypes.string
31 | };
32 |
33 | Tooltip.defaultProps = {
34 | text: "",
35 | placement: "right"
36 | };
37 |
38 | export default Tooltip;
39 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/Tooltip/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Tooltip",
3 | "version": "0.0.0",
4 | "private": true,
5 | "main": "./Tooltip.js"
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/Wizard/Wizard.js:
--------------------------------------------------------------------------------
1 | import styles from './Wizard.scss';
2 | import React, { PropTypes } from 'react';
3 | import WizardItem from './WizardItem';
4 |
5 | class Wizard extends React.Component {
6 | constructor(props) {
7 | super(props);
8 | }
9 |
10 | render() {
11 | const { steps, currentStepIdx } = this.props;
12 |
13 | var wizardItems = [];
14 | steps.forEach((i, idx) => {
15 | let key = "wizard_item_" + idx;
16 |
17 | if ((idx + 1) == currentStepIdx) {
18 | wizardItems.push();
19 | } else {
20 | wizardItems.push();
21 | }
22 | });
23 |
24 | return (
25 |
31 |
32 | );
33 | }
34 | };
35 |
36 | Wizard.propTypes = {
37 | currentStepIdx: PropTypes.number,
38 | steps: PropTypes.array
39 | };
40 |
41 | Wizard.defaultProps = {
42 | currentStepIdx: 1,
43 | steps: []
44 | };
45 |
46 | export default Wizard;
47 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/Wizard/Wizard.scss:
--------------------------------------------------------------------------------
1 | @import '../../../css/colors';
2 |
3 | .Wizard {
4 | width: 100%;
5 | padding-top: 30px;
6 | }
7 |
8 | .Wizard-Items {
9 | height: 50px;
10 | list-style: none;
11 | display: flex;
12 | justify-content: space-around;
13 | margin: 0;
14 | padding: 0;
15 | color: lighten($colorTextLight, 10%);
16 | text-transform: uppercase;
17 | text-align: center;
18 | margin-top: 10px;
19 | font-weight: normal;
20 | }
21 |
22 | .WizardItem {
23 | position: relative;
24 | padding: 0 10px;
25 | font-size: 12px;
26 | }
27 |
28 | .WizardItem-Selected {
29 | position: relative;
30 | font-weight: 700;
31 | }
32 |
33 | .WizardItem-Selected:before {
34 | background-color: lighten($colorTextDark, 10%) !important;
35 | }
36 |
37 | .WizardItem:before {
38 | position: absolute;
39 | top: -18px;
40 | width: 14px;
41 | height: 14px;
42 | left: calc(50% - 7px);
43 | border-radius: 100%;
44 | background-color: lighten($colorTextLight, 10%);
45 | content: '';
46 | transition: .25s;
47 | }
48 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/Wizard/WizardItem.js:
--------------------------------------------------------------------------------
1 | import styles from './Wizard.scss';
2 |
3 | import React, { PropTypes } from 'react';
4 | import cx from 'classnames';
5 |
6 | class WizardItem extends React.Component {
7 | constructor(props) {
8 | super(props);
9 | }
10 |
11 | render() {
12 | var className = cx(
13 | styles['WizardItem'],
14 | this.props.isSelected ? styles['WizardItem-Selected'] : null
15 | );
16 |
17 | return (
18 |
19 | {this.props.value}
20 |
21 | );
22 | }
23 | };
24 |
25 | WizardItem.propTypes = {
26 | value: PropTypes.string,
27 | isSelected: PropTypes.bool
28 | };
29 |
30 | WizardItem.defaultProps = {
31 | value: "",
32 | isSelected: false
33 | };
34 |
35 | export default WizardItem;
36 |
--------------------------------------------------------------------------------
/frontend/src/components/elements/Wizard/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Wizard",
3 | "private": true,
4 | "version": "0.0.0",
5 | "main": "./Wizard.js"
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/layouts/DashboardLayout/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "DashboardLayout",
3 | "version": "0.0.0",
4 | "private": true,
5 | "main": "./DashboardLayout.js"
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/layouts/MainLayout/MainLayout.scss:
--------------------------------------------------------------------------------
1 | @import '../../../css/colors';
2 |
3 | .MainLayout {
4 | display: flex;
5 | min-height: 100vh;
6 | flex-direction: column;
7 | }
8 |
9 | .Content {
10 | flex: 1;
11 | padding: 40px;
12 | margin: 0 auto;
13 |
14 | display:flex;
15 | justify-content: center;
16 | width:100%;
17 | height: 100%;
18 | }
19 |
--------------------------------------------------------------------------------
/frontend/src/components/layouts/MainLayout/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "MainLayout",
3 | "version": "0.0.0",
4 | "private": true,
5 | "main": "./MainLayout.js"
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/pages/Builder/Builder.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/frontend/src/components/pages/Builder/Builder.scss
--------------------------------------------------------------------------------
/frontend/src/components/pages/Builder/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Builder",
3 | "version": "0.0.0",
4 | "private": true,
5 | "main": "./Builder.js"
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/pages/Dashboard/Dashboard.scss:
--------------------------------------------------------------------------------
1 | @import '../../../css/colors';
2 |
--------------------------------------------------------------------------------
/frontend/src/components/pages/Dashboard/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Dashboard",
3 | "version": "0.0.0",
4 | "private": true,
5 | "main": "./Dashboard.js"
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/pages/Home/after.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/frontend/src/components/pages/Home/after.png
--------------------------------------------------------------------------------
/frontend/src/components/pages/Home/before.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/frontend/src/components/pages/Home/before.png
--------------------------------------------------------------------------------
/frontend/src/components/pages/Home/header.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/frontend/src/components/pages/Home/header.jpg
--------------------------------------------------------------------------------
/frontend/src/components/pages/Home/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/frontend/src/components/pages/Home/logo.png
--------------------------------------------------------------------------------
/frontend/src/components/pages/Home/option-dropdown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/frontend/src/components/pages/Home/option-dropdown.png
--------------------------------------------------------------------------------
/frontend/src/components/pages/Home/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "HomePage",
3 | "main": "./Home.js",
4 | "private": true,
5 | "version": "0.0.0"
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/pages/Home/screenshot-background.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/frontend/src/components/pages/Home/screenshot-background.jpg
--------------------------------------------------------------------------------
/frontend/src/components/pages/Home/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/frontend/src/components/pages/Home/screenshot.png
--------------------------------------------------------------------------------
/frontend/src/components/pages/Home/screenshot@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/frontend/src/components/pages/Home/screenshot@2x.png
--------------------------------------------------------------------------------
/frontend/src/components/pages/Login/Login.scss:
--------------------------------------------------------------------------------
1 | @import '../../../css/colors';
2 |
3 | .RegisterPage {
4 | width: 30%;
5 | margin: auto 0;
6 | }
7 |
8 | .RegisterPage button {
9 | margin: 0 auto;
10 | display: block;
11 | }
12 |
13 | .RegisterPage form {
14 | width: 100%;
15 | }
16 |
17 | .RegisterPage .Input {
18 | width: 100%;
19 | }
20 |
21 | .RegisterPage .Input input {
22 | width: 100%;
23 | }
24 |
--------------------------------------------------------------------------------
/frontend/src/components/pages/Login/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "LoginPage",
3 | "version": "0.0.0",
4 | "private": true,
5 | "main": "./Login.js"
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/pages/Logout/Logout.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import AuthActions from '../../../actions/AuthActions';
3 | import AuthStore from '../../../stores/AuthStore';
4 |
5 | class LogoutPage extends React.Component {
6 | constructor(props) {
7 | super(props);
8 |
9 | this.state = this._getAuthState();
10 |
11 | // Logout, once we are logged out, the _onChange will be called and we can redirect
12 | AuthActions.logout(AuthStore.token);
13 | }
14 |
15 | componentDidMount() {
16 | this.changeListener = this._onChange.bind(this);
17 | AuthStore.addChangeListener(this.changeListener);
18 | }
19 |
20 | componentWillUnmount() {
21 | AuthStore.removeChangeListener(this.changeListener);
22 | }
23 |
24 | _getAuthState() {
25 | return {
26 | isLoggedIn: AuthStore.isLoggedIn
27 | }
28 | }
29 |
30 | _onChange() {
31 | var self = this;
32 |
33 | // Change state, on callback redirect
34 | var newState = this._getAuthState();
35 | this.setState(newState, function () {
36 | // If logged in, redirect
37 | if (!newState.isLoggedIn) {
38 | self.props.history.replaceState(null, '/');
39 | }
40 | });
41 | }
42 |
43 | render() {
44 | return ();
45 | }
46 | }
47 |
48 | export default LogoutPage;
49 |
--------------------------------------------------------------------------------
/frontend/src/components/pages/Logout/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Logout",
3 | "version": "0.0.0",
4 | "private": true,
5 | "main": "./Logout.js"
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/pages/Members/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "MembersPage",
3 | "version": "0.0.0",
4 | "private": true,
5 | "main": "./Members.js"
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/pages/NotFound/NotFound.js:
--------------------------------------------------------------------------------
1 | import MainLayout from '../../layouts/MainLayout';
2 | import React from 'react';
3 |
4 | export default class NotFound extends React.Component {
5 | constructor(props) {
6 | super(props);
7 | }
8 |
9 | render() {
10 | return (
11 |
12 | Not Found
13 |
14 | );
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/frontend/src/components/pages/NotFound/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "NotFound",
3 | "version": "0.0.0",
4 | "private": true,
5 | "main": "./NotFound.js"
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/pages/Project/Project.scss:
--------------------------------------------------------------------------------
1 | @import '../../../css/colors';
2 | @import '../../../css/dimensions';
3 |
4 |
5 | .project_sidebar {
6 | border-left: 1px solid $colorBorder;
7 | height:100%;
8 | padding:20px;
9 |
10 | & > h2 {
11 | font-size: 14pt;
12 | color: $color-primary-shade-lighter-4;
13 | margin:10px 0 0 0;
14 | }
15 | }
16 |
17 | .ContainerBottom {
18 | width: 100%;
19 | position: absolute;
20 | bottom: 0;
21 | left: 0;
22 | }
23 |
24 | .ContainerBottom h1 {
25 | padding: 0 10px;
26 | }
27 |
28 | .ContainerLeft {
29 | position: relative;
30 | height: 100%;
31 | }
32 |
33 | .ContainerTop {
34 | padding: 20px;
35 | }
36 |
37 | .Clear {
38 | float: none !important;
39 | clear: both;
40 | }
41 |
--------------------------------------------------------------------------------
/frontend/src/components/pages/Project/avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/frontend/src/components/pages/Project/avatar.png
--------------------------------------------------------------------------------
/frontend/src/components/pages/Project/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ProjectPage",
3 | "version": "0.0.0",
4 | "private": true,
5 | "main": "./Project.js"
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/pages/ProjectEditImage/ProjectEditImage.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/frontend/src/components/pages/ProjectEditImage/ProjectEditImage.scss
--------------------------------------------------------------------------------
/frontend/src/components/pages/ProjectEditImage/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ProjectEditImage",
3 | "version": "0.0.0",
4 | "private": true,
5 | "main": "./ProjectEditImage.js"
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/pages/Register/Register.scss:
--------------------------------------------------------------------------------
1 | @import '../../../css/colors';
2 |
3 | .LoginPage {
4 | width: 30%;
5 | margin: auto 0;
6 | }
7 |
8 | .LoginPage button {
9 | margin: 0 auto;
10 | display: block;
11 | }
12 |
13 | .LoginPage form {
14 | width: 100%;
15 | }
16 |
17 | .LoginPage .Input {
18 | width: 100%;
19 | }
20 |
21 | .LoginPage .Input input {
22 | width: 100%;
23 | }
24 |
--------------------------------------------------------------------------------
/frontend/src/components/pages/Register/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "RegisterPage",
3 | "version": "0.0.0",
4 | "private": true,
5 | "main": "./Register.js"
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/constants/DockerHubConstants.js:
--------------------------------------------------------------------------------
1 | export const API_URL = 'https://registry.hub.docker.com/v1';
2 | export const API_URL_SEARCH = API_URL + '/search';
3 |
--------------------------------------------------------------------------------
/frontend/src/constants/LoginConstants.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by Maxim on 15/08/2015.
3 | */
4 | var BASE_URL = 'http://localhost:1337';
5 |
6 | export default {
7 | LOGIN_URL: BASE_URL + '/auth/signin',
8 | SIGNUP_URL: BASE_URL + '/auth/signup'
9 | }
10 |
--------------------------------------------------------------------------------
/frontend/src/constants/ProjectConstants.js:
--------------------------------------------------------------------------------
1 | var BASE_URL = 'http://localhost:1337';
2 |
3 | export default {
4 | PROJECT_CREATE: null,
5 | PROJECT_DESTROY: null,
6 | PROJECT_UPDATE: null,
7 | PROJECT_ASSIGN_MEMBER: null,
8 | PROJECT_REMOVE_MEMBER: null
9 |
10 | };
11 |
--------------------------------------------------------------------------------
/frontend/src/constants/RegisterConstants.js:
--------------------------------------------------------------------------------
1 | var BASE_URL = 'http://localhost:1337';
2 |
3 | export default {
4 | REGISTER_URL: BASE_URL + '/auth/signup',
5 | REGISTER_USER: "REGISTER_USER"
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/css/dimensions.scss:
--------------------------------------------------------------------------------
1 | $dimensionTextTitle: 22px;
2 | $dimensionTextSubtitle: 18px;
3 | $dimensionTextNormal: 14px;
4 | $dimensionTextSmaller: 12px;
5 |
6 |
7 | @mixin clearfix() {
8 | &:before,
9 | &:after {
10 | content: " "; /* 1 */
11 | display: table; /* 2 */
12 | }
13 |
14 | &:after {
15 | clear: both;
16 | }
17 |
18 | /**
19 | * For IE 6/7 only
20 | * Include this rule to trigger hasLayout and contain floats.
21 | */
22 | & {
23 | *zoom: 1;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/frontend/src/dispatchers/AppDispatcher.js:
--------------------------------------------------------------------------------
1 | import { Dispatcher } from 'flux';
2 |
3 | var objectAssign = require('react/lib/Object.assign');
4 |
5 | var AppDispatcher = objectAssign(new Dispatcher(), {
6 | /**
7 | * @param {object} action The details of the action, including the action's
8 | * type and additional data coming from the server.
9 | */
10 | handleServerAction: function (action) {
11 | var payload = {
12 | source: 'SERVER_ACTION',
13 | action: action
14 | };
15 |
16 | this.dispatch(payload);
17 | },
18 |
19 | /**
20 | * @param {object} action The details of the action, including the action's
21 | * type and additional data coming from the view.
22 | */
23 | handleViewAction: function (action) {
24 | var payload = {
25 | source: 'VIEW_ACTION',
26 | action: action
27 | };
28 |
29 | this.dispatch(payload);
30 | }
31 | });
32 |
33 | export default AppDispatcher;
34 |
--------------------------------------------------------------------------------
/frontend/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import routes from './routes';
4 |
5 | // Install the routes
6 | ReactDOM.render(routes, document.getElementById('root'));
7 |
--------------------------------------------------------------------------------
/frontend/src/index.tpl.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | react-kickstart
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/frontend/src/services/DockerHubService.js:
--------------------------------------------------------------------------------
1 | import * as DockerHubConstants from '../constants/DockerHubConstants';
2 | import DockerHubActions from '../actions/DockerHubActions';
3 | import request from 'reqwest';
4 | import when from 'when';
5 |
6 | // https://registry.hub.docker.com/v1/search?q=ubu&page=1
7 |
8 | class DockerHubService {
9 | fetchRepositories(searchTerm, page=1) {
10 | return when(request({
11 | url: DockerHubConstants.API_URL_SEARCH,
12 | method: 'GET',
13 | crossOrigin: true,
14 | type: 'json',
15 | data: {
16 | q: searchTerm,
17 | page: page
18 | }
19 | }))
20 | .then(function(response) {
21 | console.log(response);
22 |
23 | DockerHubActions.setRepositories(response.results);
24 |
25 | return true;
26 | });
27 | }
28 | }
29 |
30 | export default new DockerHubService();
31 |
--------------------------------------------------------------------------------
/frontend/src/services/ProjectService.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by Maxim on 08/09/2015.
3 | */
4 | //import projectStore from '../stores/ProjectStore';
5 | import request from 'superagent';
6 |
7 | class ProjectService {
8 |
9 | fetchProjects(callback) {
10 | request
11 | .get('http://localhost:1337/organisations/1/projects')
12 | .set('Authorization', 'JWT ' + localStorage.getItem('jwt'))
13 | .accept('json')
14 | .end(function(err, res){
15 | console.log(err);
16 | var result = JSON.parse(res.text);
17 | callback(result);
18 | })
19 | }
20 |
21 | }
22 |
23 | export default new ProjectService();
24 |
--------------------------------------------------------------------------------
/frontend/src/services/RouterContainer.js:
--------------------------------------------------------------------------------
1 | var _router = null;
2 | export default {
3 | set: (router) => _router = router,
4 | get: () => _router
5 | }
6 |
--------------------------------------------------------------------------------
/frontend/src/services/TeamService.js:
--------------------------------------------------------------------------------
1 | import request from 'superagent';
2 |
3 |
4 | class TeamService {
5 | fetchTeams() {
6 | request
7 | .get('http://localhost:1337/organisations/1/projects')
8 | .set('Authorization', 'JWT ' + localStorage.getItem('jwt'))
9 | .accept('json')
10 | .end(function(err, res){
11 | console.log(err);
12 | var result = JSON.parse(res.text);
13 | callback(result);
14 | })
15 | }
16 | }
17 |
18 | export default new TeamService();
19 |
--------------------------------------------------------------------------------
/frontend/src/stores/BaseStore.js:
--------------------------------------------------------------------------------
1 | import {EventEmitter} from 'events';
2 | import AppDispatcher from '../dispatchers/AppDispatcher';
3 | var CHANGE_EVENT = "CHANGE_EVENT";
4 |
5 | export default class BaseStore extends EventEmitter {
6 | constructor() {
7 | super();
8 | }
9 |
10 | addChangeListener(callback) {
11 | this.on(CHANGE_EVENT, callback);
12 | }
13 |
14 | removeChangeListener(callback) {
15 | this.removeListener(CHANGE_EVENT, callback);
16 | }
17 |
18 | // triggers change listener above, firing controller-view callback
19 | emitChange() {
20 | this.emit(CHANGE_EVENT);
21 | }
22 |
23 | subscribe(actionSubscribe) {
24 | this._dispatchToken = AppDispatcher.register(actionSubscribe());
25 | }
26 |
27 | get dispatchToken() {
28 | return this._dispatchToken;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/frontend/src/stores/DashboardStore.js:
--------------------------------------------------------------------------------
1 | import BaseStore from './BaseStore';
2 | import * as actionTypes from '../constants/ActionTypes';
3 |
4 | class DashboardStore extends BaseStore {
5 | constructor() {
6 | super();
7 |
8 | this.subscribe(() => this._registerToActions.bind(this));
9 | }
10 |
11 | _registerToActions(source) {
12 | if (!source.action) {
13 | return;
14 | }
15 |
16 | switch (source.action.type) {
17 |
18 | }
19 | }
20 | }
21 |
22 | export default new DashboardStore();
23 |
--------------------------------------------------------------------------------
/frontend/src/stores/DockerHubStore.js:
--------------------------------------------------------------------------------
1 | import BaseStore from './BaseStore';
2 | import * as types from '../constants/ActionTypes';
3 |
4 | class DockerHubStore extends BaseStore {
5 | constructor () {
6 | super();
7 |
8 | this._repositories = [];
9 | }
10 |
11 | _registerToActions(action) {
12 | case types.DOCKER_HUB_FETCH_REPOSITORIES:
13 | this._repositories = action.repositories;
14 | default:
15 | break;
16 | }
17 | }
18 |
19 | export default new DockerHubStore();
20 |
--------------------------------------------------------------------------------
/frontend/src/stores/ProjectEditImageStore.js:
--------------------------------------------------------------------------------
1 | import BaseStore from './BaseStore';
2 | import * as actionTypes from '../constants/ActionTypes';
3 |
4 |
5 | class ProjectEditImageStore extends BaseStore {
6 | constructor() {
7 | super();
8 |
9 | this.subscribe(() => this._registerToActions.bind(this));
10 | this._image = { project: {}, projectEnvInfo: {}, projectFiles: [] };
11 | }
12 |
13 | // We get a source back (VIEW or SERVER) with there the action in
14 | _registerToActions (source) {
15 | if (!source.action) {
16 | return;
17 | }
18 |
19 | switch(source.action.type) {
20 | case actionTypes.REQUEST_PROJECT:
21 | break;
22 | case actionTypes.RESPONSE_PROJECT_IMAGE:
23 | this._image.project = source.action.response.project;
24 | this._image.projectEnvInfo = source.action.response.projectEnvInfo;
25 | this._image.projectFiles = source.action.response.projectFiles;
26 | this.emitChange();
27 | break;
28 | default:
29 | break;
30 | }
31 | }
32 |
33 | get image() {
34 | return this._image;
35 | }
36 | }
37 |
38 | export default new ProjectEditImageStore();
39 |
--------------------------------------------------------------------------------
/frontend/src/utils/OrganisationAPIUtils.js:
--------------------------------------------------------------------------------
1 | import * as OrganisationServerActions from '../actions/OrganisationServerActions';
2 | import request from 'superagent';
3 |
4 | export function getOrganisationMembers(token, organisationUUID) {
5 | request
6 | .get('http://localhost:8000/organisation/' + organisationUUID + '/members')
7 | .set('Authorization', 'Bearer ' + token)
8 | .end(function (err, res) {
9 | if (err) {
10 | return OrganisationServerActions.receiveGetOrganisationMembersErrorResponse(err);
11 | }
12 |
13 | return OrganisationServerActions.receiveGetOrganisationMembersResponse(res.body);
14 | });
15 | }
16 |
17 | export function makeManager(token, organisationUUID, memberId) {
18 | request
19 | .post('http://localhost:8000/organisation/' + organisationUUID + '/member/' + memberId + '/manager')
20 | .set('Authorization', 'Bearer ' + token)
21 | .end(function (err, res) {
22 | if (err) {
23 | return OrganisationServerActions.receiveOrganisationMakeManagerErrorResponse(err);
24 | }
25 |
26 | return OrganisationServerActions.receiveOrganisationMakeManagerResponse(res.body);
27 | });
28 | }
29 |
--------------------------------------------------------------------------------
/frontend/src/validators/constraints/ConfirmConstraint.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by Maxim on 18/08/2015.
3 | */
4 | import Constraint from './Constraint.js';
5 |
6 |
7 | export default class ConfirmConstraint extends Constraint{
8 |
9 | constructor(confirmValue) {
10 | super();
11 | this.confirmValue = confirmValue;
12 | }
13 |
14 | validate(value) {
15 |
16 | if(value == this.confirmValue) {
17 | this.validateConstraint();
18 | }
19 |
20 | return this.isValid;
21 | }
22 | }
--------------------------------------------------------------------------------
/frontend/src/validators/constraints/Constraint.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by Maxim on 18/08/2015.
3 | */
4 | export default class Constraint {
5 |
6 | constructor() {
7 | if (this.constructor === Constraint) {
8 | throw new TypeError("Cannot construct Abstract instances directly");
9 | }
10 |
11 | // for forcing overriding of method
12 | //if (this.method === undefined) {
13 | // // or maybe test typeof this.method === "function"
14 | // throw new TypeError("Must override method");
15 | //}
16 |
17 | this.isValid = false;
18 | }
19 |
20 | invalidate() {
21 | this.isValid = false;
22 | }
23 |
24 | validateConstraint() {
25 | this.isValid = true;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/frontend/src/validators/constraints/EmailConstraint.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by Maxim on 18/08/2015.
3 | */
4 | import Constraint from './Constraint.js';
5 |
6 |
7 | export default class EmailConstraint extends Constraint{
8 |
9 | validate(value) {
10 |
11 | if(typeof value == "undefined") {
12 | return false;
13 | }
14 |
15 | const regex = /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;
16 |
17 | if(regex.test(value)) {
18 | this.validateConstraint();
19 | }
20 |
21 | return this.isValid;
22 | }
23 | }
--------------------------------------------------------------------------------
/frontend/src/validators/constraints/IsRequiredConstraint.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by Maxim on 18/08/2015.
3 | */
4 | import Constraint from './Constraint.js';
5 |
6 |
7 | export default class IsRequiredConstraint extends Constraint{
8 |
9 | validate(value) {
10 | if(typeof value == "undefined") {
11 | return false;
12 | }
13 |
14 | if(value.length > 0) {
15 | this.validateConstraint();
16 | }
17 |
18 | return this.isValid;
19 | }
20 | }
--------------------------------------------------------------------------------
/frontend/src/validators/constraints/LengthConstraint.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by Maxim on 18/08/2015.
3 | */
4 | import Constraint from './Constraint.js';
5 |
6 |
7 | export default class LengthConstraint extends Constraint {
8 |
9 | constructor(min, max) {
10 | super();
11 | this.min = min;
12 | this.max = max;
13 | }
14 |
15 | validate(value) {
16 |
17 | if(typeof value === "undefined") {
18 | return false;
19 | }
20 |
21 | if(typeof this.max != "undefined" && this.max > 0) {
22 | if(value.length <= this.max) {
23 | this.validateConstraint();
24 | }
25 | }
26 |
27 | if(typeof this.min != "undefined" && typeof this.min == "number") {
28 | if(value.length >= this.min) {
29 | this.validateConstraint();
30 | }
31 | }
32 |
33 | return this.isValid;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/project/.editorconfig:
--------------------------------------------------------------------------------
1 | # editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 |
--------------------------------------------------------------------------------
/project/.sailsrc:
--------------------------------------------------------------------------------
1 | {
2 | "generators": {
3 | "modules": {}
4 | }
5 | }
--------------------------------------------------------------------------------
/project/README.md:
--------------------------------------------------------------------------------
1 | # Back-end
2 | The back-end uses the sails framework
3 |
--------------------------------------------------------------------------------
/project/api/controllers/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/project/api/controllers/.gitkeep
--------------------------------------------------------------------------------
/project/api/controllers/AuthController.js:
--------------------------------------------------------------------------------
1 | /**
2 | * AuthController
3 | * @description handles the authentications
4 | */
5 | var passport = require('passport');
6 |
7 | function _onPassportAuth(req, res, err, user, info) {
8 | if (err) {
9 | console.log(err);
10 | return res.serverError(err);
11 | }
12 |
13 | if (!user) {
14 | return res.unauthorized(null, info && info.code, info && info.message);
15 | }
16 |
17 | return res.ok({
18 | token: AuthService.createToken(user),
19 | user: user
20 | });
21 | }
22 |
23 | module.exports = {
24 | signup: function (req, res) {
25 | User
26 | .create(_.omit(req.allParams(), 'id'))
27 | .then(function (user) {
28 | return {
29 | token: AuthService.createToken(user),
30 | user: user
31 | };
32 | })
33 | .then(res.created)
34 | .catch(res.serverError);
35 | },
36 | signin: function (req, res){
37 | passport.authenticate('local', _onPassportAuth.bind(this, req, res))(req, res);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/project/api/controllers/OrganisationController.js:
--------------------------------------------------------------------------------
1 | /**
2 | * OrganisationController
3 | *
4 | * @description :: Server-side logic for managing organisations
5 | * @help :: See http://sailsjs.org/#!/documentation/concepts/Controllers
6 | */
7 |
8 | module.exports = {
9 |
10 |
11 | };
12 |
13 |
--------------------------------------------------------------------------------
/project/api/controllers/ProjectRevisionController.js:
--------------------------------------------------------------------------------
1 | /**
2 | * ProjectRevisionController
3 | *
4 | * @description :: Server-side logic for managing projectrevisions
5 | * @help :: See http://sailsjs.org/#!/documentation/concepts/Controllers
6 | */
7 |
8 | module.exports = {
9 |
10 | };
11 |
12 |
--------------------------------------------------------------------------------
/project/api/controllers/UserController.js:
--------------------------------------------------------------------------------
1 | /**
2 | * UserController
3 | *
4 | * @description :: Server-side logic for managing users
5 | * @help :: See http://sailsjs.org/#!/documentation/concepts/Controllers
6 | */
7 |
8 | module.exports = {
9 | all: function (req, res) {
10 | User.find({}, function (err, users){
11 | res.json(users);
12 | });
13 | }
14 | };
15 |
--------------------------------------------------------------------------------
/project/api/controllers/UserSessionController.js:
--------------------------------------------------------------------------------
1 | /**
2 | * UserSessionController
3 | *
4 | * @description :: Server-side logic for managing usersessions
5 | * @help :: See http://sailsjs.org/#!/documentation/concepts/Controllers
6 | */
7 |
8 | module.exports = {
9 |
10 | };
11 |
12 |
--------------------------------------------------------------------------------
/project/api/models/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/project/api/models/.gitkeep
--------------------------------------------------------------------------------
/project/api/models/OrganisationUser.js:
--------------------------------------------------------------------------------
1 | /**
2 | * OrganisationUser.js
3 | *
4 | * @description :: Represents the users that belong to an organisation
5 | * @docs :: http://sailsjs.org/#!documentation/models
6 | */
7 |
8 | module.exports = {
9 | tableName: 'organisation_user',
10 | attributes: {
11 | id: {
12 | type: 'integer',
13 | unique: true,
14 | primaryKey: true,
15 | columnName: 'id',
16 | autoIncrement: true
17 | },
18 | addedOn: {
19 | type: 'datetime',
20 | columnName: 'added_on',
21 | defaultsTo: function() { return new Date(); }
22 | },
23 |
24 | //associations
25 | user: {
26 | model: 'user'
27 | },
28 | organisation: {
29 | model: 'organisation'
30 | }
31 | }
32 | };
33 |
--------------------------------------------------------------------------------
/project/api/models/ProjectFile.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Project.js
3 | *
4 | * @description :: Represents a project
5 | * @docs :: http://sailsjs.org/#!documentation/models
6 | */
7 |
8 | module.exports = {
9 | tableName: 'project_file',
10 | attributes: {
11 | id: {
12 | type: 'integer',
13 | unique: true,
14 | primaryKey: true,
15 | columnName: 'id',
16 | autoIncrement: true
17 | },
18 | fileName: 'string',
19 | fileDataUri: 'text',
20 | createdOn: {
21 | type: 'datetime',
22 | columnName: 'created_on',
23 | defaultsTo: function() { return new Date(); }
24 | },
25 |
26 | //assocations
27 | projectRevision: {
28 | model: 'projectRevision'
29 | }
30 | }
31 | };
32 |
--------------------------------------------------------------------------------
/project/api/models/ProjectUser.js:
--------------------------------------------------------------------------------
1 | /**
2 | * ProjectUser.js
3 | *
4 | * @description :: Represents the users assigned to a project
5 | * @docs :: http://sailsjs.org/#!documentation/models
6 | */
7 |
8 | module.exports = {
9 | tableName: 'project_user',
10 | attributes: {
11 | id: {
12 | type: 'integer',
13 | unique: true,
14 | primaryKey: true,
15 | columnName: 'id',
16 | autoIncrement: true
17 | },
18 | addedOn: {
19 | type: 'datetime',
20 | columnName: 'added_on',
21 | defaultsTo: function() { return new Date(); }
22 | },
23 | isManager: {
24 | type: 'boolean',
25 | defaultsTo: 'false',
26 | columnName: 'is_manager'
27 | },
28 |
29 | //associations
30 | user: {
31 | model: 'user'
32 | },
33 | project: {
34 | model: 'project'
35 | }
36 | }
37 | };
38 |
--------------------------------------------------------------------------------
/project/api/models/UserSession.js:
--------------------------------------------------------------------------------
1 | /**
2 | * UserSession.js
3 | *
4 | * @description :: Represents a session of a user
5 | * @docs :: http://sailsjs.org/#!documentation/models
6 | */
7 |
8 | module.exports = {
9 | tableName: 'user_session',
10 | attributes: {
11 | id: {
12 | type: 'integer',
13 | unique: true,
14 | primaryKey: true,
15 | columnName: 'id',
16 | autoIncrement: true
17 | },
18 | createdOn: {
19 | type: 'datetime',
20 | columnName: 'created_on',
21 | defaultsTo: function() { return new Date(); }
22 | },
23 | token: 'string',
24 | userAgent: {
25 | type: 'string',
26 | columnName: 'user_agent'
27 | },
28 | ip: 'string',
29 |
30 | //associations
31 | user: {
32 | model: 'user'
33 | }
34 | }
35 | };
36 |
--------------------------------------------------------------------------------
/project/api/policies/isAuthenticated.js:
--------------------------------------------------------------------------------
1 | var passport = require('passport');
2 |
3 | module.exports = function(req, res, next) {
4 | passport.authenticate('jwt', function(err, user, info) {
5 | if(err) {
6 | return res.serverError(err);
7 | }
8 |
9 | if(!user) {
10 | return res.unauthorized(null, info && info.code, info && info.message);
11 | }
12 |
13 | req.user = user;
14 | next();
15 | })(req, res);
16 | }
17 |
--------------------------------------------------------------------------------
/project/api/responses/created.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 201 (Created) Response
3 | * Successful creation occurred (via either POST or PUT).
4 | * Set the Location header to contain a link
5 | * to the newly-created resource (on POST).
6 | * Response body content may or may not be present.
7 | */
8 | module.exports = function (data, code, message, root) {
9 | var response = _.assign({
10 | code: code || 'CREATED',
11 | message: message
12 | || 'The request has resulted in a new resource being created',
13 | data: data || {}
14 | }, root);
15 |
16 | this.req._sails.log.silly('Sent (201 CREATED)\n', response);
17 |
18 | this.res.status(201);
19 | this.res.jsonx(response);
20 | };
21 |
--------------------------------------------------------------------------------
/project/api/responses/unauthorized.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 401 (Unauthorized) Response
3 | * Similar to 403 Forbidden.
4 | * Specifically for authentication failed or not yet provided.
5 | */
6 | module.exports = function (data, code, message, root) {
7 | var response = _.assign({
8 | code: code || 'E_UNAUTHORIZED',
9 | message: message || 'Missing or invalid authentication token',
10 | data: data || {}
11 | }, root);
12 |
13 | this.req._sails.log.silly('Sent (401 UNAUTHORIZED)\n', response);
14 |
15 | this.res.status(401);
16 | this.res.jsonx(response);
17 | };
18 |
--------------------------------------------------------------------------------
/project/api/services/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/project/api/services/.gitkeep
--------------------------------------------------------------------------------
/project/api/services/AuthService.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by Maxim on 14/08/2015.
3 | */
4 | var bcrypt = require('bcrypt-nodejs');
5 | var jwt = require('jsonwebtoken');
6 |
7 | module.exports = {
8 | secret: sails.config.jwtSettings.secret,
9 | issuer: sails.config.jwtSettings.issuer,
10 | audience: sails.config.jwtSettings.audience,
11 |
12 | hashPassword: function(user) {
13 | if (user.password) {
14 | user.password = bcrypt.hashSync(user.password);
15 | return;
16 | }
17 |
18 | console.log("No password given");
19 | },
20 |
21 | comparePassword: function(password, user) {
22 | return bcrypt.compareSync(password, user.password);
23 | },
24 | createToken: function(user) {
25 | return jwt.sign({
26 | user: user.toJSON()
27 | },
28 | sails.config.jwtSettings.secret,
29 | {
30 | algorithm: sails.config.jwtSettings.algorithm,
31 | expiresInMinutes: sails.config.jwtSettings.expiresInMinutes,
32 | //issuer: sails.config.jwtSettings.issuer,
33 | //audience: sails.config.jwtSettings.audience
34 | })
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/project/assets/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/project/assets/favicon.ico
--------------------------------------------------------------------------------
/project/assets/images/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/project/assets/images/.gitkeep
--------------------------------------------------------------------------------
/project/assets/robots.txt:
--------------------------------------------------------------------------------
1 | # The robots.txt file is used to control how search engines index your live URLs.
2 | # See http://www.robotstxt.org/wc/norobots.html for more information.
3 |
4 |
5 |
6 | # To prevent search engines from seeing the site altogether, uncomment the next two lines:
7 | # User-Agent: *
8 | # Disallow: /
9 |
--------------------------------------------------------------------------------
/project/assets/styles/importer.less:
--------------------------------------------------------------------------------
1 | /**
2 | * importer.less
3 | *
4 | * By default, new Sails projects are configured to compile this file
5 | * from LESS to CSS. Unlike CSS files, LESS files are not compiled and
6 | * included automatically unless they are imported below.
7 | *
8 | * The LESS files imported below are compiled and included in the order
9 | * they are listed. Mixins, variables, etc. should be imported first
10 | * so that they can be accessed by subsequent LESS stylesheets.
11 | *
12 | * (Just like the rest of the asset pipeline bundled in Sails, you can
13 | * always omit, customize, or replace this behavior with SASS, SCSS,
14 | * or any other Grunt tasks you like.)
15 | */
16 |
17 |
18 |
19 | // For example:
20 | //
21 | // @import 'variables/colors.less';
22 | // @import 'mixins/foo.less';
23 | // @import 'mixins/bar.less';
24 | // @import 'mixins/baz.less';
25 | //
26 | // @import 'styleguide.less';
27 | // @import 'pages/login.less';
28 | // @import 'pages/signup.less';
29 | //
30 | // etc.
31 |
--------------------------------------------------------------------------------
/project/assets/templates/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XavierGeerinck/Brewr-Site/ff4dae626e37ad84f7fde377b04618c5d706e66b/project/assets/templates/.gitkeep
--------------------------------------------------------------------------------
/project/config/bootstrap.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Bootstrap
3 | * (sails.config.bootstrap)
4 | *
5 | * An asynchronous bootstrap function that runs before your Sails app gets lifted.
6 | * This gives you an opportunity to set up your data model, run jobs, or perform some special logic.
7 | *
8 | * For more information on bootstrapping your app, check out:
9 | * http://sailsjs.org/#!/documentation/reference/sails.config/sails.config.bootstrap.html
10 | */
11 |
12 | var Barrels = require('barrels');
13 | var barrels = new Barrels();
14 | var fixtures = barrels.data;
15 |
16 | module.exports.bootstrap = function(cb) {
17 |
18 | barrels.populate(['user', 'organisation', 'project'], function(err){
19 | // It's very important to trigger this callback method when you are finished
20 | // with the bootstrap! (otherwise your server will never lift, since it's waiting on the bootstrap)
21 | if(err) {
22 | console.log(err);
23 | return cb(err);
24 | }
25 |
26 | barrels.populate(['organisationuser', 'projectuser'], function(err){
27 | if(err) {
28 | console.log(err);
29 | return cb(err);
30 | }
31 |
32 | console.log('populated');
33 | cb();
34 | });
35 | });
36 |
37 |
38 | };
39 |
--------------------------------------------------------------------------------
/project/config/env/development.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Development environment settings
3 | *
4 | * This file can include shared settings for a development team,
5 | * such as API keys or remote database passwords. If you're using
6 | * a version control solution for your Sails app, this file will
7 | * be committed to your repository unless you add it to your .gitignore
8 | * file. If your repository will be publicly viewable, don't add
9 | * any private information to this file!
10 | *
11 | */
12 |
13 | module.exports = {
14 |
15 | /***************************************************************************
16 | * Set the default database connection for models in the development *
17 | * environment (see config/connections.js and config/models.js ) *
18 | ***************************************************************************/
19 |
20 | // models: {
21 | // connection: 'someMongodbServer'
22 | // }
23 |
24 | tokenSecret: 'TqSn6Y@Pr@3TFq*f6_7&f@*+V!$766hnfcY#Njz=A=K-_yhF_PjPJAYLxBCK%_As'
25 |
26 | };
27 |
--------------------------------------------------------------------------------
/project/config/locales/_README.md:
--------------------------------------------------------------------------------
1 | # Internationalization / Localization Settings
2 |
3 | > Also see the official docs on internationalization/localization:
4 | > http://links.sailsjs.org/docs/config/locales
5 |
6 | ## Locales
7 | All locale files live under `config/locales`. Here is where you can add translations
8 | as JSON key-value pairs. The name of the file should match the language that you are supporting, which allows for automatic language detection based on request headers.
9 |
10 | Here is an example locale stringfile for the Spanish language (`config/locales/es.json`):
11 | ```json
12 | {
13 | "Hello!": "Hola!",
14 | "Hello %s, how are you today?": "¿Hola %s, como estas?",
15 | }
16 | ```
17 | ## Usage
18 | Locales can be accessed in controllers/policies through `res.i18n()`, or in views through the `__(key)` or `i18n(key)` functions.
19 | Remember that the keys are case sensitive and require exact key matches, e.g.
20 |
21 | ```ejs
22 | <%= __('Welcome to PencilPals!') %>
23 | <%= i18n('Hello %s, how are you today?', 'Pencil Maven') %>
24 | <%= i18n('That\'s right-- you can use either i18n() or __()') %>
25 | ```
26 |
27 | ## Configuration
28 | Localization/internationalization config can be found in `config/i18n.js`, from where you can set your supported locales.
29 |
--------------------------------------------------------------------------------
/project/config/locales/de.json:
--------------------------------------------------------------------------------
1 | {
2 | "Welcome": "Willkommen",
3 | "A brand new app.": "Eine neue App."
4 | }
5 |
--------------------------------------------------------------------------------
/project/config/locales/en.json:
--------------------------------------------------------------------------------
1 | {
2 | "Welcome": "Welcome",
3 | "A brand new app.": "A brand new app."
4 | }
5 |
--------------------------------------------------------------------------------
/project/config/locales/es.json:
--------------------------------------------------------------------------------
1 | {
2 | "Welcome": "Bienvenido",
3 | "A brand new app.": "Una aplicación de la nueva marca."
4 | }
5 |
--------------------------------------------------------------------------------
/project/config/locales/fr.json:
--------------------------------------------------------------------------------
1 | {
2 | "Welcome": "Bienvenue",
3 | "A brand new app.": "Une toute nouvelle application."
4 | }
5 |
--------------------------------------------------------------------------------
/project/config/log.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Built-in Log Configuration
3 | * (sails.config.log)
4 | *
5 | * Configure the log level for your app, as well as the transport
6 | * (Underneath the covers, Sails uses Winston for logging, which
7 | * allows for some pretty neat custom transports/adapters for log messages)
8 | *
9 | * For more information on the Sails logger, check out:
10 | * http://sailsjs.org/#!/documentation/concepts/Logging
11 | */
12 |
13 | module.exports.log = {
14 |
15 | /***************************************************************************
16 | * *
17 | * Valid `level` configs: i.e. the minimum log level to capture with *
18 | * sails.log.*() *
19 | * *
20 | * The order of precedence for log levels from lowest to highest is: *
21 | * silly, verbose, info, debug, warn, error *
22 | * *
23 | * You may also set the level to "silent" to suppress all logs. *
24 | * *
25 | ***************************************************************************/
26 |
27 | // level: 'info'
28 |
29 | };
30 |
--------------------------------------------------------------------------------
/project/tasks/config/clean.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Clean files and folders.
3 | *
4 | * ---------------------------------------------------------------
5 | *
6 | * This grunt task is configured to clean out the contents in the .tmp/public of your
7 | * sails project.
8 | *
9 | * For usage docs see:
10 | * https://github.com/gruntjs/grunt-contrib-clean
11 | */
12 | module.exports = function(grunt) {
13 |
14 | grunt.config.set('clean', {
15 | dev: ['.tmp/public/**'],
16 | build: ['www']
17 | });
18 |
19 | grunt.loadNpmTasks('grunt-contrib-clean');
20 | };
21 |
--------------------------------------------------------------------------------
/project/tasks/config/coffee.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Compile CoffeeScript files to JavaScript.
3 | *
4 | * ---------------------------------------------------------------
5 | *
6 | * Compiles coffeeScript files from `assest/js` into Javascript and places them into
7 | * `.tmp/public/js` directory.
8 | *
9 | * For usage docs see:
10 | * https://github.com/gruntjs/grunt-contrib-coffee
11 | */
12 | module.exports = function(grunt) {
13 |
14 | grunt.config.set('coffee', {
15 | dev: {
16 | options: {
17 | bare: true,
18 | sourceMap: true,
19 | sourceRoot: './'
20 | },
21 | files: [{
22 | expand: true,
23 | cwd: 'assets/js/',
24 | src: ['**/*.coffee'],
25 | dest: '.tmp/public/js/',
26 | ext: '.js'
27 | }, {
28 | expand: true,
29 | cwd: 'assets/js/',
30 | src: ['**/*.coffee'],
31 | dest: '.tmp/public/js/',
32 | ext: '.js'
33 | }]
34 | }
35 | });
36 |
37 | grunt.loadNpmTasks('grunt-contrib-coffee');
38 | };
39 |
--------------------------------------------------------------------------------
/project/tasks/config/concat.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Concatenate files.
3 | *
4 | * ---------------------------------------------------------------
5 | *
6 | * Concatenates files javascript and css from a defined array. Creates concatenated files in
7 | * .tmp/public/contact directory
8 | * [concat](https://github.com/gruntjs/grunt-contrib-concat)
9 | *
10 | * For usage docs see:
11 | * https://github.com/gruntjs/grunt-contrib-concat
12 | */
13 | module.exports = function(grunt) {
14 |
15 | grunt.config.set('concat', {
16 | js: {
17 | src: require('../pipeline').jsFilesToInject,
18 | dest: '.tmp/public/concat/production.js'
19 | },
20 | css: {
21 | src: require('../pipeline').cssFilesToInject,
22 | dest: '.tmp/public/concat/production.css'
23 | }
24 | });
25 |
26 | grunt.loadNpmTasks('grunt-contrib-concat');
27 | };
28 |
--------------------------------------------------------------------------------
/project/tasks/config/copy.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copy files and folders.
3 | *
4 | * ---------------------------------------------------------------
5 | *
6 | * # dev task config
7 | * Copies all directories and files, exept coffescript and less fiels, from the sails
8 | * assets folder into the .tmp/public directory.
9 | *
10 | * # build task config
11 | * Copies all directories nd files from the .tmp/public directory into a www directory.
12 | *
13 | * For usage docs see:
14 | * https://github.com/gruntjs/grunt-contrib-copy
15 | */
16 | module.exports = function(grunt) {
17 |
18 | grunt.config.set('copy', {
19 | dev: {
20 | files: [{
21 | expand: true,
22 | cwd: './assets',
23 | src: ['**/*.!(coffee|less)'],
24 | dest: '.tmp/public'
25 | }]
26 | },
27 | build: {
28 | files: [{
29 | expand: true,
30 | cwd: '.tmp/public',
31 | src: ['**/*'],
32 | dest: 'www'
33 | }]
34 | }
35 | });
36 |
37 | grunt.loadNpmTasks('grunt-contrib-copy');
38 | };
39 |
--------------------------------------------------------------------------------
/project/tasks/config/cssmin.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Compress CSS files.
3 | *
4 | * ---------------------------------------------------------------
5 | *
6 | * Minifies css files and places them into .tmp/public/min directory.
7 | *
8 | * For usage docs see:
9 | * https://github.com/gruntjs/grunt-contrib-cssmin
10 | */
11 | module.exports = function(grunt) {
12 |
13 | grunt.config.set('cssmin', {
14 | dist: {
15 | src: ['.tmp/public/concat/production.css'],
16 | dest: '.tmp/public/min/production.min.css'
17 | }
18 | });
19 |
20 | grunt.loadNpmTasks('grunt-contrib-cssmin');
21 | };
22 |
--------------------------------------------------------------------------------
/project/tasks/config/jst.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Precompiles Underscore templates to a `.jst` file.
3 | *
4 | * ---------------------------------------------------------------
5 | *
6 | * (i.e. basically it takes HTML files and turns them into tiny little
7 | * javascript functions that you pass data to and return HTML. This can
8 | * speed up template rendering on the client, and reduce bandwidth usage.)
9 | *
10 | * For usage docs see:
11 | * https://github.com/gruntjs/grunt-contrib-jst
12 | *
13 | */
14 |
15 | module.exports = function(grunt) {
16 |
17 | grunt.config.set('jst', {
18 | dev: {
19 |
20 | // To use other sorts of templates, specify a regexp like the example below:
21 | // options: {
22 | // templateSettings: {
23 | // interpolate: /\{\{(.+?)\}\}/g
24 | // }
25 | // },
26 |
27 | // Note that the interpolate setting above is simply an example of overwriting lodash's
28 | // default interpolation. If you want to parse templates with the default _.template behavior
29 | // (i.e. using ), there's no need to overwrite `templateSettings.interpolate`.
30 |
31 |
32 | files: {
33 | // e.g.
34 | // 'relative/path/from/gruntfile/to/compiled/template/destination' : ['relative/path/to/sourcefiles/**/*.html']
35 | '.tmp/public/jst.js': require('../pipeline').templateFilesToInject
36 | }
37 | }
38 | });
39 |
40 | grunt.loadNpmTasks('grunt-contrib-jst');
41 | };
42 |
--------------------------------------------------------------------------------
/project/tasks/config/less.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Compiles LESS files into CSS.
3 | *
4 | * ---------------------------------------------------------------
5 | *
6 | * Only the `assets/styles/importer.less` is compiled.
7 | * This allows you to control the ordering yourself, i.e. import your
8 | * dependencies, mixins, variables, resets, etc. before other stylesheets)
9 | *
10 | * For usage docs see:
11 | * https://github.com/gruntjs/grunt-contrib-less
12 | */
13 | module.exports = function(grunt) {
14 |
15 | grunt.config.set('less', {
16 | dev: {
17 | files: [{
18 | expand: true,
19 | cwd: 'assets/styles/',
20 | src: ['importer.less'],
21 | dest: '.tmp/public/styles/',
22 | ext: '.css'
23 | }]
24 | }
25 | });
26 |
27 | grunt.loadNpmTasks('grunt-contrib-less');
28 | };
29 |
--------------------------------------------------------------------------------
/project/tasks/config/sync.js:
--------------------------------------------------------------------------------
1 | /**
2 | * A grunt task to keep directories in sync. It is very similar to grunt-contrib-copy
3 | * but tries to copy only those files that has actually changed.
4 | *
5 | * ---------------------------------------------------------------
6 | *
7 | * Synchronize files from the `assets` folder to `.tmp/public`,
8 | * smashing anything that's already there.
9 | *
10 | * For usage docs see:
11 | * https://github.com/tomusdrw/grunt-sync
12 | *
13 | */
14 | module.exports = function(grunt) {
15 |
16 | grunt.config.set('sync', {
17 | dev: {
18 | files: [{
19 | cwd: './assets',
20 | src: ['**/*.!(coffee)'],
21 | dest: '.tmp/public'
22 | }]
23 | }
24 | });
25 |
26 | grunt.loadNpmTasks('grunt-sync');
27 | };
28 |
--------------------------------------------------------------------------------
/project/tasks/config/uglify.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Minify files with UglifyJS.
3 | *
4 | * ---------------------------------------------------------------
5 | *
6 | * Minifies client-side javascript `assets`.
7 | *
8 | * For usage docs see:
9 | * https://github.com/gruntjs/grunt-contrib-uglify
10 | *
11 | */
12 | module.exports = function(grunt) {
13 |
14 | grunt.config.set('uglify', {
15 | dist: {
16 | src: ['.tmp/public/concat/production.js'],
17 | dest: '.tmp/public/min/production.min.js'
18 | }
19 | });
20 |
21 | grunt.loadNpmTasks('grunt-contrib-uglify');
22 | };
23 |
--------------------------------------------------------------------------------
/project/tasks/config/watch.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Run predefined tasks whenever watched file patterns are added, changed or deleted.
3 | *
4 | * ---------------------------------------------------------------
5 | *
6 | * Watch for changes on
7 | * - files in the `assets` folder
8 | * - the `tasks/pipeline.js` file
9 | * and re-run the appropriate tasks.
10 | *
11 | * For usage docs see:
12 | * https://github.com/gruntjs/grunt-contrib-watch
13 | *
14 | */
15 | module.exports = function(grunt) {
16 |
17 | grunt.config.set('watch', {
18 | api: {
19 |
20 | // API files to watch:
21 | files: ['api/**/*', '!**/node_modules/**']
22 | },
23 | assets: {
24 |
25 | // Assets to watch:
26 | files: ['assets/**/*', 'tasks/pipeline.js', '!**/node_modules/**'],
27 |
28 | // When assets are changed:
29 | tasks: ['syncAssets' , 'linkAssets']
30 | }
31 | });
32 |
33 | grunt.loadNpmTasks('grunt-contrib-watch');
34 | };
35 |
--------------------------------------------------------------------------------
/project/tasks/register/build.js:
--------------------------------------------------------------------------------
1 | module.exports = function (grunt) {
2 | grunt.registerTask('build', [
3 | 'compileAssets',
4 | 'linkAssetsBuild',
5 | 'clean:build',
6 | 'copy:build'
7 | ]);
8 | };
9 |
--------------------------------------------------------------------------------
/project/tasks/register/buildProd.js:
--------------------------------------------------------------------------------
1 | module.exports = function (grunt) {
2 | grunt.registerTask('buildProd', [
3 | 'compileAssets',
4 | 'concat',
5 | 'uglify',
6 | 'cssmin',
7 | 'linkAssetsBuildProd',
8 | 'clean:build',
9 | 'copy:build'
10 | ]);
11 | };
12 |
--------------------------------------------------------------------------------
/project/tasks/register/compileAssets.js:
--------------------------------------------------------------------------------
1 | module.exports = function (grunt) {
2 | grunt.registerTask('compileAssets', [
3 | 'clean:dev',
4 | 'jst:dev',
5 | 'less:dev',
6 | 'copy:dev',
7 | 'coffee:dev'
8 | ]);
9 | };
10 |
--------------------------------------------------------------------------------
/project/tasks/register/default.js:
--------------------------------------------------------------------------------
1 | module.exports = function (grunt) {
2 | grunt.registerTask('default', ['compileAssets', 'linkAssets', 'watch']);
3 | };
4 |
--------------------------------------------------------------------------------
/project/tasks/register/linkAssets.js:
--------------------------------------------------------------------------------
1 | module.exports = function (grunt) {
2 | grunt.registerTask('linkAssets', [
3 | 'sails-linker:devJs',
4 | 'sails-linker:devStyles',
5 | 'sails-linker:devTpl',
6 | 'sails-linker:devJsJade',
7 | 'sails-linker:devStylesJade',
8 | 'sails-linker:devTplJade'
9 | ]);
10 | };
11 |
--------------------------------------------------------------------------------
/project/tasks/register/linkAssetsBuild.js:
--------------------------------------------------------------------------------
1 | module.exports = function (grunt) {
2 | grunt.registerTask('linkAssetsBuild', [
3 | 'sails-linker:devJsRelative',
4 | 'sails-linker:devStylesRelative',
5 | 'sails-linker:devTpl',
6 | 'sails-linker:devJsRelativeJade',
7 | 'sails-linker:devStylesRelativeJade',
8 | 'sails-linker:devTplJade'
9 | ]);
10 | };
11 |
--------------------------------------------------------------------------------
/project/tasks/register/linkAssetsBuildProd.js:
--------------------------------------------------------------------------------
1 | module.exports = function (grunt) {
2 | grunt.registerTask('linkAssetsBuildProd', [
3 | 'sails-linker:prodJsRelative',
4 | 'sails-linker:prodStylesRelative',
5 | 'sails-linker:devTpl',
6 | 'sails-linker:prodJsRelativeJade',
7 | 'sails-linker:prodStylesRelativeJade',
8 | 'sails-linker:devTplJade'
9 | ]);
10 | };
11 |
--------------------------------------------------------------------------------
/project/tasks/register/prod.js:
--------------------------------------------------------------------------------
1 | module.exports = function (grunt) {
2 | grunt.registerTask('prod', [
3 | 'compileAssets',
4 | 'concat',
5 | 'uglify',
6 | 'cssmin',
7 | 'sails-linker:prodJs',
8 | 'sails-linker:prodStyles',
9 | 'sails-linker:devTpl',
10 | 'sails-linker:prodJsJade',
11 | 'sails-linker:prodStylesJade',
12 | 'sails-linker:devTplJade'
13 | ]);
14 | };
15 |
--------------------------------------------------------------------------------
/project/tasks/register/syncAssets.js:
--------------------------------------------------------------------------------
1 | module.exports = function (grunt) {
2 | grunt.registerTask('syncAssets', [
3 | 'jst:dev',
4 | 'less:dev',
5 | 'sync:dev',
6 | 'coffee:dev'
7 | ]);
8 | };
9 |
--------------------------------------------------------------------------------
/project/test/fixtures/organisation.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": 1,
4 | "name": "Test organisation",
5 | "description": "an organization which focus on lipsum...",
6 | "subdomain": "test.organisation.com",
7 | "owner": 1,
8 | "user_limit": 25,
9 | "project_limit": 5,
10 | "createdBy": 1
11 | }
12 | ]
--------------------------------------------------------------------------------
/project/test/fixtures/organisationuser.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": 1,
4 | "addedOn": "2015-08-10T08:58:43.000Z",
5 | "user": 2,
6 | "organisation": 1
7 | },
8 | {
9 | "id": 2,
10 | "addedOn": "2015-08-10T08:58:43.000Z",
11 | "user": 3,
12 | "organisation": 1
13 | },
14 | {
15 | "id": 3,
16 | "addedOn": "2015-08-10T08:58:43.000Z",
17 | "user": 4,
18 | "organisation": 1
19 | }
20 | ]
--------------------------------------------------------------------------------
/project/test/fixtures/project.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": 1,
4 | "name": "Brewr",
5 | "description": "A project to create brewr, placeholder",
6 | "organisation": 1,
7 | "estimated_price": 100000,
8 | "created_by": 1
9 | },
10 | {
11 | "id": 2,
12 | "name": "What to eat",
13 | "description": "A project to share what to eat",
14 | "organisation": 1,
15 | "estimated_price": 45000,
16 | "created_by": 1
17 | }
18 | ]
19 |
--------------------------------------------------------------------------------
/project/test/fixtures/projectuser.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": 1,
4 | "addedOn": "2015-08-10T08:59:43.000Z",
5 | "deadline": "2015-11-13T08:59:43.000Z",
6 | "isManager": true,
7 | "user": 2,
8 | "project": 1
9 | },
10 | {
11 | "id": 2,
12 | "addedOn": "2015-08-10T09:10:43.000Z",
13 | "deadline": "2015-11-20T08:59:43.000Z",
14 | "isManager": false,
15 | "user": 3,
16 | "project": 1
17 | },
18 | {
19 | "id": 3,
20 | "addedOn": "2015-08-10T09:13:43.000Z",
21 | "deadline": "2015-12-10T08:59:43.000Z",
22 | "isManager": true,
23 | "user": 4,
24 | "project": 2
25 | },
26 | {
27 | "id": 4,
28 | "addedOn": "2015-08-10T09:13:43.000Z",
29 | "deadline": "2015-12-10T08:59:43.000Z",
30 | "isManager": true,
31 | "user": 1,
32 | "project": 2
33 | }
34 | ]
--------------------------------------------------------------------------------
/project/test/fixtures/user.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": 1,
4 | "email": "maximgeerinck@hotmail.com",
5 | "password": "test",
6 | "enabled": true,
7 | "scope": null,
8 | "createdOn": "2015-08-08T08:58:43.000Z",
9 | "updatedOn": "2015-08-08T08:58:47.000Z",
10 | "expiresOn": "2015-08-08T08:58:48.000Z"
11 | },
12 | {
13 | "id": 2,
14 | "email": "NicholasTCoakley@brewr.com",
15 | "password": "test",
16 | "enabled": true,
17 | "scope": null,
18 | "createdOn": "2015-08-08T08:58:43.000Z",
19 | "updatedOn": "2015-08-08T08:58:47.000Z",
20 | "expiresOn": "2015-08-08T08:58:48.000Z"
21 | },
22 | {
23 | "id": 3,
24 | "email": "AdelineNPedraza@brewr.com",
25 | "password": "test",
26 | "enabled": true,
27 | "scope": null,
28 | "createdOn": "2015-08-08T08:58:43.000Z",
29 | "updatedOn": "2015-08-08T08:58:47.000Z",
30 | "expiresOn": "2015-08-08T08:58:48.000Z"
31 | },
32 | {
33 | "id": 4,
34 | "email": "SeanAMurphy@brewr.com",
35 | "password": "test",
36 | "enabled": true,
37 | "scope": null,
38 | "createdOn": "2015-08-08T08:58:43.000Z",
39 | "updatedOn": "2015-08-08T08:58:47.000Z",
40 | "expiresOn": "2015-08-08T08:58:48.000Z"
41 | }
42 | ]
--------------------------------------------------------------------------------