| @@ -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> | |||