-
+
+
);
}
diff --git a/frontend/components/SidePanel/styles.js b/frontend/components/SidePanel/styles.js
index d1477d4e19..78e2b120dc 100644
--- a/frontend/components/SidePanel/styles.js
+++ b/frontend/components/SidePanel/styles.js
@@ -5,21 +5,43 @@ const { border, color, font, padding } = Styles;
const componentStyles = {
companyLogoStyles: {
position: 'absolute',
- left: '16px',
- height: '44px',
+ left: '0',
+ top: '23px',
+ height: '42px',
marginRight: '10px',
+ borderColor: color.accentMedium,
+ borderStyle: 'solid',
+ borderWidth: '1px',
+ borderRadius: '100%',
'@media (max-width: 760px)': {
- left: '4px',
+ left: '5px',
},
},
headerStyles: {
borderBottomColor: color.accentLight,
borderBottomStyle: 'solid',
borderBottomWidth: '1px',
- height: '67px',
- marginBottom: padding.half,
- marginRight: padding.medium,
+ height: '62px',
+ cursor: 'pointer',
paddingLeft: '54px',
+ paddingTop: '26px',
+ marginRight: '16px',
+ position: 'relative',
+ },
+ orgChevronStyles: {
+ color: color.accentMedium,
+ fontSize: '12px',
+ position: 'absolute',
+ top: '50px',
+ right: '35px',
+ '@media (max-width: 760px)': {
+ top: 'auto',
+ left: '0',
+ right: '0',
+ bottom: '6px',
+ textAlign: 'center',
+ display: 'block',
+ },
},
iconStyles: {
position: 'relative',
@@ -28,7 +50,9 @@ const componentStyles = {
top: '4px',
left: 0,
'@media (max-width: 760px)': {
- left: '5px',
+ display: 'block',
+ textAlign: 'center',
+ marginRight: 0,
},
},
navItemBeforeStyles: {
@@ -36,8 +60,8 @@ const componentStyles = {
width: '6px',
height: '50px',
position: 'absolute',
- left: '-24px',
- top: '2px',
+ left: '-16px',
+ top: 0,
bottom: 0,
backgroundColor: '#9a61c6',
'@media (max-width: 760px)': {
@@ -60,10 +84,11 @@ const componentStyles = {
const activeStyles = {
color: color.brand,
borderBottom: 'none',
- transition: 'none',
+ ':hover': {
+ color: color.brandDark,
+ },
'@media (max-width: 760px)': {
- borderBottom: '8px solid #9a61c6',
- textAlign: 'center',
+ borderBottom: '6px solid #9a61c6',
},
};
@@ -72,12 +97,13 @@ const componentStyles = {
position: 'relative',
color: color.textLight,
cursor: 'pointer',
- fontSize: font.small,
+ fontSize: '13px',
+ letterSpacing: '0.5px',
textTransform: 'uppercase',
paddingTop: padding.half,
- transition: 'all 0.2s ease-in-out',
- '@media (max-width: 760px)': {
- textAlign: 'center',
+ transition: 'color 0.2s ease-in-out',
+ ':hover': {
+ color: color.textDark,
},
};
@@ -122,25 +148,24 @@ const componentStyles = {
bottom: 0,
boxShadow: '2px 0 8px 0 rgba(0, 0, 0, 0.1)',
left: 0,
- paddingLeft: padding.large,
- paddingTop: padding.large,
+ paddingLeft: '16px',
position: 'fixed',
top: 0,
- width: '216px',
+ width: '223px',
'@media (max-width: 760px)': {
paddingLeft: 0,
width: '54px',
},
},
orgNameStyles: {
- fontSize: font.medium,
+ fontSize: '16px',
letterSpacing: '0.5px',
margin: 0,
overFlow: 'hidden',
padding: 0,
position: 'relative',
textOverflow: 'ellipsis',
- top: '3px',
+ top: '1px',
whiteSpace: 'nowrap',
'@media (max-width: 760px)': {
display: 'none',
@@ -167,8 +192,12 @@ const componentStyles = {
},
subItemStyles: (active) => {
const activeStyles = {
+ fontSize: '13px',
fontWeight: font.weight.bold,
opacity: '1',
+ ':hover': {
+ opacity: '1.0',
+ },
};
const baseStyles = {
@@ -184,6 +213,9 @@ const componentStyles = {
position: 'relative',
textTransform: 'none',
transition: 'all 0.2s ease-in-out',
+ ':hover': {
+ opacity: '0.75',
+ },
};
if (active) {
@@ -195,54 +227,62 @@ const componentStyles = {
return baseStyles;
},
- subItemsStyles: (expanded) => {
- return {
- backgroundColor: color.brand,
- boxShadow: 'inset 0 5px 8px 0 rgba(0, 0, 0, 0.12), inset 0 -5px 8px 0 rgba(0, 0, 0, 0.12)',
- marginBottom: 0,
- marginRight: 0,
- minHeight: '87px',
- paddingBottom: padding.half,
- paddingTop: padding.half,
- marginLeft: '-24px',
- marginTop: padding.medium,
- transition: 'width 0.1s ease-in-out',
- '@media (max-width: 760px)': {
- bottom: '-8px',
- left: '54px',
- marginLeft: 0,
- position: 'absolute',
- width: expanded ? '251px' : '18px',
- },
- };
+ subItemsStyles: {
+ backgroundColor: color.brand,
+ boxShadow: 'inset 0 5px 8px 0 rgba(0, 0, 0, 0.12), inset 0 -5px 8px 0 rgba(0, 0, 0, 0.12)',
+ marginRight: 0,
+ marginBottom: '6px',
+ paddingBottom: '3px',
+ paddingTop: '3px',
+ marginLeft: '-16px',
+ position: 'relative',
+ top: '10px',
+ transition: 'width 0.1s ease-in-out',
+ '@media (max-width: 760px)': {
+ minHeight: '84px',
+ borderTopRightRadius: '3px',
+ borderBottomRightRadius: '3px',
+ boxShadow: '2px 2px 8px rgba(0,0,0,0.1)',
+ bottom: '-8px',
+ left: '54px',
+ marginLeft: 0,
+ position: 'absolute',
+ },
},
subItemListStyles: (expanded) => {
return {
listStyle: 'none',
+ paddingLeft: '16px',
'@media (max-width: 760px)': {
borderRight: '1px solid rgba(0,0,0,0.16)',
display: expanded ? 'inline-block' : 'none',
padding: 0,
textAlign: 'left',
- width: '211px',
+ width: '166px',
},
};
},
collapseSubItemsWrapper: {
position: 'absolute',
- right: '3px',
- top: '41%',
+ right: '4px',
+ top: '0',
+ bottom: '0',
+ lineHeight: '95px',
+ color: '#fff',
+
'@media (min-width: 761px)': {
display: 'none',
},
},
usernameStyles: {
position: 'relative',
- top: '3px',
display: 'inline-block',
margin: 0,
padding: 0,
- fontSize: font.small,
+ top: '-3px',
+ left: '4px',
+ fontSize: '13px',
+ letterSpacing: '0.6px',
textTransform: 'uppercase',
'@media (max-width: 760px)': {
display: 'none',
@@ -257,10 +297,8 @@ const componentStyles = {
borderRadius: border.radius.circle,
display: 'inline-block',
height: size,
- left: '1px',
marginRight: '6px',
position: 'relative',
- top: '6px',
width: size,
'@media (max-width: 760px)': {
display: 'none',
diff --git a/frontend/components/SidePanel/styles.scss b/frontend/components/SidePanel/styles.scss
new file mode 100644
index 0000000000..8eb4c9d775
--- /dev/null
+++ b/frontend/components/SidePanel/styles.scss
@@ -0,0 +1,8 @@
+@media (max-width: 760px) {
+ .sub-nav {
+ width: 22px;
+ }
+ .sub-nav--expanded {
+ width: 188px;
+ }
+}
diff --git a/frontend/components/StackedWhiteBoxes/StackedWhiteBoxes.jsx b/frontend/components/StackedWhiteBoxes/StackedWhiteBoxes.jsx
index 9080a57f2c..a16c604585 100644
--- a/frontend/components/StackedWhiteBoxes/StackedWhiteBoxes.jsx
+++ b/frontend/components/StackedWhiteBoxes/StackedWhiteBoxes.jsx
@@ -24,7 +24,7 @@ class StackedWhiteBoxes extends Component {
return (
- x
+ ╳
);
}
diff --git a/frontend/components/StackedWhiteBoxes/styles.js b/frontend/components/StackedWhiteBoxes/styles.js
index e92bfb2ce7..f8a5d2bd7e 100644
--- a/frontend/components/StackedWhiteBoxes/styles.js
+++ b/frontend/components/StackedWhiteBoxes/styles.js
@@ -4,16 +4,15 @@ const { border, color, font, padding } = styles;
export default {
boxStyles: {
- alignItems: 'center',
backgroundColor: color.white,
- borderTopLeftRadius: border.radius.base,
- borderTopRightRadius: border.radius.base,
+ borderRadius: border.radius.base,
boxShadow: border.shadow.blur,
+ minHeight: '370px',
boxSizing: 'border-box',
- display: 'flex',
- flexDirection: 'column',
- padding: padding.base,
- width: '522px',
+ padding: '30px',
+ width: '524px',
+ position: 'relative',
+ fontWeight: 300,
},
containerStyles: {
alignItems: 'center',
@@ -24,6 +23,10 @@ export default {
exStyles: {
color: color.lightGrey,
textDecoration: 'none',
+ position: 'absolute',
+ top: '30px',
+ right: '30px',
+ fontWeight: 'bold',
},
exWrapperStyles: {
textAlign: 'right',
@@ -53,6 +56,8 @@ export default {
textStyles: {
color: color.purpleGrey,
fontSize: font.medium,
+ lineHeight: '30px',
+ letterSpacing: '0.64px',
},
smallTabStyles: {
backgroundColor: color.white,
diff --git a/frontend/components/buttons/GradientButton/styles.js b/frontend/components/buttons/GradientButton/styles.js
index 9df7f50698..08786120c8 100644
--- a/frontend/components/buttons/GradientButton/styles.js
+++ b/frontend/components/buttons/GradientButton/styles.js
@@ -16,7 +16,6 @@ export default {
fontSize: font.large,
fontWeight: '300',
letterSpacing: '4px',
- marginTop: padding.base,
padding: padding.medium,
position: 'relative',
textTransform: 'uppercase',
diff --git a/frontend/components/forms/ForgotPasswordForm/ForgotPasswordForm.jsx b/frontend/components/forms/ForgotPasswordForm/ForgotPasswordForm.jsx
index f8ce0c35f2..dc91d7d348 100644
--- a/frontend/components/forms/ForgotPasswordForm/ForgotPasswordForm.jsx
+++ b/frontend/components/forms/ForgotPasswordForm/ForgotPasswordForm.jsx
@@ -86,7 +86,7 @@ class ForgotPasswordForm extends Component {
render () {
const { error: serverError } = this.props;
const { errors: clientErrors } = this.state;
- const { formStyles, inputStyles, submitButtonStyles } = componentStyles;
+ const { formStyles, submitButtonContainerStyles, submitButtonStyles } = componentStyles;
const { onFormSubmit, onInputFieldChange } = this;
return (
@@ -94,17 +94,18 @@ class ForgotPasswordForm extends Component {
-
+
+
+
);
}
diff --git a/frontend/components/forms/ForgotPasswordForm/styles.js b/frontend/components/forms/ForgotPasswordForm/styles.js
index 3c379eebdb..2db5632f3c 100644
--- a/frontend/components/forms/ForgotPasswordForm/styles.js
+++ b/frontend/components/forms/ForgotPasswordForm/styles.js
@@ -2,7 +2,15 @@ export default {
formStyles: {
width: '100%',
},
- inputStyles: {
- width: '100%',
+ submitButtonStyles: {
+ ':active': {
+ boxShadow: '0 1px 0 #734893',
+ },
+ },
+ submitButtonContainerStyles: {
+ position: 'absolute',
+ bottom: '30px',
+ left: '30px',
+ right: '30px',
},
};
diff --git a/frontend/components/forms/LoginForm/LoginForm.jsx b/frontend/components/forms/LoginForm/LoginForm.jsx
index 30c56d9c8f..1fddd1941d 100644
--- a/frontend/components/forms/LoginForm/LoginForm.jsx
+++ b/frontend/components/forms/LoginForm/LoginForm.jsx
@@ -140,14 +140,14 @@ class LoginForm extends Component {
{
- const { error } = this.props;
- const { value } = this.state;
-
- if (error) return 'error';
-
- if (value) return 'colored';
-
- return 'default';
- }
-
renderHeading = () => {
const { error, placeholder } = this.props;
const { value } = this.state;
@@ -70,9 +59,9 @@ class InputFieldWithIcon extends Component {
render () {
const { error, iconName, name, placeholder, style, type } = this.props;
- const { containerStyles, iconStyles, inputErrorStyles, inputStyles } = componentStyles;
+ const { containerStyles, iconStyles, iconErrorStyles, inputErrorStyles, inputStyles } = componentStyles;
const { value } = this.state;
- const { iconVariant, onInputChange } = this;
+ const { onInputChange } = this;
return (
@@ -80,12 +69,13 @@ class InputFieldWithIcon extends Component {
{ this.input = r; }}
- style={[inputStyles(value), inputErrorStyles(error), style]}
+ style={[inputStyles(value, type), inputErrorStyles(error), style]}
type={type}
/>
-
+
);
}
diff --git a/frontend/components/forms/fields/InputFieldWithIcon/styles.js b/frontend/components/forms/fields/InputFieldWithIcon/styles.js
index 5ddf8f47cd..27237b3de8 100644
--- a/frontend/components/forms/fields/InputFieldWithIcon/styles.js
+++ b/frontend/components/forms/fields/InputFieldWithIcon/styles.js
@@ -6,16 +6,38 @@ export default {
containerStyles: {
marginTop: padding.base,
position: 'relative',
+ width: '100%',
},
errorStyles: {
color: color.alert,
fontSize: font.small,
textTransform: 'lowercase',
},
- iconStyles: {
- position: 'absolute',
- right: '6px',
- top: '29px',
+ iconStyles: (value) => {
+ const baseStyles = {
+ position: 'absolute',
+ right: '6px',
+ top: '28px',
+ fontSize: '20px',
+ color: color.accentText,
+ };
+ if (value) {
+ return {
+ ...baseStyles,
+ color: color.brand,
+ };
+ }
+
+ return baseStyles;
+ },
+
+ iconErrorStyles: (error) => {
+ if (error) {
+ return {
+ color: color.alert,
+ };
+ }
+ return false;
},
inputErrorStyles: (error) => {
if (error) {
@@ -26,21 +48,35 @@ export default {
return {};
},
- inputStyles: (value) => {
+ inputStyles: (value, type) => {
const baseStyles = {
borderLeft: 'none',
borderRight: 'none',
borderTop: 'none',
- borderBottomWidth: '1px',
+ borderBottomWidth: '2px',
+ fontSize: '20px',
borderBottomStyle: 'solid',
- borderBottomColor: color.brand,
+ borderBottomColor: color.brandUltralight,
color: color.accentText,
- width: '378px',
+ paddingRight: '30px',
+ opacity: '1',
+ textIndent: '1px',
+ position: 'relative',
+ width: '100%',
+ boxSizing: 'border-box',
':focus': {
outline: 'none',
},
};
+ if (type === 'password' && value) {
+ return {
+ ...baseStyles,
+ letterSpacing: '7px',
+ color: color.textUltradark,
+ };
+ }
+
if (value) {
return {
...baseStyles,
diff --git a/frontend/index.jsx b/frontend/index.jsx
index 67f250e226..56a32170d2 100644
--- a/frontend/index.jsx
+++ b/frontend/index.jsx
@@ -1,5 +1,6 @@
import ReactDOM from 'react-dom';
import routes from './router';
+import './index.scss';
if (typeof window !== 'undefined') {
const { document } = global;
diff --git a/frontend/index.scss b/frontend/index.scss
new file mode 100644
index 0000000000..1399fd12e5
--- /dev/null
+++ b/frontend/index.scss
@@ -0,0 +1,3 @@
+@import "stylesheets/fonts.scss";
+@import "stylesheets/icons.scss";
+@import "stylesheets/forms.scss";
diff --git a/frontend/pages/LoginSuccessfulPage/LoginSuccessfulPage.jsx b/frontend/pages/LoginSuccessfulPage/LoginSuccessfulPage.jsx
index 8f7166a1f7..7c7a9438e8 100644
--- a/frontend/pages/LoginSuccessfulPage/LoginSuccessfulPage.jsx
+++ b/frontend/pages/LoginSuccessfulPage/LoginSuccessfulPage.jsx
@@ -6,13 +6,11 @@ import componentStyles from './styles';
import Icon from '../../components/icons/Icon';
import paths from '../../router/paths';
-const COUNTDOWN_INTERVAL = 1000;
-const REDIRECT_TIME = 3000;
+const REDIRECT_TIME = 1200;
class LoginSuccessfulPage extends Component {
static propTypes = {
dispatch: PropTypes.func.isRequired,
- user: PropTypes.object,
};
constructor (props) {
@@ -27,42 +25,23 @@ class LoginSuccessfulPage extends Component {
this.startRedirectCountdown();
}
- componentWillUnmount () {
- const { interval } = this;
-
- if (interval) clearInterval(interval);
- }
-
startRedirectCountdown = () => {
const { dispatch } = this.props;
const { HOME } = paths;
+ const { redirectTime } = this.state;
- this.interval = setInterval(() => {
- const { redirectTime } = this.state;
-
- if (redirectTime > 0) {
- this.setState({
- redirectTime: redirectTime - COUNTDOWN_INTERVAL,
- });
-
- return false;
- }
-
+ setTimeout(() => {
return dispatch(push(HOME));
- }, COUNTDOWN_INTERVAL);
+ }, redirectTime);
}
render () {
const { loginSuccessStyles, subtextStyles, whiteBoxStyles } = componentStyles;
- const { redirectTime } = this.state;
- const secondsToRedirect = redirectTime / 1000;
-
return (
Login successful
-
Hold on to your butts.
-
redirecting in {secondsToRedirect}
+
hold on to your butts...
);
}
diff --git a/assets/stylesheets/fonts.css b/frontend/stylesheets/fonts.scss
similarity index 100%
rename from assets/stylesheets/fonts.css
rename to frontend/stylesheets/fonts.scss
diff --git a/frontend/stylesheets/forms.scss b/frontend/stylesheets/forms.scss
new file mode 100644
index 0000000000..8b3c16a9a0
--- /dev/null
+++ b/frontend/stylesheets/forms.scss
@@ -0,0 +1,4 @@
+.input-with-icon::placeholder {
+ color: #A8B1CD;
+ opacity: 1;
+}
diff --git a/assets/stylesheets/icons.css b/frontend/stylesheets/icons.scss
similarity index 100%
rename from assets/stylesheets/icons.css
rename to frontend/stylesheets/icons.scss
diff --git a/frontend/templates/react.tmpl b/frontend/templates/react.tmpl
index 185751cd75..84252d3469 100644
--- a/frontend/templates/react.tmpl
+++ b/frontend/templates/react.tmpl
@@ -2,8 +2,7 @@
-
-
+
Kolide
diff --git a/package.json b/package.json
index eeb1138081..734ebc3ad2 100644
--- a/package.json
+++ b/package.json
@@ -34,6 +34,7 @@
"jsdom": "^9.5.0",
"lodash": "^4.3.0",
"nock": "^8.0.0",
+ "node-sass": "^3.10.0",
"postcss-functions": "^2.1.0",
"postcss-loader": "^0.8.0",
"precss": "^1.4.0",
@@ -49,6 +50,7 @@
"redux-mock-store": "^1.2.0",
"redux-thunk": "^2.1.0",
"require-hacker": "^2.1.4",
+ "sass-loader": "^4.0.2",
"style-loader": "^0.13.0",
"stylus-loader": "1.5.1",
"url-loader": "^0.5.7",
diff --git a/webpack.config.js b/webpack.config.js
index c52d129216..13f0d493e4 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -6,8 +6,9 @@ var autoprefixer = require('autoprefixer');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var plugins = [
- new webpack.NoErrorsPlugin(),
- new webpack.optimize.DedupePlugin(),
+ new webpack.NoErrorsPlugin(),
+ new webpack.optimize.DedupePlugin(),
+ new ExtractTextPlugin("bundle.css", {allChunks: false})
];
if (process.env.NODE_ENV === 'production') {
@@ -39,6 +40,10 @@ var config = {
{test: /\.(png|gif)$/, loader: 'url-loader?name=[name]@[hash].[ext]&limit=6000'},
{test: /\.(pdf|ico|jpg|svg|eot|otf|woff|ttf|mp4|webm)$/, loader: 'file-loader?name=[name]@[hash].[ext]'},
{test: /\.json$/, loader: 'json-loader'},
+ {
+ test: /\.scss$/,
+ loader: ExtractTextPlugin.extract("style-loader", "css-loader!autoprefixer-loader!sass-loader")
+ },
{
test: /\.jsx?$/,
include: path.join(repo, 'frontend'),