Skip to content

Commit

Permalink
ft/working on the project tag input component,and feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
mosesmulumba committed Jul 5, 2024
1 parent c53bf2c commit 077a0e1
Show file tree
Hide file tree
Showing 7 changed files with 172 additions and 88 deletions.
7 changes: 7 additions & 0 deletions src/components/CreateProject/CreateProject.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@
width: 100%;
border-radius: 5px;
}
.Element div div div{
display: flex;
}
.Element div div input{
width: 85%;
}

.FormsSection {
padding: 1rem;
align-self: center;
Expand Down
20 changes: 19 additions & 1 deletion src/components/CreateProject/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { handlePostRequestWithOutDataObject } from "../../apis/apis.js";
import { retrieveProjectTypes } from "../../helpers/projecttypes";
import { namedOrganisations } from "../../helpers/projectOrganisations";
import handleProjectValidation from "../../helpers/validation";
import TagInput from "../ProjectTagInput";

class CreateProject extends React.Component {
constructor(props) {
Expand Down Expand Up @@ -197,6 +198,18 @@ class CreateProject extends React.Component {
const types = retrieveProjectTypes();
const presetOrganisations = namedOrganisations();

const suggestions = [
"react",
"javascript",
"css",
"html",
"nodejs",
"django",
"firebase",
"python",
"java",
];

return (
<div className={styles.MainContentSection}>
<Header />
Expand Down Expand Up @@ -332,7 +345,12 @@ class CreateProject extends React.Component {
}}
/>
</div>

<div className={styles.Element}>
<div className={styles.ElementTitle}>Project tags</div>
<div className={`${styles.inputTagSection}`}>
<TagInput suggestions={suggestions} />
</div>
</div>
{error && (
<div className={styles.CreateProjectError}>
<Feedback type="error" message={error} />
Expand Down
70 changes: 70 additions & 0 deletions src/components/ProjectTagInput/TagInput.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
.tagInputContainer {
border: 1px solid #000;
padding: 5px;
border-radius: 5px;
display: inline-block;
width: 99%;
min-height: 4vh;
}

.tagList {
display: flex;
justify-items: flex-start;
max-width: 27.5rem;
}

.tagList ,.tag{
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 5px;
}

.tag {
background-color: #e0e0e0;
border-radius: 3px;
padding: 2px 5px;
display: flex;
align-items: center;
}

.tag:hover{
background-color: #ccc;
color: #000;
}

.tag button {
background: none;
border: none;
margin-left: 5px;
cursor: pointer;
}

.input {
border: none;
outline: none;
flex: 1;
}

.suggestions {
border: 1px solid #ccc;
border-radius: 5px;
margin-top: 5px;
position: absolute;
background: white;
z-index: 1;
width: 300px;
}

.suggestion {
padding: 5px;
cursor: pointer;
}

.suggestion:hover {
background-color: #f0f0f0;
}
.Element > div > .tagInputContainer , .tagList{
min-width: 35rem;
max-width: 100%;
}
102 changes: 59 additions & 43 deletions src/components/ProjectTagInput/index.jsx
Original file line number Diff line number Diff line change
@@ -1,63 +1,79 @@
import React, { useState } from 'react';
import PrimaryButton from '../PrimaryButton/index.js';
import styles from './taginput.css';
import React, { useState } from "react";
import styles from "./TagInput.module.css";

const TagInput = () => {
const [tag, setTag] = useState('');
const TagInput = ({ suggestions }) => {
const [tags, setTags] = useState([]);
const [error, setError] = useState('');
const [input, setInput] = useState("");
const [filteredSuggestions, setFilteredSuggestions] = useState([]);

const handleInputChange = (e) => {
setTag(e.target.value);
};
const value = e.target.value;
setInput(value);

const handleAddTag = () => {
if (tag.trim() === '') {
setError('Tag cannot be empty');
return;
if (value) {
const filtered = suggestions.filter((suggestion) =>
suggestion.toLowerCase().includes(value.toLowerCase())
);
setFilteredSuggestions(filtered);
} else {
setFilteredSuggestions([]);
}
};

setTags([...tags, { tag_id: Date.now(), tag }]);
setTag('');
setError('');
const handleKeyDown = (e) => {
if (e.key === "Enter" && input) {
if (!tags.includes(input)) {
setTags([...tags, input]);
}
setInput("");
setFilteredSuggestions([]);
}
};

const handleDeleteTag = (tagId) => {
setTags(tags.filter(tag => tag.tag_id !== tagId));
const handleTagRemove = (index) => {
setTags(tags.filter((_, i) => i !== index));
};

const handleKeyDown = (e) => {
if (e.key === 'Enter') {
handleAddTag();
const handleSuggestionClick = (suggestion) => {
if (!tags.includes(suggestion)) {
setTags([...tags, suggestion]);
}
setInput("");
setFilteredSuggestions([]);
};

return (
<div className={`${styles.tagContainer}`}>
<div className={`${styles.inputsection}`}>
<input
type="text"
value={tag}
onChange={handleInputChange}
onKeyDown={handleKeyDown}
placeholder="Enter a tag"
/>
<PrimaryButton onClick={handleAddTag} size="Primary-Btn">
Add Tag
</PrimaryButton>
</div>

{error && <p style={{ color: 'red' }}>{error}</p>}
<ul>
{tags.map((tag) => (
<li key={tag.tag_id}>
{tag.tag} &nbsp;
<button onClick={() => handleDeleteTag(tag.tag_id)}>x</button>
</li>
<div className={styles.tagInputContainer}>
<div className={styles.tagList}>
{tags.map((tag, index) => (
<div key={index} className={styles.tag}>
{tag}
<button onClick={() => handleTagRemove(index)}>x</button>
</div>
))}
</ul>
</div>
<input
type="text"
value={input}
onChange={handleInputChange}
onKeyDown={handleKeyDown}
className={styles.input}
/>
{filteredSuggestions.length > 0 && (
<div className={styles.suggestions}>
{filteredSuggestions.map((suggestion, index) => (
<div
key={index}
className={styles.suggestion}
onClick={() => handleSuggestionClick(suggestion)}
>
{suggestion}
</div>
))}
</div>
)}
</div>
);
};

export default TagInput;
export default TagInput;
41 changes: 0 additions & 41 deletions src/components/ProjectTagInput/taginput.css

This file was deleted.

4 changes: 3 additions & 1 deletion src/pages/ProjectSettingsPage/ProjectSettingsPage.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,12 @@

.ProjectInputTag div div{
display: flex;
justify-content: space-between;
place-items: center;
}

/* .UpdateInputSection , .DeleteDescription , .ProjectInputTag .tagInputContainer .tagList{
max-width: 20rem;
} */
.DeleteDescription span {
padding: 0.2rem 0.4rem;
margin: 0;
Expand Down
16 changes: 14 additions & 2 deletions src/pages/ProjectSettingsPage/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,19 @@ class ProjectSettingsPage extends React.Component {
const types = retrieveProjectTypes();
const roles = retrieveMembershipRoles();

const suggestions = [
"react",
"javascript",
"css",
"html",
"nodejs",
"django",
"firebase",
"python",
"java",
];


const { projectID } = params;
const presetOrganisations = namedOrganisations();
return (
Expand Down Expand Up @@ -1116,8 +1129,7 @@ class ProjectSettingsPage extends React.Component {
Project tags
</div>
<div className={styles.ProjectInputTag}>
<TagInput
className={styles.tagInput}/>
<TagInput suggestions={suggestions}/>
</div>
</div>
<div className={styles.UpdateInputSection}>
Expand Down

0 comments on commit 077a0e1

Please sign in to comment.