Merge pull request #1 from DramaFever/v1

posting challenge v1
This commit is contained in:
Ryan Provost
2016-08-17 20:03:43 -04:00
committed by GitHub
15 changed files with 1038 additions and 1 deletions

View File

@@ -1 +1,50 @@
# front-end-coding-challenge
Front-End Coding Challenge
===
### Premise
Its not always easy to evaluate a candidates technical abilities. While we love writing tests here, we hate asking people to take them during an interview. More importantly, we hate asking people to “white-board” solutions.
We—as an industry—can do better. So, just how can we do better?
### Solution
We developed this coding challenge to help us better gauge your technical abilities. This challenge:
* can be completed on your own time
* where you are most comfortable
* on equipment youre accustomed to
* using the tools youre proficient with
Basically, you have access to all the things that allow you to work best.
We hope youll enjoy working through this challenge as much as weve enjoyed creating it for you.
### Guidelines
Because were awful developers, this project isnt quite ready to release. There are some broken pieces that wed like you to fix. To do that, youll need to:
1. Fork this project.
2. Fix any problems you find with it.
3. Open a PR with your changes.
4. You have 24-hours.
Our awesome design team provided the following images to demonstrate what the site should look like: http://imgur.com/a/dDuKc
### FAQ
**Q: What am I supposed to focus on?**
A: The entire project. There are problems with everything, its up to you to find them and fix them.
**Q: How do I know if Ive completed the challenge?**
A: You dont. But, thats because _we_ dont know either.
**Q: I cant get past X, what do I do?**
A: Google is your friend.
**Q: How long should this take?**
A: That really depends on you.
**Q: Can I rewrite this in React?**
A: While React is a very popular library today, all of our code is written in Angular and we'd like to see your competancy with our stack.

34
bower.json Normal file
View File

@@ -0,0 +1,34 @@
{
"name": "frontend-developer-challenge",
"description": "Sheesh. There's a lot wrong with this project.",
"main": "index.js",
"authors": [
"Ryan Provost"
],
"license": "ISC",
"keywords": [
"frontend",
"challenge"
],
"homepage": "https://github.com/rprovost/code-test-creation",
"private": true,
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
],
"dependencies": {
"angular": "^1.5.7",
"font-awesome": "fontawesome#^4.6.3",
"weather-icons": "^2.0.10",
"express": "^4.14.0"
},
"devDependencies": {
"angular-mocks": "^1.5.7",
"hammerjs": "^2.0.8",
"d3": "^4.2.2",
"react": "^15.3.0"
}
}

144
gulpfile.js Normal file
View File

