import React, { useState, useEffect } from 'react'; import ReactGA from 'react-ga4'; import WelcomeForm2 from "../components/WelcomeForm2.jsx"; import AppFramework from "../components/AppFramework.jsx"; import {isMobile} from "react-device-detect"; import { HelpOutline as HelpOutlineIcon, } from '@mui/icons-material'; import { Grid, Container, Fade, Typography, Paper, Button, Card, CardContent, CardActionArea, Stepper, Step, StepLabel, Tooltip, } from '@mui/material'; import { getTheme } from '../theme.jsx'; import { useNavigate, Link, useLocation } from "react-router-dom"; import ArrowBackIosIcon from '@mui/icons-material/ArrowBackIos'; import Drift from "react-driftjs"; import { Context } from "../context/ContextApi.jsx"; const Welcome = (props) => { const { themeMode } = React.useContext(Context); const theme = getTheme(themeMode); const { globalUrl, surfaceColor, newColor, mini, inputColor, userdata, isLoggedIn, isLoaded, serverside, checkLogin } = props; const [skipped, setSkipped] = React.useState(new Set()); const [inputUsecase, setInputUsecase] = useState({}); const [frameworkData, setFrameworkData] = useState(undefined); const [discoveryWrapper, setDiscoveryWrapper] = useState(undefined); const [activeStep, setActiveStep] = React.useState(0); const [apps, setApps] = React.useState([]); const [defaultSearch, setDefaultSearch] = React.useState("") const [selectionOpen, setSelectionOpen] = React.useState(false) const [showWelcome, setShowWelcome] = React.useState(false) const [usecases, setUsecases] = React.useState([]); const [workflows, setWorkflows] = React.useState([]); let navigate = useNavigate(); const location = useLocation(); useEffect(() => { if (checkLogin !== undefined) { checkLogin() } }, [activeStep]) const isCloud = window.location.host === "localhost:3002" || window.location.host === "shuffler.io"; const [steps, setSteps] = useState([ "Help us get to know you", "Find your Apps", "Discover Usecases", ]) const handleKeysetting = (categorydata, workflows) => { //workflows[0].category = ["detect"] //workflows[0].usecase_ids = ["Correlate tickets"] if (workflows !== undefined && workflows !== null) { var newcategories = [] for (var key in categorydata) { var category = categorydata[key] category.matches = [] for (var subcategorykey in category.list) { var subcategory = category.list[subcategorykey] subcategory.matches = [] for (var workflowkey in workflows) { const workflow = workflows[workflowkey] if (workflow.usecase_ids !== undefined && workflow.usecase_ids !== null) { for (var usecasekey in workflow.usecase_ids) { if (workflow.usecase_ids[usecasekey].toLowerCase() === subcategory.name.toLowerCase()) { //console.log("Got match: ", workflow.usecase_ids[usecasekey]) category.matches.push({ "workflow": workflow.id, "category": subcategory.name, }) subcategory.matches.push(workflow.id) break } } } if (subcategory.matches.length > 0) { break } } } newcategories.push(category) } setUsecases(newcategories) } else { setUsecases(categorydata) } setWorkflows(workflows) } const fetchUsecases = (workflows) => { fetch(globalUrl + "/api/v1/workflows/usecases", { method: "GET", headers: { "Content-Type": "application/json", Accept: "application/json", }, credentials: "include", }) .then((response) => { if (response.status !== 200) { console.log("Status not 200 for usecases"); } return response.json() }) .then((responseJson) => { if (responseJson.success !== false) { handleKeysetting(responseJson, workflows) } else { //setWorkflows(workflows); //setWorkflowDone(true); } }) .catch((error) => { console.log("Usecase error: " + error.toString()) }); } const getAvailableWorkflows = () => { fetch(globalUrl + "/api/v1/workflows", { method: "GET", headers: { "Content-Type": "application/json", Accept: "application/json", }, credentials: "include", }) .then((response) => { if (response.status !== 200) { console.log("Status not 200 for workflows :O!: ", response.status); } return response.json(); }) .then((responseJson) => { if (responseJson !== undefined) { var newarray = [] for (var key in responseJson) { const wf = responseJson[key] if (wf.public === true) { continue } newarray.push(wf) } // Workflows are set in here fetchUsecases(newarray) } }) .catch((error) => { console.log("err in get workflows: ", error.toString()); }) } const getFramework = () => { fetch(globalUrl + "/api/v1/apps/frameworkConfiguration", { method: "GET", headers: { "Content-Type": "application/json", Accept: "application/json", }, credentials: "include", }) .then((response) => { if (response.status !== 200) { console.log("Status not 200 for framework!"); } return response.json(); }) .then((responseJson) => { if (responseJson.success === false) { setFrameworkData({}) if (responseJson.reason !== undefined) { //toast("Failed loading: " + responseJson.reason) } else { //toast("Failed to load framework for your org.") } } else { setFrameworkData(responseJson) } }) .catch((error) => { console.log("err in framework: ", error.toString()); }) } const getApps = () => { fetch(globalUrl + "/api/v1/apps", { method: "GET", headers: { "Content-Type": "application/json", Accept: "application/json", }, credentials: "include", }) .then((response) => { if (response.status !== 200) { console.log("Status not 200 for apps :O!"); } return response.json(); }) .then((responseJson) => { setApps(responseJson); }) .catch((error) => { console.log("App loading error: "+error.toString()); }); } const usecaseButtons = [{ "name": "Phishing", "usecase": "Email management", "color": "#C51152", }, { "name": "Enrichment", "usecase": "2. Enrich", "color": "#F4C20D", }, { "name": "Detection", "usecase": "3. Detect", "color": "#3CBA54", }, { "name": "Response", "usecase": "4. Respond", "color": "#4885ED", }] const handleSetSearch = (input, orgupdate) => { if (input !== defaultSearch) { setDefaultSearch(input) setSelectionOpen(false) setTimeout(function(){ setSelectionOpen(true) }, 150); //if (userdata !== undefined && userdata.active_org !== undefined && userdata.active_org.id !== undefined) { // sendOrgUpdate("", "", userdata.active_org.id, orgupdate) //} } else { setDefaultSearch("") setSelectionOpen(false) } } useEffect(() => { getFramework() getApps() getAvailableWorkflows() }, []) useEffect(() => { if (location.search !== undefined && location.search !== null) { const urlSearchParams = new URLSearchParams(location.search); const params = Object.fromEntries(urlSearchParams.entries()); const foundTab = params["tab"]; // Make foundtab into a number console.log("foundTab: ", foundTab, activeStep+1) if (foundTab !== null && foundTab !== undefined && !isNaN(foundTab) && foundTab >= 1 && foundTab <= 3) { console.log("SETTING TAB TO: ", foundTab) setShowWelcome(true) if (foundTab === 3 || foundTab === "3") { handleSetSearch(usecaseButtons[0].name, usecaseButtons[0].usecase) } setActiveStep(foundTab-1) //setRenderDone( } else { setShowWelcome(false) } } else { setShowWelcome(false) } }, [location.search]) const isStepSkipped = step => { return skipped.has(step) } const paperObject = { flex: 1, padding: 0, textAlign: "center", maxWidth: isMobile ? null : 275, minWidth: isMobile ? null : 275, backgroundColor: theme.palette.surfaceColor, color: "white", borderRadius: theme.palette?.borderRadius, } const actionObject = { padding: "25px", maxHeight: 280, minHeight: 280, borderRadius: theme.palette?.borderRadius, } const imageStyle = { width: 70, // height: 150, // margin: "auto", // marginTop: 10, marginBottom: 18, // borderRadius: 75, objectFit: "scale-down", } const buttonStyle = { borderRadius: 200, height: 51, width: isMobile ? 300 : 464, fontSize: 16, // background: "linear-gradient(89.83deg, #FF8444 0.13%, #F2643B 99.84%)", background: "linear-gradient(90deg, #F86744 0%, #F34475 100%)", padding: "16px 24px", top: 105, margin: "auto", itemAlign: "center", marginLeft: isMobile? null : "65px", } const defaultImage = "/images/experienced.png" const experienced_image = userdata !== undefined && userdata !== null && userdata.active_org !== undefined && userdata.active_org.image !== undefined && userdata.active_org.image !== null && userdata.active_org.image !== "" ? userdata.active_org.image : defaultImage const welcomeCardsOptions = [ { badge: "New easy setup", title: "Shuffle Security", subtitle: "Set security specific usecases automatically", icon: ( ), onClick: () => { if (isCloud) { ReactGA.event({ category: "welcome", action: "click_shuffle_security", label: "", }) navigate("https://security.shuffler.io/onboarding?utm_source=shuffler_onboarding") } else { // Default new port is 3002/3444 const { protocol, hostname } = window.location; var newPort = 3002; if (protocol === "https") { newPort = 3444 } const newUrl = `${protocol}//${hostname}:${newPort}/onboarding`; window.location.href = newUrl; } }, tooltip: "Automate your security operations with built-in use cases.", }, { title: "Shuffle Core", subtitle: "Build my workflows manually or with templates.", icon: Shuffle, onClick: () => { if (isCloud) { ReactGA.event({ category: "welcome", action: "click_shuffle_infrastructure", label: "", }) } navigate("/welcome?tab=2") }, tooltip: "Create custom workflows tailored to your specific infrastructure.", } ]; return (
{/*
*/} {showWelcome === true ?
{/*
{steps.map((label, index) => { const stepProps = {} const labelProps = {} //if (isStepOptional(index)) { // labelProps.optional = "optional" //} if (isStepSkipped(index)) { stepProps.completed = false; } return ( {label} ) })}
*/}
{/* */}
:
What do you want to do with Shuffle? Let us help you create a smoother journey.
{welcomeCardsOptions.map((card) => (
{card.badge && (
{card.badge}
)}
{card.icon}
{card.title} {card.subtitle}
))}
}
) } export default Welcome;