@@ -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"> | |||
<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> |
@@ -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 { ReactComponent as LogoIcon } from '../../assets/icons/anamnesis.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 BrainIcon } from '../../assets/icons/bx-brain.svg'; | |||
import { ReactComponent as InternBadge } from '../../assets/icons/intern-badge.svg'; | |||
import { CircularProgressbar } from 'react-circular-progressbar'; | |||
import { AddWord } from "../add-word/AddWord"; | |||
export const Home: React.FC = () => { | |||
const [isAddWordModalOpen, setAddWordModalState] = useState<boolean>(false); | |||
return <section className="page"> | |||
<header className={styles.pageHeader}> | |||
@@ -57,7 +59,7 @@ export const Home: React.FC = () => { | |||
</section> | |||
<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 /> | |||
</div> | |||
@@ -252,5 +254,8 @@ export const Home: React.FC = () => { | |||
</ul> | |||
</section> | |||
{ isAddWordModalOpen && <AddWord hideModal={() => { setAddWordModalState(false); }} /> } | |||
</section> | |||
} |
@@ -9,7 +9,7 @@ import { ReactComponent as MoreIcon } from '../../assets/icons/more-vertical.svg | |||
import { NavLink } from "react-router-dom"; | |||
export const Tabs: React.FC = () => { | |||
return <section className={styles.tabs} id="tabs"> | |||
return <section className={styles.tabs}> | |||
<NavLink to={'/home'} activeClassName={styles.active}> | |||
<HomeIcon /> | |||
</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, | |||
audioPronounciationURL: string, | |||
grammaticalDetails: Array<{ | |||
typeName: 'NOUN' | 'ADJECTIVE' | 'VERB', | |||
typeName: 'NOUN' | 'ADJECTIVE' | 'VERB' | 'ADVERB', | |||
description: string, | |||
}>, | |||
similarWords: Array<string> |