Skip to content

Commit

Permalink
faq code
Browse files Browse the repository at this point in the history
  • Loading branch information
HarshithaSolai committed Feb 1, 2023
1 parent 3a2cfc2 commit 0740b98
Show file tree
Hide file tree
Showing 5 changed files with 182 additions and 5 deletions.
72 changes: 70 additions & 2 deletions coding-assignment.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,75 @@
## Build a Food Ordering App - Chapter-11 features


### Practice React Context with code examples
### Props Drilling

`Props Drilling` is the technique by which props are passed from one component to another, which in turn passes to another component and so on to reach the component which needs this props.

### Try out Nested Contexts
I have already implemented `props drilling` in our app InstaFood without knowing its actually name. So, I wanted to pass user info like name, email and isAuthenticated values that I get in landing page (`AppLayout`) component to `NavComponent` in `Header` where based on isAuthenticated value, display Login or Logout button.

Check App.js & Header.js to see how the props is passed from `AppLayout` to `NavComponent`

### Lifting up state

When we want to pass some props from child component to parent or its siblings, we can use `lifting up state` technique. It can be thought as if the control is handed over to the parent and let the child modify the data through the function that is passed to child as props.

<ans>Child -> Parent </ans>

Again, I have already implemented this in InstaFood without knowing its actually name. On click of Favourites button in Body Component, only the restaurants that are marked favourite (enabled/disabled by toggling heart button on restaurant card component). For this, I wanted my marked restaurant data in Body to update the Body to show the favourite restaurant ie child's props must be passed to parent. For this, I moved the adding/removing favourites logic to Body and passed that function to child, where the child can update through that function. This is one way of `lifting up state`.

<ans> Child -> Siblings</ans>

I am implementing sharing data between Siblings feature in this chapter. For eg: There are multiple FAQs sections in the Help Page and all the FAQ answers are initially hidden, once the user clicks on any question, its corresponding answer is visible. If user clicks on any another question, the previous visible answer must be hidden and new answer must be visible.

All the `FAQ sections` are `Siblings` Components and `Help` is the `Parent` component.

<ans>Static Version : </ans>
The data to display FAQ sections of Help page is mocked in config.js.Each section (faq) has an unique id, title (question) and description (answer). Loop through the FAQ array and display title and description of each FAQ in Section Components

<ans>Show/Hide Description:</ans>

```javascript
const [visibleSection, setIsvisibleSection] = useState(
{
id : 1,
status : false
}); /* Initial Dummy value */
```

Giving the control of state `visibleSection` to the parent (Help Component) and child (Section) can modify the state only through the callback function `setIsVisible` passed by the Parent (Help), in turn parent updates the state through `setVisibleSection`. This way the sibling components can be shown/hidden based on this state maintained by the parent. Initially description of all Section component is hidden. For this, a initial dummy value (id and status as false are set).


```javascript
<Section key={question.id} id={question.id} title={question.title}
description ={question.description}
isVisible={visibleSection.status && visibleSection.id === question.id }
setIsVisible={(obj) => setIsvisibleSection(obj)}
```

Since status is false, all section components `isVisible` will be 'false` and in Section component down arrow will be displayed.

```javascript
{
isVisible ? (
<SlArrowUp onClick={() => setIsVisible({id : id, status : false})} className="cursor-pointer" />
) : (
<SlArrowDown onClick={() => setIsVisible({id : id, status : true})} className="cursor-pointer" />
)}



{isVisible && <p className="text-bio text-base">{description}</p>}

```
<ans>User clicks for the first time</ans>
Once the user clicks on any section's down arrow button, the state that parent maintained is updated by the child through the callback funtion `setIsVisible` by setting status to true and id with the current section id.

Now, in Help component `isVisible` is set to true, because of which the arrow changes to up arrow and description is displayed. Note that all other sections state is still false and no changes happens there.

<ans>Subsequent User clicks </ans>


### React Context


### Nested Contexts
10 changes: 8 additions & 2 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import RestaurantMenu from "./components/RestaurantMenu";
import Login from "./components/Login";
import { useLocation } from "react-router-dom";
import Shimmer from "./components/Shimmer";