@@ -0,0 +1,144 @@
'use strict';
const gulp = require('gulp');
const pkg = require('./package.json');
const plugins = require('gulp-load-plugins')();
const browserSync = require('browser-sync').create();
const karmaServer = require('karma').Server;
gulp.task('build', ['build:html', 'build:js', 'build:json', 'build:sass', 'build:libs']);
gulp.task('watch2', ['build', 'watch:tests', 'watch:src', 'serve']);
/***
* Output a summary of unit test code coverage
**/
gulp.task('test:coverage', (done) => {
new KarmaServer({
configFile: __dirname + '/karma.conf.js',
singleRun: true,
reporters: ['coverage'],
coverageReporter: {
type: ['text-summary']
}
}, done).start();
return;
});
/***
* Generate an HTML report that details coverage
**/
gulp.task('test:report', (done) => {
new karmaServer({
configFile: __dirname + '/karma.conf.js',
singleRun: true,
reporters: ['coverage'],
coverageReporter: {
type: ['html']
}
}, done).start();
return;
});
/***
* Run the project with BrowserSync
**/
gulp.task('serve', () => {
browserSync.init({
server: {
baseDir: "./dist"
}
});
gulp.watch(['./dist/**/*.js', './dist/**/*.html'], browserSync.reload);
});
/***
* Reload or stream changes to browsers with BrowserSync
**/
gulp.task('watch:src', () => {
gulp.watch('./src/**/*.scss', ['build:sass']);
gulp.watch('./src/**/*.js', ['lint', 'build:js'], browserSync.reload);
gulp.watch('./src/**/*.json', ['build:json'], browserSync.reload);
gulp.watch('./src/**/*.html', ['build:html'], browserSync.reload);
});
/***
* Run test suite when affected source files change
**/
gulp.task('watch:tests',
function (done) {
new karmaServer({
configFile: __dirname + '/karma.conf.js',
singleRun: false,
reporters: ['progress'],
}, Done).start();
});
/***
* ESLint
**/
gulp.task(
'lint', () => {
let eslint = plugins.eslint;
gulp.src(['./src/**/*.js'])
.pipe(eslint())
.pipe(eslint.format())
.pipe(eslint.failAfterError());
});
/***
* Copy the HTML files into the DIST folder
**/
gulp.task('build:html', () => {
gulp.src('./src/**/*.html')
.pipe(gulp.dest('./dist'));
});
/***
* Copy the JSON files into the DIST folder
**/
gulp.task('build:json', () => {
gulp.src('./src/**/*.json')
.pipe(gulp.dest('./dist'));
});
/***
* Build all Sass files into a single css file
**/
gulp.task('build:sass', () => {
gulp.src('./src/app.scss')
.pipe(plugins.sass.sync())
.pipe(plugins.rename(pkg.name + '.css'))
.pipe(gulp.dest('./dist'))
.pipe(browserSync.stream());
});
/***
* Build all JS files into a single application file
**/
gulp.task('build:js', () => {
let filename = pkg.name + '.js';
let filenameMinified = pkg.name + '.min.js';
gulp.src(['!./src/**/*.spec.js', './src/**/*.js'])
// .pipe(plugins.plumber())
.pipe(plugins.concat(filename))
.pipe(gulp.dest('./dist'))
});
/***
* Copy all dependencies into the DIST folder
**/
gulp.task('build:libs', () => {
gulp.src('./bower.json')
.pipe(plugins.mainBowerFiles({
overrides: {
"font-awesome": { main: ['./css/font-awesome.css'] }
}
}))
.pipe(gulp.dest('./dist/libs'));
});

16
karma.conf.js Normal file
View File

@@ -0,0 +1,16 @@
module.exports = function(config) {
config.set({
browsers: ['Chrome'],
frameworks: ['jasmine'],
files: [
{pattern: 'src/**/*.json', included: false},
'node_modules/karma-read-json/karma-read-json.js',
'bower_components/angular/angular.js',
'bower_components/angular-mocks/angular-mocks.js',
'src/**/*.js'
],
preprocessors: {
'src/**/*.js': ['coverage']
},
});
};

45
package.json Normal file
View File

@@ -0,0 +1,45 @@
{
"name": "frontend-developer-challenge",
"version": "1.0.0",
"description": "Sheesh. There's a lot wrong with this project.",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/rprovost/code-test-creation.git"
},
"keywords": [
"frontend",
"challenge"
],
"author": "Ryan Provost",
"license": "ISC",
"bugs": {
"url": "https://github.com/rprovost/code-test-creation/issues"
},
"homepage": "https://github.com/rprovost/code-test-creation#readme",
"devDependencies": {
"browser-sync": "^2.13.0",
"express": "^4.14.0",
"gulp": "^3.9.1",
"gulp-concat": "^2.6.0",
"gulp-eslint": "^3.0.1",
"gulp-load-plugins": "^1.2.4",
"gulp-main-bower-files": "^1.5.2",
"gulp-plumber": "^1.1.0",
"gulp-rename": "^1.2.2",
"gulp-sass": "^2.3.2",
"istanbul": "^0.4.4",
"jasmine-core": "^2.4.1",
"karma": "^1.1.1",
"karma-chrome-launcher": "^1.0.1",
"karma-coverage": "^1.1.1",
"karma-coverage-es6": "^0.2.7",
"karma-jasmine": "^1.0.2",
"karma-phantomjs-launcher": "^1.0.1",
"karma-read-json": "^1.1.0"
},
"dependencies": {}
}

