Files
shuffle-cracked/frontend/src/components/AppSearch1.jsx
T
2026-05-07 15:27:32 +05:30

215 lines
9.8 KiB
React

import React, { useState, useEffect, useRef } from 'react';
import theme from '../theme.jsx';
import { Link, useNavigate } from 'react-router-dom';
import { Search as SearchIcon, CloudQueue as CloudQueueIcon, Code as CodeIcon } from '@mui/icons-material';
//import algoliasearch from 'algoliasearch/lite';
import algoliasearch from 'algoliasearch';
import { InstantSearch, connectSearchBox, connectHits } from 'react-instantsearch-dom';
import {
Grid,
Paper,
TextField,
InputAdornment,
Typography,
} from '@mui/material';
const searchClient = algoliasearch("JNSS5CFDZZ", "33e4e3564f4f060e96e0531957bed552")
const Appsearch = props => {
const { maxRows, showName, showSuggestion, isMobile, globalUrl, parsedXs, newSelectedApp, setNewSelectedApp, defaultSearch, showSearch, ConfiguredHits, userdata, cy, isCreatorPage, actionImageList, setActionImageList, setUserSpecialzedApp, placeholder,
} = props
let navigate = useNavigate();
const rowHandler = maxRows === undefined || maxRows === null ? 50 : maxRows
const xs = parsedXs === undefined || parsedXs === null ? 12 : parsedXs
const [open, setOpen] = React.useState(false);
const [value, setValue] = useState("");
window.title = "Shuffle | Apps | Find and integration any app"
const useCloseOnBlur = (setOpen) => {
useEffect(() => {
// Add event listener to detect clicks outside of the search box
const handleClickOutside = (event) => {
// Check if the click is outside the search box
if (!event.target.closest('.search-box')) {
setOpen(false);
}
};
document.addEventListener('mousedown', handleClickOutside);
// Clean up event listener
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, [setOpen]); // Ensure that this effect runs whenever setOpen changes
};
useCloseOnBlur(setOpen);
const SearchBox = ({ currentRefinement, refine, isSearchStalled }) => {
useEffect(() => {
//console.log("FIRST LOAD ONLY? RUN REFINEMENT: !", currentRefinement)
if (defaultSearch !== undefined && defaultSearch !== null) {
refine(defaultSearch)
}
}, [])
return (
<div style={{ textAlign: isMobile ? "center" : "" }}>
<form noValidate action="" role="search">
<TextField
sx={{
'& input[type="search"]': {
filter:
'brightness(0) invert(1)',
},
}}
fullWidth
variant="standard"
style={{
width: isMobile ? 295 : 402,
borderRadius: 8,
border: 0,
boxShadow: 0,
margin: 10,
height: isMobile ? 51 : "",
textAlign: "center",
// border: "1px solid rgba(241.19, 241.19, 241.19, 0.10)",
boxShadow: "none",
backgroundColor: "rgba(241.19, 241.19, 241.19, 0.10)",
fontWeight: 400,
marginLeft: 10,
zIndex: 110,
}}
InputProps={{
disableUnderline: true,
style: {
fontSize: isMobile ? "0.8em" : "1em",
height: 50,
zIndex: 1100,
paddingLeft: 15,
},
endAdornment: (
<InputAdornment position="end">
<div
style={{
width: isMobile ? 42 : 42,
height: isMobile ? 36 : 36,
background: "#806BFF",
borderRadius: 8,
marginRight: 10,
}}
>
<SearchIcon
onClick={() => {
navigate("/search?q=" + currentRefinement, { state: value, replace: true })
//navigate("/search?q="+currentRefinement, { state: value, replace: true })
//window.open("/apps"+currentRefinement, "_blank")
}}
style={{ cursor: 'pointer', width: isMobile ? 20 : "", marginright: 5, marginTop: isMobile ? 6 : 7 }}
/>
</div>
</InputAdornment>
),
}}
autoComplete="off"
type="search"
color="primary"
placeholder={placeholder !== undefined ? placeholder : "Search more than 2500 Apps"}
id="shuffle_search_field"
onChange={(event) => {
// Remove "q" from URL
// removeQuery("q")
refine(event.currentTarget.value)
}}
onKeyDown={(event) => {
if (event.keyCode === 13) {
navigate("/search?q=" + currentRefinement, { state: value, replace: true });
}
}}
onClick={(event) => {
setOpen(true);
}}
/>
{/*isSearchStalled ? 'My search is stalled' : ''*/}
</form>
</div>
)
}
const Hits = ({ hits, currentRefinement }) => {
const [mouseHoverIndex, setMouseHoverIndex] = useState(-1)
var counted = 0
return (
<Grid container spacing={0} style={{ display: "flex", alignItems: "center", justifyContent: "center", width: isMobile ? 302 : 402, maxHeight: 250, minHeight: 250, overflowY: "auto", overflowX: "hidden", }}>
{hits.map((data, index) => {
const paperStyle = {
backgroundColor: index === mouseHoverIndex ? "rgba(255,255,255,1)" : "#38383A",
color: index === mouseHoverIndex ? theme.palette.inputColor : "rgba(255,255,255,0.8)",
// border: newSelectedApp.objectID !== data.objectID ? `1px solid rgba(255,255,255,0.2)` : "2px solid #f86a3e",
textAlign: "left",
padding: 10,
cursor: "pointer",
position: "relative",
overflow: "hidden",
width: 402,
minHeight: 37,
maxHeight: 52,
}
if (counted === 12 / xs * rowHandler) {
return null
}
counted += 1
var parsedname = data.name.valueOf()
parsedname = (parsedname.charAt(0).toUpperCase() + parsedname.substring(1)).replaceAll("_", " ")
return (
<Paper key={index} elevation={0} style={paperStyle} onMouseOver={() => {
setMouseHoverIndex(index)
}} onMouseOut={() => {
setMouseHoverIndex(-1)
}} onClick={() => {
if (setNewSelectedApp !== undefined) {
setNewSelectedApp(data.name)
} else {
//need to add perfect url which redirect direct to app page
const newname = data.name.toLowerCase().replaceAll(" ", "_")
window.open("/apps/" + newname, "_blank")
}
}}>
<div style={{ display: "flex" }}>
<img alt={data.name} src={data.image_url} style={{ width: "100%", maxWidth: 30, minWidth: 30, minHeight: 30, borderRadius: 40, maxHeight: 30, display: "block", }} />
<Typography variant="body1" style={{ marginTop: 2, marginLeft: 10, }}>
{parsedname}
</Typography>
</div>
</Paper>
)
})}
</Grid>
)
}
const InputHits = ConfiguredHits === undefined ? Hits : ConfiguredHits
const CustomSearchBox = connectSearchBox(SearchBox)
const CustomHits = connectHits(InputHits)
return (
<div className="search-box" style={{ width: isMobile ? null : "100%", height: 95, alignItems: "center", justifyContent: "center", gap: 138, zIndex: 11000, }}>
<InstantSearch searchClient={searchClient} indexName="appsearch">
<div style={{ maxWidth: 450, margin: "auto", }}>
<CustomSearchBox />
</div>
<div style={{ alignItems: "center", justifyContent: "center", width: "100%", display: "flex" }}>
{open ? <CustomHits hitsPerPage={1} /> : null}
</div>
</InstantSearch>
</div>
)
}
export default Appsearch;