@@ -88,7 +88,35 @@ | |||
margin-bottom: 1.5rem; | |||
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 { | |||
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 { | |||
content: ''; | |||
position: absolute; | |||
@@ -7,12 +7,13 @@ import { ReactComponent as AddIcon } from '../../assets/icons/plus.svg'; | |||
import { IWord } from "../../structure/word"; | |||
import { ALL_WORDS } from "../../data/all-words"; | |||
import { NavLink } from "react-router-dom"; | |||
import { NavLink, useHistory } from "react-router-dom"; | |||
import { userProfileData } from "../../App"; | |||
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 history = useHistory(); | |||
const searchWords = (searchWord: string) => { | |||
if (searchWord.length > 0) { | |||
@@ -22,7 +23,7 @@ export const AddWord: React.FC = () => { | |||
setSearchResult(result); | |||
} else { | |||
setSearchResult([]); | |||
setSearchResult(ALL_WORDS); | |||
} | |||
} | |||
@@ -89,7 +90,14 @@ export const AddWord: React.FC = () => { | |||
{ userProfileData.categories.map((category, categoryIndex) => { | |||
return category.shelves.map((shelf, shelfIndex) => { | |||
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}> | |||
{ category.icon } | |||
@@ -37,4 +37,366 @@ | |||
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 { 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 { ICategory } from "../../structure/category"; | |||
import { IShelf } from "../../structure/shelf"; | |||
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 = () => { | |||
const location = useLocation(); | |||
@@ -13,6 +19,19 @@ export const ShelfDetails: React.FC = () => { | |||
const shelf_id: any = queryString.parse(location.pathname)['shelf_id']; | |||
const category: ICategory = userProfileData.categories[category_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"> | |||
<header className={styles.navHeader}> | |||
@@ -29,9 +48,47 @@ export const ShelfDetails: React.FC = () => { | |||
</header> | |||
<header className={styles.tabHeading}> | |||
<button className={styles.moreButton}> | |||
<MoreIcon /> | |||
</button> | |||
<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> | |||
<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> | |||
} |