Browse Source

Add word to shelf UI

master
kj1352 4 years ago
parent
commit
93a45764a4
7 changed files with 222 additions and 135 deletions
  1. +111
    -3
      src/components/add-word/AddWord.module.scss
  2. +29
    -3
      src/components/add-word/AddWord.tsx
  3. +79
    -119
      src/components/home/Home.tsx
  4. +0
    -8
      src/data/all-medals.ts
  5. +1
    -1
      src/structure/category.ts
  6. +1
    -1
      src/structure/medals.ts
  7. +1
    -0
      src/structure/shelf.ts

+ 111
- 3
src/components/add-word/AddWord.module.scss View File

@@ -107,8 +107,9 @@
position: relative;
overflow: hidden;
border-radius: 2rem;
padding: 1rem 1.5rem;
padding: 1rem 1.5rem 1.7rem;
margin-bottom: 1.5rem;
background-color: white;

&:nth-child(2n) {
&::before {
@@ -121,6 +122,10 @@
color: var(--teal);
}
}
button {
background-color: var(--teal);
}
}

.description {
@@ -128,6 +133,10 @@
color: var(--teal);
}
}

.addButton {
background-color: var(--teal);
}
}

&::before {
@@ -138,7 +147,7 @@
width: 100%;
height: 100%;
background-color: var(--orange);
opacity: 0.3;
opacity: 0.4;
}

&>* {
@@ -205,7 +214,7 @@
margin-left: auto;
border: none;
border-radius: 3rem;
height: 3rem;
height: 2.7rem;
cursor: pointer;
display: flex;
align-items: center;
@@ -221,4 +230,103 @@
}
}
}
}

.shelfList {
list-style: none;
padding: 1rem 2rem;

header {
margin: 0 auto 1rem;
h5 {
font-weight: 300;
font-size: 1.2rem;
color: var(--black);
}
}

li {
display: flex;
justify-content: space-between;
align-items: center;
margin: 0 0 2rem;

&:nth-child(3n) .icon {
background-color: var(--red);
}

&:nth-child(3n - 1) .icon {
background-color: var(--orange);
}

&:nth-child(3n - 2) .icon {
background-color: var(--blue);
}
}

.icon {
width: 4rem;
height: 4rem;
background-color: var(--grey);
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;

svg {
fill: white;
width: 3rem;
}
}

.info {
width: calc(100% - 5rem);

label, span {
display: block;
}

label {
font-size: 1.2rem;
color: var(--black);
font-weight: 700;
}

span {
font-size: 1rem;
color: var(--grey);
}
}
}

.AddShelfButton {
position: fixed;
bottom: 0;
left: 0;
padding: 2rem 3rem;
display: flex;
align-items: center;
justify-content: flex-start;
width: 100%;
background-color: var(--creamy-white);
border: none;
box-shadow: 0px 0px 5px var(--creamy-white);
font-weight: 600;
color: var(--black);

span {
width: 3rem;
height: 3rem;
background-color: var(--teal);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin-right: 1.5rem;
svg {
fill: white;
width: 1.2rem;
}
}
}

+ 29
- 3
src/components/add-word/AddWord.tsx View File

@@ -7,13 +7,16 @@ import { ReactComponent as AddIcon } from '../../assets/icons/plus.svg';

import { IWord } from "../../structure/word";
import { ALL_WORDS } from "../../data/all-words";
import { userProfileData } from "../home/Home";


type OwnProps = {
hideModal: () => void;
hideModal: () => void
};

