@@ -0,0 +1,3 @@ | |||||
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="22.609" viewBox="0 0 13 22.609"> | |||||
<path id="back-light" d="M19.857,21.952,9.9,12.162l9.953-9.79L18.319.857,6.857,12.168l11.462,11.3Z" transform="translate(-6.857 -0.857)" fill-rule="evenodd"/> | |||||
</svg> |
@@ -1,3 +1,3 @@ | |||||
<svg xmlns="http://www.w3.org/2000/svg" width="19.34" height="19.221" viewBox="0 0 19.34 19.221"> | <svg xmlns="http://www.w3.org/2000/svg" width="19.34" height="19.221" viewBox="0 0 19.34 19.221"> | ||||
<path id="speaker" d="M0,5.7H4.558L11.414.111V19.332L4.558,13.744H0Zm13.99-.912A6.83,6.83,0,0,1,16.05,9.7a6.364,6.364,0,0,1-2.061,4.755L12.6,13.03a4.607,4.607,0,0,0,1.427-3.369A4.783,4.783,0,0,0,12.6,6.213L13.99,4.786Zm2.378-2.338A9.774,9.774,0,0,1,19.34,9.622a9.9,9.9,0,0,1-2.972,7.213L14.9,15.369a7.722,7.722,0,0,0,2.378-5.727A7.852,7.852,0,0,0,14.9,3.876l1.467-1.427Z" transform="translate(0 -0.111)" fill="#fff"/> | |||||
<path id="speaker" d="M0,5.7H4.558L11.414.111V19.332L4.558,13.744H0Zm13.99-.912A6.83,6.83,0,0,1,16.05,9.7a6.364,6.364,0,0,1-2.061,4.755L12.6,13.03a4.607,4.607,0,0,0,1.427-3.369A4.783,4.783,0,0,0,12.6,6.213L13.99,4.786Zm2.378-2.338A9.774,9.774,0,0,1,19.34,9.622a9.9,9.9,0,0,1-2.972,7.213L14.9,15.369a7.722,7.722,0,0,0,2.378-5.727A7.852,7.852,0,0,0,14.9,3.876l1.467-1.427Z" transform="translate(0 -0.111)"/> | |||||
</svg> | </svg> |
@@ -0,0 +1,224 @@ | |||||
.modalPage { | |||||
background-color: var(--creamy-white); | |||||
position: fixed; | |||||
top: 0; | |||||
left: 0; | |||||
z-index: 2; | |||||
width: 100vw; | |||||
height: 100vh; | |||||
overflow: auto; | |||||
opacity: 0; | |||||
animation: fadeIn 0.3s forwards; | |||||
@keyframes fadeIn { | |||||
0% { | |||||
opacity: 0; | |||||
transform: translateY(10vh); | |||||
} 100% { | |||||
opacity: 1; | |||||
transform: translateY(0vh); | |||||
} | |||||
} | |||||
} | |||||
.navHeader { | |||||
background-color: transparent; | |||||
text-align: center; | |||||
position: relative; | |||||
display: flex; | |||||
justify-content: space-between; | |||||
align-items: center; | |||||
padding: 1rem 1.5rem; | |||||
button { | |||||
width: 4rem; | |||||
text-align: center; | |||||
background-color: transparent; | |||||
border: 0; | |||||
display: flex; | |||||
align-items: center; | |||||
justify-content: flex-start; | |||||
svg { | |||||
width: 1rem; | |||||
color: var(--black); | |||||
} | |||||
} | |||||
h5 { | |||||
font-size: 1.5rem; | |||||
} | |||||
figure { | |||||
display: block; | |||||
img { | |||||
display: block; | |||||
width: 4rem; | |||||
height: 4rem; | |||||
border-radius: 50%; | |||||
border: 1px solid var(--creamy-white); | |||||
} | |||||
} | |||||
} | |||||
.searchBarHolder { | |||||
background-color: var(--teal); | |||||
padding: 2rem 0 6rem; | |||||
border-top-right-radius: 3rem; | |||||
border-top-left-radius: 3rem; | |||||
.searchBar { | |||||
background-color: white; | |||||
display: flex; | |||||
border-radius: 3rem; | |||||
height: 5rem; | |||||
width: calc(100% - 6rem); | |||||
margin: 0 auto; | |||||
align-items: center; | |||||
justify-content: space-between; | |||||
box-shadow: 0px 5px 30px -20px var(--grey); | |||||
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: -4rem 0; | |||||
min-height: 5rem; | |||||
padding: 2rem; | |||||
li { | |||||
position: relative; | |||||
overflow: hidden; | |||||
border-radius: 2rem; | |||||
padding: 1rem 1.5rem; | |||||
margin-bottom: 1.5rem; | |||||
&:nth-child(2n) { | |||||
&::before { | |||||
background-color: var(--teal); | |||||
} | |||||
header { | |||||
h4 { | |||||
span { | |||||
color: var(--teal); | |||||
} | |||||
} | |||||
} | |||||
.description { | |||||
span, p { | |||||
color: var(--teal); | |||||
} | |||||
} | |||||
} | |||||
&::before { | |||||
content: ''; | |||||
position: absolute; | |||||
left: 0; | |||||
top: 0; | |||||
width: 100%; | |||||
height: 100%; | |||||
background-color: var(--orange); | |||||
opacity: 0.3; | |||||
} | |||||
&>* { | |||||
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); | |||||
} | |||||
} | |||||
.addButton { | |||||
width: 7rem; | |||||
margin-left: auto; | |||||
border: none; | |||||
border-radius: 3rem; | |||||
height: 3rem; | |||||
cursor: pointer; | |||||
display: flex; | |||||
align-items: center; | |||||
justify-content: center; | |||||
font-size: 1.2rem; | |||||
color: white; | |||||
background-color: var(--orange); | |||||
svg { | |||||
fill: white; | |||||
width: 1rem; | |||||
margin-right: 0.5rem; | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,68 @@ | |||||
import React, { useState } from "react"; | |||||
import styles from './AddWord.module.scss'; | |||||
import { ReactComponent as ChevronLeft } from '../../assets/icons/chevron-left.svg'; | |||||
import { ReactComponent as SearchIcon } from '../../assets/icons/bx-search-alt.svg'; | |||||
import { ReactComponent as SpeakerIcon } from '../../assets/icons/speaker.svg'; | |||||
import { ReactComponent as AddIcon } from '../../assets/icons/plus.svg'; | |||||
import { IWord } from "../../structure/word"; | |||||
import { ALL_WORDS } from "../../data/all-words"; | |||||
type OwnProps = { | |||||
hideModal: () => void; | |||||
}; | |||||
export const AddWord: React.FC<OwnProps> = (props: OwnProps) => { | |||||
const [searchResult, setSearchResult] = useState<Array<IWord>>([]); | |||||
const searchWords = (searchWord: string) => { | |||||
if (searchWord.length > 0) { | |||||
let result = ALL_WORDS.filter((word) => { | |||||
return word.name.toLowerCase().includes(searchWord.toLowerCase()); | |||||
}); | |||||
setSearchResult(result); | |||||
} else { | |||||
setSearchResult([]); | |||||
} | |||||
} | |||||
return <section className={styles.modalPage}> | |||||
<header className={styles.navHeader}> | |||||
<button onClick={props.hideModal}> | |||||
<ChevronLeft /> | |||||
</button> | |||||
<h5> Add a Word </h5> | |||||
<figure> | |||||
{/* eslint-disable-next-line */} | |||||
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSERA5Pm3aRBV7AaI8tvpZfzpD24ZgrU1_8NA&usqp=CAU" alt="profile-image" /> | |||||
</figure> | |||||
</header> | |||||
<div className={styles.searchBarHolder}> | |||||
<div className={styles.searchBar}> | |||||
<input type="text" autoFocus={true} placeholder={'Search and add a word'} onChange={(event) => searchWords(event.currentTarget.value)} /> | |||||
<SearchIcon /> | |||||
</div> | |||||
</div> | |||||
<ul className={styles.searchResult}> | |||||
{ searchResult.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> | |||||
<button className={styles.addButton}> <AddIcon /> Add </button> | |||||
</li> | |||||
}) } | |||||
</ul> | |||||
</section> | |||||
} |
@@ -1,4 +1,4 @@ | |||||
import React from "react"; | |||||
import React, { useState } from "react"; | |||||
import styles from './Home.module.scss'; | import styles from './Home.module.scss'; | ||||
import { ReactComponent as LogoIcon } from '../../assets/icons/anamnesis.svg'; | import { ReactComponent as LogoIcon } from '../../assets/icons/anamnesis.svg'; | ||||
import { ReactComponent as SearchIcon } from '../../assets/icons/bx-search-alt.svg'; | import { ReactComponent as SearchIcon } from '../../assets/icons/bx-search-alt.svg'; | ||||
@@ -15,11 +15,13 @@ import { ReactComponent as GridIcon } from '../../assets/icons/circled.svg'; | |||||
import { ReactComponent as PersonSpeakerIcon } from '../../assets/icons/user-speaker.svg'; | import { ReactComponent as PersonSpeakerIcon } from '../../assets/icons/user-speaker.svg'; | ||||
import { ReactComponent as BrainIcon } from '../../assets/icons/bx-brain.svg'; | import { ReactComponent as BrainIcon } from '../../assets/icons/bx-brain.svg'; | ||||
import { ReactComponent as InternBadge } from '../../assets/icons/intern-badge.svg'; | import { ReactComponent as InternBadge } from '../../assets/icons/intern-badge.svg'; | ||||
import { CircularProgressbar } from 'react-circular-progressbar'; | import { CircularProgressbar } from 'react-circular-progressbar'; | ||||
import { AddWord } from "../add-word/AddWord"; | |||||
export const Home: React.FC = () => { | export const Home: React.FC = () => { | ||||
const [isAddWordModalOpen, setAddWordModalState] = useState<boolean>(false); | |||||
return <section className="page"> | return <section className="page"> | ||||
<header className={styles.pageHeader}> | <header className={styles.pageHeader}> | ||||
@@ -57,7 +59,7 @@ export const Home: React.FC = () => { | |||||
</section> | </section> | ||||
<div className={styles.searchBar}> | <div className={styles.searchBar}> | ||||
<input type="text" placeholder={'Search and add a word'} /> | |||||
<input type="text" placeholder={'Search and add a word'} onClick={() => setAddWordModalState(true)} /> | |||||
<SearchIcon /> | <SearchIcon /> | ||||
</div> | </div> | ||||
@@ -252,5 +254,8 @@ export const Home: React.FC = () => { | |||||
</ul> | </ul> | ||||
</section> | </section> | ||||
{ isAddWordModalOpen && <AddWord hideModal={() => { setAddWordModalState(false); }} /> } | |||||
</section> | </section> | ||||
} | } |
@@ -9,7 +9,7 @@ import { ReactComponent as MoreIcon } from '../../assets/icons/more-vertical.svg | |||||
import { NavLink } from "react-router-dom"; | import { NavLink } from "react-router-dom"; | ||||
export const Tabs: React.FC = () => { | export const Tabs: React.FC = () => { | ||||
return <section className={styles.tabs} id="tabs"> | |||||
return <section className={styles.tabs}> | |||||
<NavLink to={'/home'} activeClassName={styles.active}> | <NavLink to={'/home'} activeClassName={styles.active}> | ||||
<HomeIcon /> | <HomeIcon /> | ||||
</NavLink > | </NavLink > | ||||
@@ -0,0 +1,27 @@ | |||||
import { IWord } from "../structure/word"; | |||||
export const ALL_WORDS: Array<IWord> = [{ | |||||
name: 'Pleasure', | |||||
pronounciation: '/ˈplɛʒə/', | |||||
audioPronounciationURL: '', | |||||
grammaticalDetails: [{ | |||||
typeName: 'NOUN', | |||||
description: 'a feeling of happy satisfaction and enjoyment.' | |||||
}, { | |||||
typeName: 'ADJECTIVE', | |||||
description: 'used or intended for entertainment rather than business.' | |||||
}], | |||||
similarWords: ['Happiness', 'Delight', 'Joy', 'Rapture', 'Glee'], | |||||
}, { | |||||
name: 'Please', | |||||
pronounciation: '/pliːz/', | |||||
audioPronounciationURL: '', | |||||
grammaticalDetails: [{ | |||||
typeName: 'VERB', | |||||
description: 'cause to feel happy and satisfied.' | |||||
}, { | |||||
typeName: 'ADVERB', | |||||
description: 'used in polite requests or questions.' | |||||
}], | |||||
similarWords: ['Nice', 'Agreeable', 'Pleasant', 'Satisfying', 'Gratifying'], | |||||
}] |
@@ -3,7 +3,7 @@ export type IWord = { | |||||
pronounciation: string, | pronounciation: string, | ||||
audioPronounciationURL: string, | audioPronounciationURL: string, | ||||
grammaticalDetails: Array<{ | grammaticalDetails: Array<{ | ||||
typeName: 'NOUN' | 'ADJECTIVE' | 'VERB', | |||||
typeName: 'NOUN' | 'ADJECTIVE' | 'VERB' | 'ADVERB', | |||||
description: string, | description: string, | ||||
}>, | }>, | ||||
similarWords: Array<string> | similarWords: Array<string> |