68
src/app.js Normal file
View File

@@ -0,0 +1,68 @@
angular.module('weather', [])
.controller('forecast', ['$http', '$scope', function($http, $scope){
const _this = this;
let default_city = 'New York, NY';
// recall the existing city or display the default
$scope.name = $scope.name || default_city;
// holds the 48 conditions and their corresponding icons
_this.conditions = new Array(12);
/***
* there are 48 different condition codes that the api can return
* this method makes those conditions and their corresponding icon mapping
* available to the rest of the controller
**/
var GetConditionMap = function() {
var success = function(response) {
_this.conditions = response.data;
};
const error = function(response) {
};
$http.get('conditions.json').then(success, error);
}
/***
* this method is expected to set the forecast objects
**/
$scope.getWeather = function(city) {
var success = function(response) {
var data = response.data.query.results.channel;
$scope.location = data.location;
$scope.item = data.item;
};
let Error = function(response) {
};
$http.get(`http://query.yahooapis.com/v1/public/yql?q=select * from weather.forecast where woeid in (select woeid from geo.places(1) where text="${city}")&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys`)
.then(success, Error);
}
/***
* this method is expected to return the icon for the corresponding condition code
* from the codeToCondition map file
**/
$scope.getIcon = function(code) {
return _this.conditions.filter(condition => condition.code == code)[0].icon;
};
/***
* load the condition code map
* this maps the condition code returned from the api to the corresponding icon
*/
setTimeout(GetConditionMap,
5000);
/***
* load weather for the default city
*/
// $scope.getWeather(name);
}]);

4
src/app.scss Normal file
View File

@@ -0,0 +1,4 @@
@import "styles/colors";
@import "styles/page"
@import "styles/menu";
@import "styles/weather";

116
src/app.spec.js Normal file
View File

@@ -0,0 +1,116 @@
// testing controller
describe('The weather app', function() {
var $httpBackend,
$scope,
;
// Set up the module
beforeEach(module('weather'));
beforeEach(inject(function($injector) {
$httpBackend = $injector.get('$httpBackend');
$scope = $injector.get('$rootScope');
var $controller = $injector.get('$controller');
createController = function() {
return $controller('forecast', {'$scope' : $scope });
};
}));
afterEach(function() {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});
describe('condition map', function(){
beforeEach(function(){
});
it('should throw an error when the condition map cannot be loaded.', function(){
$httpBackend.whenGET(/conditions/).respond(200, {});
$httpBackend.whenGET(/query.yahooapis.com/).respond(200, readJSON('./src/forecast.json'));
var controller = createController();
expect(controller.conditions).not.toBe(undefined);
expect( controller.conditions.length ).toBe(0);
expect(controller.conditions.length).toBe(0);
expect(controller.conditions[1]).toBe(undefined);
});
it('should load all known conditions.', function(){
$httpBackend.whenGET(/conditions/).respond(200, readJSON('./src/conditions.json'));
$httpBackend.whenGET(/query.yahooapis.com/).respond(200, readJSON('./src/forecast.json'));
var controller = createController();
expect(controller.conditions).not.toBe(undefined);
expect(controller.conditions.length).toBe(0);
$httpBackend.flush();
expect(controller.conditions.length).toBe(49);
expect(controller.conditions[1].code).toBe(1);
expect(controller.conditions[1].icon).toBe('wi-storm-showers');
});
});
describe('with condition map successfully loaded', function() {
beforeEach(function(){
});
it('should gracefully handle a weather forecast that cannot be loaded.', function() {
$httpBackend.whenGET(/query.yahooapis.com/).respond(500, {});
var controller = createController();
$httpBackend.flush() ;
expect($scope.item).toBe(undefined);
expect($scope.location).toBe(undefined);
});
it('should load a weather forecast for a default location.', function() {
$httpBackend.whenGET(/query.yahooapis.com/).respond(200, readJSON('./src/forecast.json'));
var controller = createController();
expect($scope.item).toBe(undefined);
expect($scope.location).toBe(undefined);
$httpBackend.flush();
expect( $scope.item ).not.toBe(undefined);
expect($scope.location).not.toBe(undefined);
expect($scope.location.city).toBe('New York');
// expect($scope.item.condition.code).toBe('29');
});
});
describe('with condition map and forecast successfully loaded', function() {
beforeEach(function(){
$httpBackend.whenGET(/conditions/).respond(200, readJSON('./src/conditions.json'));
$httpBackend.whenGET(/query.yahooapis.com/).respond(readJSON('./src/forecast.json'));
var controller = createController();
$httpBackend.flush();
});
it('should provide an icon for the provided weather code.', function(){
var icon = $scope.getIcon('29');
expect(icon).toBe('wi-night-partly-cloudy');
});
});
});

