lots more changes
This commit is contained in:
@@ -5,6 +5,7 @@ import { useInfiniteScroll } from "../../hooks/infiniteScroll";
|
||||
import Files from "../Files";
|
||||
import { memo, useEffect, useState } from "react";
|
||||
import SpinnerPage from "../SpinnerPage";
|
||||
import SearchBar from "../SearchBar";
|
||||
|
||||
const DataForm = memo(() => {
|
||||
const {
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
import React from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
const Header = (props) => {
|
||||
const navigate = useNavigate();
|
||||
|
||||
return (
|
||||
<header>
|
||||
<div className="container">
|
||||
<div className="outer__header">
|
||||
<div className="left__header">
|
||||
<div className="logo__wrapper">
|
||||
<a onClick={() => navigate("/")}>
|
||||
<img
|
||||
className="header__icon"
|
||||
src="/images/mydrive-logo.png"
|
||||
alt="logo"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
<div className="search__wrapper">
|
||||
<a href="#">
|
||||
<img src="/assets/searchicon.svg" alt="search" />
|
||||
</a>
|
||||
<input
|
||||
type="text"
|
||||
onChange={props.searchOnChange}
|
||||
value={props.search}
|
||||
placeholder="Search"
|
||||
onFocus={props.showSuggested}
|
||||
onBlur={props.hideSuggested}
|
||||
/>
|
||||
<div
|
||||
className="search__files--dropdown"
|
||||
style={
|
||||
props.state.focused && props.searchValue.length !== 0
|
||||
? { display: "block" }
|
||||
: { display: "none" }
|
||||
}
|
||||
>
|
||||
<div
|
||||
onMouseDown={props.selectSuggestedByParent}
|
||||
className="elem__search--files search__filter--local"
|
||||
>
|
||||
<a>
|
||||
Search for{" "}
|
||||
<span className="file__name">{props.searchValue}</span>
|
||||
<span className="spacer">
|
||||
<img src="/assets/spacer.svg" alt="spacer" />
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="right__header">
|
||||
<div className="profile__info">
|
||||
<div className="settings__button">
|
||||
<a onClick={props.goToSettings}>
|
||||
<img src="/assets/settings.svg" alt="settings" />
|
||||
</a>
|
||||
</div>
|
||||
<div className="profile__wrapper">
|
||||
<div className="profile__button">
|
||||
<a style={{ backgroundColor: "#3c85ee" }}>
|
||||
<span style={{ color: "#fff" }}>
|
||||
{props.getProfilePic()}
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
};
|
||||
|
||||
export default Header;
|
||||
@@ -1,213 +0,0 @@
|
||||
import Header from "./Header";
|
||||
import { startLogout } from "../../actions/auth";
|
||||
import { showSettings } from "../../actions/settings";
|
||||
import { setSearch } from "../../actions/filter";
|
||||
import { loadMoreItems } from "../../actions/main";
|
||||
import { setParent, resetParentList } from "../../actions/parent";
|
||||
import { startSetFiles } from "../../actions/files";
|
||||
import { startSetFolders } from "../../actions/folders";
|
||||
import env from "../../enviroment/envFrontEnd";
|
||||
import axios from "../../axiosInterceptor";
|
||||
import { connect } from "react-redux";
|
||||
import React from "react";
|
||||
import withNavigate from "../HocComponent";
|
||||
|
||||
const currentURL = env.url;
|
||||
|
||||
class HeaderContainer extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.searchValue = "";
|
||||
|
||||
this.state = {
|
||||
focused: false,
|
||||
suggestedList: {
|
||||
fileList: [],
|
||||
folderList: [],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
searchEvent = (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
const value = this.props.search;
|
||||
|
||||
// console.log("Search value". value)
|
||||
|
||||
const parent = "/";
|
||||
this.props.dispatch(setParent(parent));
|
||||
this.props.dispatch(loadMoreItems(true));
|
||||
this.props.dispatch(startSetFiles(undefined, undefined, value));
|
||||
this.props.dispatch(startSetFolders(undefined, undefined, value));
|
||||
this.props.dispatch(resetParentList());
|
||||
};
|
||||
|
||||
searchOnChange = (e) => {
|
||||
const value = e.target.value;
|
||||
this.searchValue = value;
|
||||
|
||||
this.props.dispatch(setSearch(value));
|
||||
this.searchSuggested();
|
||||
};
|
||||
|
||||
showSuggested = () => {
|
||||
this.setState(() => {
|
||||
return {
|
||||
...this.state,
|
||||
focused: true,
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
hideSuggested = () => {
|
||||
this.setState(() => {
|
||||
return {
|
||||
...this.state,
|
||||
focused: false,
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
selectSuggested = () => {
|
||||
this.props.navigate(`/search/${this.searchValue}`);
|
||||
|
||||
this.searchValue = "";
|
||||
|
||||
this.setState(() => {
|
||||
return {
|
||||
...this.state,
|
||||
suggestedList: {
|
||||
fileList: [],
|
||||
folderList: [],
|
||||
},
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
searchSuggested = () => {
|
||||
return;
|
||||
|
||||
// if (this.searchValue === "") {
|
||||
|
||||
// return this.setState(() => {
|
||||
// return {
|
||||
// ...this.state,
|
||||
// suggestedList: {
|
||||
// fileList: [],
|
||||
// folderList: []
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
|
||||
// const url = !env.googleDriveEnabled ? currentURL +`/file-service/suggested-list?search=${this.searchValue}` : currentURL +`/file-service-google-mongo/suggested-list?search=${this.searchValue}`
|
||||
|
||||
// axios.get(url).then((results) => {
|
||||
|
||||
// this.setState(() => {
|
||||
// return {
|
||||
// ...this.state,
|
||||
// suggestedList: results.data
|
||||
// }
|
||||
// })
|
||||
|
||||
// }).catch((err) => {
|
||||
// console.log(err)
|
||||
// })
|
||||
};
|
||||
|
||||
showSettings = () => {
|
||||
this.props.dispatch(showSettings());
|
||||
};
|
||||
|
||||
logoutUser = () => {
|
||||
this.props.dispatch(startLogout());
|
||||
};
|
||||
|
||||
itemClick = () => {
|
||||
console.log("item click");
|
||||
};
|
||||
|
||||
selectSuggestedByParent = () => {
|
||||
// const parent = this.props.parent === "/" ? "home" : this.props.parent;
|
||||
|
||||
const parent = this.props.parent;
|
||||
|
||||
this.props.navigate(
|
||||
`/search/${this.searchValue}?parent=${parent}&folder_search=true`
|
||||
);
|
||||
|
||||
this.searchValue = "";
|
||||
|
||||
this.setState(() => {
|
||||
return {
|
||||
...this.state,
|
||||
suggestedList: {
|
||||
fileList: [],
|
||||
folderList: [],
|
||||
},
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
selectSuggestedByStorageType = () => {
|
||||
this.props.navigate(`/search/${this.searchValue}?storageType=stripe`);
|
||||
|
||||
this.searchValue = "";
|
||||
|
||||
this.setState(() => {
|
||||
return {
|
||||
...this.state,
|
||||
suggestedList: {
|
||||
fileList: [],
|
||||
folderList: [],
|
||||
},
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
goToSettings = () => {
|
||||
this.props.navigate("/settings");
|
||||
};
|
||||
|
||||
getProfilePic = () => {
|
||||
if (env.name && env.name.length !== 0) {
|
||||
return env.name.substring(0, 1).toUpperCase();
|
||||
} else if (env.emailAddress && env.emailAddress.length !== 0) {
|
||||
return env.emailAddress.substring(0, 1).toUpperCase();
|
||||
} else {
|
||||
return "?";
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Header
|
||||
searchEvent={this.searchEvent}
|
||||
searchOnChange={this.searchOnChange}
|
||||
selectSuggested={this.selectSuggested}
|
||||
showSuggested={this.showSuggested}
|
||||
hideSuggested={this.hideSuggested}
|
||||
showSettings={this.showSettings}
|
||||
searchValue={this.searchValue}
|
||||
selectSuggestedByParent={this.selectSuggestedByParent}
|
||||
selectSuggestedByStorageType={this.selectSuggestedByStorageType}
|
||||
itemClick={this.itemClick}
|
||||
goToSettings={this.goToSettings}
|
||||
getProfilePic={this.getProfilePic}
|
||||
state={this.state}
|
||||
{...this.props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const connectPropToStore = (state) => ({
|
||||
search: state.filter.search,
|
||||
parentNameList: state.parent.parentNameList,
|
||||
parent: state.parent.parent,
|
||||
});
|
||||
|
||||
export default connect(connectPropToStore)(withNavigate(HeaderContainer));
|
||||
@@ -0,0 +1,35 @@
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import SearchBar from "../SearchBar";
|
||||
|
||||
const Header = () => {
|
||||
const navigate = useNavigate();
|
||||
return (
|
||||
<header>
|
||||
<div className="px-6 flex justify-between min-h-[68px] items-center py-[15px]">
|
||||
<div className="flex items-center w-[260px]">
|
||||
<a
|
||||
className="inline-flex items-center justify-center cursor-pointer"
|
||||
onClick={() => navigate("/")}
|
||||
>
|
||||
<img className="w-[35px]" src="/images/icon.png" alt="logo" />
|
||||
</a>
|
||||
</div>
|
||||
<SearchBar />
|
||||
<div className="flex justify-end w-[260px]">
|
||||
<div>
|
||||
<div>
|
||||
<a
|
||||
onClick={() => navigate("/settings")}
|
||||
className="cursor-pointer"
|
||||
>
|
||||
<img src="/assets/settings.svg" alt="settings" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
};
|
||||
|
||||
export default Header;
|
||||
@@ -1,4 +1,4 @@
|
||||
import Header from "../Header";
|
||||
import Header from "../Header/";
|
||||
import LeftSection from "../LeftSection";
|
||||
import MainSection from "../MainSection";
|
||||
import Uploader from "../Uploader";
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
import { memo, useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { useAppDispatch } from "../../hooks/store";
|
||||
import { useSearchSuggestions } from "../../hooks/files";
|
||||
import debounce from "lodash/debounce";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useClickOutOfBounds } from "../../hooks/utils";
|
||||
import SearchBarItem from "../SearchBarItem";
|
||||
import { FolderInterface } from "../../types/folders";
|
||||
import { FileInterface } from "../../types/file";
|
||||
import { setPopupFile } from "../../actions/popupFile";
|
||||
import Spinner from "../Spinner";
|
||||
import classNames from "classnames";
|
||||
|
||||
const SearchBar = memo(() => {
|
||||
const [searchText, setSearchText] = useState("");
|
||||
const dispatch = useAppDispatch();
|
||||
const [debouncedSearchText, setDebouncedSearchText] = useState("");
|
||||
const { data: searchSuggestions, isLoading: isLoadingSearchSuggestions } =
|
||||
useSearchSuggestions(debouncedSearchText);
|
||||
const navigate = useNavigate();
|
||||
|
||||
const debouncedSetSearchText = useMemo(
|
||||
() => debounce(setDebouncedSearchText, 500),
|
||||
[]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
debouncedSetSearchText(searchText);
|
||||
return () => {
|
||||
debouncedSetSearchText.cancel();
|
||||
};
|
||||
}, [searchText, debouncedSetSearchText]);
|
||||
|
||||
const resetState = useCallback(() => {
|
||||
setSearchText("");
|
||||
setDebouncedSearchText("");
|
||||
}, []);
|
||||
|
||||
const { wrapperRef } = useClickOutOfBounds(resetState);
|
||||
|
||||
// TODO: Fix any
|
||||
const onSearch = (e: any) => {
|
||||
e.preventDefault();
|
||||
setSearchText("");
|
||||
setDebouncedSearchText("");
|
||||
if (searchText.length) {
|
||||
navigate(`/search/${searchText}`);
|
||||
} else {
|
||||
navigate("/home");
|
||||
}
|
||||
};
|
||||
|
||||
const onChangeSearch = (e: any) => {
|
||||
setSearchText(e.target.value);
|
||||
};
|
||||
|
||||
const fileClick = (file: FileInterface) => {
|
||||
dispatch(setPopupFile({ showPopup: true, ...file }));
|
||||
resetState();
|
||||
};
|
||||
|
||||
const folderClick = (folder: FolderInterface) => {
|
||||
navigate(`/folder/${folder?._id}`);
|
||||
resetState();
|
||||
};
|
||||
|
||||
return (
|
||||
<form
|
||||
onSubmit={onSearch}
|
||||
className="w-full max-w-[700px] relative flex items-center justify-center flex-col"
|
||||
// @ts-ignore
|
||||
ref={wrapperRef}
|
||||
>
|
||||
<a
|
||||
href="#"
|
||||
className={classNames(
|
||||
"absolute",
|
||||
!isLoadingSearchSuggestions ? "left-[15px]" : "left-[5px]"
|
||||
)}
|
||||
>
|
||||
{isLoadingSearchSuggestions ? (
|
||||
<div className="spinner-small"></div>
|
||||
) : (
|
||||
<img src="/assets/searchicon.svg" alt="search" />
|
||||
)}
|
||||
</a>
|
||||
<input
|
||||
type="text"
|
||||
onChange={onChangeSearch}
|
||||
value={searchText}
|
||||
placeholder="Search"
|
||||
className="w-full min-h-[42px] border border-[#BEC9D3] pl-[45px] pr-[15px] text-[16px] text-black rounded-[5px]"
|
||||
/>
|
||||
<div
|
||||
className="absolute left-0 bg-white shadow-xl rounded-[4px] w-full top-[42px] max-h-[400px] overflow-y-scroll border border-[#BEC9D3]"
|
||||
style={
|
||||
debouncedSearchText.length !== 0 && !isLoadingSearchSuggestions
|
||||
? { display: "block" }
|
||||
: { display: "none" }
|
||||
}
|
||||
>
|
||||
{searchSuggestions?.folderList.length === 0 &&
|
||||
searchSuggestions?.fileList.length === 0 ? (
|
||||
<div className="flex justify-center items-center p-4">
|
||||
<span>No Results</span>
|
||||
</div>
|
||||
) : undefined}
|
||||
{searchSuggestions?.folderList.map((folder: FolderInterface) => (
|
||||
<SearchBarItem
|
||||
type="folder"
|
||||
folder={folder}
|
||||
folderClick={folderClick}
|
||||
fileClick={fileClick}
|
||||
key={folder._id}
|
||||
/>
|
||||
))}
|
||||
{searchSuggestions?.fileList.map((file: FileInterface) => (
|
||||
<SearchBarItem
|
||||
type="file"
|
||||
file={file}
|
||||
folderClick={folderClick}
|
||||
fileClick={fileClick}
|
||||
key={file._id}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
});
|
||||
|
||||
export default SearchBar;
|
||||
@@ -0,0 +1,84 @@
|
||||
import { FileInterface } from "../../types/file";
|
||||
import { FolderInterface } from "../../types/folders";
|
||||
import { useMemo } from "react";
|
||||
import { getFileColor, getFileExtension } from "../../utils/files";
|
||||
|
||||
interface SearchBarItemProps {
|
||||
file?: FileInterface;
|
||||
folder?: FolderInterface;
|
||||
type: "file" | "folder";
|
||||
fileClick: (file: FileInterface) => void;
|
||||
folderClick: (folder: FolderInterface) => void;
|
||||
}
|
||||
|
||||
const SearchBarItem = (props: SearchBarItemProps) => {
|
||||
const { type, folder, file, fileClick, folderClick } = props;
|
||||
const fileExtension = useMemo(
|
||||
() => getFileExtension(file?.filename || "", 3),
|
||||
[file?.filename]
|
||||
);
|
||||
|
||||
const imageColor = useMemo(
|
||||
() => getFileColor(file?.filename || ""),
|
||||
[file?.filename]
|
||||
);
|
||||
|
||||
if (type === "folder" && folder) {
|
||||
return (
|
||||
<div
|
||||
className="flex flex-row items-center py-2 px-4 overflow-hidden text-ellipsis hover:bg-[#f6f5fd] cursor-pointer"
|
||||
key={folder._id}
|
||||
onClick={() => folderClick(folder)}
|
||||
>
|
||||
<div>
|
||||
<svg
|
||||
className="w-[30px] h-[30px] text-[#3c85ee]"
|
||||
aria-hidden="true"
|
||||
focusable="false"
|
||||
data-prefix="fas"
|
||||
data-icon="folder"
|
||||
role="img"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512"
|
||||
data-fa-i2svg=""
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M464 128H272l-64-64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V176c0-26.51-21.49-48-48-48z"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
<span className="text-sm ml-4 text-ellipsis overflow-hidden whitespace-nowrap">
|
||||
{folder.name}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
} else if (type === "file" && file) {
|
||||
return (
|
||||
<div
|
||||
className="flex flex-row items-center py-2 px-4 overflow-hidden text-ellipsis hover:bg-[#f6f5fd] cursor-pointer"
|
||||
key={file._id}
|
||||
onClick={() => fileClick(file)}
|
||||
>
|
||||
<div>
|
||||
<span className="inline-flex items-center max-w-[27px] min-w-[27px] min-h-[27px] max-h-[27px]">
|
||||
<div
|
||||
className="h-[27px] w-[27px] bg-red-500 rounded-[3px] flex flex-row justify-center items-center"
|
||||
style={{ background: imageColor }}
|
||||
>
|
||||
<span className="font-semibold text-[9.5px] text-white">
|
||||
{fileExtension}
|
||||
</span>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
<span className="text-sm ml-4 text-ellipsis overflow-hidden whitespace-nowrap">
|
||||
{file.filename}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return <div></div>;
|
||||
};
|
||||
|
||||
export default SearchBarItem;
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from "react";
|
||||
import Header from "../Header/index";
|
||||
import Header from "../Header";
|
||||
import axios from "../../axiosInterceptor";
|
||||
import env from "../../enviroment/envFrontEnd";
|
||||
import Swal from "sweetalert2";
|
||||
|
||||
Reference in New Issue
Block a user