export const AddWord: React.FC<OwnProps> = (props: OwnProps) => {
const [searchResult, setSearchResult] = useState<Array<IWord>>([]);
const [selectedWord, setSelectedWord] = useState<IWord>();

const searchWords = (searchWord: string) => {
if (searchWord.length > 0) {
@@ -48,7 +51,7 @@ export const AddWord: React.FC<OwnProps> = (props: OwnProps) => {
</div>

<ul className={styles.searchResult}>
{ searchResult.map((word) => {
{ !selectedWord && searchResult.map((word) => {
return <li key={word.name}>
<header>
<h4> { word.name } <span> { word.pronounciation } </span> </h4>
@@ -60,9 +63,32 @@ export const AddWord: React.FC<OwnProps> = (props: OwnProps) => {
<span> { word.grammaticalDetails[0].typeName } </span>
<p> { word.grammaticalDetails[0].description } </p>
</div>
<button className={styles.addButton}> <AddIcon /> Add </button>
<button className={styles.addButton} onClick={() => setSelectedWord(word)}> <AddIcon /> Add </button>
</li>
}) }
</ul>

{ selectedWord && <ul className={styles.shelfList}>
<header>
<h5> All Shelves </h5>
</header>
{ 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);
}}>
<div className={styles.icon}>
{ category.icon }
</div>
<div className={styles.info}>
<label> { shelf.name } </label>
<span> { category.name } </span>
</div>
</li>
})
}) }

<button className={styles.AddShelfButton}> <span> <AddIcon /> </span> Create New Shelf </button>
</ul> }
</section>
}

+ 79
- 119
src/components/home/Home.tsx View File

@@ -17,11 +17,52 @@ 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";
import { IProfile } from "../../structure/profile";


export var userProfileData : IProfile = {
name: 'Neymar Jr',
image: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSERA5Pm3aRBV7AaI8tvpZfzpD24ZgrU1_8NA&usqp=CAU',
medal: {
name: 'Intern badge',
minValue: 0,
maxValue: 100,
icon: <InternBadge />
},
categories: [{
name: 'Vocabulary',
icon: <TimeIcon />,
shelves: [{
name: 'All Words',
words: [],
revisedWords: [],
description: 'All Words that I use on a daily basis',
viewPermission: 'PUBLIC'
}]
}, {
name: 'Books',
icon: <BookMarkIcon />,
shelves: [{
name: 'Sapiens',
words: [],
revisedWords: [],
description: 'Sapiens book complex words',
viewPermission: 'PUBLIC'
}]
}, {
name: 'GRE',
icon: <BrainIcon />,
shelves: []
}, {
name: 'ELTS',
icon: <PersonSpeakerIcon />,
shelves: []
}]
};

