├── .gitignore
├── README.md
├── angular.json
├── browserslist
├── e2e
├── protractor.conf.js
├── src
│ ├── app.e2e-spec.ts
│ └── app.po.ts
└── tsconfig.json
├── img
└── calendar.png
├── ionic.config.json
├── karma.conf.js
├── package-lock.json
├── package.json
├── src
├── app
│ ├── app-routing.module.ts
│ ├── app.component.html
│ ├── app.component.scss
│ ├── app.component.ts
│ ├── app.module.ts
│ └── home
│ │ ├── home.module.ts
│ │ ├── home.page.html
│ │ ├── home.page.scss
│ │ └── home.page.ts
├── assets
│ ├── icon
│ │ └── favicon.png
│ └── shapes.svg
├── environments
│ ├── environment.prod.ts
│ └── environment.ts
├── global.scss
├── index.html
├── main.ts
├── polyfills.ts
├── test.ts
├── theme
│ └── variables.scss
└── zone-flags.ts
├── tsconfig.app.json
├── tsconfig.json
├── tsconfig.spec.json
├── tslint.json
└── typings
└── cordova-typings.d.ts
/.gitignore:
--------------------------------------------------------------------------------
1 | /.angular/cache
2 | # Specifies intentionally untracked files to ignore when using Git
3 | # http://git-scm.com/docs/gitignore
4 |
5 | *~
6 | *.sw[mnpcod]
7 | .tmp
8 | *.tmp
9 | *.tmp.*
10 | *.sublime-project
11 | *.sublime-workspace
12 | .DS_Store
13 | Thumbs.db
14 | UserInterfaceState.xcuserstate
15 | $RECYCLE.BIN/
16 |
17 | *.log
18 | log.txt
19 | npm-debug.log*
20 |
21 | /.idea
22 | /.ionic
23 | /.sass-cache
24 | /.sourcemaps
25 | /.versions
26 | /.vscode
27 | /coverage
28 | /dist
29 | /node_modules
30 | /platforms
31 | /plugins
32 | /www
33 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # :zap: Ionic Angular Calendar
2 |
3 | * App to show an Ionic calendar with events stored in Firebase. This is another great tutorial from [Jameson Saunders of JamiBot, Youtube video 'Ionic 4 Custom Calendar Tutorial'](https://www.youtube.com/watch?v=SYz-tH3XOF8&t=766s) that I have updated.
4 |
5 | 
6 | 
7 | 
8 | 
9 |
10 | ## :page_facing_up: Table of contents
11 |
12 | * [:zap: Ionic Angular Calendar](#zap-ionic-angular-calendar)
13 | * [:page_facing_up: Table of contents](#page_facing_up-table-of-contents)
14 | * [:books: General info](#books-general-info)
15 | * [:camera: Screenshots](#camera-screenshots)
16 | * [:signal_strength: Technologies](#signal_strength-technologies)
17 | * [:floppy_disk: Setup](#floppy_disk-setup)
18 | * [:computer: Code Examples](#computer-code-examples)
19 | * [:cool: Features](#cool-features)
20 | * [:clipboard: Status & To-do list](#clipboard-status--to-do-list)
21 | * [:clap: Inspiration](#clap-inspiration)
22 | * [:file_folder: License](#file_folder-license)
23 | * [:envelope: Contact](#envelope-contact)
24 |
25 | ## :books: General info
26 |
27 | * Uses the [ionic2-calendar](https://www.npmjs.com/package/ionic2-calendar) package to display events input by the user.
28 | * This app is set up to use a Google Firebase backend to store calender entries.
29 |
30 | ## :camera: Screenshots
31 |
32 | 
33 |
34 | ## :signal_strength: Technologies
35 |
36 | * [Ionic v6](https://ionicframework.com/)
37 | * [Ionic/angular v6](https://ionicframework.com/)
38 | * [Angular v15](https://angular.io/)
39 | * [ionic2-calendar v0.6.9](https://www.npmjs.com/package/ionic2-calendar)
40 | * [Angular/Fire v7](https://www.npmjs.com/package/@angular/fire) for Google Firebase Database connection.
41 |
42 | ## :floppy_disk: Setup
43 |
44 | * Create a Google Firebase database and add access credentials to environment.ts
45 | * To start the server on _localhost://8100_ type: 'ionic serve'
46 | * To start the server on a mobile using Ionic devapp and connected via wifi, type: 'ionic serve --devapp'
47 | * The Ionic DevApp was installed on an Android device from the Google Play app store.
48 |
49 | ## :computer: Code Examples
50 |
51 | * function to add a new event - including start and end time. Title is derived from seconds and is intended to create semi-random data.
52 |
53 | ```typescript
54 | addNewEvent() {
55 | const start = this.selectedDate;
56 | const end = this.selectedDate;
57 | end.setMinutes(end.getMinutes() + 60);
58 |
59 | const event = {
60 | title: 'Event #' + start.getMinutes(),
61 | startTime: start,
62 | endTime: end,
63 | allDay: false
64 | };
65 |
66 | this.db.collection('events').add(event);
67 | }
68 | ```
69 |
70 | ## :cool: Features
71 |
72 | * Google Firebase storage of calendar events. Data is retrieved from Firebase in the constructor function at the beginning of the page lifecycle.
73 | * Calender date format can be changed using options from the ionic2-calender.
74 |
75 | ## :clipboard: Status & To-do list
76 |
77 | * Status: Working
78 | * To-do: A lot more complexity can be added to this calendar app. The option to change the view from day to week to month would be useful - as shown in the [demo project](https://github.com/twinssbc/Ionic2-Calendar/tree/v5/demo).
79 |
80 | ## :clap: Inspiration
81 |
82 | * [Jameson Saunders of JamiBot, Youtube video 'Ionic 4 Custom Calendar Tutorial'](https://www.youtube.com/watch?v=SYz-tH3XOF8&t=766s)
83 | * [Ionic2-Calendar github repo](https://github.com/twinssbc/Ionic2-Calendar)
84 | * [demo project](https://github.com/twinssbc/Ionic2-Calendar/tree/v5/demo).
85 |
86 | ## :file_folder: License
87 |
88 | * N/A
89 |
90 | ## :envelope: Contact
91 |
92 | * Repo created by [ABateman](https://github.com/AndrewJBateman), email: gomezbateman@yahoo.com
93 |
--------------------------------------------------------------------------------
/angular.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3 | "version": 1,
4 | "newProjectRoot": "projects",
5 | "projects": {
6 | "app": {
7 | "root": "",
8 | "sourceRoot": "src",
9 | "projectType": "application",
10 | "prefix": "app",
11 | "schematics": {},
12 | "architect": {
13 | "build": {
14 | "builder": "@angular-devkit/build-angular:browser",
15 | "options": {
16 | "outputPath": "www",
17 | "index": "src/index.html",
18 | "main": "src/main.ts",
19 | "polyfills": "src/polyfills.ts",
20 | "tsConfig": "tsconfig.app.json",
21 | "assets": [
22 | {
23 | "glob": "**/*",
24 | "input": "src/assets",
25 | "output": "assets"
26 | },
27 | {
28 | "glob": "**/*.svg",
29 | "input": "node_modules/ionicons/dist/ionicons/svg",
30 | "output": "./svg"
31 | }
32 | ],
33 | "styles": [
34 | {
35 | "input": "src/theme/variables.scss",
36 | "inject": true
37 | },
38 | {
39 | "input": "src/global.scss",
40 | "inject": true
41 | }
42 | ],
43 | "scripts": [],
44 | "aot": false,
45 | "vendorChunk": true,
46 | "extractLicenses": false,
47 | "buildOptimizer": false,
48 | "sourceMap": true,
49 | "optimization": false,
50 | "namedChunks": true
51 | },
52 | "configurations": {
53 | "production": {
54 | "fileReplacements": [
55 | {
56 | "replace": "src/environments/environment.ts",
57 | "with": "src/environments/environment.prod.ts"
58 | }
59 | ],
60 | "optimization": true,
61 | "outputHashing": "all",
62 | "sourceMap": false,
63 | "namedChunks": false,
64 | "aot": true,
65 | "extractLicenses": true,
66 | "vendorChunk": false,
67 | "buildOptimizer": true,
68 | "budgets": [
69 | {
70 | "type": "initial",
71 | "maximumWarning": "2mb",
72 | "maximumError": "5mb"
73 | }
74 | ]
75 | },
76 | "ci": {
77 | "progress": false
78 | },
79 | "development": {}
80 | },
81 | "defaultConfiguration": "production"
82 | },
83 | "serve": {
84 | "builder": "@angular-devkit/build-angular:dev-server",
85 | "options": {
86 | "browserTarget": "app:build:development"
87 | },
88 | "configurations": {
89 | "production": {
90 | "browserTarget": "app:build:production"
91 | },
92 | "ci": {
93 | },
94 | "development": {
95 | "browserTarget": "app:build:development"
96 | }
97 | },
98 | "defaultConfiguration": "development"
99 | },
100 | "extract-i18n": {
101 | "builder": "@angular-devkit/build-angular:extract-i18n",
102 | "options": {
103 | "browserTarget": "app:build"
104 | }
105 | },
106 | "test": {
107 | "builder": "@angular-devkit/build-angular:karma",
108 | "options": {
109 | "main": "src/test.ts",
110 | "polyfills": "src/polyfills.ts",
111 | "tsConfig": "tsconfig.spec.json",
112 | "karmaConfig": "karma.conf.js",
113 | "styles": [],
114 | "scripts": [],
115 | "assets": [
116 | {
117 | "glob": "favicon.ico",
118 | "input": "src/",
119 | "output": "/"
120 | },
121 | {
122 | "glob": "**/*",
123 | "input": "src/assets",
124 | "output": "/assets"
125 | }
126 | ]
127 | },
128 | "configurations": {
129 | "ci": {
130 | "progress": false,
131 | "watch": false
132 | }
133 | }
134 | },
135 | "e2e": {
136 | "builder": "@angular-devkit/build-angular:protractor",
137 | "options": {
138 | "protractorConfig": "e2e/protractor.conf.js"
139 | },
140 | "configurations": {
141 | "production": {
142 | "devServerTarget": "app:serve:production"
143 | },
144 | "ci": {
145 | "devServerTarget": "app:serve:ci"
146 | },
147 | "development": {
148 | "devServerTarget": "app:serve:development"
149 | }
150 | },
151 | "defaultConfiguration": "development"
152 | },
153 | "ionic-cordova-build": {
154 | "builder": "@ionic/angular-toolkit:cordova-build",
155 | "options": {
156 | "browserTarget": "app:build"
157 | },
158 | "configurations": {
159 | "production": {
160 | "browserTarget": "app:build:production"
161 | }
162 | }
163 | },
164 | "ionic-cordova-serve": {
165 | "builder": "@ionic/angular-toolkit:cordova-serve",
166 | "options": {
167 | "cordovaBuildTarget": "app:ionic-cordova-build",
168 | "devServerTarget": "app:serve"
169 | },
170 | "configurations": {
171 | "production": {
172 | "cordovaBuildTarget": "app:ionic-cordova-build:production",
173 | "devServerTarget": "app:serve:production"
174 | }
175 | }
176 | }
177 | }
178 | }
179 | },
180 | "cli": {
181 | "schematicCollections": [
182 | "@ionic/angular-toolkit"
183 | ]
184 | },
185 | "schematics": {
186 | "@ionic/angular-toolkit:component": {
187 | "styleext": "scss"
188 | },
189 | "@ionic/angular-toolkit:page": {
190 | "styleext": "scss"
191 | }
192 | }
193 | }
194 |
--------------------------------------------------------------------------------
/browserslist:
--------------------------------------------------------------------------------
1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
2 | # For additional information regarding the format and rule options, please see:
3 | # https://github.com/browserslist/browserslist#queries
4 |
5 | # You can see what browsers were selected by your queries by running:
6 | # npx browserslist
7 |
8 | > 0.5%
9 | last 2 versions
10 | Firefox ESR
11 | not dead
12 | not IE 9-11 # For IE 9-11 support, remove 'not'.
13 |
--------------------------------------------------------------------------------
/e2e/protractor.conf.js:
--------------------------------------------------------------------------------
1 | // Protractor configuration file, see link for more information
2 | // https://github.com/angular/protractor/blob/master/lib/config.ts
3 |
4 | const { SpecReporter } = require('jasmine-spec-reporter');
5 |
6 | exports.config = {
7 | allScriptsTimeout: 11000,
8 | specs: [
9 | './src/**/*.e2e-spec.ts'
10 | ],
11 | capabilities: {
12 | 'browserName': 'chrome'
13 | },
14 | directConnect: true,
15 | baseUrl: 'http://localhost:4200/',
16 | framework: 'jasmine',
17 | jasmineNodeOpts: {
18 | showColors: true,
19 | defaultTimeoutInterval: 30000,
20 | print: function() {}
21 | },
22 | onPrepare() {
23 | require('ts-node').register({
24 | project: require('path').join(__dirname, './tsconfig.json')
25 | });
26 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
27 | }
28 | };
29 |
--------------------------------------------------------------------------------
/e2e/src/app.e2e-spec.ts:
--------------------------------------------------------------------------------
1 | import { AppPage } from './app.po';
2 |
3 | describe('new App', () => {
4 | let page: AppPage;
5 |
6 | beforeEach(() => {
7 | page = new AppPage();
8 | });
9 |
10 | it('should be blank', () => {
11 | page.navigateTo();
12 | expect(page.getParagraphText()).toContain('The world is your oyster.');
13 | });
14 | });
15 |
--------------------------------------------------------------------------------
/e2e/src/app.po.ts:
--------------------------------------------------------------------------------
1 | import { browser, by, element } from 'protractor';
2 |
3 | export class AppPage {
4 | navigateTo() {
5 | return browser.get('/');
6 | }
7 |
8 | getParagraphText() {
9 | return element(by.deepCss('app-root ion-content')).getText();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/e2e/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../out-tsc/app",
5 | "module": "commonjs",
6 | "target": "es5",
7 | "types": [
8 | "jasmine",
9 | "jasminewd2",
10 | "node"
11 | ]
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/img/calendar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndrewJBateman/ionic-angular-calendar/ec5246140e50cd56d177812812e757657ae8b681/img/calendar.png
--------------------------------------------------------------------------------
/ionic.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ionic-angular-calendar",
3 | "integrations": {},
4 | "type": "angular"
5 | }
6 |
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | // Karma configuration file, see link for more information
2 | // https://karma-runner.github.io/1.0/config/configuration-file.html
3 |
4 | module.exports = function (config) {
5 | config.set({
6 | basePath: '',
7 | frameworks: ['jasmine', '@angular-devkit/build-angular'],
8 | plugins: [
9 | require('karma-jasmine'),
10 | require('karma-chrome-launcher'),
11 | require('karma-jasmine-html-reporter'),
12 | require('karma-coverage-istanbul-reporter'),
13 | require('@angular-devkit/build-angular/plugins/karma')
14 | ],
15 | client: {
16 | clearContext: false // leave Jasmine Spec Runner output visible in browser
17 | },
18 | coverageIstanbulReporter: {
19 | dir: require('path').join(__dirname, '../coverage'),
20 | reports: ['html', 'lcovonly', 'text-summary'],
21 | fixWebpackSourcePaths: true
22 | },
23 | reporters: ['progress', 'kjhtml'],
24 | port: 9876,
25 | colors: true,
26 | logLevel: config.LOG_INFO,
27 | autoWatch: true,
28 | browsers: ['Chrome'],
29 | singleRun: false
30 | });
31 | };
32 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ionic-angular-calendar",
3 | "version": "0.0.1",
4 | "author": "Ionic Framework",
5 | "homepage": "https://ionicframework.com/",
6 | "scripts": {
7 | "ng": "ng",
8 | "start": "ng serve",
9 | "build": "ng build",
10 | "test": "ng test",
11 | "lint": "ng lint",
12 | "e2e": "ng e2e"
13 | },
14 | "private": true,
15 | "dependencies": {
16 | "@angular/common": "^15.1.0",
17 | "@angular/compiler": "^15.1.0",
18 | "@angular/core": "^15.1.0",
19 | "@angular/fire": "^7.5.0",
20 | "@angular/forms": "^15.1.0",
21 | "@angular/platform-browser": "^15.1.0",
22 | "@angular/platform-browser-dynamic": "^15.1.0",
23 | "@angular/router": "^15.1.0",
24 | "@ionic-native/core": "^5.36.0",
25 | "@ionic-native/splash-screen": "^5.36.0",
26 | "@ionic-native/status-bar": "^5.36.0",
27 | "@ionic/angular": "^6.4.2",
28 | "ajv": "^8.12.0",
29 | "core-js": "^3.27.1",
30 | "firebase": "^9.15.0",
31 | "ionic2-calendar": "^0.6.9",
32 | "promise-polyfill": "^8.2.3",
33 | "rxjs": "^7.8.0",
34 | "rxjs-compat": "^6.6.7",
35 | "tslib": "^2.4.1",
36 | "zone.js": "^0.12.0"
37 | },
38 | "devDependencies": {
39 | "@angular-devkit/architect": "^0.1501.1",
40 | "@angular-devkit/build-angular": "^15.1.1",
41 | "@angular-devkit/core": "^15.1.1",
42 | "@angular-devkit/schematics": "^15.1.1",
43 | "@angular/cli": "^15.1.1",
44 | "@angular/compiler-cli": "^15.1.0",
45 | "@angular/language-service": "^15.1.0",
46 | "@ionic/angular-toolkit": "^7.0.0",
47 | "@types/jasmine": "~4.3.1",
48 | "@types/jasminewd2": "~2.0.10",
49 | "@types/node": "~18.11.18",
50 | "codelyzer": "^6.0.2",
51 | "jasmine-core": "~4.5.0",
52 | "jasmine-spec-reporter": "~7.0.0",
53 | "karma": "~6.4.1",
54 | "karma-chrome-launcher": "~3.1.1",
55 | "karma-coverage-istanbul-reporter": "~3.0.3",
56 | "karma-jasmine": "~5.1.0",
57 | "karma-jasmine-html-reporter": "^2.0.0",
58 | "protractor": "~7.0.0",
59 | "ts-node": "~10.9.1",
60 | "tslint": "~6.1.3",
61 | "typescript": "~4.8.4"
62 | },
63 | "description": "An Ionic project"
64 | }
65 |
--------------------------------------------------------------------------------
/src/app/app-routing.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { PreloadAllModules, RouterModule, Routes } from '@angular/router';
3 |
4 | const routes: Routes = [
5 | { path: '', redirectTo: 'home', pathMatch: 'full' },
6 | { path: 'home', loadChildren: () => import('./home/home.module').then( m => m.HomePageModule)},
7 | ];
8 |
9 | @NgModule({
10 | imports: [
11 | RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })
12 | ],
13 | exports: [RouterModule]
14 | })
15 | export class AppRoutingModule { }
16 |
--------------------------------------------------------------------------------
/src/app/app.component.html:
--------------------------------------------------------------------------------
1 |