diff --git a/src/meta/play-meta.js b/src/meta/play-meta.js index 7d6afa6e65..cc3f5b26a5 100644 --- a/src/meta/play-meta.js +++ b/src/meta/play-meta.js @@ -10,6 +10,7 @@ import { RandomMemeGenerator, Keeper, ReactTodoApp, +QuoteGenerator, ExpandingCards, AnalogClock, PasswordGenerator, @@ -129,6 +130,31 @@ export const plays = [ blog: '', video: '' }, { + id: 'pl-react-todo-app', + name: 'React Todo App', + description: 'It is a simple Todo App which keeps track of your regular work', + component: () => { return }, + path: '/plays/react-todo-app', + level: 'Beginner', + tags: 'ReactHooks, JavaScript, Css, React State', + github: 'nirban256', + cover: 'https://res.cloudinary.com/atapas/image/upload/v1650866465/demos/cover_y20bzk.png', + blog: '', + video: '' + },{ + id: 'pl-quote-generator', + name: 'Random Quote Generator', + description: 'Randomly Generate quotes from 3rd Party API', + component: () => {return }, + path: '/plays/quote-generator', + level: 'Intermediate', + tags: 'Hooks,API,Async/Await', + github: 'Abhishek-90', + cover: 'https://i0.wp.com/dariusforoux.com/wp-content/uploads/2015/08/motivational-quotes.png?fit=2048%2C1536&ssl=1', + blog: '', + video: '' + }, + { id: 'pl-keeper', name: 'Keeper', description: 'Keeper is the clone of google keep where we can save and delete our notes', @@ -140,22 +166,6 @@ export const plays = [ cover: 'https://res.cloudinary.com/dbjmy6wdu/image/upload/v1651678725/keepicon_jsn5bh.png', blog: '', video: '' - }, { - id: "pl-react-todo-app", - name: "React Todo App", - description: - "It is a simple Todo App which keeps track of your regular work", - component: () => { - return ; - }, - path: "/plays/react-todo-app", - level: "Beginner", - tags: "ReactHooks, JavaScript, Css, React State", - github: "nirban256", - cover: - "https://res.cloudinary.com/atapas/image/upload/v1650866465/demos/cover_y20bzk.png", - blog: "", - video: "", }, { id: "pl-expanding-cards", name: "Expanding-Cards", diff --git a/src/plays/index.js b/src/plays/index.js index 95867efe46..65ae248b42 100644 --- a/src/plays/index.js +++ b/src/plays/index.js @@ -11,6 +11,7 @@ export { default as SocialCard } from 'plays/social-card/SocialCard'; export { default as RandomMemeGenerator } from 'plays/random-meme-generator/RandomMemeGenerator'; export { default as Keeper } from 'plays/keeper/Keeper'; export { default as ReactTodoApp } from 'plays/react-todo-app/ReactTodoApp'; +export { default as QuoteGenerator } from 'plays/quote-generator/QuoteGenerator'; export { default as ExpandingCards } from 'plays/expanding-cards/ExpandingCards'; export { default as AnalogClock } from 'plays/analog-clock/AnalogClock'; diff --git a/src/plays/quote-generator/QuoteGenerator.jsx b/src/plays/quote-generator/QuoteGenerator.jsx new file mode 100644 index 0000000000..62585abca2 --- /dev/null +++ b/src/plays/quote-generator/QuoteGenerator.jsx @@ -0,0 +1,138 @@ +import { getPlayById } from "meta/play-meta-util"; +import PlayHeader from "common/playlists/PlayHeader"; +import "./quoteGenerator.css"; +import { useEffect, useState } from "react"; + +const fetchQuote = () => { + const response = fetch("https://api.quotable.io/random"); + return response; +}; + +function QuoteGenerator(props) { + // Do not remove the below lines. + // The following code is to fetch the current play from the URL + const { id } = props; + const play = getPlayById(id); + + // Your Code Start below. + const [quoteArray, setQuoteArray] = useState([]); + const [current, setCurrent] = useState(0); + + const updateState = (newState, stateUpdator) => { + return new Promise((resolve) => { + return stateUpdator(newState, resolve()); + }); + }; + + const previousQuote = async () => { + await updateState(current - 1, setCurrent); + return; + }; + + const nextQuote = async () => { + if (current < quoteArray.length - 1) { + await updateState(current + 1, setCurrent); + return; + } + + const response = await (await fetchQuote()).json(); + await updateState( + [...quoteArray, [response.content, response.author]], + setQuoteArray + ); + await updateState(current + 1, setCurrent); + return; + }; + + useEffect(() => { + const fetcher = async () => { + const response = await (await fetchQuote()).json(); + await updateState( + [...quoteArray, [response.content, response.author]], + setQuoteArray + ); + }; + fetcher(); + }, []); + + return ( + <> +
+ +
+ {/* Your Code Starts Here */} +
+

Quote Generator - Get Motivated Randomly.

+
+
+
+ +
+
+
+ {quoteArray.length > 0 &&

{quoteArray[current][0]}

} +
+
+ {quoteArray.length > 0 && + +

+ {current + 1}/{quoteArray.length} +

+
} + + {quoteArray.length > 0 && ( +

- {quoteArray[current][1]}

+ )} +
+
+
+
+ +
+
+ {/* Your Code Ends Here */} +
+
+ + ); +} + +export default QuoteGenerator; diff --git a/src/plays/quote-generator/Readme.md b/src/plays/quote-generator/Readme.md new file mode 100644 index 0000000000..e1e0ef9bf8 --- /dev/null +++ b/src/plays/quote-generator/Readme.md @@ -0,0 +1,7 @@ +# Quote Generator + +This play revolves around Random Quote generations, saving them and being able to traverse between different that has been fetched. Under the hood, this uses different hooks like, useEffect, useState etc. + +On loading this play, a random quote will be displayed which is stored using useState hook. User can fetch more quotes with the help of Generate Quote Button. + +User can use previous and Next button to traverse between various quotes stored with the help of useState hook. \ No newline at end of file diff --git a/src/plays/quote-generator/quoteGenerator.css b/src/plays/quote-generator/quoteGenerator.css new file mode 100644 index 0000000000..2c4b9cb159 --- /dev/null +++ b/src/plays/quote-generator/quoteGenerator.css @@ -0,0 +1,99 @@ +.rand-quote-gen .play-area { + border: none; + display: flex; + flex-direction: row; + justify-content: space-around; + height: fit-content; +} + +.rand-quote-gen .play-area .quote-area { + min-height: 15rem; + height: fit-content; + width: 100%; + display: flex; + flex-direction: column; + justify-content: center; +} + +.rand-quote-gen .play-area .quote-area .quote{ + height: 100%; + width: 55%; + font-size: 2rem; + justify-items: center; + margin-left: 25%; +} + +.rand-quote-gen .play-area .quote-area .page-author { + width: 45%; + display: flex; + justify-content: space-between; +} + +.rand-quote-gen .play-area .quote-area .page-author{ + margin-left: 30%; +} + +.rand-quote-gen .play-area .quote-area .page-author quote-author .author { + float: right; +} + +.rand-quote-gen .play-area .change-btn { + width: 5rem; + height: 100%; + background: transparent; + display: flex; + align-items: center; + justify-content: center; + border:none; +} + +.rand-quote-gen .play-area .change-btn:hover:enabled { + background-color: rgb(193, 192, 192); +} + +@media only screen and (max-width: 760px) { + .rand-quote-gen .play-area .quote-area .quote { + font-size: 1rem; + width: 100%; + margin-left: 0; + padding: 0 10px 0 10px; + } + + .rand-quote-gen .play-area .change-btn { + width: 3rem; + height: 100%; + background: transparent; + display: flex; + align-items: center; + justify-content: center; + border:none; + } + + .rand-quote-gen .play-area .quote-area { + min-height: 10rem; + height: fit-content; + width: 100%; + display: flex; + flex-direction: column; + justify-content: center; + } + + .rand-qutote-gen .play-area { + border: none; + display: flex; + flex-direction: row; + justify-content: space-between; + height: fit-content; + width: 100%; + } + + .rand-quote-gen .play-area .quote-area .page-author{ + margin-left: 0; + width: 100%; + padding: 0 10px 0 10px; + } + + .rand-quote-gen .play-area .change-btn:hover { + background-color: rgb(193, 192, 192); + } +}