51
src/conditions.json Normal file
View File

@@ -0,0 +1,51 @@
[
{ "code": 0, "icon": "wi-tornado", "text": "tornado" },
{ "code": 1, "icon": "wi-storm-showers", "text": "tropical storm" },
{ "code": 2, "icon": "wi-hurricane", "text": "hurricane" },
{ "code": 3, "icon": "wi-thunderstorm", "text": "severe thunderstorms" },
{ "code": 4, "icon": "wi-day-sunny", "text": "thunderstorms" },
{ "code": 5, "icon": "wi-sleet", "text": "mixed rain and snow" },
{ "code": 6, "icon": "wi-sleet", "text": "mixed rain and sleet" },
{ "code": 7, "icon": "wi-sleet", "text": "mixed snow and sleet" },
{ "code": 8, "icon": "wi-rain-mix", "text": "freezing drizzle" },
{ "code": 9, "icon": "wi-rain", "text": "drizzle" },
{ "code": 10, "icon": "wi-rain-mix", "text": "freezing rain" },
{ "code": 11, "icon": "wi-showers", "text": "showers" },
{ "code": 12, "icon": "wi-showers", "text": "showers" },
{ "code": 13, "icon": "wi-snow", "text": "snow flurries" },
{ "code": 14, "icon": "wi-snow", "text": "light snow showers" },
{ "code": 15, "icon": "wi-snow", "text": "blowing snow" },
{ "code": 16, "icon": "wi-snow", "text": "snow" },
{ "code": 17, "icon": "wi-hail", "text": "hail" },
{ "code": 18, "icon": "wi-sleet", "text": "sleet" },
{ "code": 19, "icon": "wi-dust", "text": "dust" },
{ "code": 20, "icon": "wi-fog", "text": "foggy" },
{ "code": 21, "icon": "wi-day-haze", "text": "haze" },
{ "code": 22, "icon": "wi-smoke", "text": "smoky" },
{ "code": 23, "icon": "wi-day-windy", "text": "blustery" },
{ "code": 24, "icon": "wi-day-windy", "text": "windy" },
{ "code": 25, "icon": "wi-thermometer-exterior", "text": "cold" },
{ "code": 26, "icon": "wi-cloudy", "text": "cloudy" },
{ "code": 27, "icon": "wi-night-cloudy", "text": "mostly cloudy (night)" },
{ "code": 28, "icon": "wi-day-cloudy", "text": "mostly cloudy (day)" },
{ "code": 29, "icon": "wi-night-partly-cloudy", "text": "partly cloudy (night)" },
{ "code": 30, "icon": "wi-day-cloudy", "text": "partly cloudy (day)" },
{ "code": 31, "icon": "wi-night-clear", "text": "clear (night)" },
{ "code": 32, "icon": "wi-day-sunny", "text": "sunny" },
{ "code": 33, "icon": "", "text": "fair (night)" },
{ "code": 34, "icon": "", "text": "fair (day)" },
{ "code": 35, "icon": "wi-day-rain-mix", "text": "mixed rain and hail" },
{ "code": 36, "icon": "wi-hot", "text": "hot" },
{ "code": 37, "icon": "wi-thunderstorm", "text": "isolated thunderstorms" },
{ "code": 38, "icon": "wi-thunderstorm", "text": "scattered thunderstorms" },
{ "code": 39, "icon": "wi-thunderstorm", "text": "scattered thunderstorms" },
{ "code": 40, "icon": "wi-thunderstorm", "text": "scattered showers" },
{ "code": 41, "icon": "wi-snow", "text": "heavy snow" },
{ "code": 42, "icon": "wi-snow", "text": "scattered snow showers" },
{ "code": 43, "icon": "wi-snow", "text": "heavy snow" },
{ "code": 44, "icon": "wi-cloud", "text": "partly cloudy" },
{ "code": 45, "icon": "wi-storm-showers", "text": "thundershowers" },
{ "code": 46, "icon": "wi-snow", "text": "snow showers" },
{ "code": 47, "icon": "wi-thunderstorm", "text": "isolated thundershowers" },
{ "code": 3200, "icon": "wi-na", "text": "not available" }
]

