react-redux#useDispatch JavaScript Examples
The following examples show how to use
react-redux#useDispatch.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: BookPage.js From mern_library_nginx with MIT License | 6 votes |
BookPage = ({ match }) => {
const dispatch = useDispatch();
const bookDetails = useSelector((state) => state.bookDetails);
const { loading, error, book } = bookDetails;
useEffect(() => {
dispatch(listBookDetails(match.params.id));
}, [dispatch, match]);
return (
<>
<Link className="btn btn-success my-3" to="/books">
Go Back to My Books
</Link>
{loading ? (
<Loader />
) : error ? (
<Message variant="danger">{error}</Message>
) : (
<Row>
<Card className="my-3 p-3 rounded">
<Card.Header as="h2">
<strong>{book.title}</strong>
</Card.Header>
<Card.Body>
<Card.Subtitle className="mb-2 text-muted">
{book.subtitle}
</Card.Subtitle>
<Card.Text>{book.description}</Card.Text>
<Card.Text as="h6">ISBN {book.isbn}</Card.Text>
<Button variant="primary">{book.author}</Button>
</Card.Body>
</Card>
</Row>
)}
</>
);
}
Example #2
Source File: termsPolicyContent.js From ActiveLearningStudio-react-client with GNU Affero General Public License v3.0 | 6 votes |
export default function TermsPolicyContent(props) {
const organization = useSelector((state) => state.organization);
const { currentOrganization } = organization;
const [content, setContent] = useState('');
const dispatch = useDispatch();
const { match } = props;
useEffect(() => {
const contentType = match.params.content;
const orgDomain = match.params.organization ? match.params.organization : 'currikistudio';
if (contentType === 'tos_content') {
setContent(currentOrganization?.tos_content);
} else if (contentType === 'privacy_policy_content') {
setContent(currentOrganization?.privacy_policy_content);
}
if (!content) {
dispatch(getBranding(orgDomain));
}
});
return (
<div className="terms-policy-container" dangerouslySetInnerHTML={{ __html: content }} />
);
}
Example #3
Source File: App.js From React-discord-clone with MIT License | 6 votes |
function App() {
const dispatch = useDispatch()
const user = useSelector(selectUser)
useEffect(() => {
auth.onAuthStateChanged((authUser) => {
if (authUser) {
dispatch(login({
uid : authUser.uid,
photo: authUser.photoURL,
email: authUser.email,
displayName : authUser.displayName,
}))
}
else {
dispatch(logout())
}
})
}, [dispatch])
return (
<div className="app">
{ user ? (
<>
<Sidebar />
<Chat />
</>
) : (
<Login />
)}
</div>
);
}
Example #4
Source File: ArchivedLists.js From TrelloClone with MIT License | 6 votes |
ArchivedLists = () => {
const listObjects = useSelector((state) => state.board.board.listObjects);
const dispatch = useDispatch();
const onSubmit = async (listId) => {
dispatch(archiveList(listId, false));
};
return (
<div>
<List>
{listObjects
.filter((list) => list.archived)
.map((list, index) => (
<ListItem key={index}>
<ListItemText primary={list.title} />
<Button onClick={() => onSubmit(list._id)}>Send to Board</Button>
</ListItem>
))}
</List>
</div>
);
}
Example #5
Source File: ViewDeck.jsx From ashteki with GNU Affero General Public License v3.0 | 6 votes |
ViewDeck = ({ deck }) => {
const dispatch = useDispatch();
const handleDeleteClick = () => {
dispatch(deleteDeck(deck));
};
const handleEditClick = () => {
dispatch(navigate('/decks/edit'));
};
return (
<Panel title={deck?.name}>
<Col xs={12} className='text-center'>
<ButtonGroup>
<button className='btn btn-primary' onClick={handleEditClick}>
Edit
</button>
<ConfirmButton onClick={handleDeleteClick}>
<Trans>Delete</Trans>
</ConfirmButton>
</ButtonGroup>
</Col>
<DeckSummary deck={deck} />
</Panel>
);
}
Example #6
Source File: MapOverlay.js From foster-together-fe with MIT License | 6 votes |
export default function MapThing() {
const dispatch = useDispatch();
useEffect(() => {
dispatch(getMembers());
}, [dispatch]);
const locations = useSelector(state => state.mem);
const [points, setPoints] = useState(locations.membersArray);
const [selected, setSelected] = useState({});
return (
<>
<NavBar />
<PageContain>
<MapFilters filter={setPoints} locations={locations.membersArray} />
<Map locations={points} selected={selected} setSelected={setSelected} />
<PersonInfo selected={selected} />
</PageContain>
</>
);
}
Example #7
Source File: EditProfileForms.js From grants-fe with MIT License | 6 votes |
EditButton = (props) => {
const viewerId = props.viewerId;
const profileId = props.profileId;
const dispatch = useDispatch();
const editToggle = () => {
dispatch(toggleEditing());
};
if (Number(viewerId) === Number(profileId)) {
return <Button onClick={editToggle}>Edit Profile</Button>;
} else {
return null;
}
}
Example #8
Source File: EditNeighborhood.js From neighborhood-chef-fe with MIT License | 6 votes |
EditNeighborhood = (props) => {
const [newName, setNewName] = useState(props.currentName);
const dispatch = useDispatch();
const classes = textBoxStyles();
return (
<form
className={classes.background}
onSubmit={(e) => {
e.preventDefault();
dispatch(changeNeighborhoodName(newName));
props.setIsEditing(false);
}}
>
<input
className={classes.textBox}
type="text"
name="neighborhood"
value={newName}
onChange={(e) => setNewName(e.target.value)}
/>
<button className={classes.button}>
<Icon width="2em" icon={baselineCheck} />
</button>
</form>
);
}
Example #9
Source File: index.js From ActiveLearningStudio-react-client with GNU Affero General Public License v3.0 | 5 votes |
EmailCheckForm = (props) => {
const { currentOrg, handleEmailChecked } = props;
const [email, setEmail] = useState('');
const [error, setError] = useState(null);
const dispatch = useDispatch();
const doCheck = async () => {
setError(null);
const response = await adminService.checkUserEmail(currentOrg.id, email);
console.log(response);
if (response?.message && response?.user) {
// User exists and belongs to currentOrg
setError(response.message);
return;
}
if (response?.user) {
// User exists but doesn't belong to currentOrg
dispatch(setCurrentUser(response.user));
handleEmailChecked('existing-user', response?.user?.email);
return;
}
if (response?.message) {
// User does not exist
handleEmailChecked('new-user', email);
}
};
return (
<div className="container email-check-form">
<label>Email</label>
<div className="row">
<div className="col">
<div className="form-group-create">
<input className="form-control" type="email" name="email" onChange={(e) => setEmail(e.target.value)} />
{error && (
<div className="error">
{error}
</div>
)}
</div>
</div>
<div className="col text-right">
{error ? (
<button type="button" className="btn btn-primary addButton" onClick={() => dispatch(removeActiveAdminForm())}>Ok</button>
) : (
<button type="button" className="btn btn-primary addButton" onClick={doCheck}>
Add User
</button>
)}
</div>
</div>
</div>
);
}
Example #10
Source File: Counter.js From React-discord-clone with MIT License | 5 votes |
export function Counter() {
const count = useSelector(selectCount);
const dispatch = useDispatch();
const [incrementAmount, setIncrementAmount] = useState('2');
return (
<div>
<div className={styles.row}>
<button
className={styles.button}
aria-label="Increment value"
onClick={() => dispatch(increment())}
>
+
</button>
<span className={styles.value}>{count}</span>
<button
className={styles.button}
aria-label="Decrement value"
onClick={() => dispatch(decrement())}
>
-
</button>
</div>
<div className={styles.row}>
<input
className={styles.textbox}
aria-label="Set increment amount"
value={incrementAmount}
onChange={e => setIncrementAmount(e.target.value)}
/>
<button
className={styles.button}
onClick={() =>
dispatch(incrementByAmount(Number(incrementAmount) || 0))
}
>
Add Amount
</button>
<button
className={styles.asyncButton}
onClick={() => dispatch(incrementAsync(Number(incrementAmount) || 0))}
>
Add Async
</button>
</div>
</div>
);
}
Example #11
Source File: ArchivedCards.js From TrelloClone with MIT License | 5 votes |
ArchivedCards = () => {
const cards = useSelector((state) => state.board.board.cardObjects);
const lists = useSelector((state) => state.board.board.listObjects);
const dispatch = useDispatch();
const onDelete = async (listId, cardId) => {
dispatch(deleteCard(listId, cardId));
};
const onSendBack = async (cardId) => {
dispatch(archiveCard(cardId, false));
};
return (
<div>
<List>
{cards
.filter((card) => card.archived)
.map((card, index) => (
<ListItem key={index} className='archived-card'>
<Card>
<CardContent>{card.title}</CardContent>
</Card>
<div>
<Button
color='secondary'
onClick={() =>
onDelete(
lists.find((list) => list.cards.includes(card._id))._id,
card._id
)
}
>
Delete Card
</Button>
<Button onClick={() => onSendBack(card._id)}>Send to List</Button>
</div>
</ListItem>
))}
</List>
</div>
);
}
Example #12
Source File: PasswordGame.jsx From ashteki with GNU Affero General Public License v3.0 | 5 votes |
PasswordGame = () => {
const { t } = useTranslation();
const { passwordError, passwordJoinType, passwordGame } = useSelector((state) => ({
passwordError: state.lobby.passwordError,
passwordGame: state.lobby.passwordGame,
passwordJoinType: state.lobby.passwordJoinType
}));
const [password, setPassword] = useState('');
const dispatch = useDispatch();
if (!passwordGame) {
return null;
}
return (
<div>
<Panel title={passwordGame.name}>
{passwordError && <AlertPanel type='danger' message={t(passwordError)} />}
<h3>
<Trans>Enter the password</Trans>
</h3>
<div className='mt-1 mb-3'>
<input
className='form-control'
type='text'
onChange={(event) => setPassword(event.target.value)}
value={password}
/>
</div>
<div className='text-center'>
<Button
variant='primary'
onClick={() => {
dispatch(
sendSocketMessage(
passwordJoinType === 'Join' ? 'joingame' : 'watchgame',
passwordGame.id,
password
)
);
}}
>
{t(passwordJoinType)}
</Button>
<Button variant='danger' onClick={() => dispatch(cancelPasswordJoin())}>
<Trans>Cancel</Trans>
</Button>
</div>
</Panel>
</div>
);
}
Example #13
Source File: App.js From Merch-Dropper-fe with MIT License | 5 votes |
function App() {
const [design, setDesign] = useState(initialShirtState.designInfo);
const [garment, setGarment] = useState(initialShirtState.garment);
const [product, setProduct] = useState(initialState.products)
const [thumbRender, setThumbRender] = useState();
const dispatch = useDispatch();
return (
<div className="App" >
<NavBar />
<div className="outsideContainer" onClick={() => {dispatch(resetCart())}} >
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/develop" component={DevAuth} />
<Route exact path="/cart" component={ShoppingCart} />
<Route exact path="/checkout" component={CheckoutPage} />
<Route
exact
path="/addproduct"
render={(props) => <AddProductToTable garment={garment} design={design}{...props} />}
/>
<PrivateRoute
exact
path="/products"
render={(props) => <ProductDisplay {...props} />}
/>
<PrivateRoute exact path="/dashboard" component={Dashboard} />
<Route exact path="/createstore" component={CreateStore} />
<Route
exact
path="/designshirt"
render={(props) => (
<DesignShirt
design={design}
setDesign={setDesign}
garment={garment}
setGarment={setGarment}
thumbRender={thumbRender}
setThumbRender={setThumbRender}
product={product}
setProduct={setProduct}
{...props}
/>
)}
/>
<Route exact path="/:domain_name/shippingAddress" component={ShippingAddress} />
<Route exact path="/learnmore" component={LearnMore} />
<Route exact path="/redirect" component={Redirect} />
<Route exact path="/stripe-setup" component={StripeSetup} />
<Route
exact
path="/:domain_name"
render={(props) => <ProductDisplayDomain {...props} />}
/>
<Route exact path="/:domain_name/checkout" component={CheckoutPage} />
</Switch>
<Footer />
</div>
</div>
);
}
Example #14
Source File: AdminDashboard.js From foster-together-fe with MIT License | 5 votes |
export default function Distance() {
const dispatch = useDispatch();
useEffect(() => {
dispatch(getMembers());
}, [dispatch]);
const { membersArray } = useSelector(state => state.mem);
// Functions to display taskbar //
const numApplications = membersArray.filter(
people => people.application === 1
);
const numVolunteers = membersArray.filter(
people => people.type === "neighbors"
);
const familiesToMatch = membersArray.filter(
people => people.type === "families"
);
return (
<>
<Navigation />
<DashContainer>
<Welcome />
<TaskBar
members={membersArray}
numApplications={numApplications}
numVolunteers={numVolunteers}
familiesToMatch={familiesToMatch}
/>
<SearchBar members={membersArray} />
<TableContain>
<MemberTable members={membersArray} />
</TableContain>
</DashContainer>
</>
);
}
Example #15
Source File: App.js From grants-fe with MIT License | 5 votes |
//
function App() {
const loggedIn = useSelector((state) => state.login.loggedIn);
const user = useSelector((state) => state.login.user);
const userType = useSelector((state) => state.login.usertype);
const userId = useSelector((state) => state.login.userId);
const grants = useSelector((state) => state.grants.applicantGrants);
const dispatch = useDispatch();
useEffect(() => {
//only fetches grants if a userId exists and grants have not already been fetched
if (userId !== undefined && grants && grants.length === 0) {
dispatch(getGrants());
}
}, [dispatch, userId, grants]);
return (
<Router>
<ThemeProvider theme={theme}>
<Route exact path="/">
<LandingPage />
</Route>
{loggedIn && <Navbar />}
<Switch>
<PrivateRoute
path="/writer-favorites"
component={WritersFavoriteGrants}
/>
<PrivateRoute path="/EditGrant/:id" component={UpdateGrant} />
<PrivateRoute path="/GrantsForm" component={GrantsForm} />
<PrivateRoute path="/GrantsList" component={GrantsList} />
{userType && userType === "applicant" ? (
<PrivateRoute path="/profile" component={ApplicantProfile} />
) : (
<PrivateRoute path="/profile" component={WriterProfile} />
)}
<PrivateRoute path="/Homepage" component={Homepage} />
{user && user.user_type === "applicant" ? (
<PrivateRoute path="/onboarding" component={ApplicantProfileForm} />
) : (
<PrivateRoute path="/onboarding" component={WriterProfileForm} />
)}
<Route path="/RegisterForm">
<RegisterForm />
</Route>
<Route path="/LoginForm">
<LoginForm />
</Route>
<PrivateRoute exact path="/Grants" component={GrantsPage} />
</Switch>
</ThemeProvider>
</Router>
);
}
Example #16
Source File: AuthFields.js From neighborhood-chef-fe with MIT License | 5 votes |
AuthFields = (props) => {
const buttonClass = buttonStyles();
const dispatch = useDispatch();
const [buttonDisable, setButtonDisable] = useState(true);
const checkValues = (e) => {
const email = document.querySelector("input[name='email']").value;
const terms = document.querySelector("input[type='checkbox']").checked;
if (
/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(email) &&
terms === true
) {
setButtonDisable(false);
} else {
setButtonDisable(true);
}
};
return (
<>
<Field
style={{ marginTop: "10%" }}
component={TextField}
type="email"
name="email"
className="email"
InputProps={{ onKeyUp: checkValues }}
label="Email"
required
/>
<label style={{ marginTop: "10%" }} className="terms">
<Field
component={Checkbox}
type="checkbox"
name="terms"
onChange={checkValues}
/>
I accept the terms and conditions.
</label>
<Button
style={{ marginTop: "10%" }}
className={`${buttonClass.root} ${buttonClass.active}`}
onClick={() => {
dispatch(changePage(2));
}}
disabled={buttonDisable}
>
<Typography variant="h5">Continue registering</Typography>
</Button>
</>
);
}
Example #17
Source File: BookListPage.js From mern_library_nginx with MIT License | 4 votes |
BookListPage = ({ history }) => {
const [title, setTitle] = useState("");
const [subtitle, setSubTitle] = useState("");
const [author, setAuthor] = useState("");
const [description, setDescription] = useState("");
const [isbn, setISBN] = useState("");
const dispatch = useDispatch();
const bookList = useSelector((state) => state.bookList);
const { loading, error, books } = bookList;
const bookCreate = useSelector((state) => state.bookCreate);
const {
loading: loadingCreate,
error: errorCreate,
success: successCreate,
book: createdBook,
} = bookCreate;
const bookDelete = useSelector((state) => state.bookDelete);
const {
loading: loadingDelete,
error: errorDelete,
success: successDelete,
} = bookDelete;
useEffect(() => {
dispatch({ type: BOOK_CREATE_RESET });
if (successCreate) {
history.push(`/books/${createdBook._id}`);
} else {
dispatch(listBooks());
}
}, [dispatch, history, successCreate, successDelete, createdBook]);
const createBookHandler = (e) => {
e.preventDefault();
dispatch(
createBook({
title,
subtitle,
description,
author,
isbn,
})
);
};
const deleteHandler = (id) => {
dispatch(deleteBook(id));
};
return (
<>
{loadingCreate && <Loader />}
{errorCreate && <Message variant="danger">{errorCreate}</Message>}
{loadingDelete && <Loader />}
{errorDelete && <Message variant="danger">{errorDelete}</Message>}
<Row>
<Col>
<Form onSubmit={createBookHandler}>
<Form.Group controlId="bookTitle">
<Form.Label>Book Title</Form.Label>
<Form.Control
type="text"
value={title}
onChange={(e) => setTitle(e.target.value)}
placeholder="Enter Title"
/>
</Form.Group>
<Form.Group controlId="bookSubTitle">
<Form.Label>Book Sub-Title</Form.Label>
<Form.Control
type="text"
value={subtitle}
onChange={(e) => setSubTitle(e.target.value)}
placeholder="Enter Sub title"
/>
</Form.Group>
<Form.Group controlId="bookAuthor">
<Form.Label>Author</Form.Label>
<Form.Control
type="text"
value={author}
onChange={(e) => setAuthor(e.target.value)}
placeholder="Enter an Author"
/>
</Form.Group>
<Form.Group controlId="bookDescription">
<Form.Label>Description</Form.Label>
<Form.Control
type="text"
value={description}
onChange={(e) => setDescription(e.target.value)}
placeholder="Enter Description"
/>
</Form.Group>
<Form.Group controlId="bookISBN">
<Form.Label>ISBN Number</Form.Label>
<Form.Control
type="text"
value={isbn}
onChange={(e) => setISBN(e.target.value)}
placeholder="Enter ISBN Number"
/>
</Form.Group>
<Button
variant="warning"
type="submit"
onClick={createBookHandler}
size="lg"
block
>
<i className="fas fa-plus"></i> Create Book
</Button>
</Form>
</Col>
</Row>
<Row>
<Col className="p-5">
<h1>The Books in My Library </h1>
</Col>
</Row>
{loading ? (
<Loader />
) : error ? (
<Message variant="danger">{error}</Message>
) : (
<>
<Row>
{books.map((book) => (
<Col key={book._id} sm={12} md={6} lg={4}>
<Book book={book} deleteHandler={deleteHandler} />
</Col>
))}
</Row>
</>
)}
</>
);
}
Example #18
Source File: index.js From ActiveLearningStudio-react-client with GNU Affero General Public License v3.0 | 4 votes |
function ExistingActivitySearch(props) {
const { fromTeam, addActivity, libraries } = props;
const [toggleStates, setToggleStates] = useState({
searchLibrary: true,
subject: true,
education: false,
type: false,
});
const allState = useSelector((state) => state.search);
const activityTypesState = useSelector((state) => state.resource.types);
const { currentOrganization, permission } = useSelector((state) => state.organization);
const dispatch = useDispatch();
const [activityTypes, setActivityTypes] = useState([]);
const [search, setSearch] = useState([]);
const [searchQueries, SetSearchQuery] = useState('');
const [searchInput, setSearchInput] = useState('');
const [meta, setMeta] = useState({});
const [activePage, setActivePage] = useState(1);
const [totalCount, setTotalCount] = useState(0);
const [activeModel, setActiveModel] = useState('activities');
const [activeType, setActiveType] = useState([]);
const [activeSubject, setActiveSubject] = useState([]);
const [activeEducation, setActiveEducation] = useState([]);
const [searchType, setSearchType] = useState(null);
const [authorName, SetAuthor] = useState('');
const [activetab, setActiveTab] = useState('activities');
const [todate, Settodate] = useState(undefined);
const [fromdate, Setfromdate] = useState(undefined);
useEffect(() => {
if (localStorage.getItem('refreshPage') === 'true' && currentOrganization && searchType) {
let dataSend;
if (searchType === 'orgSearch') {
dataSend = {
phrase: searchInput.trim(),
subjectArray: activeSubject,
gradeArray: activeEducation,
standardArray: activeType,
author: authorName || undefined,
type: searchType,
from: 0,
size: 20,
model: 'activities',
standardArray: libraries,
};
} else {
dataSend = {
phrase: searchInput.trim(),
subjectArray: activeSubject,
gradeArray: activeEducation,
standardArray: activeType,
author: authorName || undefined,
type: searchType,
from: 0,
size: 20,
model: 'activities',
standardArray: libraries,
};
}
let result;
(async () => {
result = await dispatch(simpleSearchAction(dataSend));
})();
setTotalCount(result?.meta?.total);
const tempEducation = [];
const tempSubject = [];
if (activeEducation) {
activeEducation.forEach((edu) => {
if (String(edu).includes('&')) {
const temp = String(edu).replace('&', 'and');
tempEducation.push(temp);
} else {
tempEducation.push(edu);
}
});
setActiveEducation(tempEducation);
}
if (activeSubject) {
activeSubject.forEach((sub) => {
if (String(sub).includes('&')) {
const temp = String(sub).replace('&', 'and');
tempSubject.push(temp);
} else {
tempSubject.push(sub);
}
});
setActiveSubject(tempSubject);
}
}
}, [currentOrganization]);
useEffect(() => {
if (allState.searchResult) {
if (allState.searchResult.length > 0) {
setSearch(allState.searchResult);
SetSearchQuery(allState.searchQuery);
setSearchInput(allState.searchQuery);
setMeta(allState.searchMeta);
localStorage.setItem('loading', 'false');
Swal.close();
} else if (allState.searchMeta.total === 0) {
setSearch([]);
SetSearchQuery(allState.searchQuery);
setSearchInput(allState.searchQuery);
setMeta({});
localStorage.setItem('loading', 'false');
Swal.close();
}
}
}, [allState.searchMeta, allState.searchQuery, allState.searchResult]);
useEffect(() => {
if (allState.searchResult) {
if (allState.searchResult.length > 0 && paginationStarter) {
paginationStarter = false;
setTotalCount(allState.searchMeta.total);
}
}
}, [allState.searchMeta, allState.searchResult, totalCount]);
useEffect(() => {
if (localStorage.getItem('loading') === 'true') {
Swal.fire({
html: 'Searching...', // add html attribute if you want or remove
allowOutsideClick: false,
onBeforeOpen: () => {
Swal.showLoading();
},
});
}
});
useEffect(() => {
if (activityTypesState.length === 0) {
dispatch(loadResourceTypesAction());
}
}, []);
const compare = (a, b) => {
// Use toUpperCase() to ignore character casing
const bandA = a.title.toUpperCase();
const bandB = b.title.toUpperCase();
let comparison = 0;
if (bandA > bandB) {
comparison = 1;
} else if (bandA < bandB) {
comparison = -1;
}
return comparison;
};
useEffect(() => {
const allItems = [];
activityTypesState?.data?.map((data) => data.activityItems.map((itm) => allItems.push(itm)));
setActivityTypes(allItems.sort(compare));
}, [activityTypesState]);
return (
<>
<div>
<div className={!fromTeam && 'search-wrapper'}>
<div className="content-search">
{true ? (
<div className="search-result-main">
{!fromTeam && <div className="current-org-search">{currentOrganization?.name}</div>}
{!fromTeam && <div className="exp-lib-cnt">Explore library content</div>}
<div
className="total-count"
style={{
display: totalCount > 1000 || !!searchQueries ? 'block' : 'none',
}}
>
{totalCount > 10000 ? (
<div>
Your search returned more than <span>10,000</span> results. Please refine your search criteria.
</div>
) : null}
{!!searchQueries && (
<div>
Showing {search ? meta.total : '0'} results For <span>{searchQueries}</span>
</div>
)}
</div>
<div className="main-content-search">
<div className="left-search">
<div className="search-library">
<Accordion defaultActiveKey="0">
<Card>
<Accordion.Toggle
as={Card.Header}
eventKey="0"
onClick={() =>
setToggleStates({
...toggleStates,
searchLibrary: !toggleStates.searchLibrary,
})
}
>
Search Library
<FontAwesomeIcon className="ml-2" icon={toggleStates.searchLibrary ? 'chevron-up' : 'chevron-down'} />
</Accordion.Toggle>
<Accordion.Collapse eventKey="0">
<Card.Body>
<div className="body-search">
<input
// style={{ display: searchType === 'orgSearch' ? 'none' : 'block' }}
value={searchInput}
onChange={(e) => {
setSearchInput(e.target.value);
}}
onKeyPress={async (e) => {
if (e.key === 'Enter') {
if (!searchInput.trim() && searchType !== 'orgSearch') {
Swal.fire('Search field is required.');
} else if (searchInput.length > 255) {
Swal.fire('Character limit should be less than 255.');
} else {
Swal.fire({
title: 'Searching...', // add html attribute if you want or remove
html: 'We are fetching results for you!',
allowOutsideClick: false,
onBeforeOpen: () => {
Swal.showLoading();
},
});
let dataSend;
if (searchType === 'orgSearch') {
dataSend = {
phrase: searchInput.trim(),
subjectArray: activeSubject,
gradeArray: activeEducation,
authors: authorName || undefined,
standardArray: activeType,
type: searchType,
from: 0,
size: 20,
model: 'activities',
standardArray: libraries,
};
} else {
dataSend = {
phrase: searchInput.trim(),
subjectArray: activeSubject,
gradeArray: activeEducation,
authors: authorName || undefined,
standardArray: activeType,
type: searchType,
from: 0,
size: 20,
model: 'activities',
standardArray: libraries,
};
}
const result = await dispatch(simpleSearchAction(dataSend));
setTotalCount(result.meta?.total);
const tempEducation = [];
const tempSubject = [];
if (activeEducation) {
activeEducation.forEach((edu) => {
if (String(edu).includes('&')) {
const temp = String(edu).replace('&', 'and');
tempEducation.push(temp);
} else {
tempEducation.push(edu);
}
});
setActiveEducation(tempEducation);
}
if (activeSubject) {
activeSubject.forEach((sub) => {
if (String(sub).includes('&')) {
const temp = String(sub).replace('&', 'and');
tempSubject.push(temp);
} else {
tempSubject.push(sub);
}
});
setActiveSubject(tempSubject);
}
}
}
}}
type="search"
placeholder="Search"
/>
<div className="form-group">
<div className="radio-btns">
{true && (
<label>
<input
name="type"
onChange={(e) => {
setSearchType(e.target.value);
}}
value="private"
checked={searchType === 'private'}
type="radio"
/>
<span>My Projects</span>
</label>
)}
{true && (
<label>
<input
name="type"
onChange={(e) => {
setSearchType(e.target.value);
}}
value="public"
checked={searchType === 'public'}
type="radio"
/>
<span>All Shared Projects</span>
</label>
)}
{true && (
<label>
<input
name="type"
onChange={(e) => {
setSearchType(e.target.value);
}}
value="orgSearch"
checked={searchType === 'orgSearch'}
type="radio"
/>
<span>All Shared Projects In My Org</span>
</label>
)}
</div>
</div>
{permission?.Organization?.includes('organization:view-user') && searchType !== 'private' && <div className="author-label">Author</div>}
<div
className="form-group"
style={{
display: permission?.Organization?.includes('organization:view-user') && searchType !== 'private' ? 'block' : 'none',
}}
>
<input
placeholder="Enter author name"
className="authorName"
value={authorName}
onChange={({ target }) => {
if (target.value) {
SetAuthor(target.value);
} else {
SetAuthor('');
}
}}
/>
</div>
<div
className="src-btn"
onClick={async () => {
Setfromdate(undefined);
Settodate(undefined);
setActiveTab('activities');
if (!searchInput.trim() && searchType !== 'orgSearch') {
Swal.fire('Search field is required.');
} else if (searchInput.length > 255) {
Swal.fire('Character limit should be less than 255.');
} else if (!searchType) {
Swal.fire('Search type is required. Click one of the radio buttons.');
} else {
Swal.fire({
title: 'Searching...', // add html attribute if you want or remove
html: 'We are fetching results for you!',
allowOutsideClick: false,
onBeforeOpen: () => {
Swal.showLoading();
},
});
let dataSend;
if (searchType === 'orgSearch') {
dataSend = {
phrase: searchInput.trim(),
subjectArray: activeSubject,
gradeArray: activeEducation,
standardArray: activeType,
author: authorName || undefined,
fromDate: fromdate || undefined,
toDate: todate || undefined,
type: searchType,
from: 0,
size: 20,
model: 'activities',
standardArray: libraries,
};
} else {
dataSend = {
phrase: searchInput.trim(),
subjectArray: activeSubject,
author: authorName || undefined,
fromDate: fromdate || undefined,
toDate: todate || undefined,
gradeArray: activeEducation,
standardArray: activeType,
type: searchType,
from: 0,
size: 20,
model: 'activities',
standardArray: libraries,
};
}
const result = await dispatch(simpleSearchAction(dataSend));
setTotalCount(result.meta?.total);
const tempEducation = [];
const tempSubject = [];
if (activeEducation) {
activeEducation.forEach((edu) => {
if (String(edu).includes('&')) {
const temp = String(edu).replace('&', 'and');
tempEducation.push(temp);
} else {
tempEducation.push(edu);
}
});
setActiveEducation(tempEducation);
}
if (activeSubject) {
activeSubject.forEach((sub) => {
if (String(sub).includes('&')) {
const temp = String(sub).replace('&', 'and');
tempSubject.push(temp);
} else {
tempSubject.push(sub);
}
});
setActiveSubject(tempSubject);
}
}
}}
>
<FontAwesomeIcon icon="search" />
Search
</div>
</div>
</Card.Body>
</Accordion.Collapse>
</Card>
</Accordion>
</div>
<div className="refine-search">
<div className="headline">Refine your search</div>
<Accordion defaultActiveKey="0">
<Card>
<Accordion.Toggle
as={Card.Header}
eventKey="0"
onClick={() =>
setToggleStates({
...toggleStates,
type: false,
education: false,
subject: !toggleStates.subject,
})
}
>
Subject
<FontAwesomeIcon className="ml-2" icon={toggleStates.subject ? 'chevron-up' : 'chevron-down'} />
</Accordion.Toggle>
<Accordion.Collapse eventKey="0">
<Card.Body>
{subjects.map((data) => (
<div
className="list-item-keys"
key={data.value}
value={data.subject}
onClick={() => {
if (activeSubject.includes(data.subject)) {
if (data.subject === 'Career & Technical Education') {
setActiveSubject(
activeSubject.filter((index) => {
if (index === 'Career & Technical Education' || index === 'Career and Technical Education') {
return false;
}
return true;
})
);
} else {
setActiveSubject(activeSubject.filter((index) => index !== data.subject));
}
} else {
setActiveSubject([...activeSubject, data.subject]);
}
}}
>
{data.subject === 'Career & Technical Education' ? (
activeSubject.includes('Career & Technical Education') || activeSubject.includes('Career and Technical Education') ? (
<FontAwesomeIcon icon="check-square" />
) : (
<FontAwesomeIcon icon="square" />
)
) : activeSubject.includes(data.subject) ? (
<FontAwesomeIcon icon="check-square" />
) : (
<FontAwesomeIcon icon="square" />
)}
<span>{data.subject}</span>
</div>
))}
</Card.Body>
</Accordion.Collapse>
</Card>
<Card>
<Accordion.Toggle
as={Card.Header}
eventKey="1"
onClick={() =>
setToggleStates({
...toggleStates,
type: false,
subject: false,
education: !toggleStates.education,
})
}
>
Education Level
<FontAwesomeIcon className="ml-2" icon={toggleStates.education ? 'chevron-up' : 'chevron-down'} />
</Accordion.Toggle>
<Accordion.Collapse eventKey="1">
<Card.Body>
{educationLevels.map((data) => (
<div
className="list-item-keys"
key={data.value}
value={data.name}
onClick={() => {
if (activeEducation.includes(data.name)) {
if (data.name === 'College & Beyond') {
setActiveEducation(
activeEducation.filter((index) => {
if (index === 'College & Beyond' || index === 'College and Beyond') {
return false;
}
return true;
})
);
} else {
setActiveEducation(activeEducation.filter((index) => index !== data.name));
}
} else {
setActiveEducation([...activeEducation, data.name]);
}
}}
>
{data.name === 'College & Beyond' ? (
activeEducation.includes('College & Beyond') || activeEducation.includes('College and Beyond') ? (
<FontAwesomeIcon icon="check-square" />
) : (
<FontAwesomeIcon icon="square" />
)
) : activeEducation.includes(data.name) ? (
<FontAwesomeIcon icon="check-square" />
) : (
<FontAwesomeIcon icon="square" />
)}
<span>{data.name}</span>
</div>
))}
</Card.Body>
</Accordion.Collapse>
</Card>
<Card>
<Accordion.Toggle
as={Card.Header}
eventKey="3"
onClick={() =>
setToggleStates({
...toggleStates,
subject: false,
education: false,
type: !toggleStates.type,
})
}
>
Type of Activity
<FontAwesomeIcon className="ml-2" icon={toggleStates.type ? 'chevron-up' : 'chevron-down'} />
</Accordion.Toggle>
<Accordion.Collapse eventKey="3">
<Card.Body
style={{
'max-height': '300px',
'overflow-y': 'auto',
}}
>
{activityTypes.map((data) => (
<div
className="list-item-keys"
key={data.id}
value={data.h5pLib}
onClick={() => {
if (activeType.includes(data.h5pLib)) {
// eslint-disable-next-line eqeqeq
setActiveType(activeType.filter((index) => index != data.h5pLib));
} else {
setActiveType([...activeType, data.h5pLib]);
}
}}
>
{activeType.includes(data.h5pLib) ? <FontAwesomeIcon icon="check-square" /> : <FontAwesomeIcon icon="square" />}
<span>{data.title}</span>
</div>
))}
</Card.Body>
</Accordion.Collapse>
</Card>
</Accordion>
</div>
</div>
<div className="right-search" id="right-search-branding-style">
<Tabs
activeKey={activetab}
id="uncontrolled-tab-example"
onSelect={async (e) => {
if (!searchInput && searchType !== 'orgSearch') {
Swal.fire('Search field is required.');
} else {
setActiveTab(e);
if (e === 'total') {
let searchData;
if (searchType === 'orgSearch') {
searchData = {
phrase: searchQueries.trim() || searchInput,
from: 0,
size: 20,
type: searchType,
author: authorName || undefined,
fromDate: fromdate || undefined,
toDate: todate || undefined,
subjectArray: activeSubject,
gradeArray: activeEducation,
standardArray: activeType,
};
} else {
searchData = {
phrase: searchQueries.trim() || searchInput,
from: 0,
size: 20,
author: authorName || undefined,
fromDate: fromdate || undefined,
toDate: todate || undefined,
type: searchType,
subjectArray: activeSubject,
gradeArray: activeEducation,
standardArray: activeType,
};
}
Swal.fire({
title: 'Loading...', // add html attribute if you want or remove
allowOutsideClick: false,
onBeforeOpen: () => {
Swal.showLoading();
},
});
const resultModel = await dispatch(simpleSearchAction(searchData));
Swal.close();
setTotalCount(resultModel.meta[e]);
setActiveModel(e);
setActivePage(1);
} else {
let searchData;
if (searchType === 'orgSearch') {
searchData = {
phrase: searchQueries.trim() || searchInput,
from: 0,
size: 20,
author: authorName || undefined,
fromDate: fromdate || undefined,
toDate: todate || undefined,
model: e,
type: searchType,
subjectArray: activeSubject,
gradeArray: activeEducation,
standardArray: activeType,
standardArray: libraries,
};
} else {
searchData = {
phrase: searchQueries.trim() || searchInput,
from: 0,
size: 20,
model: e,
author: authorName || undefined,
fromDate: fromdate || undefined,
toDate: todate || undefined,
type: searchType,
subjectArray: activeSubject,
gradeArray: activeEducation,
standardArray: activeType,
standardArray: libraries,
};
}
Swal.fire({
title: 'Loading...', // add html attribute if you want or remove
allowOutsideClick: false,
onBeforeOpen: () => {
Swal.showLoading();
},
});
const resultModel = await dispatch(simpleSearchAction(searchData));
Swal.close();
setTotalCount(resultModel.meta[e]);
setActiveModel(e);
setActivePage(1);
}
}
}}
>
{!fromTeam && (
<Tab eventKey="activities" title={!!search && !!meta.activities ? `activity (${meta.activities})` : 'activity (0)'}>
<div className="content">
<div className="results_search">
{!!search && search.length > 0 ? (
search.map((res) => (
<>
{res.model === 'Activity' && (
<div className="box">
<div className="imgbox">
{res.thumb_url ? (
<div
style={{
backgroundImage: res.thumb_url.includes('pexels.com')
? `url(${res.thumb_url})`
: `url(${global.config.resourceUrl}${res.thumb_url})`,
}}
/>
) : (
<div
style={{
// eslint-disable-next-line max-len
backgroundImage:
'https://images.pexels.com/photos/593158/pexels-photo-593158.jpeg?auto=compress&cs=tinysrgb&dpr=1&fit=crop&h=200&w=280',
}}
/>
)}
</div>
<div className="contentbox">
<div className="search-content">
<a
href={
res.model === 'Activity'
? `/activity/${res.id}/preview`
: res.model === 'Playlist'
? `/playlist/${res.id}/preview/lti`
: `/project/${res.id}/preview`
}
target="_blank"
rel="noreferrer"
>
<h2>{res.title || res.name}</h2>
</a>
<ul>
{res.user && (
<li>
by <span>{res.user.first_name}</span>
</li>
)}
<li>
Type <span className="type">{res.model}</span>
</li>
</ul>
<p>{res.description}</p>
</div>
<Buttons text="Add" secondary={true} width="153px" height="36px" onClick={() => addActivity(res)} hover={true} />
</div>
</div>
)}
</>
))
) : (
<div className="box">No result found !</div>
)}
</div>
</div>
</Tab>
)}
</Tabs>
{totalCount > 20 && (
<Pagination
activePage={activePage}
itemsCountPerPage={20}
totalItemsCount={totalCount > 10000 ? 10000 : totalCount}
pageRangeDisplayed={8}
onChange={async (e) => {
setActivePage(e);
if (activeModel === 'total') {
const searchData = {
phrase: searchQueries.trim(),
from: e * 20 - 20,
size: 20,
type: searchType,
subjectArray: activeSubject || undefined,
gradeArray: activeEducation || undefined,
standardArray: activeType || undefined,
author: authorName || undefined,
};
Swal.fire({
title: 'Loading...',
allowOutsideClick: false,
onBeforeOpen: () => {
Swal.showLoading();
},
});
await dispatch(simpleSearchAction(searchData));
Swal.close();
} else {
const searchData = {
phrase: searchQueries.trim(),
from: e * 20 - 20,
size: 20,
type: searchType,
model: activeModel,
subjectArray: activeSubject || undefined,
gradeArray: activeEducation || undefined,
standardArray: activeType || undefined,
author: authorName || undefined,
standardArray: libraries,
};
Swal.fire({
title: 'Loading...',
allowOutsideClick: false,
onBeforeOpen: () => {
Swal.showLoading();
},
});
await dispatch(simpleSearchAction(searchData));
Swal.close();
}
}}
itemClass="page-item"
linkClass="page-link"
/>
)}
</div>
</div>
</div>
) : (
<Alert variant="danger">You are not authorized to view this page!</Alert>
)}
</div>
</div>
</div>
</>
);
}