export const Home: React.FC = () => {
const [isAddWordModalOpen, setAddWordModalState] = useState<boolean>(false);

return <section className="page">

<header className={styles.pageHeader}>
@@ -42,8 +83,8 @@ export const Home: React.FC = () => {
}}
} />
{/* eslint-disable-next-line */}
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSERA5Pm3aRBV7AaI8tvpZfzpD24ZgrU1_8NA&usqp=CAU" alt="profile-image" />
<InternBadge />
<img src={userProfileData.image} alt="profile-image" />
{ userProfileData.medal.icon }
</div>
<div className={styles.userDetails}>
<h2> Neymar Junior </h2>
@@ -118,86 +159,30 @@ export const Home: React.FC = () => {
</button>
</header>
<ul>
<li>
<div className={styles.progress}>
<CircularProgressbar value={30} strokeWidth={7}
styles={{
path: {
stroke: 'white',
strokeLinecap: 'round',
},
trail: {
stroke: 'rgba(255, 255, 255, 0.25)',
strokeLinecap: 'round',
}}
} />
<span className={styles.text}> 30% </span>
</div>
<h5> All Words </h5>
<p> Vocabulary </p>
<p> 1.2K Words </p>
</li>
<li>
<div className={styles.progress}>
<CircularProgressbar value={50} strokeWidth={7}
styles={{
path: {
stroke: 'white',
strokeLinecap: 'round',
},
trail: {
stroke: 'rgba(255, 255, 255, 0.25)',
strokeLinecap: 'round',
}}
} />
<span className={styles.text}> 50% </span>
</div>
<h5> IELTS Fundamentals </h5>
<p> IELTS </p>
<p> 250 Words </p>
</li>
<li>
<div className={styles.progress}>
<CircularProgressbar value={10} strokeWidth={7}
styles={{
path: {
stroke: 'white',
strokeLinecap: 'round',
},
trail: {
stroke: 'rgba(255, 255, 255, 0.25)',
strokeLinecap: 'round',
}}
} />
<span className={styles.text}> 10% </span>
</div>
<h5> GRE Fundamentals </h5>
<p> GRE </p>
<p> 456 Words </p>
</li>
<li>
<div className={styles.progress}>
<CircularProgressbar value={25} strokeWidth={7}
styles={{
path: {
stroke: 'white',
strokeLinecap: 'round',
},
trail: {
stroke: 'rgba(255, 255, 255, 0.25)',
strokeLinecap: 'round',
}}
} />
<span className={styles.text}> 25% </span>
</div>
<h5> Sapiens </h5>
<p> Book </p>
<p> 125 Words </p>
</li>
{ userProfileData.categories.map(category => {
return category.shelves.map(shelf => {
return <li key={shelf.name}>
<div className={styles.progress}>
<CircularProgressbar value={shelf.words.length > 0 ? (shelf.revisedWords.length * 100/ shelf.words.length) : 0} strokeWidth={7}
styles={{
path: {
stroke: 'white',
strokeLinecap: 'round',
},
trail: {
stroke: 'rgba(255, 255, 255, 0.25)',
strokeLinecap: 'round',
}}
} />
<span className={styles.text}> { shelf.words.length > 0 ? (shelf.revisedWords.length * 100/ shelf.words.length) : 0 }% </span>
</div>
<h5> { category.name } </h5>
<p> { shelf.name } </p>
<p> { shelf.words.length } words </p>
</li>
})
}) }
</ul>
</section>

@@ -215,42 +200,17 @@ export const Home: React.FC = () => {
</button>
</header>
<ul>
<li>
<div className={styles.icon}>
<TimeIcon />
</div>
<div className={styles.info}>
<label> Vocabulary </label>
<span> 5 Shelves </span>
</div>
</li>
<li>
<div className={styles.icon}>
<BookMarkIcon />
</div>
<div className={styles.info}>
<label> Books </label>
<span> 3 Shelves </span>
</div>
</li>
<li>
<div className={styles.icon}>
<PersonSpeakerIcon />
</div>
<div className={styles.info}>
<label> IELTS </label>
<span> 5 Shelves </span>
</div>
</li>
<li>
<div className={styles.icon}>
<BrainIcon />
</div>
<div className={styles.info}>
<label> GRE </label>
<span> 2 Shelves </span>
</div>
</li>
{ userProfileData.categories.map(category => {
return <li key={category.name}>
<div className={styles.icon}>
{ category.icon }
</div>
<div className={styles.info}>
<label> { category.name } </label>
<span> { category.shelves.length } Shelves </span>
</div>
</li>
})}
</ul>
</section>



+ 0
- 8
src/data/all-medals.ts View File

@@ -1,8 +0,0 @@
import { IMedal } from "../structure/medals";

export const ALL_MEDALS: Array<IMedal> = [{
name: 'Intern',
minValue: 0,
maxValue: 100,
icon: ''
}]

+ 1
- 1
src/structure/category.ts View File

@@ -2,6 +2,6 @@ import { IShelf } from "./shelf";

export type ICategory = {
name: string,
icon: string,
icon: JSX.Element,
shelves: Array<IShelf>
};

+ 1
- 1
src/structure/medals.ts View File

@@ -2,5 +2,5 @@ export type IMedal = {
name: string,
minValue: number,
maxValue: number,
icon: string,
icon: JSX.Element,
};

+ 1
- 0
src/structure/shelf.ts View File

@@ -1,6 +1,7 @@
import { IWord } from "./word";

export type IShelf = {
name: string,
words: Array<IWord>,
revisedWords: Array<IWord>,
description: string,


Loading…
Cancel
Save