Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions client/src/components/AddSnippet/AddSnippet.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import TagInput from '../../components/ui/TagInput/TagInput';
// importing external functionality
import CodeMirror from '@uiw/react-codemirror';
import PropTypes from 'prop-types';
import { markdown, markdownLanguage } from '@codemirror/lang-markdown';
import { languages } from '@codemirror/language-data';
import { langs } from '@uiw/codemirror-extensions-langs';

// importing utils
Expand All @@ -21,12 +19,12 @@ import styles from './AddSnippet.module.scss';
// importing data
import { LANGUAGES } from '../../data/data.js';

const AddSnippet = ({ closeModal }) => {
const AddSnippet = ({ closeModal, getUserData }) => {
const [title, setTitle] = useState('');
const [language, setLanguage] = useState('');
const [comments, setComments] = useState('');
const [storedCode, setStoredCode] = useState('');
const [tagList, setTags] = useState('');
const [tagList, setTags] = useState([]);
const [error, setError] = useState(false);
const [openModal, setOpenModal] = useState(false);

Expand Down Expand Up @@ -57,7 +55,11 @@ const AddSnippet = ({ closeModal }) => {
storedCode: storedCode
})
})
.then((data) => data.json())
.then((data) => {
getUserData();
closeModal(false);
data.json();
})
.catch((err) => {
console.log(err);
console.log('failed saving snippet');
Expand Down Expand Up @@ -178,7 +180,8 @@ const AddSnippet = ({ closeModal }) => {
};

AddSnippet.propTypes = {
closeModal: PropTypes.func
closeModal: PropTypes.func,
getUserData: PropTypes.func
};

export default AddSnippet;
15 changes: 9 additions & 6 deletions client/src/containers/MainContainer/MainContainer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ const MainContainer = () => {
fetch('http://localhost:3000/authentication/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
username: usernameInputValue,
password: passwordInputValue,
}),
password: passwordInputValue
})
})
.then((result) => result.json())
.then((result) => {
Expand All @@ -33,6 +33,9 @@ const MainContainer = () => {
.catch((err) => {
console.log(err);
});

//Bypass login requirement:
setLogin(true);
};
//functino to handle showing the signup page
const handleHaveAccount = () => setHaveAccount(false);
Expand All @@ -48,12 +51,12 @@ const MainContainer = () => {
fetch('http://localhost:3000/authentication/signup', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
username: nameValue,
password: passwordValue,
}),
password: passwordValue
})
})
.then((result) => result.json())
.then((result) => {
Expand Down
138 changes: 99 additions & 39 deletions client/src/containers/Sidebar/Sidebar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import React, { useState, useEffect } from 'react';
import SnippetDisplay from '../../components/SnippetDisplay/SnippetDisplay.jsx';
import AddSnippet from '../../components/AddSnippet/AddSnippet.jsx';
import SnippetsRadioList from './SnippetsRadioList/SnippetsRadioList.jsx';
import TagsList from './TagsList/TagsList.jsx';

// importing utils
import { Card, Spinner } from 'react-bootstrap';
Expand All @@ -16,27 +17,35 @@ import arrow from '../../assets/arrow.png';
import img from '../../assets/star nose mole.jpeg';

const Sidebar = ({ handleLogin }) => {
//Snippets and selected snippet
const [snippets, setSnippets] = useState([]);
const [selectedSnippet, setSelectedSnippet] = useState({});

//Tags and selected tags
const [userTags, setUserTags] = useState([]);
const [selectedTags, setSelectedTags] = useState([]);

const [openModal, setOpenModal] = useState(false);
const [collapse, setCollapse] = useState(false);
const [loading, setLoading] = useState(true);
const [displayType, setDisplayType] = useState('snippets');

useEffect(() => {
getSnippet();
getUserData();
}, []);
//Get all snippets stored under user's account
//TODO: Get user ID from global state to include in request
//FIXME: HARD CODING ID FOR NOW
const userId = '6463eb52ab99bf89a84a3ebd';

const getSnippet = () => {
const getUserData = () => {
setLoading(true);
fetch('/snippets?' + new URLSearchParams({ userId: userId }))
.then((res) => res.json())
.then((newSnippetArray) => {
.then((data) => {
//As structured in snippets route, should receive an array of snippet objects
setSnippets(newSnippetArray);
setSnippets(data.snippets);
setUserTags([...data.tagsLangs.tags, ...data.tagsLangs.languages]);
setLoading(false);
})
.catch((error) =>
Expand All @@ -60,10 +69,69 @@ const Sidebar = ({ handleLogin }) => {
setSelectedSnippet(e);
};

const selectDeselectTag = (tagValue) => {
const newTagList = new Set(selectedTags);
if (!newTagList.has(tagValue)) {
newTagList.add(tagValue);
} else {
newTagList.delete(tagValue);
}

setSelectedTags(Array.from(newTagList));
};

const toggleSidebar = () => {
setCollapse(() => !collapse);
};

const toggleDisplayType = (event) => {
console.log(event.target.value);
setDisplayType(event.target.value);
};

const snippetsDisplay = (
<Card.Body className="px-0 pt-0">
{/* Animation while app is fetching data from DB */}
<div className={styles.cardBody}>
{loading && (
<div className="d-flex justify-content-center pt-3">
<Spinner
animation="border"
role="status"
variant="primary"
></Spinner>
</div>
)}
<SnippetsRadioList
snippets={snippets}
setSelectedSnippet={setSelectedSnippetWrapper}
/>
</div>
</Card.Body>
);

const tagsDisplay = (
<Card.Body className="px-0 pt-0">
{/* Animation while app is fetching data from DB */}
<div className={styles.cardBody}>
{loading && (
<div className="d-flex justify-content-center pt-3">
<Spinner
animation="border"
role="status"
variant="primary"
></Spinner>
</div>
)}
<TagsList
allTags={userTags}
selectedTags={selectedTags}
selectDeselectTag={selectDeselectTag}
/>
</div>
</Card.Body>
);

return (
<React.Fragment>
{/*----- SIDE BAR -----*/}
Expand All @@ -74,21 +142,28 @@ const Sidebar = ({ handleLogin }) => {
<Card.Header>
{/* Changes the collapse state, which will render/unrender the sidebar*/}
<div className={styles.displayTypeSelector}>
<input
type="radio"
name="displayType"
id="browseBySnippets"
value="snippets"
checked
></input>
<label htmlFor="browseBySnippets">Snippets</label>
<input
type="radio"
name="displayType"
id="browseByTags"
<button
value="snippets"
></input>
<label htmlFor="browseByTags">Tags</label>
className={
displayType === 'snippets'
? styles.displayTypeButtonActive
: styles.displayTypeButtonInactive
}
onClick={toggleDisplayType}
>
Snippets
</button>
<button
value="tags"
className={
displayType === 'tags'
? styles.displayTypeButtonActive
: styles.displayTypeButtonInactive
}
onClick={toggleDisplayType}
>
Tags
</button>
</div>
<button className={styles.toggleButton} onClick={toggleSidebar}>
<img
Expand All @@ -101,38 +176,23 @@ const Sidebar = ({ handleLogin }) => {

{/* Renders the list of snippets fetched from DB */}

<Card.Body className="px-0 pt-0">
{/* Animation while app is fetching data from DB */}
<div className={styles.cardBody}>
{loading && (
<div className="d-flex justify-content-center pt-3">
<Spinner
animation="border"
role="status"
variant="primary"
></Spinner>
</div>
)}
<SnippetsRadioList
snippets={snippets}
setSelectedSnippet={setSelectedSnippetWrapper}
/>
</div>
</Card.Body>
{displayType === 'snippets' ? snippetsDisplay : tagsDisplay}

<button
className={styles.addButton}
onClick={() => {
setOpenModal(true);
}}
>
Add New
Add New Snippet
</button>
</Card>

{/*----- ADD SNIPPET MODAL -----*/}

{openModal && <AddSnippet closeModal={setOpenModal} />}
{openModal && (
<AddSnippet closeModal={setOpenModal} getUserData={getUserData} />
)}

{/*----- SNIPPET DISPLAY -----*/}

Expand All @@ -144,7 +204,7 @@ const Sidebar = ({ handleLogin }) => {
{snippets && (
<SnippetDisplay
selectedSnippet={selectedSnippet}
getSnippet={getSnippet}
getSnippet={getUserData}
/>
)}
</div>
Expand Down
34 changes: 19 additions & 15 deletions client/src/containers/Sidebar/Sidebar.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,29 @@
// border-color: black;
// }

.displayTypeSelectosr {
.displayTypeSelector {
display: flex;
justify-content: space-around;
text-align: center;
gap: 10px;
width: 100%;
input {
display: none;
}
label {
}
.displayTypeButton {
.active {
color: whitesmoke;
border-bottom: 1pt double whitesmoke;
}
.inactive {
}
}
}

.displayTypeButtonActive {
background-color: transparent;
box-shadow: none;
width: 100%;
color: whitesmoke !important;
border: none;
border-bottom: 1.5pt solid whitesmoke !important;
}

.displayTypeButtonInactive {
background-color: transparent;
box-shadow: none;
width: 100%;
color: rgb(124, 124, 124) !important;
border: none !important;
}

.sidebar {
Expand Down Expand Up @@ -118,7 +123,6 @@
.addButton {
border: transparent;
height: 50px;
width: 270px;
// padding-left: 7px;
// padding-right: 7px;
border-radius: 10px;
Expand Down
41 changes: 41 additions & 0 deletions client/src/containers/Sidebar/TagsList/TagsList.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React, { useEffect } from 'react';

// importing utils
import PropTypes from 'prop-types';

// importing styles
import styles from './TagsList.module.scss';

function TagsList({ allTags, selectedTags, selectDeselectTag }) {
const buttonList = [];

const onTagClick = (e) => {
selectDeselectTag(e.target.value);
};

if (allTags) {
allTags.forEach((el) => {
const currButton = (
<button
value={el}
key={`tag-${el}`}
onClick={onTagClick}
className={
selectedTags.includes(el) ? styles.activeTag : styles.inactiveTag
}
>
{el}
</button>
);
buttonList.push(currButton);
});
}

return <div className={styles.tagsListDisplay}>{buttonList}</div>;
}
TagsList.propTypes = {
allTags: PropTypes.array,
selectedTags: PropTypes.array,
selectDeselectTag: PropTypes.func
};
export default TagsList;
Loading