:clipboard: Angular Material & RxJS Observables are used to display my data. A Google Cloud Firestore NoSQL database stores the blog posts & website data. Anyone can read the blog posts.
Responsive: grid of Angular Material mat-cards using Breakpoint detection
Navbars: Top/side navbars with page routing & links to Github & LinkedIn. Dark mode can be selected
Footer with date & link to Build information page
Build Data info. on main app dependencies
Home: Angular Tab Groups/Material card grid to display data, using data-binding from an array of 'areas' based on an Area model.
Projects: card grid to display project data using data-binding from an array of projects based on a Project model.
Skills: card grid to display project data using data-binding from an array of skills based on a Skill model.
Contact: Simple form that user can fill in with name, email and comment. Input validation is included - Send button disabled if form incomplete/incorrect. Buttons to navigate to previous page and to clear the form. The data is sent to the app Firestore backend using angularfire-lite and a success message is returned once sending is complete. Large buttons allow user to return to Home page or send another message (which actually navigates 'back' to the same page presenting a clear form).
Posts: Posts are stored in the app Firebase DB and displayed using mat-tabs.
Mat-cards now display Post title, subtitle, content, time to read (calculated using a simple Angular pipe) and how old the post is (another pipe using the npm module Day.js). The Post Detail page includes the post image, Blog Detail and the footer includes an image credit with web link to the authors page and date published info.
Not Found: In the event of the user trying to route to any page address that is not listed in the router-module a single Mat-card will display a message to the user. There is a simple button to reroute the user to the Home page.
RxJS share used to multicast (share) the original Observable with multiple subscribers to prevent more than one http fetch of Posts data in a user session - the Posts data does not change that frequently so this avoids wasting a user's mobile data quota with unnecessary http data requests
Dayjs v1 to convert Github UTC Timestamp to '... ago'
Webpack Bundle Analyser v4 to create an 'interactive treemap visualization of the contents of all your bundles.
ng serve for a dev server. Navigate to http://localhost:4200/. The app will automatically reload if you change any of the source files
npm run build to create build file with Ahead of Time (AOT) compilation. Source map explorer set to false
If source map explorer was set to true when build folder created: npm run explore to run the webpack-bundle-analyzer - opens bundle analysis drawing
http-server -g -b -p 8080 dist/angular-material-portfolio/browser to run build files on test server port 8080 using the GZip & Brottli files
firebase deploy to deploy build file to firebase hosting
firebase login --reauth if firebase deploy not working and it shows you are logged in but in fact login token is stale
π» Code Examples
core/services/breakpoint.service.ts extracted BreakpointObserver service to provide breakpoint information to components
/** * BreakpointService provides information about current viewport size breakpoints. * It uses Angular CDK BreakpointObserver to get breakpoint state, and maps it to * a number of grid columns to use for grid layouts. */exportclassBreakpointService{breakpointObserver=inject(BreakpointObserver);// return number of grid columns based on user screen size breakpoint, default 4breakpointColumnNr$=this.breakpointObserver.observe([Breakpoints.XSmall,Breakpoints.Small,Breakpoints.Medium]).pipe(map(state=>state.breakpoints[Breakpoints.XSmall]
? BreakpointSize.XSmall
: state.breakpoints[Breakpoints.Small]
? BreakpointSize.Small
: state.breakpoints[Breakpoints.Medium]
? BreakpointSize.Medium
: BreakpointSize.Large),shareReplay(1));}
π Features
common Grid card layouts with data from a shared firebase database service
latest Angular 17 control flows replace '*ngIf' and '*ngFor'
local storage dark mode and post mat-tab active settings stored so still there after refresh
π Status & To-Do List
Status: Working, deployed to Firebase. ighthouse performance 90%, accessibility 100%, Best Practises: 100%, SEO 100% & working PWA
To-Do: General: fix index CSP, add text compression, reduce unused JS, cache policy 1 year?
To-Do: Skills: add more skills, PLC programming Beckhoff...
To-Do: Improve lighthouse performance score: remove unused CSS and redo small images.
To-Do: Projects: Terracota project, add to Node projects, add Docker/Java/IoT.. projects. Serve static assets with an efficient cache policy
To-Do: Posts: Unsplash images - use sizing website.
To-Do: SCSS - reorganise
To-Do: Colors: Add to styles SCSS to reduce repeated scss throughout app.
This project is licensed under the terms of the MIT license.
βοΈ Contact
Repo created by ABateman, email: gomezbateman@yahoo.com
About
:clipboard: Angular Material & RxJS Observables are used to display my data. A Google Cloud Firestore NoSQL database stores the blog posts & website data. Anyone can read the blog posts.