From 656ea960e2a04ab01ceb791acf631b1dab902251 Mon Sep 17 00:00:00 2001 From: GOKULNATH R S <114755342+GOKULNATH-RS@users.noreply.github.com> Date: Sun, 6 Aug 2023 21:15:10 +0530 Subject: [PATCH 1/5] Added files of Topic with updated styling in notes In notes the height and character limit has been changed --- Topic.css | 232 +++++++++++++++++++++++ Topic.js | 541 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 773 insertions(+) create mode 100644 Topic.css create mode 100644 Topic.js diff --git a/Topic.css b/Topic.css new file mode 100644 index 0000000..db263f5 --- /dev/null +++ b/Topic.css @@ -0,0 +1,232 @@ +:root { + /* These are the breakpoints, usage: for media query */ + --table-xl-width: 1140px; + --table-lg-width: 960px; + --table-md-width: 720px; + --table-sm-width: 540px; +} + +.Toastify__toast-body { + color: white; + font-family: "Ubuntu Mono", monospace; + font-weight: 600; + padding: 0 0.5rem; +} + +.Toastify__toast-body .toast-subtitle { + font-weight: 400; + font-size: small; +} + +/* Marked Complete */ +.Toastify__toast.toast-Done { + background: #27ae60; +} + +.Toastify__toast.toast-Done .Toastify__progress-bar { + background: #c8e6c9; +} + +/* Marked Incomplete */ +.Toastify__toast.toast-Incomplete { + background: #007bff; +} + +.Toastify__toast.toast-Incomplete .Toastify__progress-bar { + background: #aad0f6; +} + +.sort-button { + margin: 0px 20px 0px 20px; +} + +/* Notes section */ +.note-container { + background: white; + position: absolute; + display: block; + height: 70%; + width: 50%; + padding: 2% 1%; + top: 30%; + right: 25%; + border: 2px solid black; + border-radius: 0.5em; +} + +.question-title { + width: 100%; + background: rgb(243, 243, 243); + margin-bottom: 0.5em; + font-weight: bold; + resize: none; + font-size: 1.2em; + border: 0.5px solid black; + border-radius: 5px; + padding: 0.5em 0.8em; + word-wrap: break-word; +} + +.note-section { + background: rgb(255, 255, 255); + display: none; + border: 2px solid #27ae60; + border-radius: 5px; + position: relative; + margin-bottom: 0.5em; + width: 100%; + padding: 0.5em 0.8em; + resize: none; + height: 30em; +} +.note-section:focus-visible { + outline: none; +} + +::placeholder { + color: black; + opacity: 0.5; +} +.button-container { + display: flex; + align-items: right; + flex-direction: row-reverse; + justify-content: flex-end; +} + +.note-exit { + display: none; + position: relative; + width: 5em; + background: #dc3545; + margin-right: 0.3em; + border-radius: 0.3em; + color: white; +} + +.note-save { + display: none; + position: relative; + background: #27ae60; + width: 5em; + border-radius: 0.3em; + margin-right: 0.3em; + color: white; +} + +.note-area { + display: none; + height: 10em; + width: 10em; + background: rgba(255, 255, 255, 0.1); + backdrop-filter: blur(2px); + + top: 0; + position: fixed; + width: 100%; + height: 100%; +} + +#tooltip-top > .tooltip-inner { + background-color: #fff; + color: green; + border: 1px solid #062e56; +} + +#tooltip-top > .tooltip-arrow { + border-top: 5px solid #062e56; +} +.dark-table { + color: white; +} + +.question-link:hover { + color: rgb(0, 115, 192); +} +.header-rand { + display: flex; + flex-direction: column; + align-items: center; +} +.random { + margin-bottom: 25px; +} +.random > a { + padding: 10px 15px; + border-radius: 10px; + background-color: #27ae60; + color: white; + text-decoration: none; +} +.random > a:hover { + color: white; + background-color: #1a8647; +} +.pick-random-btn { + z-index: 0 !important; /*To Override z-index set by Bootstrap*/ +} + +.completed-questions { + margin: 0px; + background: rgb(200, 230, 201); + font-size: 18px; + font-weight: 100; + padding: 5px 8px; + margin-left: auto; +} + +.topic-input-container { + display: flex; + width: 100%; + max-width: var(--table-xl-width); + padding: 0px 15px; + box-sizing: border-box; + align-items: center; +} +.container-custom2 { + margin: 0px; + padding-left: 0px; +} +.container-custom2 > .mb-4 { + padding: 10px 0px; + margin-bottom: 0px !important; +} + +@media screen and (max-width: 1199px) { + .topic-input-container { + max-width: var(--table-lg-width); + } +} +@media screen and (max-width: 991px) { + .topic-input-container { + max-width: var(--table-md-width); + } +} +@media screen and (max-width: 767px) { + .container-custom { + padding-bottom: 50px; + } + .search-input-container { + min-width: 300px !important; + } + .container-custom2 > .mb-4 { + margin-left: 0px !important; + } + .container-custom2 { + width: 100% !important; + } + .topic-input-container { + flex-direction: column; + align-items: flex-start; + } + .container-custom2 > .topic-input-container { + flex-direction: column; + } + .topic-input-container { + max-width: var(--table-sm-width); + margin-bottom: 10px; + } + .completed-questions { + margin-left: 0px; + } +} diff --git a/Topic.js b/Topic.js new file mode 100644 index 0000000..4382215 --- /dev/null +++ b/Topic.js @@ -0,0 +1,541 @@ +import React, { useState, useEffect, useContext } from 'react'; +import BootstrapTable from 'react-bootstrap-table-next'; +import ToolkitProvider from 'react-bootstrap-table2-toolkit'; +import InputGroup from 'react-bootstrap/InputGroup'; +import FormControl from 'react-bootstrap/FormControl'; +import Spinner from 'react-bootstrap/Spinner'; +import OverlayTrigger from 'react-bootstrap/OverlayTrigger'; +import Tooltip from 'react-bootstrap/Tooltip'; +import Badge from 'react-bootstrap/Badge'; +import Fade from 'react-reveal/Fade'; +import { Link } from 'react-router-dom'; +import { toast, ToastContainer } from 'react-toastify'; +import 'react-toastify/dist/ReactToastify.min.css'; +import 'react-bootstrap-table-next/dist/react-bootstrap-table2.min.css'; +import './Topic.css'; +import { ThemeContext } from '../../App'; +import Button from 'react-bootstrap/Button'; + +export default function Topic({ data, updateData }) { + /* + This component takes data releted to a paticular topic + and updateData() from App component + */ + /* + Setting state for fields that comes from `data` prop + so that `data` prop is not undefined on reload + */ + const [select, setSelected] = useState([]); + const [isBookmarkSortFilterSelected, setIsBookmarkSortFilterSelected] = useState(false); + const [isSelectedComplete, setSelectedComplete] = useState(true); + const [sortMode, setSortMode] = useState({ + dataField: '_is_selected', + order: 'asc', + }); + const [questionsTableData, setQuestionsTableData] = useState([]); + const [topicName, setTopicName] = useState(''); + + const dark = useContext(ThemeContext); + // updating states using useEffect with dependency on `data` prop + useEffect(() => { + if (data !== undefined) { + let doneQuestion = []; + + let tableData = data.questions.map((question, index) => { + if (question.Done) { + doneQuestion.push(index); + } + /* + | Hidden properties `_is_selected` and `_search_text` are used to sort the table + | and search the table respectively. react-bootstrap-table does not allow sorting + | by selectRow by default, and requires plain text to perform searches. + */ + return { + id: index, + question: ( +
+ {/* Question link */} + + {question.Problem} + +
+ ), + links:( +
+ {question.URL2.length>0 && icon { + window.open(`${question.URL2}&utm_source=website&utm_medium=affiliate&utm_campaign=450dsatracker`, '_blank'); + }} + />} + + icon { + window.open(question.URL, '_blank'); + }} + /> +
+ ), + controls: ( +
+ {/* icon { + window.open(question.URL, '_blank'); + }} + /> */} + + handleBookmark(index, question)} + > + {question.Bookmark ? ( + + ) : ( + + )} + + + + shownotes(index)} + > + {question.Notes && question.Notes.length !== 0 ? ( + + ) : ( + + )} + + +
+ ), + + _is_selected: question.Done, + Bookmark: question.Bookmark, + _search_text: question.Problem, + }; + }); + setQuestionsTableData(tableData); + setTopicName(data.topicName); + setSelected(doneQuestion); + } + }, [data]); + + //tooltip functions + const renderTooltipAddBookmark = (props) => ( + + Add Bookmark + + ); + + const renderTooltipRemoveBookmark = (props) => ( + + Remove Bookmark + + ); + + const renderTooltipSortBookmark = (props) => ( + + Show Bookmarks + + ); + + const renderTooltipResetSortBookmark = (props) => ( + + Reset Show Bookmarks + + ); + + const renderTooltipView = (props) => ( + + View Notes + + ); + + const renderTooltipAdd = (props) => ( + + Add Notes + + ); + + // seacrh bar config + const Sorter = (x) => { + if (!x) { + setSortMode({ + dataField: 'Bookmark', + order: 'desc', + }); + setSelectedComplete(x); + } else { + setSortMode({ + dataField: '_is_selected', + order: 'asc', + }); + setSelectedComplete(x); + } + setIsBookmarkSortFilterSelected(!x); + }; + const SearchBar = (props) => { + const handleChange = (e) => { + props.onSearch(e.target.value); + }; + return ( +
+
+ + + + + + + +

