✨ This workspace has been generated by Nx, a Smart, fast and extensible build system. ✨
Run nx serve frontend
for a dev server and nx serve server
to run the API. Navigate to http://localhost:4200/. The app will automatically reload if you change any of the source files. Note: if nx
is not installed then running npx nx serve frontend
and npx nx serve server
should work.
Run nx graph
to see a diagram of the dependencies of the projects.
Run npx nx connect-to-nx-cloud
to enable remote caching and make CI faster.
Visit the Nx Documentation to learn more.
-
Fork this repository, then clone it down locally, and run
npm i
. -
Connecting your code to firebase
- Create/Sign in to your firebase account.
- Click on 'Go to Console' and then 'Create a Project'.
- Name and create your project, all default settings are fine.
- Go to 'Project Settings' in your firebase app. Scroll down to your apps and select web app. You should see a create web app screen. Name your app and also set up firebase hosting. The next part is confusing, do not follow firebase instructions, follow OUR instructions carefully.
- Copy the
projectId
and paste it infirebase.ts
in thelibs
folder inside the 'settings' constant (we already have most things set up for you). Also copy and pasteauthDomain
,databaseURL
,projectId
, andstorageBucket
infirebase.ts
inapps/frontend/src/app/firebase
(these are also in 'Project Settings' after the app is created if not provided). - Next navigate in firebase to 'Project Settings -> Service Accounts' and generate a new private key. Create a
.env
file in the root directory and add this key (make the entire object is in a string, on one line, and has no spaces). - Delete
.firebaserc
andfirebase.json
files in the root of this directory if you have them. - Run
npm install firebase
, thennpm install -g firebase-tools
, thenfirebase login
, and finallyfirebase init
. While initting your project, select use an existing project and select your project, when selecting features choose; firestore/realtime database/both hostings/storage, use the default files and do not overwrite them, when asked to install dependencies select yes, when asked if you want to use your public directory type indist/apps/frontend
, type yes for a single-page app, and finally type no for automatic builds and deploys. - In firebase navigate from 'Build -> Storage', then click on the 'Rules' tab. Change the
write: if false
towrite: if true
(you may have to click 'Get Started' on this and also on Firestore Database, Realtime Database, Hosting, and Functions). - In your
firebase.json
file inside thehosting
key, change therewrites
section to[ { "source": "/api/**", "function": "apiv1" }, { "source": "**", "destination": "/index.html" } ]
. - In order to host your backend in firebase functions, you must upgrade your firebase project to the 'Blaze' plan. This will include adding a debit/credit card but you will only pay if your app reaches a certain number of API requests.
- After your app is upgraded, we must edit
firebase.json
again. In the 'functions' key, change the 'source' key todist/apps/server-firebase
, this is just changing it from the default to our build folder. Also add"runtime": "nodejs18"
to that 'functions' object. Finally switch outignore
key for"predeploy": []
. Also in yourstorage.rules
change theif false
toif true
. - Once your app is initialized, run
npm run build
and thenfirebase deploy
. If all was done correctly then you should be able to navigate to the URL provided and see our default app. NOTE: Thepackage.json
in thedist/apps/server-firebase
folder should be the same as thepackage.json
inside theapps/server/src
folder. If not then copy thepackage.json
in theapps/server/src
folder and overwrite the same file in thedist/apps/server-firebase
folder.
-
Google Login
- Use this article to help with your apps Google login, https://blog.logrocket.com/guide-adding-google-login-react-app/.
- Make sure when adding trusted sites to use your google app, that you include localhost and your hosted site urls.
- We already included the code in this template, you only have to change the clientId of the GoogleOAuthProvider in 'main.tsx' of the frontend folder.
-
Sengrid for dynamic emails
- We have set up a template for you if you would like to be able to send emails through your app.
- First you must set up a sendgrid account and create your default email account and create all the email templates you need.
- After that you must add to your
.env
file,SENDGRID_API_KEY=${your-api-key}
. - Once completed, you can use the different functions we have already built out in the 'integrations' folder of the backend, specifically
sendDynamicEmail
function.
-
Redeploying
- You can always redeploy your site by using
firebase deploy
. This will simultaneously deploy front and back ends. NOTE: if you havent changedstorage.rules
toif true
then it will be overwritten and cause firebase storage problems. - In order to redeploy our frontend and backend seperately, we must edit one of the 'scripts' in
package.json
. Inside the script,deploy:firebase:api:dev
, change 'nxfirebasetemplate' to your project ID and then runnpm run build
and thennpm run deploy:firebase:api:dev
. This will deploy your backend to firebase functions. - Anytime you make changes and want to redeploy for your hosted site use
npm run build
and thenfirebase deploy --only hosting
for the frontend.
- You can always redeploy your site by using
-
Setting up Auto-deployments
- Go to your Github repository and click on 'Actions', and enable actions in this repository.
- In the terminal use
firebase init hosting:github
, choose your project and select your repository. Select 'yes' when asked to set up a workflow. Overwrite the files and use the basic scripts. You can choose another branch to be your hosting branch but 'main' is just fine. - NOTE: Auto deployments sometimes only deploy to one of the two domains that firebase hosting provides.
-
Structure
apps/server
folder is where everyting is stored for the backend server.- Inside the
src
folder there are two main folders that you will be using,app
andintegrations
. The app folder holds all of the routes that you will be creating, while the integrations folder holds any third party applications, like sendgrid, that you need to create functions for.
-
Creating a Module
- We have provided an example of a 'Blogs' module in the blogs folder.
- Whenever you need to create a new collection of a instance, you should create another folder inside the
app
folder and inside the new folder you need three files: module, controller, and service. You also have to create a collection in your firebase database to correspond to this module. NOTE: it is a good practice to name your folder the same as your collection in firebase. - For example, if I need to create a new collection of 'dogs', then I would create a new folder called
dogs
and then inside I would createdogs.controller.ts
,dogs.module.ts
, anddogs.service.ts
. All CRUD functionality for 'dogs' should primarily go through this module. - The
dogs.module.ts
file is the connector between the routes and the functions that need to be called. In here you will declare the new 'dogs' module, import other necessary modules, controllers, and services. - The
dogs.controller.ts
file is where your routes will be stored. For our 'dogs' example, I would make the base route,'dogs'
, but then I could add other pieces to the url, like':dogId'
, to certain routes to help specify which function I am trying to reach and pass data. NOTE: any route with a':'
in it represents a variable/parameter that helps pass data. - The
dogs.service.ts
file is where the functions that your routes call are stored. This is the file that should call our prebuilt firebase functions. These functions are stored inlibs/firebase/src/lib/firebase.ts
, and they do the editting of your firebase database. - Once all these files are built, the last step is to import your module to
app.module.ts
and then add it to the imports section of theAppModule
. NOTE: if your server is running make sure to restart it before testing if your routes are working.
- In the
frontend/src/app
folder, you can use every subfolder available and yourapp.tsx
file is your base for the frontend. We will run through what each subfolder is used for. - The
api-client
folder is where you will keep your functions that communicate with your backend. In theindex.ts
file you will see that it is already set up to send requests. Anytime you create a new collection of an instance, you should create a new file in theapiModules
subfolder that holds any functions associated with that collection and create a new 'apiEndpoint' inindex.ts
. NOTE: when creating new collection functions, follow the blogs functions layout. - The
components
folder is where you will store highly reuseable and dynamic components. These components are usually stuff you would copy from places like 'tailwind'. The point of keeping them here is to be able to easily import them all over your app. NOTE: nothing in these components should be hard coded, this is to ensure reuseability. - The
firebase
folder is specific to only one purpose, accessing the firebase storage. Firebase storage is frontend oriented and is made for storing documents, images, or other files. - The
images
folder is self-explanatory, store you images here for easy access and importing. - The
shared
folder is for functions that are used everywhere. Storing validation functions or string parsers here is useful as long as they are dynamic and able to be used around the app. - The
views
folder is where most of your work will go. This folder holds all of the different components that build your frontend. Each different component is seperated into its own folder for readability and organization. These folders will hold all 'views' of each component as well as css files and utility files. This folder also contains the router folder, which is the folder that indicates what component corresponds to what url. NOTE: anytime any of these views change, the server will auto update so no need to restart to see the changes.
- Use Prettier to format your code. To get Prettier go to the 'Extensions' sidebar in Visual studio Code and search and install Prettier.
- Use ESLint to check your code for bugs. Get ESLint in the 'Extensions' sidebar.
- We use TypeScript instead of JavaScript in order to help keep functions in order and organized. Since we use TypeScript, creating interfaces or using correct types can save a lot of headache from moving data around incorrectly.
- Testing your code. Two folders are provided for you to create tests for your code,
server-e2e
andfrontend-e2e
. - Building tests are a great way to make sure any edits in your code do not accidentally break something elsewhere. To use run
npx nx e2e SPECIFIC-FOLDER --skip-cache
. - Coding some tests on the frontend require a backend, like the tests provided in
frontend-e2e
folder (tests that require CRUD functionality). This means that you must have your localhost backend running when calling this folder to test the application. NOTE: in thetests.yml
file there is an example of how to have your backend server running while you use the testing command. - To get CRUD functionality working in Github actions we need to first set up some Github secrets. In your repo go to 'Settings' -> 'Secrets and variables' -> 'Actions' and create a new secret called
FIREBASE_ADMINSDK_KEY
and then set it to the value in your.env
file. Next we have to allow your Google Project to allow Github access. To do this create another secret and call itGCP_PRIVATE_KEY
and set it to your Google Cloud Key. NOTE: if you do not have the key saved somewhere, then you can just create a new one, go to the google cloud console and select your project, navigate to 'IAM & Admin' -> 'Service Accounts' -> 'Keys' and create a JSON key.
To begin contributing to the project, follow these steps:
-
Clone the main branch and switch to the "AT" branch:
git clone https://github.com/tirzah-dev/WOL-Planner.git
git checkout AT
-
Create a new branch from the "AT" branch for your changes. For example:
git checkout -b setup
-
Install project dependencies:
npm i
-
Create a
.env
file at the root of the directory:touch .env
-
Reach out to the Project Manager for the necessary content to populate the
.env
file.
Once set up, you can start the frontend and backend servers for testing:
-
Start the backend server:
npx nx serve server
-
Open another terminal and start the frontend server:
npx nx serve frontend
For more information on installing Nx into an existing repository, refer to the Installing Nx guide:
- Initialize Nx in your project:
npx nx@latest init
Please note that instead of npx nx serve server
, you can use nx serve server
and nx serve frontend
.