├── .deployment ├── .eslintignore ├── .eslintrc ├── .github └── workflows │ └── main_reactclockjagord.yml ├── .gitignore ├── Dockerfile ├── README.md ├── azuredeploy.bicep ├── k8s ├── acr.sh ├── deployment.yaml └── loadbalancer.yaml ├── manifests ├── deployment-1.yml ├── deployment-2.yml ├── deployment.yml ├── ingress-1.yml ├── ingress-2.yml ├── ingress.yml ├── service-1.yml ├── service-2.yml └── service.yml ├── other ├── default └── vm-install.sh ├── package-lock.json ├── package.json ├── src ├── components │ ├── App.js │ ├── Clock.js │ ├── Display.js │ ├── Header.js │ └── Panel.js ├── favicon.ico ├── index.html ├── index.js ├── lib │ ├── .deployment │ └── DateTime.js └── styles │ ├── _base.scss │ ├── _settings.scss │ ├── app.scss │ └── components │ ├── _display.scss │ ├── _header.scss │ └── _panel.scss └── webpack.config.js /.deployment: -------------------------------------------------------------------------------- 1 | [config] 2 | SCM_DO_BUILD_DURING_DEPLOYMENT=true -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaydestro/react-clock-basic/8bdf92b01900fcc1bf4a5f0e87a42980a10ebcaa/.eslintignore -------------------------------------------------------------------------------- /.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 | } -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 -------------------------------------------------------------------------------- /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 -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 -------------------------------------------------------------------------------- /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/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" -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 |