+ + {data.doneQuestions}/{data.questions.length} + {' '} + Done{' '} + + ✅ + +

+
+
+ + + +
+
+
+ ); + }; + // table config + const columns = [ + { + dataField: 'id', + text: 'id', + headerStyle: { width: '40px', fontSize: '20px', textAlign: 'center' }, + style: { fontSize: '20px', cursor: 'pointer', textAlign: 'center' }, + events: { + onClick: (e, column, columnIndex, row, rowIndex) => { + handleSelect(row, !row._is_selected); + }, + }, + }, + { + dataField: 'question', + text: 'Questions', + headerStyle: { fontSize: '20px', textAlign: 'center', width: '80%' }, + }, + { + dataField: 'links', + text: 'Links', + headerStyle: { fontSize: '20px', textAlign: 'center' }, + }, + { + dataField: 'controls', + text: '', + headerStyle: { fontSize: '20px', textAlign: 'center' }, + }, + { + dataField: '_is_selected', + text: 'Is Selected', + headerStyle: { fontSize: '20px' }, + hidden: true, + sort: true, + }, + { + dataField: '_search_text', + text: 'Search Text', + headerStyle: { fontSize: '20px' }, + hidden: true, + }, + { + dataField: 'Bookmark', + text: 'Bookmark', + headerStyle: { fontSize: '20px' }, + hidden: true, + }, + ]; + const rowStyle = { fontSize: '20px' }; + const selectRow = { + mode: 'checkbox', + style: { background: dark ? '#393E46' : '#c8e6c9', fontSize: '24px' }, + selected: select, + onSelect: handleSelect, + hideSelectAll: true, + }; + // func() triggered when a question is marked done + function handleSelect(row, isSelect) { + let key = topicName.replace(/[^A-Z0-9]+/gi, '_').toLowerCase(); + let newDoneQuestion = [...select]; + let updatedQuestionsStatus = data.questions.map((question, index) => { + if (row.id === index) { + question.Done = isSelect; + if (isSelect) { + newDoneQuestion.push(row.id); + } else { + var pos = newDoneQuestion.indexOf(row.id); + newDoneQuestion.splice(pos, 1); + } + return question; + } else { + return question; + } + }); + updateData( + key, + { + started: newDoneQuestion.length > 0 ? true : false, + doneQuestions: newDoneQuestion.length, + questions: updatedQuestionsStatus, + }, + data.position + ); + if (isSelectedComplete) displayToast(isSelect, row.id); + } + + // trigger an information message for user on select change + function displayToast(isSelect, id) { + const { type, icon, dir } = { + type: isSelect ? 'Done' : 'Incomplete', + icon: isSelect ? '๐ŸŽ‰' : '๐Ÿ™‡๐Ÿปโ€โ™‚๏ธ', + dir: isSelect ? '๐Ÿ‘‡๐Ÿป' : '๐Ÿ‘†๐Ÿป', + }; + + const title = `${isSelect ? select.length + 1 : select.length - 1}/${data.questions.length} Done`; + const subTitle = `Question pushed ${dir} the table.`; + + const Card = ( + <> +

