├── .gitignore ├── DEMO.md ├── LICENSE ├── README.md ├── deploy.sh ├── ionic-beer ├── .editorconfig ├── .gitignore ├── config.xml ├── ionic.config.json ├── package-lock.json ├── package.json ├── resources │ ├── README.md │ ├── android │ │ ├── icon │ │ │ ├── drawable-hdpi-icon.png │ │ │ ├── drawable-ldpi-icon.png │ │ │ ├── drawable-mdpi-icon.png │ │ │ ├── drawable-xhdpi-icon.png │ │ │ ├── drawable-xxhdpi-icon.png │ │ │ └── drawable-xxxhdpi-icon.png │ │ └── splash │ │ │ ├── drawable-land-hdpi-screen.png │ │ │ ├── drawable-land-ldpi-screen.png │ │ │ ├── drawable-land-mdpi-screen.png │ │ │ ├── drawable-land-xhdpi-screen.png │ │ │ ├── drawable-land-xxhdpi-screen.png │ │ │ ├── drawable-land-xxxhdpi-screen.png │ │ │ ├── drawable-port-hdpi-screen.png │ │ │ ├── drawable-port-ldpi-screen.png │ │ │ ├── drawable-port-mdpi-screen.png │ │ │ ├── drawable-port-xhdpi-screen.png │ │ │ ├── drawable-port-xxhdpi-screen.png │ │ │ └── drawable-port-xxxhdpi-screen.png │ ├── icon.png │ ├── ios │ │ ├── icon │ │ │ ├── icon-1024.png │ │ │ ├── icon-40.png │ │ │ ├── icon-40@2x.png │ │ │ ├── icon-40@3x.png │ │ │ ├── icon-50.png │ │ │ ├── icon-50@2x.png │ │ │ ├── icon-60.png │ │ │ ├── icon-60@2x.png │ │ │ ├── icon-60@3x.png │ │ │ ├── icon-72.png │ │ │ ├── icon-72@2x.png │ │ │ ├── icon-76.png │ │ │ ├── icon-76@2x.png │ │ │ ├── icon-83.5@2x.png │ │ │ ├── icon-small.png │ │ │ ├── icon-small@2x.png │ │ │ ├── icon-small@3x.png │ │ │ ├── icon.png │ │ │ └── icon@2x.png │ │ └── splash │ │ │ ├── Default-568h@2x~iphone.png │ │ │ ├── Default-667h.png │ │ │ ├── Default-736h.png │ │ │ ├── Default-Landscape-736h.png │ │ │ ├── Default-Landscape@2x~ipad.png │ │ │ ├── Default-Landscape@~ipadpro.png │ │ │ ├── Default-Landscape~ipad.png │ │ │ ├── Default-Portrait@2x~ipad.png │ │ │ ├── Default-Portrait@~ipadpro.png │ │ │ ├── Default-Portrait~ipad.png │ │ │ ├── Default@2x~iphone.png │ │ │ ├── Default@2x~universal~anyany.png │ │ │ └── Default~iphone.png │ └── splash.png ├── src │ ├── app │ │ ├── app.component.ts │ │ ├── app.html │ │ ├── app.module.ts │ │ ├── app.scss │ │ └── main.ts │ ├── assets │ │ ├── icon │ │ │ └── favicon.ico │ │ └── imgs │ │ │ └── logo.png │ ├── index.html │ ├── manifest.json │ ├── pages │ │ ├── about │ │ │ ├── about.html │ │ │ ├── about.scss │ │ │ └── about.ts │ │ ├── beer │ │ │ ├── beer-modal.html │ │ │ ├── beer-modal.ts │ │ │ ├── beer.html │ │ │ ├── beer.module.ts │ │ │ ├── beer.scss │ │ │ └── beer.ts │ │ ├── contact │ │ │ ├── contact.html │ │ │ ├── contact.scss │ │ │ └── contact.ts │ │ ├── home │ │ │ ├── home.html │ │ │ ├── home.scss │ │ │ └── home.ts │ │ └── tabs │ │ │ ├── tabs.html │ │ │ └── tabs.ts │ ├── providers │ │ ├── beer-service.ts │ │ └── giphy-service.ts │ ├── service-worker.js │ └── theme │ │ └── variables.scss ├── tsconfig.json └── tslint.json └── server ├── .gitignore ├── .mvn └── wrapper │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── mvnw ├── mvnw.cmd ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── example │ │ └── demo │ │ ├── DemoApplication.java │ │ └── beer │ │ ├── Beer.java │ │ ├── BeerCommandLineRunner.java │ │ ├── BeerController.java │ │ └── BeerRepository.java └── resources │ └── application.properties └── test └── java └── com └── example └── demo └── DemoApplicationTests.java /.gitignore: -------------------------------------------------------------------------------- 1 | ### STS ### 2 | .apt_generated 3 | .classpath 4 | .factorypath 5 | .project 6 | .settings 7 | .springBeans 8 | 9 | ### IntelliJ IDEA ### 10 | .idea 11 | *.iws 12 | *.iml 13 | *.ipr 14 | 15 | ### NetBeans ### 16 | nbproject/private/ 17 | build/ 18 | nbbuild/ 19 | dist/ 20 | nbdist/ 21 | .nb-gradle/ 22 | -------------------------------------------------------------------------------- /DEMO.md: -------------------------------------------------------------------------------- 1 | ## Spring Boot API 2 | 3 | Create your Spring Boot API project using [start.spring.io](https://start.spring.io) or the command line. 4 | 5 | ``` 6 | http https://start.spring.io/starter.zip \ 7 | dependencies==data-jpa,data-rest,h2,web,devtools -d 8 | ``` 9 | 10 | 1. Open project in IntelliJ IDEA. Create a `Beer` entity class in `src/main/java/com/example/demo/beer`. → **boot-entity** 11 | 2. Create a JPA Repository to manage the `Beer` entity (tip: `@RepositoryRestResource`). → **boot-repository** 12 | 3. Create a CommandLineRunner to populate the database. → **boot-command** 13 | 4. Add default data in the `run()` method. → **boot-add** 14 | 5. Create a `BeerController` for your REST API. Add some business logic that results in a `/good-beers` endpoint. → **boot-controller** 15 | 6. Add a `/good-beers` mapping that filters out beers that aren't great. → **boot-good** 16 | 17 | ## Create Ionic App 18 | 19 | Install Ionic and Cordova: 20 | 21 | ``` 22 | yarn global add cordova ionic 23 | ``` 24 | 25 | From a terminal window, create a new application using the following command: 26 | 27 | ``` 28 | ionic start ionic-beer 29 | cd ionic-beer 30 | ionic serve 31 | ``` 32 | 33 | ## Build a Good Beers UI 34 | 35 | 1. Run `ionic generate page beer`. 36 | 2. Add `BeerPageModule` to the `imports` list in `app.module.ts`. 37 | 3. Create `src/providers/beer-service.ts`. → **io-beer-service** 38 | 5. Modify `beer.html` to show the list of beers. → **io-beer-list** 39 | 6. Update `beer.ts` to import `BeerService` and add as a provider. Call the `getGoodBeers()` method in the `ionViewDidLoad()` lifecycle method. → **io-get-good-beers** 40 | 7. To expose this page on the tab bar, add it to `tabs.ts`. Update `tabs.html` too! 41 | 42 | If you run `ionic serve`, you’ll likely see a CORS error in your browser’s console. To fix this, open your `BeerController` and add the following line to the good beers endpoint. 43 | 44 | ``` 45 | @CrossOrigin(origins = {"http://localhost:8100","file://"}) 46 | ``` 47 | 48 | Restart Spring Boot and your Ionic app. 49 | 50 | Add some fun with Giphy! Create `giphy-service.ts`. → **ng-giphy-service** 51 | 52 | Update `beer.ts` to take advantage of `GiphyService`. → **ng-giphy-foreach** 53 | 54 | Update `beer.html` to display the image retrieved. → **io-avatar** 55 | 56 | If everything works as expected, you should see a page with a list of beers and images. 57 | 58 | ### Add a Modal for Editing 59 | 60 | Change the header in `beer.html` to have a button that opens a modal to add a new beer. → **io-open-modal** 61 | 62 | In this same file, change `` to have a click handler for opening the modal for the current item. 63 | 64 | ```html 65 | 66 | ``` 67 | 68 | Add `ModalController` as a dependency in `BeerPage` and add an `openModal()` method. → **io-open-modal-ts** 69 | 70 | This won't compile because `BeerModalPage` doesn't exist. Create `beer-modal.ts` in the same directory. → **io-beer-modal** 71 | 72 | Create `beer-modal.html` as a template for this page. → **io-beer-modal-html** 73 | 74 | Import `BeerModalPage` in `beer.ts` and add it to the `declarations` and `entryComponents` lists in `beer.module.ts`. 75 | 76 | You'll also need to modify `beer-service.ts` to have `get()` and `save()` methods. → **io-get-save** 77 | 78 | Demo how editing fails, then add `CrossOrigin` annotation to `BeerRepository`. 79 | 80 | ```java 81 | @CrossOrigin(origins = {"http://localhost:8100","file://"}) 82 | ``` 83 | 84 | ### Add Swipe to Delete 85 | 86 | To add swipe-to-delete functionality on the list of beers, open `beer.html` and make it so `` wraps `` and contains the `*ngFor`. → **io-swipe** 87 | 88 | Add a `remove()` method to `beer.ts`. → **io-remove** 89 | 90 | Add `toastCtrl: ToastController` as a dependency in the constructor so everything compiles. 91 | 92 | After making these additions, you should be able to add, edit and delete beers. 93 | 94 | ## PWAs with Ionic 95 | 96 | Run the [Lighthouse Chrome extension](https://developers.google.com/web/tools/lighthouse/) on this application. To register a service worker, and improve the app’s score, uncomment the `serviceWorker` block in `index.html`. 97 | 98 | After making this change, the score should improve. In my tests, it increased to 75/100. 99 | 100 | If you refresh the app and Chrome doesn’t prompt you to install the app (a PWA feature), you probably need to turn on a couple of features. 101 | 102 | ``` 103 | chrome://flags/#bypass-app-banner-engagement-checks 104 | chrome://flags/#enable-add-to-shelf 105 | ``` 106 | 107 | After enabling these flags, you’ll see an error in your browser’s console about `assets/imgs/logo.png` not being found. This files is referenced in `src/manifest.json`. You can fix this by copying a 512x512 PNG into this location or by modifying `manifest.json` accordingly. 108 | 109 | ## Deploy to a Mobile Device 110 | 111 | To see how your application will look on different devices you can run `ionic serve --lab`. The `--lab` flag opens opens a page in your browser that lets you see how your app looks on different devices. 112 | 113 | ### iOS 114 | 115 | To emulate or deploy to an iOS device, you’ll need a Mac and a fresh installation of [Xcode](https://developer.apple.com/xcode/). If you’d like to build iOS apps on Windows, Ionic offers an [Ionic Package](http://ionic.io/cloud#packaging) service. 116 | 117 | ``` 118 | npm install -g ios-sim 119 | ionic cordova emulate ios 120 | ``` 121 | 122 | If this fails, run the following to open/deploy the project. 123 | 124 | ``` 125 | open platforms/ios/MyApp.xcodeproj 126 | ``` 127 | 128 | The biggest problem I found when running the app in Simulator was that it was difficult to get the keyboard to popup. To workaround this, I used Edit > Hardware > Keyboard > Toggle Software Keyboard when I needed to type text in a field. 129 | 130 | In order to deploy the app to a phone, you'll need to deploy the backend to a public server. Copy `deploy.sh` from 131 | [spring-boot-ionic-example](https://github.com/oktadeveloper/spring-boot-ionic-example) and run it to deploy the backend 132 | to Cloud Foundry. 133 | 134 | If this fails, run the following to open/deploy the project. 135 | 136 | ``` 137 | open platforms/ios/MyApp.xcodeproj 138 | ``` 139 | 140 | Select your phone as the target in Xcode and click the play button to run your app. 141 | 142 | ### Android 143 | 144 | To deploy to the Android emulator, run `ionic cordova emulate android`. 145 | 146 | ``` 147 | AVD Name: TestPhone 148 | Device: Nexus 5 149 | Target: Android 7.1.1 150 | CPU/ABI: Google APIs Intel Axom (x86_64) 151 | Skin: Skin with dynamic hardware controls 152 | ``` 153 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2017 Okta, Inc. 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Spring Boot + Ionic 🍻 2 | 3 | This project is an example application for a typical [Ionic](https://ionicframework.com/) app with a [Spring Boot](https://projects.spring.io/spring-boot/) backend. 4 | 5 | You can read about how this application was created in [Develop a Mobile App With Ionic and Spring Boot](http://developer.okta.com/blog/2017/05/17/develop-a-mobile-app-with-ionic-and-spring-boot). Feel free to copy any code in this project for your own use in accordance with the [Apache license](LICENSE). 6 | 7 | **Prerequisites**: Java 8 and Node.js. 8 | 9 | To run the Spring Boot backend, cd into `server` and run `mvn spring-boot:run`. 10 | 11 | In another terminal window, install Ionic and Cordova. 12 | 13 | ``` 14 | npm install -g ionic cordova 15 | ``` 16 | 17 | Next, cd into `ionic-beer` and execute `npm install && ionic serve`. The aforementioned [tutorial](http://developer.okta.com/blog/2017/05/17/develop-a-mobile-app-with-ionic-and-spring-boot) shows you how to deploy this app to an emulator/device. 18 | -------------------------------------------------------------------------------- /deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Warning: this script has only been tested on macOS Sierra. There's a good chance 3 | # it won't work on other operating systems. If you get it working on another OS, 4 | # please send a pull request with any changes required. Thanks! 5 | set -e 6 | 7 | ### CloudFoundry CLI utilities 8 | CLOUD_DOMAIN=${DOMAIN:-run.pivotal.io} 9 | CLOUD_TARGET=api.${DOMAIN} 10 | 11 | function login(){ 12 | cf api | grep ${CLOUD_TARGET} || cf api ${CLOUD_TARGET} --skip-ssl-validation 13 | cf apps | grep OK || cf login 14 | } 15 | 16 | function app_domain(){ 17 | D=`cf apps | grep $1 | tr -s ' ' | cut -d' ' -f 6 | cut -d, -f1` 18 | echo $D 19 | } 20 | 21 | function deploy_service(){ 22 | N=$1 23 | D=`app_domain $N` 24 | JSON='{"uri":"http://'$D'"}' 25 | cf create-user-provided-service $N -p $JSON 26 | } 27 | 28 | ### Installation 29 | 30 | cd `dirname $0` 31 | r=`pwd` 32 | echo $r 33 | 34 | ## Reset 35 | cf d -f ionic-server 36 | 37 | cf a 38 | 39 | # Deploy the server 40 | cd $r/server 41 | mvn clean package 42 | cf push -p target/*jar ionic-server --no-start --random-route 43 | cf set-env ionic-server FORCE_HTTPS true 44 | cf start ionic-server 45 | 46 | # Get the URL for the server 47 | serverUri=https://`app_domain ionic-server` 48 | 49 | # Deploy the client 50 | cd $r/ionic-beer 51 | npm run clean 52 | # replace the server URL in the client 53 | sed -i -e "s|http://localhost:8080|$serverUri|g" src/providers/beer-service.ts 54 | npm install 55 | 56 | # build ios 57 | ionic cordova build ios --prod 58 | # Run on ios 59 | ionic cordova run ios 60 | 61 | # If the above command fails with the following error: 62 | # xcrun: error: unable to find utility "PackageApplication", not a developer tool or in PATH 63 | # See http://stackoverflow.com/a/43363820 64 | 65 | # cleanup changed files 66 | sed -i -e "s|$serverUri|http://localhost:8080|g" src/providers/beer-service.ts 67 | rm $r/ionic-beer/src/providers/beer-service.ts-e 68 | -------------------------------------------------------------------------------- /ionic-beer/.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent coding styles between different editors and IDEs 2 | # editorconfig.org 3 | 4 | root = true 5 | 6 | [*] 7 | indent_style = space 8 | indent_size = 2 9 | 10 | # We recommend you to keep these unchanged 11 | end_of_line = lf 12 | charset = utf-8 13 | trim_trailing_whitespace = true 14 | insert_final_newline = true 15 | 16 | [*.md] 17 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /ionic-beer/.gitignore: -------------------------------------------------------------------------------- 1 | # Specifies intentionally untracked files to ignore when using Git 2 | # http://git-scm.com/docs/gitignore 3 | 4 | *~ 5 | *.sw[mnpcod] 6 | *.log 7 | *.tmp 8 | *.tmp.* 9 | log.txt 10 | *.sublime-project 11 | *.sublime-workspace 12 | .vscode/ 13 | npm-debug.log* 14 | 15 | .idea/ 16 | .sourcemaps/ 17 | .sass-cache/ 18 | .tmp/ 19 | .versions/ 20 | coverage/ 21 | dist/ 22 | node_modules/ 23 | tmp/ 24 | temp/ 25 | hooks/ 26 | platforms/ 27 | plugins/ 28 | plugins/android.json 29 | plugins/ios.json 30 | www/ 31 | $RECYCLE.BIN/ 32 | 33 | .DS_Store 34 | Thumbs.db 35 | UserInterfaceState.xcuserstate 36 | -------------------------------------------------------------------------------- /ionic-beer/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | ionic-beer 4 | An awesome Ionic/Cordova app. 5 | Ionic Framework Team 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /ionic-beer/ionic.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ionic-beer", 3 | "app_id": "", 4 | "type": "ionic-angular", 5 | "integrations": { 6 | "cordova": {} 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /ionic-beer/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ionic-beer", 3 | "version": "0.0.1", 4 | "author": "Ionic Framework", 5 | "homepage": "http://ionicframework.com/", 6 | "private": true, 7 | "scripts": { 8 | "clean": "ionic-app-scripts clean", 9 | "build": "ionic-app-scripts build", 10 | "lint": "ionic-app-scripts lint", 11 | "ionic:build": "ionic-app-scripts build", 12 | "ionic:serve": "ionic-app-scripts serve" 13 | }, 14 | "dependencies": { 15 | "@angular/common": "5.0.3", 16 | "@angular/compiler": "5.0.3", 17 | "@angular/compiler-cli": "5.0.3", 18 | "@angular/core": "5.0.3", 19 | "@angular/forms": "5.0.3", 20 | "@angular/http": "5.0.3", 21 | "@angular/platform-browser": "5.0.3", 22 | "@angular/platform-browser-dynamic": "5.0.3", 23 | "@ionic-native/core": "4.4.0", 24 | "@ionic-native/splash-screen": "4.4.0", 25 | "@ionic-native/status-bar": "4.4.0", 26 | "@ionic/storage": "2.1.3", 27 | "cordova-android": "7.0.0", 28 | "cordova-ios": "4.5.4", 29 | "cordova-plugin-device": "^2.0.1", 30 | "cordova-plugin-ionic-keyboard": "^2.0.5", 31 | "cordova-plugin-ionic-webview": "^1.1.16", 32 | "cordova-plugin-splashscreen": "^5.0.2", 33 | "cordova-plugin-whitelist": "^1.3.3", 34 | "ionic-angular": "3.9.2", 35 | "ionicons": "3.0.0", 36 | "rxjs": "5.5.2", 37 | "sw-toolbox": "3.6.0", 38 | "zone.js": "0.8.18" 39 | }, 40 | "devDependencies": { 41 | "@ionic/app-scripts": "3.1.8", 42 | "typescript": "2.4.2" 43 | }, 44 | "description": "An Ionic project", 45 | "cordova": { 46 | "plugins": { 47 | "cordova-plugin-whitelist": {}, 48 | "cordova-plugin-device": {}, 49 | "cordova-plugin-splashscreen": {}, 50 | "cordova-plugin-ionic-webview": {}, 51 | "cordova-plugin-ionic-keyboard": {} 52 | }, 53 | "platforms": [ 54 | "ios", 55 | "android" 56 | ] 57 | } 58 | } -------------------------------------------------------------------------------- /ionic-beer/resources/README.md: -------------------------------------------------------------------------------- 1 | These are Cordova resources. You can replace icon.png and splash.png and run 2 | `ionic cordova resources` to generate custom icons and splash screens for your 3 | app. See `ionic cordova resources --help` for details. 4 | 5 | Cordova reference documentation: 6 | 7 | - Icons: https://cordova.apache.org/docs/en/latest/config_ref/images.html 8 | - Splash Screens: https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-splashscreen/ 9 | -------------------------------------------------------------------------------- /ionic-beer/resources/android/icon/drawable-hdpi-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/android/icon/drawable-hdpi-icon.png -------------------------------------------------------------------------------- /ionic-beer/resources/android/icon/drawable-ldpi-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/android/icon/drawable-ldpi-icon.png -------------------------------------------------------------------------------- /ionic-beer/resources/android/icon/drawable-mdpi-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/android/icon/drawable-mdpi-icon.png -------------------------------------------------------------------------------- /ionic-beer/resources/android/icon/drawable-xhdpi-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/android/icon/drawable-xhdpi-icon.png -------------------------------------------------------------------------------- /ionic-beer/resources/android/icon/drawable-xxhdpi-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/android/icon/drawable-xxhdpi-icon.png -------------------------------------------------------------------------------- /ionic-beer/resources/android/icon/drawable-xxxhdpi-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/android/icon/drawable-xxxhdpi-icon.png -------------------------------------------------------------------------------- /ionic-beer/resources/android/splash/drawable-land-hdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/android/splash/drawable-land-hdpi-screen.png -------------------------------------------------------------------------------- /ionic-beer/resources/android/splash/drawable-land-ldpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/android/splash/drawable-land-ldpi-screen.png -------------------------------------------------------------------------------- /ionic-beer/resources/android/splash/drawable-land-mdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/android/splash/drawable-land-mdpi-screen.png -------------------------------------------------------------------------------- /ionic-beer/resources/android/splash/drawable-land-xhdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/android/splash/drawable-land-xhdpi-screen.png -------------------------------------------------------------------------------- /ionic-beer/resources/android/splash/drawable-land-xxhdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/android/splash/drawable-land-xxhdpi-screen.png -------------------------------------------------------------------------------- /ionic-beer/resources/android/splash/drawable-land-xxxhdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/android/splash/drawable-land-xxxhdpi-screen.png -------------------------------------------------------------------------------- /ionic-beer/resources/android/splash/drawable-port-hdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/android/splash/drawable-port-hdpi-screen.png -------------------------------------------------------------------------------- /ionic-beer/resources/android/splash/drawable-port-ldpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/android/splash/drawable-port-ldpi-screen.png -------------------------------------------------------------------------------- /ionic-beer/resources/android/splash/drawable-port-mdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/android/splash/drawable-port-mdpi-screen.png -------------------------------------------------------------------------------- /ionic-beer/resources/android/splash/drawable-port-xhdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/android/splash/drawable-port-xhdpi-screen.png -------------------------------------------------------------------------------- /ionic-beer/resources/android/splash/drawable-port-xxhdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/android/splash/drawable-port-xxhdpi-screen.png -------------------------------------------------------------------------------- /ionic-beer/resources/android/splash/drawable-port-xxxhdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/android/splash/drawable-port-xxxhdpi-screen.png -------------------------------------------------------------------------------- /ionic-beer/resources/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/icon.png -------------------------------------------------------------------------------- /ionic-beer/resources/ios/icon/icon-1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/ios/icon/icon-1024.png -------------------------------------------------------------------------------- /ionic-beer/resources/ios/icon/icon-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/ios/icon/icon-40.png -------------------------------------------------------------------------------- /ionic-beer/resources/ios/icon/icon-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/ios/icon/icon-40@2x.png -------------------------------------------------------------------------------- /ionic-beer/resources/ios/icon/icon-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/ios/icon/icon-40@3x.png -------------------------------------------------------------------------------- /ionic-beer/resources/ios/icon/icon-50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/ios/icon/icon-50.png -------------------------------------------------------------------------------- /ionic-beer/resources/ios/icon/icon-50@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/ios/icon/icon-50@2x.png -------------------------------------------------------------------------------- /ionic-beer/resources/ios/icon/icon-60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/ios/icon/icon-60.png -------------------------------------------------------------------------------- /ionic-beer/resources/ios/icon/icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/ios/icon/icon-60@2x.png -------------------------------------------------------------------------------- /ionic-beer/resources/ios/icon/icon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/ios/icon/icon-60@3x.png -------------------------------------------------------------------------------- /ionic-beer/resources/ios/icon/icon-72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/ios/icon/icon-72.png -------------------------------------------------------------------------------- /ionic-beer/resources/ios/icon/icon-72@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/ios/icon/icon-72@2x.png -------------------------------------------------------------------------------- /ionic-beer/resources/ios/icon/icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/ios/icon/icon-76.png -------------------------------------------------------------------------------- /ionic-beer/resources/ios/icon/icon-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/ios/icon/icon-76@2x.png -------------------------------------------------------------------------------- /ionic-beer/resources/ios/icon/icon-83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/ios/icon/icon-83.5@2x.png -------------------------------------------------------------------------------- /ionic-beer/resources/ios/icon/icon-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/ios/icon/icon-small.png -------------------------------------------------------------------------------- /ionic-beer/resources/ios/icon/icon-small@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/ios/icon/icon-small@2x.png -------------------------------------------------------------------------------- /ionic-beer/resources/ios/icon/icon-small@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/ios/icon/icon-small@3x.png -------------------------------------------------------------------------------- /ionic-beer/resources/ios/icon/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/ios/icon/icon.png -------------------------------------------------------------------------------- /ionic-beer/resources/ios/icon/icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/ios/icon/icon@2x.png -------------------------------------------------------------------------------- /ionic-beer/resources/ios/splash/Default-568h@2x~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/ios/splash/Default-568h@2x~iphone.png -------------------------------------------------------------------------------- /ionic-beer/resources/ios/splash/Default-667h.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/ios/splash/Default-667h.png -------------------------------------------------------------------------------- /ionic-beer/resources/ios/splash/Default-736h.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/ios/splash/Default-736h.png -------------------------------------------------------------------------------- /ionic-beer/resources/ios/splash/Default-Landscape-736h.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/ios/splash/Default-Landscape-736h.png -------------------------------------------------------------------------------- /ionic-beer/resources/ios/splash/Default-Landscape@2x~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/ios/splash/Default-Landscape@2x~ipad.png -------------------------------------------------------------------------------- /ionic-beer/resources/ios/splash/Default-Landscape@~ipadpro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/ios/splash/Default-Landscape@~ipadpro.png -------------------------------------------------------------------------------- /ionic-beer/resources/ios/splash/Default-Landscape~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/ios/splash/Default-Landscape~ipad.png -------------------------------------------------------------------------------- /ionic-beer/resources/ios/splash/Default-Portrait@2x~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/ios/splash/Default-Portrait@2x~ipad.png -------------------------------------------------------------------------------- /ionic-beer/resources/ios/splash/Default-Portrait@~ipadpro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/ios/splash/Default-Portrait@~ipadpro.png -------------------------------------------------------------------------------- /ionic-beer/resources/ios/splash/Default-Portrait~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/ios/splash/Default-Portrait~ipad.png -------------------------------------------------------------------------------- /ionic-beer/resources/ios/splash/Default@2x~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/ios/splash/Default@2x~iphone.png -------------------------------------------------------------------------------- /ionic-beer/resources/ios/splash/Default@2x~universal~anyany.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/ios/splash/Default@2x~universal~anyany.png -------------------------------------------------------------------------------- /ionic-beer/resources/ios/splash/Default~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/ios/splash/Default~iphone.png -------------------------------------------------------------------------------- /ionic-beer/resources/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/resources/splash.png -------------------------------------------------------------------------------- /ionic-beer/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { Platform } from 'ionic-angular'; 3 | import { StatusBar } from '@ionic-native/status-bar'; 4 | import { SplashScreen } from '@ionic-native/splash-screen'; 5 | 6 | import { TabsPage } from '../pages/tabs/tabs'; 7 | 8 | @Component({ 9 | templateUrl: 'app.html' 10 | }) 11 | export class MyApp { 12 | rootPage:any = TabsPage; 13 | 14 | constructor(platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen) { 15 | platform.ready().then(() => { 16 | // Okay, so the platform is ready and our plugins are available. 17 | // Here you can do any higher level native things you might need. 18 | statusBar.styleDefault(); 19 | splashScreen.hide(); 20 | }); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ionic-beer/src/app/app.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /ionic-beer/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule, ErrorHandler } from '@angular/core'; 2 | import { BrowserModule } from '@angular/platform-browser'; 3 | import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular'; 4 | import { MyApp } from './app.component'; 5 | 6 | import { AboutPage } from '../pages/about/about'; 7 | import { ContactPage } from '../pages/contact/contact'; 8 | import { HomePage } from '../pages/home/home'; 9 | import { TabsPage } from '../pages/tabs/tabs'; 10 | 11 | import { StatusBar } from '@ionic-native/status-bar'; 12 | import { SplashScreen } from '@ionic-native/splash-screen'; 13 | 14 | import { BeerPageModule } from '../pages/beer/beer.module'; 15 | import { HttpClientModule } from '@angular/common/http'; 16 | 17 | @NgModule({ 18 | declarations: [ 19 | MyApp, 20 | AboutPage, 21 | ContactPage, 22 | HomePage, 23 | TabsPage 24 | ], 25 | imports: [ 26 | BrowserModule, 27 | HttpClientModule, 28 | IonicModule.forRoot(MyApp), 29 | BeerPageModule 30 | ], 31 | bootstrap: [IonicApp], 32 | entryComponents: [ 33 | MyApp, 34 | AboutPage, 35 | ContactPage, 36 | HomePage, 37 | TabsPage 38 | ], 39 | providers: [ 40 | StatusBar, 41 | SplashScreen, 42 | {provide: ErrorHandler, useClass: IonicErrorHandler} 43 | ] 44 | }) 45 | export class AppModule {} 46 | -------------------------------------------------------------------------------- /ionic-beer/src/app/app.scss: -------------------------------------------------------------------------------- 1 | // http://ionicframework.com/docs/theming/ 2 | 3 | 4 | // App Global Sass 5 | // -------------------------------------------------- 6 | // Put style rules here that you want to apply globally. These 7 | // styles are for the entire app and not just one component. 8 | // Additionally, this file can be also used as an entry point 9 | // to import other Sass files to be included in the output CSS. 10 | // 11 | // Shared Sass variables, which can be used to adjust Ionic's 12 | // default Sass variables, belong in "theme/variables.scss". 13 | // 14 | // To declare rules for a specific mode, create a child rule 15 | // for the .md, .ios, or .wp mode classes. The mode class is 16 | // automatically applied to the element in the app. 17 | -------------------------------------------------------------------------------- /ionic-beer/src/app/main.ts: -------------------------------------------------------------------------------- 1 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 2 | 3 | import { AppModule } from './app.module'; 4 | 5 | platformBrowserDynamic().bootstrapModule(AppModule); 6 | -------------------------------------------------------------------------------- /ionic-beer/src/assets/icon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/src/assets/icon/favicon.ico -------------------------------------------------------------------------------- /ionic-beer/src/assets/imgs/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/ionic-beer/src/assets/imgs/logo.png -------------------------------------------------------------------------------- /ionic-beer/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Ionic App 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 28 | 29 | 30 | 31 | 32 | 33 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /ionic-beer/src/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Ionic", 3 | "short_name": "Ionic", 4 | "start_url": "index.html", 5 | "display": "standalone", 6 | "icons": [{ 7 | "src": "assets/imgs/logo.png", 8 | "sizes": "512x512", 9 | "type": "image/png" 10 | }], 11 | "background_color": "#4e8ef7", 12 | "theme_color": "#4e8ef7" 13 | } -------------------------------------------------------------------------------- /ionic-beer/src/pages/about/about.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | About 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /ionic-beer/src/pages/about/about.scss: -------------------------------------------------------------------------------- 1 | page-about { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /ionic-beer/src/pages/about/about.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { NavController } from 'ionic-angular'; 3 | 4 | @Component({ 5 | selector: 'page-about', 6 | templateUrl: 'about.html' 7 | }) 8 | export class AboutPage { 9 | 10 | constructor(public navCtrl: NavController) { 11 | 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /ionic-beer/src/pages/beer/beer-modal.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{beer ? 'Beer Details' : 'Add Beer'}} 5 | 6 | 7 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 |
{{error}}
35 | 37 |
38 |
39 |
40 |
41 | -------------------------------------------------------------------------------- /ionic-beer/src/pages/beer/beer-modal.ts: -------------------------------------------------------------------------------- 1 | import { BeerService } from '../../providers/beer-service'; 2 | import { Component, ViewChild } from '@angular/core'; 3 | import { GiphyService } from '../../providers/giphy-service'; 4 | import { NavParams, ViewController, ToastController, NavController } from 'ionic-angular'; 5 | import { NgForm } from '@angular/forms'; 6 | 7 | @Component({ 8 | templateUrl: './beer-modal.html' 9 | }) 10 | export class BeerModalPage { 11 | @ViewChild('name') name; 12 | beer: any = {}; 13 | error: any; 14 | 15 | constructor(public beerService: BeerService, 16 | public giphyService: GiphyService, 17 | public params: NavParams, 18 | public viewCtrl: ViewController, 19 | public toastCtrl: ToastController, 20 | public navCtrl: NavController) { 21 | if (this.params.data.id) { 22 | this.beerService.get(this.params.get('id')).subscribe((beer: any) => { 23 | this.beer = beer; 24 | this.beer.href = beer._links.self.href; 25 | this.giphyService.get(beer.name).subscribe(url => beer.giphyUrl = url); 26 | }); 27 | } 28 | } 29 | 30 | dismiss() { 31 | this.viewCtrl.dismiss(); 32 | } 33 | 34 | save(form: NgForm) { 35 | let update: boolean = form['href']; 36 | this.beerService.save(form).subscribe(result => { 37 | let toast = this.toastCtrl.create({ 38 | message: 'Beer "' + form.name + '" ' + ((update) ? 'updated' : 'added') + '.', 39 | duration: 2000 40 | }); 41 | toast.present(); 42 | this.dismiss(); 43 | }, error => this.error = error) 44 | } 45 | 46 | ionViewDidLoad() { 47 | setTimeout(() => { 48 | this.name.setFocus(); 49 | },150); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /ionic-beer/src/pages/beer/beer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Good Beers 4 | 5 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |

{{beer.name}}

21 |
22 | 23 | 26 | 27 |
28 |
29 |
30 | -------------------------------------------------------------------------------- /ionic-beer/src/pages/beer/beer.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { IonicPageModule } from 'ionic-angular'; 3 | import { BeerPage } from './beer'; 4 | import { BeerService } from '../../providers/beer-service'; 5 | import { GiphyService } from '../../providers/giphy-service'; 6 | import { BeerModalPage } from './beer-modal'; 7 | 8 | @NgModule({ 9 | declarations: [ 10 | BeerPage, 11 | BeerModalPage 12 | ], 13 | imports: [ 14 | IonicPageModule.forChild(BeerPage), 15 | ], 16 | providers: [ 17 | BeerService, 18 | GiphyService 19 | ], 20 | entryComponents: [ 21 | BeerModalPage 22 | ] 23 | }) 24 | export class BeerPageModule {} 25 | -------------------------------------------------------------------------------- /ionic-beer/src/pages/beer/beer.scss: -------------------------------------------------------------------------------- 1 | page-beer { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /ionic-beer/src/pages/beer/beer.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { IonicPage, ModalController, NavController, NavParams, ToastController } from 'ionic-angular'; 3 | import { BeerService } from '../../providers/beer-service'; 4 | import { GiphyService } from '../../providers/giphy-service'; 5 | import { BeerModalPage } from './beer-modal'; 6 | 7 | @IonicPage() 8 | @Component({ 9 | selector: 'page-beer', 10 | templateUrl: 'beer.html', 11 | }) 12 | export class BeerPage { 13 | private beers: Array; 14 | 15 | constructor(public navCtrl: NavController, public navParams: NavParams, 16 | public beerService: BeerService, public giphyService: GiphyService, 17 | public modalCtrl: ModalController, public toastCtrl: ToastController) { 18 | } 19 | 20 | ionViewDidLoad() { 21 | this.beerService.getGoodBeers().subscribe(beers => { 22 | this.beers = beers; 23 | for (const beer of this.beers) { 24 | this.giphyService.get(beer.name).subscribe(url => { 25 | beer.giphyUrl = url 26 | }); 27 | } 28 | }) 29 | } 30 | 31 | openModal(beerId) { 32 | let modal = this.modalCtrl.create(BeerModalPage, beerId); 33 | modal.present(); 34 | // refresh data after modal dismissed 35 | modal.onDidDismiss(() => this.ionViewDidLoad()) 36 | } 37 | 38 | remove(beer) { 39 | this.beerService.remove(beer.id).subscribe(response => { 40 | for (let i = 0; i < this.beers.length; i++) { 41 | if (this.beers[i] === beer) { 42 | this.beers.splice(i, 1); 43 | let toast = this.toastCtrl.create({ 44 | message: 'Beer "' + beer.name + '" deleted.', 45 | duration: 2000, 46 | position: 'top' 47 | }); 48 | toast.present(); 49 | } 50 | } 51 | }); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /ionic-beer/src/pages/contact/contact.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Contact 5 | 6 | 7 | 8 | 9 | 10 | 11 | Follow us on Twitter 12 | 13 | 14 | @ionicframework 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /ionic-beer/src/pages/contact/contact.scss: -------------------------------------------------------------------------------- 1 | page-contact { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /ionic-beer/src/pages/contact/contact.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { NavController } from 'ionic-angular'; 3 | 4 | @Component({ 5 | selector: 'page-contact', 6 | templateUrl: 'contact.html' 7 | }) 8 | export class ContactPage { 9 | 10 | constructor(public navCtrl: NavController) { 11 | 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /ionic-beer/src/pages/home/home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Home 4 | 5 | 6 | 7 | 8 |

Welcome to Ionic!

9 |

10 | This starter project comes with simple tabs-based layout for apps 11 | that are going to primarily use a Tabbed UI. 12 |

13 |

14 | Take a look at the src/pages/ directory to add or change tabs, 15 | update any existing page or create new pages. 16 |

17 |
18 | -------------------------------------------------------------------------------- /ionic-beer/src/pages/home/home.scss: -------------------------------------------------------------------------------- 1 | page-home { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /ionic-beer/src/pages/home/home.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { NavController } from 'ionic-angular'; 3 | 4 | @Component({ 5 | selector: 'page-home', 6 | templateUrl: 'home.html' 7 | }) 8 | export class HomePage { 9 | 10 | constructor(public navCtrl: NavController) { 11 | 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /ionic-beer/src/pages/tabs/tabs.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /ionic-beer/src/pages/tabs/tabs.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | import { AboutPage } from '../about/about'; 4 | import { ContactPage } from '../contact/contact'; 5 | import { HomePage } from '../home/home'; 6 | import { BeerPage } from '../beer/beer'; 7 | 8 | @Component({ 9 | templateUrl: 'tabs.html' 10 | }) 11 | export class TabsPage { 12 | tab1Root = HomePage; 13 | tab2Root = BeerPage; 14 | tab3Root = AboutPage; 15 | tab4Root = ContactPage; 16 | 17 | constructor() { 18 | 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /ionic-beer/src/providers/beer-service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { Observable } from 'rxjs'; 3 | import { HttpClient } from '@angular/common/http'; 4 | 5 | @Injectable() 6 | export class BeerService { 7 | public API = 'http://192.168.1.48:8080'; 8 | public BEER_API = this.API + '/beers'; 9 | 10 | constructor(public http: HttpClient) { 11 | } 12 | 13 | getGoodBeers(): Observable { 14 | return this.http.get(this.API + '/good-beers'); 15 | } 16 | 17 | get(id: string) { 18 | return this.http.get(this.BEER_API + '/' + id); 19 | } 20 | 21 | save(beer: any): Observable { 22 | let result: Observable; 23 | if (beer['href']) { 24 | result = this.http.put(beer.href, beer); 25 | } else { 26 | result = this.http.post(this.BEER_API, beer) 27 | } 28 | return result.catch(error => Observable.throw(error)); 29 | } 30 | 31 | remove(id: string) { 32 | return this.http.delete(this.BEER_API + '/' + id); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ionic-beer/src/providers/giphy-service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { HttpClient } from '@angular/common/http'; 3 | import 'rxjs/add/operator/map'; 4 | 5 | @Injectable() 6 | // http://tutorials.pluralsight.com/front-end-javascript/getting-started-with-angular-2-by-building-a-giphy-search-application 7 | export class GiphyService { 8 | 9 | // Public beta key: https://github.com/Giphy/GiphyAPI#public-beta-key 10 | giphyApi = 'https://api.giphy.com/v1/gifs/search?api_key=dc6zaTOxFJmzC&limit=1&q='; 11 | 12 | constructor(public http: HttpClient) { 13 | } 14 | 15 | get(searchTerm) { 16 | const apiLink = this.giphyApi + searchTerm; 17 | return this.http.get(apiLink).map((response: any) => { 18 | if (response.data.length > 0) { 19 | return response.data[0].images.original.url; 20 | } else { 21 | return 'https://media.giphy.com/media/YaOxRsmrv9IeA/giphy.gif'; // dancing cat for 404 22 | } 23 | }); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ionic-beer/src/service-worker.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Check out https://googlechromelabs.github.io/sw-toolbox/ for 3 | * more info on how to use sw-toolbox to custom configure your service worker. 4 | */ 5 | 6 | 7 | 'use strict'; 8 | importScripts('./build/sw-toolbox.js'); 9 | 10 | self.toolbox.options.cache = { 11 | name: 'ionic-cache' 12 | }; 13 | 14 | // pre-cache our key assets 15 | self.toolbox.precache( 16 | [ 17 | './build/main.js', 18 | './build/vendor.js', 19 | './build/main.css', 20 | './build/polyfills.js', 21 | 'index.html', 22 | 'manifest.json' 23 | ] 24 | ); 25 | 26 | // dynamically cache any other local assets 27 | self.toolbox.router.any('/*', self.toolbox.fastest); 28 | 29 | // for any other requests go to the network, cache, 30 | // and then only use that cached resource if your user goes offline 31 | self.toolbox.router.default = self.toolbox.networkFirst; 32 | -------------------------------------------------------------------------------- /ionic-beer/src/theme/variables.scss: -------------------------------------------------------------------------------- 1 | // Ionic Variables and Theming. For more info, please see: 2 | // http://ionicframework.com/docs/theming/ 3 | 4 | // Font path is used to include ionicons, 5 | // roboto, and noto sans fonts 6 | $font-path: "../assets/fonts"; 7 | 8 | 9 | // The app direction is used to include 10 | // rtl styles in your app. For more info, please see: 11 | // http://ionicframework.com/docs/theming/rtl-support/ 12 | $app-direction: ltr; 13 | 14 | 15 | @import "ionic.globals"; 16 | 17 | 18 | // Shared Variables 19 | // -------------------------------------------------- 20 | // To customize the look and feel of this app, you can override 21 | // the Sass variables found in Ionic's source scss files. 22 | // To view all the possible Ionic variables, see: 23 | // http://ionicframework.com/docs/theming/overriding-ionic-variables/ 24 | 25 | 26 | 27 | 28 | // Named Color Variables 29 | // -------------------------------------------------- 30 | // Named colors makes it easy to reuse colors on various components. 31 | // It's highly recommended to change the default colors 32 | // to match your app's branding. Ionic uses a Sass map of 33 | // colors so you can add, rename and remove colors as needed. 34 | // The "primary" color is the only required color in the map. 35 | 36 | $colors: ( 37 | primary: #488aff, 38 | secondary: #32db64, 39 | danger: #f53d3d, 40 | light: #f4f4f4, 41 | dark: #222 42 | ); 43 | 44 | 45 | // App iOS Variables 46 | // -------------------------------------------------- 47 | // iOS only Sass variables can go here 48 | 49 | 50 | 51 | 52 | // App Material Design Variables 53 | // -------------------------------------------------- 54 | // Material Design only Sass variables can go here 55 | 56 | 57 | 58 | 59 | // App Windows Variables 60 | // -------------------------------------------------- 61 | // Windows only Sass variables can go here 62 | 63 | 64 | 65 | 66 | // App Theme 67 | // -------------------------------------------------- 68 | // Ionic apps can have different themes applied, which can 69 | // then be future customized. This import comes last 70 | // so that the above variables are used and Ionic's 71 | // default are overridden. 72 | 73 | @import "ionic.theme.default"; 74 | 75 | 76 | // Ionicons 77 | // -------------------------------------------------- 78 | // The premium icon font for Ionic. For more info, please see: 79 | // http://ionicframework.com/docs/ionicons/ 80 | 81 | @import "ionic.ionicons"; 82 | 83 | 84 | // Fonts 85 | // -------------------------------------------------- 86 | 87 | @import "roboto"; 88 | @import "noto-sans"; 89 | -------------------------------------------------------------------------------- /ionic-beer/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "declaration": false, 5 | "emitDecoratorMetadata": true, 6 | "experimentalDecorators": true, 7 | "lib": [ 8 | "dom", 9 | "es2015" 10 | ], 11 | "module": "es2015", 12 | "moduleResolution": "node", 13 | "sourceMap": true, 14 | "target": "es5" 15 | }, 16 | "include": [ 17 | "src/**/*.ts" 18 | ], 19 | "exclude": [ 20 | "node_modules", 21 | "src/**/*.spec.ts", 22 | "src/**/__tests__/*.ts" 23 | ], 24 | "compileOnSave": false, 25 | "atom": { 26 | "rewriteTsconfig": false 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ionic-beer/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "no-duplicate-variable": true, 4 | "no-unused-variable": [ 5 | true 6 | ] 7 | }, 8 | "rulesDirectory": [ 9 | "node_modules/tslint-eslint-rules/dist/rules" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /server/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | 4 | ### STS ### 5 | .apt_generated 6 | .classpath 7 | .factorypath 8 | .project 9 | .settings 10 | .springBeans 11 | 12 | ### IntelliJ IDEA ### 13 | .idea 14 | *.iws 15 | *.iml 16 | *.ipr 17 | 18 | ### NetBeans ### 19 | nbproject/private/ 20 | build/ 21 | nbbuild/ 22 | dist/ 23 | nbdist/ 24 | .nb-gradle/ -------------------------------------------------------------------------------- /server/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/server/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /server/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.2/apache-maven-3.5.2-bin.zip 2 | -------------------------------------------------------------------------------- /server/mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven2 Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /etc/mavenrc ] ; then 40 | . /etc/mavenrc 41 | fi 42 | 43 | if [ -f "$HOME/.mavenrc" ] ; then 44 | . "$HOME/.mavenrc" 45 | fi 46 | 47 | fi 48 | 49 | # OS specific support. $var _must_ be set to either true or false. 50 | cygwin=false; 51 | darwin=false; 52 | mingw=false 53 | case "`uname`" in 54 | CYGWIN*) cygwin=true ;; 55 | MINGW*) mingw=true;; 56 | Darwin*) darwin=true 57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 59 | if [ -z "$JAVA_HOME" ]; then 60 | if [ -x "/usr/libexec/java_home" ]; then 61 | export JAVA_HOME="`/usr/libexec/java_home`" 62 | else 63 | export JAVA_HOME="/Library/Java/Home" 64 | fi 65 | fi 66 | ;; 67 | esac 68 | 69 | if [ -z "$JAVA_HOME" ] ; then 70 | if [ -r /etc/gentoo-release ] ; then 71 | JAVA_HOME=`java-config --jre-home` 72 | fi 73 | fi 74 | 75 | if [ -z "$M2_HOME" ] ; then 76 | ## resolve links - $0 may be a link to maven's home 77 | PRG="$0" 78 | 79 | # need this for relative symlinks 80 | while [ -h "$PRG" ] ; do 81 | ls=`ls -ld "$PRG"` 82 | link=`expr "$ls" : '.*-> \(.*\)$'` 83 | if expr "$link" : '/.*' > /dev/null; then 84 | PRG="$link" 85 | else 86 | PRG="`dirname "$PRG"`/$link" 87 | fi 88 | done 89 | 90 | saveddir=`pwd` 91 | 92 | M2_HOME=`dirname "$PRG"`/.. 93 | 94 | # make it fully qualified 95 | M2_HOME=`cd "$M2_HOME" && pwd` 96 | 97 | cd "$saveddir" 98 | # echo Using m2 at $M2_HOME 99 | fi 100 | 101 | # For Cygwin, ensure paths are in UNIX format before anything is touched 102 | if $cygwin ; then 103 | [ -n "$M2_HOME" ] && 104 | M2_HOME=`cygpath --unix "$M2_HOME"` 105 | [ -n "$JAVA_HOME" ] && 106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 107 | [ -n "$CLASSPATH" ] && 108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 109 | fi 110 | 111 | # For Migwn, ensure paths are in UNIX format before anything is touched 112 | if $mingw ; then 113 | [ -n "$M2_HOME" ] && 114 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 115 | [ -n "$JAVA_HOME" ] && 116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 117 | # TODO classpath? 118 | fi 119 | 120 | if [ -z "$JAVA_HOME" ]; then 121 | javaExecutable="`which javac`" 122 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 123 | # readlink(1) is not available as standard on Solaris 10. 124 | readLink=`which readlink` 125 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 126 | if $darwin ; then 127 | javaHome="`dirname \"$javaExecutable\"`" 128 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 129 | else 130 | javaExecutable="`readlink -f \"$javaExecutable\"`" 131 | fi 132 | javaHome="`dirname \"$javaExecutable\"`" 133 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 134 | JAVA_HOME="$javaHome" 135 | export JAVA_HOME 136 | fi 137 | fi 138 | fi 139 | 140 | if [ -z "$JAVACMD" ] ; then 141 | if [ -n "$JAVA_HOME" ] ; then 142 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 143 | # IBM's JDK on AIX uses strange locations for the executables 144 | JAVACMD="$JAVA_HOME/jre/sh/java" 145 | else 146 | JAVACMD="$JAVA_HOME/bin/java" 147 | fi 148 | else 149 | JAVACMD="`which java`" 150 | fi 151 | fi 152 | 153 | if [ ! -x "$JAVACMD" ] ; then 154 | echo "Error: JAVA_HOME is not defined correctly." >&2 155 | echo " We cannot execute $JAVACMD" >&2 156 | exit 1 157 | fi 158 | 159 | if [ -z "$JAVA_HOME" ] ; then 160 | echo "Warning: JAVA_HOME environment variable is not set." 161 | fi 162 | 163 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 164 | 165 | # traverses directory structure from process work directory to filesystem root 166 | # first directory with .mvn subdirectory is considered project base directory 167 | find_maven_basedir() { 168 | 169 | if [ -z "$1" ] 170 | then 171 | echo "Path not specified to find_maven_basedir" 172 | return 1 173 | fi 174 | 175 | basedir="$1" 176 | wdir="$1" 177 | while [ "$wdir" != '/' ] ; do 178 | if [ -d "$wdir"/.mvn ] ; then 179 | basedir=$wdir 180 | break 181 | fi 182 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 183 | if [ -d "${wdir}" ]; then 184 | wdir=`cd "$wdir/.."; pwd` 185 | fi 186 | # end of workaround 187 | done 188 | echo "${basedir}" 189 | } 190 | 191 | # concatenates all lines of a file 192 | concat_lines() { 193 | if [ -f "$1" ]; then 194 | echo "$(tr -s '\n' ' ' < "$1")" 195 | fi 196 | } 197 | 198 | BASE_DIR=`find_maven_basedir "$(pwd)"` 199 | if [ -z "$BASE_DIR" ]; then 200 | exit 1; 201 | fi 202 | 203 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 204 | echo $MAVEN_PROJECTBASEDIR 205 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 206 | 207 | # For Cygwin, switch paths to Windows format before running java 208 | if $cygwin; then 209 | [ -n "$M2_HOME" ] && 210 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 211 | [ -n "$JAVA_HOME" ] && 212 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 213 | [ -n "$CLASSPATH" ] && 214 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 215 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 216 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 217 | fi 218 | 219 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 220 | 221 | exec "$JAVACMD" \ 222 | $MAVEN_OPTS \ 223 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 224 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 225 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 226 | -------------------------------------------------------------------------------- /server/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 40 | 41 | @REM set %HOME% to equivalent of $HOME 42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 43 | 44 | @REM Execute a user defined script before this one 45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 49 | :skipRcPre 50 | 51 | @setlocal 52 | 53 | set ERROR_CODE=0 54 | 55 | @REM To isolate internal variables from possible post scripts, we use another setlocal 56 | @setlocal 57 | 58 | @REM ==== START VALIDATION ==== 59 | if not "%JAVA_HOME%" == "" goto OkJHome 60 | 61 | echo. 62 | echo Error: JAVA_HOME not found in your environment. >&2 63 | echo Please set the JAVA_HOME variable in your environment to match the >&2 64 | echo location of your Java installation. >&2 65 | echo. 66 | goto error 67 | 68 | :OkJHome 69 | if exist "%JAVA_HOME%\bin\java.exe" goto init 70 | 71 | echo. 72 | echo Error: JAVA_HOME is set to an invalid directory. >&2 73 | echo JAVA_HOME = "%JAVA_HOME%" >&2 74 | echo Please set the JAVA_HOME variable in your environment to match the >&2 75 | echo location of your Java installation. >&2 76 | echo. 77 | goto error 78 | 79 | @REM ==== END VALIDATION ==== 80 | 81 | :init 82 | 83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 84 | @REM Fallback to current working directory if not found. 85 | 86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 88 | 89 | set EXEC_DIR=%CD% 90 | set WDIR=%EXEC_DIR% 91 | :findBaseDir 92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 93 | cd .. 94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 95 | set WDIR=%CD% 96 | goto findBaseDir 97 | 98 | :baseDirFound 99 | set MAVEN_PROJECTBASEDIR=%WDIR% 100 | cd "%EXEC_DIR%" 101 | goto endDetectBaseDir 102 | 103 | :baseDirNotFound 104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 105 | cd "%EXEC_DIR%" 106 | 107 | :endDetectBaseDir 108 | 109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 110 | 111 | @setlocal EnableExtensions EnableDelayedExpansion 112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 114 | 115 | :endReadAdditionalConfig 116 | 117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 118 | 119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 121 | 122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 123 | if ERRORLEVEL 1 goto error 124 | goto end 125 | 126 | :error 127 | set ERROR_CODE=1 128 | 129 | :end 130 | @endlocal & set ERROR_CODE=%ERROR_CODE% 131 | 132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 136 | :skipRcPost 137 | 138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 140 | 141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 142 | 143 | exit /B %ERROR_CODE% 144 | -------------------------------------------------------------------------------- /server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.example 7 | demo 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | demo 12 | Demo project for Spring Boot 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 1.5.10.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-data-jpa 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-data-rest 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-starter-web 39 | 40 | 41 | 42 | org.springframework.boot 43 | spring-boot-devtools 44 | runtime 45 | 46 | 47 | com.h2database 48 | h2 49 | runtime 50 | 51 | 52 | org.springframework.boot 53 | spring-boot-starter-test 54 | test 55 | 56 | 57 | 58 | 59 | 60 | 61 | org.springframework.boot 62 | spring-boot-maven-plugin 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /server/src/main/java/com/example/demo/DemoApplication.java: -------------------------------------------------------------------------------- 1 | package com.example.demo; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class DemoApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(DemoApplication.class, args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /server/src/main/java/com/example/demo/beer/Beer.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.beer; 2 | 3 | import javax.persistence.Entity; 4 | import javax.persistence.GeneratedValue; 5 | import javax.persistence.Id; 6 | 7 | @Entity 8 | public class Beer { 9 | 10 | @Id 11 | @GeneratedValue 12 | private Long id; 13 | private String name; 14 | 15 | public Beer() { 16 | } 17 | 18 | public Beer(String name) { 19 | this.name = name; 20 | } 21 | 22 | public Long getId() { 23 | return id; 24 | } 25 | 26 | public void setId(Long id) { 27 | this.id = id; 28 | } 29 | 30 | public String getName() { 31 | return name; 32 | } 33 | 34 | public void setName(String name) { 35 | this.name = name; 36 | } 37 | 38 | @Override 39 | public String toString() { 40 | return "Beer{" + 41 | "id=" + id + 42 | ", name='" + name + '\'' + 43 | '}'; 44 | } 45 | } -------------------------------------------------------------------------------- /server/src/main/java/com/example/demo/beer/BeerCommandLineRunner.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.beer; 2 | 3 | import org.springframework.boot.CommandLineRunner; 4 | import org.springframework.stereotype.Component; 5 | 6 | import java.util.stream.Stream; 7 | 8 | @Component 9 | public class BeerCommandLineRunner implements CommandLineRunner { 10 | 11 | private final BeerRepository repository; 12 | 13 | public BeerCommandLineRunner(BeerRepository repository) { 14 | this.repository = repository; 15 | } 16 | 17 | @Override 18 | public void run(String... strings) throws Exception { 19 | // Top beers from https://www.beeradvocate.com/lists/top/ 20 | Stream.of("Kentucky Brunch Brand Stout", "Good Morning", "Very Hazy", "King Julius", 21 | "Budweiser", "Coors Light", "PBR").forEach(name -> 22 | repository.save(new Beer(name)) 23 | ); 24 | repository.findAll().forEach(System.out::println); 25 | } 26 | } -------------------------------------------------------------------------------- /server/src/main/java/com/example/demo/beer/BeerController.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.beer; 2 | 3 | import org.springframework.web.bind.annotation.CrossOrigin; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | import org.springframework.web.bind.annotation.RestController; 6 | 7 | import java.util.Collection; 8 | import java.util.stream.Collectors; 9 | 10 | @RestController 11 | public class BeerController { 12 | private BeerRepository repository; 13 | 14 | public BeerController(BeerRepository repository) { 15 | this.repository = repository; 16 | } 17 | 18 | @GetMapping("/good-beers") 19 | @CrossOrigin(origins = {"http://localhost:8100","http://localhost:8080"}) 20 | public Collection goodBeers() { 21 | 22 | return repository.findAll().stream() 23 | .filter(this::isGreat) 24 | .collect(Collectors.toList()); 25 | } 26 | 27 | private boolean isGreat(Beer beer) { 28 | return !beer.getName().equals("Budweiser") && 29 | !beer.getName().equals("Coors Light") && 30 | !beer.getName().equals("PBR"); 31 | } 32 | } -------------------------------------------------------------------------------- /server/src/main/java/com/example/demo/beer/BeerRepository.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.beer; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import org.springframework.data.rest.core.annotation.RepositoryRestResource; 5 | import org.springframework.web.bind.annotation.CrossOrigin; 6 | 7 | @RepositoryRestResource 8 | @CrossOrigin(origins = {"http://localhost:8100","http://localhost:8080"}) 9 | interface BeerRepository extends JpaRepository { 10 | } -------------------------------------------------------------------------------- /server/src/main/resources/application.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oktadev/spring-boot-ionic-example/4e48a89c184777dca7d8b15ae9c70bd9a38d1b0f/server/src/main/resources/application.properties -------------------------------------------------------------------------------- /server/src/test/java/com/example/demo/DemoApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.example.demo; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class DemoApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | --------------------------------------------------------------------------------