Code Monkey home page Code Monkey logo

ihc-wellness-app's People

Contributors

benson272 avatar bobbytatum27 avatar c3duan avatar dependabot[bot] avatar graskovi avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar

ihc-wellness-app's Issues

Add editing to Checkin backend

Add functions to CheckinBackend for getting an array of question objects, activating and deactivating questions, adding new custom questions, and as a stretch goal editing the question title of custom questions.

The object schema needs to contain any information needed to render a question on the screen, such as the question title, a unique state key (e.g. "mood" for a question about mood, "custom1" for a custom question), active or not, and props associated with slider questions. For functions that create or modify this data (and for functions in general that create or modify data for frontend) return the data at the end of the function to avoid frontend having to call an extraneous get method.

Implementation is up to you. The backend google doc still has notes on how similar functions were implemented, update it after settling on an implementation for these functions.

Add Checkin question edits

Finish the CheckinPage by implementing a questions FlatList and two modal components:

The FlatList should take this.state.questions as data and render all of the active slider and text input questions. Modify the ICheckInQuestion interface as necessary for this, and use conditional rendering in the renderItem method to render a slider or text input for each item.

The first is a full-page modal that displays all of the checkin questions as well as whether they are active. Pressing a question should flip whether it is active or not. Later the newly updated array with only the active fields changed can be sent to the backend, but that is for later.

The second is a full-page modal with a TextInput for typing the title of a new custom question and two buttons that close the modal: one button should close the modal and add the question to the array of questions, the other should close the modal and cancel the question add.

The React Native Modal documentation is pretty good, and there are also good tutorials such as this one and this one.
The basic idea is that a modal component will have a state variable tracking whether it is open, the prop transparent determines if it is more of a pop-up (transparent={true}) or a full-page (transparent={false}), and handlers that fire when the modal opens or closes (onShow and onDismiss). Remember to center the elements nested in a modal horizontally and vertically as the modal takes up the entire page, and the TouchableHighlight that opens the modal is not nested inside the modal as it should appear on CheckinPage.

The FlatList for the questions is more straightforward, just define a renderItem method to take an ICheckinQuestion object and use it to return the corresponding JSX, and track the current question array in state and pass it to the data prop of the FlatList. For the keyExtractor, just set the key as the index of the question.

  1. This tutorial app uses Expo and AsyncStorage and seems to be a good place to start. The written portion seems outdated but the source code has the FlatList JSX. The basic logic seems to be to load the data in the constructor or on componentDidMount and store it in the page state, letting the FlatList re-render as the state changes.

  2. If that does not work, this StackOverflow post details how to use extraData to force a re-render.

Stretch goal:
Add a delete button to the CheckinQuestion component. Simplest might be this component.

Shop backend

Write a file storeBackend.tsx similar to checkInBackend.tsx for storing the available items for purchase and retrieving them, as well as the quantities owned by the user.

Write a generator for returning each matrix row. Format should be [sectionInfo, itemArray].

Get app running on Expo

Download npm, expo-cli from npm, and either a simulator/emulator on your computer or the Expo app on your phone and attempt to run the project. Ask in Slack about any technical difficulties you face. If a branch isn't working (e.g. open the master branch of app and you get the red screen of death) try switching to another branch (e.g. ShopAndCheckin) and try running it again.

Shop page MVP

Use the StoreBackend to implement a testing page by creating an MVP for the shop page.

Top priority: Get the FlatList to re-render to reflect updates to the backend. This can be done in one of 2 similar ways:

  1. Store the FlatList data in the state object of the page and load it from AsyncStorage on componentDidMount and change the state whenever changing the AsyncStorage data. This file has some useful code that accomplishes this.
  2. Or store the FlatList data anywhere in the class, load it on componentDidMount, and use the extraData prop to force a re-render.

For now this is a testing page, make appearance of locked vs unlocked item very different, e.g. with a red square for locked items and a green square for unlocked items. This could be achieved by returning a View in renderItem with its backgroundColor prop set.

Write logic for unlocking items with achievements. Implement a horizontal FlatList for rendering different sections of the shop that shows basic info about each item.

Frontend stretch goals (ignore for now):
Implement a modal that will open for each item with the item image and a button to buy it.

See page mockups for appearance, but top priority is to have horizontal flatlists and modals.

Plant page MVP

On the plant page add item swapping to the FlatList.

In the FlatList renderItem method, add a TouchableHighlight wrapper that activates a modal onPress. To make this easier, create a PlantCard component to hold the Image, Modal and TouchableHighlight JSX. Similar to how in CheckinPage the sliders and text inputs could change page state by having a function passed to them, you'll likely need to pass a similar function to the PlantCard that lets it set the name of the pressed IPlantItem in a call to setState.

