@diagramers/admin
Version:
Diagramers Admin Template - React starter for admin dashboards.
177 lines (161 loc) • 6.67 kB
JavaScript
import React, { useEffect, useState } from 'react';
import { Row, Col, Button } from 'react-bootstrap';
import { useSelector, useDispatch } from 'react-redux';
import { useWindowSize } from 'hooks/useWindowSize';
import Fuse from 'fuse.js';
import HtmlHead from 'components/html-head/HtmlHead';
import BreadcrumbList from 'components/breadcrumb-list/BreadcrumbList';
import CsLineIcons from 'cs-line-icons/CsLineIcons';
import AddEditModal from './components/AddEditModal';
import MenuModal from './components/MenuModal';
import TaskListItem from './components/TaskListItem';
import MenuContent from './components/MenuContent';
import SearchInput from './components/SearchInput';
import { getTasks, setSelectedTask } from './tasksSlice';
const TasksApp = () => {
const title = 'Tasks';
const description = 'Implementation for a basic events and schedule application that built on top of Full Calendar plugin.';
const breadcrumbs = [
{ to: '', text: 'Home' },
{ to: 'apps', title: 'Apps' },
];
const dispatch = useDispatch();
const { tasks, showSettings, loading } = useSelector((state) => state.tasks);
const { themeValues } = useSelector((state) => state.settings);
const lgBreakpoint = parseInt(themeValues.lg.replace('px', ''), 10);
const { width } = useWindowSize();
const [listingItems, setListingItems] = useState(tasks);
const [filteredMailbox, setFilteredMailbox] = useState([]);
const [isLgScreen, setIsLgScreen] = useState(false);
const [isOpenMenuModal, setIsOpenMenuModal] = useState(false);
const [isOpenNewTask, setIsOpenNewTask] = useState(false);
useEffect(() => {
if (width) {
if (width >= lgBreakpoint) {
if (!isLgScreen) setIsLgScreen(true);
if (isOpenMenuModal) setIsOpenMenuModal(false);
} else if (isLgScreen) setIsLgScreen(false);
}
return () => {};
// eslint-disable-next-line
}, [width]);
useEffect(() => {
dispatch(getTasks());
return () => {};
// eslint-disable-next-line
}, []);
useEffect(() => {
setListingItems(tasks);
return () => {};
}, [tasks]);
const escapeRegexCharacters = (str) => {
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
};
const onChangeSearchTerm = (value) => {
if (value === '') {
setListingItems(filteredMailbox);
} else {
const escapedValue = escapeRegexCharacters(value.trim());
const fuse = new Fuse(filteredMailbox, {
includeScore: true,
keys: ['title', 'from', 'detail'],
threshold: 0.4,
});
const results = fuse.search(escapedValue).map((result) => {
return result.item;
});
setListingItems(results);
}
};
useEffect(() => {
if (tasks) {
const { deleted, status, tags } = showSettings;
let filteringMailbox = tasks;
filteringMailbox = filteringMailbox.filter((x) => x.deleted === deleted);
if (status !== 'All') filteringMailbox = filteringMailbox.filter((x) => x.status === status);
if (tags !== 'All') filteringMailbox = filteringMailbox.filter((x) => x.tags.find((y) => y.title === tags));
setFilteredMailbox(filteringMailbox);
setListingItems(filteringMailbox);
}
return () => {};
}, [tasks, showSettings]);
const onClickNewTask = () => {
setIsOpenNewTask(true);
dispatch(setSelectedTask(null));
};
const onEditClick = (task) => {
setIsOpenNewTask(true);
dispatch(setSelectedTask(task));
};
return (
<>
<HtmlHead title={title} description={description} />
{!loading && (
<>
<div className="page-title-container">
<Row className="g-0">
<Col xs="auto" className="mb-2 mb-md-0 me-auto">
<div className="w-auto sw-md-25">
<h1 className="mb-0 pb-0 display-4">{title}</h1>
<BreadcrumbList items={breadcrumbs} />
</div>
</Col>
<Col xs="auto" className="d-flex d-lg-none align-items-start mb-2 mb-md-0 order-md-1">
<Button variant="primary" className="btn-icon btn-icon-only ms-1" onClick={() => setIsOpenMenuModal(true)}>
<CsLineIcons icon="menu-left" />
</Button>
</Col>
<Col xs="12" md className="d-flex align-items-start justify-content-end justify-content-lg-start">
<div className="me-lg-auto w-100 w-md-auto search-input-container border border-separator">
<SearchInput onChange={onChangeSearchTerm} />
</div>
<Button variant="outline-primary" className="btn-icon btn-icon-start ms-1" onClick={onClickNewTask}>
<CsLineIcons icon="plus" /> <span>New Task</span>
</Button>
</Col>
</Row>
</div>
<Row className="row g-0">
{isLgScreen && (
<Col xs="auto" className="d-lg-flex">
<div className="nav flex-column sw-25 mt-n2">
<MenuContent />
</div>
</Col>
)}
<Col>
{/* List Items Start */}
<Row className="g-2 row-cols-1 row-cols-lg-2 row-cols-xl-3" id="tasksContainer">
{listingItems &&
listingItems.map((task, tIndex) => {
return <TaskListItem key={`task.${tIndex}`} task={task} onEditClick={onEditClick} />;
})}
{/* Tag Item Template Start */}
<template id="taskTagTemplate">
<span className="badge opacity-75 text-decoration-none me-1" />
</template>
{/* Tag Item Template End */}
{/* No Task Template Start */}
<template id="noTasksFound">
<Col xs="12" className="small-gutter-col mb-2 flex-grow-1 mw-100">
<div className="h-100">
<div className="text-center">
<i className="cs-warning-hexagon text-primary" />
<p className="mb-0">No tasks found!</p>
</div>
</div>
</Col>
</template>
{/* No Task Template End */}
</Row>
{/* List Items End */}
</Col>
</Row>
{isLgScreen === false && <MenuModal show={isOpenMenuModal} onHide={() => setIsOpenMenuModal(false)} />}
{isOpenNewTask && <AddEditModal show={isOpenNewTask} onHide={() => setIsOpenNewTask(false)} />}
</>
)}
</>
);
};
export default TasksApp;