+ {title} {icon} +

+

{subTitle}

+ + ); + + toast(Card, { + className: `toast-${type}`, + autoClose: 2000, + closeButton: true, + }); + } + + //Notes component + const NoteSection = (props) => { + let id = localStorage.getItem('cid'); + + const [quickNotes, setQuickNotes] = useState(data.questions[id]?.Notes); + const addnewnotes = (event) => { + setQuickNotes(event.target.value); + }; + + const onadd = () => { + let key = topicName.replace(/[^A-Z0-9]+/gi, '_').toLowerCase(); + // let id = localStorage.getItem("cid"); + if (id) { + let que = data.questions; + que[id].Notes = quickNotes.trim().length === 0 ? '' : quickNotes.trim(); + updateData( + key, + { + started: data.started, + doneQuestions: data.doneQuestions, + questions: que, + }, + data.position + ); + localStorage.removeItem('cid'); + } else { + saveAndExitNotes(); + } + }; + + return ( + <> +
+
+
+ +
+ + +
+
+
+ + ); + }; + //function for bookmarks + function handleBookmark(row, quest) { + let key = topicName.replace(/[^A-Z0-9]+/gi, '_').toLowerCase(); + let newDoneQuestion = [...select]; + let updatedQuestionsStatus = data.questions.map((question, index) => { + if (row === index) { + question.Bookmark = quest.Bookmark ? false : true; + return question; + } else { + return question; + } + }); + updateData( + key, + { + started: newDoneQuestion.length > 0 ? true : false, + doneQuestions: newDoneQuestion.length, + questions: updatedQuestionsStatus, + }, + data.position + ); + // console.log(quest.Bookmark) + } + //function for closing notes + function saveAndExitNotes() { + document.getElementsByClassName('note-section')[0].style.display = 'none'; + document.getElementsByClassName('note-exit')[0].style.display = 'none'; + document.getElementsByClassName('note-save')[0].style.display = 'none'; + document.getElementsByClassName('note-area')[0].style.display = 'none'; + localStorage.removeItem('cid'); + } + //funtion for taking notes + function shownotes(ind) { + document.getElementsByClassName('note-section')[0].style.display = 'block'; + document.getElementsByClassName('note-exit')[0].style.display = 'block'; + document.getElementsByClassName('note-save')[0].style.display = 'block'; + document.getElementsByClassName('note-area')[0].style.display = 'block'; + + localStorage.setItem('cid', ind); + document.getElementsByClassName('note-section')[0].value = data.questions[ind].Notes; + document.getElementsByClassName('question-title')[0].innerHTML = data.questions[ind].Problem; + } + return ( + <> +