Nested in the modal there should be a horizontal ScrollView or FlatList that takes an array of IOwnedItems and renders them (ScrollView would be by passing an array of JSX created using .map() as a child, UserPage has an example of this, or with FlatList it would be by defining the renderItem method and passing the array to the data prop). These arrays can be hardcoded: 3 in total for headers, bodies, and footers. The elements should be wrapped in a TouchableHighlight or TouchableOpacity so that onPress the plant item that was pressed to bring up the modal will be replaced by the pressed IOwnedItem in the modal. An IPlantItem only has a name key, so just set the header or footer or element in bodies array to an object with the name of the IOwnedItem.

Set the state of the PlantPage to hold the current header, footer, and bodies. For now, this will be the hardcoded data. Later they will be populated by calling the backend methods that return them when the PlantPage loads. For this later stage, this can be done either by waiting for promises to resolve in the PlantPage constructor with a .then() callback or by waiting in the PlantPage async componentDidMount() method using await. When we get there it will also be useful to use object destructuring to receive data from Backend methods that return multiple named values.

Stretch goal:
Add a button that adds a single default plant element to this.state.bodies to test the ability of the FlatList to re-render given an updated state.

Backend queries

Create a function in checkInBackend.tsx for querying past results.
Call it retrieveResponses : async (pastNumberOfDays : int, queryName) {...}

Stretch goals
Access fields from the object after verifying there is a response in the object, as some days might be missing a field, e.g. no response to sleep field for some days but not others.
Add a file with the name of possible response parameters. Call it CheckinFields.ts and put it in the constants folder: see Colors.ts and index.ts inside the constants folder for guidance (i.e. const object in file and export in index).
Use the arguments object to allow for a variable number of arguments, and assume that these are all queries to retrieve from previous responses.

Fix Frontend inheritance issue

Currently, certain screens are not appearing correctly (highly skewed) likely due to an inheritance issue. Find and correct the incorrectly inherited styles, or the actual underlying issue.

Plant page second draft

Improve the plant page in a number of potential ways:

  • Top priority: allow user to press different parts of the plant and have a modal popup of applicable materials appear (e.g. press footer and app shows pots, press body and app shows flowers). Can use hardcoded data for available materials.

Stretch goals:

  • Enable images (e.g. flowers on top of branches) to be able to be placed on top of elements.
  • Make seam between components invisible (i.e. make scrolling plant seamless).

Plant backend

Create the queries needed for the frontend to display and allow the user to modify their plant. More information to come.

Profile page MVP

Create a profile page with StackNavigator modal navigation that allows users to observe graphs of their checkin responses over time. Here's a fairly simple example of a modal, use page state to track which whether a modal is open (if any). The easiest solution is probably a state key per chart modal with a boolean value.

Import @react-navigation/stack, try different StackOverflow solutions or asking Bobby for a suggestion.

On UserPage load (componentDidMount()) get checkin responses from ProfileBackend and in a .then() callback handler filter the data for each chart's desired response and save it to the UserPage state or member variables. This filtered array is what you will pass as a prop to each chart.

Look into how to get the temporal axis working, i.e. each data point should map to its date

The initial page will have links to settings and a number of graphs for different checkin responses. Create a graph page modal that is given a query a data array as a prop~~ and retrieves the user responses to the corresponding question in a chart~~. react-native-chart-kit or react-native-svg-charts appear to be good charting libraries to use, it is up to you which of these to use or to use another solution.

Add interfaces to backend

In each back-end file add and export interfaces defining the schema of custom objects.
The main schema will be PlantItem for plant and store items, CheckinQuestion for user questions, and CheckinResponse for a user's daily response and the profile queries.
Note: the lines will be export interface MyInterface {...}, don't do a default export.

For CRUD functions that modify data that the frontend uses, change them to return the new data after calling setItem on AsyncStorage. Check to see if it is necessary to await the setItem call before returning the data.

Also, update the backend documentation to include a simple description of what each backend function does.

Checkin page MVP

Create component file CheckinSlider.tsx (under components) using the React Native slider for form input.

Stretch goal: Add a textbox for journaling (string input).

Profile backend

Add any additional backend to checkin queries needed for frontend to display graphs of different responses over time. More information to come.

Checkin Components

Add a CheckinTextInput component. Similar to the CheckinSlider in that it has a question title prop. Modify for better UX, i.e. the user can see what they're typing as they type. Using composition, make a component for a custom question that has a TextInput for the question title with a CheckinTextInput below as a preview for the custom question.

Improve the CheckinSlider component so that its current value follows the slider. Will need to measure the component at the onLayout event, see StackOverflow for some implementation suggestions.

Add AsyncStorage/state management

Implement resource tracking (e.g. saving what flowers, soils, and leaves are available) using AsyncStorage to locally save data and/or state management to keep track of unsigned integer representations of available resources.

Refactor CheckinBackend

Week 10 task:

