diff --git a/frontend/public/images/demo1.png b/frontend/public/images/demo1.png new file mode 100644 index 00000000..4cd8faf1 Binary files /dev/null and b/frontend/public/images/demo1.png differ diff --git a/frontend/public/images/demo2.png b/frontend/public/images/demo2.png new file mode 100644 index 00000000..2d98b193 Binary files /dev/null and b/frontend/public/images/demo2.png differ diff --git a/frontend/public/images/demo3.png b/frontend/public/images/demo3.png new file mode 100644 index 00000000..cbe2ed96 Binary files /dev/null and b/frontend/public/images/demo3.png differ diff --git a/frontend/public/images/testing.png b/frontend/public/images/testing.png new file mode 100644 index 00000000..032c94a8 Binary files /dev/null and b/frontend/public/images/testing.png differ diff --git a/frontend/src/components/AppGrid1.jsx b/frontend/src/components/AppGrid1.jsx new file mode 100644 index 00000000..8706ef17 --- /dev/null +++ b/frontend/src/components/AppGrid1.jsx @@ -0,0 +1,377 @@ +import React, {useEffect, useState} from 'react'; + +import ReactGA from 'react-ga'; +import { useTheme } from '@material-ui/core/styles'; +import {Link} from 'react-router-dom'; + +import { Search as SearchIcon, CloudQueue as CloudQueueIcon, Code as CodeIcon } from '@material-ui/icons'; + +import algoliasearch from 'algoliasearch/lite'; +import { InstantSearch, Configure, connectSearchBox, connectHits, connectHitInsights } from 'react-instantsearch-dom'; + +import aa from 'search-insights' + +import { + Zoom, + Grid, + Paper, + TextField, + ButtonBase, + InputAdornment, + Typography, + Button, + Tooltip +} from '@material-ui/core'; + +const searchClient = algoliasearch("JNSS5CFDZZ", "db08e40265e2941b9a7d8f644b6e5240") +//const searchClient = algoliasearch("L55H18ZINA", "a19be455e7e75ee8f20a93d26b9fc6d6") +const AppGrid1 = props => { + const { maxRows, showName, showSuggestion, isMobile, globalUrl, parsedXs, userdata, searchValue } = props + + const isCloud = + window.location.host === "localhost:3000" || + window.location.host === "shuffler.io"; + + const rowHandler = maxRows === undefined || maxRows === null ? 50 : maxRows + const xs = parsedXs === undefined || parsedXs === null ? isMobile ? 6 : 2 : parsedXs + const theme = useTheme(); + //const [apps, setApps] = React.useState([]); + //const [filteredApps, setFilteredApps] = React.useState([]); + const [formMail, setFormMail] = React.useState(""); + const [message, setMessage] = React.useState(""); + const [formMessage, setFormMessage] = React.useState(""); + + const buttonStyle = {borderRadius: 30, height: 50, width: 220, margin: isMobile ? "15px auto 15px auto" : 20, fontSize: 18,} + + const innerColor = "rgba(255,255,255,0.65)" + const borderRadius = 3 + window.title = "Shuffle | Apps | Find and integrate any app" + + const submitContact = (email, message) => { + const data = { + "firstname": "", + "lastname": "", + "title": "", + "companyname": "", + "email": email, + "phone": "", + "message": message, + } + + const errorMessage = "Something went wrong. Please contact frikky@shuffler.io directly." + + fetch(globalUrl+"/api/v1/contact", { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(data), + }) + .then(response => response.json()) + .then(response => { + if (response.success === true) { + setFormMessage(response.reason) + //alert.info("Thanks for submitting!") + } else { + setFormMessage(errorMessage) + } + + setFormMail("") + setMessage("") + }) + .catch(error => { + setFormMessage(errorMessage) + console.log(error) + }); + } + + const SearchBox = ({currentRefinement, refine, isSearchStalled} ) => { + + 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 = {searchValue} + if (foundQuery !== null && foundQuery !== undefined) { + console.log("Got query: ", foundQuery) + refine(foundQuery) + } + } + }, []) + + return ( +
+ + + + ), + }} + autoComplete='off' + type="hidden" + color="primary" + defaultValue={currentRefinement} + placeholder="Find Apps..." + id="shuffle_search_field" + onChange={(event) => { + refine(event.currentTarget.value) + }} + limit={5} + /> + {/*isSearchStalled ? 'My search is stalled' : ''*/} + + ) + } + + var workflowDelay = -50 + const Hits = ({ hits, insights }) => { + const [mouseHoverIndex, setMouseHoverIndex] = useState(-1) + var counted = 0 + + //console.log(hits) + //var curhits = hits + //if (hits.length > 0 && defaultApps.length === 0) { + // setDefaultApps(hits) + //} + + //const [defaultApps, setDefaultApps] = React.useState([]) + //console.log(hits) + //if (hits.length > 0 && hits.length !== innerHits.length) { + // setInnerHits(hits) + //} + + return ( + + {hits.map((data, index) => { + + workflowDelay += 50 + + const paperStyle = { + backgroundColor: index === mouseHoverIndex ? "rgba(255,255,255,0.8)" : theme.palette.inputColor, + color: index === mouseHoverIndex ? theme.palette.inputColor : "rgba(255,255,255,0.8)", + border: `1px solid ${innerColor}`, + padding: 15, + cursor: "pointer", + position: "relative", + minHeight: 116, + } + + if (counted === 12/xs*rowHandler) { + return null + } + + counted += 1 + var parsedname = "" + for (var key = 0; key < data.name.length; key++) { + var character = data.name.charAt(key) + if (character === character.toUpperCase()) { + //console.log(data.name[key], data.name[key+1]) + if (data.name.charAt(key+1) !== undefined && data.name.charAt(key+1) === data.name.charAt(key+1).toUpperCase()) { + } else { + parsedname += " " + } + } + + parsedname += character + } + + parsedname = (parsedname.charAt(0).toUpperCase()+parsedname.substring(1)).replaceAll("_", " ") + + return ( + + + + { + setMouseHoverIndex(index) + /* + ReactGA.event({ + category: "app_grid_view", + action: `search_bar_click`, + label: "", + }) + */ + }} onMouseOut={() => { + setMouseHoverIndex(-1) + }} onClick={() => { + if (isCloud) { + ReactGA.event({ + category: "app_grid_view", + action: `app_${parsedname}_${data.id}_click`, + label: "", + }) + } + + //const searchClient = algoliasearch("L55H18ZINA", "a19be455e7e75ee8f20a93d26b9fc6d6") + console.log(searchClient) + aa('init', { + appId: searchClient.appId, + apiKey: searchClient.transporter.queryParameters["x-algolia-api-key"] + }) + + const timestamp = new Date().getTime() + aa('sendEvents', [ + { + eventType: 'click', + eventName: 'Product Clicked', + index: 'appsearch', + objectIDs: [data.objectID], + timestamp: timestamp, + queryID: data.__queryID, + positions: [data.__position], + userToken: userdata === undefined || userdata === null || userdata.id === undefined ? "unauthenticated" : userdata.id, + } + ]) + + }}> + + {data.name} + +
+ {index === mouseHoverIndex || showName === true ? + parsedname + : + null + } + {data.generated ? + + {data.invalid ? + + : + + } + + : + + + + } + + + + + ) + })} + + ) + } + + const CustomSearchBox = connectSearchBox(SearchBox) + const CustomHits = connectHits(Hits) + //const CustomHits = connectHitInsights(aa)(Hits) + const selectButtonStyle = { + minWidth: 150, + maxWidth: 150, + minHeight: 50, + } + + return ( +
+ {/* +
+ +
+ */} +
+ +
+ +
+ + +
+ {showSuggestion === true ? +
+ + Can't find what you're looking for? + +
+ setFormMail(e.target.value)} + /> + setMessage(e.target.value)} + /> +
+ + {formMessage} +
+ : null + } + + + + Search by + + + Algolia logo + + +
+
+ ) +} + +export default AppGrid1; diff --git a/frontend/src/views/AppExplorer.jsx b/frontend/src/views/AppExplorer.jsx new file mode 100644 index 00000000..01fc4546 --- /dev/null +++ b/frontend/src/views/AppExplorer.jsx @@ -0,0 +1,468 @@ + +import { Grid, Divider, List, ListItem, ListItemText } from "@mui/material"; +import { experimentalStyled as styled } from '@mui/material/styles'; +import Typography from "@material-ui/core/Typography"; +import Paper from "@material-ui/core/Paper"; +import Button from '@mui/material/Button'; +import Box from '@material-ui/core/Box'; +import React, { useState, useEffect } from "react"; + + +import algoliasearch from "algoliasearch"; +//import algoliarecommend from "algoliarecommend"; + +const searchClient = algoliasearch( + "JNSS5CFDZZ", + "db08e40265e2941b9a7d8f644b6e5240" +); + +// https://www.algolia.com/doc/api-client/getting-started/install/ +/*const algoliarecommend = require('@algolia/recommend'); + +const client = algoliarecommend( + "NSS5CFDZZ", + "db08e40265e2941b9a7d8f644b6e5240" +);*/ + + +const Item = styled(Paper)(({ theme }) => ({ + padding: theme.spacing(2), + border: "0.0625rem solid #b2b2b2", + borderRadius: "1.5625rem", + boxSizing: "content-box", + backgroundColor: "transparent", + width: "200px", + textAlign: 'center', + color: theme.palette.text.secondary, + marginTop: "20px", + marginBottom: "20px", + color: "textPrimary" +})); +const AppExplorer = (props) => { + const [algoliaResult, setAlgoliaResult] = useState(""); + + const runAlgoliaAppSearch = (query) => { + const index = searchClient.initIndex("appsearch"); + + index + .search(`${query}`) + .then(({ hits }) => { + setAlgoliaResult(hits); + }) + .catch((err) => { + console.log(err); + }); + }; + + useEffect(() => { + + runAlgoliaAppSearch("wazuh") + + }, []) + + + const brandApp = () => { + const index = searchClient.initIndex("appsearch"); + + const replicaIndex = searchClient.initIndex('appsearch'); + replicaIndex.setSettings({ + customRanking: [ + "asc(time_edited)" + ] + }) + + .then(({ hits }) => { + console.log(hits); + }) + .catch((err) => { + console.log(err); + }); + }; + + useEffect(() => { + + brandApp() + + }, []) + + /*const trandingApp = () => { + + const index = client.getTrendingGlobalItems([ + { + indexName: "appsearch", + threshold: 60 + }, + ]) + .then(({ results }) => { + console.log(results); + }) + .catch(err => { + console.log(err); + }); + }; + + useEffect(() => { + + trandingApp(); + + }, []) + */ + + const SideBar = { + minWidth: 250, + + borderRight: "1px solid rgba(255,255,255,0.3)", + left: 0, + position: "sticky", + minHeight: "90vh", + maxHeight: "90vh", + overflowX: "hidden", + overflowY: "auto", + zIndex: 1000, + color: "white" + }; + const contentbar = { + padding: "40px", + + }; + const boxdata = { + paddingLeft: "30px" + } + const link = { + textDecoration: "none" + } + const catItems = ( +
+ + + + Categories + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ ) + return ( +
+
+ + {catItems} +
+ + + + + Getting Started + +
+
+ +
+
+ + + {Array.from(Array(algoliaResult.length)).map((_, index) => ( + + + + + + +
+ +
+ shuffle +
+
+
+ + {algoliaResult[0]["name"]} + +
+
+ + {algoliaResult[0]["description"].substring(0, 20)} + +
+
+ +
+
+
+
+ ))} +
+
+ + + + Most Popular + +
+
+ +
+ + + {Array.from(Array(3)).map((_, index) => ( + + + +
+
+ shuffle +
+
+
+ + App Name + +
+
+ + Description + +
+
+ +
+
+
+
+ ))} +
+
+ + + + + Brand New + +
+
+ +
+ + + {Array.from(Array(3)).map((_, index) => ( + + + +
+
+ shuffle +
+
+
+ + App Name + +
+
+ + Description + +
+
+ +
+
+
+
+ ))} +
+
+ + + + + {Array.from(Array(3)).map((_, index) => ( + + +
+
+ shuffle +
+
+ +
+ ))} +
+
+ + + + + Hybrid work + +
+
+ +
+ + + + {Array.from(Array(3)).map((_, index) => ( + + + +
+
+ shuffle +
+
+
+ + App Name + +
+
+ + Description + +
+
+ +
+
+
+
+ ))} +
+
+ +
+
+ Don't see it? Build it! + Use our APIs to create an app that makes your working life better.And maybe even share it with the world. + visit developer portal +
+
+
+
+ shuffle +
+
+ shuffle +
+
+ shuffle +
+
+
+
+ +
+ +
+
+ + ); +} +export default AppExplorer; diff --git a/frontend/src/views/AppHub.jsx b/frontend/src/views/AppHub.jsx new file mode 100644 index 00000000..5a4db83a --- /dev/null +++ b/frontend/src/views/AppHub.jsx @@ -0,0 +1,789 @@ +import React from "react"; +import { Grid, Container, Divider, CardMedia, List, ListItem, ListItemText } from "@mui/material"; + +import { makeStyles } from "@material-ui/core/styles"; +import Card from "@material-ui/core/Card"; +import CardContent from "@material-ui/core/CardContent"; + +import Table from "@material-ui/core/Table"; +import TableBody from "@material-ui/core/TableBody"; +import TableCell from "@material-ui/core/TableCell"; +import TableContainer from "@material-ui/core/TableContainer"; +import TableHead from "@material-ui/core/TableHead"; +import TableRow from "@material-ui/core/TableRow"; +import Paper from "@material-ui/core/Paper"; + +import { LineChart, LineSeries, BarChart } from "reaviz"; +import { Gridline, GridStripe } from "reaviz"; +import { GridlineSeries } from "reaviz"; + +import InputLabel from '@material-ui/core/InputLabel'; +import FormControl from '@material-ui/core/FormControl'; +import Select from '@material-ui/core/Select'; + +import { styled, alpha } from '@mui/material/styles'; +import AppBar from '@mui/material/AppBar'; +import Box from '@mui/material/Box'; +import Toolbar from '@mui/material/Toolbar'; +import IconButton from '@mui/material/IconButton'; +import Typography from '@mui/material/Typography'; +import InputBase from '@mui/material/InputBase'; +import Badge from '@mui/material/Badge'; +import MenuItem from '@mui/material/MenuItem'; +import Menu from '@mui/material/Menu'; +import MenuIcon from '@mui/icons-material/Menu'; +import SearchIcon from '@mui/icons-material/Search'; +import AccountCircle from '@mui/icons-material/AccountCircle'; +import MailIcon from '@mui/icons-material/Mail'; +import NotificationsIcon from '@mui/icons-material/Notifications'; +import MoreIcon from '@mui/icons-material/MoreVert'; +import SearchField from "../components/Searchfield"; +import { SpaRounded } from "@material-ui/icons"; +import { isMobile } from "react-device-detect" + +const data = [ + { + key: new Date("11/29/2019"), + data: 10, + }, + { + key: new Date("11/30/2019"), + data: 14, + }, + { + key: new Date("12/01/2019"), + data: 5, + }, + { + key: new Date("12/02/2019"), + data: 18, + }, +]; + +const useStyles1 = makeStyles((theme) => ({ + formControl: { + margin: theme.spacing(1), + minWidth: 120, + }, + selectEmpty: { + marginTop: theme.spacing(2), + }, +})); + + +const useStyles = makeStyles({ + table: { + minWidth: 650, + }, + root: { + minWidth: 275, + }, + bullet: { + display: "inline-block", + margin: "0 2px", + transform: "scale(0.8)", + }, + title: { + fontSize: 14, + }, + pos: { + marginBottom: 12, + }, +}); + +function createData(name, calories, fat, carbs, protein) { + return { name, calories, fat, carbs, protein }; +} + +const rows = [ + createData("Frozen yoghurt", 159, 6.0, 24, 4.0), + createData("Ice cream sandwich", 237, 9.0, 37, 4.3), + createData("Eclair", 262, 16.0, 24, 6.0), + createData("Cupcake", 305, 3.7, 67, 4.3), + createData("Gingerbread", 356, 16.0, 49, 3.9), +]; + +const Search = styled('div')(({ theme }) => ({ + position: 'relative', + borderRadius: theme.shape.borderRadius, + backgroundColor: alpha(theme.palette.common.white, 0.15), + '&:hover': { + backgroundColor: alpha(theme.palette.common.white, 0.25), + }, + marginRight: theme.spacing(2), + marginLeft: 0, + width: '100%', + [theme.breakpoints.up('sm')]: { + marginLeft: theme.spacing(3), + width: 'auto', + }, +})); + +const SearchIconWrapper = styled('div')(({ theme }) => ({ + padding: theme.spacing(0, 2), + height: '100%', + position: 'absolute', + pointerEvents: 'none', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', +})); + +const StyledInputBase = styled(InputBase)(({ theme }) => ({ + color: 'inherit', + '& .MuiInputBase-input': { + padding: theme.spacing(1, 1, 1, 0), + // vertical padding + font size from searchIcon + paddingLeft: `calc(1em + ${theme.spacing(4)})`, + transition: theme.transitions.create('width'), + width: '100%', + [theme.breakpoints.up('md')]: { + width: '20ch', + }, + }, +})); + +function PrimarySearchAppBar() { + const [anchorEl, setAnchorEl] = React.useState(null); + const [mobileMoreAnchorEl, setMobileMoreAnchorEl] = React.useState(null); + + const isMenuOpen = Boolean(anchorEl); + const isMobileMenuOpen = Boolean(mobileMoreAnchorEl); + + const handleProfileMenuOpen = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleMobileMenuClose = () => { + setMobileMoreAnchorEl(null); + }; + + const handleMenuClose = () => { + setAnchorEl(null); + handleMobileMenuClose(); + }; + + const handleMobileMenuOpen = (event) => { + setMobileMoreAnchorEl(event.currentTarget); + }; + + const menuId = 'primary-search-account-menu'; + const renderMenu = ( + + Profile + My account + + ); + + const mobileMenuId = 'primary-search-account-menu-mobile'; + const renderMobileMenu = ( + + + + + + + +

Messages

+
+ + + + + + +

Notifications

+
+ + + + +

Profile

+
+
+ ); + + return ( + + + + shuffle img + + {/* */} + + + + {renderMobileMenu} + {renderMenu} + + ); +} + +const AppHub = () => { + const classes = useStyles(); + const classes1 = useStyles1(); + + const [usecases, setUsecases] = React.useState([ + { + "name": "1. Collect", + "color": "#c51152", + "list": [ + { + "name": "Email management", + "priority": 100, + "type": "communication", + "items": { + "name": "Release a quarantined message", + "items": {} + }, + "matches": [] + }, + { + "name": "EDR to ticket", + "priority": 100, + "type": "edr", + "items": { + "name": "Get host information", + "items": {} + }, + "matches": [] + }, + { + "name": "SIEM to ticket", + "priority": 100, + "type": "siem", + "description": "Ensure tickets are forwarded to the correct destination. Alternatively add enrichment on it's way there.", + "video": "https://www.youtube.com/watch?v=FBISHA7V15c&t=197s&ab_channel=OpenSecure", + "blogpost": "https://medium.com/shuffle-automation/introducing-shuffle-an-open-source-soar-platform-part-1-58a529de7d12", + "reference_image": "/images/detectionframework.png", + "items": {}, + "matches": [] + }, + { + "name": "2-way Ticket synchronization", + "priority": 90, + "items": {}, + "matches": [] + }, + { + "name": "ChatOps", + "priority": 70, + "items": {}, + "matches": [] + }, + { + "name": "Threat Intel received", + "priority": 50, + "items": {}, + "matches": [] + }, + { + "name": "Assign tickets", + "priority": 30, + "items": {}, + "matches": [] + }, + { + "name": "Firewall alerts", + "priority": 90, + "items": { + "name": "URL filtering", + "items": {} + }, + "matches": [] + }, + { + "name": "IDS/IPS alerts", + "priority": 90, + "items": { + "name": "Manage policies", + "items": {} + }, + "matches": [] + }, + { + "name": "Deduplicate information", + "priority": 70, + "items": {}, + "matches": [] + } + ], + "matches": [] + }, + { + "name": "2. Enrich", + "color": "#f4c20d", + "list": [ + { + "name": "Internal Enrichment", + "priority": 100, + "items": { + "name": "...", + "items": {} + }, + "matches": [] + }, + { + "name": "External historical Enrichment", + "priority": 90, + "items": { + "name": "...", + "items": {} + }, + "matches": [] + }, + { + "name": "Realtime", + "priority": 50, + "items": { + "name": "Analyze screenshots", + "items": {} + }, + "matches": [] + } + ], + "matches": [] + }, + { + "name": "3. Detect", + "color": "#3cba54", + "list": [ + { + "name": "Search SIEM (Sigma)", + "priority": 90, + "items": { + "name": "Endpoint", + "items": {} + }, + "matches": [] + }, + { + "name": "Search EDR (OSQuery)", + "priority": 90, + "items": {}, + "matches": [] + }, + { + "name": "Search emails (Sublime)", + "priority": 90, + "items": { + "name": "Check headers and IOCs", + "items": {} + }, + "matches": [] + }, + { + "name": "Search IOCs (ioc-finder)", + "priority": 50, + "items": {}, + "matches": [] + }, + { + "name": "Search files (Yara)", + "priority": 50, + "items": {}, + "matches": [] + }, + { + "name": "Memory Analysis (Volatility)", + "priority": 50, + "items": {}, + "matches": [] + }, + { + "name": "IDS & IPS (Snort/Surricata)", + "priority": 50, + "items": {}, + "matches": [] + }, + { + "name": "Validate old tickets", + "priority": 50, + "items": {}, + "matches": [] + }, + { + "name": "Honeypot access", + "priority": 50, + "items": { + "name": "...", + "items": {} + }, + "matches": [] + } + ], + "matches": [] + }, + { + "name": "4. Respond", + "color": "#4885ed", + "list": [ + { + "name": "Eradicate malware", + "priority": 90, + "items": {}, + "matches": [] + }, + { + "name": "Quarantine host(s)", + "priority": 90, + "items": {}, + "matches": [] + }, + { + "name": "Block IPs, URLs, Domains and Hashes", + "priority": 90, + "items": {}, + "matches": [] + }, + { + "name": "Trigger scans", + "priority": 50, + "items": {}, + "matches": [] + }, + { + "name": "Update indicators (FW, EDR, SIEM...)", + "priority": 50, + "items": {}, + "matches": [] + }, + { + "name": "Autoblock activity when threat intel is received", + "priority": 50, + "items": {}, + "matches": [] + }, + { + "name": "Lock/Delete/Reset account", + "priority": 50, + "items": {}, + "matches": [] + }, + { + "name": "Lock vault", + "priority": 50, + "items": {}, + "matches": [] + }, + { + "name": "Increase authentication", + "priority": 50, + "items": {}, + "matches": [] + }, + { + "name": "Get policies from assets", + "priority": 50, + "items": {}, + "matches": [] + }, + { + "name": "Run ansible scripts", + "priority": 50, + "items": {}, + "matches": [] + } + ], + "matches": [] + }, + { + "name": "5. Verify", + "color": "#7f00ff", + "list": [ + { + "name": "Discover vulnerabilities", + "priority": 80, + "items": {}, + "matches": [] + }, + { + "name": "Discover assets", + "priority": 80, + "items": {}, + "matches": [] + }, + { + "name": "Ensure policies are followed", + "priority": 80, + "items": {}, + "matches": [] + }, + { + "name": "Find Inactive users", + "priority": 50, + "items": {}, + "matches": [] + }, + { + "name": "Botnet tracker", + "priority": 50, + "items": {}, + "matches": [] + }, + { + "name": "Ensure access rights match HR systems", + "priority": 50, + "items": {}, + "matches": [] + }, + { + "name": "Ensure onboarding is followed", + "priority": 50, + "items": {}, + "matches": [] + }, + { + "name": "Third party apps in SaaS", + "priority": 50, + "items": {}, + "matches": [] + }, + { + "name": "Devices used for your cloud account", + "priority": 50, + "items": {}, + "matches": [] + }, + { + "name": "Too much access in GCP/Azure/AWS/ other clouds", + "priority": 50, + "items": {}, + "matches": [] + }, + { + "name": "Certificate validation", + "priority": 50, + "items": {}, + "matches": [] + }, + { + "name": "Domain investigation with LetsEncrypt", + "priority": 50, + "items": {}, + "matches": [] + }, + { + "name": "Monitor new DNS entries for domain with passive DNS", + "priority": 50, + "items": {}, + "matches": [] + }, + { + "name": "Monitor and track password dumps", + "priority": 50, + "items": {}, + "matches": [] + }, + { + "name": "Monitor for mentions of domain on darknet sites", + "priority": 50, + "items": {}, + "matches": [] + }, + { + "name": "Reporting", + "priority": 50, + "items": { + "name": "Monthly reports", + "items": { + "name": "...", + "items": {} + } + }, + "matches": [] + } + ], + "matches": [] + } + ]); + + const SideBar = { + minWidth: 250, + maxWidth: 300, + borderRight: "1px solid rgba(255,255,255,0.3)", + left: 0, + position: "sticky", + minHeight: "90vh", + maxHeight: "90vh", + overflowX: "hidden", + overflowY: "auto", + zIndex: 1000, + color: "black" + }; + + const [age, setAge] = React.useState(0); + + const handleChange = (event) => { + setAge(event.target.value); + + }; + + return ( +
+ + +
+
+
+ +
+
+
+ shuffle img + + SHUFFLE + +
+
+ +
+
+
+
+
+
+
+
+ + + + Categories + + + + + + + Workflows + + + + + Apps + + + + + Docs + + + +
+
+ + Workflow + +
+ {!isMobile && usecases !== null && usecases !== undefined && usecases.length > 0 ? +
+ + {usecases.map((usecase, index) => { + //console.log(usecase) + return ( + + { + console.log("clicked...") + }} + > + + + {usecase.name} + + + In use: {usecase.matches.length}/{usecase.list.length} + + + + + ) + })} + +
+ : null} + +
+
+
+ + + + footer + + + +
+ ); +}; + +export default AppHub; \ No newline at end of file diff --git a/frontend/src/views/Appdemo.jsx b/frontend/src/views/Appdemo.jsx new file mode 100644 index 00000000..3fe5aae1 --- /dev/null +++ b/frontend/src/views/Appdemo.jsx @@ -0,0 +1,268 @@ +import React, { useState, useEffect } from "react"; +import { Grid, Container, Divider, CardMedia, List, ListItem, ListItemText } from "@mui/material"; +import Typography from "@material-ui/core/Typography"; + +import theme from '../theme'; +import {isMobile} from "react-device-detect"; +import AppGrid1 from "../components/AppGrid1.jsx" +import WorkflowGrid from "../components/WorkflowGrid.jsx" +import CreatorGrid from "../components/CreatorGrid.jsx" +import DocsGrid from "../components/DocsGrid.jsx" +import Button from '@mui/material/Button'; +import { useNavigate, Link } from "react-router-dom"; + +import { + Tabs, + Paper, + Tab, +} from "@material-ui/core"; + +import { + Business as BusinessIcon, + Apps as AppsIcon, + Polymer as PolymerIcon, + EmojiObjects as EmojiObjectsIcon, + Description as DescriptionIcon, +} from "@material-ui/icons"; + + +const bodyDivStyle = { + margin: "auto", + maxWidth: 1024, + scrollX: "hidden", + overflowX: "hidden", +} + +// Should be different if logged in :| +const Appdemo = (props) => { + const { globalUrl, isLoaded, serverside, userdata, hidemargins, } = props; + const [appCategory,setAppCategory] = useState(); + let navigate = useNavigate(); + + const [curTab, setCurTab] = useState(0); + const iconStyle = { marginRight: 10 }; + + useEffect(() => { + if (serverside !== true && window.location.search !== undefined && window.location.search !== null) { + const urlSearchParams = new URLSearchParams(window.location.search) + const params = Object.fromEntries(urlSearchParams.entries()) + const foundTab = params["tab"] + if (foundTab !== null && foundTab !== undefined) { + for (var key in Object.keys(views)) { + const value = views[key] + console.log(key, value) + if (value === foundTab) { + setConfig("", key) + break + } + } + } + } + }, []) + + if (serverside === true) { + return null + } + + const boxStyle = { + color: "white", + flex: "1", + marginLeft: 10, + marginRight: 10, + paddingLeft: 30, + paddingRight: 30, + paddingBottom: 30, + paddingTop: hidemargins === true ? 0 : 30, + display: "flex", + flexDirection: "column", + overflowX: "hidden", + minHeight: 400, + } + const NoArguments_NoReturn = () => { + + alert('Function Called...'); + + } + const SideBar = { + minWidth: 250, + maxWidth: 300, + borderRight: "1px solid rgba(255,255,255,0.3)", + left: 0, + position: "sticky", + minHeight: "90vh", + maxHeight: "90vh", + overflowX: "hidden", + overflowY: "auto", + zIndex: 1000, + color: "white" + }; + const catItems = ( +
+ + + + Categories + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+) + + const views = { + 0: "apps", + 1: "workflows", + 2: "docs", + 3: "creators", + } + + const setConfig = (event, inputValue) => { + const newValue = parseInt(inputValue) + + setCurTab(newValue) + if (newValue === 0) { + document.title = "Shuffle - search - apps"; + } else if (newValue === 1) { + document.title = "Shuffle - search - workflows"; + } else if (newValue === 2) { + document.title = "Shuffle - search - documentation"; + } else if (newValue === 3) { + document.title = "Shuffle - search - creators"; + } else { + document.title = "Shuffle - search"; + } + + + const urlSearchParams = new URLSearchParams(window.location.search) + const params = Object.fromEntries(urlSearchParams.entries()) + const foundQuery = params["q"] + var extraQ = "" + if (foundQuery !== null && foundQuery !== undefined) { + extraQ = "&q="+foundQuery + } + + + if ((serverside === false || serverside === undefined) && window.location.pathname.includes("/search")) { + navigate(`/search?tab=${views[newValue]}`+extraQ) + } + } + + if (isLoaded === false) { + return null + } + + + // Random names for type & autoComplete. Didn't research :^) + const landingpageDataBrowser = +
+
+ + + Apps + + /> + + + {curTab === 0 ? + + : + curTab === 1 ? + window.location.pathname === "/search" ? + + : + + : + curTab === 2 ? + + : + curTab === 3 ? + + : + null} +
+
+ //{/*alternativeView={true} />*/} + + const loadedCheck = isLoaded ? +
+
{landingpageDataBrowser}
+
+ : +
+
+ + // #1f2023? + return( +
+ {catItems} + {loadedCheck} +
+ ) +} + +export default Appdemo;