├── .eslintignore
├── .deployment
├── src
├── lib
│ ├── .deployment
│ └── DateTime.js
├── styles
│ ├── components
│ │ ├── _header.scss
│ │ ├── _display.scss
│ │ └── _panel.scss
│ ├── _base.scss
│ ├── _settings.scss
│ └── app.scss
├── favicon.ico
├── index.js
├── components
│ ├── App.js
│ ├── Header.js
│ ├── Display.js
│ ├── Panel.js
│ └── Clock.js
└── index.html
├── manifests
├── service.yml
├── service-1.yml
├── service-2.yml
├── deployment-1.yml
├── deployment-2.yml
├── ingress.yml
├── ingress-1.yml
├── ingress-2.yml
└── deployment.yml
├── k8s
├── loadbalancer.yaml
├── acr.sh
└── deployment.yaml
├── other
├── default
└── vm-install.sh
├── .gitignore
├── Dockerfile
├── .eslintrc
├── azuredeploy.bicep
├── package.json
├── .github
└── workflows
│ └── main_reactclockjagord.yml
├── webpack.config.js
└── README.md
/.eslintignore:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.deployment:
--------------------------------------------------------------------------------
1 | [config]
2 | SCM_DO_BUILD_DURING_DEPLOYMENT=true
--------------------------------------------------------------------------------
/src/lib/.deployment:
--------------------------------------------------------------------------------
1 | [config]
2 | SCM_DO_BUILD_DURING_DEPLOYMENT=true
--------------------------------------------------------------------------------
/src/styles/components/_header.scss:
--------------------------------------------------------------------------------
1 | .header {
2 | height: 100px;
3 | }
--------------------------------------------------------------------------------
/src/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jaydestro/react-clock-basic/HEAD/src/favicon.ico
--------------------------------------------------------------------------------
/src/styles/_base.scss:
--------------------------------------------------------------------------------
1 | body {
2 | background-color: $smoke;
3 | font-family: $font-family;
4 | }
--------------------------------------------------------------------------------
/src/styles/_settings.scss:
--------------------------------------------------------------------------------
1 | $font-family: 'Open Sans', Helvetica, Arial, sans-serif;
2 | $smoke: whitesmoke;
--------------------------------------------------------------------------------
/src/styles/app.scss:
--------------------------------------------------------------------------------
1 | @import '_settings.scss';
2 | @import '_base.scss';
3 | @import './components/_display.scss';
4 | @import './components/_panel.scss';
5 | @import './components/_header.scss';
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import AppComponent from './components/App';
4 | import './styles/app.scss';
5 |
6 | ReactDOM.render(, document.getElementById('app'));
--------------------------------------------------------------------------------
/manifests/service.yml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: clockaks01
5 | spec:
6 | type: LoadBalancer
7 | selector:
8 | app: clockaks01
9 | ports:
10 | - protocol: TCP
11 | port: 80
12 | targetPort: 8080
13 |
--------------------------------------------------------------------------------
/k8s/loadbalancer.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: react-clock-basic-loadbalancer
5 | spec:
6 | type: LoadBalancer
7 | selector:
8 | app: react-clock-basic
9 | ports:
10 | - protocol: TCP
11 | port: 80
12 | targetPort: 8080
13 |
14 |
--------------------------------------------------------------------------------
/other/default:
--------------------------------------------------------------------------------
1 | server {
2 | listen 80;
3 | server_name example.com;
4 |
5 | location / {
6 | proxy_set_header X-Forwarded-For $remote_addr;
7 | proxy_set_header Host $http_host;
8 | proxy_pass "http://127.0.0.1:1337";
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/manifests/service-1.yml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: "jayaks2-c927"
5 | labels:
6 | app: "jayaks2-c927"
7 | spec:
8 | type: ClusterIP
9 | ports:
10 | - port: 8080
11 | targetPort: 8080
12 | protocol: TCP
13 | name: http
14 | selector:
15 | app: "jayaks2-c927"
--------------------------------------------------------------------------------
/manifests/service-2.yml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: "jayaksdemo-4ca2"
5 | labels:
6 | app: "jayaksdemo-4ca2"
7 | spec:
8 | type: ClusterIP
9 | ports:
10 | - port: 8080
11 | targetPort: 8080
12 | protocol: TCP
13 | name: http
14 | selector:
15 | app: "jayaksdemo-4ca2"
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 |
6 | # testing
7 | /coverage
8 |
9 | # production
10 | /build
11 | /public
12 |
13 | # misc
14 | .DS_Store
15 | .env.local
16 | .env.development.local
17 | .env.test.local
18 | .env.production.local
19 | /.vscode/**/*
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/manifests/deployment-1.yml:
--------------------------------------------------------------------------------
1 | apiVersion : apps/v1beta1
2 | kind: Deployment
3 | metadata:
4 | name: "jayaks2-c927"
5 | spec:
6 | replicas: 2
7 | template:
8 | metadata:
9 | labels:
10 | app: "jayaks2-c927"
11 | spec:
12 | containers:
13 | - name: "jayaks2-c927"
14 | image: "jayacr002.azurecr.io/jayaks2"
15 | ports:
16 | - containerPort: 8080
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12
2 |
3 | # Create app directory
4 | WORKDIR /usr/src/app
5 |
6 | # Install app dependencies
7 | # A wildcard is used to ensure both package.json AND package-lock.json are copied
8 | # where available (npm@5+)
9 | COPY package*.json ./
10 |
11 | RUN npm install
12 | # If you are building your code for production
13 | # RUN npm install --only=production
14 |
15 | # Bundle app source
16 | COPY . .
17 |
18 | EXPOSE 8080
19 | CMD [ "npm", "start" ]
20 |
--------------------------------------------------------------------------------
/manifests/deployment-2.yml:
--------------------------------------------------------------------------------
1 | apiVersion : apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: "jayaksdemo-4ca2"
5 | spec:
6 | replicas: 2
7 | selector:
8 | matchLabels:
9 | app: "jayaksdemo-4ca2"
10 | template:
11 | metadata:
12 | labels:
13 | app: "jayaksdemo-4ca2"
14 | spec:
15 | containers:
16 | - name: "jayaksdemo-4ca2"
17 | image: "jayacrdemo.azurecr.io/jayaksdemo"
18 | ports:
19 | - containerPort: 8080
--------------------------------------------------------------------------------
/src/components/App.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import Clock from './Clock';
3 | import Header from './Header';
4 |
5 | export default class App extends Component {
6 |
7 | constructor() {
8 | super();
9 |
10 | this.state = {
11 | title: 'React Clock'
12 | };
13 | }
14 |
15 | render() {
16 | return (
17 |
18 |
19 |
20 |
21 | );
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/manifests/ingress.yml:
--------------------------------------------------------------------------------
1 | apiVersion: extensions/v1beta1
2 | kind: Ingress
3 | metadata:
4 | name: "clockaks01"
5 | labels:
6 | app: "clockaks01"
7 | annotations:
8 | kubernetes.io/ingress.class: addon-http-application-routing
9 | spec:
10 | rules:
11 | - host: clockaks01d3f1-clockaks01.b9c65ff5ed3a47ef88be.eastus.aksapp.io
12 | http:
13 | paths:
14 | - path: /
15 | backend:
16 | serviceName: "clockaks01"
17 | servicePort: 8080
--------------------------------------------------------------------------------
/manifests/ingress-1.yml:
--------------------------------------------------------------------------------
1 | apiVersion: extensions/v1beta1
2 | kind: Ingress
3 | metadata:
4 | name: "jayaks2-c927"
5 | labels:
6 | app: "jayaks2-c927"
7 | annotations:
8 | kubernetes.io/ingress.class: addon-http-application-routing
9 | spec:
10 | rules:
11 | - host: jayaks210cf-jayaks2-c927.86b44fad5c574b39b67a.eastus.aksapp.io
12 | http:
13 | paths:
14 | - path: /
15 | backend:
16 | serviceName: "jayaks2-c927"
17 | servicePort: 8080
--------------------------------------------------------------------------------
/manifests/ingress-2.yml:
--------------------------------------------------------------------------------
1 | apiVersion: extensions/v1beta1
2 | kind: Ingress
3 | metadata:
4 | name: "jayaksdemo-4ca2"
5 | labels:
6 | app: "jayaksdemo-4ca2"
7 | annotations:
8 | kubernetes.io/ingress.class: addon-http-application-routing
9 | spec:
10 | rules:
11 | - host: jayaksdemo9cfa-jayaksdemo-4ca2.7566743ebff34eb6b579.eastus.aksapp.io
12 | http:
13 | paths:
14 | - path: /
15 | backend:
16 | serviceName: "jayaksdemo-4ca2"
17 | servicePort: 8080
--------------------------------------------------------------------------------
/k8s/acr.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | AKS_RESOURCE_GROUP=
4 | AKS_CLUSTER_NAME=
5 | ACR_RESOURCE_GROUP=
6 | ACR_NAME=
7 |
8 | # Get the id of the service principal configured for AKS
9 | CLIENT_ID=$(az aks show --resource-group $AKS_RESOURCE_GROUP --name $AKS_CLUSTER_NAME --query "servicePrincipalProfile.clientId" --output tsv)
10 |
11 | # Get the ACR registry resource id
12 | ACR_ID=$(az acr show --name $ACR_NAME --resource-group $ACR_RESOURCE_GROUP --query "id" --output tsv)
13 |
14 | # Create role assignment
15 | az role assignment create --assignee $CLIENT_ID --role acrpull --scope $ACR_ID
16 |
--------------------------------------------------------------------------------
/src/components/Header.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 |
4 | const Header = (props) => (
5 |
13 | );
14 |
15 | Header.defaultProps = {
16 | title: 'Title'
17 | };
18 |
19 | Header.propTypes = {
20 | title: PropTypes.string
21 | };
22 |
23 | export default Header;
--------------------------------------------------------------------------------
/src/styles/components/_display.scss:
--------------------------------------------------------------------------------
1 | $display-background-color: #000000;
2 | $display-border-color: #32363E;
3 | $display-color: #0dff00;
4 |
5 | .display {
6 | align-items: center;
7 | background-color: $display-background-color;
8 | border: 1rem solid $display-border-color;
9 | border-radius: 50%;
10 | display: flex;
11 | flex-direction: column;
12 | height: 14rem;
13 | justify-content: center;
14 | margin: 1rem auto;
15 | width: 14rem;
16 | }
17 |
18 | .display-date {
19 | color: $display-color;
20 | font-size: 14px;
21 | font-weight: 300;
22 | }
23 |
24 | .display-time {
25 | color: $display-color;
26 | font-size: 42px;
27 | font-weight: 600;
28 | }
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "parser": "babel-eslint",
3 | "env": {
4 | "browser": true,
5 | "commonjs": true,
6 | "es6": true,
7 | "node": true
8 | },
9 | "extends": [ "eslint:recommended", "plugin:react/recommended" ],
10 | "parserOptions": {
11 | "ecmaVersion": 6,
12 | "ecmaFeatures": {
13 | "jsx": true
14 | },
15 | "sourceType": "module"
16 | },
17 | "plugins": [
18 | "react"
19 | ],
20 | "rules": {
21 | "no-console": "off",
22 | "indent": [
23 | "error",
24 | 4
25 | ],
26 | "quotes": [
27 | "error",
28 | "single"
29 | ],
30 | "semi": [
31 | "error",
32 | "always"
33 | ]
34 | }
35 | }
--------------------------------------------------------------------------------
/k8s/deployment.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: react-clock-basic
5 | spec:
6 | selector:
7 | matchLabels:
8 | app: react-clock-basic
9 | replicas: 3
10 | template:
11 | metadata:
12 | labels:
13 | app: react-clock-basic
14 | spec:
15 | containers:
16 | - name: react-clock-basic
17 | image: <>.azurecr.io/react-clock-basic:v1
18 | imagePullPolicy: Always
19 | readinessProbe:
20 | httpGet:
21 | port: 8080
22 | path: /
23 | livenessProbe:
24 | httpGet:
25 | port: 8080
26 | path: /
27 | resources:
28 | requests:
29 | memory: "128Mi"
30 | cpu: "100m"
31 | limits:
32 | memory: "256Mi"
33 | cpu: "500m"
34 |
--------------------------------------------------------------------------------
/src/components/Display.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import DateTime from '../lib/DateTime';
4 |
5 | const Display = (props) => (
6 |
7 |
8 |
9 |
10 |
{DateTime.toTimeString(props.date)}
11 | { props.isDateVisible &&
{DateTime.toDateString(props.date)}
}
12 |
13 |
14 |
15 |
16 | );
17 |
18 | Display.defaultProps = {
19 | date: new Date(),
20 | isDateVisible: true
21 | };
22 |
23 | Display.propTypes = {
24 | date: PropTypes.object,
25 | isDateVisible: PropTypes.bool
26 | };
27 |
28 | export default Display;
--------------------------------------------------------------------------------
/manifests/deployment.yml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: jayaks2
5 | spec:
6 | selector:
7 | matchLabels:
8 | app: jayacr002
9 | replicas: 3
10 | template:
11 | metadata:
12 | labels:
13 | app: jayaks2
14 | spec:
15 | containers:
16 | - name: jayacr002
17 | image: "jayacr002.azurecr.io/jayaks2:v1"
18 | imagePullPolicy: Always
19 | readinessProbe:
20 | httpGet:
21 | port: 8080
22 | path: /
23 | livenessProbe:
24 | httpGet:
25 | port: 8080
26 | path: /
27 | resources:
28 | requests:
29 | memory: "128Mi"
30 | cpu: "100m"
31 | limits:
32 | memory: "256Mi"
33 | cpu: "500m"
34 |
--------------------------------------------------------------------------------
/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | React Clock
9 |
10 |
11 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/components/Panel.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 |
4 | const Panel = (props) => {
5 | return (
6 |
7 |
8 |
9 |
10 |
14 |
17 |
18 |
19 |
20 |
21 | );
22 | };
23 |
24 | Panel.defaultProps = {
25 | dateOn: true,
26 | toggleDate: () => {},
27 | };
28 |
29 | Panel.propTypes = {
30 | dateOn: PropTypes.bool,
31 | toggleDate: PropTypes.func
32 | };
33 |
34 | export default Panel;
--------------------------------------------------------------------------------
/src/components/Clock.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import Display from './Display';
3 | import Panel from './Panel';
4 |
5 | class Clock extends Component {
6 |
7 | constructor() {
8 | super();
9 |
10 | this.state = {
11 | date: new Date(),
12 | isDateVisible: true
13 | };
14 |
15 | this.toggleDate = this.toggleDate.bind(this);
16 | }
17 |
18 | componentDidMount() {
19 | this.startTime();
20 | }
21 |
22 | componentWillUnmount() {
23 | clearInterval(this.timer);
24 | }
25 |
26 | startTime() {
27 | this.timer = setInterval(() => {
28 | this.setState(() => ({ date: new Date()}));
29 | }, 1000);
30 | }
31 |
32 | toggleDate() {
33 | this.setState((prevState) => ({ isDateVisible: !prevState.isDateVisible}));
34 | }
35 |
36 | render() {
37 | return (
38 |
42 | );
43 | }
44 | }
45 |
46 | export default Clock;
--------------------------------------------------------------------------------
/azuredeploy.bicep:
--------------------------------------------------------------------------------
1 | param webAppName string = 'wtdx63txirdpdf' // Generate unique String for web app name
2 | param sku string = 'P1V2' // The SKU of App Service Plan
3 | param linuxFxVersion string = 'node|14-lts' // The runtime stack of web app
4 | param location string = resourceGroup().location // Location for all resources
5 | param repositoryUrl string = 'https://github.com/jaydestro/react-clock-basic'
6 | param branch string = 'main'
7 |
8 | var appServicePlanName = toLower('AppServicePlan-${webAppName}')
9 | var webSiteName = toLower('wapp-${webAppName}')
10 |
11 | resource appServicePlan 'Microsoft.Web/serverfarms@2020-06-01' = {
12 | name: appServicePlanName
13 | location: location
14 | properties: {
15 | reserved: true
16 | }
17 | sku: {
18 | name: sku
19 | }
20 | kind: 'linux'
21 | }
22 |
23 | resource appService 'Microsoft.Web/sites@2020-06-01' = {
24 | name: webSiteName
25 | location: location
26 | properties: {
27 | serverFarmId: appServicePlan.id
28 | siteConfig: {
29 | linuxFxVersion: linuxFxVersion
30 | }
31 | }
32 | }
33 |
34 | resource srcControls 'Microsoft.Web/sites/sourcecontrols@2021-01-01' = {
35 | name: '${appService.name}/web'
36 | properties: {
37 | repoUrl: repositoryUrl
38 | branch: branch
39 | isManualIntegration: true
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-clock-basic",
3 | "version": "1.0.0",
4 | "description": "A basic clock that displays the current date and time",
5 | "scripts": {
6 | "build": "webpack -d",
7 | "build:watch": "webpack --watch",
8 | "lint": "eslint .; exit 0",
9 | "lint:fix": "eslint . --fix",
10 | "serve": "webpack -d && live-server ./public",
11 | "serve:dev": "webpack-dev-server --open",
12 | "start": "npm run serve"
13 | },
14 | "repository": {
15 | "type": "git",
16 | "url": "git+https://github.com/drminnaar/react-clock-basic.git"
17 | },
18 | "license": "MIT",
19 | "babel": {
20 | "presets": [
21 | "env",
22 | "react"
23 | ]
24 | },
25 | "devDependencies": {
26 | "babel-cli": "^6.26.0",
27 | "babel-core": "^6.26.0",
28 | "babel-eslint": "^8.2.1",
29 | "babel-loader": "^7.1.2",
30 | "babel-preset-env": "^1.6.1",
31 | "babel-preset-react": "^6.24.1",
32 | "chai": "^4.2.0",
33 | "clean-webpack-plugin": "^0.1.18",
34 | "css-loader": "^0.28.9",
35 | "eslint": "^4.17.0",
36 | "eslint-loader": "^1.9.0",
37 | "eslint-plugin-react": "^7.6.1",
38 | "file-loader": "^1.1.6",
39 | "html-webpack-plugin": "^2.30.1",
40 | "live-server": "^1.2.0",
41 | "mocha": "^6.2.0",
42 | "node-sass": "^4.14.1",
43 | "sass-loader": "^6.0.6",
44 | "style-loader": "^0.20.1",
45 | "url-loader": "^0.6.2",
46 | "webpack": "^3.10.0",
47 | "webpack-dev-server": "^2.11.1"
48 | },
49 | "dependencies": {
50 | "react": "^16.2.0",
51 | "react-dom": "^16.2.0"
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/.github/workflows/main_reactclockjagord.yml:
--------------------------------------------------------------------------------
1 | # Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy
2 | # More GitHub Actions for Azure: https://github.com/Azure/actions
3 |
4 | name: Build and deploy Node.js app to Azure Web App - reactclockjagord
5 |
6 | on:
7 | push:
8 | branches:
9 | - main
10 | workflow_dispatch:
11 |
12 | jobs:
13 | build:
14 | runs-on: ubuntu-latest
15 |
16 | steps:
17 | - uses: actions/checkout@v2
18 |
19 | - name: Set up Node.js version
20 | uses: actions/setup-node@v1
21 | with:
22 | node-version: '12.x'
23 |
24 | - name: npm install, build, and test
25 | run: |
26 | npm install
27 | npm run build --if-present
28 | npm run test --if-present
29 |
30 | - name: Upload artifact for deployment job
31 | uses: actions/upload-artifact@v2
32 | with:
33 | name: node-app
34 | path: .
35 |
36 | deploy:
37 | runs-on: ubuntu-latest
38 | needs: build
39 | environment:
40 | name: 'Production'
41 | url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}
42 |
43 | steps:
44 | - name: Download artifact from build job
45 | uses: actions/download-artifact@v2
46 | with:
47 | name: node-app
48 |
49 | - name: 'Deploy to Azure Web App'
50 | id: deploy-to-webapp
51 | uses: azure/webapps-deploy@v2
52 | with:
53 | app-name: 'reactclockjagord'
54 | slot-name: 'Production'
55 | publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_6370EB6753504ACFB191C05F4539532C }}
56 | package: .
57 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const CleanWebPackPlugin = require('clean-webpack-plugin');
3 | const HtmlWebPackPlugin = require('html-webpack-plugin');
4 |
5 | module.exports = {
6 | entry: './src/index.js',
7 | output: {
8 | filename: 'bundle.js',
9 | path: path.resolve(__dirname, 'public')
10 | },
11 | module: {
12 | rules: [
13 | {
14 | enforce: 'pre',
15 | test: /\.js$/,
16 | loader: 'eslint-loader',
17 | options: {
18 | failOnWarning: true,
19 | failOnerror: true
20 | },
21 | exclude: /node_modules/
22 | },
23 | {
24 | test: /\.js$/,
25 | loader: 'babel-loader',
26 | exclude: /node_modules/
27 | },
28 | {
29 | test: /\.s?css$/,
30 | use: [ 'style-loader', 'css-loader', 'sass-loader' ],
31 | exclude: /node_modules/
32 | },
33 | {
34 | test: /\.svg$/,
35 | loader: 'url-loader',
36 | exclude: /node_modules/
37 | }
38 | ]
39 | },
40 | plugins: [
41 | new CleanWebPackPlugin([ 'public' ], { root: path.resolve(__dirname)}),
42 | new HtmlWebPackPlugin({
43 | template: './src/index.html',
44 | favicon: './src/favicon.ico',
45 | inject: false
46 | })
47 | ],
48 | devtool: 'cheap-module-eval-source-map',
49 | devServer: {
50 | contentBase: path.resolve(__dirname, 'public'),
51 | compress: true,
52 | port: 9000
53 | }
54 | };
--------------------------------------------------------------------------------
/src/lib/DateTime.js:
--------------------------------------------------------------------------------
1 | export default class DateTime {
2 |
3 | constructor(date) {
4 | this.date = date ? date : new Date();
5 |
6 | this.monthNames = [
7 | 'January', 'February', 'March',
8 | 'April', 'May', 'June',
9 | 'July', 'August', 'September',
10 | 'October', 'November', 'December'
11 | ];
12 |
13 | this.dayNames = [
14 | 'Sunday', 'Monday', 'Tuesday', 'Wednesday',
15 | 'Thursday', 'Friday', 'Saturday'
16 | ];
17 | }
18 |
19 | hours() {
20 | return this.formatUnitOfTime(this.date.getHours());
21 | }
22 |
23 | minutes() {
24 | return this.formatUnitOfTime(this.date.getMinutes());
25 | }
26 |
27 | seconds() {
28 | return this.formatUnitOfTime(this.date.getSeconds());
29 | }
30 |
31 | dayOfWeek() {
32 | return this.dayNames[this.date.getDay()];
33 | }
34 |
35 | dayOfMonth() {
36 | return this.formatUnitOfTime(this.date.getUTCDate());
37 | }
38 |
39 | month() {
40 | return this.monthNames[this.date.getMonth()];
41 | }
42 |
43 | year() {
44 | return `${this.date.getFullYear()}`;
45 | }
46 |
47 | formatUnitOfTime(unitOfTime) {
48 | return unitOfTime < 10 ? `0${unitOfTime}` : `${unitOfTime}`;
49 | }
50 |
51 | static toDateString(date) {
52 | var dateTime = new DateTime(date);
53 |
54 | return `${dateTime.dayOfWeek().substring(0, 3)} ${dateTime.dayOfMonth()} ${dateTime.month()} ${dateTime.year()}`;
55 | }
56 |
57 | static toTimeString(date) {
58 | var dateTime = new DateTime(date);
59 |
60 | return `${dateTime.hours()}:${dateTime.minutes()}:${dateTime.seconds()}`;
61 | }
62 | }
--------------------------------------------------------------------------------
/src/styles/components/_panel.scss:
--------------------------------------------------------------------------------
1 | .panel {
2 | align-items: center;
3 | display: flex;
4 | flex-direction: row;
5 | height: 4rem;
6 | justify-content: center;
7 | margin: 1rem auto;
8 | width: 14rem;
9 | }
10 |
11 | .panel-switch-text {
12 | font-size: 2rem;
13 | padding: 0.5rem;
14 | color: #333;
15 | }
16 |
17 | /**
18 | * The following block of CSS is taken directly from https://www.w3schools.com/howto/howto_css_switch.asp
19 | */
20 |
21 | /* The switch - the box around the slider */
22 | .switch {
23 | padding: 0.5rem;
24 | position: relative;
25 | display: inline-block;
26 | width: 60px;
27 | height: 34px;
28 | }
29 |
30 | /* Hide default HTML checkbox */
31 | .switch input {display:none;}
32 |
33 | /* The slider */
34 | .slider {
35 | position: absolute;
36 | cursor: pointer;
37 | top: 0;
38 | left: 0;
39 | right: 0;
40 | bottom: 0;
41 | background-color: #ccc;
42 | -webkit-transition: .4s;
43 | transition: .4s;
44 | }
45 |
46 | .slider:before {
47 | position: absolute;
48 | content: "";
49 | height: 26px;
50 | width: 26px;
51 | left: 4px;
52 | bottom: 4px;
53 | background-color: white;
54 | -webkit-transition: .4s;
55 | transition: .4s;
56 | }
57 |
58 | input:checked + .slider {
59 | background-color: #61DAFB;
60 | }
61 |
62 | input:focus + .slider {
63 | box-shadow: 0 0 1px #61DAFB;
64 | }
65 |
66 | input:checked + .slider:before {
67 | -webkit-transform: translateX(26px);
68 | -ms-transform: translateX(26px);
69 | transform: translateX(26px);
70 | }
71 |
72 | /* Rounded sliders */
73 | .slider.round {
74 | border-radius: 34px;
75 | }
76 |
77 | .slider.round:before {
78 | border-radius: 50%;
79 | }
--------------------------------------------------------------------------------
/other/vm-install.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | ### no warranty - works on ubuntu 18.04 LTS
4 | ### @jaydestro
5 |
6 | # install npm
7 |
8 | ### repositories
9 | add-apt-repository universe
10 | apt-get update -y
11 | apt-get install nodejs npm build-essential git sudo stress-ng -y
12 |
13 |
14 |
15 | ### installation
16 |
17 |
18 | echo "Downloading Repo"
19 |
20 | mkdir /react-clock-basic
21 | git clone https://github.com/jaydestro/react-clock-basic.git /react-clock-basic
22 | cd /react-clock-basic
23 | npm install
24 |
25 |
26 |
27 | # Publish and start application
28 | sudo apt-get install -y supervisor
29 | touch /etc/supervisor/conf.d/react-clock-basic.conf
30 |
31 | cat >> /etc/supervisor/conf.d/react-clock-basic.conf << 'EOF'
32 | [program:react-clock-basic]
33 | command=npm run serve
34 | directory=/react-clock-basic/
35 | autostart=true
36 | autorestart=true
37 | stderr_logfile=/var/log/reach-clock-basic.err.log
38 | stdout_logfile=/var/log/reach-clock-basic.out.log
39 | environment=
40 | stopsignal=INT
41 | EOF
42 |
43 | sudo service supervisor stop
44 | sudo service supervisor start
45 |
46 |
47 | #sysctl
48 |
49 | echo 1048576 > /proc/sys/fs/inotify/max_user_watches
50 |
51 | apt-get install nginx -y
52 | systemctl enable nginx
53 | systemctl start nginx
54 | rm /etc/nginx/sites-available/default
55 | touch /etc/nginx/sites-available/default
56 |
57 | cat >> /etc/nginx/sites-available/default << 'EOF'
58 | server {
59 | listen 80;
60 | location / {
61 | proxy_pass http://localhost:8080;
62 | proxy_http_version 1.1;
63 | proxy_set_header Upgrade $http_upgrade;
64 | proxy_set_header Connection keep-alive;
65 | proxy_set_header Host $host;
66 | proxy_cache_bypass $http_upgrade;
67 | }
68 | }
69 | EOF
70 |
71 | nginx -t
72 | nginx -s reload
73 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # React Clock
2 |
3 | This is a fork of this clock app that includes deployments for Azure Kubernetes Service and Docker.
4 |
5 |
6 | ### App Service Deployment Method:
7 |
8 | In Azure cloud shell:
9 |
10 | ```
11 | git clone https://github.com/jaydestro/react-clock-basic.git
12 |
13 | az group create --name $NAME --location eastus
14 |
15 | az network vnet create --name $nameVNET --resource-group $NAME --subnet-name default
16 |
17 | az acr create --resource-group $NAME--name $NAMEacr --sku Basic --admin-enabled true
18 |
19 | az acr build --registry $NAMEacr --image react-clock-basic:v1 .
20 | ```
21 |
22 | Go to portal in Azure, create a new app service, select your resource group, pick linux, pick docker container, create a new service plan, select dev/test - click Docker
23 |
24 | Drop down source, select Azure Container Registry. Click the registry you created above then select the image name and version.
25 |
26 | Click Review and create.
27 |
28 |
29 | A basic clock that displays the current date and time
30 |
31 | Go **[here](http://react-clock-basic.drminnaar.me/)** for live demo.
32 |
33 | Component Diagram
34 | 
35 |
36 | This project also demonstrates:
37 |
38 | * a typcial React project layout structure
39 | * babel setup and configuration
40 | * webpack setup and configuration
41 | * eslint setup and configuration
42 | * SCSS setup and configuration
43 |
44 | **Screenshots:**
45 |
46 | ... | ...
47 | --- | ---
48 |  | 
49 |
50 | ---
51 |
52 | ## Developed With
53 |
54 | * [Node.js](https://nodejs.org/en/) - Javascript runtime
55 | * [React](https://reactjs.org/) - A javascript library for building user interfaces
56 | * [Babel](https://babeljs.io/) - A transpiler for javascript
57 | * [Webpack](https://webpack.js.org/) - A module bundler
58 | * [SCSS](http://sass-lang.com/) - A css metalanguage
59 | * [Bootstrap 4](https://getbootstrap.com/) - Bootstrap is an open source toolkit for developing with HTML, CSS, and JS
60 | * [Surge]: https://surge.sh/
61 |
62 | ---
63 |
64 | ## Related Projects
65 |
66 | * [react-starter]
67 |
68 | A basic template that consists of the essential elements that are required to start building a React application
69 |
70 | * [react-clicker]
71 |
72 | A basic React app that allows one to increase, decrease, or reset a counter
73 |
74 | * [react-timer-basic]
75 |
76 | A basic timer that will start a countdown based on an input of time in seconds
77 |
78 | * [react-timer-advanced]
79 |
80 | A basic countdown timer that offers an advanced UI experience
81 |
82 | * [react-masterminds]
83 |
84 | A basic game of guessing a number with varying degrees of difficulty
85 |
86 | * [react-movie-cards]
87 |
88 | A basic application that displays a list of movies as a list of cards
89 |
90 | * [react-calculator-standard]
91 |
92 | A calculator that provides the essential arithmetic operations, an expression builder, and a complete history of all expressions
93 |
94 | * [react-bitcoin-monitor]
95 |
96 | An app that monitors changes in the Bitcoin Price Index (BPI)
97 |
98 | * [react-weather-standard]
99 |
100 | A weather application that displays the current weather, daily forecasts, and hourly forecasts based on your current geolocation
101 |
102 | ---
103 |
104 | ## Getting Started
105 |
106 | These instructions will get you a copy of the project up and running on your local machine for development and testing purposes.
107 |
108 | ### Prerequisites
109 |
110 | The following software is required to be installed on your system:
111 |
112 | * Node 12.x
113 | * Npm 3.x
114 |
115 | Type the following commands in the terminal to verify your node and npm versions
116 |
117 | ```bash
118 | node -v
119 | npm -v
120 | ```
121 |
122 | ### Install
123 |
124 | Follow the following steps to get development environment running.
125 |
126 | * Clone _'react-clock-basic'_ repository from GitHub
127 |
128 | ```bash
129 | git clone https://github.com/drminnaar/react-clock-basic.git
130 | ```
131 |
132 | _OR USING SSH_
133 |
134 | ```bash
135 | git clone git@github.com:drminnaar/react-clock-basic.git
136 | ```
137 |
138 | * Install node modules
139 |
140 | ```bash
141 | cd react-clock-basic
142 | npm install
143 | npm dedupe
144 | ```
145 |
146 | ### Build
147 |
148 | * Build application
149 |
150 | This command will also run ESLint as part of build process.
151 |
152 | ```bash
153 | npm run build
154 | ```
155 |
156 | * Build application and start watching for changes
157 |
158 | This command will also run ESLint as part of build process.
159 |
160 | ```bash
161 | npm run build:watch
162 | ```
163 |
164 | ### Run ESlint
165 |
166 | * Lint project using ESLint
167 |
168 | ```bash
169 | npm run lint
170 | ```
171 |
172 | * Lint project using ESLint, and autofix
173 |
174 | ```bash
175 | npm run lint:fix
176 | ```
177 |
178 | ### Run
179 |
180 | * Run start
181 |
182 | This will run the _'serve'_ npm task
183 |
184 | ```bash
185 | npm start
186 | ```
187 |
188 | * Run webpack dev server
189 |
190 | ```bash
191 | npm run serve:dev
192 | ```
193 |
194 | * Alternatively run live-server (simple development http server with live reload capability)
195 |
196 | ```bash
197 | npm run serve
198 | ```
199 |
200 | ---
201 |
202 | ## Versioning
203 |
204 | I use [SemVer](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/drminnaar/react-clock-basic/tags).
205 |
206 | ## Authors
207 |
208 | * **Douglas Minnaar** - *Initial work* - [drminnaar](https://github.com/drminnaar)
209 |
210 | [react-starter]: https://github.com/drminnaar/react-starter
211 | [react-clicker]: https://github.com/drminnaar/react-clicker
212 | [react-clock-basic]: https://github.com/drminnaar/react-clock-basic
213 | [react-timer-basic]: https://github.com/drminnaar/react-timer-basic
214 | [react-timer-advanced]: https://github.com/drminnaar/react-timer-advanced
215 | [react-masterminds]: https://github.com/drminnaar/react-masterminds
216 | [react-movie-cards]: https://github.com/drminnaar/react-movie-cards
217 | [react-calculator-standard]: https://github.com/drminnaar/react-calculator-standard
218 | [react-bitcoin-monitor]: https://github.com/drminnaar/react-bitcoin-monitor
219 | [react-weather-standard]: https://github.com/drminnaar/react-weather-standard
220 |
--------------------------------------------------------------------------------