From 4855b549376c57ddebc0655089ee07a513e0d14b Mon Sep 17 00:00:00 2001 From: monilprajapati Date: Wed, 13 Nov 2024 13:29:50 +0530 Subject: [PATCH] added the basic ui structure for now --- frontend/src/App.jsx | 16 + frontend/src/views/Apps2.jsx | 562 +++++++++++++++++++++++++++++++++++ 2 files changed, 578 insertions(+) create mode 100644 frontend/src/views/Apps2.jsx diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 7349952b..c4d118d9 100755 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -14,6 +14,7 @@ import HealthPage from "./components/HealthPage.jsx"; //import Header from "./components/Header.jsx"; import theme from "./theme"; import Apps from "./views/Apps"; +import Apps2 from "./views/Apps2.jsx"; import AppCreator from "./views/AppCreator"; import DetectionDashBoard from "./views/DetectionDashboard.jsx"; @@ -408,6 +409,21 @@ const App = (message, props) => { {...props} /> } + /> + + } /> { + const isCloud = window.location.host === "localhost:3002" || window.location.host === "shuffler.io"; + const appUrl = isCloud ? `/apps/${data.id}` : `https://shuffler.io/apps/${data.id}`; + + const paperStyle = { + backgroundColor: mouseHoverIndex === index ? "rgba(26, 26, 26, 1)" : "#1A1A1A", + color: "rgba(241, 241, 241, 1)", + cursor: "pointer", + position: "relative", + width: 365, + height: 96, + borderRadius: 8, + boxShadow: "0px 0px 10px 0px rgba(0, 0, 0, 0.1)", + marginBottom: 20, + }; + + return ( + + + setMouseHoverIndex(index)} onMouseOut={() => setMouseHoverIndex(-1)}> + + {data.name} +
+
+ {data.name.replace(/_/g, ' ').replace(/\b\w/g, char => char.toUpperCase())} +
+
+ {data.categories ? data.categories.join(", ") : "NA"} +
+
+
+ {data.generated !== true && data.tags && data.tags.slice(0, 2).map((tag, tagIndex) => ( + + {tag} + {tagIndex < data.tags.length - 1 ? ", " : ""} + + ))} +
+ {/* Deactivate button logic */} + {data.generated === true ? ( + + ) : null} +
+
+
+
+
+
+ ); +}; + +const Apps2 = (props) => { + const { globalUrl, isLoaded, serverside, userdata } = props; + let navigate = useNavigate(); + const { leftSideBarOpenByClick } = useContext(Context); + const location = useLocation(); + const [searchQuery, setSearchQuery] = useState(""); + const [selectedCategory, setSelectedCategory] = useState(""); + const [selectedLabel, setSelectedLabel] = useState(""); + const [currTab, setCurrTab] = useState(0); + const [categories, setCategories] = useState([]); + const [labels, setLabels] = useState([]); + const [isLoading, setIsLoading] = useState(true); + const [userApps, setUserApps] = useState([]); + const [orgApps, setOrgApps] = useState([]); + const [selectedCategoryForUsersAndOgsApps, setselectedCategoryForUsersAndOgsApps] = useState([]); + const [selectedTagsForUserAndOrgApps, setSelectedTagsForUserAndOrgApps] = useState([]); + const [appsToShow, setAppsToShow] = useState([]); + const [deactivatedIndexes, setDeactivatedIndexes] = React.useState([]); + + + const [mouseHoverIndex, setMouseHoverIndex] = useState(-1); + var counted = 0; + const [showNoAppFound, setShowNoAppFound] = useState(false); + + const isCloud = + window.location.host === "localhost:3002" || + window.location.host === "shuffler.io"; + + useEffect(() => { + const timer = setTimeout(() => { + setShowNoAppFound(true); + }, 1000); + return () => clearTimeout(timer); + }, []); + + useEffect(() => { + const queryParams = new URLSearchParams(location.search); + const tabParam = queryParams.get('tab'); + if (tabParam !== null && tabParam !== undefined) { + if (tabParam === 'org_apps') { + setCurrTab(0); + } else if (tabParam === 'my_apps') { + setCurrTab(1); + } else { + setCurrTab(2); + } + } + }, [location.search]); + + + useEffect(() => { + if (currTab === 1) { + const baseUrl = globalUrl; + const userAppsUrl = `${baseUrl}/api/v1/users/me/apps`; + fetch(userAppsUrl, { + method: "GET", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + }) + .then((response) => response.json()) + .then((data) => { + setUserApps(data); + setIsLoading(false); + }) + .catch((err) => { + console.error("Error fetching user apps:", err); + }); + } else if (currTab === 0) { + const baseUrl = globalUrl; + const appsUrl = `${baseUrl}/api/v1/apps`; + fetch(appsUrl, { + method: "GET", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + }) + .then((response) => response.json()) + .then((data) => { + console.log("data of orgApps", data) + setOrgApps(data); + setIsLoading(false) + }) + .catch((err) => { + console.error("Error fetching apps:", err); + }); + } + }, [currTab]); + + + + + useEffect(() => { + if (serverside) { + return null; + } + }, [serverside]); + + + useEffect(() => { + + const findTopCategories = () => { + const categoryCountMap = {}; + + // Check if userAndOrgsApp is an array before iterating over it and Find top 10 Category from the apps + if (Array.isArray(appsToShow)) { + appsToShow.forEach((app) => { + const categories = app.categories; + + if (categories && categories.length > 0) { + categories.forEach((category) => { + categoryCountMap[category] = (categoryCountMap[category] || 0) + 1; + }); + } + }); + + const categoryArray = Object.keys(categoryCountMap).map((category) => ({ + category, + count: categoryCountMap[category], + })); + + categoryArray.sort((a, b) => b.count - a.count); + + const topCategories = categoryArray.slice(0, 7); + + return topCategories; + } + }; + + const findTopTags = () => { + const tagCountMap = {}; + + if (Array.isArray(appsToShow)) { + appsToShow.forEach((app) => { + const tags = app.tags; + if (tags && tags.length > 0) { + tags.forEach((tag) => { + tagCountMap[tag] = (tagCountMap[tag] || 0) + 1; + }); + } + }); + } + + const tagArray = Object.keys(tagCountMap).map((tag) => ({ + tag, + count: tagCountMap[tag], + })); + + tagArray.sort((a, b) => b.count - a.count); + + const topTags = tagArray.slice(0, 8); + + return topTags; + }; + + const categories = findTopCategories(); + if (categories) { + setCategories(categories) + } + console.log(categories) + const tags = findTopTags(); + if (tags) { + setLabels(tags); + } + console.log(tags) + }, [currTab]) + + const handleCreateApp = () => { + navigate('/create-app'); + }; + + + //Search app base on app name, category and tag + const filteredUserAppdata = Array.isArray(appsToShow) ? appsToShow.filter((app) => { + const matchesSearchQuery = ( + searchQuery === "" || + app.name.toLowerCase().includes(searchQuery.toLowerCase()) || + (app.tags && app.tags.some(tag => + tag.toLowerCase().includes(searchQuery.toLowerCase()) + )) || + (app.categories && app.categories.some((category) => + category.toLowerCase().includes(searchQuery.toLowerCase()) + )) + ); + + const matchesSelectedCategories = ( + selectedCategoryForUsersAndOgsApps.length === 0 || + (app.categories && app.categories.some(category => + selectedCategoryForUsersAndOgsApps.includes(category) + )) + ); + + const matchesSelectedTags = ( + selectedTagsForUserAndOrgApps.length === 0 || + (app.tags && selectedTagsForUserAndOrgApps.some(tag => + app.tags.includes(tag) + )) + ); + + + return matchesSearchQuery && matchesSelectedCategories && matchesSelectedTags; + }) : []; + + + const handleTabChange = (newTab) => { + setCurrTab(newTab); + if (currTab === 0) { + setAppsToShow(orgApps) + } + if (currTab === 1) { + setAppsToShow(userApps) + } + const newQueryParam = newTab === 0 ? 'org_apps' : newTab === 1 ? 'my_apps' : 'all_apps'; + const queryParams = new URLSearchParams(location.search); + queryParams.set('tab', newQueryParam); + queryParams.delete('q'); + window.history.replaceState({}, '', `${location.pathname}?${queryParams.toString()}`); + console.log("Current Tab", currTab) + console.log("Apps to show", appsToShow) + }; + + + + + const boxStyle = { + color: "white", + display: "flex", + flexDirection: "column", + width: "100%", + margin: "auto", + maxWidth: "60%", + // padding: '20px 380px', + }; + + const CustomClearRefinements = connectStateResults(({ searchResults, ...rest }) => { + const hasFilters = searchResults && searchResults.nbHits !== searchResults.nbSortedHits; + return Clear All }} {...rest} disabled={!hasFilters} />; + }); + + + const SearchBox = ({ refine, searchQuery, setSearchQuery }) => { + var defaultSearch = ""; + + + //useEffect(() => { + if ( + window !== undefined && + window.location !== undefined && + window.location.search !== undefined && + window.location.search !== null + ) { + const urlSearchParams = new URLSearchParams(window.location.search); + const params = Object.fromEntries(urlSearchParams.entries()); + const foundQuery = params["q"]; + if (foundQuery !== null && foundQuery !== undefined) { + console.log("Got query: ", foundQuery); + refine(foundQuery); + defaultSearch = foundQuery; + searchQuery = foundQuery + } + } + //}, []) + + + const handleSearch = () => { + refine(searchQuery.trim()); + }; + + return ( +
+ + + + ), + endAdornment: ( + + {searchQuery.length > 0 && ( + { + setSearchQuery('') + removeQuery("q"); + refine('') + }} + /> + ) + } + + + ), + + }} + autoComplete="off" + color="primary" + placeholder="Search more than 2500 Apps" + id="shuffle_search_field" + onChange={(event) => { + setSearchQuery(event.currentTarget.value); + removeQuery("q"); + refine(event.currentTarget.value); + }} + onKeyDown={(event) => { + if (event.key === "Enter") { + event.preventDefault(); + } + }} + limit={5} + /> + {/*isSearchStalled ? 'My search is stalled' : ''*/} + + ); + }; + + + + + const CustomSearchBox = connectSearchBox(SearchBox); + // const CustomHits = connectHits(Hits); + + + + + return ( +
+ + Apps + +
+ handleTabChange(newTab)} + TabIndicatorProps={{ style: { height: '3px', borderRadius: 10 } }} + > + + + + +
+
+
+ { + setSearchQuery(event.currentTarget.value); + removeQuery("q"); + // refine(event.currentTarget.value); + }} + onKeyDown={(event) => { + if (event.key === "Enter") { + event.preventDefault(); + } + }} + limit={5} + style={{ width: '100%', borderRadius: '7px', fontFamily: "var(--zds-typography-base,Inter,Helvetica,arial,sans-serif)" }} + InputProps={{ + style: { + borderRadius: 8, + }, + endAdornment: ( + + { + searchQuery.length === 0 ? : + } + + ), + }} + /> + {/* */} +
+
+ +
+
+ +
+
+ +
+
+
+
+ {orgApps.map((data, index) => ( + + ))} +
+
+ +
+ ); +}; + +export default Apps2;