| @@ -88,7 +88,35 @@ | |||||
| margin-bottom: 1.5rem; | margin-bottom: 1.5rem; | ||||
| background-color: white; | background-color: white; | ||||
| &:nth-child(2n) { | |||||
| &:nth-child(4n - 4) { | |||||
| &::before { | |||||
| background-color: var(--orange); | |||||
| } | |||||
| header { | |||||
| h4 { | |||||
| span { | |||||
| color: var(--orange); | |||||
| } | |||||
| } | |||||
| button { | |||||
| background-color: var(--orange); | |||||
| } | |||||
| } | |||||
| .description { | |||||
| span, p { | |||||
| color: var(--orange); | |||||
| } | |||||
| } | |||||
| .addButton { | |||||
| background-color: var(--teal); | |||||
| } | |||||
| } | |||||
| &:nth-child(4n - 3) { | |||||
| &::before { | &::before { | ||||
| background-color: var(--teal); | background-color: var(--teal); | ||||
| } | } | ||||
| @@ -116,6 +144,63 @@ | |||||
| } | } | ||||
| } | } | ||||
| &:nth-child(4n - 2) { | |||||
| &::before { | |||||
| background-color: var(--blue); | |||||
| } | |||||
| header { | |||||
| h4 { | |||||
| span { | |||||
| color: var(--blue); | |||||
| } | |||||
| } | |||||
| button { | |||||
| background-color: var(--blue); | |||||
| } | |||||
| } | |||||
| .description { | |||||
| span, p { | |||||
| color: var(--blue); | |||||
| } | |||||
| } | |||||
| .addButton { | |||||
| background-color: var(--blue); | |||||
| } | |||||
| } | |||||
| &:nth-child(4n - 1) { | |||||
| &::before { | |||||
| background-color: var(--red); | |||||
| } | |||||
| header { | |||||
| h4 { | |||||
| span { | |||||
| color: var(--red); | |||||
| } | |||||
| } | |||||
| button { | |||||
| background-color: var(--red); | |||||
| } | |||||
| } | |||||
| .description { | |||||
| span, p { | |||||
| color: var(--red); | |||||
| } | |||||
| } | |||||
| .addButton { | |||||
| background-color: var(--red); | |||||
| } | |||||
| } | |||||
| &::before { | &::before { | ||||
| content: ''; | content: ''; | ||||
| position: absolute; | position: absolute; | ||||
| @@ -7,12 +7,13 @@ import { ReactComponent as AddIcon } from '../../assets/icons/plus.svg'; | |||||
| import { IWord } from "../../structure/word"; | import { IWord } from "../../structure/word"; | ||||
| import { ALL_WORDS } from "../../data/all-words"; | import { ALL_WORDS } from "../../data/all-words"; | ||||
| import { NavLink } from "react-router-dom"; | |||||
| import { NavLink, useHistory } from "react-router-dom"; | |||||
| import { userProfileData } from "../../App"; | import { userProfileData } from "../../App"; | ||||
| export const AddWord: React.FC = () => { | export const AddWord: React.FC = () => { | ||||
| const [searchWordResult, setSearchResult] = useState<Array<IWord>>([]); | |||||
| const [searchWordResult, setSearchResult] = useState<Array<IWord>>(ALL_WORDS); | |||||
| const [selectedWord, setSelectedWord] = useState<IWord>(); | const [selectedWord, setSelectedWord] = useState<IWord>(); | ||||
| const history = useHistory(); | |||||
| const searchWords = (searchWord: string) => { | const searchWords = (searchWord: string) => { | ||||
| if (searchWord.length > 0) { | if (searchWord.length > 0) { | ||||
| @@ -22,7 +23,7 @@ export const AddWord: React.FC = () => { | |||||
| setSearchResult(result); | setSearchResult(result); | ||||
| } else { | } else { | ||||
| setSearchResult([]); | |||||
| setSearchResult(ALL_WORDS); | |||||
| } | } | ||||
| } | } | ||||
| @@ -89,7 +90,14 @@ export const AddWord: React.FC = () => { | |||||
| { userProfileData.categories.map((category, categoryIndex) => { | { userProfileData.categories.map((category, categoryIndex) => { | ||||
| return category.shelves.map((shelf, shelfIndex) => { | return category.shelves.map((shelf, shelfIndex) => { | ||||
| return <li key={shelf.name} onClick={() => { | return <li key={shelf.name} onClick={() => { | ||||
| userProfileData.categories[categoryIndex].shelves[shelfIndex].words.push(selectedWord); | |||||
| let findWord = userProfileData.categories[categoryIndex].shelves[shelfIndex].words.find(word => word.name.toLowerCase().includes(selectedWord.name.toLowerCase())); | |||||
| if (findWord) { | |||||
| alert("Word already Present!"); | |||||
| } else { | |||||
| userProfileData.categories[categoryIndex].shelves[shelfIndex].words.push(selectedWord); | |||||
| history.push('/shelf-details/category_id=' + categoryIndex + '&&shelf_id=' + shelfIndex); | |||||
| } | |||||
| }}> | }}> | ||||
| <div className={styles.icon}> | <div className={styles.icon}> | ||||
| { category.icon } | { category.icon } | ||||
| @@ -37,4 +37,366 @@ | |||||
| border: 1px solid var(--creamy-white); | border: 1px solid var(--creamy-white); | ||||
| } | } | ||||
| } | } | ||||
| } | |||||
| .tabHeading { | |||||
| background-color: transparent; | |||||
| position: relative; | |||||
| padding: 1.5rem 0 8rem; | |||||
| text-align: center; | |||||
| &::before { | |||||
| content: ''; | |||||
| position: absolute; | |||||
| left: 0; | |||||
| bottom: 0; | |||||
| width: 100%; | |||||
| height: 100%; | |||||
| background-color: var(--teal); | |||||
| border-top-left-radius: 3rem; | |||||
| border-top-right-radius: 3rem; | |||||
| } | |||||
| &>* { | |||||
| position: relative; | |||||
| } | |||||
| h4 { | |||||
| color: white; | |||||
| font-size: 2.2rem; | |||||
| font-weight: 600; | |||||
| } | |||||
| p { | |||||
| color: white; | |||||
| font-size: 1.4rem; | |||||
| } | |||||
| .moreButton { | |||||
| position: absolute; | |||||
| right: 2rem; | |||||
| top: 2.5rem; | |||||
| width: 2rem; | |||||
| height: 5rem; | |||||
| display: flex; | |||||
| align-items: flex-start; | |||||
| justify-content: center; | |||||
| background-color: transparent; | |||||
| border: none; | |||||
| svg { | |||||
| fill: white; | |||||
| width: 1.8rem; | |||||
| height: 1.8rem; | |||||
| } | |||||
| } | |||||
| .progressHolder { | |||||
| padding: 0 4rem; | |||||
| margin-top: 1rem; | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: space-between; | |||||
| .progressBarHolder { | |||||
| width: calc(100% - 6rem); | |||||
| .progressBar { | |||||
| width: 100%; | |||||
| overflow: hidden; | |||||
| height: 1rem; | |||||
| border-radius: 1rem; | |||||
| background-color: white; | |||||
| position: relative; | |||||
| margin-top: 0.3rem; | |||||
| &::before { | |||||
| content: ''; | |||||
| position: absolute; | |||||
| left: 0; | |||||
| top: 0; | |||||
| width: 100%; | |||||
| height: 100%; | |||||
| background-color: var(--red); | |||||
| opacity: 0.6; | |||||
| } | |||||
| span { | |||||
| position: absolute; | |||||
| left: 0; | |||||
| top: 0; | |||||
| width: 0%; | |||||
| height: 100%; | |||||
| background-color: var(--red); | |||||
| border-radius: inherit; | |||||
| } | |||||
| } | |||||
| } | |||||
| .reviseButton { | |||||
| width: 4.5rem; | |||||
| height: 4.5rem; | |||||
| background-color: white; | |||||
| box-shadow: 0px 0px 5px var(--grey); | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: center; | |||||
| border-radius: 50%; | |||||
| border: none; | |||||
| svg { | |||||
| fill: var(--teal); | |||||
| width: 2rem; | |||||
| height: 2rem; | |||||
| } | |||||
| } | |||||
| .info { | |||||
| display: flex; | |||||
| width: 100%; | |||||
| justify-content: space-between; | |||||
| h6 { | |||||
| color: white; | |||||
| font-size: 1.4rem; | |||||
| } | |||||
| span { | |||||
| color: white; | |||||
| font-size: 1.4rem; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| .searchHolder { | |||||
| position: relative; | |||||
| &::before { | |||||
| content: ''; | |||||
| position: absolute; | |||||
| left: 0; | |||||
| bottom: 0; | |||||
| width: 100%; | |||||
| height: 100%; | |||||
| background-color: var(--creamy-white); | |||||
| border-top-left-radius: 3rem; | |||||
| border-top-right-radius: 3rem; | |||||
| } | |||||
| &>* { | |||||
| position: relative; | |||||
| } | |||||
| .searchBar { | |||||
| background-color: white; | |||||
| display: flex; | |||||
| border-radius: 3rem; | |||||
| height: 5rem; | |||||
| width: calc(100% - 6rem); | |||||
| margin: -2.5rem auto 0; | |||||
| align-items: center; | |||||
| justify-content: space-between; | |||||
| box-shadow: 0px 5px 30px -20px var(--grey); | |||||
| transform: translateY(-2.5rem); | |||||
| input { | |||||
| height: 100%; | |||||
| border: 0; | |||||
| width: calc(100% - 5rem); | |||||
| background-color: transparent; | |||||
| padding-left: 2rem; | |||||
| font-size: 1.4rem; | |||||
| } | |||||
| svg { | |||||
| width: 5rem; | |||||
| fill: var(--red); | |||||
| } | |||||
| } | |||||
| } | |||||
| .searchResult { | |||||
| background-color: var(--creamy-white); | |||||
| border-top-right-radius: 3rem; | |||||
| border-top-left-radius: 3rem; | |||||
| margin: -2.5rem 0; | |||||
| min-height: 5rem; | |||||
| padding: 2rem; | |||||
| li { | |||||
| position: relative; | |||||
| overflow: hidden; | |||||
| border-radius: 2rem; | |||||
| padding: 1rem 1.5rem; | |||||
| margin-bottom: 1.5rem; | |||||
| background-color: white; | |||||
| &:nth-child(4n - 4) { | |||||
| &::before { | |||||
| background-color: var(--orange); | |||||
| } | |||||
| header { | |||||
| h4 { | |||||
| span { | |||||
| color: var(--orange); | |||||
| } | |||||
| } | |||||
| button { | |||||
| background-color: var(--orange); | |||||
| } | |||||
| } | |||||
| .description { | |||||
| span, p { | |||||
| color: var(--orange); | |||||
| } | |||||
| } | |||||
| } | |||||
| &:nth-child(4n - 3) { | |||||
| &::before { | |||||
| background-color: var(--teal); | |||||
| } | |||||
| header { | |||||
| h4 { | |||||
| span { | |||||
| color: var(--teal); | |||||
| } | |||||
| } | |||||
| button { | |||||
| background-color: var(--teal); | |||||
| } | |||||
| } | |||||
| .description { | |||||
| span, p { | |||||
| color: var(--teal); | |||||
| } | |||||
| } | |||||
| } | |||||
| &:nth-child(4n - 2) { | |||||
| &::before { | |||||
| background-color: var(--blue); | |||||
| } | |||||
| header { | |||||
| h4 { | |||||
| span { | |||||
| color: var(--blue); | |||||
| } | |||||
| } | |||||
| button { | |||||
| background-color: var(--blue); | |||||
| } | |||||
| } | |||||
| .description { | |||||
| span, p { | |||||
| color: var(--blue); | |||||
| } | |||||
| } | |||||
| } | |||||
| &:nth-child(4n - 1) { | |||||
| &::before { | |||||
| background-color: var(--red); | |||||
| } | |||||
| header { | |||||
| h4 { | |||||
| span { | |||||
| color: var(--red); | |||||
| } | |||||
| } | |||||
| button { | |||||
| background-color: var(--red); | |||||
| } | |||||
| } | |||||
| .description { | |||||
| span, p { | |||||
| color: var(--red); | |||||
| } | |||||
| } | |||||
| } | |||||
| &::before { | |||||
| content: ''; | |||||
| position: absolute; | |||||
| left: 0; | |||||
| top: 0; | |||||
| width: 100%; | |||||
| height: 100%; | |||||
| background-color: var(--orange); | |||||
| opacity: 0.4; | |||||
| } | |||||
| &>* { | |||||
| position: relative; | |||||
| } | |||||
| header { | |||||
| display: flex; | |||||
| align-items: flex-start; | |||||
| justify-content: space-between; | |||||
| h4 { | |||||
| font-size: 2rem; | |||||
| font-weight: 600; | |||||
| color: var(--black); | |||||
| span { | |||||
| display: block; | |||||
| font-size: 1.2rem; | |||||
| color: var(--orange); | |||||
| filter: brightness(50%); | |||||
| font-weight: 500; | |||||
| } | |||||
| } | |||||
| button { | |||||
| background-color: transparent; | |||||
| border: none; | |||||
| background-color: var(--orange); | |||||
| width: 4rem; | |||||
| height: 4rem; | |||||
| border-radius: 50%; | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: center; | |||||
| svg { | |||||
| width: 1.7rem; | |||||
| fill: white; | |||||
| } | |||||
| } | |||||
| } | |||||
| .description { | |||||
| margin: 1rem 0; | |||||
| filter: brightness(40%); | |||||
| opacity: 0.7; | |||||
| span { | |||||
| font-size: 1.2rem; | |||||
| color: var(--orange); | |||||
| font-weight: 600; | |||||
| text-transform: lowercase; | |||||
| } | |||||
| p { | |||||
| font-size: 1.2rem; | |||||
| color: var(--orange); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | } | ||||
| @@ -1,11 +1,17 @@ | |||||
| import React from "react"; | |||||
| import React, { useState } from "react"; | |||||
| import styles from './ShelfDetails.module.scss'; | import styles from './ShelfDetails.module.scss'; | ||||
| import { ReactComponent as ChevronLeft } from '../../assets/icons/chevron-left.svg'; | import { ReactComponent as ChevronLeft } from '../../assets/icons/chevron-left.svg'; | ||||
| import { useLocation } from "react-router-dom"; | |||||
| import { NavLink, useLocation } from "react-router-dom"; | |||||
| import queryString from 'query-string'; | import queryString from 'query-string'; | ||||
| import { ICategory } from "../../structure/category"; | import { ICategory } from "../../structure/category"; | ||||
| import { IShelf } from "../../structure/shelf"; | import { IShelf } from "../../structure/shelf"; | ||||
| import { userProfileData } from "../../App"; | import { userProfileData } from "../../App"; | ||||
| import { ReactComponent as BookIcon } from '../../assets/icons/book-sharp.svg'; | |||||
| import { ReactComponent as MoreIcon } from '../../assets/icons/more-alt.svg'; | |||||
| import { ReactComponent as SearchIcon } from '../../assets/icons/bx-search-alt.svg'; | |||||
| import { ReactComponent as SpeakerIcon } from '../../assets/icons/speaker.svg'; | |||||
| import { IWord } from "../../structure/word"; | |||||
| import { ALL_WORDS } from "../../data/all-words"; | |||||
| export const ShelfDetails: React.FC = () => { | export const ShelfDetails: React.FC = () => { | ||||
| const location = useLocation(); | const location = useLocation(); | ||||
| @@ -13,6 +19,19 @@ export const ShelfDetails: React.FC = () => { | |||||
| const shelf_id: any = queryString.parse(location.pathname)['shelf_id']; | const shelf_id: any = queryString.parse(location.pathname)['shelf_id']; | ||||
| const category: ICategory = userProfileData.categories[category_id]; | const category: ICategory = userProfileData.categories[category_id]; | ||||
| const shelf: IShelf = category.shelves[shelf_id]; | const shelf: IShelf = category.shelves[shelf_id]; | ||||
| const [searchWordResult, setSearchResult] = useState<Array<IWord>>(shelf.words); | |||||
| const searchWords = (searchWord: string) => { | |||||
| if (searchWord.length > 0) { | |||||
| let result = shelf.words.filter((word) => { | |||||
| return word.name.toLowerCase().includes(searchWord.toLowerCase()); | |||||
| }); | |||||
| setSearchResult(result); | |||||
| } else { | |||||
| setSearchResult(shelf.words); | |||||
| } | |||||
| } | |||||
| return <section className="modalPage"> | return <section className="modalPage"> | ||||
| <header className={styles.navHeader}> | <header className={styles.navHeader}> | ||||
| @@ -29,9 +48,47 @@ export const ShelfDetails: React.FC = () => { | |||||
| </header> | </header> | ||||
| <header className={styles.tabHeading}> | <header className={styles.tabHeading}> | ||||
| <button className={styles.moreButton}> | |||||
| <MoreIcon /> | |||||
| </button> | |||||
| <h4> { shelf.name } </h4> | <h4> { shelf.name } </h4> | ||||
| <p> { shelf.words.length } </p> | |||||
| <p> { shelf.words.length } Words </p> | |||||
| { shelf.words.length > 0 && <div className={styles.progressHolder}> | |||||
| <div className={styles.progressBarHolder}> | |||||
| <div className={styles.info}> <h6> Revision </h6> <span> { shelf.revisedWords.length * 100/ shelf.words.length }% </span> </div> | |||||
| <div className={styles.progressBar}> <span className={styles.progress} style={{ width: shelf.revisedWords.length * 100/ shelf.words.length + '%' }}></span> </div> | |||||
| </div> | |||||
| <NavLink to={'/revise'} className={styles.reviseButton}> | |||||
| <BookIcon /> | |||||
| </NavLink> | |||||
| </div> } | |||||
| </header> | </header> | ||||
| <section className={styles.searchHolder}> | |||||
| <div className={styles.searchBar}> | |||||
| <input type="text" autoFocus={true} placeholder={'Search words'} onChange={(event) => searchWords(event.currentTarget.value)} /> | |||||
| <SearchIcon /> | |||||
| </div> | |||||
| </section> | |||||
| <ul className={styles.searchResult}> | |||||
| { searchWordResult.map((word) => { | |||||
| return <li key={word.name}> | |||||
| <header> | |||||
| <h4> { word.name } <span> { word.pronounciation } </span> </h4> | |||||
| <button> | |||||
| <SpeakerIcon /> | |||||
| </button> | |||||
| </header> | |||||
| <div className={styles.description}> | |||||
| <span> { word.grammaticalDetails[0].typeName } </span> | |||||
| <p> { word.grammaticalDetails[0].description } </p> | |||||
| </div> | |||||
| </li> | |||||
| }) } | |||||
| </ul> | |||||
| </section> | </section> | ||||
| } | } | ||||