From 810c5052a37ed83cf29669bc8f7dc6363603f40a Mon Sep 17 00:00:00 2001 From: SURAJ <90304648+SURAJ-SHARMA27@users.noreply.github.com> Date: Sun, 12 Nov 2023 00:01:23 +0530 Subject: [PATCH] tag-functionality-added --- .../OrgInfoCard/editOrgDetailsModal.jsx | 1 - .../Organization/ViewOrganization/index.jsx | 9 ++ src/components/Organization/pages/General.jsx | 150 ++++++++++++++++-- src/components/Organization/pages/Tags.css | 105 ++++++++++++ .../Tutorials/subComps/EditControls.jsx | 12 +- src/components/UserDetails/Tag.jsx | 78 +++++++++ 6 files changed, 338 insertions(+), 17 deletions(-) create mode 100644 src/components/Organization/pages/Tags.css create mode 100644 src/components/UserDetails/Tag.jsx diff --git a/src/components/Organization/OrgInfoCard/editOrgDetailsModal.jsx b/src/components/Organization/OrgInfoCard/editOrgDetailsModal.jsx index 9eac2749..fd860938 100644 --- a/src/components/Organization/OrgInfoCard/editOrgDetailsModal.jsx +++ b/src/components/Organization/OrgInfoCard/editOrgDetailsModal.jsx @@ -70,7 +70,6 @@ const EditOrgDetailsModal = ({ currentOrgData, modelCloseCallback }) => { org_description: currentOrgData.org_description, org_country: currentOrgData.org_country, }); - const onSubmit = (formData) => { formData.preventDefault(); editGeneralData( diff --git a/src/components/Organization/ViewOrganization/index.jsx b/src/components/Organization/ViewOrganization/index.jsx index f4a37100..5884972a 100644 --- a/src/components/Organization/ViewOrganization/index.jsx +++ b/src/components/Organization/ViewOrganization/index.jsx @@ -20,6 +20,7 @@ import Description from "../../UserDetails/Description"; import Spinner from "../../../helpers/spinner"; import ActivityList from "../../Topbar/Activity/ActivityList"; import { BasicImage, NoImage } from "../../../helpers/images"; +import Tag from "../../UserDetails/Tag"; const useStyles = makeStyles(theme => ({ acitvitylist: { padding: theme.spacing(1), @@ -258,6 +259,14 @@ const ViewOrganization = () => { Content={currentOrgData.org_description} /> + + + event => { setOrgData({ ...OrgData, [name]: event.target.value }); }; + + const [itemList, setItemList] = useState([]); + const [selectedItems, setSelectedItems] = useState([]); + const [filterText, setFilterText] = useState(''); + const [showDropdown, setShowDropdown] = useState(false); + const itemsToShow = 8; // Number of items to show at a time + const maxDropdownHeight = 150; // Max height of the dropdown in pixels + + const dummyItems = [ + 'C', 'C++', 'Java', 'JavaScript', 'Python', 'Ruby', 'Swift', 'TypeScript', + 'C#', 'PHP', 'Go', 'Kotlin', 'Rust', 'Scala', 'Julia', 'D', 'Haskell', 'Elixir', + 'Clojure', 'Lua', 'Perl', 'Assembly', 'Fortran', 'HTML', 'CSS', 'Matlab', 'R', + 'SAS', 'VBA', 'SwiftUI', 'Flutter', 'React Native', 'Qt', 'wxWidgets', 'Gtk+', + 'Tkinter', 'Android', 'iOS', 'WebAssembly', 'React', 'Vue.js', 'Angular', 'Svelte', + 'Ember.js', 'Django', 'Flask', 'Rails', 'Laravel', 'ASP.NET Core', 'Spring Boot', + 'Express.js', 'Koa.js', 'Nest.js', 'TensorFlow', 'PyTorch', 'Scikit-learn', 'Pandas', + 'NumPy', 'Matplotlib', 'Seaborn', 'Bokeh', 'Plotly', 'Docker', 'Kubernetes', + 'Apache Spark', 'Apache Hadoop', 'Cassandra', 'Kafka', 'MongoDB', 'MySQL', + 'PostgreSQL', 'Elasticsearch', 'Prometheus', 'Grafana', 'Kibana', 'Logstash', + 'Terraform', 'Ansible', 'Puppet', 'Chef', 'Docker Compose', 'Kubernetes Helm', + 'Istio', 'ServiceMesh', 'gRPC', 'Protobuf', 'Thrift', 'Apache Camel', + 'Apache Mule ESB', 'Apache Kafka Streams', 'Spring Integration', + 'Oracle Fusion Middleware', 'IBM Integration Bus', 'TIBCO ActiveMatrix BusinessWorks Plus', + 'Azure Logic Apps', 'AWS Step Functions', 'Google Cloud Functions' +]; + + const inputRef = useRef(null); + + useEffect(() => { + // Close the dropdown when clicking outside the input and list + const handleOutsideClick = (event) => { + if (inputRef.current && !inputRef.current.contains(event.target)) { + setShowDropdown(false); + } + }; + + document.addEventListener('click', handleOutsideClick); + + return () => { + document.removeEventListener('click', handleOutsideClick); + }; + }, []); + + const showItems = () => { + setShowDropdown(true); + }; + + const addItem = (item) => { + setSelectedItems([...selectedItems, item]); + setFilterText(''); + setShowDropdown(false); + const updatedTags = OrgData.org_tags ? `${OrgData.org_tags},${item}` : item; + + setOrgData({ ...OrgData, org_tags: updatedTags }); + }; + + const resetItems = () => { + setSelectedItems([]); + // Create a new object to trigger a re-render + setOrgData((prevOrgData) => ({ ...prevOrgData, org_tags: ' ' })); + }; + + const handleFilterChange = (event) => { + const text = event.target.value; + setFilterText(text); + + // If the filter text is empty, show all items + if (!text.trim()) { + setItemList([]); + setShowDropdown(true); + return; + } + + // Filter the items based on the input text and show only a certain number + const filteredItems = dummyItems + .filter((item) => item.toLowerCase().includes(text.toLowerCase())) + .slice(0, itemsToShow); + setItemList(filteredItems); + setShowDropdown(true); + }; + - console.log(OrgData); const saveImage = (canvas, crop) => { if (!crop || !canvas) { @@ -372,17 +454,59 @@ function General() { onChange={handleChange("org_description")} /> - Select tags - - - - - - + {console.log(OrgData)} + Select tags +
+ + {showDropdown && ( +
    + {itemList.map((item, index) => ( +
  • addItem(item)}> + {item} +
  • + ))} +
+ )} +
+ + + + +
+ + Selected Tags +
+ {selectedItems.map((item, index) => ( + + ))} +
+ + + +
+
diff --git a/src/components/Organization/pages/Tags.css b/src/components/Organization/pages/Tags.css new file mode 100644 index 00000000..197e4dff --- /dev/null +++ b/src/components/Organization/pages/Tags.css @@ -0,0 +1,105 @@ +.tags-input { + display: inline-block; + position: relative; + border: 1px solid #ccc; + border-radius: 4px; + padding: 5px; + box-shadow: 2px 2px 5px #00000033; + width: 50%; +} + +.tags-input ul { + list-style: none; + padding: 0; + margin: 0; +} + +.tags-input li { + display: inline-block; + background-color: #f2f2f2; + color: #333; + border-radius: 20px; + padding: 5px 10px; + margin-right: 5px; + margin-bottom: 5px; +} + +.tags-input input[type="text"] { + border: none; + outline: none; + padding: 5px; + font-size: 14px; +} + +.tags-input input[type="text"]:focus { + outline: none; +} + +.tags-input .delete-button { + background-color: transparent; + border: none; + color: #999; + cursor: pointer; + margin-left: 5px; +} + + +/* Dropdown Button */ +.dropbtn { + background-color: #04AA6D; + color: white; + padding: 16px; + font-size: 16px; + border: none; + cursor: pointer; + } + + /* Dropdown button on hover & focus */ + .dropbtn:hover, .dropbtn:focus { + background-color: #3e8e41; + } + + /* The search field */ + #myInput { + box-sizing: border-box; + background-image: url('searchicon.png'); + background-position: 14px 12px; + background-repeat: no-repeat; + font-size: 16px; + padding: 14px 20px 12px 45px; + border: none; + border-bottom: 1px solid #ddd; + } + + /* The search field when it gets focus/clicked on */ + #myInput:focus {outline: 3px solid #ddd;} + + /* The container
- needed to position the dropdown content */ + .dropdown { + position: relative; + display: inline-block; + } + + /* Dropdown Content (Hidden by Default) */ + .dropdown-content { + display: none; + position: absolute; + background-color: #f6f6f6; + min-width: 230px; + border: 1px solid #ddd; + z-index: 1; + } + + /* Links inside the dropdown */ + .dropdown-content a { + color: black; + padding: 12px 16px; + text-decoration: none; + display: block; + } + + /* Change color of dropdown links on hover */ + .dropdown-content a:hover {background-color: #f1f1f1} + + /* Show the dropdown menu (use JS to add this class to the .dropdown-content container when the user clicks on the dropdown button) */ + .show {display:block;} \ No newline at end of file diff --git a/src/components/Tutorials/subComps/EditControls.jsx b/src/components/Tutorials/subComps/EditControls.jsx index 7ba446a6..0b329fb4 100644 --- a/src/components/Tutorials/subComps/EditControls.jsx +++ b/src/components/Tutorials/subComps/EditControls.jsx @@ -7,6 +7,7 @@ import Button from "@mui/material/Button"; import FileCopyIcon from "@mui/icons-material/FileCopy"; import ListIcon from "@mui/icons-material/List"; import DeleteIcon from "@mui/icons-material/Delete"; +import DoneIcon from "@mui/icons-material/Done"; import ChatIcon from "@mui/icons-material/Chat"; import EditIcon from "@mui/icons-material/Edit"; import VisibilityIcon from "@mui/icons-material/Visibility"; @@ -21,8 +22,10 @@ import { useFirebase, useFirestore } from "react-redux-firebase"; import { useDispatch } from "react-redux"; import RemoveStepModal from "./RemoveStepModal"; import ColorPickerModal from "./ColorPickerModal"; +import { useHistory } from 'react-router-dom'; import { Box, Stack } from "@mui/system"; + const EditControls = ({ isPublished, stepPanelVisible, @@ -50,11 +53,11 @@ const EditControls = ({ const handleClick = event => { setAnchorEl(event.currentTarget); }; - + const handleClose = () => { setAnchorEl(null); }; - + return ( <> + )} diff --git a/src/components/UserDetails/Tag.jsx b/src/components/UserDetails/Tag.jsx new file mode 100644 index 00000000..42557733 --- /dev/null +++ b/src/components/UserDetails/Tag.jsx @@ -0,0 +1,78 @@ +import React from "react"; +import { makeStyles } from "@mui/styles"; +import Card from "@mui/material/Card"; +import { + Button, + } from "@mui/material"; +import CardContent from "@mui/material/CardContent"; +import Typography from "@mui/material/Typography"; +import { createTheme, responsiveFontSizes, ThemeProvider } from "@mui/material"; + +const useStyles = makeStyles((theme) => ({ + root: { + margin: "auto", + display: "block", + maxWidth: "100%", + maxHeight: "100%", + [theme.breakpoints.down("xs")]: { + width: "95%", + }, + }, + head: { + fontWeight: "medium", + marginBottom: "5px", + }, +})); + +function Tag({ Heading, backgroundColor, Content }) { + const classes = useStyles(); + let theme = createTheme(); + theme = responsiveFontSizes(theme); + + // Check if Content is empty + if (!Content) { + // Handle the case when Content is empty, you can return null or handle it accordingly + return null; + } + + // Split the string into an array using commas as the delimiter + const contentArray = Content.split(','); + + return ( + + + + + {Heading} + + {contentArray.map((item, index) => ( + + ))} + + + + ); +} + +export default Tag;