/* import Instamart from "./components/Instamart";
On Demand loading
Expand All @@ -22,6 +21,8 @@ On Demand loading

const Instamart = lazy(() => import("./components/Instamart"));
const About = lazy(() => import("./components/About"));
const Help = lazy(() => import("./components/Help"));


const AppLayout = () => {
const location = useLocation();
Expand Down Expand Up @@ -66,9 +67,14 @@ const appRouter = createBrowserRouter([
{
path : "/restaurant/:resId",
element : <RestaurantMenu />
},{
},
{
path : "/instamart",
element : (<Suspense fallback={<Shimmer />}> <Instamart /></Suspense> )
},
{
path : "/help",
element : (<Suspense fallback={<div className="container"><h1>Loading...</h1></div>}> <Help /></Suspense> )
}
],
},
Expand Down
3 changes: 2 additions & 1 deletion src/components/Header.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ export const NavComponent = (user) => {
<li className="p-2.5"> <Link to="/"><button className="nav--btn "> Home</button></Link></li>
<li className="p-2.5"> <Link to="/about"><button className="nav--btn" > About</button></Link> </li>
<li className="p-2.5"> <Link to="/instamart"><button className="nav--btn"> Instamart</button></Link></li>
<li className="p-2.5"> <button className="nav--btn" onClick={() => {toggleLogin()}} > {isLoggedIn? "Logout" : "Login" }
<li className="p-2.5"> <Link to="/help"><button className="nav--btn"> Help</button></Link></li>
<li className="p-2.5"> <button className="nav--btn" onClick={() => {toggleLogin()}} > {isLoggedIn? "Logout " : "Login " }
<span className={isOnline ? "text-green" : "text-red" }></span></button>
</li>
</ul>
Expand Down
50 changes: 50 additions & 0 deletions src/components/Help.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { useState } from "react";
import { SlArrowDown, SlArrowUp } from "react-icons/sl";
import { FAQ } from "../config";

const Section = ({id, title, description, isVisible, setIsVisible }) => {

return (

<div className="flex flex-col shadow rounded-md p-2.5 m-2.5">
<div className="flex justify-between">
<h3 className="font-semibold text-lg text-title">{title}</h3>
{
isVisible ? (
<SlArrowUp onClick={() => setIsVisible({id : id, status : false})} className="cursor-pointer" />
) : (
<SlArrowDown onClick={() => setIsVisible({id : id, status : true})} className="cursor-pointer" />
)}
</div>
{isVisible && <p className="text-bio text-base">{description}</p>}
</div>
);
};

const Help = () => {
const [visibleSection, setIsvisibleSection] = useState(
{
id : 1,
status : false
}); /* Initial Dummy value */

return (
<div className="container">
<div className="card-container">
<h1 className="card-container-title pb-5"> FAQ</h1>
{FAQ.map((question) => {
return (
<Section key={question.id} id={question.id} title={question.title} description={question.description}
isVisible={visibleSection.status && visibleSection.id === question.id }
setIsVisible={(obj) => setIsvisibleSection(obj)}
/>

)
}
)}
</div>
</div>
);
};

export default Help;
52 changes: 52 additions & 0 deletions src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,58 @@ export const GITHUB_LINK = "/~https://github.com/HarshithaSolai";
export const LINKEDIN_LINK = "https://www.linkedin.com/in/harshitha-sv/";
export const GMAIL_LINK = "mailto:solaiharshitha0@gmail.com";

/* Mock FAQ */
export const FAQ = [
{
id: 473,
title: "Can I edit my order?",
description:
"Your order can be edited before it reaches the restaurant. You could contact customer support team via chat or call to do so. Once order is placed and restaurant starts preparing your food, you may not edit its contents",
},
{
id: 474,
title: "I want to cancel my order",
description:
"We will do our best to accommodate your request if the order is not placed to the restaurant (Customer service number: 080-67466729). Please note that we will have a right to charge a cancellation fee up to full order value to compensate our restaurant and delivery partners if your order has been confirmed.",
},
{
id: 475,
title: "Will Swiggy be accountable for quality/quantity? ",
description:
"Quantity and quality of the food is the restaurants' responsibility. However in case of issues with the quality or quantity, kindly submit your feedback and we will pass it on to the restaurant.",
},
{
id: 476,
title: "Is there a minimum order value?",
description:
"We have no minimum order value and you can order for any amount. ",
},
{
id: 477,
title: "Do you charge for delivery?",
description:
"Delivery fee varies from city to city and is applicable if order value is below a certain amount. Additionally, certain restaurants might have fixed delivery fees. Delivery fee (if any) is specified on the 'Review Order' page. ",
},
{
id: 478,
title: "How long do you take to deliver?",
description:
"Standard delivery times vary by the location selected and prevailing conditions. Once you select your location, an estimated delivery time is mentioned for each restaurant.",
},
{
id: 479,
title: "What are your delivery hours?",
description:
"Our delivery hours vary for different locations and depends on availability of supply from restaurant partners.",
},
{
id: 481,
title: "Is single order from many restaurants possible?",
description:
"We currently do not support this functionality. However, you can place orders for individual items from different restaurants.",
},
];

/* Mock Data for Restaurant Card */
export const restaurantList = {
statusCode: 0,
Expand Down

0 comments on commit 0740b98

Please sign in to comment.