138
src/forecast.json Normal file
View File

@@ -0,0 +1,138 @@
{
"query": {
"count": 1,
"created": "2016-07-13T02:37:36Z",
"lang": "en-US",
"results": {
"channel": {
"units": {
"distance": "mi",
"pressure": "in",
"speed": "mph",
"temperature": "F"
},
"title": "Yahoo! Weather - New York, NY, US",
"link": "http://us.rd.yahoo.com/dailynews/rss/weather/Country__Country/*https://weather.yahoo.com/country/state/city-2459115/",
"description": "Yahoo! Weather for New York, NY, US",
"language": "en-us",
"lastBuildDate": "Tue, 12 Jul 2016 10:37 PM EDT",
"ttl": "60",
"location": {
"city": "New York",
"country": "United States",
"region": " NY"
},
"wind": {
"chill": "75",
"direction": "180",
"speed": "22"
},
"atmosphere": {
"humidity": "73",
"pressure": "1016.0",
"rising": "0",
"visibility": "16.1"
},
"astronomy": {
"sunrise": "5:36 am",
"sunset": "8:27 pm"
},
"image": {
"title": "Yahoo! Weather",
"width": "142",
"height": "18",
"link": "http://weather.yahoo.com",
"url": "http://l.yimg.com/a/i/brand/purplelogo//uh/us/news-wea.gif"
},
"item": {
"title": "Conditions for New York, NY, US at 09:00 PM EDT",
"lat": "40.71455",
"long": "-74.007118",
"link": "http://us.rd.yahoo.com/dailynews/rss/weather/Country__Country/*https://weather.yahoo.com/country/state/city-2459115/",
"pubDate": "Tue, 12 Jul 2016 09:00 PM EDT",
"condition": {
"code": "29",
"date": "Tue, 12 Jul 2016 09:00 PM EDT",
"temp": "75",
"text": "Partly Cloudy"
},
"forecast": [{
"code": "30",
"date": "12 Jul 2016",
"day": "Tue",
"high": "81",
"low": "69",
"text": "Partly Cloudy"
}, {
"code": "47",
"date": "13 Jul 2016",
"day": "Wed",
"high": "83",
"low": "71",
"text": "Scattered Thunderstorms"
}, {
"code": "4",
"date": "14 Jul 2016",
"day": "Thu",
"high": "85",
"low": "74",
"text": "Thunderstorms"
}, {
"code": "4",
"date": "15 Jul 2016",
"day": "Fri",
"high": "92",
"low": "77",
"text": "Thunderstorms"
}, {
"code": "30",
"date": "16 Jul 2016",
"day": "Sat",
"high": "85",
"low": "75",
"text": "Partly Cloudy"
}, {
"code": "30",
"date": "17 Jul 2016",
"day": "Sun",
"high": "87",
"low": "75",
"text": "Partly Cloudy"
}, {
"code": "4",
"date": "18 Jul 2016",
"day": "Mon",
"high": "85",
"low": "74",
"text": "Thunderstorms"
}, {
"code": "4",
"date": "19 Jul 2016",
"day": "Tue",
"high": "85",
"low": "74",
"text": "Thunderstorms"
}, {
"code": "4",
"date": "20 Jul 2016",
"day": "Wed",
"high": "84",
"low": "73",
"text": "Thunderstorms"
}, {
"code": "30",
"date": "21 Jul 2016",
"day": "Thu",
"high": "84",
"low": "73",
"text": "Partly Cloudy"
}],
"description": "<![CDATA[<img src=\"http://l.yimg.com/a/i/us/we/52/29.gif\"/>\n<BR />\n<b>Current Conditions:</b>\n<BR />Partly Cloudy\n<BR />\n<BR />\n<b>Forecast:</b>\n<BR /> Tue - Partly Cloudy. High: 81Low: 69\n<BR /> Wed - Scattered Thunderstorms. High: 83Low: 71\n<BR /> Thu - Thunderstorms. High: 85Low: 74\n<BR /> Fri - Thunderstorms. High: 92Low: 77\n<BR /> Sat - Partly Cloudy. High: 85Low: 75\n<BR />\n<BR />\n<a href=\"http://us.rd.yahoo.com/dailynews/rss/weather/Country__Country/*https://weather.yahoo.com/country/state/city-2459115/\">Full Forecast at Yahoo! Weather</a>\n<BR />\n<BR />\n(provided by <a href=\"http://www.weather.com\" >The Weather Channel</a>)\n<BR />\n]]>",
"guid": {
"isPermaLink": "false"
}
}
}
}
}
}

