This is a clone of Cooking by NY Times.
TODO add links to feature list etc.
Food For Thought was built using React, Redux, AWS S3, Flask and SQLAlchemy to create an application. Heroku was used for production hosting, and AWS S3 was used to host image files uploaded by users for use with the application.
-
Clone this repository (only this branch)
git clone https://github.com/appacademy-starters/python-project-starter.git
-
Install dependencies
pipenv install --dev -r dev-requirements.txt && pipenv install -r requirements.txt
-
Create a .env file based on the example with proper settings for your development environment
-
Setup your PostgreSQL user, password and database and make sure it matches your .env file
-
Get into your pipenv, migrate your database, seed your database, and run your flask app
pipenv shell
flask db upgrade
flask seed all
flask run
-
To run the React App in development, checkout the README inside the
react-app
directory.
IMPORTANT! psycopg2-binary MUST remain a dev dependency because you can't install it on alpine-linux. There is a layer in the Dockerfile that will install psycopg2 (not binary) for us.
Food For Thought allows users to add thoughts(recipes) to the application to include recipe description, instruction and ingredients. Users also attribute thoughts to categories which they can choose. The user can also pick an image to upload to an AWS S3 bucket.
Users can add reviews to any thought on Food For Thought, which includes a star rating from one to five. Each thought dynamically averages the total ratings and displays it on the front end notifying the user visually what the rating is for that thought.
Food For Thought's thought detail page showcases complex dynamic rendering on simple, smooth and easy UI/UX for users. Users can CRUD ingredients and CRUD reviews on the same page without refresh.
Users are given the full CRUD option to add/edit or delete their ingredients to their newly created thought. When user wants to add an ingredient to an existing thought, they are greeted with a modal to input information.
Users are given the full CRUD option to add/edit or delete their reviews in the same thought detail page.
When a user hovers on a review they posted, they are shown an edit and delete icon.
Each thought's ratings are updated as soon as another user posts a rating/review. It also calculates the percentage value of the rating based on its average and displays it dynamically as stars.
Users can query the database based on the search input's value.
Main page dynamically renders and live filters the thoughts (recipes) based on the category selected by the user.
-
Integrated Google books API, Food For Thought application can perform full-text searches and retrieve book information, viewability and eBook availability.
-
Search and browse throught a list of books that match the user's query.
-
Ability to view information about a book, including metadata, availability, price and links where the user can purchase the book.
This component defines the default state as an empty array. Using axios (promise based HTTP client for browser and Node.js), was able to do a "READ" operation. The user's search input is passed as an argument for the query. The promise's result is set as the new data array which we can render in the front end. The max results is set to 40.
Each element in the bookData array is mapped and passed into the Card component. Inside the card component we display the thumbnail image, title and price of the book. Using state manipulation, when the user clicks the card component it sets the show state to true and the bookItem to that item which displays the modal (info) for the user.
TODO, still need to fix thought page. Don't forget to put code snippets and also the setProxyState([]).
Per input, the user is notified how many characters the current input has. Each input notifies the user if it is required, the min and max values it can contain. Users can also add multiple ingredients for the thought(recipe).
When a user decides to edit the ingredient they added, when they click confirm. An onlick function which passes the ingredient's current index as an argument. The function uses the ingredient's index to splice and update it with the edit input's value.
It also has to pass error handling before the edit can be confirmed. In order to trigger a re-render of the component. There needs to be a detected change between the real DOM vs. the virtual DOM.
When we invoke the function setProxyState and pass an empty array, the virtual DOM is compared with the real DOM and a change is detected. Therefore, the component will rerender along with its updated states.
-
Introduce more complexity for the ingredients table. Allow users to quantify their selected ingredients enabling them to input measurements as well.
-
A notifications tab which notifies the user if another user left a review on their thought (recipe).
-
Allow the user to post a video along with the instructions table that demonstrates how to prepare the dish.
-
Allow users to bookmark a thought (recipe) and also access their bookmark page.