+ Topics/{topicName} +

+ + {data === undefined ? ( +
+ +
+ ) : ( + + {(props) => ( +
+
{SearchBar({ ...props.searchProps })}
+
+ + + +
+
+ )} +
+ )} + + + + ); +} + +function RandomButton({ data }) { + let min = 0; + let max = data.questions.length - 1; + const [rnd, setRnd] = useState(Math.floor(Math.random() * (max - min)) + min); + function pickRandomHandler() { + setRnd(Math.floor(Math.random() * (max - min)) + min); + } + return ( + + ); +} From 86daa184e4b08e22d43d565c329de65172c2f1ee Mon Sep 17 00:00:00 2001 From: GOKULNATH R S <114755342+GOKULNATH-RS@users.noreply.github.com> Date: Sun, 6 Aug 2023 21:16:25 +0530 Subject: [PATCH 2/5] Update Topic.css --- src/components/Topic/Topic.css | 283 +++++++++++++++++---------------- 1 file changed, 142 insertions(+), 141 deletions(-) diff --git a/src/components/Topic/Topic.css b/src/components/Topic/Topic.css index 84f298f..235fe1d 100644 --- a/src/components/Topic/Topic.css +++ b/src/components/Topic/Topic.css @@ -1,231 +1,232 @@ :root { - /* These are the breakpoints, usage: for media query */ - --table-xl-width: 1140px; - --table-lg-width: 960px; - --table-md-width: 720px; - --table-sm-width: 540px; + /* These are the breakpoints, usage: for media query */ + --table-xl-width: 1140px; + --table-lg-width: 960px; + --table-md-width: 720px; + --table-sm-width: 540px; } .Toastify__toast-body { - color: white; - font-family: 'Ubuntu Mono', monospace; - font-weight: 600; - padding: 0 0.5rem; + color: white; + font-family: "Ubuntu Mono", monospace; + font-weight: 600; + padding: 0 0.5rem; } .Toastify__toast-body .toast-subtitle { - font-weight: 400; - font-size: small; + font-weight: 400; + font-size: small; } /* Marked Complete */ .Toastify__toast.toast-Done { - background: #27ae60; + background: #27ae60; } .Toastify__toast.toast-Done .Toastify__progress-bar { - background: #c8e6c9; + background: #c8e6c9; } /* Marked Incomplete */ .Toastify__toast.toast-Incomplete { - background: #007bff; + background: #007bff; } .Toastify__toast.toast-Incomplete .Toastify__progress-bar { - background: #aad0f6; + background: #aad0f6; } .sort-button { - margin: 0px 20px 0px 20px; + margin: 0px 20px 0px 20px; } /* Notes section */ .note-container { - background: white; - position: absolute; - display: block; - width: 50%; - padding: 2% 1%; - top: 30%; - right: 25%; - border: 2px solid black; - border-radius: 0.5em; + background: white; + position: absolute; + display: block; + height: 70%; + width: 50%; + padding: 2% 1%; + top: 30%; + right: 25%; + border: 2px solid black; + border-radius: 0.5em; } .question-title { - width: 100%; - background: rgb(243, 243, 243); - margin-bottom: 0.5em; - font-weight: bold; - resize: none; - font-size: 1.2em; - border: 0.5px solid black; - border-radius: 5px; - padding: 0.5em 0.8em; - word-wrap: break-word; + width: 100%; + background: rgb(243, 243, 243); + margin-bottom: 0.5em; + font-weight: bold; + resize: none; + font-size: 1.2em; + border: 0.5px solid black; + border-radius: 5px; + padding: 0.5em 0.8em; + word-wrap: break-word; } .note-section { - background: rgb(255, 255, 255); - display: none; - border: 2px solid #27ae60; - border-radius: 5px; - position: relative; - margin-bottom: 0.5em; - width: 100%; - padding: 0.5em 0.8em; - resize: none; - height: 10em; + background: rgb(255, 255, 255); + display: none; + border: 2px solid #27ae60; + border-radius: 5px; + position: relative; + margin-bottom: 0.5em; + width: 100%; + padding: 0.5em 0.8em; + resize: none; + height: 30em; } .note-section:focus-visible { - outline: none; + outline: none; } ::placeholder { - color: black; - opacity: 0.5; + color: black; + opacity: 0.5; } .button-container { - display: flex; - align-items: right; - flex-direction: row-reverse; - justify-content: flex-end; + display: flex; + align-items: right; + flex-direction: row-reverse; + justify-content: flex-end; } .note-exit { - display: none; - position: relative; - width: 5em; - background: #dc3545; - margin-right: 0.3em; - border-radius: 0.3em; - color: white; + display: none; + position: relative; + width: 5em; + background: #dc3545; + margin-right: 0.3em; + border-radius: 0.3em; + color: white; } .note-save { - display: none; - position: relative; - background: #27ae60; - width: 5em; - border-radius: 0.3em; - margin-right: 0.3em; - color: white; + display: none; + position: relative; + background: #27ae60; + width: 5em; + border-radius: 0.3em; + margin-right: 0.3em; + color: white; } .note-area { - display: none; - height: 10em; - width: 10em; - background: rgba(255, 255, 255, 0.1); - backdrop-filter: blur(2px); + display: none; + height: 10em; + width: 10em; + background: rgba(255, 255, 255, 0.1); + backdrop-filter: blur(2px); - top: 0; - position: fixed; - width: 100%; - height: 100%; + top: 0; + position: fixed; + width: 100%; + height: 100%; } #tooltip-top > .tooltip-inner { - background-color: #fff; - color: green; - border: 1px solid #062e56; + background-color: #fff; + color: green; + border: 1px solid #062e56; } #tooltip-top > .tooltip-arrow { - border-top: 5px solid #062e56; + border-top: 5px solid #062e56; } .dark-table { - color: white; + color: white; } .question-link:hover { - color: rgb(0, 115, 192); + color: rgb(0, 115, 192); } .header-rand { - display: flex; - flex-direction: column; - align-items: center; + display: flex; + flex-direction: column; + align-items: center; } .random { - margin-bottom: 25px; + margin-bottom: 25px; } .random > a { - padding: 10px 15px; - border-radius: 10px; - background-color: #27ae60; - color: white; - text-decoration: none; + padding: 10px 15px; + border-radius: 10px; + background-color: #27ae60; + color: white; + text-decoration: none; } .random > a:hover { - color: white; - background-color: #1a8647; + color: white; + background-color: #1a8647; } .pick-random-btn { - z-index: 0 !important; /*To Override z-index set by Bootstrap*/ + z-index: 0 !important; /*To Override z-index set by Bootstrap*/ } .completed-questions { - margin: 0px; - background: rgb(200, 230, 201); - font-size: 18px; - font-weight: 100; - padding: 5px 8px; - margin-left: auto; + margin: 0px; + background: rgb(200, 230, 201); + font-size: 18px; + font-weight: 100; + padding: 5px 8px; + margin-left: auto; } .topic-input-container { - display: flex; - width: 100%; - max-width: var(--table-xl-width); - padding: 0px 15px; - box-sizing: border-box; - align-items: center; + display: flex; + width: 100%; + max-width: var(--table-xl-width); + padding: 0px 15px; + box-sizing: border-box; + align-items: center; } .container-custom2 { - margin: 0px; - padding-left: 0px; + margin: 0px; + padding-left: 0px; } .container-custom2 > .mb-4 { - padding: 10px 0px; - margin-bottom: 0px !important; + padding: 10px 0px; + margin-bottom: 0px !important; } @media screen and (max-width: 1199px) { - .topic-input-container { - max-width: var(--table-lg-width); - } + .topic-input-container { + max-width: var(--table-lg-width); + } } @media screen and (max-width: 991px) { - .topic-input-container { - max-width: var(--table-md-width); - } + .topic-input-container { + max-width: var(--table-md-width); + } } @media screen and (max-width: 767px) { - .container-custom { - padding-bottom: 50px; - } - .search-input-container { - min-width: 300px !important; - } - .container-custom2 > .mb-4 { - margin-left: 0px !important; - } - .container-custom2 { - width: 100% !important; - } - .topic-input-container { - flex-direction: column; - align-items: flex-start; - } - .container-custom2 > .topic-input-container { - flex-direction: column; - } - .topic-input-container { - max-width: var(--table-sm-width); - margin-bottom: 10px; - } - .completed-questions { - margin-left: 0px; - } + .container-custom { + padding-bottom: 50px; + } + .search-input-container { + min-width: 300px !important; + } + .container-custom2 > .mb-4 { + margin-left: 0px !important; + } + .container-custom2 { + width: 100% !important; + } + .topic-input-container { + flex-direction: column; + align-items: flex-start; + } + .container-custom2 > .topic-input-container { + flex-direction: column; + } + .topic-input-container { + max-width: var(--table-sm-width); + margin-bottom: 10px; + } + .completed-questions { + margin-left: 0px; + } } From b950549709dd70b26b7730c41d198a9be9dbe7fa Mon Sep 17 00:00:00 2001 From: GOKULNATH R S <114755342+GOKULNATH-RS@users.noreply.github.com> Date: Sun, 6 Aug 2023 21:17:03 +0530 Subject: [PATCH 3/5] Update Topic.js --- src/components/Topic/Topic.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Topic/Topic.js b/src/components/Topic/Topic.js index d5e7e3d..eb6f58a 100644 --- a/src/components/Topic/Topic.js +++ b/src/components/Topic/Topic.js @@ -423,7 +423,7 @@ export default function Topic({ data, updateData }) {
- +
- - -
-
- ); - }; - // table config - const columns = [ - { - dataField: 'id', - text: 'id', - headerStyle: { width: '40px', fontSize: '20px', textAlign: 'center' }, - style: { fontSize: '20px', cursor: 'pointer', textAlign: 'center' }, - events: { - onClick: (e, column, columnIndex, row, rowIndex) => { - handleSelect(row, !row._is_selected); - }, - }, - }, - { - dataField: 'question', - text: 'Questions', - headerStyle: { fontSize: '20px', textAlign: 'center', width: '80%' }, - }, - { - dataField: 'links', - text: 'Links', - headerStyle: { fontSize: '20px', textAlign: 'center' }, - }, - { - dataField: 'controls', - text: '', - headerStyle: { fontSize: '20px', textAlign: 'center' }, - }, - { - dataField: '_is_selected', - text: 'Is Selected', - headerStyle: { fontSize: '20px' }, - hidden: true, - sort: true, - }, - { - dataField: '_search_text', - text: 'Search Text', - headerStyle: { fontSize: '20px' }, - hidden: true, - }, - { - dataField: 'Bookmark', - text: 'Bookmark', - headerStyle: { fontSize: '20px' }, - hidden: true, - }, - ]; - const rowStyle = { fontSize: '20px' }; - const selectRow = { - mode: 'checkbox', - style: { background: dark ? '#393E46' : '#c8e6c9', fontSize: '24px' }, - selected: select, - onSelect: handleSelect, - hideSelectAll: true, - }; - // func() triggered when a question is marked done - function handleSelect(row, isSelect) { - let key = topicName.replace(/[^A-Z0-9]+/gi, '_').toLowerCase(); - let newDoneQuestion = [...select]; - let updatedQuestionsStatus = data.questions.map((question, index) => { - if (row.id === index) { - question.Done = isSelect; - if (isSelect) { - newDoneQuestion.push(row.id); - } else { - var pos = newDoneQuestion.indexOf(row.id); - newDoneQuestion.splice(pos, 1); - } - return question; - } else { - return question; - } - }); - updateData( - key, - { - started: newDoneQuestion.length > 0 ? true : false, - doneQuestions: newDoneQuestion.length, - questions: updatedQuestionsStatus, - }, - data.position - ); - if (isSelectedComplete) displayToast(isSelect, row.id); - } - - // trigger an information message for user on select change - function displayToast(isSelect, id) { - const { type, icon, dir } = { - type: isSelect ? 'Done' : 'Incomplete', - icon: isSelect ? '๐ŸŽ‰' : '๐Ÿ™‡๐Ÿปโ€โ™‚๏ธ', - dir: isSelect ? '๐Ÿ‘‡๐Ÿป' : '๐Ÿ‘†๐Ÿป', - }; - - const title = `${isSelect ? select.length + 1 : select.length - 1}/${data.questions.length} Done`; - const subTitle = `Question pushed ${dir} the table.`; - - const Card = ( - <> -