76
src/index.html Normal file
View File

@@ -0,0 +1,76 @@
<!DOCTYPE html>
<html ng-app="weather">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Weather or Not</title>
<link rel="stylesheet" href="./libs/weather-icons/css/weather-icons.css">
<link rel="stylesheet" href="./libs/font-awesome/css/font-awesome.css">
<link rel="stylesheet" href="//fonts.googleapis.com/icon?family=Material+Icons">
<link rel="stylesheet" href="frontend-developer-challenge.css">
<script src="./libs/angular/angular.js"></script>
<script src="frontend-developer-challenge.js"></script>
</head>
<body ng-controller="forecast" ng-class="theme">
<div class="menu" ng-class="{'open': showMenu}">
<div class="tab" ng-click="showMenu == !showMenu">
<i class="material-icons open">menu</i>
<i class="material-icons close">close</i>
</div>
<h1>Select a City</h2>
<form name="city" ng-submit="getWeather(name); showMenu = false;">
<input ng-model="name" autocomplete="off" onfocus="this.select();" ng-class="theme" required>
<div ng-messages="city.name.$error" ng-show="city.name.$dirty">
We can't find weather for you if you don't give us a city to lookup.
</div>
</form>
<h2>Theme</h1>
<ul class="theme">
<li class="Color mojo" ng-click="theme='mojo'">&nbsp;</li>
<li class="color governor-bay" ng-click="theme='governor-bay'"></li>
<li class="color bluewood" ng-click="theme='bluewood'"></li>
<li class="color fire-bush" ng-click="theme='fire-bush'"></li>
<li class="color thunder" ng-click="theme='thunder'"></li>
<li class="color burnt-sienna" ng-click="theme='burnt-sienna'"></li>
<li class="color wine-berry" ng-click="theme='wine-berries"></li>
<li class="color tom-thumb" ng-click="theme='tom-thumb'"></li>
<li class="color vistas" ng-click="theme='vista'"></li>
</ul>
</div>
<div class="weather">
<ul class="forecast">
<li class="day now">
<div class="icon">
<i class="wi" ng-class="getIcon(item.condition.code)"></i>
</div>
<div class="temp">{{item.condition.temp}}<i class="wi wi-celsius"></i></div>
<div class="name">Now</div>
<div class="text">{{ item.condition.text }}</div>
</li>
<li class="day future" ng-repeat="forecast in item.forecast | limitTo:4">
<div class="icon">
<i class="wi" ng-class="getIcon(forecast.code)"></i>
</div>
<div class="temp">
<span class="high"><span ng-bind="forecast.high">{{ forecast.high }}</span><i class="wi wi-degrees"></i></span>
<span class="low"><span ng-bind="forecast.low"></span><i class="wi wi-degrees"></i></span>
</div>
<div class="name" ng-bind="forecast"></div>
<div class="text" ng-bind="forecast.text"></div>
</li>
</ul>
<div class="city">"{{ location.city }}, {{ location.region }}</div>
</div>
</body>
</html>

