-
Notifications
You must be signed in to change notification settings - Fork 1
Documentation by Features
See Bill Generation
Overview: Onboarding is the app's sign-up process. It takes a user through filling in all the information that we need from a new General Owner. It is composed of 1 primary component and a number of step components.
The first step of the onboarding process creates a user, after the first step, an owner may log out and come back to finish onboarding later at any time. When they want to come back, they simply log in with the credentials they made.
Onboarding.js
This is the primary component that represents all onboarding screens. It keeps track of all the onboarding user's data as they go through the process
Functions:
-
constructor
: This function sets up the initial owner. If the user has just started to sign up, they are classified as a general owner with 1 share that is receiving dividends. The -
componentDidMount
/componentDidUpdate
: these two functions ensure that when the component comes on the screen, it keeps the values in state are synchronized with the values stored in redux. -
refreshState
: This function takes the owner values from props (Redux) and pulls them into state. This happens when a user returns to onboarding after logging out. Redux stores the logged-in user's data, and this step is necessary to make sure the user sees all their old data.- If the user is logged in, it simply copies the owner object from props to state
- If the user is not logged in, it checks to see if the URL has an invite token. If it does, it tries to find an unused pledge invite and pre-populates some of the fields.
-
nextStep
: This function is the brain of onboarding, when a user wants to move on to the next step, this function is called. Every time a user moves forward a step, their info is validated and updated in Airtable. It does the following:- It finds the list of fields that belong to the current step of the onboarding process and validates them using the validators in
onboardingUtils.js
. - If there are errors, it updates state with those messages, if not, it creates a new owner object
- If the user had an invite code, it adds the pre-populated fields to the new object and marks the invite as "Used"
- It then calls
updateOwnerFields
fromonboardingUtils.js
which either creates a new owner object if it doesn't exist (on step 1) or updates an existing owner object with only the fields infieldsToUpdate
.updateOwnerFields
also increments theonboardingStep
variable. -
updateOwnerFields
prompts redux to refresh its data which passes new props to the Onboarding component. This triggersrefreshState
which will update the view for the user.
- It finds the list of fields that belong to the current step of the onboarding process and validates them using the validators in
-
prevStep
: This function lets the owner go back a step, validation and update only happens a user goes forward. To go back, we simply decrement the onboarding step -
handleChange
: this function handles updates to the fields of the owner. It does not validate the fields, but it does perform some extra formatting tasks needed for edge cases -
onFinish
: When the user finishes onboarding, we update the user's onboarding step to -1 and refresh. An onboarding step of-1
represents a completed onboarding and will send the user to their dashboard. -
render
: The render function renders the current step that the owner is on. The component comes fromOnboardingData.js
All the onboarding steps work very similarly. They are all form components. When a value is changed, they call the handleChange
function passed down from Onboarding.js
. When they want to move on to the next or previous step, they call nextStep
or prevStep
.
The data for the onboarding steps (namely, which component they use and what fields should be updated in the process) are all stored in OnboardingData.js
.
Onboarding Validation happens in onboardingUtils.js
In the file, there are a number of validation functions. These functions take in a value and return either an error message or an empty string (if there is no error). Some take an optional second parameter as a default error message.
The variable ValidatorData
then maps field names to the validators that they need to pass. validateField
ensures that all the validators associated with a field pass and it returns any error messages
Overview: This is the landing page that users first see when they log in. It's a place where they can see an overview of various other pages, like project news, investments, and their environmental impact.
Components:
There are various components used on this page, which are listed below:
- Announcements List: Depending on what project group the user in, this will return a list of announcements under "Project News" on the homepage. It is displayed in order of most recent at the top.
- Production Equivalencies Chart: This displays the chart under "Solar Projects". It shows a graph with how much energy was produced over a span of 4 months, and underneath, various cards that change automatically showing statistics on how the energy created impacts the environment.
- Investment Widget: Shows how many shares the user owns, along with a progress bar implying what percentage it is out of the maximum 10 shares a user can have.
Functionality:
Here are functionalities broken down by component/page:
-
AnnouncementList.js
:- list: A constant that goes through the announcements for the user and formats them into the announcement card. It returns a list of the formatted cards to be displayed on the dashboard page.
- ProductionEquivalenciesChart.js:
-
renderEquivalencyOne()
,renderEquivalencyTwo()
,renderEquivalencyThree()
: Returns 3 different statistics based on the energy produced by solar panels. They are the green, pink and yellow cards under the chart in "Solar Projects". -
renderEquivalency()
: Uses the 3 cards rendered by the functions above and returns them with transitions that change the cards automatically.
-
Overview:
On this page, subscribers are able to see a summary of billing, a chart of how the cost of people power compares to the cost of PG&E, and a list of recent project news.
Components:
There are various components used on this page, which are listed below:
-
DashboardBilling
: This component is related to the billing section of the subscriber dashboard. The user is able to see current balance, make a payment, see recent transactions, and go to more transactions. -
DashboardCharts
: This component is related to the charts section of the subscriber dashboard. This is where the subscriber will see the cost difference between using people power as opposed to PG&E. -
DashboardProjectNews
: This component is related to the project news section of the subscriber dashboard. This is where the subscriber will see the most recent news specific to their project group. -
TransactionTable
: This component displays the Transaction table in the Billing section of the dashboard. -
PaymentButton.js
: This file is rendered whenever the paypal button is rendered on the dashboard.
Functionality:
Here are functionalities broken down by component/page:
-
SubscriberDashboard.js
:-
componentDidMount()
: This function retrieves the subscriber's transaction information and effective cost data and sets it in state. -
seeAllBills()
: This function sends the subscriber to the view all transactions view in billing.
-
- DashboardCharts.js:
-
switchChartView()
: If the subscriber is a part of a community solar project, they will be able to switch charts between 'My Solar Project' and 'Community Solar Projects'. This function switches the user between the 2 chart views.
-
-
DashboardProjectNews.js
: This file renders the project news section -
DashboardBilling.js
: This file renders the billing section -
subscriberUtils.js
:-
formatAmount()
: This function returns the amount input in the correct form with 2 decimal places. -
createTransactionFromPayment()
: This function returns an object in the correct form from the payments retrieved from airtable -
createTransactionFromBill()
: This function returns an object in the correct form from the bills retrieved from airtable -
isBillPayment()
: This function returns whether a payment is a bill type. -
round()
: This function rounds a number to a specific number of decimal places. -
getEffectiveCostData()
: This function calculates the effective cost data. It retrieves the bills of the subscriber. Then it converts them to the correct date using moment. and returns the data points for the effective cost chart. -
getSubscriberTransactionData()
: This function gets all the active bills and transactions of the user which is used to displayed in the Billing section of the subscriber dashboard
-
Overview: Billing is the section of the app that lets subscribers manage and pay their bills. There are a few main pages: Main Bills View, All Bills View, Bill Payment.
This is the overarching component for the billing page. Its main purpose is to display one of two views: the main view and the all bills view.
Functions:
-
constructor
: this function sets up the component's initial state. This page accepts an optional query parameter to set the default view. The constructor reads it in from props and sets the initial state with it -
refreshState
: This function gets the subscriber's transaction data (including bills and payments) and the latest bill.
This page renders a summary of the subscriber's latest bill and the transactions they have. It makes use of the TransactionsTable
component. It only shows 6 rows of the table.
This page just renders the TransactionsTable
component. It renders all rows as well as pagination.
This page lets a user pay off a portion of their bill. It's only available if the user has an active bill.
Functions:
-
componentDidMount
: In this function, we get the active bill. Until this happens, a loading animation is shown -
onChangePaymentAmount
: this function handles the event when the user changes the how much of the bill they want to pay off. TheprocessCurrencyInput
formats the output in a nice manner. -
onPaymentSuccess
: When the Paypal payment succeeds, this function is called which shows the success screen and records the bill payment. -
render
: The render function renders the component. We us thePayPalButton
component from the react-paypal-button-v2 library
This is a helper component that renders a table of transactions using the ReactTable library. It's used in multiple places in the codebase and exposes some props to help fit different use cases, including:
-
fieldsToShow
: which decides which fields will have columns in the table -
numRows
: determining how many rows to show -
showHeader
: whether to show the header -
transactions
: the data in the table
Overview:
This page is where users can see everything related to their investments, including information related to the amount of shares they own and having the option to buy more, their dividend preferences, their past transactions, and how their money is being used through the investment breakdown graph.
Components:
There are various components used on this page, which are listed below:
- Shares Progress Bar (Investment Widget): This is the icon with how many shares the user owns with a pink circle bar surrounding it implying what percentage it is out of the maximum 10 shares a user can have.
- Buy Shares Button & Page: Upon clicking the "Buy Shares" button, it will route the user to a page where they can choose to buy more shares. The components used on the Buy Shares page include a Shares Progress Bar and a PayPal button to complete their payment.
- Transactions List: This is a list that shows all the payments related to shares and dividends that a user makes. It will not show any bill payments. It displays the type of payment, the date it was made, the quantity of shares bought, and the amount in dollars.
- Investment Breakdown Graph: This graph will pull section titles, colors and percentages from the Airtable. It is made using the HighChar package.
Functionality: Here are functionalities broken down by component/page:
-
Investment.js
:-
refreshState()
: This function gets called to update info to display on screen, eg. when someone changes their dividends preferences. Since information like whether -
submitPreference()
: This is a function that gets passed down to the dividends preferences modal. If the user chooses a different option as to whether to receive dividends or not from their current preferences, this function sets that new preference to the state so it can be used in different parts of the code. -
getPayments()
: This function stores the transactions a user has made into a list called paymentsListand then sets it to the state variable
payments`. This is then used in creating the transactions list on the page.
-
-
DividendsPreferencesModal.js
:-
handleOpenModal()
/handleCloseModal()
: Determines whether the modal pop-up shows up on the screen, which is dependent on whether the state variableshowModal
is true of false.handleOpenModal()
sets it to true and is called when users click on the "Change" button, andhandleCloseModal()
sets it to false and is called when users click on "Submit Preferences" or outside the modal. -
handleCheckYes()
/handleCheckNo()
: These functions are called depending on whether the user selects "yes" or "no" on the modal. They update the state variablenewIsReceivingDividends
, which displays the checked button on the form. -
handleSubmit()
: This is called when users click "Save Preferences" on the modal. It callssubmitPreference()
which is passed down to set the state depending on the updated choice of whether the user wants dividends or not.
-
-
TransactionsList.js
:-
filteredList
: This constant ensures that the list used for Transactions List are only Shares and Dividends transactions, not Bill Payments. - list: This constant is where each transaction gets formatted into one card of the transactions list. It is a list of these formatted cards. This list is then returned by the component to be displayed on the My Investment page.
-
Overview: On this page, an admin is able to see an overview of all the users in their project group, have the ability to invite new users, and perform various tasks. In addition, if you are a super admin, here is where you will have additional access to a super admin page which allows you to generate bills for specific project groups.
Components:
There are various components used on this page, which are listed below:
- Admin card: These are the card views in the admin dashboard which display each member of your project group, their member type, since when they were a member, and the ability to remove them from a project group.
- Admin Modal: This modal appears when you click on a card. In this modal, you are able to view more contact information for a specific member and are able to edit that information.
- Invite Modal: This modal appears when you click on the invite button. Once you fill out the information of the person you want to invite, you will see a confirmation modal and an email with a link should be sent to the person so that they can onboard for your project group.
- Super Admin View: In this view, you will see all the solar projects and have the ability to generate a specific solar project bill.
Functionality:
Here are functionalities broken down by component/page:
-
AdminDashboard.js
:-
componentDidMount()
: This function makes sure the the list of all the owners' records of the project group is retrieved when this page is loaded. -
componentDidUpdate()
: If the user was assigned a new project group, this function retrieves the updated list of all the owners in the project group. -
handleChange()
: If any changes were made to any inputs, this function will make these changes to this.state. -
handleAdminChange()
: When a user's card is clicked, the information displayed on the modal is updated using this function -
handleSubmit()
: After filling out the Invite form, this function is called. It first validates all the inputs making sure they are in the correct format, then if all there are no errors the invite is sent. While it is sending, the loading component is displayed. Once the email was successfully submitted, the confirmation modal is displayed. -
validateContactandSubmitData()
: This function is called when the admin wants to edit the contact information of a certain member. This is possible when the admin has the Admin card modal open. This function first validates to see if the inputs are in the correct form then if there are no errors then the owners information is updated. -
fetchOwnerRecors()
: this function fetches all the owners of the current project group. -
handleOpenModal()
: This handles clicks related to opening modals. -
handleCloseModal()
: This handles clicks related to closing modals. -
handleContactEdit()
: This function handles any clicks in the admin card modal. If the edit button is clicked, this changes the view to edit mode. If the cancel button is clicked, it switches out of edit mode. If the save button is clicked, it validates, updated, and then switches out of edit mode.
-
-
SuperAdmindashboard.js
:-
componentDidMount()
: This function makes sure all the solar projects are fetched when the page is loaded -
generateBillForSolarProject()
: This function is called when you want to generate the bill of a specific solar project.
-
-
AdminDashboard.js
: renders the view of the admin dashboard -
adminUtils.js
:-
validateShares()
: Validates the input for how many shares in the invite modal is correct. -
validateUSState()
: Validates the input for state in the admin card modal is correct. -
validatorData
: keeps track of all the inputs and the specific validation tied to the input. -
toggleValidColor()
: This function returns the correct class or output when validating inputs.- type 0 - returns a class based on whether the input in the invite modal is correct
- type 1 - returns an error message if the input is not in the correct form
- type 2 - returns a class based on whether the input in the user card modal is correct
-
validateField()
: For the specific input, this function loops through all the validators listed in validatorData and returns all the error messages -
removeOwner()
: Removes an owner from a project group. -
getOwnerRecordsForProjectGroup()
: Returns all the owners that have completed onboarding in a specific project group -
inviteMember()
: This creates a pledge invite -
triggerEmail()
: This function sends the invite email to the intended person.
-
Overview: On this page, any user is able to update their contact information
Components:
UserProfile.js
: This component represents the entire Settings screen. It is the only component used on this page. The primary features
Functions:
-
componentDidMount()
: On page render, this makes surepopulateOwnerInformation()
is called. -
componentDidUpdate()
: After an update occurs, this function checks to see if the user is different from the previous user. If the page detects a new user, it recallspopulateOwnerInformation()
-
handleCancel()
: This function sets the page out of edit mode and then callspopulateOwnerInformation()
-
handleChange()
: When in edit mode, this function is called if any of the user's information is changed. -
validateAndSubmitData()
: This function validates all inputs, checks if all inputs are in the correct form, and then updates the owner. -
onContactButtonPressed()
: This function is called whenever the contact button is pressed. Based on whether or not it is in edit mode. If is it in edit mode, it will validate, update the owner information in the database, and then refresh the page. -
onGeneralButtonPressed()
: This function is called whenever the general button is pressed. Based on whether or not it is in edit mode. If is it in edit mode, it will validate, update the user's information in the database, and then refresh the page. -
populateOwnerInformation()
: This function retrieves all of the user's information from airtable. -
renderInputLabel()
: This function will render the correct type of input whether it is the user's information or an input form if in edit mode.
Validation for user profile happens in onboardingUtils.js
because they have the same input types.
In the file, there are a number of validation functions. These functions take in a value and return either an error message or an empty string (if there is no error). Some take an optional second parameter as a default error message.
The variable ValidatorData
then maps field names to the validators that they need to pass. validateField
ensures that all the validators associated with a field pass and it returns any error messages
Overview:
On this page, a user is able to view all project news, and make new posts (if they are admins)
Components:
Community.js
: This component is the main component for displaying Project News. All Project News related Components are referred to as Community... components in the codebase.
The Community.js
component displays either a NoProjects
default component if there are no project news or a list of announcements. The component also displays an AddAnnouncement
component if the user is an admin.
Functionality:
The Community.js
component is a relatively simple UI component that mostly displays the announcements passed into it as props. It is agnostic of the backend processes required to fetch such data. The AddAnnouncement
uses utility functions to write to Airtable.