- {title} {icon} -

-

{subTitle}

- - ); - - toast(Card, { - className: `toast-${type}`, - autoClose: 2000, - closeButton: true, - }); - } - - //Notes component - const NoteSection = (props) => { - let id = localStorage.getItem('cid'); - - const [quickNotes, setQuickNotes] = useState(data.questions[id]?.Notes); - const addnewnotes = (event) => { - setQuickNotes(event.target.value); - }; - - const onadd = () => { - let key = topicName.replace(/[^A-Z0-9]+/gi, '_').toLowerCase(); - // let id = localStorage.getItem("cid"); - if (id) { - let que = data.questions; - que[id].Notes = quickNotes.trim().length === 0 ? '' : quickNotes.trim(); - updateData( - key, - { - started: data.started, - doneQuestions: data.doneQuestions, - questions: que, - }, - data.position - ); - localStorage.removeItem('cid'); - } else { - saveAndExitNotes(); - } - }; - - return ( - <> -
-
-
- -
- - -
-
-
- - ); - }; - //function for bookmarks - function handleBookmark(row, quest) { - let key = topicName.replace(/[^A-Z0-9]+/gi, '_').toLowerCase(); - let newDoneQuestion = [...select]; - let updatedQuestionsStatus = data.questions.map((question, index) => { - if (row === index) { - question.Bookmark = quest.Bookmark ? false : true; - return question; - } else { - return question; - } - }); - updateData( - key, - { - started: newDoneQuestion.length > 0 ? true : false, - doneQuestions: newDoneQuestion.length, - questions: updatedQuestionsStatus, - }, - data.position - ); - // console.log(quest.Bookmark) - } - //function for closing notes - function saveAndExitNotes() { - document.getElementsByClassName('note-section')[0].style.display = 'none'; - document.getElementsByClassName('note-exit')[0].style.display = 'none'; - document.getElementsByClassName('note-save')[0].style.display = 'none'; - document.getElementsByClassName('note-area')[0].style.display = 'none'; - localStorage.removeItem('cid'); - } - //funtion for taking notes - function shownotes(ind) { - document.getElementsByClassName('note-section')[0].style.display = 'block'; - document.getElementsByClassName('note-exit')[0].style.display = 'block'; - document.getElementsByClassName('note-save')[0].style.display = 'block'; - document.getElementsByClassName('note-area')[0].style.display = 'block'; - - localStorage.setItem('cid', ind); - document.getElementsByClassName('note-section')[0].value = data.questions[ind].Notes; - document.getElementsByClassName('question-title')[0].innerHTML = data.questions[ind].Problem; - } - return ( - <> -

- Topics/{topicName} -

- - {data === undefined ? ( -
- -
- ) : ( - - {(props) => ( -
-
{SearchBar({ ...props.searchProps })}
-
- - - -
-
- )} -
- )} - - - - ); -} - -function RandomButton({ data }) { - let min = 0; - let max = data.questions.length - 1; - const [rnd, setRnd] = useState(Math.floor(Math.random() * (max - min)) + min); - function pickRandomHandler() { - setRnd(Math.floor(Math.random() * (max - min)) + min); - } - return ( - - ); -}