11
src/styles/colors.scss Normal file
View File

@@ -0,0 +1,11 @@
// define theme colors
$mojo: rgb(195, 77, 64);
$governor-bay: rgb(66,66,186);
$bluewood: rgb(46, 60,86);
$fire-bush: rgb(229, 156, 47);
$burnt-sienna: rgb(234,114, 76);
$wine-berry: rgb(92, 37,51);
$tom-thumb: rgb(45, 68, 47);
$thunder: rgb(65, 47, 63);
$vista: rgb(141, 211, 151);
;

109
src/styles/menu.scss Normal file
View File

@@ -0,0 +1,109 @@
.menu {
background-color: rgba(255, 255, 255, 0.8);
height: 100%;
left: -20em;
min-width: 200px;
padding: 0 1em;
position: fixed;
transition: all .6s cubic-bezier(.9,0,.33,1) .2s;
width: 20em;
z-index: 1;
// styles for the hamburger
.tab {
position: absolute;
width: 50px;
height: 50px;
right: -50px;
cursor: pointer;
padding: 7px 9px;
border-left: 0;
border-radius: 10px 10px 10px 10px;
transition: right .6s cubic-bezier(.9,0,.33,1) .2s;
i {
position: absolute;
top: 7px;
left: 9px;
transition: opacity .6s cubic-bezier(.9,0,.33,1) .2s;
font-size: 36px;
}
.open {
color: rgba(255, 255, 255, 0.4);
opacity: 1;
}
.close {
color: rgba(0, 0, 0, 0.4);
opacity: 0;
}
}
input {
background-color: rgba(0,0,0,0);
border-bottom-color: rgba($mojo, .6);
border-width: 0 0 2px 0;
font-size: 1.25em;
font-style: italic;
width: 250px;
text-transform: capitalize;
transition: border-bottom-color .6s ease;
&.mojo {border-bottom-color: rgba($mojo, .6);}
&.governor-bay {border-bottom-color: rgba($governor-bay, .6);}
&.bluewood {border-bottom-color: rgba($bluewood, .6);}
&.fire-bush {border-bottom-color: rgba($fire-bush, .6);}
&.burnt-sienna {border-bottom-color: rgba($burnt-sienna, .6);}
&.wine-berry {border-bottom-color: rgba($wine-berry, .6);}
&.tom-thumb {border-bottom-color: rgba($tom-thumb, .6);}
&.thunder {border-bottom-color: rgba($thunder, .6);}
&.vista {border-bottom-color: rgba($vista, .6);}
}
// styles for the theme selector
.theme{
border-radius: 15px;
overflow: hidden;
width: 75%;
margin: auto;
padding: 0;
.color {
width: 33%;
margin: 1px;
height: 60px;
position: relative;
float: left;
cursor: move;
&:after {content: "\00a0";}
&.mojo {background: $mojo;}
&.governor-bay {background: $governor-bay;}
&.bluewood {background: $bluewood;}
&.fire-bush {background: $fire-bush;}
&.burnt-sienna {background: $burnt-sienna;}
&.wine-berry {background: $wine-berry;}
&.tom-thumb {background: $tom-thumb;}
&.thunder {background: $thunder;}
&.vista {background: $vista;}
}
}
// styles when menu is open
&.open {
left: 0;
box-shadow: 0 0 20px 10px rgba(27, 255, 34, 0.3);
.tab {
top: 25px;
right: 0px;
.open {opacity: 0;}
.close {opacity: 1;}
}
}
}