CheckinBackend can use more of a Model-View-ViewModel approach, which basically means the frontend handles much of the data management, so it is not necessary to convert CheckinBackend to a singleton. Other than singleton logic, perform refactors akin to those for PlantBackend and StoreBackend that improved readability.

Talk to Bobby about the logic he's writing, as the MVVM pattern means his logic will drive the data updates. Chances are CheckinBackend will only need the function to save the checkin (finished), get the questions array and set the questions array (call setItem and return the promise).

If frontend reports any bugs, missing but needed functions, confusing function names, lack of JSDoc comments etc., that will take priority over CheckinBackend refactors.

CheckinPage backend refactor

Finish the CheckinPage by making some last changes:

Use the needed CheckinBackend methods to load the initial state from AsyncStorage. This tutorial app uses Expo and AsyncStorage. The written portion seems outdated but the source code has the FlatList JSX. The basic logic will be to load the data in the constructor by calling a questions array getter backend method and storing it in the page state. When the state changes significantly, such as when the toggle or add modal is closed, call the questions setter method to have this change get saved.

Change the renderItem method to not use if-else logic to render questions: instead, add members to the ICheckinQuestion interface that are needed to render a CheckinSlider (e.g. minValue: number; maxValue: number; title already exists so use that, step and key). This can be accomplished by either adding these 3 new members as optional members in ICheckinQuestion or by creating a separate interface for slider and text: ICheckinSlider and ICheckinTextInput, and defining ICheckinQuestion as a union between them, ICheckinSlider | ICheckinTextInput.

Stretch goals:
On page enter, check if the user has checked in already, such as by using isUserCheckedIn from ProfileBackend, and alert them if they have.
On Checkin submit, use React Navigation and this.props.navigation.navigate(string) to navigate to the plant page. Check src/View/Navigations/Navigation.tsx for route names, for plant plage it's 'Plant'.
Implement valid dynamic keys for the custom questions. This can be accomplished by having each key be custom${index} where index is the index of the custom question, e.g. first custom question would have key 'custom0'.

Fix StoreBackend bugs, add reset functions

The StoreBackend appears to have bugs involving buying an item. For example, at times clicking a button that calls the buyItem function once results in the item count getting increased by 3. Test and fix this functionality, and for the different Backend objects add functions that reset the AsyncStorage keys to a new-user state, i.e. setting the keys to have new-user values or deleting the keys and modifying the create/update functions to check whether a key exists yet and creating a new-user value if it does not.

Create "practice" branch

Create a branch called "practice" and play around with react-navigation, particularly the TabNavigator object.

PlantPage backend refactor

Change the PlantPage to use backend calls instead of hardcoded data. In the constructor, use the plantController (PlantBackend instance) to get the initial page state and assign it in this.state.

Replace the plantItems state members with calls to StoreBackend's getOwned() in the PlantCard modal.

Replace changes to the plant state with calls to PlantBackend functions that take a current state member and return the new value and the promise it will be saved. If there are any problems here ask Rohith or Benson about any issues with the logic.

Store screen rough draft

Create a rough draft implementation of the store screen.

  • Edit StorePage.tsx
  • Use a StackNavigator with ~3 levels: first is scrollable store sections (pots, soils, leaves, etc.), pressing a section leads to scrollable section items (i.e. the different specific pots available, e.g. cheap pot, fancy pot), and pressing an item leads to view of that item (i.e. image of cheap pot with button below for buying and number indicating quantity of item already owned).
  • Add files for section items screen and item screen to src/View or src/components, can be changed later, and sample photos to assets/images.

Refactor PlantBackend and StoreBackend

Merge backend with the master branch. In the backend files, there are a number of comments describing changes to make the code more readable, efficient, and shorter.

Priorities in decreasing order are:

  1. Implementing singleton logic in PlantBackend and StoreBackend. Use PlantBackend as a guide for implementing the singleton boilerplate. Add member variables to track data received from AsyncStorage and assign them inside the constructor. As the constructor cannot be marked async, use the .then() method to perform these assignments. PlantBackend will track the plant array, StoreBackend will track money and the owned object (with arrays for owned headers, bodies, footers).

  2. Replace, where applicable, for-loops with calls to .find(), .findIndex(), and higher-order functions such as .map(), .filter(), etc. This quora post has a good explanation for the benefits of these and some useful code snippets.

  3. Document functions by adding two pieces of information. JSDoc comments, note that JSDoc type descriptions can be added to the comment with {type}. Function types to specify the type of function parameters and the type the return value. Note that for an async function that returns a type, its return type is Promise.

  4. Add previous value parameters to CRUD functions where the original value(s) that will get updated is a parameter and return the new value(s) and setItem promise(s), objects preferred as return values.

  5. Add default parameters where applicable (mainly plantIndex in PlantBackend).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.