@ -0,0 +1,3 @@ |
|||||
|
MySQL |
||||
|
USR dslak |
||||
|
PWD D5l4kMyPwd! |
@ -0,0 +1 @@ |
|||||
|
rsync -rlvz --delete --exclude "tmp" --exclude "config.php" -e "ssh -p2222" ./api/ dslak@2.233.91.82:/var/www/weather/api/ |
@ -0,0 +1,16 @@ |
|||||
|
# This file is used by the build system to adjust CSS and JS output to support the specified browsers below. |
||||
|
# For additional information regarding the format and rule options, please see: |
||||
|
# https://github.com/browserslist/browserslist#queries |
||||
|
|
||||
|
# For the full list of supported browsers by the Angular framework, please see: |
||||
|
# https://angular.io/guide/browser-support |
||||
|
|
||||
|
# You can see what browsers were selected by your queries by running: |
||||
|
# npx browserslist |
||||
|
|
||||
|
last 1 Chrome version |
||||
|
last 1 Firefox version |
||||
|
last 2 Edge major versions |
||||
|
last 2 Safari major versions |
||||
|
last 2 iOS major versions |
||||
|
Firefox ESR |
@ -0,0 +1,16 @@ |
|||||
|
# Editor configuration, see https://editorconfig.org |
||||
|
root = true |
||||
|
|
||||
|
[*] |
||||
|
charset = utf-8 |
||||
|
indent_style = space |
||||
|
indent_size = 2 |
||||
|
insert_final_newline = true |
||||
|
trim_trailing_whitespace = true |
||||
|
|
||||
|
[*.ts] |
||||
|
quote_type = single |
||||
|
|
||||
|
[*.md] |
||||
|
max_line_length = off |
||||
|
trim_trailing_whitespace = false |
@ -0,0 +1,42 @@ |
|||||
|
# See http://help.github.com/ignore-files/ for more about ignoring files. |
||||
|
|
||||
|
# Compiled output |
||||
|
/dist |
||||
|
/tmp |
||||
|
/out-tsc |
||||
|
/bazel-out |
||||
|
|
||||
|
# Node |
||||
|
/node_modules |
||||
|
npm-debug.log |
||||
|
yarn-error.log |
||||
|
|
||||
|
# IDEs and editors |
||||
|
.idea/ |
||||
|
.project |
||||
|
.classpath |
||||
|
.c9/ |
||||
|
*.launch |
||||
|
.settings/ |
||||
|
*.sublime-workspace |
||||
|
|
||||
|
# Visual Studio Code |
||||
|
.vscode/* |
||||
|
!.vscode/settings.json |
||||
|
!.vscode/tasks.json |
||||
|
!.vscode/launch.json |
||||
|
!.vscode/extensions.json |
||||
|
.history/* |
||||
|
|
||||
|
# Miscellaneous |
||||
|
/.angular/cache |
||||
|
.sass-cache/ |
||||
|
/connect.lock |
||||
|
/coverage |
||||
|
/libpeerconnection.log |
||||
|
testem.log |
||||
|
/typings |
||||
|
|
||||
|
# System files |
||||
|
.DS_Store |
||||
|
Thumbs.db |
@ -0,0 +1,4 @@ |
|||||
|
{ |
||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846 |
||||
|
"recommendations": ["angular.ng-template"] |
||||
|
} |
@ -0,0 +1,20 @@ |
|||||
|
{ |
||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 |
||||
|
"version": "0.2.0", |
||||
|
"configurations": [ |
||||
|
{ |
||||
|
"name": "ng serve", |
||||
|
"type": "pwa-chrome", |
||||
|
"request": "launch", |
||||
|
"preLaunchTask": "npm: start", |
||||
|
"url": "http://localhost:4200/" |
||||
|
}, |
||||
|
{ |
||||
|
"name": "ng test", |
||||
|
"type": "chrome", |
||||
|
"request": "launch", |
||||
|
"preLaunchTask": "npm: test", |
||||
|
"url": "http://localhost:9876/debug.html" |
||||
|
} |
||||
|
] |
||||
|
} |
@ -0,0 +1,42 @@ |
|||||
|
{ |
||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558 |
||||
|
"version": "2.0.0", |
||||
|
"tasks": [ |
||||
|
{ |
||||
|
"type": "npm", |
||||
|
"script": "start", |
||||
|
"isBackground": true, |
||||
|
"problemMatcher": { |
||||
|
"owner": "typescript", |
||||
|
"pattern": "$tsc", |
||||
|
"background": { |
||||
|
"activeOnStart": true, |
||||
|
"beginsPattern": { |
||||
|
"regexp": "(.*?)" |
||||
|
}, |
||||
|
"endsPattern": { |
||||
|
"regexp": "bundle generation complete" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"type": "npm", |
||||
|
"script": "test", |
||||
|
"isBackground": true, |
||||
|
"problemMatcher": { |
||||
|
"owner": "typescript", |
||||
|
"pattern": "$tsc", |
||||
|
"background": { |
||||
|
"activeOnStart": true, |
||||
|
"beginsPattern": { |
||||
|
"regexp": "(.*?)" |
||||
|
}, |
||||
|
"endsPattern": { |
||||
|
"regexp": "bundle generation complete" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
] |
||||
|
} |
@ -0,0 +1,27 @@ |
|||||
|
# Weather |
||||
|
|
||||
|
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 14.2.1. |
||||
|
|
||||
|
## Development server |
||||
|
|
||||
|
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The application will automatically reload if you change any of the source files. |
||||
|
|
||||
|
## Code scaffolding |
||||
|
|
||||
|
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. |
||||
|
|
||||
|
## Build |
||||
|
|
||||
|
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. |
||||
|
|
||||
|
## Running unit tests |
||||
|
|
||||
|
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). |
||||
|
|
||||
|
## Running end-to-end tests |
||||
|
|
||||
|
Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities. |
||||
|
|
||||
|
## Further help |
||||
|
|
||||
|
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page. |
@ -0,0 +1,119 @@ |
|||||
|
{ |
||||
|
"$schema": "./node_modules/@angular/cli/lib/config/schema.json", |
||||
|
"version": 1, |
||||
|
"newProjectRoot": "projects", |
||||
|
"projects": { |
||||
|
"weather": { |
||||
|
"projectType": "application", |
||||
|
"schematics": { |
||||
|
"@schematics/angular:component": { |
||||
|
"style": "scss" |
||||
|
} |
||||
|
}, |
||||
|
"root": "", |
||||
|
"sourceRoot": "src", |
||||
|
"prefix": "app", |
||||
|
"architect": { |
||||
|
"build": { |
||||
|
"builder": "@angular-devkit/build-angular:browser", |
||||
|
"options": { |
||||
|
"outputPath": "dist/weather", |
||||
|
"index": "src/index.html", |
||||
|
"main": "src/main.ts", |
||||
|
"polyfills": "src/polyfills.ts", |
||||
|
"tsConfig": "tsconfig.app.json", |
||||
|
"inlineStyleLanguage": "scss", |
||||
|
"assets": [ |
||||
|
"src/favicon.ico", |
||||
|
"src/assets", |
||||
|
"src/.htaccess", |
||||
|
"src/api", |
||||
|
"src/uploads" |
||||
|
], |
||||
|
"styles": [ |
||||
|
"src/assets/scss/main.scss" |
||||
|
], |
||||
|
"scripts": [] |
||||
|
}, |
||||
|
"configurations": { |
||||
|
"production": { |
||||
|
"budgets": [ |
||||
|
{ |
||||
|
"type": "initial", |
||||
|
"maximumWarning": "8mb", |
||||
|
"maximumError": "10mb" |
||||
|
}, |
||||
|
{ |
||||
|
"type": "anyComponentStyle", |
||||
|
"maximumWarning": "80kb", |
||||
|
"maximumError": "100kb" |
||||
|
} |
||||
|
], |
||||
|
"fileReplacements": [ |
||||
|
{ |
||||
|
"replace": "src/environments/environment.ts", |
||||
|
"with": "src/environments/environment.prod.ts" |
||||
|
} |
||||
|
], |
||||
|
"outputHashing": "all" |
||||
|
}, |
||||
|
"development": { |
||||
|
"buildOptimizer": false, |
||||
|
"optimization": false, |
||||
|
"vendorChunk": true, |
||||
|
"extractLicenses": false, |
||||
|
"sourceMap": true, |
||||
|
"namedChunks": true |
||||
|
} |
||||
|
}, |
||||
|
"defaultConfiguration": "production" |
||||
|
}, |
||||
|
"serve": { |
||||
|
"builder": "@angular-devkit/build-angular:dev-server", |
||||
|
"options": { |
||||
|
"browserTarget": "weather:build", |
||||
|
"proxyConfig": "proxy.conf.json" |
||||
|
}, |
||||
|
"configurations": { |
||||
|
"production": { |
||||
|
"browserTarget": "weather:build:production", |
||||
|
"proxyConfig": "proxy.conf.prod.json" |
||||
|
}, |
||||
|
"development": { |
||||
|
"browserTarget": "weather:build:development", |
||||
|
"proxyConfig": "proxy.conf.json" |
||||
|
} |
||||
|
}, |
||||
|
"defaultConfiguration": "development" |
||||
|
}, |
||||
|
"extract-i18n": { |
||||
|
"builder": "@angular-devkit/build-angular:extract-i18n", |
||||
|
"options": { |
||||
|
"browserTarget": "weather:build" |
||||
|
} |
||||
|
}, |
||||
|
"test": { |
||||
|
"builder": "@angular-devkit/build-angular:karma", |
||||
|
"options": { |
||||
|
"main": "src/test.ts", |
||||
|
"polyfills": "src/polyfills.ts", |
||||
|
"tsConfig": "tsconfig.spec.json", |
||||
|
"karmaConfig": "karma.conf.js", |
||||
|
"inlineStyleLanguage": "scss", |
||||
|
"assets": [ |
||||
|
"src/favicon.ico", |
||||
|
"src/assets", |
||||
|
"src/.htaccess", |
||||
|
"src/api", |
||||
|
"src/uploads" |
||||
|
], |
||||
|
"styles": [ |
||||
|
"src/assets/scss/main.scss" |
||||
|
], |
||||
|
"scripts": [] |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,44 @@ |
|||||
|
// Karma configuration file, see link for more information
|
||||
|
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||
|
|
||||
|
module.exports = function (config) { |
||||
|
config.set({ |
||||
|
basePath: '', |
||||
|
frameworks: ['jasmine', '@angular-devkit/build-angular'], |
||||
|
plugins: [ |
||||
|
require('karma-jasmine'), |
||||
|
require('karma-chrome-launcher'), |
||||
|
require('karma-jasmine-html-reporter'), |
||||
|
require('karma-coverage'), |
||||
|
require('@angular-devkit/build-angular/plugins/karma') |
||||
|
], |
||||
|
client: { |
||||
|
jasmine: { |
||||
|
// you can add configuration options for Jasmine here
|
||||
|
// the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
|
||||
|
// for example, you can disable the random execution with `random: false`
|
||||
|
// or set a specific seed with `seed: 4321`
|
||||
|
}, |
||||
|
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
||||
|
}, |
||||
|
jasmineHtmlReporter: { |
||||
|
suppressAll: true // removes the duplicated traces
|
||||
|
}, |
||||
|
coverageReporter: { |
||||
|
dir: require('path').join(__dirname, './coverage/weather'), |
||||
|
subdir: '.', |
||||
|
reporters: [ |
||||
|
{ type: 'html' }, |
||||
|
{ type: 'text-summary' } |
||||
|
] |
||||
|
}, |
||||
|
reporters: ['progress', 'kjhtml'], |
||||
|
port: 9876, |
||||
|
colors: true, |
||||
|
logLevel: config.LOG_INFO, |
||||
|
autoWatch: true, |
||||
|
browsers: ['Chrome'], |
||||
|
singleRun: false, |
||||
|
restartOnFileChange: true |
||||
|
}); |
||||
|
}; |
@ -0,0 +1,40 @@ |
|||||
|
{ |
||||
|
"name": "weather", |
||||
|
"version": "0.0.0", |
||||
|
"scripts": { |
||||
|
"dev": "export NODE_OPTIONS=--openssl-legacy-provider && ng serve", |
||||
|
"prod": "export NODE_OPTIONS=--openssl-legacy-provider && ng build --configuration production --base-href /weather/", |
||||
|
"deploy": "yarn prod && sh deploy.sh" |
||||
|
}, |
||||
|
"private": true, |
||||
|
"dependencies": { |
||||
|
"@angular/animations": "^14.0.0", |
||||
|
"@angular/common": "^14.0.0", |
||||
|
"@angular/compiler": "^14.0.0", |
||||
|
"@angular/core": "^14.0.0", |
||||
|
"@angular/forms": "^14.0.0", |
||||
|
"@angular/platform-browser": "^14.0.0", |
||||
|
"@angular/platform-browser-dynamic": "^14.0.0", |
||||
|
"@angular/router": "^14.0.0", |
||||
|
"@popperjs/core": "^2.11.6", |
||||
|
"bootstrap": "^5.2.3", |
||||
|
"echarts": "^5.4.1", |
||||
|
"hamburgers": "^1.2.1", |
||||
|
"rxjs": "~7.5.0", |
||||
|
"tslib": "^2.3.0", |
||||
|
"zone.js": "~0.11.4" |
||||
|
}, |
||||
|
"devDependencies": { |
||||
|
"@angular-devkit/build-angular": "^14.2.1", |
||||
|
"@angular/cli": "~14.2.1", |
||||
|
"@angular/compiler-cli": "^14.0.0", |
||||
|
"@types/jasmine": "~4.0.0", |
||||
|
"jasmine-core": "~4.3.0", |
||||
|
"karma": "~6.4.0", |
||||
|
"karma-chrome-launcher": "~3.1.0", |
||||
|
"karma-coverage": "~2.2.0", |
||||
|
"karma-jasmine": "~5.1.0", |
||||
|
"karma-jasmine-html-reporter": "~2.0.0", |
||||
|
"typescript": "~4.7.2" |
||||
|
} |
||||
|
} |
@ -0,0 +1,9 @@ |
|||||
|
|
||||
|
{ |
||||
|
"/api/*": { |
||||
|
"target": "http://weatherapi.local", |
||||
|
"secure": false, |
||||
|
"changeOrigin": true, |
||||
|
"logLevel": "debug" |
||||
|
} |
||||
|
} |
@ -0,0 +1,9 @@ |
|||||
|
|
||||
|
{ |
||||
|
"/api/*": { |
||||
|
"target": "http://2.233.91.82/weather/api", |
||||
|
"secure": false, |
||||
|
"changeOrigin": true, |
||||
|
"logLevel": "debug" |
||||
|
} |
||||
|
} |
@ -0,0 +1,3 @@ |
|||||
|
RewriteEngine On |
||||
|
RewriteCond %{REQUEST_FILENAME} !-f |
||||
|
RewriteRule ^([^\.]+)$ $1.php [NC,L] |
@ -0,0 +1,7 @@ |
|||||
|
<?php |
||||
|
|
||||
|
$GLOBALS['CONF']['DB']['HOST'] = 'localhost'; |
||||
|
$GLOBALS['CONF']['DB']['USER'] = 'root'; |
||||
|
$GLOBALS['CONF']['DB']['PASS'] = 'root'; |
||||
|
|
||||
|
?> |
@ -0,0 +1,33 @@ |
|||||
|
<?php |
||||
|
@include 'config.php'; |
||||
|
@include 'headers.php'; |
||||
|
|
||||
|
$conn = @mysqli_connect($CONF['DB']['HOST'], $CONF['DB']['USER'], $CONF['DB']['PASS'], 'weather')or die("CONNECTION ERROR"); |
||||
|
|
||||
|
$day = $_GET['day']; |
||||
|
|
||||
|
$q = mysqli_query($conn, "SELECT * FROM `data` WHERE `date` LIKE '$day%'"); |
||||
|
|
||||
|
if($q) { |
||||
|
|
||||
|
$list = array(); |
||||
|
|
||||
|
while($row = mysqli_fetch_assoc($q)) { |
||||
|
$list[] = $row; |
||||
|
} |
||||
|
|
||||
|
http_response_code(200); |
||||
|
echo json_encode(array( |
||||
|
"status" => 200, |
||||
|
"items" => $list |
||||
|
)); |
||||
|
|
||||
|
} else { |
||||
|
http_response_code(400); |
||||
|
echo json_encode(array( |
||||
|
"status" => 400, |
||||
|
"message" => "Error executing query" |
||||
|
)); |
||||
|
|
||||
|
} |
||||
|
?> |
@ -0,0 +1,9 @@ |
|||||
|
<?php |
||||
|
|
||||
|
header("Access-Control-Allow-Origin: *"); |
||||
|
header("Content-Type: application/json; charset=UTF-8"); |
||||
|
header("Access-Control-Allow-Methods: POST,GET"); |
||||
|
header("Access-Control-Max-Age: 3600"); |
||||
|
|
||||
|
?> |
||||
|
|
@ -0,0 +1,25 @@ |
|||||
|
<?php |
||||
|
@include 'config.php'; |
||||
|
@include 'headers.php'; |
||||
|
|
||||
|
$conn = @mysqli_connect($CONF['DB']['HOST'], $CONF['DB']['USER'], $CONF['DB']['PASS'], 'weather')or die("CONNECTION ERROR"); |
||||
|
|
||||
|
$data = explode('|',$_GET['data']); |
||||
|
|
||||
|
$query = "INSERT INTO `data` VALUES(NULL, NOW(), ".$data[0].", ".$data[1].", ".$data[2].", ".$data[3].", ".$data[4].")"; |
||||
|
|
||||
|
if(mysqli_query($conn, $query)) { |
||||
|
http_response_code(200); |
||||
|
echo json_encode(array( |
||||
|
"status" => 200, |
||||
|
"message" => "Data succesfully added" |
||||
|
)); |
||||
|
} else { |
||||
|
http_response_code(400); |
||||
|
echo json_encode(array( |
||||
|
"status" => 400, |
||||
|
"message" => "Error executing query".$query |
||||
|
)); |
||||
|
|
||||
|
} |
||||
|
?> |
@ -0,0 +1 @@ |
|||||
|
<p>app-layout works!</p> |
@ -0,0 +1,23 @@ |
|||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing'; |
||||
|
|
||||
|
import { AppLayoutComponent } from './app-layout.component'; |
||||
|
|
||||
|
describe('AppLayoutComponent', () => { |
||||
|
let component: AppLayoutComponent; |
||||
|
let fixture: ComponentFixture<AppLayoutComponent>; |
||||
|
|
||||
|
beforeEach(async () => { |
||||
|
await TestBed.configureTestingModule({ |
||||
|
declarations: [ AppLayoutComponent ] |
||||
|
}) |
||||
|
.compileComponents(); |
||||
|
|
||||
|
fixture = TestBed.createComponent(AppLayoutComponent); |
||||
|
component = fixture.componentInstance; |
||||
|
fixture.detectChanges(); |
||||
|
}); |
||||
|
|
||||
|
it('should create', () => { |
||||
|
expect(component).toBeTruthy(); |
||||
|
}); |
||||
|
}); |
@ -0,0 +1,15 @@ |
|||||
|
import { Component, OnInit } from '@angular/core'; |
||||
|
|
||||
|
@Component({ |
||||
|
selector: 'app-app-layout', |
||||
|
templateUrl: './app-layout.component.html', |
||||
|
styleUrls: ['./app-layout.component.scss'] |
||||
|
}) |
||||
|
export class AppLayoutComponent implements OnInit { |
||||
|
|
||||
|
constructor() { } |
||||
|
|
||||
|
ngOnInit(): void { |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,18 @@ |
|||||
|
<header class="header"> |
||||
|
<span class="title">{{title}}</span> |
||||
|
<div class="menu"> |
||||
|
<div class="hamburger hamburger--spin" [ngClass]="{'is-active': menuOpen}" (click)="toggleMenu()"> |
||||
|
<div class="hamburger-box"> |
||||
|
<div class="hamburger-inner"></div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="menu-items" [@slideInOut]="menuOpen ? 'open' : 'close'"> |
||||
|
<div class="item" (click)="toggleMenu()">Capaccio</div> |
||||
|
<div class="item" (click)="toggleMenu()">Pisciotta</div> |
||||
|
</div> |
||||
|
</header> |
||||
|
|
||||
|
<main class="main-content"> |
||||
|
<app-dashboard [day]="day"></app-dashboard> |
||||
|
</main> |
@ -0,0 +1,67 @@ |
|||||
|
@import "../assets/scss/variables"; |
||||
|
|
||||
|
.header { |
||||
|
position: fixed; |
||||
|
display: flex; |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
height: $header-height-mobile; |
||||
|
width: 100%; |
||||
|
background: $dark-gray; |
||||
|
background-color: rgb(32, 32, 32); |
||||
|
background-image: linear-gradient(45deg, $dark-gray 25%, transparent 25%, transparent 75%, $dark-gray 75%, $dark-gray), |
||||
|
linear-gradient(45deg, $dark-gray 25%, transparent 25%, transparent 75%, $dark-gray 75%, $dark-gray), |
||||
|
linear-gradient(to bottom, $black-alpha, $dark-gray); |
||||
|
background-size: 10px 10px, 10px 10px, 10px 5px; |
||||
|
background-position: 0px 0px, 5px 5px, 0px 0px; |
||||
|
|
||||
|
@media (min-width: map-get($grid-breakpoints, 'md')) { |
||||
|
height: $header-height; |
||||
|
} |
||||
|
|
||||
|
.title { |
||||
|
display: block; |
||||
|
padding: 0 50px; |
||||
|
font-family: $font-serif; |
||||
|
font-size: $font-30; |
||||
|
font-weight: bold; |
||||
|
color: $white-alpha; |
||||
|
margin: auto auto 15px auto; |
||||
|
text-shadow: 0 0 2px $black; |
||||
|
} |
||||
|
|
||||
|
.menu { |
||||
|
position: absolute; |
||||
|
top: 20px; |
||||
|
right: 20px; |
||||
|
height: $hamburger-layer-width; |
||||
|
width: $hamburger-layer-width; |
||||
|
overflow: visible; |
||||
|
} |
||||
|
|
||||
|
.menu-items { |
||||
|
position: absolute; |
||||
|
display: block; |
||||
|
width: 100%; |
||||
|
top: $header-height-mobile; |
||||
|
left: 0; |
||||
|
overflow: hidden; |
||||
|
|
||||
|
@media (min-width: map-get($grid-breakpoints, 'md')) { |
||||
|
top: $header-height; |
||||
|
} |
||||
|
|
||||
|
.item { |
||||
|
display: block; |
||||
|
background: $white; |
||||
|
padding: 20px; |
||||
|
font-size: $font-34; |
||||
|
font-family: $font-serif; |
||||
|
text-align: center; |
||||
|
text-transform: uppercase; |
||||
|
color: $dark-gray; |
||||
|
border-bottom: 1px dotted $black-alpha; |
||||
|
cursor: pointer; |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,31 @@ |
|||||
|
import { TestBed } from '@angular/core/testing'; |
||||
|
import { AppComponent } from './app.component'; |
||||
|
|
||||
|
describe('AppComponent', () => { |
||||
|
beforeEach(async () => { |
||||
|
await TestBed.configureTestingModule({ |
||||
|
declarations: [ |
||||
|
AppComponent |
||||
|
], |
||||
|
}).compileComponents(); |
||||
|
}); |
||||
|
|
||||
|
it('should create the app', () => { |
||||
|
const fixture = TestBed.createComponent(AppComponent); |
||||
|
const app = fixture.componentInstance; |
||||
|
expect(app).toBeTruthy(); |
||||
|
}); |
||||
|
|
||||
|
it(`should have as title 'weather'`, () => { |
||||
|
const fixture = TestBed.createComponent(AppComponent); |
||||
|
const app = fixture.componentInstance; |
||||
|
expect(app.title).toEqual('weather'); |
||||
|
}); |
||||
|
|
||||
|
it('should render title', () => { |
||||
|
const fixture = TestBed.createComponent(AppComponent); |
||||
|
fixture.detectChanges(); |
||||
|
const compiled = fixture.nativeElement as HTMLElement; |
||||
|
expect(compiled.querySelector('.content span')?.textContent).toContain('weather app is running!'); |
||||
|
}); |
||||
|
}); |
@ -0,0 +1,33 @@ |
|||||
|
import { Component } from '@angular/core' |
||||
|
import { trigger, state, style, animate, transition } from '@angular/animations' |
||||
|
|
||||
|
@Component({ |
||||
|
selector: 'app-root', |
||||
|
templateUrl: './app.component.html', |
||||
|
styleUrls: ['./app.component.scss'], |
||||
|
animations: [ |
||||
|
trigger('slideInOut', [ |
||||
|
state('close', style({ |
||||
|
opacity: '0', |
||||
|
height: '0px' |
||||
|
})), |
||||
|
state('open', style({ |
||||
|
opacity: '1', |
||||
|
height: '*' |
||||
|
})), |
||||
|
transition('close => open', animate('300ms ease-in-out')), |
||||
|
transition('open => close', animate('300ms ease-in-out')) |
||||
|
]) |
||||
|
] |
||||
|
}) |
||||
|
|
||||
|
export class AppComponent { |
||||
|
|
||||
|
public title: string = 'Dslak weather station' |
||||
|
public day: string = new Date().toISOString().substring(0,10) |
||||
|
public menuOpen: boolean = false |
||||
|
|
||||
|
toggleMenu(): void { |
||||
|
this.menuOpen = !this.menuOpen |
||||
|
} |
||||
|
} |
@ -0,0 +1,29 @@ |
|||||
|
import { NgModule } from '@angular/core'; |
||||
|
import { FormsModule } from '@angular/forms'; |
||||
|
import { BrowserModule } from '@angular/platform-browser'; |
||||
|
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; |
||||
|
import { HttpClientModule } from '@angular/common/http'; |
||||
|
import { environment } from '../environments/environment' |
||||
|
|
||||
|
import { AppComponent } from './app.component'; |
||||
|
import { AppLayoutComponent } from './app-layout/app-layout.component'; |
||||
|
import { GraphComponent } from './graph/graph.component'; |
||||
|
import { DashboardComponent } from './dashboard/dashboard.component'; |
||||
|
|
||||
|
@NgModule({ |
||||
|
declarations: [ |
||||
|
AppComponent, |
||||
|
AppLayoutComponent, |
||||
|
GraphComponent, |
||||
|
DashboardComponent |
||||
|
], |
||||
|
imports: [ |
||||
|
BrowserModule, |
||||
|
FormsModule, |
||||
|
BrowserAnimationsModule, |
||||
|
HttpClientModule |
||||
|
], |
||||
|
providers: [], |
||||
|
bootstrap: [AppComponent] |
||||
|
}) |
||||
|
export class AppModule { } |
@ -0,0 +1,2 @@ |
|||||
|
<p>dashboard works!</p> |
||||
|
{{day}} |
@ -0,0 +1,23 @@ |
|||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing'; |
||||
|
|
||||
|
import { DashboardComponent } from './dashboard.component'; |
||||
|
|
||||
|
describe('DashboardComponent', () => { |
||||
|
let component: DashboardComponent; |
||||
|
let fixture: ComponentFixture<DashboardComponent>; |
||||
|
|
||||
|
beforeEach(async () => { |
||||
|
await TestBed.configureTestingModule({ |
||||
|
declarations: [ DashboardComponent ] |
||||
|
}) |
||||
|
.compileComponents(); |
||||
|
|
||||
|
fixture = TestBed.createComponent(DashboardComponent); |
||||
|
component = fixture.componentInstance; |
||||
|
fixture.detectChanges(); |
||||
|
}); |
||||
|
|
||||
|
it('should create', () => { |
||||
|
expect(component).toBeTruthy(); |
||||
|
}); |
||||
|
}); |
@ -0,0 +1,18 @@ |
|||||
|
import { Component, OnInit, Input } from '@angular/core' |
||||
|
|
||||
|
@Component({ |
||||
|
selector: 'app-dashboard', |
||||
|
templateUrl: './dashboard.component.html', |
||||
|
styleUrls: ['./dashboard.component.scss'] |
||||
|
}) |
||||
|
|
||||
|
export class DashboardComponent implements OnInit { |
||||
|
|
||||
|
@Input() day: string = '' |
||||
|
|
||||
|
constructor() { } |
||||
|
|
||||
|
ngOnInit(): void { |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1 @@ |
|||||
|
<p>graph works!</p> |
@ -0,0 +1,23 @@ |
|||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing'; |
||||
|
|
||||
|
import { GraphComponent } from './graph.component'; |
||||
|
|
||||
|
describe('GraphComponent', () => { |
||||
|
let component: GraphComponent; |
||||
|
let fixture: ComponentFixture<GraphComponent>; |
||||
|
|
||||
|
beforeEach(async () => { |
||||
|
await TestBed.configureTestingModule({ |
||||
|
declarations: [ GraphComponent ] |
||||
|
}) |
||||
|
.compileComponents(); |
||||
|
|
||||
|
fixture = TestBed.createComponent(GraphComponent); |
||||
|
component = fixture.componentInstance; |
||||
|
fixture.detectChanges(); |
||||
|
}); |
||||
|
|
||||
|
it('should create', () => { |
||||
|
expect(component).toBeTruthy(); |
||||
|
}); |
||||
|
}); |
@ -0,0 +1,15 @@ |
|||||
|
import { Component, OnInit } from '@angular/core'; |
||||
|
|
||||
|
@Component({ |
||||
|
selector: 'app-graph', |
||||
|
templateUrl: './graph.component.html', |
||||
|
styleUrls: ['./graph.component.scss'] |
||||
|
}) |
||||
|
export class GraphComponent implements OnInit { |
||||
|
|
||||
|
constructor() { } |
||||
|
|
||||
|
ngOnInit(): void { |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,16 @@ |
|||||
|
import { TestBed } from '@angular/core/testing'; |
||||
|
|
||||
|
import { StationService } from './station.service'; |
||||
|
|
||||
|
describe('StationService', () => { |
||||
|
let service: StationService; |
||||
|
|
||||
|
beforeEach(() => { |
||||
|
TestBed.configureTestingModule({}); |
||||
|
service = TestBed.inject(StationService); |
||||
|
}); |
||||
|
|
||||
|
it('should be created', () => { |
||||
|
expect(service).toBeTruthy(); |
||||
|
}); |
||||
|
}); |
@ -0,0 +1,40 @@ |
|||||
|
import { Injectable } from '@angular/core' |
||||
|
import { HttpClient, HttpErrorResponse, HttpHeaders, HttpParams, HttpRequest } from '@angular/common/http' |
||||
|
import { Observable, Subject, throwError } from 'rxjs' |
||||
|
import { catchError, retry } from 'rxjs/operators' |
||||
|
import { environment } from '../environments/environment' |
||||
|
|
||||
|
@Injectable({ |
||||
|
providedIn: 'root' |
||||
|
}) |
||||
|
|
||||
|
export class StationService { |
||||
|
|
||||
|
private restApi = `${environment.API_URL}` |
||||
|
|
||||
|
constructor(private http: HttpClient) { |
||||
|
this.layout = null |
||||
|
} |
||||
|
|
||||
|
commonHeaders(): any { |
||||
|
return new HttpHeaders({ |
||||
|
//'Authorization': `Bearer ${sessionStorage.getItem('auth_token')}`
|
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
protected handleError(error: HttpErrorResponse) { |
||||
|
if(error.error instanceof ErrorEvent) { |
||||
|
console.error('An error occurred:', error.error.message) |
||||
|
} |
||||
|
return throwError(error) |
||||
|
} |
||||
|
|
||||
|
|
||||
|
getData(day: string): Observable<any> { |
||||
|
const apiUrl = `${this.restApi}/get_data?day=${day}`; |
||||
|
return this.http.get<any>(apiUrl, {headers: this.commonHeaders()}).pipe( |
||||
|
catchError(this.handleError) |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
} |
After Width: | Height: | Size: 35 KiB |
After Width: | Height: | Size: 510 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 523 B |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 351 B |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 5.9 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 4.1 KiB |
After Width: | Height: | Size: 4.5 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 5.3 KiB |
After Width: | Height: | Size: 756 B |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 4.1 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 3.1 KiB |
@ -0,0 +1,102 @@ |
|||||
|
|
||||
|
|
||||
|
input, |
||||
|
button, |
||||
|
select, |
||||
|
textarea { |
||||
|
border: none; |
||||
|
border-radius: $border-radius; |
||||
|
background: none; |
||||
|
appearance: none; |
||||
|
font-family: $font-sans; |
||||
|
font-size: $font-16; |
||||
|
resize: none; |
||||
|
&::-ms-clear { |
||||
|
display: none; |
||||
|
} |
||||
|
&:focus {outline:none;} |
||||
|
&::-moz-focus-inner {border:0;} |
||||
|
} |
||||
|
|
||||
|
input, |
||||
|
select, |
||||
|
textarea { |
||||
|
width: 100%; |
||||
|
box-sizing: border-box; |
||||
|
} |
||||
|
|
||||
|
input[type=text], |
||||
|
input[type=password]{ |
||||
|
color: $gray; |
||||
|
padding: 10px 20px; |
||||
|
text-align: left; |
||||
|
box-sizing: border-box; |
||||
|
&:focus::placeholder { |
||||
|
color: transparent; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
input[type="date"]::-webkit-inner-spin-button, |
||||
|
input[type="date"]::-webkit-calendar-picker-indicator { |
||||
|
display: none; |
||||
|
-webkit-appearance: none; |
||||
|
} |
||||
|
|
||||
|
.input-text { |
||||
|
border: 1px solid $gray; |
||||
|
padding: 10px 20px; |
||||
|
} |
||||
|
|
||||
|
.input-select { |
||||
|
width: 100%; |
||||
|
border: 1px solid $gray; |
||||
|
padding: 10px 20px; |
||||
|
color: $black; |
||||
|
border-radius: 2px; |
||||
|
background: $white; |
||||
|
background: url(/assets/images/icons/angle.svg); |
||||
|
background-position: right 10px top 15px; |
||||
|
background-repeat: no-repeat; |
||||
|
background-size: 14px; |
||||
|
cursor: pointer; |
||||
|
} |
||||
|
|
||||
|
.input-textarea { |
||||
|
border: 1px solid $gray; |
||||
|
padding: 10px; |
||||
|
width: 100%; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
.button { |
||||
|
position: relative; |
||||
|
border: none; |
||||
|
appearance: none; |
||||
|
background: $blue; |
||||
|
display: inline-block; |
||||
|
border-radius: 5px; |
||||
|
padding: 12px 30px; |
||||
|
text-align: center; |
||||
|
color: $white !important; |
||||
|
font-size: $font-20; |
||||
|
font-weight: 500; |
||||
|
transition: opacity .3s; |
||||
|
white-space: nowrap; |
||||
|
outline: none; |
||||
|
cursor: pointer; |
||||
|
|
||||
|
&:disabled { |
||||
|
opacity: 0.8; |
||||
|
} |
||||
|
|
||||
|
&.button-small { |
||||
|
padding: 6px 15px; |
||||
|
font-size: $font-14; |
||||
|
} |
||||
|
|
||||
|
&.button-white { |
||||
|
border: 1px solid $blue !important; |
||||
|
color: $blue !important; |
||||
|
background: $white !important; |
||||
|
} |
||||
|
} |
@ -0,0 +1,115 @@ |
|||||
|
@import url('https://fonts.googleapis.com/css2?family=Hind+Madurai:wght@300;400;500;600;700&family=Open+Sans:wght@300;400;500;600;700&display=swap'); |
||||
|
|
||||
|
html, |
||||
|
body { |
||||
|
font-family: $font-sans; |
||||
|
font-weight: normal; |
||||
|
margin: 0; |
||||
|
padding: 0; |
||||
|
width: 100%; |
||||
|
height: 100vh; |
||||
|
color: $black; |
||||
|
background: $white; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
h1,h2,h3,h4,h5 { |
||||
|
margin: 0; |
||||
|
} |
||||
|
|
||||
|
p { |
||||
|
margin: 0; |
||||
|
padding: 0; |
||||
|
} |
||||
|
|
||||
|
ul { |
||||
|
list-style: none; |
||||
|
padding: 0; |
||||
|
margin: 0; |
||||
|
} |
||||
|
|
||||
|
a, |
||||
|
input, |
||||
|
button { |
||||
|
text-decoration: none; |
||||
|
outline: none; |
||||
|
&:active, |
||||
|
&:visited, |
||||
|
&:hover, |
||||
|
&:focus{ |
||||
|
color: initial; |
||||
|
outline: none; |
||||
|
text-decoration: none; |
||||
|
opacity: 1; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.h-100 { |
||||
|
height: 100%; |
||||
|
} |
||||
|
|
||||
|
.w-100 { |
||||
|
width: 100%; |
||||
|
} |
||||
|
|
||||
|
.position-relative { |
||||
|
position: relative; |
||||
|
} |
||||
|
|
||||
|
.font-serif { |
||||
|
font-family: $font-serif; |
||||
|
} |
||||
|
|
||||
|
.font-sans { |
||||
|
font-family: $font-sans; |
||||
|
} |
||||
|
|
||||
|
.text-white { color: $white !important; } |
||||
|
.text-black { color: $black !important; } |
||||
|
.text-blue { color: $blue !important; } |
||||
|
|
||||
|
.text-center { |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
.text-right { |
||||
|
text-align: right; |
||||
|
} |
||||
|
|
||||
|
.text-left { |
||||
|
text-align: left; |
||||
|
} |
||||
|
|
||||
|
@each $bp in $grid-breakpoints { |
||||
|
$key: nth($bp, 1); |
||||
|
$value: nth($bp, 2); |
||||
|
|
||||
|
@media (min-width: $value) { |
||||
|
.text-#{$key}-center{ text-align: center; } |
||||
|
.text-#{$key}-left { text-align: left; } |
||||
|
.text-#{$key}-right { text-align: right; } |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
section { |
||||
|
padding: 20px 0; |
||||
|
} |
||||
|
|
||||
|
.container { |
||||
|
width: 100%; |
||||
|
margin: 0 auto; |
||||
|
padding: 0 !important; |
||||
|
} |
||||
|
|
||||
|
.main-content { |
||||
|
width: 100%; |
||||
|
min-height: calc(100vh - #{$header-height-mobile}); |
||||
|
padding-top: $header-height-mobile; |
||||
|
background: transparent; |
||||
|
overflow-x: hidden; |
||||
|
|
||||
|
@media (min-width: map-get($grid-breakpoints, 'md')) { |
||||
|
min-height: calc(100vh - #{$header-height}); |
||||
|
padding-top: $header-height; |
||||
|
} |
||||
|
} |
@ -0,0 +1,120 @@ |
|||||
|
@font-face { |
||||
|
font-family: 'icomoon'; |
||||
|
src: url('../fonts/icomoon.eot'); |
||||
|
src: url('../fonts/icomoon.eot#iefix') format('embedded-opentype'), |
||||
|
url('../fonts/icomoon.ttf') format('truetype'), |
||||
|
url('../fonts/icomoon.woff') format('woff'), |
||||
|
url('../fonts/icomoon.svg#icomoon') format('svg'); |
||||
|
font-weight: normal; |
||||
|
font-style: normal; |
||||
|
} |
||||
|
|
||||
|
[class^="icon-"], [class*=" icon-"] { |
||||
|
/* use !important to prevent issues with browser extensions that change fonts */ |
||||
|
font-family: 'icomoon' !important; |
||||
|
speak: none; |
||||
|
font-style: normal; |
||||
|
font-weight: normal; |
||||
|
font-variant: normal; |
||||
|
text-transform: none; |
||||
|
line-height: 1; |
||||
|
|
||||
|
/* Better Font Rendering =========== */ |
||||
|
-webkit-font-smoothing: antialiased; |
||||
|
-moz-osx-font-smoothing: grayscale; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
.icon-angle-right:before { |
||||
|
content: "\e900"; |
||||
|
} |
||||
|
.icon-angle-left:before { |
||||
|
content: "\e901"; |
||||
|
} |
||||
|
.icon-angle-down:before { |
||||
|
content: "\e902"; |
||||
|
} |
||||
|
.icon-angle-up:before { |
||||
|
content: "\e903"; |
||||
|
} |
||||
|
.icon-article:before { |
||||
|
content: "\e904"; |
||||
|
} |
||||
|
.icon-calendar:before { |
||||
|
content: "\e905"; |
||||
|
} |
||||
|
.icon-clock:before { |
||||
|
content: "\e906"; |
||||
|
} |
||||
|
.icon-dots:before { |
||||
|
content: "\e907"; |
||||
|
} |
||||
|
.icon-edit:before { |
||||
|
content: "\e908"; |
||||
|
} |
||||
|
.icon-facebook:before { |
||||
|
content: "\e909"; |
||||
|
} |
||||
|
.icon-food:before { |
||||
|
content: "\e90a"; |
||||
|
} |
||||
|
.icon-heart:before { |
||||
|
content: "\e90b"; |
||||
|
} |
||||
|
.icon-list:before { |
||||
|
content: "\e90c"; |
||||
|
} |
||||
|
.icon-medal:before { |
||||
|
content: "\e90d"; |
||||
|
} |
||||
|
.icon-message:before { |
||||
|
content: "\e90e"; |
||||
|
} |
||||
|
.icon-minus:before { |
||||
|
content: "\e90f"; |
||||
|
} |
||||
|
.icon-plus:before { |
||||
|
content: "\e910"; |
||||
|
} |
||||
|
.icon-close:before { |
||||
|
content: "\e918"; |
||||
|
} |
||||
|
.icon-question:before { |
||||
|
content: "\e911"; |
||||
|
} |
||||
|
.icon-rules:before { |
||||
|
content: "\e912"; |
||||
|
} |
||||
|
.icon-telegram:before { |
||||
|
content: "\e913"; |
||||
|
} |
||||
|
.icon-tricks:before { |
||||
|
content: "\e914"; |
||||
|
} |
||||
|
.icon-twitter:before { |
||||
|
content: "\e915"; |
||||
|
} |
||||
|
.icon-vaccine:before { |
||||
|
content: "\e916"; |
||||
|
} |
||||
|
.icon-whatsapp:before { |
||||
|
content: "\e917"; |
||||
|
} |
||||
|
.icon-trash:before { |
||||
|
content: "\e919"; |
||||
|
} |
||||
|
.icon-save:before { |
||||
|
content: "\e91a"; |
||||
|
} |
||||
|
.icon-checkmark:before { |
||||
|
content: "\e91b"; |
||||
|
} |
||||
|
.icon-download:before { |
||||
|
content: "\e91c"; |
||||
|
} |
||||
|
.icon-upload:before { |
||||
|
content: "\e91d"; |
||||
|
} |
||||
|
.icon-email:before { |
||||
|
content: "\e91e"; |
||||
|
} |
@ -0,0 +1,13 @@ |
|||||
|
@use 'sass:math'; |
||||
|
|
||||
|
@import "./variables"; |
||||
|
//@import "./mixins"; |
||||
|
|
||||
|
/* Libraries */ |
||||
|
@import "node_modules/bootstrap/scss/bootstrap-grid"; |
||||
|
@import "node_modules/hamburgers/_sass/hamburgers/hamburgers"; |
||||
|
|
||||
|
/* Global setup */ |
||||
|
@import "./global"; |
||||
|
@import "./forms"; |
||||
|
@import "./icons"; |
@ -0,0 +1,72 @@ |
|||||
|
@import "../../src/scss/variables.scss"; |
||||
|
|
||||
|
@mixin font-style ( $font: $font-sans, $style: 'regular', $size: $font-12 , $ls: normal ) { |
||||
|
font-family: $font; |
||||
|
font-size: $size; |
||||
|
letter-spacing: $ls; |
||||
|
|
||||
|
@if $style == 'regular' { |
||||
|
font-weight: 400; |
||||
|
} @else if $style == 'light' { |
||||
|
font-weight: 200; |
||||
|
} @else if $style == 'medium' { |
||||
|
font-weight: 500; |
||||
|
} @else if $style == 'semibold' { |
||||
|
font-weight: 600; |
||||
|
} @else if $style == 'bold' { |
||||
|
font-weight: 700; |
||||
|
} @else if $style == 'black' { |
||||
|
font-weight: 900; |
||||
|
} @else if $style == 'regular-italic' { |
||||
|
font-weight: 400; |
||||
|
font-style: italic; |
||||
|
} @else if $style == 'medium-italic' { |
||||
|
font-weight: 500; |
||||
|
font-style: italic; |
||||
|
} @else if $style == 'light-italic' { |
||||
|
font-weight: 200; |
||||
|
font-style: italic; |
||||
|
} @else if $style == 'semibold-italic' { |
||||
|
font-weight: 600; |
||||
|
font-style: italic; |
||||
|
} @else if $style == 'bold-italic' { |
||||
|
font-weight: 700; |
||||
|
font-style: italic; |
||||
|
} @else if $style == 'black-italic' { |
||||
|
font-weight: 900; |
||||
|
font-style: italic; |
||||
|
} @else { |
||||
|
font-weight: $style; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@mixin middle() { |
||||
|
position: absolute; |
||||
|
top: 50%; |
||||
|
transform: translateY(-50%); |
||||
|
} |
||||
|
|
||||
|
@mixin full-middle() { |
||||
|
position: absolute; |
||||
|
left: 50%; |
||||
|
top: 50%; |
||||
|
transform: translate(-50%, -50%); |
||||
|
} |
||||
|
|
||||
|
@mixin middle-right() { |
||||
|
position: absolute; |
||||
|
right: 0; |
||||
|
top: 50%; |
||||
|
transform: translateY(-50%); |
||||
|
} |
||||
|
|
||||
|
@mixin middle-left() { |
||||
|
position: absolute; |
||||
|
left: 0; |
||||
|
top: 50%; |
||||
|
transform: translateY(-50%); |
||||
|
} |
||||
|
|
||||
|
@mixin wrapper() { |
||||
|
max-width: 1000px; |
||||
|
} |
@ -0,0 +1,108 @@ |
|||||
|
// Bootstrap Settings |
||||
|
|
||||
|
$spacer: 20px; |
||||
|
$spacers: ( |
||||
|
0: 0, |
||||
|
1: ($spacer * .25), // 5px |
||||
|
2: ($spacer * .5), // 10px |
||||
|
3: $spacer, // 20px |
||||
|
4: ($spacer * 1.5), // 30px |
||||
|
5: ($spacer * 3), // 60px |
||||
|
6: ($spacer * 6), // 120px |
||||
|
); |
||||
|
|
||||
|
$grid-columns: 12; |
||||
|
$grid-gutter-width: 20px; |
||||
|
$grid-gutter-width-mobile: 5px; |
||||
|
|
||||
|
$grid-breakpoints: ( |
||||
|
xs: 0, // Mobile Portrait |
||||
|
sm: 768px, // Tablet Portrait |
||||
|
md: 1024px, // Tablet landscape/Small desktop |
||||
|
lg: 1280px, // Desktop |
||||
|
xl: 1600px, // Large desktop |
||||
|
); |
||||
|
|
||||
|
$container-max-widths: ( |
||||
|
sm: 1000px, |
||||
|
md: 1200px, |
||||
|
lg: 1420px, |
||||
|
xl: 1560px |
||||
|
); |
||||
|
|
||||
|
$font-serif: 'Hind Madurai'; |
||||
|
$font-sans: 'Open Sans'; |
||||
|
$icon: 'icomoon'; |
||||
|
|
||||
|
$header-height: 85px; |
||||
|
$header-height-mobile: 70px; |
||||
|
|
||||
|
$black: #000; |
||||
|
$white: #fff; |
||||
|
$gray: #858585; |
||||
|
$dark-gray: #2E2E2E; |
||||
|
$light-gray: #ccc; |
||||
|
$lighter-gray:#F2F5F8; |
||||
|
|
||||
|
$blue: #0F3250; |
||||
|
$orange: #E94E10; |
||||
|
$green: #8BC3A0; |
||||
|
|
||||
|
$white-alpha: rgba(255, 255, 255, 0.8); |
||||
|
$black-alpha: rgba(0, 0, 0, 0.8); |
||||
|
|
||||
|
$box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.1); |
||||
|
$border-radius: 3px; |
||||
|
|
||||
|
// Hamburgers |
||||
|
$hamburger-padding-x : 0px; |
||||
|
$hamburger-padding-y : 0px; |
||||
|
$hamburger-layer-width : 32px; |
||||
|
$hamburger-layer-height : 4px; |
||||
|
$hamburger-layer-spacing : 7px; |
||||
|
$hamburger-layer-color : $white; |
||||
|
$hamburger-layer-border-radius : 7px; |
||||
|
$hamburger-hover-opacity : 1; |
||||
|
$hamburger-active-layer-color : $hamburger-layer-color; |
||||
|
$hamburger-active-hover-opacity: $hamburger-hover-opacity; |
||||
|
|
||||
|
$slick-font-path: "../fonts/"; |
||||
|
$slick-font-family: $icon; |
||||
|
$slick-loader-path: "/images/"; |
||||
|
$slick-prev-character: "\e901"; |
||||
|
$slick-next-character: "\e900"; |
||||
|
$slick-dot-character: "\8226"; |
||||
|
$slick-arrow-color: $orange; |
||||
|
|
||||
|
/* Font-size variables PX/16 */ |
||||
|
$font-6: 0.375rem; /* 6px */ |
||||
|
$font-8: 0.5rem; /* 8px */ |
||||
|
$font-10: 0.625rem; /* 10px */ |
||||
|
$font-11: 0.687rem; /* 11px */ |
||||
|
$font-12: 0.75rem; /* 12px */ |
||||
|
$font-13: 0.812rem; /* 13px */ |
||||
|
$font-14: 0.875rem; /* 14px */ |
||||
|
$font-15: 0.937rem; /* 15px */ |
||||
|
$font-16: 1rem; /* 16px */ |
||||
|
$font-18: 1.125rem; /* 18px */ |
||||
|
$font-20: 1.25rem; /* 20px */ |
||||
|
$font-22: 1.375rem; /* 22px */ |
||||
|
$font-24: 1.5rem; /* 24px */ |
||||
|
$font-25: 1.56rem; /* 25px */ |
||||
|
$font-26: 1.625rem; /* 26px */ |
||||
|
$font-28: 1.75rem; /* 28px */ |
||||
|
$font-30: 1.875rem; /* 30px */ |
||||
|
$font-32: 2rem; /* 32px */ |
||||
|
$font-34: 2.125rem; /* 34px */ |
||||
|
$font-36: 2.25rem; /* 36px */ |
||||
|
$font-38: 2.375rem; /* 38px */ |
||||
|
$font-40: 2.5rem; /* 40px */ |
||||
|
$font-42: 2.625rem; /* 42px */ |
||||
|
$font-44: 2.75rem; /* 44px */ |
||||
|
$font-46: 2.875rem; /* 46px */ |
||||
|
$font-48: 3rem; /* 48px */ |
||||
|
$font-50: 3.125rem; /* 50px */ |
||||
|
$font-52: 3.25rem; /* 52px */ |
||||
|
$font-54: 3.375rem; /* 54px */ |
||||
|
$font-60: 3.75rem; /* 60px */ |
||||
|
$font-72: 4.5rem; /* 72px */ |
@ -0,0 +1,4 @@ |
|||||
|
export const environment = { |
||||
|
production: true, |
||||
|
REST_API: 'http://2.233.91.82/weather/api/' |
||||
|
} |
@ -0,0 +1,4 @@ |
|||||
|
export const environment = { |
||||
|
production: false, |
||||
|
REST_API: 'http://weatherapi.local' |
||||
|
} |
After Width: | Height: | Size: 948 B |
@ -0,0 +1,13 @@ |
|||||
|
<!doctype html> |
||||
|
<html lang="en"> |
||||
|
<head> |
||||
|
<meta charset="utf-8"> |
||||
|
<title>Weather</title> |
||||
|
<base href="/"> |
||||
|
<meta name="viewport" content="width=device-width, initial-scale=1"> |
||||
|
<link rel="icon" type="image/x-icon" href="favicon.ico"> |
||||
|
</head> |
||||
|
<body> |
||||
|
<app-root></app-root> |
||||
|
</body> |
||||
|
</html> |
@ -0,0 +1,12 @@ |
|||||
|
import { enableProdMode } from '@angular/core'; |
||||
|
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; |
||||
|
|
||||
|
import { AppModule } from './app/app.module'; |
||||
|
import { environment } from './environments/environment'; |
||||
|
|
||||
|
if (environment.production) { |
||||
|
enableProdMode(); |
||||
|
} |
||||
|
|
||||
|
platformBrowserDynamic().bootstrapModule(AppModule) |
||||
|
.catch(err => console.error(err)); |
@ -0,0 +1,53 @@ |
|||||
|
/** |
||||
|
* This file includes polyfills needed by Angular and is loaded before the app. |
||||
|
* You can add your own extra polyfills to this file. |
||||
|
* |
||||
|
* This file is divided into 2 sections: |
||||
|
* 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. |
||||
|
* 2. Application imports. Files imported after ZoneJS that should be loaded before your main |
||||
|
* file. |
||||
|
* |
||||
|
* The current setup is for so-called "evergreen" browsers; the last versions of browsers that |
||||
|
* automatically update themselves. This includes recent versions of Safari, Chrome (including |
||||
|
* Opera), Edge on the desktop, and iOS and Chrome on mobile. |
||||
|
* |
||||
|
* Learn more in https://angular.io/guide/browser-support
|
||||
|
*/ |
||||
|
|
||||
|
/*************************************************************************************************** |
||||
|
* BROWSER POLYFILLS |
||||
|
*/ |
||||
|
|
||||
|
/** |
||||
|
* By default, zone.js will patch all possible macroTask and DomEvents |
||||
|
* user can disable parts of macroTask/DomEvents patch by setting following flags |
||||
|
* because those flags need to be set before `zone.js` being loaded, and webpack |
||||
|
* will put import in the top of bundle, so user need to create a separate file |
||||
|
* in this directory (for example: zone-flags.ts), and put the following flags |
||||
|
* into that file, and then add the following code before importing zone.js. |
||||
|
* import './zone-flags'; |
||||
|
* |
||||
|
* The flags allowed in zone-flags.ts are listed here. |
||||
|
* |
||||
|
* The following flags will work for all browsers. |
||||
|
* |
||||
|
* (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
|
||||
|
* (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
|
||||
|
* (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
|
||||
|
* |
||||
|
* in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js |
||||
|
* with the following flag, it will bypass `zone.js` patch for IE/Edge |
||||
|
* |
||||
|
* (window as any).__Zone_enable_cross_context_check = true; |
||||
|
* |
||||
|
*/ |
||||
|
|
||||
|
/*************************************************************************************************** |
||||
|
* Zone JS is required by default for Angular itself. |
||||
|
*/ |
||||
|
import 'zone.js'; // Included with Angular CLI.
|
||||
|
|
||||
|
|
||||
|
/*************************************************************************************************** |
||||
|
* APPLICATION IMPORTS |
||||
|
*/ |
@ -0,0 +1,26 @@ |
|||||
|
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||
|
|
||||
|
import 'zone.js/testing'; |
||||
|
import { getTestBed } from '@angular/core/testing'; |
||||
|
import { |
||||
|
BrowserDynamicTestingModule, |
||||
|
platformBrowserDynamicTesting |
||||
|
} from '@angular/platform-browser-dynamic/testing'; |
||||
|
|
||||
|
declare const require: { |
||||
|
context(path: string, deep?: boolean, filter?: RegExp): { |
||||
|
<T>(id: string): T; |
||||
|
keys(): string[]; |
||||
|
}; |
||||
|
}; |
||||
|
|
||||
|
// First, initialize the Angular testing environment.
|
||||
|
getTestBed().initTestEnvironment( |
||||
|
BrowserDynamicTestingModule, |
||||
|
platformBrowserDynamicTesting(), |
||||
|
); |
||||
|
|
||||
|
// Then we find all the tests.
|
||||
|
const context = require.context('./', true, /\.spec\.ts$/); |
||||
|
// And load the modules.
|
||||
|
context.keys().forEach(context); |
@ -0,0 +1,15 @@ |
|||||
|
/* To learn more about this file see: https://angular.io/config/tsconfig. */ |
||||
|
{ |
||||
|
"extends": "./tsconfig.json", |
||||
|
"compilerOptions": { |
||||
|
"outDir": "./out-tsc/app", |
||||
|
"types": [] |
||||
|
}, |
||||
|
"files": [ |
||||
|
"src/main.ts", |
||||
|
"src/polyfills.ts" |
||||
|
], |
||||
|
"include": [ |
||||
|
"src/**/*.d.ts" |
||||
|
] |
||||
|
} |
@ -0,0 +1,32 @@ |
|||||
|
/* To learn more about this file see: https://angular.io/config/tsconfig. */ |
||||
|
{ |
||||
|
"compileOnSave": false, |
||||
|
"compilerOptions": { |
||||
|
"baseUrl": "./", |
||||
|
"outDir": "./dist/out-tsc", |
||||
|
"forceConsistentCasingInFileNames": true, |
||||
|
"strict": true, |
||||
|
"noImplicitOverride": true, |
||||
|
"noPropertyAccessFromIndexSignature": true, |
||||
|
"noImplicitReturns": true, |
||||
|
"noFallthroughCasesInSwitch": true, |
||||
|
"sourceMap": true, |
||||
|
"declaration": false, |
||||
|
"downlevelIteration": true, |
||||
|
"experimentalDecorators": true, |
||||
|
"moduleResolution": "node", |
||||
|
"importHelpers": true, |
||||
|
"target": "es2020", |
||||
|
"module": "es2020", |
||||
|
"lib": [ |
||||
|
"es2020", |
||||
|
"dom" |
||||
|
] |
||||
|
}, |
||||
|
"angularCompilerOptions": { |
||||
|
"enableI18nLegacyMessageIdFormat": false, |
||||
|
"strictInjectionParameters": true, |
||||
|
"strictInputAccessModifiers": true, |
||||
|
"strictTemplates": true |
||||
|
} |
||||
|
} |
@ -0,0 +1,18 @@ |
|||||
|
/* To learn more about this file see: https://angular.io/config/tsconfig. */ |
||||
|
{ |
||||
|
"extends": "./tsconfig.json", |
||||
|
"compilerOptions": { |
||||
|
"outDir": "./out-tsc/spec", |
||||
|
"types": [ |
||||
|
"jasmine" |
||||
|
] |
||||
|
}, |
||||
|
"files": [ |
||||
|
"src/test.ts", |
||||
|
"src/polyfills.ts" |
||||
|
], |
||||
|
"include": [ |
||||
|
"src/**/*.spec.ts", |
||||
|
"src/**/*.d.ts" |
||||
|
] |
||||
|
} |