49
src/styles/page.scss Normal file
View File

@@ -0,0 +1,49 @@
// breakpoints
$tiny: 25em;
$small: 42em;
$medium: 75em;
$large: 90em;
$xlarge: 120em;
html {
height: 100%;
}
*:focus {outline: none;}
*,::after,::before {
box-sizing: inherit
}
li {list-style-type: none;}
html {
font-size: 100%;
height: 100%
}
body {
background: $mojo;
box-sizing: border-box;
font-family: 'HelveticaNeue-UltraLight', 'Helvetica Neue UltraLight', 'Helvetica Neue', 'Open-Light', sans-serif;
font-weight: 400;
line-height: 1.5;
margin: 0;
padding: 0;
height: auto;
min-height: 100vh;
position: relative;
transition: background-color .6s ease;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
&.mojo {background: $mojo;}
&.governor-bay {background: $governor-bay;}
&.bluewood {background: $mojo;}
&.fire-bush {background: $fire-bush;}
&.burnt-sienna {background: $burnt-sienna;}
&.wine-berry {background: $wine-berry;}
&.tom-thumb {background: $tom-thumb;}
&.thunder {background: $thunder;}
&.vista {background: $vista;}
}

127
src/styles/weather.scss Normal file
View File

@@ -0,0 +1,127 @@
.weather {
padding: 15% 10% 0;
position: relative;
.city {
COLORS: rgba(255, 255, 255, 0.4);
font-weight: bold;
font-size: .8em;
width: 80%;
margin: 5% auto;
TEXT-align: center;
}
.forecast {
width: 80%;
margin: auto;
padding: 0;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
.day {
display: flex;
flex-wrap: nowrap;
justify-content: center;
align-items: center;
padding: 0;
margin: 0;
width: 20%;
min-width: 150px;
text-align: center;
color: rgba(255, 255, 255, 0.7);
div {
width: 100%;
}
.icon {
font-size: 3em;
Padding-Bottom: 25px;
}
.temp {
font-size: 2em;
font-weight: bold;
.low {
opacity: .4;
font-size: .8em;
}
}
.name {
font-size: 1.5em;
}
.text {
white-space: nowrap;
}
&.now {
.icon {
font-size: 8em;
padding-bottom: 0;
}
.name {
font-size: 2.5em;
}
.text {
font-size: 1.5em;
}
}
}
}
@media screen and (max-width: $medium) {
padding: 5vh;
.forecast {
width: 100%;
.day {
line-height: 1.25;
&:nth-child(4) {
padding-top: 15px;
}
&.now {
width: 100%;
padding-bottom: 40px;
.icon{
line-height: 1.5;
}
}
}
}
}
@media screen and (max-width: $small) and (max-width: 600px) {
.forecast {
.day {
padding-bottom: 40px;
line-height: 1.25;
&:nth-child(3) {
padding-bottom: 75px;
}
&.future {
width: 50%;
}
}
}
}
@media screen and (max-width: $tiny) {
.forecast {
.day {
&.future {
width: 100%;
}
}
}
}
}