add dashboard
This commit is contained in:
parent
988fb33b09
commit
07c4421987
@ -10,11 +10,15 @@
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@heroicons/react": "v1",
|
||||
"@reduxjs/toolkit": "^1.9.5",
|
||||
"moment": "^2.29.4",
|
||||
"react": "^18.2.0",
|
||||
"react-charts": "^3.0.0-beta.55",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-redux": "^8.1.2",
|
||||
"react-router-dom": "^6.15.0",
|
||||
"react-table": "^7.8.0",
|
||||
"redux-persist": "^6.0.0",
|
||||
"redux-thunk": "^2.4.2",
|
||||
"validator": "^13.11.0"
|
||||
|
24
src/App.jsx
24
src/App.jsx
@ -1,18 +1,36 @@
|
||||
import { RouterProvider, createBrowserRouter } from 'react-router-dom';
|
||||
import { Route, Routes, createBrowserRouter, useNavigate } from 'react-router-dom';
|
||||
import 'regenerator-runtime/runtime';
|
||||
import routes from './routes';
|
||||
import { Provider } from 'react-redux';
|
||||
import { PersistGate } from 'redux-persist/integration/react';
|
||||
import { persistore, store } from './stores/configureStore';
|
||||
import { Login } from './pages';
|
||||
import { DefaultLayout } from './layouts';
|
||||
|
||||
const router = createBrowserRouter(routes)
|
||||
// const router = createBrowserRouter(routes)
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<>
|
||||
<Provider store={store}>
|
||||
<PersistGate persistor={persistore}>
|
||||
<RouterProvider router={router} />
|
||||
<Routes>
|
||||
<Route index element={<Login />} />
|
||||
<Route element={<DefaultLayout />}>
|
||||
{routes.map(({ path, name, element}) => (
|
||||
<>
|
||||
<Route
|
||||
path={path}
|
||||
id={name}
|
||||
element={element}
|
||||
/>
|
||||
</>
|
||||
))}
|
||||
</Route>
|
||||
</Routes>
|
||||
</PersistGate>
|
||||
</Provider>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
5
src/actions/AuthAction.js
Normal file
5
src/actions/AuthAction.js
Normal file
@ -0,0 +1,5 @@
|
||||
import { LOGOUT } from "../constants/action_type";
|
||||
|
||||
export const logout = () => ({
|
||||
type: LOGOUT
|
||||
});
|
1
src/actions/index.js
Normal file
1
src/actions/index.js
Normal file
@ -0,0 +1 @@
|
||||
export * from './AuthAction';
|
18
src/components/Button/Pagination/DefaultButton/index.jsx
Normal file
18
src/components/Button/Pagination/DefaultButton/index.jsx
Normal file
@ -0,0 +1,18 @@
|
||||
import { classNames } from "../../../../utils";
|
||||
|
||||
const PaginationDefaultButton = ({ children, className, ...rest }) => {
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className={classNames(
|
||||
"relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50",
|
||||
className
|
||||
)}
|
||||
{...rest}
|
||||
>
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
export default PaginationDefaultButton;
|
18
src/components/Button/Pagination/PageButton/index.jsx
Normal file
18
src/components/Button/Pagination/PageButton/index.jsx
Normal file
@ -0,0 +1,18 @@
|
||||
import { classNames } from "../../../../utils";
|
||||
|
||||
const PaginationPageButton = ({ children, className, ...rest }) => {
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className={classNames(
|
||||
"relative inline-flex items-center px-2 py-2 border border-gray-300 bg-white text-sm font-medium text-gray-500 hover:bg-gray-50",
|
||||
className
|
||||
)}
|
||||
{...rest}
|
||||
>
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
export default PaginationPageButton;
|
240
src/components/ChartConfig/index.tsx
Normal file
240
src/components/ChartConfig/index.tsx
Normal file
@ -0,0 +1,240 @@
|
||||
import React from "react";
|
||||
|
||||
//
|
||||
|
||||
const options = {
|
||||
elementType: ["line", "area", "bar"],
|
||||
primaryAxisType: ["linear", "time", "log", "band"],
|
||||
secondaryAxisType: ["linear", "time", "log", "band"],
|
||||
primaryAxisPosition: ["top", "left", "right", "bottom"],
|
||||
secondaryAxisPosition: ["top", "left", "right", "bottom"],
|
||||
secondaryAxisStack: [true, false],
|
||||
primaryAxisShow: [true, false],
|
||||
secondaryAxisShow: [true, false],
|
||||
interactionMode: ["primary", "closest"],
|
||||
tooltipGroupingMode: ["single", "primary", "secondary", "series"],
|
||||
tooltipAnchor: [
|
||||
"closest",
|
||||
"top",
|
||||
"bottom",
|
||||
"left",
|
||||
"right",
|
||||
"center",
|
||||
"gridTop",
|
||||
"gridBottom",
|
||||
"gridLeft",
|
||||
"gridRight",
|
||||
"gridCenter",
|
||||
"pointer",
|
||||
],
|
||||
tooltipAlign: [
|
||||
"auto",
|
||||
"top",
|
||||
"bottom",
|
||||
"left",
|
||||
"right",
|
||||
"topLeft",
|
||||
"topRight",
|
||||
"bottomLeft",
|
||||
"bottomRight",
|
||||
"center",
|
||||
],
|
||||
snapCursor: [true, false],
|
||||
} as const;
|
||||
|
||||
type DataType = "time" | "ordinal" | "linear";
|
||||
type ElementType = typeof options["elementType"][number];
|
||||
type PrimaryAxisType = typeof options["primaryAxisType"][number];
|
||||
type SecondaryAxisType = typeof options["secondaryAxisType"][number];
|
||||
type PrimaryAxisPosition = typeof options["primaryAxisPosition"][number];
|
||||
type SecondaryAxisPosition = typeof options["secondaryAxisPosition"][number];
|
||||
type TooltipAnchor = typeof options["tooltipAnchor"][number];
|
||||
type TooltipAlign = typeof options["tooltipAlign"][number];
|
||||
type InteractionMode = typeof options["interactionMode"][number];
|
||||
type TooltipGroupingMode = typeof options["tooltipGroupingMode"][number];
|
||||
|
||||
const optionKeys = Object.keys(options) as (keyof typeof options)[];
|
||||
|
||||
export default function useChartConfig({
|
||||
series,
|
||||
datums = 10,
|
||||
useR,
|
||||
show = [],
|
||||
count = 1,
|
||||
|
||||
resizable = true,
|
||||
canRandomize = true,
|
||||
dataType = "time",
|
||||
elementType = "line",
|
||||
primaryAxisType = "time",
|
||||
secondaryAxisType = "linear",
|
||||
primaryAxisPosition = "bottom",
|
||||
secondaryAxisPosition = "left",
|
||||
primaryAxisStack = false,
|
||||
secondaryAxisStack = true,
|
||||
primaryAxisShow = true,
|
||||
secondaryAxisShow = true,
|
||||
tooltipAnchor = "closest",
|
||||
tooltipAlign = "auto",
|
||||
interactionMode = "primary",
|
||||
tooltipGroupingMode = "primary",
|
||||
snapCursor = true,
|
||||
}: {
|
||||
series: number;
|
||||
datums?: number;
|
||||
useR?: boolean;
|
||||
show?: (keyof typeof options)[];
|
||||
count?: number;
|
||||
resizable?: boolean;
|
||||
canRandomize?: boolean;
|
||||
dataType?: DataType;
|
||||
elementType?: ElementType;
|
||||
primaryAxisType?: PrimaryAxisType;
|
||||
secondaryAxisType?: SecondaryAxisType;
|
||||
primaryAxisPosition?: PrimaryAxisPosition;
|
||||
secondaryAxisPosition?: SecondaryAxisPosition;
|
||||
primaryAxisStack?: boolean;
|
||||
secondaryAxisStack?: boolean;
|
||||
primaryAxisShow?: boolean;
|
||||
secondaryAxisShow?: boolean;
|
||||
tooltipAnchor?: TooltipAnchor;
|
||||
tooltipAlign?: TooltipAlign;
|
||||
interactionMode?: InteractionMode;
|
||||
tooltipGroupingMode?: TooltipGroupingMode;
|
||||
snapCursor?: boolean;
|
||||
}) {
|
||||
const [state, setState] = React.useState({
|
||||
count,
|
||||
resizable,
|
||||
canRandomize,
|
||||
dataType,
|
||||
elementType,
|
||||
primaryAxisType,
|
||||
secondaryAxisType,
|
||||
primaryAxisPosition,
|
||||
secondaryAxisPosition,
|
||||
primaryAxisStack,
|
||||
secondaryAxisStack,
|
||||
primaryAxisShow,
|
||||
secondaryAxisShow,
|
||||
tooltipAnchor,
|
||||
tooltipAlign,
|
||||
interactionMode,
|
||||
tooltipGroupingMode,
|
||||
snapCursor,
|
||||
datums,
|
||||
data: makeDataFrom(dataType, series, datums, useR),
|
||||
});
|
||||
|
||||
React.useEffect(() => {
|
||||
setState((old) => ({
|
||||
...old,
|
||||
data: makeDataFrom(dataType, series, datums, useR),
|
||||
}));
|
||||
}, [count, dataType, datums, series, useR]);
|
||||
|
||||
const Options = optionKeys
|
||||
.filter((option) => show.indexOf(option) > -1)
|
||||
.map((option) => (
|
||||
<div key={option}>
|
||||
{option}:
|
||||
<select
|
||||
value={state[option] as string}
|
||||
onChange={({ target: { value } }) =>
|
||||
setState((old) => ({
|
||||
...old,
|
||||
[option]:
|
||||
typeof options[option][0] === "boolean"
|
||||
? value === "true"
|
||||
: value,
|
||||
}))
|
||||
}
|
||||
>
|
||||
{options[option].map((d: any) => (
|
||||
<option value={d as string} key={d.toString()}>
|
||||
{d.toString()}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<br />
|
||||
</div>
|
||||
));
|
||||
|
||||
return {
|
||||
...state,
|
||||
Options,
|
||||
};
|
||||
}
|
||||
|
||||
function makeDataFrom(
|
||||
dataType: DataType,
|
||||
series: number,
|
||||
datums: number,
|
||||
useR?: boolean
|
||||
) {
|
||||
return [
|
||||
...new Array(series || Math.max(Math.round(Math.random() * 5), 1)),
|
||||
].map((d, i) => makeSeries(i, dataType, datums, useR));
|
||||
}
|
||||
|
||||
function makeSeries(
|
||||
i: number,
|
||||
dataType: DataType,
|
||||
datums: number,
|
||||
useR?: boolean
|
||||
) {
|
||||
const start = 0;
|
||||
const startDate = new Date();
|
||||
// startDate.setFullYear(2020);
|
||||
startDate.setUTCHours(0);
|
||||
startDate.setUTCMinutes(0);
|
||||
startDate.setUTCSeconds(0);
|
||||
startDate.setUTCMilliseconds(0);
|
||||
// const length = 5 + Math.round(Math.random() * 15)
|
||||
const length = datums;
|
||||
const min = 0;
|
||||
const max = 100;
|
||||
const rMin = 2;
|
||||
const rMax = 20;
|
||||
const nullChance = 0;
|
||||
return {
|
||||
label: `Series ${i + 1}`,
|
||||
data: [...new Array(length)].map((_, i) => {
|
||||
let x;
|
||||
|
||||
if (dataType === "ordinal") {
|
||||
x = `Ordinal Group ${start + i}`;
|
||||
} else if (dataType === "time") {
|
||||
x = new Date(startDate.getTime() + 60 * 1000 * 60 * 24 * i);
|
||||
} else if (dataType === "linear") {
|
||||
x =
|
||||
Math.random() < nullChance
|
||||
? null
|
||||
: min + Math.round(Math.random() * (max - min));
|
||||
} else {
|
||||
x = start + i;
|
||||
}
|
||||
|
||||
const distribution = 1.1;
|
||||
|
||||
const y =
|
||||
Math.random() < nullChance
|
||||
? null
|
||||
: min + Math.round(Math.random() * (max - min));
|
||||
|
||||
const r = !useR
|
||||
? undefined
|
||||
: rMax -
|
||||
Math.floor(
|
||||
Math.log(Math.random() * (distribution ** rMax - rMin) + rMin) /
|
||||
Math.log(distribution)
|
||||
);
|
||||
|
||||
return {
|
||||
primary: x,
|
||||
secondary: y,
|
||||
radius: r,
|
||||
};
|
||||
}),
|
||||
};
|
||||
}
|
8
src/components/DataTable/index.css
Normal file
8
src/components/DataTable/index.css
Normal file
@ -0,0 +1,8 @@
|
||||
table tr:nth-child(odd) td{
|
||||
background-color: #f5f6fa;
|
||||
}
|
||||
|
||||
.tab-filter:hover {
|
||||
border-bottom: 3px solid black;
|
||||
color: #055274 !important;
|
||||
}
|
236
src/components/DataTable/index.jsx
Normal file
236
src/components/DataTable/index.jsx
Normal file
@ -0,0 +1,236 @@
|
||||
import React, { useState } from "react";
|
||||
import {
|
||||
useAsyncDebounce,
|
||||
useTable,
|
||||
useGlobalFilter,
|
||||
useFilters,
|
||||
usePagination
|
||||
} from "react-table";
|
||||
import { ChevronDoubleLeftIcon, ChevronDoubleRightIcon, ChevronLeftIcon, ChevronRightIcon } from "@heroicons/react/solid";
|
||||
|
||||
import "./index.css";
|
||||
import PaginationDefaultButton from "../Button/Pagination/DefaultButton";
|
||||
import PaginationPageButton from "../Button/Pagination/PageButton";
|
||||
|
||||
|
||||
const DataTable = ({ columns, data, tabFilterData }) => {
|
||||
|
||||
const [selectedRole, setSelectedRole] = useState('All')
|
||||
|
||||
// Use the state and functions returned from useTable to build your UI
|
||||
const {
|
||||
getTableProps,
|
||||
getTableBodyProps,
|
||||
headerGroups,
|
||||
rows,
|
||||
|
||||
page, // Instead of using 'rows', we'll use page,
|
||||
// which has only the rows for the active page
|
||||
|
||||
// The rest of these things are super handy, too ;)
|
||||
canPreviousPage,
|
||||
canNextPage,
|
||||
pageOptions,
|
||||
pageCount,
|
||||
gotoPage,
|
||||
nextPage,
|
||||
previousPage,
|
||||
setPageSize,
|
||||
|
||||
|
||||
prepareRow,
|
||||
state,
|
||||
preGlobalFilteredRows,
|
||||
setGlobalFilter
|
||||
} =
|
||||
useTable({
|
||||
columns,
|
||||
data,
|
||||
},
|
||||
useGlobalFilter,
|
||||
usePagination
|
||||
);
|
||||
|
||||
let row_data = page;
|
||||
|
||||
if (selectedRole !== 'All') {
|
||||
row_data = page.filter(x => x.values.role_name === selectedRole || x.values.type === selectedRole);
|
||||
}
|
||||
|
||||
|
||||
// Render the UI for your table
|
||||
return (
|
||||
<>
|
||||
<GlobalFilter
|
||||
preGlobalFilteredRows={preGlobalFilteredRows}
|
||||
globalFilter={state.globalFilter}
|
||||
setGlobalFilter={setGlobalFilter}
|
||||
tabFilterData={tabFilterData}
|
||||
onSelectedTabFilter={(role_name) => setSelectedRole(role_name)}
|
||||
selectedRole={selectedRole}
|
||||
/>
|
||||
<div className="mt-2 flex flex-col">
|
||||
<div className="-my-2 overflow-x-auto -mx-4 sm:-mx-6 lg:-mx-8">
|
||||
<div className="py-2 align-middle inline-block min-w-full sm:px-6 lg:px-8">
|
||||
<div className="shadow overflow-hidden rounded">
|
||||
<table {...getTableProps()} className="min-w-full divide-y divide-gray">
|
||||
<thead className="bg-primary">
|
||||
{headerGroups.map((headerGroup) => (
|
||||
<tr style={{ padding: 10 }} {...headerGroup.getHeaderGroupProps()}>
|
||||
{headerGroup.headers.map((column) => (
|
||||
<th className="p-2" style={{ color: 'white', textAlign: 'left' }} {...column.getHeaderProps()}>{column.render("Header")}</th>
|
||||
))}
|
||||
<th style={{ color: 'white', textAlign: 'left', width: '5%' }}>Action</th>
|
||||
</tr>
|
||||
))}
|
||||
</thead>
|
||||
<tbody {...getTableBodyProps()}>
|
||||
{row_data.map((row, i) => {
|
||||
prepareRow(row);
|
||||
return (
|
||||
<tr {...row.getRowProps()}>
|
||||
{row.cells.map((cell) => {
|
||||
return (
|
||||
<td className="p-2"{...cell.getCellProps()}>
|
||||
{cell.column.id === 'rowNumber' ? i + 1 : cell.render('Cell')}
|
||||
</td>
|
||||
);
|
||||
})}
|
||||
<td className="flex flex-row py-3 gap-2 px-3">
|
||||
<button className="px-4 py-1 rounded" style={{ border: '1px solid black', fontSize: 14 }}>
|
||||
Edit
|
||||
</button>
|
||||
<button className='bg-red text-white px-4 py-1 rounded' style={{ fontSize: 14}}>
|
||||
Delete
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="py-3 flex items-center justify-between">
|
||||
<div className="flex-1 flex justify-between sm:hidden">
|
||||
<PaginationDefaultButton onClick={() => previousPage()} disabled={!canPreviousPage}>Previous</PaginationDefaultButton>
|
||||
<PaginationDefaultButton onClick={() => nextPage()} disabled={!canNextPage}>Next</PaginationDefaultButton>
|
||||
</div>
|
||||
<div className="hidden sm:flex-1 sm:flex sm:items-center sm:justify-between">
|
||||
<div className="flex gap-x-2 items-baseline">
|
||||
<span className="text-sm text-gray-700">
|
||||
Page <span className="font-medium">{state.pageIndex + 1}</span> of <span className="font-medium">{pageOptions.length}</span>
|
||||
</span>
|
||||
<label>
|
||||
<span className="sr-only">Items Per Page</span>
|
||||
<select
|
||||
className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50"
|
||||
value={state.pageSize}
|
||||
onChange={e => {
|
||||
setPageSize(Number(e.target.value))
|
||||
}}
|
||||
>
|
||||
{[5, 10, 20].map(pageSize => (
|
||||
<option key={pageSize} value={pageSize}>
|
||||
Show {pageSize}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<nav className="relative z-0 inline-flex rounded-md shadow-sm -space-x-px" aria-label="Pagination">
|
||||
<PaginationPageButton
|
||||
className="rounded-l-md"
|
||||
onClick={() => gotoPage(0)}
|
||||
disabled={!canPreviousPage}
|
||||
>
|
||||
<span className="sr-only">First</span>
|
||||
<ChevronDoubleLeftIcon className="h-5 w-5 text-gray-400" aria-hidden="true" />
|
||||
</PaginationPageButton>
|
||||
<PaginationPageButton
|
||||
onClick={() => previousPage()}
|
||||
disabled={!canPreviousPage}
|
||||
>
|
||||
<span className="sr-only">Previous</span>
|
||||
<ChevronLeftIcon className="h-5 w-5 text-gray-400" aria-hidden="true" />
|
||||
</PaginationPageButton>
|
||||
<PaginationPageButton
|
||||
onClick={() => nextPage()}
|
||||
disabled={!canNextPage
|
||||
}>
|
||||
<span className="sr-only">Next</span>
|
||||
<ChevronRightIcon className="h-5 w-5 text-gray-400" aria-hidden="true" />
|
||||
</PaginationPageButton>
|
||||
<PaginationPageButton
|
||||
className="rounded-r-md"
|
||||
onClick={() => gotoPage(pageCount - 1)}
|
||||
disabled={!canNextPage}
|
||||
>
|
||||
<span className="sr-only">Last</span>
|
||||
<ChevronDoubleRightIcon className="h-5 w-5 text-gray-400" aria-hidden="true" />
|
||||
</PaginationPageButton>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const GlobalFilter = ({
|
||||
globalFilter,
|
||||
setGlobalFilter,
|
||||
tabFilterData,
|
||||
onSelectedTabFilter,
|
||||
selectedRole
|
||||
}) => {
|
||||
const [value, setValue] = React.useState(globalFilter)
|
||||
const onChange = useAsyncDebounce(value => {
|
||||
setGlobalFilter(value || undefined)
|
||||
}, 200)
|
||||
|
||||
const tabsFilter = ['All', ...tabFilterData];
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="bg-gray p-3 mb-4">
|
||||
<div class="relative text-gray-600 focus-within:text-gray-400 flex flex-row">
|
||||
<span class="absolute inset-y-0 left-0 flex items-center pl-2">
|
||||
<button type="submit" class="p-1 focus:outline-none focus:shadow-outline">
|
||||
<svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24" class="w-4 h-4"><path d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path></svg>
|
||||
</button>
|
||||
</span>
|
||||
<input
|
||||
type="search"
|
||||
name="q"
|
||||
className="py-2 text-sm text-black bg-gray-900 rounded-md pl-10 focus:outline-none focus:bg-white focus:text-gray-900"
|
||||
style={{ width: '90% ' }}
|
||||
placeholder={`Enter Keyword ...`}
|
||||
value={value}
|
||||
onChange={e => {
|
||||
setValue(e.target.value);
|
||||
onChange(e.target.value)
|
||||
}}
|
||||
autocomplete="off"
|
||||
/>
|
||||
<button className='ml-4 bg-white rounded justify-center hover:bg-opacity-70 font-medium px-4 py-3 flex text-black' style={{ borderColor: 'black', borderWidth: 1 }}>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="mr-3" style={{ alignSelf: 'center' }} fill="black" height="18" viewBox="0 -960 960 960" width="18"><path d="M440-160q-17 0-28.5-11.5T400-200v-240L161-745q-14-17-4-36t31-19h584q21 0 31 19t-4 36L560-440v240q0 17-11.5 28.5T520-160h-80Zm40-276 240-304H240l240 304Zm0 0Z" /></svg>
|
||||
Filters
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex mb-4' style={{ borderBottomWidth: 1 }}>
|
||||
{tabsFilter.map((filter) => (
|
||||
<ul>
|
||||
<a onClick={() => onSelectedTabFilter(filter)} href='#' className='mr-4 tab-filter' style={selectedRole === filter ? { borderBottom: '3px solid black', color: '#055274' } : { color: '#7fa8b9' }}>{filter}</a>
|
||||
</ul>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default DataTable;
|
98
src/components/Header/index.jsx
Normal file
98
src/components/Header/index.jsx
Normal file
@ -0,0 +1,98 @@
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { logout } from '../../actions';
|
||||
|
||||
const Header = (props) => {
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const handleLogoutClick = () => {
|
||||
dispatch(logout())
|
||||
navigate("/")
|
||||
}
|
||||
|
||||
return (
|
||||
<header className="sticky top-0 z-999 flex w-full bg-white drop-shadow-1 dark:bg-boxdark dark:drop-shadow-none">
|
||||
<div className="flex flex-grow items-center py-4 px-4 shadow-2 md:px-6 2xl:px-11">
|
||||
<div className="flex items-center gap-2 sm:gap-4 lg:hidden">
|
||||
{/* <!-- Hamburger Toggle BTN --> */}
|
||||
<button
|
||||
aria-controls="sidebar"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
props.setSidebarOpen(!props.sidebarOpen);
|
||||
}}
|
||||
className="z-99999 block rounded-sm border border-stroke bg-white p-1.5 shadow-sm dark:border-strokedark dark:bg-boxdark lg:hidden"
|
||||
>
|
||||
<span className="relative block h-5.5 w-5.5 cursor-pointer">
|
||||
<span className="du-block absolute right-0 h-full w-full">
|
||||
<span
|
||||
className={`relative top-0 left-0 my-1 block h-0.5 w-0 rounded-sm bg-black delay-[0] duration-200 ease-in-out dark:bg-white ${
|
||||
!props.sidebarOpen && '!w-full delay-300'
|
||||
}`}
|
||||
></span>
|
||||
<span
|
||||
className={`relative top-0 left-0 my-1 block h-0.5 w-0 rounded-sm bg-black delay-150 duration-200 ease-in-out dark:bg-white ${
|
||||
!props.sidebarOpen && 'delay-400 !w-full'
|
||||
}`}
|
||||
></span>
|
||||
<span
|
||||
className={`relative top-0 left-0 my-1 block h-0.5 w-0 rounded-sm bg-black delay-200 duration-200 ease-in-out dark:bg-white ${
|
||||
!props.sidebarOpen && '!w-full delay-500'
|
||||
}`}
|
||||
></span>
|
||||
</span>
|
||||
<span className="absolute right-0 h-full w-full rotate-45">
|
||||
<span
|
||||
className={`absolute left-2.5 top-0 block h-full w-0.5 rounded-sm bg-black delay-300 duration-200 ease-in-out dark:bg-white ${
|
||||
!props.sidebarOpen && '!h-0 !delay-[0]'
|
||||
}`}
|
||||
></span>
|
||||
<span
|
||||
className={`delay-400 absolute left-0 top-2.5 block h-0.5 w-full rounded-sm bg-black duration-200 ease-in-out dark:bg-white ${
|
||||
!props.sidebarOpen && '!h-0 !delay-200'
|
||||
}`}
|
||||
></span>
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
{/* <!-- Hamburger Toggle BTN --> */}
|
||||
|
||||
{/* <Link className="block flex-shrink-0 lg:hidden" to="/">
|
||||
<img src={Logo} alt="Logo" />
|
||||
</Link> */}
|
||||
</div>
|
||||
|
||||
<div className="ml-4 flex-1">
|
||||
<h1>Loan market / {props.routeName}</h1>
|
||||
</div>
|
||||
|
||||
<button onClick={() => handleLogoutClick()}>
|
||||
<h1>logout</h1>
|
||||
</button>
|
||||
|
||||
|
||||
{/* <div className="flex items-center gap-3 2xsm:gap-7">
|
||||
<ul className="flex items-center gap-2 2xsm:gap-4">
|
||||
<!-- Dark Mode Toggler -->
|
||||
<DarkModeSwitcher />
|
||||
<!-- Dark Mode Toggler -->
|
||||
|
||||
<!-- Notification Menu Area -->
|
||||
<DropdownNotification />
|
||||
<!-- Notification Menu Area -->
|
||||
|
||||
<!-- Chat Notification Area -->
|
||||
<DropdownMessage />
|
||||
<!-- Chat Notification Area -->
|
||||
</ul>
|
||||
|
||||
<!-- User Area -->
|
||||
<DropdownUser />
|
||||
<!-- User Area -->
|
||||
</div> */}
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
};
|
||||
|
||||
export default Header;
|
39
src/components/ProgressBar/index.jsx
Normal file
39
src/components/ProgressBar/index.jsx
Normal file
@ -0,0 +1,39 @@
|
||||
const ProgressBar = (props) => {
|
||||
const { bgcolor, completed } = props;
|
||||
|
||||
const containerStyles = {
|
||||
height: 5,
|
||||
width: '100%',
|
||||
backgroundColor: "#e0e0de",
|
||||
borderRadius: 50,
|
||||
}
|
||||
|
||||
const fillerStyles = {
|
||||
height: '100%',
|
||||
width: `${completed}%`,
|
||||
backgroundColor: bgcolor,
|
||||
borderRadius: 'inherit',
|
||||
textAlign: 'right'
|
||||
}
|
||||
|
||||
const labelStyles = {
|
||||
padding: 5,
|
||||
color: 'black',
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="mt-4 mb-4">
|
||||
<div className="flex flex-row justify-between">
|
||||
<p style={labelStyles}>{props.label}</p>
|
||||
<p style={labelStyles}>{props.completed} %</p>
|
||||
</div>
|
||||
<div style={containerStyles}>
|
||||
<div style={fillerStyles}>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ProgressBar;
|
253
src/components/Sidebar/index.jsx
Normal file
253
src/components/Sidebar/index.jsx
Normal file
@ -0,0 +1,253 @@
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { NavLink, useLocation } from 'react-router-dom';
|
||||
// import Logo from './vite.svg';
|
||||
import SidebarLinkGroup from '../SidebarLinkGroup';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
// interface SidebarProps {
|
||||
// sidebarOpen: boolean;
|
||||
// setSidebarOpen: (arg: boolean) => void;
|
||||
// }
|
||||
|
||||
const Sidebar = ({ sidebarOpen, setSidebarOpen }) => {
|
||||
const location = useLocation();
|
||||
const { pathname } = location;
|
||||
|
||||
const auth = useSelector(state => state.auth)
|
||||
|
||||
const trigger = useRef(null);
|
||||
const sidebar = useRef(null);
|
||||
|
||||
const storedSidebarExpanded = localStorage.getItem('sidebar-expanded');
|
||||
const [sidebarExpanded, setSidebarExpanded] = useState(
|
||||
storedSidebarExpanded === null ? false : storedSidebarExpanded === 'true'
|
||||
);
|
||||
|
||||
// close on click outside
|
||||
useEffect(() => {
|
||||
const clickHandler = ({ target }) => {
|
||||
if (!sidebar.current || !trigger.current) return;
|
||||
if (
|
||||
!sidebarOpen ||
|
||||
sidebar.current.contains(target) ||
|
||||
trigger.current.contains(target)
|
||||
)
|
||||
return;
|
||||
setSidebarOpen(false);
|
||||
};
|
||||
document.addEventListener('click', clickHandler);
|
||||
return () => document.removeEventListener('click', clickHandler);
|
||||
});
|
||||
|
||||
// close if the esc key is pressed
|
||||
useEffect(() => {
|
||||
const keyHandler = ({ keyCode }) => {
|
||||
if (!sidebarOpen || keyCode !== 27) return;
|
||||
setSidebarOpen(false);
|
||||
};
|
||||
document.addEventListener('keydown', keyHandler);
|
||||
return () => document.removeEventListener('keydown', keyHandler);
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
localStorage.setItem('sidebar-expanded', sidebarExpanded.toString());
|
||||
if (sidebarExpanded) {
|
||||
document.querySelector('body')?.classList.add('sidebar-expanded');
|
||||
} else {
|
||||
document.querySelector('body')?.classList.remove('sidebar-expanded');
|
||||
}
|
||||
}, [sidebarExpanded]);
|
||||
|
||||
return (
|
||||
<aside
|
||||
ref={sidebar}
|
||||
className={`absolute left-0 top-0 z-9999 flex h-screen w-72.5 flex-col overflow-y-hidden bg-black duration-300 ease-linear dark:bg-boxdark lg:static lg:translate-x-0 ${
|
||||
sidebarOpen ? 'translate-x-0' : '-translate-x-full'
|
||||
}`}
|
||||
>
|
||||
{/* <!-- SIDEBAR HEADER --> */}
|
||||
<div className="flex items-center justify-between gap-2 px-6 py-5.5 lg:py-6.5">
|
||||
{/* <NavLink to="/">
|
||||
<img src={Logo} alt="Logo" />
|
||||
</NavLink> */}
|
||||
|
||||
<button
|
||||
ref={trigger}
|
||||
onClick={() => setSidebarOpen(!sidebarOpen)}
|
||||
aria-controls="sidebar"
|
||||
aria-expanded={sidebarOpen}
|
||||
className="block lg:hidden"
|
||||
>
|
||||
<svg
|
||||
style={{ fill: 'white'}}
|
||||
width="20"
|
||||
height="18"
|
||||
viewBox="0 0 20 18"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M19 8.175H2.98748L9.36248 1.6875C9.69998 1.35 9.69998 0.825 9.36248 0.4875C9.02498 0.15 8.49998 0.15 8.16248 0.4875L0.399976 8.3625C0.0624756 8.7 0.0624756 9.225 0.399976 9.5625L8.16248 17.4375C8.31248 17.5875 8.53748 17.7 8.76248 17.7C8.98748 17.7 9.17498 17.625 9.36248 17.475C9.69998 17.1375 9.69998 16.6125 9.36248 16.275L3.02498 9.8625H19C19.45 9.8625 19.825 9.4875 19.825 9.0375C19.825 8.55 19.45 8.175 19 8.175Z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
{/* <!-- SIDEBAR HEADER --> */}
|
||||
|
||||
<div className="no-scrollbar flex flex-col overflow-y-auto duration-300 ease-linear">
|
||||
{/* <!-- Sidebar Menu --> */}
|
||||
|
||||
<div className="mt-5 py-4 px-4 lg:px-6">
|
||||
<h3 className="ml-4 text-sm font-semibold text-white">{auth.name}</h3>
|
||||
<h3 className="mb-4 ml-4 text-sm font-semibold text-bodydark2">{auth.role_name}</h3>
|
||||
</div>
|
||||
<nav className="py-4 px-4 lg:px-6">
|
||||
|
||||
{/* <!-- Menu Group --> */}
|
||||
<div>
|
||||
<h3 className="mb-4 ml-4 text-sm font-semibold text-bodydark2">
|
||||
MENU
|
||||
</h3>
|
||||
|
||||
<ul className="mb-6 flex flex-col gap-1.5">
|
||||
{/* <!-- Menu Item Calendar --> */}
|
||||
<li>
|
||||
<NavLink
|
||||
to="/dashboard"
|
||||
className={`group relative flex items-center gap-2.5 rounded-sm py-2 px-4 font-medium text-bodydark1 duration-300 ease-in-out hover:bg-graydark dark:hover:bg-meta-4 ${
|
||||
pathname.includes('dashboard') &&
|
||||
'bg-graydark dark:bg-meta-4'
|
||||
}`}
|
||||
>
|
||||
<svg
|
||||
className="fill-current"
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 -960 960 960"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M220-180h150v-250h220v250h150v-390L480-765 220-570v390Zm-60 60v-480l320-240 320 240v480H530v-250H430v250H160Zm320-353Z"
|
||||
fill=""
|
||||
/>
|
||||
</svg>
|
||||
Dashboard
|
||||
</NavLink>
|
||||
</li>
|
||||
<li>
|
||||
<NavLink
|
||||
to="/users"
|
||||
className={`group relative flex items-center gap-2.5 rounded-sm py-2 px-4 font-medium text-bodydark1 duration-300 ease-in-out hover:bg-graydark dark:hover:bg-meta-4 ${
|
||||
pathname.includes('user') && 'bg-graydark dark:bg-meta-4'
|
||||
}`}
|
||||
>
|
||||
<svg
|
||||
className="fill-current"
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 18 18"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M9.0002 7.79065C11.0814 7.79065 12.7689 6.1594 12.7689 4.1344C12.7689 2.1094 11.0814 0.478149 9.0002 0.478149C6.91895 0.478149 5.23145 2.1094 5.23145 4.1344C5.23145 6.1594 6.91895 7.79065 9.0002 7.79065ZM9.0002 1.7719C10.3783 1.7719 11.5033 2.84065 11.5033 4.16252C11.5033 5.4844 10.3783 6.55315 9.0002 6.55315C7.62207 6.55315 6.49707 5.4844 6.49707 4.16252C6.49707 2.84065 7.62207 1.7719 9.0002 1.7719Z"
|
||||
fill=""
|
||||
/>
|
||||
<path
|
||||
d="M10.8283 9.05627H7.17207C4.16269 9.05627 1.71582 11.5313 1.71582 14.5406V16.875C1.71582 17.2125 1.99707 17.5219 2.3627 17.5219C2.72832 17.5219 3.00957 17.2407 3.00957 16.875V14.5406C3.00957 12.2344 4.89394 10.3219 7.22832 10.3219H10.8564C13.1627 10.3219 15.0752 12.2063 15.0752 14.5406V16.875C15.0752 17.2125 15.3564 17.5219 15.7221 17.5219C16.0877 17.5219 16.3689 17.2407 16.3689 16.875V14.5406C16.2846 11.5313 13.8377 9.05627 10.8283 9.05627Z"
|
||||
fill=""
|
||||
/>
|
||||
</svg>
|
||||
User management
|
||||
</NavLink>
|
||||
</li>
|
||||
<SidebarLinkGroup
|
||||
activeCondition={
|
||||
pathname === '/news' || pathname.includes('news')
|
||||
}
|
||||
>
|
||||
{(handleClick, open) => {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<NavLink
|
||||
to="news"
|
||||
className={`group relative flex items-center gap-2.5 rounded-sm py-2 px-4 font-medium text-bodydark1 duration-300 ease-in-out hover:bg-graydark dark:hover:bg-meta-4 ${
|
||||
(pathname === '/' ||
|
||||
pathname.includes('news')) &&
|
||||
'bg-graydark dark:bg-meta-4'
|
||||
}`}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
sidebarExpanded
|
||||
? handleClick()
|
||||
: setSidebarExpanded(true);
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
className="fill-current"
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 -960 960 960"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M167-120q-21 5-36.5-10.5T120-167l40-191 198 198-191 40Zm191-40L160-358l473-473q17-17 42-17t42 17l114 114q17 17 17 42t-17 42L358-160Zm317-628L233-346l113 113 442-442-113-113Z"
|
||||
fill=''
|
||||
/>
|
||||
</svg>
|
||||
News
|
||||
<svg
|
||||
className={`absolute right-4 top-1/2 -translate-y-1/2 fill-current ${
|
||||
open && 'rotate-180'
|
||||
}`}
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 20 20"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M4.41107 6.9107C4.73651 6.58527 5.26414 6.58527 5.58958 6.9107L10.0003 11.3214L14.4111 6.91071C14.7365 6.58527 15.2641 6.58527 15.5896 6.91071C15.915 7.23614 15.915 7.76378 15.5896 8.08922L10.5896 13.0892C10.2641 13.4147 9.73651 13.4147 9.41107 13.0892L4.41107 8.08922C4.08563 7.76378 4.08563 7.23614 4.41107 6.9107Z"
|
||||
fill=""
|
||||
/>
|
||||
</svg>
|
||||
</NavLink>
|
||||
{/* <!-- Dropdown Menu Start --> */}
|
||||
<div
|
||||
className={`translate transform overflow-hidden ${
|
||||
open && 'hidden'
|
||||
}`}
|
||||
>
|
||||
<ul className="mt-4 mb-5.5 flex flex-col gap-2.5 pl-6">
|
||||
<li>
|
||||
<NavLink
|
||||
to="/news"
|
||||
className={({ isActive }) =>
|
||||
'group relative flex items-center gap-2.5 rounded-md px-4 font-medium text-bodydark2 duration-300 ease-in-out hover:text-white ' +
|
||||
(isActive && '!text-white')
|
||||
}
|
||||
>
|
||||
Add news
|
||||
</NavLink>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
{/* <!-- Dropdown Menu End --> */}
|
||||
</React.Fragment>
|
||||
);
|
||||
}}
|
||||
</SidebarLinkGroup>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
{/* <!-- Sidebar Menu --> */}
|
||||
</div>
|
||||
</aside>
|
||||
);
|
||||
};
|
||||
|
||||
export default Sidebar;
|
16
src/components/SidebarLinkGroup/index.jsx
Normal file
16
src/components/SidebarLinkGroup/index.jsx
Normal file
@ -0,0 +1,16 @@
|
||||
import { useState } from 'react';
|
||||
|
||||
const SidebarLinkGroup = ({
|
||||
children,
|
||||
activeCondition,
|
||||
}) => {
|
||||
const [open, setOpen] = useState(activeCondition);
|
||||
|
||||
const handleClick = () => {
|
||||
setOpen(!open);
|
||||
};
|
||||
|
||||
return <li>{children(handleClick, open)}</li>;
|
||||
};
|
||||
|
||||
export default SidebarLinkGroup;
|
5
src/components/SparkChart/index.css
Normal file
5
src/components/SparkChart/index.css
Normal file
@ -0,0 +1,5 @@
|
||||
#chart {
|
||||
width: '100px' !important;
|
||||
height: '100px' !important;
|
||||
position: 'relative' !important;
|
||||
}
|
46
src/components/SparkChart/index.tsx
Normal file
46
src/components/SparkChart/index.tsx
Normal file
@ -0,0 +1,46 @@
|
||||
import useDemoConfig from "../ChartConfig";
|
||||
import React from "react";
|
||||
import { AxisOptions, Chart } from "react-charts";
|
||||
import './index.css'
|
||||
|
||||
export default function SparkChart() {
|
||||
const { data } = useDemoConfig({
|
||||
series: 1,
|
||||
dataType: "time",
|
||||
});
|
||||
|
||||
const primaryAxis = React.useMemo<
|
||||
AxisOptions<typeof data[number]["data"][number]>
|
||||
>(
|
||||
() => ({
|
||||
getValue: (datum) => datum.primary as unknown as Date,
|
||||
show: false,
|
||||
}),
|
||||
[]
|
||||
);
|
||||
|
||||
const secondaryAxes = React.useMemo<
|
||||
AxisOptions<typeof data[number]["data"][number]>[]
|
||||
>(
|
||||
() => [
|
||||
{
|
||||
getValue: (datum) => datum.secondary,
|
||||
show: false,
|
||||
showDatumElements: false,
|
||||
},
|
||||
],
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Chart
|
||||
options={{
|
||||
data,
|
||||
primaryAxis,
|
||||
secondaryAxes,
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
17
src/components/index.js
Normal file
17
src/components/index.js
Normal file
@ -0,0 +1,17 @@
|
||||
import Sidebar from "./Sidebar";
|
||||
import Header from "./Header";
|
||||
import ProgressBar from "./ProgressBar";
|
||||
import SparkChart from "./SparkChart";
|
||||
import DataTable from "./DataTable";
|
||||
import PaginationDefaultButton from "./Button/Pagination/DefaultButton";
|
||||
import PaginationPageButton from "./Button/Pagination/PageButton";
|
||||
|
||||
export {
|
||||
Sidebar,
|
||||
Header,
|
||||
ProgressBar,
|
||||
SparkChart,
|
||||
DataTable,
|
||||
PaginationDefaultButton,
|
||||
PaginationPageButton
|
||||
}
|
@ -1,2 +1 @@
|
||||
export const LOGIN = 'LOGIN';
|
||||
export const LOGOUT = 'LOGOUT';
|
@ -1,19 +1,225 @@
|
||||
[
|
||||
{
|
||||
"name": "superadmin",
|
||||
"email": "superadmin@superadmin.com",
|
||||
"password": "12345",
|
||||
"phone": "180121312",
|
||||
"role_id": "1",
|
||||
"role_name": "Super admin"
|
||||
},
|
||||
{
|
||||
"name": "author",
|
||||
"email": "author@author.com",
|
||||
"password": "12345",
|
||||
"phone": "180123142",
|
||||
"role_id": "2",
|
||||
"role_name": "Author"
|
||||
},
|
||||
{
|
||||
"name": "admin",
|
||||
"email": "admin@admin.com",
|
||||
"password": "12345",
|
||||
"phone": "1818230123",
|
||||
"role_id": "3",
|
||||
"role_name": "Admin"
|
||||
},
|
||||
{
|
||||
"name": "user1",
|
||||
"email": "user1@example.com",
|
||||
"password": "password1",
|
||||
"phone": "1234567891",
|
||||
"role_id": "3",
|
||||
"role_name": "Admin"
|
||||
},
|
||||
{
|
||||
"name": "user2",
|
||||
"email": "user2@example.com",
|
||||
"password": "password2",
|
||||
"phone": "2345678912",
|
||||
"role_id": "3",
|
||||
"role_name": "Admin"
|
||||
},
|
||||
{
|
||||
"name": "user3",
|
||||
"email": "user3@example.com",
|
||||
"password": "password3",
|
||||
"phone": "3456789123",
|
||||
"role_id": "3",
|
||||
"role_name": "Admin"
|
||||
},
|
||||
{
|
||||
"name": "user4",
|
||||
"email": "user4@example.com",
|
||||
"password": "password4",
|
||||
"phone": "4567891234",
|
||||
"role_id": "3",
|
||||
"role_name": "Admin"
|
||||
},
|
||||
{
|
||||
"name": "user5",
|
||||
"email": "user5@example.com",
|
||||
"password": "password5",
|
||||
"phone": "5678912345",
|
||||
"role_id": "3",
|
||||
"role_name": "Admin"
|
||||
},
|
||||
{
|
||||
"name": "user6",
|
||||
"email": "user6@example.com",
|
||||
"password": "password6",
|
||||
"phone": "6789123456",
|
||||
"role_id": "3",
|
||||
"role_name": "Admin"
|
||||
},
|
||||
{
|
||||
"name": "user7",
|
||||
"email": "user7@example.com",
|
||||
"password": "password7",
|
||||
"phone": "7891234567",
|
||||
"role_id": "3",
|
||||
"role_name": "Admin"
|
||||
},
|
||||
{
|
||||
"name": "user8",
|
||||
"email": "user8@example.com",
|
||||
"password": "password8",
|
||||
"phone": "8912345678",
|
||||
"role_id": "3",
|
||||
"role_name": "Admin"
|
||||
},
|
||||
{
|
||||
"name": "user9",
|
||||
"email": "user9@example.com",
|
||||
"password": "password9",
|
||||
"phone": "9123456789",
|
||||
"role_id": "3",
|
||||
"role_name": "Admin"
|
||||
},
|
||||
{
|
||||
"name": "user10",
|
||||
"email": "user10@example.com",
|
||||
"password": "password10",
|
||||
"phone": "1234567890",
|
||||
"role_id": "3",
|
||||
"role_name": "Admin"
|
||||
},
|
||||
{
|
||||
"name": "user11",
|
||||
"email": "user11@example.com",
|
||||
"password": "password11",
|
||||
"phone": "2345678901",
|
||||
"role_id": "3",
|
||||
"role_name": "Admin"
|
||||
},
|
||||
{
|
||||
"name": "user12",
|
||||
"email": "user12@example.com",
|
||||
"password": "password12",
|
||||
"phone": "3456789012",
|
||||
"role_id": "3",
|
||||
"role_name": "Admin"
|
||||
},
|
||||
{
|
||||
"name": "user13",
|
||||
"email": "user13@example.com",
|
||||
"password": "password13",
|
||||
"phone": "4567890123",
|
||||
"role_id": "3",
|
||||
"role_name": "Admin"
|
||||
},
|
||||
{
|
||||
"name": "user14",
|
||||
"email": "user14@example.com",
|
||||
"password": "password14",
|
||||
"phone": "5678901234",
|
||||
"role_id": "3",
|
||||
"role_name": "Admin"
|
||||
},
|
||||
{
|
||||
"name": "user15",
|
||||
"email": "user15@example.com",
|
||||
"password": "password15",
|
||||
"phone": "6789012345",
|
||||
"role_id": "3",
|
||||
"role_name": "Admin"
|
||||
},
|
||||
{
|
||||
"name": "user16",
|
||||
"email": "user16@example.com",
|
||||
"password": "password16",
|
||||
"phone": "7890123456",
|
||||
"role_id": "3",
|
||||
"role_name": "Admin"
|
||||
},
|
||||
{
|
||||
"name": "user17",
|
||||
"email": "user17@example.com",
|
||||
"password": "password17",
|
||||
"phone": "8901234567",
|
||||
"role_id": "3",
|
||||
"role_name": "Admin"
|
||||
},
|
||||
{
|
||||
"name": "user18",
|
||||
"email": "user18@example.com",
|
||||
"password": "password18",
|
||||
"phone": "9012345678",
|
||||
"role_id": "3",
|
||||
"role_name": "Admin"
|
||||
},
|
||||
{
|
||||
"name": "user19",
|
||||
"email": "user19@example.com",
|
||||
"password": "password19",
|
||||
"phone": "0123456789",
|
||||
"role_id": "3",
|
||||
"role_name": "Admin"
|
||||
},
|
||||
{
|
||||
"name": "user20",
|
||||
"email": "user20@example.com",
|
||||
"password": "password20",
|
||||
"phone": "9876543210",
|
||||
"role_id": "3",
|
||||
"role_name": "Admin"
|
||||
},
|
||||
{
|
||||
"name": "user21",
|
||||
"email": "user21@example.com",
|
||||
"password": "password21",
|
||||
"phone": "8765432109",
|
||||
"role_id": "3",
|
||||
"role_name": "Admin"
|
||||
},
|
||||
{
|
||||
"name": "user22",
|
||||
"email": "user22@example.com",
|
||||
"password": "password22",
|
||||
"phone": "7654321098",
|
||||
"role_id": "3",
|
||||
"role_name": "Admin"
|
||||
},
|
||||
{
|
||||
"name": "user23",
|
||||
"email": "user23@example.com",
|
||||
"password": "password23",
|
||||
"phone": "6543210987",
|
||||
"role_id": "3",
|
||||
"role_name": "Admin"
|
||||
},
|
||||
{
|
||||
"name": "user24",
|
||||
"email": "user24@example.com",
|
||||
"password": "password24",
|
||||
"phone": "5432109876",
|
||||
"role_id": "3",
|
||||
"role_name": "Admin"
|
||||
},
|
||||
{
|
||||
"name": "user25",
|
||||
"email": "user25@example.com",
|
||||
"password": "password25",
|
||||
"phone": "4321098765",
|
||||
"role_id": "3",
|
||||
"role_name": "Admin"
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { createSlice, current } from "@reduxjs/toolkit";
|
||||
import { createSlice } from "@reduxjs/toolkit";
|
||||
|
||||
const initialState = []
|
||||
const initialState = {}
|
||||
|
||||
const authSlice = createSlice({
|
||||
name: 'auth',
|
||||
|
@ -1,3 +1,9 @@
|
||||
@tailwind base;
|
||||
@tailwind component;
|
||||
@tailwind utilities;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@layer base {
|
||||
body {
|
||||
@apply bg-whiten relative z-1;
|
||||
}
|
||||
}
|
40
src/layouts/DefaultLayout/index.jsx
Normal file
40
src/layouts/DefaultLayout/index.jsx
Normal file
@ -0,0 +1,40 @@
|
||||
import { useState } from 'react';
|
||||
import { Header, Sidebar } from '../../components';
|
||||
import { Outlet, useLocation } from 'react-router-dom';
|
||||
import { getRouteName } from '../../utils';
|
||||
|
||||
const DefaultLayout = () => {
|
||||
const [sidebarOpen, setSidebarOpen] = useState(false);
|
||||
const routeName = getRouteName(useLocation().pathname);
|
||||
|
||||
|
||||
return (
|
||||
<div className="dark:bg-boxdark-2 dark:text-bodydark">
|
||||
{/* <!-- ===== Page Wrapper Start ===== --> */}
|
||||
<div className="flex h-screen overflow-hidden">
|
||||
{/* <!-- ===== Sidebar Start ===== --> */}
|
||||
<Sidebar sidebarOpen={sidebarOpen} setSidebarOpen={setSidebarOpen} />
|
||||
{/* <!-- ===== Sidebar End ===== --> */}
|
||||
|
||||
{/* <!-- ===== Content Area Start ===== --> */}
|
||||
<div className="relative flex flex-1 flex-col overflow-y-auto overflow-x-hidden">
|
||||
{/* <!-- ===== Header Start ===== --> */}
|
||||
<Header sidebarOpen={sidebarOpen} setSidebarOpen={setSidebarOpen} routeName={routeName} />
|
||||
{/* <!-- ===== Header End ===== --> */}
|
||||
|
||||
{/* <!-- ===== Main Content Start ===== --> */}
|
||||
<main>
|
||||
<div className="mx-auto max-w-screen-2xl p-4 md:p-6 2xl:p-10">
|
||||
<Outlet />
|
||||
</div>
|
||||
</main>
|
||||
{/* <!-- ===== Main Content End ===== --> */}
|
||||
</div>
|
||||
{/* <!-- ===== Content Area End ===== --> */}
|
||||
</div>
|
||||
{/* <!-- ===== Page Wrapper End ===== --> */}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default DefaultLayout;
|
5
src/layouts/index.jsx
Normal file
5
src/layouts/index.jsx
Normal file
@ -0,0 +1,5 @@
|
||||
import DefaultLayout from "./DefaultLayout";
|
||||
|
||||
export {
|
||||
DefaultLayout,
|
||||
}
|
@ -2,9 +2,12 @@ import React from 'react'
|
||||
import ReactDOM from 'react-dom/client'
|
||||
import App from './App.jsx'
|
||||
import './index.css'
|
||||
import { BrowserRouter as Router} from 'react-router-dom'
|
||||
|
||||
ReactDOM.createRoot(document.getElementById('root')).render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
<Router>
|
||||
<App />
|
||||
</Router>
|
||||
</React.StrictMode>,
|
||||
)
|
||||
|
14
src/pages/Dashboard/index.css
Normal file
14
src/pages/Dashboard/index.css
Normal file
@ -0,0 +1,14 @@
|
||||
@media only screen and (max-width:1268px) {
|
||||
.box {
|
||||
margin-bottom: 10px; /* Or required space */
|
||||
display: block;
|
||||
}
|
||||
.box-center {
|
||||
align-self: center;
|
||||
width: 210px;
|
||||
}
|
||||
.big-box {
|
||||
display: block;
|
||||
margin: 0 10px;
|
||||
}
|
||||
}
|
@ -1,7 +1,206 @@
|
||||
import React from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { logout } from '../../actions';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import data from '../.././datas/dashboard.json';
|
||||
import './index.css';
|
||||
import { ProgressBar, SparkChart } from '../../components';
|
||||
|
||||
const Dashboard = () => {
|
||||
const dispatch = useDispatch();
|
||||
const navigate = useNavigate();
|
||||
const auth = useSelector(state => state.auth)
|
||||
const handleOnClick = () => {
|
||||
dispatch(logout())
|
||||
navigate("/")
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<h1>Dashboard</h1>
|
||||
<div className='mb-6 flex flex-col-2 gap-3 flex-row justify-between'>
|
||||
<div>
|
||||
<h1>Dashboard</h1>
|
||||
<h3>User quantity</h3>
|
||||
</div>
|
||||
{ auth.role_id != 2 &&
|
||||
<button className='bg-primary rounded justify-center hover:bg-opacity-70 text-gray font-medium px-4 py-3 flex'>
|
||||
Go to CRM
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="ml-3" style={{ alignSelf: 'center' }} fill="white" height="18" viewBox="0 -960 960 960" width="18"><path d="M686-450H160v-60h526L438-758l42-42 320 320-320 320-42-42 248-248Z" /></svg>
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
<div className='grid lg:grid-cols-3 md:grid-cols-3 sm:grid-cols-2 xl:grid-cols-6 gap-5'>
|
||||
<div class="flex justify-center">
|
||||
<div class="bg-white rounded py-5 px-15 text-center">
|
||||
<div className='bg-black justify-center py-5 px-5 rounded shadow-lg mt-10'>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="white" height="48" viewBox="0 -960 960 960" width="48"><path d="M222-255q63-44 125-67.5T480-346q71 0 133.5 23.5T739-255q44-54 62.5-109T820-480q0-145-97.5-242.5T480-820q-145 0-242.5 97.5T140-480q0 61 19 116t63 109Zm257.814-195Q422-450 382.5-489.686q-39.5-39.686-39.5-97.5t39.686-97.314q39.686-39.5 97.5-39.5t97.314 39.686q39.5 39.686 39.5 97.5T577.314-489.5q-39.686 39.5-97.5 39.5Zm.654 370Q398-80 325-111.5q-73-31.5-127.5-86t-86-127.266Q80-397.532 80-480.266T111.5-635.5q31.5-72.5 86-127t127.266-86q72.766-31.5 155.5-31.5T635.5-848.5q72.5 31.5 127 86t86 127.032q31.5 72.532 31.5 155T848.5-325q-31.5 73-86 127.5t-127.032 86q-72.532 31.5-155 31.5ZM480-140q55 0 107.5-16T691-212q-51-36-104-55t-107-19q-54 0-107 19t-104 55q51 40 103.5 56T480-140Zm0-370q34 0 55.5-21.5T557-587q0-34-21.5-55.5T480-664q-34 0-55.5 21.5T403-587q0 34 21.5 55.5T480-510Zm0-77Zm0 374Z" /></svg>
|
||||
</div>
|
||||
<h1 className='mt-15'>{data.users_data.total_users}</h1>
|
||||
<h1 className='mb-10'>User</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-center">
|
||||
<div class="bg-white rounded py-5 px-15 text-center">
|
||||
<div className='bg-black justify-center py-5 px-5 rounded shadow-lg mt-10'>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="white" height="48" viewBox="0 -960 960 960" width="48"><path d="M222-255q63-44 125-67.5T480-346q71 0 133.5 23.5T739-255q44-54 62.5-109T820-480q0-145-97.5-242.5T480-820q-145 0-242.5 97.5T140-480q0 61 19 116t63 109Zm257.814-195Q422-450 382.5-489.686q-39.5-39.686-39.5-97.5t39.686-97.314q39.686-39.5 97.5-39.5t97.314 39.686q39.5 39.686 39.5 97.5T577.314-489.5q-39.686 39.5-97.5 39.5Zm.654 370Q398-80 325-111.5q-73-31.5-127.5-86t-86-127.266Q80-397.532 80-480.266T111.5-635.5q31.5-72.5 86-127t127.266-86q72.766-31.5 155.5-31.5T635.5-848.5q72.5 31.5 127 86t86 127.032q31.5 72.532 31.5 155T848.5-325q-31.5 73-86 127.5t-127.032 86q-72.532 31.5-155 31.5ZM480-140q55 0 107.5-16T691-212q-51-36-104-55t-107-19q-54 0-107 19t-104 55q51 40 103.5 56T480-140Zm0-370q34 0 55.5-21.5T557-587q0-34-21.5-55.5T480-664q-34 0-55.5 21.5T403-587q0 34 21.5 55.5T480-510Zm0-77Zm0 374Z" /></svg>
|
||||
</div>
|
||||
<h1 className='mt-15'>{data.users_data.total_users}</h1>
|
||||
<h1 className='mb-10'>User</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-center">
|
||||
<div class="bg-white rounded py-5 px-15 text-center">
|
||||
<div className='bg-black justify-center py-5 px-5 rounded shadow-lg mt-10'>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="white" height="48" viewBox="0 -960 960 960" width="48"><path d="M222-255q63-44 125-67.5T480-346q71 0 133.5 23.5T739-255q44-54 62.5-109T820-480q0-145-97.5-242.5T480-820q-145 0-242.5 97.5T140-480q0 61 19 116t63 109Zm257.814-195Q422-450 382.5-489.686q-39.5-39.686-39.5-97.5t39.686-97.314q39.686-39.5 97.5-39.5t97.314 39.686q39.5 39.686 39.5 97.5T577.314-489.5q-39.686 39.5-97.5 39.5Zm.654 370Q398-80 325-111.5q-73-31.5-127.5-86t-86-127.266Q80-397.532 80-480.266T111.5-635.5q31.5-72.5 86-127t127.266-86q72.766-31.5 155.5-31.5T635.5-848.5q72.5 31.5 127 86t86 127.032q31.5 72.532 31.5 155T848.5-325q-31.5 73-86 127.5t-127.032 86q-72.532 31.5-155 31.5ZM480-140q55 0 107.5-16T691-212q-51-36-104-55t-107-19q-54 0-107 19t-104 55q51 40 103.5 56T480-140Zm0-370q34 0 55.5-21.5T557-587q0-34-21.5-55.5T480-664q-34 0-55.5 21.5T403-587q0 34 21.5 55.5T480-510Zm0-77Zm0 374Z" /></svg>
|
||||
</div>
|
||||
<h1 className='mt-15'>{data.users_data.total_users}</h1>
|
||||
<h1 className='mb-10'>User</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div className='justify-between flex flex-col'>
|
||||
<div className='bg-white text-right px-3 py-4 box-center box' style={{ display: 'flex', justifyContent: 'space-between' }}>
|
||||
<div class="bg-black rounded px-2 py-2">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="white" height="30" viewBox="0 -960 960 960" width="30"><path d="M222-255q63-44 125-67.5T480-346q71 0 133.5 23.5T739-255q44-54 62.5-109T820-480q0-145-97.5-242.5T480-820q-145 0-242.5 97.5T140-480q0 61 19 116t63 109Zm257.814-195Q422-450 382.5-489.686q-39.5-39.686-39.5-97.5t39.686-97.314q39.686-39.5 97.5-39.5t97.314 39.686q39.5 39.686 39.5 97.5T577.314-489.5q-39.686 39.5-97.5 39.5Zm.654 370Q398-80 325-111.5q-73-31.5-127.5-86t-86-127.266Q80-397.532 80-480.266T111.5-635.5q31.5-72.5 86-127t127.266-86q72.766-31.5 155.5-31.5T635.5-848.5q72.5 31.5 127 86t86 127.032q31.5 72.532 31.5 155T848.5-325q-31.5 73-86 127.5t-127.032 86q-72.532 31.5-155 31.5ZM480-140q55 0 107.5-16T691-212q-51-36-104-55t-107-19q-54 0-107 19t-104 55q51 40 103.5 56T480-140Zm0-370q34 0 55.5-21.5T557-587q0-34-21.5-55.5T480-664q-34 0-55.5 21.5T403-587q0 34 21.5 55.5T480-510Zm0-77Zm0 374Z" /></svg>
|
||||
</div>
|
||||
<div>
|
||||
<p>Admin office</p>
|
||||
<p>4</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className='bg-white text-right px-3 py-4 box-center box' style={{ display: 'flex', justifyContent: 'space-between' }}>
|
||||
<div class="bg-black rounded px-2 py-2">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="white" height="30" viewBox="0 -960 960 960" width="30"><path d="M222-255q63-44 125-67.5T480-346q71 0 133.5 23.5T739-255q44-54 62.5-109T820-480q0-145-97.5-242.5T480-820q-145 0-242.5 97.5T140-480q0 61 19 116t63 109Zm257.814-195Q422-450 382.5-489.686q-39.5-39.686-39.5-97.5t39.686-97.314q39.686-39.5 97.5-39.5t97.314 39.686q39.5 39.686 39.5 97.5T577.314-489.5q-39.686 39.5-97.5 39.5Zm.654 370Q398-80 325-111.5q-73-31.5-127.5-86t-86-127.266Q80-397.532 80-480.266T111.5-635.5q31.5-72.5 86-127t127.266-86q72.766-31.5 155.5-31.5T635.5-848.5q72.5 31.5 127 86t86 127.032q31.5 72.532 31.5 155T848.5-325q-31.5 73-86 127.5t-127.032 86q-72.532 31.5-155 31.5ZM480-140q55 0 107.5-16T691-212q-51-36-104-55t-107-19q-54 0-107 19t-104 55q51 40 103.5 56T480-140Zm0-370q34 0 55.5-21.5T557-587q0-34-21.5-55.5T480-664q-34 0-55.5 21.5T403-587q0 34 21.5 55.5T480-510Zm0-77Zm0 374Z" /></svg>
|
||||
</div>
|
||||
<div >
|
||||
<p>Admin office</p>
|
||||
<p>4</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className='bg-white text-right px-3 py-4 box-center' style={{ display: 'flex', justifyContent: 'space-between' }}>
|
||||
<div class="bg-black rounded px-2 py-2">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="white" height="30" viewBox="0 -960 960 960" width="30"><path d="M222-255q63-44 125-67.5T480-346q71 0 133.5 23.5T739-255q44-54 62.5-109T820-480q0-145-97.5-242.5T480-820q-145 0-242.5 97.5T140-480q0 61 19 116t63 109Zm257.814-195Q422-450 382.5-489.686q-39.5-39.686-39.5-97.5t39.686-97.314q39.686-39.5 97.5-39.5t97.314 39.686q39.5 39.686 39.5 97.5T577.314-489.5q-39.686 39.5-97.5 39.5Zm.654 370Q398-80 325-111.5q-73-31.5-127.5-86t-86-127.266Q80-397.532 80-480.266T111.5-635.5q31.5-72.5 86-127t127.266-86q72.766-31.5 155.5-31.5T635.5-848.5q72.5 31.5 127 86t86 127.032q31.5 72.532 31.5 155T848.5-325q-31.5 73-86 127.5t-127.032 86q-72.532 31.5-155 31.5ZM480-140q55 0 107.5-16T691-212q-51-36-104-55t-107-19q-54 0-107 19t-104 55q51 40 103.5 56T480-140Zm0-370q34 0 55.5-21.5T557-587q0-34-21.5-55.5T480-664q-34 0-55.5 21.5T403-587q0 34 21.5 55.5T480-510Zm0-77Zm0 374Z" /></svg>
|
||||
</div>
|
||||
<div >
|
||||
<p>Admin office</p>
|
||||
<p>4</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='justify-between flex flex-col'>
|
||||
<div className='bg-white text-right px-3 py-4 box-center box' style={{ display: 'flex', justifyContent: 'space-between' }}>
|
||||
<div class="bg-black rounded px-2 py-2">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="white" height="30" viewBox="0 -960 960 960" width="30"><path d="M222-255q63-44 125-67.5T480-346q71 0 133.5 23.5T739-255q44-54 62.5-109T820-480q0-145-97.5-242.5T480-820q-145 0-242.5 97.5T140-480q0 61 19 116t63 109Zm257.814-195Q422-450 382.5-489.686q-39.5-39.686-39.5-97.5t39.686-97.314q39.686-39.5 97.5-39.5t97.314 39.686q39.5 39.686 39.5 97.5T577.314-489.5q-39.686 39.5-97.5 39.5Zm.654 370Q398-80 325-111.5q-73-31.5-127.5-86t-86-127.266Q80-397.532 80-480.266T111.5-635.5q31.5-72.5 86-127t127.266-86q72.766-31.5 155.5-31.5T635.5-848.5q72.5 31.5 127 86t86 127.032q31.5 72.532 31.5 155T848.5-325q-31.5 73-86 127.5t-127.032 86q-72.532 31.5-155 31.5ZM480-140q55 0 107.5-16T691-212q-51-36-104-55t-107-19q-54 0-107 19t-104 55q51 40 103.5 56T480-140Zm0-370q34 0 55.5-21.5T557-587q0-34-21.5-55.5T480-664q-34 0-55.5 21.5T403-587q0 34 21.5 55.5T480-510Zm0-77Zm0 374Z" /></svg>
|
||||
</div>
|
||||
<div>
|
||||
<p>Admin office</p>
|
||||
<p>4</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className='bg-white text-right px-3 py-4 box-center box' style={{ display: 'flex', justifyContent: 'space-between' }}>
|
||||
<div class="bg-black rounded px-2 py-2">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="white" height="30" viewBox="0 -960 960 960" width="30"><path d="M222-255q63-44 125-67.5T480-346q71 0 133.5 23.5T739-255q44-54 62.5-109T820-480q0-145-97.5-242.5T480-820q-145 0-242.5 97.5T140-480q0 61 19 116t63 109Zm257.814-195Q422-450 382.5-489.686q-39.5-39.686-39.5-97.5t39.686-97.314q39.686-39.5 97.5-39.5t97.314 39.686q39.5 39.686 39.5 97.5T577.314-489.5q-39.686 39.5-97.5 39.5Zm.654 370Q398-80 325-111.5q-73-31.5-127.5-86t-86-127.266Q80-397.532 80-480.266T111.5-635.5q31.5-72.5 86-127t127.266-86q72.766-31.5 155.5-31.5T635.5-848.5q72.5 31.5 127 86t86 127.032q31.5 72.532 31.5 155T848.5-325q-31.5 73-86 127.5t-127.032 86q-72.532 31.5-155 31.5ZM480-140q55 0 107.5-16T691-212q-51-36-104-55t-107-19q-54 0-107 19t-104 55q51 40 103.5 56T480-140Zm0-370q34 0 55.5-21.5T557-587q0-34-21.5-55.5T480-664q-34 0-55.5 21.5T403-587q0 34 21.5 55.5T480-510Zm0-77Zm0 374Z" /></svg>
|
||||
</div>
|
||||
<div >
|
||||
<p>Admin office</p>
|
||||
<p>4</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className='bg-white text-right px-3 py-4 box-center' style={{ display: 'flex', justifyContent: 'space-between' }}>
|
||||
<div class="bg-black rounded px-2 py-2">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="white" height="30" viewBox="0 -960 960 960" width="30"><path d="M222-255q63-44 125-67.5T480-346q71 0 133.5 23.5T739-255q44-54 62.5-109T820-480q0-145-97.5-242.5T480-820q-145 0-242.5 97.5T140-480q0 61 19 116t63 109Zm257.814-195Q422-450 382.5-489.686q-39.5-39.686-39.5-97.5t39.686-97.314q39.686-39.5 97.5-39.5t97.314 39.686q39.5 39.686 39.5 97.5T577.314-489.5q-39.686 39.5-97.5 39.5Zm.654 370Q398-80 325-111.5q-73-31.5-127.5-86t-86-127.266Q80-397.532 80-480.266T111.5-635.5q31.5-72.5 86-127t127.266-86q72.766-31.5 155.5-31.5T635.5-848.5q72.5 31.5 127 86t86 127.032q31.5 72.532 31.5 155T848.5-325q-31.5 73-86 127.5t-127.032 86q-72.532 31.5-155 31.5ZM480-140q55 0 107.5-16T691-212q-51-36-104-55t-107-19q-54 0-107 19t-104 55q51 40 103.5 56T480-140Zm0-370q34 0 55.5-21.5T557-587q0-34-21.5-55.5T480-664q-34 0-55.5 21.5T403-587q0 34 21.5 55.5T480-510Zm0-77Zm0 374Z" /></svg>
|
||||
</div>
|
||||
<div >
|
||||
<p>Admin office</p>
|
||||
<p>4</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='justify-between flex flex-col'>
|
||||
<div className='bg-white text-right px-3 py-4 box-center box' style={{ display: 'flex', justifyContent: 'space-between' }}>
|
||||
<div class="bg-black rounded px-2 py-2">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="white" height="30" viewBox="0 -960 960 960" width="30"><path d="M222-255q63-44 125-67.5T480-346q71 0 133.5 23.5T739-255q44-54 62.5-109T820-480q0-145-97.5-242.5T480-820q-145 0-242.5 97.5T140-480q0 61 19 116t63 109Zm257.814-195Q422-450 382.5-489.686q-39.5-39.686-39.5-97.5t39.686-97.314q39.686-39.5 97.5-39.5t97.314 39.686q39.5 39.686 39.5 97.5T577.314-489.5q-39.686 39.5-97.5 39.5Zm.654 370Q398-80 325-111.5q-73-31.5-127.5-86t-86-127.266Q80-397.532 80-480.266T111.5-635.5q31.5-72.5 86-127t127.266-86q72.766-31.5 155.5-31.5T635.5-848.5q72.5 31.5 127 86t86 127.032q31.5 72.532 31.5 155T848.5-325q-31.5 73-86 127.5t-127.032 86q-72.532 31.5-155 31.5ZM480-140q55 0 107.5-16T691-212q-51-36-104-55t-107-19q-54 0-107 19t-104 55q51 40 103.5 56T480-140Zm0-370q34 0 55.5-21.5T557-587q0-34-21.5-55.5T480-664q-34 0-55.5 21.5T403-587q0 34 21.5 55.5T480-510Zm0-77Zm0 374Z" /></svg>
|
||||
</div>
|
||||
<div>
|
||||
<p>Admin office</p>
|
||||
<p>4</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className='bg-white text-right px-3 py-4 box-center box' style={{ display: 'flex', justifyContent: 'space-between' }}>
|
||||
<div class="bg-black rounded px-2 py-2">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="white" height="30" viewBox="0 -960 960 960" width="30"><path d="M222-255q63-44 125-67.5T480-346q71 0 133.5 23.5T739-255q44-54 62.5-109T820-480q0-145-97.5-242.5T480-820q-145 0-242.5 97.5T140-480q0 61 19 116t63 109Zm257.814-195Q422-450 382.5-489.686q-39.5-39.686-39.5-97.5t39.686-97.314q39.686-39.5 97.5-39.5t97.314 39.686q39.5 39.686 39.5 97.5T577.314-489.5q-39.686 39.5-97.5 39.5Zm.654 370Q398-80 325-111.5q-73-31.5-127.5-86t-86-127.266Q80-397.532 80-480.266T111.5-635.5q31.5-72.5 86-127t127.266-86q72.766-31.5 155.5-31.5T635.5-848.5q72.5 31.5 127 86t86 127.032q31.5 72.532 31.5 155T848.5-325q-31.5 73-86 127.5t-127.032 86q-72.532 31.5-155 31.5ZM480-140q55 0 107.5-16T691-212q-51-36-104-55t-107-19q-54 0-107 19t-104 55q51 40 103.5 56T480-140Zm0-370q34 0 55.5-21.5T557-587q0-34-21.5-55.5T480-664q-34 0-55.5 21.5T403-587q0 34 21.5 55.5T480-510Zm0-77Zm0 374Z" /></svg>
|
||||
</div>
|
||||
<div >
|
||||
<p>Admin office</p>
|
||||
<p>4</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className='bg-white text-right px-3 py-4 box-center' style={{ display: 'flex', justifyContent: 'space-between' }}>
|
||||
<div class="bg-black rounded px-2 py-2">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="white" height="30" viewBox="0 -960 960 960" width="30"><path d="M222-255q63-44 125-67.5T480-346q71 0 133.5 23.5T739-255q44-54 62.5-109T820-480q0-145-97.5-242.5T480-820q-145 0-242.5 97.5T140-480q0 61 19 116t63 109Zm257.814-195Q422-450 382.5-489.686q-39.5-39.686-39.5-97.5t39.686-97.314q39.686-39.5 97.5-39.5t97.314 39.686q39.5 39.686 39.5 97.5T577.314-489.5q-39.686 39.5-97.5 39.5Zm.654 370Q398-80 325-111.5q-73-31.5-127.5-86t-86-127.266Q80-397.532 80-480.266T111.5-635.5q31.5-72.5 86-127t127.266-86q72.766-31.5 155.5-31.5T635.5-848.5q72.5 31.5 127 86t86 127.032q31.5 72.532 31.5 155T848.5-325q-31.5 73-86 127.5t-127.032 86q-72.532 31.5-155 31.5ZM480-140q55 0 107.5-16T691-212q-51-36-104-55t-107-19q-54 0-107 19t-104 55q51 40 103.5 56T480-140Zm0-370q34 0 55.5-21.5T557-587q0-34-21.5-55.5T480-664q-34 0-55.5 21.5T403-587q0 34 21.5 55.5T480-510Zm0-77Zm0 374Z" /></svg>
|
||||
</div>
|
||||
<div >
|
||||
<p>Admin office</p>
|
||||
<p>4</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='mb-5 mt-15'>
|
||||
<h2>Data & analytics</h2>
|
||||
<p>Show updates of post</p>
|
||||
</div>
|
||||
{/* container */}
|
||||
<div className='bg-white px-3 py-3 rounded'>
|
||||
{/* 2 grid */}
|
||||
<div className="grid lg:grid-cols-2 gap-10">
|
||||
{/* inside 2 grid */}
|
||||
<div>
|
||||
{/* header */}
|
||||
<div className='grid lg:grid-cols-2 py-2 gap-10' style={{ borderBottomWidth: 1, borderColor: '#ededed'}}>
|
||||
<div className='flex flex-row px-2 justify-between' style={{ borderLeftWidth: 4, borderRadius: 4, borderColor: '#68c0d9'}}>
|
||||
<div className='flex flex-col flex'>
|
||||
<p>Belum diproses</p>
|
||||
<p>9123</p>
|
||||
</div>
|
||||
<div style={{ width: '100px'}}>
|
||||
<SparkChart />
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex flex-row justify-between px-2' style={{ borderLeftWidth: 4, borderRadius: 4, borderColor: '#f76c6b'}}>
|
||||
<div className='flex flex-col flex'>
|
||||
<p>Sudah diproses</p>
|
||||
<p>9123</p>
|
||||
</div>
|
||||
<div style={{ width: '100px'}}>
|
||||
<SparkChart />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='pl-4'>
|
||||
<ProgressBar label="Belum diproses" completed="43" bgcolor='#68c0d9'/>
|
||||
<ProgressBar label="Sudah diproses" completed="37" bgcolor="#f76c6b"/>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="py-2" style={{ borderBottomWidth: 1, borderColor: '#ededed'}}>
|
||||
<div>
|
||||
<div className='flex flex-row px-2' style={{ borderLeftWidth: 4, borderRadius: 4, borderColor: '#fcc00c'}}>
|
||||
<div className='flex flex-col flex mr-10'>
|
||||
<p>Customer</p>
|
||||
<p>9123</p>
|
||||
</div>
|
||||
<div style={{ width: '150px'}}>
|
||||
<SparkChart />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='pl-4'>
|
||||
<ProgressBar label="Pria" completed="43" bgcolor='#fcc00c'/>
|
||||
<ProgressBar label="Wanita diproses" completed="37" bgcolor="#fcc00c"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
@ -1,9 +1,14 @@
|
||||
import { useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import user from "../../datas/users.json";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { authAdded } from "../../features/auth/authSlice";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
const Login = () => {
|
||||
const dispatch = useDispatch();
|
||||
const auth = useSelector(state => state.auth);
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [authForm, setAuthForm] = useState({
|
||||
email: '',
|
||||
password: ''
|
||||
@ -14,9 +19,6 @@ const Login = () => {
|
||||
message: ''
|
||||
});
|
||||
|
||||
const dispatch = useDispatch();
|
||||
const auth = useSelector(state => state.auth);
|
||||
|
||||
const handleAuthForm = (e) => {
|
||||
if(err.err) {
|
||||
setErr({ ...err, err: false})
|
||||
@ -42,9 +44,16 @@ const Login = () => {
|
||||
return;
|
||||
}
|
||||
dispatch(authAdded({current_user}));
|
||||
console.log(auth);
|
||||
navigate("/dashboard")
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if(!auth == {}) {
|
||||
console.log("BRUHH", auth);
|
||||
navigate("/dashboard")
|
||||
}
|
||||
})
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flex min-h-full flex-1 flex-col justify-center px-6 py-12 lg:px-8">
|
||||
@ -95,7 +104,7 @@ const Login = () => {
|
||||
</div>
|
||||
<div>
|
||||
<button
|
||||
className="flex w-full justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
|
||||
className="flex w-full justify-center rounded-md bg-primary px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
|
||||
type="submit"
|
||||
>
|
||||
Sign in
|
||||
|
58
src/pages/News/index.jsx
Normal file
58
src/pages/News/index.jsx
Normal file
@ -0,0 +1,58 @@
|
||||
import { useMemo } from 'react';
|
||||
import { DataTable } from '../../components';
|
||||
import data from '../../datas/articles.json';
|
||||
import moment from 'moment';
|
||||
|
||||
const News = () => {
|
||||
|
||||
let roleTemp = [];
|
||||
data.map(({ type }) => {
|
||||
roleTemp.push(type)
|
||||
})
|
||||
|
||||
const proccessed_data = data.map((obj, i) => ({ ...obj, publish_date: moment(obj.publish_date).format('DD MMMM YYYY')}))
|
||||
|
||||
const type_set = new Set([...roleTemp]);
|
||||
const type = [...type_set];
|
||||
|
||||
const columns = useMemo(
|
||||
() => [
|
||||
{
|
||||
Header: () => <span>No</span>,
|
||||
id: 'rowNumber',
|
||||
width: 30,
|
||||
},
|
||||
{
|
||||
Header: "Type",
|
||||
accessor: 'type'
|
||||
},
|
||||
{
|
||||
Header: "Title",
|
||||
accessor: 'title'
|
||||
},
|
||||
{
|
||||
Header: "Publish",
|
||||
accessor: 'publish_date'
|
||||
},
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flex flex-row justify-end">
|
||||
<button className='bg-primary rounded justify-center hover:bg-opacity-70 text-gray font-medium px-4 py-3 flex'>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="mr-3" style={{ alignSelf: 'center' }} fill="white" height="18" viewBox="0 -960 960 960" width="18"><path d="M730-400v-130H600v-60h130v-130h60v130h130v60H790v130h-60Zm-370-81q-66 0-108-42t-42-108q0-66 42-108t108-42q66 0 108 42t42 108q0 66-42 108t-108 42ZM40-160v-94q0-35 17.5-63.5T108-360q75-33 133.338-46.5 58.339-13.5 118.5-13.5Q420-420 478-406.5 536-393 611-360q33 15 51 43t18 63v94H40Zm60-60h520v-34q0-16-9-30.5T587-306q-71-33-120-43.5T360-360q-58 0-107.5 10.5T132-306q-15 7-23.5 21.5T100-254v34Zm260-321q39 0 64.5-25.5T450-631q0-39-25.5-64.5T360-721q-39 0-64.5 25.5T270-631q0 39 25.5 64.5T360-541Zm0-90Zm0 411Z" /></svg>
|
||||
Create News
|
||||
</button>
|
||||
</div>
|
||||
<div className="p-4 bg-white mt-8 rounded">
|
||||
<div className='mt-4'>
|
||||
<DataTable columns={columns} data={proccessed_data} tabFilterData={type} />
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default News;
|
58
src/pages/User/index.jsx
Normal file
58
src/pages/User/index.jsx
Normal file
@ -0,0 +1,58 @@
|
||||
import { useMemo } from 'react';
|
||||
import data from '../../datas/users.json';
|
||||
import { DataTable } from '../../components';
|
||||
|
||||
const User = () => {
|
||||
|
||||
let roleTemp = [];
|
||||
data.map(({ role_name }) => {
|
||||
roleTemp.push(role_name)
|
||||
})
|
||||
|
||||
const role_set = new Set([...roleTemp]);
|
||||
const role = [...role_set];
|
||||
|
||||
const columns = useMemo(
|
||||
() => [
|
||||
{
|
||||
Header: () => <span>No</span>,
|
||||
id: 'rowNumber',
|
||||
width: 30,
|
||||
},
|
||||
{
|
||||
Header: "Name",
|
||||
accessor: 'name'
|
||||
},
|
||||
{
|
||||
Header: "Phone",
|
||||
accessor: 'phone'
|
||||
},
|
||||
{
|
||||
Header: "Email",
|
||||
accessor: 'email'
|
||||
},
|
||||
{
|
||||
Header: "Role",
|
||||
accessor: "role_name"
|
||||
}
|
||||
]
|
||||
)
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flex flex-row justify-end">
|
||||
<button className='bg-primary rounded justify-center hover:bg-opacity-70 text-gray font-medium px-4 py-3 flex'>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="mr-3" style={{ alignSelf: 'center' }} fill="white" height="18" viewBox="0 -960 960 960" width="18"><path d="M730-400v-130H600v-60h130v-130h60v130h130v60H790v130h-60Zm-370-81q-66 0-108-42t-42-108q0-66 42-108t108-42q66 0 108 42t42 108q0 66-42 108t-108 42ZM40-160v-94q0-35 17.5-63.5T108-360q75-33 133.338-46.5 58.339-13.5 118.5-13.5Q420-420 478-406.5 536-393 611-360q33 15 51 43t18 63v94H40Zm60-60h520v-34q0-16-9-30.5T587-306q-71-33-120-43.5T360-360q-58 0-107.5 10.5T132-306q-15 7-23.5 21.5T100-254v34Zm260-321q39 0 64.5-25.5T450-631q0-39-25.5-64.5T360-721q-39 0-64.5 25.5T270-631q0 39 25.5 64.5T360-541Zm0-90Zm0 411Z" /></svg>
|
||||
Add User
|
||||
</button>
|
||||
</div>
|
||||
<div className="p-4 bg-white mt-8 rounded">
|
||||
<div className='mt-4'>
|
||||
<DataTable columns={columns} data={data} tabFilterData={role} />
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default User;
|
@ -1,9 +1,13 @@
|
||||
import Login from './Login';
|
||||
import Notfound404 from './Notfound404';
|
||||
import Dashboard from './Dashboard';
|
||||
import User from './User';
|
||||
import News from './News';
|
||||
|
||||
export {
|
||||
Login,
|
||||
Notfound404,
|
||||
Dashboard,
|
||||
User,
|
||||
News
|
||||
}
|
@ -1,18 +1,24 @@
|
||||
import {
|
||||
Dashboard,
|
||||
Login,
|
||||
Notfound404
|
||||
Dashboard,
|
||||
User,
|
||||
News
|
||||
} from "../pages";
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: "/",
|
||||
element: <Login />,
|
||||
errorElement: <Notfound404 />
|
||||
path: "/dashboard",
|
||||
name: "Dashboard",
|
||||
element: <Dashboard />
|
||||
},
|
||||
{
|
||||
path: "/dashboard",
|
||||
element: <Dashboard />
|
||||
path: "/users",
|
||||
name: "Users",
|
||||
element: <User />
|
||||
},
|
||||
{
|
||||
path: "/news",
|
||||
name: "News",
|
||||
element: <News />
|
||||
}
|
||||
]
|
||||
|
||||
|
7
src/utils/common.js
Normal file
7
src/utils/common.js
Normal file
@ -0,0 +1,7 @@
|
||||
export const getRouteName = (pathName) => {
|
||||
return pathName.replace(/\/(.)/, (_, firstLetter) => firstLetter.toUpperCase());
|
||||
}
|
||||
|
||||
export const classNames = (...classes) => {
|
||||
return classes.filter(Boolean).join(" ");
|
||||
}
|
6
src/utils/index.js
Normal file
6
src/utils/index.js
Normal file
@ -0,0 +1,6 @@
|
||||
import { getRouteName, classNames} from './common';
|
||||
|
||||
export {
|
||||
getRouteName,
|
||||
classNames,
|
||||
}
|
@ -1,14 +1,215 @@
|
||||
const defaultTheme = require('tailwindcss/defaultTheme')
|
||||
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
export default {
|
||||
content: [
|
||||
"./index.html",
|
||||
"./src/**/*.{js,jsx,ts,tsx}",
|
||||
],
|
||||
module.exports = {
|
||||
content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
|
||||
darkMode: 'class',
|
||||
theme: {
|
||||
extend: {},
|
||||
fontFamily: {
|
||||
satoshi: ['Satoshi', 'sans-serif'],
|
||||
},
|
||||
colors: {
|
||||
current: 'currentColor',
|
||||
transparent: 'transparent',
|
||||
white: '#FFFFFF',
|
||||
black: '#1C2434',
|
||||
body: '#64748B',
|
||||
bodydark: '#AEB7C0',
|
||||
bodydark1: '#DEE4EE',
|
||||
bodydark2: '#8A99AF',
|
||||
primary: '#022b3a',
|
||||
stroke: '#E2E8F0',
|
||||
gray: '#EFF4FB',
|
||||
graydark: '#333A48',
|
||||
whiten: '#F1F5F9',
|
||||
whiter: '#F5F7FD',
|
||||
boxdark: '#24303F',
|
||||
'boxdark-2': '#1A222C',
|
||||
strokedark: '#2E3A47',
|
||||
red: '#dc3545'
|
||||
},
|
||||
screens: {
|
||||
'2xsm': '375px',
|
||||
xsm: '425px',
|
||||
'3xl': '2000px',
|
||||
...defaultTheme.screens,
|
||||
},
|
||||
extend: {
|
||||
fontSize: {
|
||||
'title-xxl': ['44px', '55px'],
|
||||
'title-xl': ['36px', '45px'],
|
||||
'title-xl2': ['33px', '45px'],
|
||||
'title-lg': ['28px', '35px'],
|
||||
'title-md': ['24px', '30px'],
|
||||
'title-md2': ['26px', '30px'],
|
||||
'title-sm': ['20px', '26px'],
|
||||
'title-xsm': ['18px', '24px'],
|
||||
},
|
||||
spacing: {
|
||||
4.5: '1.125rem',
|
||||
5.5: '1.375rem',
|
||||
6.5: '1.625rem',
|
||||
7.5: '1.875rem',
|
||||
8.5: '2.125rem',
|
||||
9.5: '2.375rem',
|
||||
10.5: '2.625rem',
|
||||
11: '2.75rem',
|
||||
11.5: '2.875rem',
|
||||
12.5: '3.125rem',
|
||||
13: '3.25rem',
|
||||
13.5: '3.375rem',
|
||||
14: '3.5rem',
|
||||
14.5: '3.625rem',
|
||||
15: '3.75rem',
|
||||
15.5: '3.875rem',
|
||||
16: '4rem',
|
||||
16.5: '4.125rem',
|
||||
17: '4.25rem',
|
||||
17.5: '4.375rem',
|
||||
18: '4.5rem',
|
||||
18.5: '4.625rem',
|
||||
19: '4.75rem',
|
||||
19.5: '4.875rem',
|
||||
21: '5.25rem',
|
||||
21.5: '5.375rem',
|
||||
22: '5.5rem',
|
||||
22.5: '5.625rem',
|
||||
24.5: '6.125rem',
|
||||
25: '6.25rem',
|
||||
25.5: '6.375rem',
|
||||
26: '6.5rem',
|
||||
27: '6.75rem',
|
||||
27.5: '6.875rem',
|
||||
29: '7.25rem',
|
||||
29.5: '7.375rem',
|
||||
30: '7.5rem',
|
||||
31: '7.75rem',
|
||||
32.5: '8.125rem',
|
||||
34: '8.5rem',
|
||||
34.5: '8.625rem',
|
||||
35: '8.75rem',
|
||||
36.5: '9.125rem',
|
||||
37.5: '9.375rem',
|
||||
39: '9.75rem',
|
||||
39.5: '9.875rem',
|
||||
40: '10rem',
|
||||
42.5: '10.625rem',
|
||||
44: '11rem',
|
||||
45: '11.25rem',
|
||||
46: '11.5rem',
|
||||
47.5: '11.875rem',
|
||||
49: '12.25rem',
|
||||
50: '12.5rem',
|
||||
52: '13rem',
|
||||
52.5: '13.125rem',
|
||||
54: '13.5rem',
|
||||
54.5: '13.625rem',
|
||||
55: '13.75rem',
|
||||
55.5: '13.875rem',
|
||||
59: '14.75rem',
|
||||
60: '15rem',
|
||||
62.5: '15.625rem',
|
||||
65: '16.25rem',
|
||||
67: '16.75rem',
|
||||
67.5: '16.875rem',
|
||||
70: '17.5rem',
|
||||
72.5: '18.125rem',
|
||||
73: '18.25rem',
|
||||
75: '18.75rem',
|
||||
90: '22.5rem',
|
||||
94: '23.5rem',
|
||||
95: '23.75rem',
|
||||
100: '25rem',
|
||||
115: '28.75rem',
|
||||
125: '31.25rem',
|
||||
132.5: '33.125rem',
|
||||
150: '37.5rem',
|
||||
171.5: '42.875rem',
|
||||
180: '45rem',
|
||||
187.5: '46.875rem',
|
||||
203: '50.75rem',
|
||||
230: '57.5rem',
|
||||
242.5: '60.625rem',
|
||||
},
|
||||
maxWidth: {
|
||||
2.5: '0.625rem',
|
||||
3: '0.75rem',
|
||||
4: '1rem',
|
||||
11: '2.75rem',
|
||||
13: '3.25rem',
|
||||
14: '3.5rem',
|
||||
15: '3.75rem',
|
||||
22.5: '5.625rem',
|
||||
25: '6.25rem',
|
||||
30: '7.5rem',
|
||||
34: '8.5rem',
|
||||
35: '8.75rem',
|
||||
40: '10rem',
|
||||
42.5: '10.625rem',
|
||||
44: '11rem',
|
||||
45: '11.25rem',
|
||||
70: '17.5rem',
|
||||
90: '22.5rem',
|
||||
94: '23.5rem',
|
||||
125: '31.25rem',
|
||||
132.5: '33.125rem',
|
||||
142.5: '35.625rem',
|
||||
150: '37.5rem',
|
||||
180: '45rem',
|
||||
203: '50.75rem',
|
||||
230: '57.5rem',
|
||||
242.5: '60.625rem',
|
||||
270: '67.5rem',
|
||||
280: '70rem',
|
||||
292.5: '73.125rem',
|
||||
},
|
||||
maxHeight: {
|
||||
35: '8.75rem',
|
||||
70: '17.5rem',
|
||||
90: '22.5rem',
|
||||
550: '34.375rem',
|
||||
300: '18.75rem',
|
||||
},
|
||||
minWidth: {
|
||||
22.5: '5.625rem',
|
||||
42.5: '10.625rem',
|
||||
47.5: '11.875rem',
|
||||
75: '18.75rem',
|
||||
},
|
||||
zIndex: {
|
||||
999999: '999999',
|
||||
99999: '99999',
|
||||
9999: '9999',
|
||||
999: '999',
|
||||
99: '99',
|
||||
9: '9',
|
||||
1: '1',
|
||||
},
|
||||
opacity: {
|
||||
65: '.65',
|
||||
},
|
||||
borderWidth: {
|
||||
6: '6px',
|
||||
},
|
||||
boxShadow: {
|
||||
default: '0px 8px 13px -3px rgba(0, 0, 0, 0.07)',
|
||||
card: '0px 1px 3px rgba(0, 0, 0, 0.12)',
|
||||
'card-2': '0px 1px 2px rgba(0, 0, 0, 0.05)',
|
||||
switcher:
|
||||
'0px 2px 4px rgba(0, 0, 0, 0.2), inset 0px 2px 2px #FFFFFF, inset 0px -1px 1px rgba(0, 0, 0, 0.1)',
|
||||
'switch-1': '0px 0px 5px rgba(0, 0, 0, 0.15)',
|
||||
1: '0px 1px 3px rgba(0, 0, 0, 0.08)',
|
||||
2: '0px 1px 4px rgba(0, 0, 0, 0.12)',
|
||||
3: '0px 1px 5px rgba(0, 0, 0, 0.14)',
|
||||
4: '0px 4px 10px rgba(0, 0, 0, 0.12)',
|
||||
5: '0px 1px 1px rgba(0, 0, 0, 0.15)',
|
||||
6: '0px 3px 15px rgba(0, 0, 0, 0.1)',
|
||||
7: '-5px 0 0 #313D4A, 5px 0 0 #313D4A',
|
||||
8: '1px 0 0 #313D4A, -1px 0 0 #313D4A, 0 1px 0 #313D4A, 0 -1px 0 #313D4A, 0 3px 13px rgb(0 0 0 / 8%)',
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
require('@tailwindcss/forms'),
|
||||
require('@tailwindcss/forms')
|
||||
],
|
||||
}
|
||||
|
||||
}
|
196
yarn.lock
196
yarn.lock
@ -184,7 +184,7 @@
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.22.5"
|
||||
|
||||
"@babel/runtime@^7.12.1", "@babel/runtime@^7.9.2":
|
||||
"@babel/runtime@^7.12.1", "@babel/runtime@^7.14.6", "@babel/runtime@^7.9.2":
|
||||
version "7.22.10"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.10.tgz#ae3e9631fd947cb7e3610d3e9d8fef5f76696682"
|
||||
integrity sha512-21t/fkKLMZI4pqP2wlmsQAWnYW1PDyKyyUV4vCi+B25ydmdaYTKXPwCj0BzSUnZf4seIiYvSA3jcZ3gdsMFkLQ==
|
||||
@ -367,6 +367,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.47.0.tgz#5478fdf443ff8158f9de171c704ae45308696c7d"
|
||||
integrity sha512-P6omY1zv5MItm93kLM8s2vr1HICJH8v0dvddDhysbIuZ+vcjOHg5Zbkf1mTkcmi2JA9oBG2anOkRnW8WJTS8Og==
|
||||
|
||||
"@heroicons/react@v1":
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/@heroicons/react/-/react-1.0.6.tgz#35dd26987228b39ef2316db3b1245c42eb19e324"
|
||||
integrity sha512-JJCXydOFWMDpCP4q13iEplA503MQO3xLoZiKum+955ZCtHINWnx26CUxVxxFQu/uLb4LW3ge15ZpzIkXKkJ8oQ==
|
||||
|
||||
"@humanwhocodes/config-array@^0.11.10":
|
||||
version "0.11.10"
|
||||
resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.10.tgz#5a3ffe32cc9306365fb3fd572596cd602d5e12d2"
|
||||
@ -461,6 +466,35 @@
|
||||
dependencies:
|
||||
mini-svg-data-uri "^1.2.3"
|
||||
|
||||
"@types/d3-array@^3.0.1":
|
||||
version "3.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3-array/-/d3-array-3.0.5.tgz#857c1afffd3f51319bbc5b301956aca68acaa7b8"
|
||||
integrity sha512-Qk7fpJ6qFp+26VeQ47WY0mkwXaiq8+76RJcncDEfMc2ocRzXLO67bLFRNI4OX1aGBoPzsM5Y2T+/m1pldOgD+A==
|
||||
|
||||
"@types/d3-path@*":
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3-path/-/d3-path-3.0.0.tgz#939e3a784ae4f80b1fde8098b91af1776ff1312b"
|
||||
integrity sha512-0g/A+mZXgFkQxN3HniRDbXMN79K3CdTpLsevj+PXiTcb2hVyvkZUBg37StmgCQkaD84cUJ4uaDAWq7UJOQy2Tg==
|
||||
|
||||
"@types/d3-scale@^4.0.1":
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-4.0.3.tgz#7a5780e934e52b6f63ad9c24b105e33dd58102b5"
|
||||
integrity sha512-PATBiMCpvHJSMtZAMEhc2WyL+hnzarKzI6wAHYjhsonjWJYGq5BXTzQjv4l8m2jO183/4wZ90rKvSeT7o72xNQ==
|
||||
dependencies:
|
||||
"@types/d3-time" "*"
|
||||
|
||||
"@types/d3-shape@^3.0.1":
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-3.1.1.tgz#15cc497751dac31192d7aef4e67a8d2c62354b95"
|
||||
integrity sha512-6Uh86YFF7LGg4PQkuO2oG6EMBRLuW9cbavUW46zkIO5kuS2PfTqo2o9SkgtQzguBHbLgNnU90UNsITpsX1My+A==
|
||||
dependencies:
|
||||
"@types/d3-path" "*"
|
||||
|
||||
"@types/d3-time@*":
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-3.0.0.tgz#e1ac0f3e9e195135361fa1a1d62f795d87e6e819"
|
||||
integrity sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg==
|
||||
|
||||
"@types/hoist-non-react-statics@^3.3.1":
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f"
|
||||
@ -474,6 +508,18 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf"
|
||||
integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==
|
||||
|
||||
"@types/raf@^3.4.0":
|
||||
version "3.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/raf/-/raf-3.4.0.tgz#2b72cbd55405e071f1c4d29992638e022b20acc2"
|
||||
integrity sha512-taW5/WYqo36N7V39oYyHP9Ipfd5pNFvGTIQsNGj86xV88YQ7GnI30/yMfKDF7Zgin0m3e+ikX88FvImnK4RjGw==
|
||||
|
||||
"@types/react-dom@^17.0.9":
|
||||
version "17.0.20"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.20.tgz#e0c8901469d732b36d8473b40b679ad899da1b53"
|
||||
integrity sha512-4pzIjSxDueZZ90F52mU3aPoogkHIoSIDG+oQ+wQK7Cy2B9S+MvOqY0uEA/qawKz381qrEDkvpwyt8Bm31I8sbA==
|
||||
dependencies:
|
||||
"@types/react" "^17"
|
||||
|
||||
"@types/react-dom@^18.2.7":
|
||||
version "18.2.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.7.tgz#67222a08c0a6ae0a0da33c3532348277c70abb63"
|
||||
@ -490,6 +536,15 @@
|
||||
"@types/scheduler" "*"
|
||||
csstype "^3.0.2"
|
||||
|
||||
"@types/react@^17", "@types/react@^17.0.14":
|
||||
version "17.0.64"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.64.tgz#468162c66c33ddb4548eb1a0e36682028d9e9a62"
|
||||
integrity sha512-IlgbX/vglDTwrCRgad6fTCzOT+D/5C0xwuvrzfuqfhg9gJrkFqAGADpUFlEtqbrP1IEo9QLSbo41MaFfoIu9Aw==
|
||||
dependencies:
|
||||
"@types/prop-types" "*"
|
||||
"@types/scheduler" "*"
|
||||
csstype "^3.0.2"
|
||||
|
||||
"@types/scheduler@*":
|
||||
version "0.16.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.3.tgz#cef09e3ec9af1d63d2a6cc5b383a737e24e6dcf5"
|
||||
@ -799,6 +854,95 @@ csstype@^3.0.2:
|
||||
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b"
|
||||
integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==
|
||||
|
||||
d3-array@2, d3-array@^2.12.1, d3-array@^2.3.0:
|
||||
version "2.12.1"
|
||||
resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-2.12.1.tgz#e20b41aafcdffdf5d50928004ececf815a465e81"
|
||||
integrity sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==
|
||||
dependencies:
|
||||
internmap "^1.0.0"
|
||||
|
||||
"d3-array@2 - 3":
|
||||
version "3.2.4"
|
||||
resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-3.2.4.tgz#15fec33b237f97ac5d7c986dc77da273a8ed0bb5"
|
||||
integrity sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==
|
||||
dependencies:
|
||||
internmap "1 - 2"
|
||||
|
||||
"d3-color@1 - 2":
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-2.0.0.tgz#8d625cab42ed9b8f601a1760a389f7ea9189d62e"
|
||||
integrity sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ==
|
||||
|
||||
d3-delaunay@5.3.0:
|
||||
version "5.3.0"
|
||||
resolved "https://registry.yarnpkg.com/d3-delaunay/-/d3-delaunay-5.3.0.tgz#b47f05c38f854a4e7b3cea80e0bb12e57398772d"
|
||||
integrity sha512-amALSrOllWVLaHTnDLHwMIiz0d1bBu9gZXd1FiLfXf8sHcX9jrcj81TVZOqD4UX7MgBZZ07c8GxzEgBpJqc74w==
|
||||
dependencies:
|
||||
delaunator "4"
|
||||
|
||||
"d3-format@1 - 2":
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-2.0.0.tgz#a10bcc0f986c372b729ba447382413aabf5b0767"
|
||||
integrity sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA==
|
||||
|
||||
"d3-interpolate@1.2.0 - 2":
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-2.0.1.tgz#98be499cfb8a3b94d4ff616900501a64abc91163"
|
||||
integrity sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==
|
||||
dependencies:
|
||||
d3-color "1 - 2"
|
||||
|
||||
"d3-path@1 - 2":
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-2.0.0.tgz#55d86ac131a0548adae241eebfb56b4582dd09d8"
|
||||
integrity sha512-ZwZQxKhBnv9yHaiWd6ZU4x5BtCQ7pXszEV9CU6kRgwIQVQGLMv1oiL4M+MK/n79sYzsj+gcgpPQSctJUsLN7fA==
|
||||
|
||||
d3-scale@^3.3.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-3.3.0.tgz#28c600b29f47e5b9cd2df9749c206727966203f3"
|
||||
integrity sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ==
|
||||
dependencies:
|
||||
d3-array "^2.3.0"
|
||||
d3-format "1 - 2"
|
||||
d3-interpolate "1.2.0 - 2"
|
||||
d3-time "^2.1.1"
|
||||
d3-time-format "2 - 3"
|
||||
|
||||
d3-shape@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-2.1.0.tgz#3b6a82ccafbc45de55b57fcf956c584ded3b666f"
|
||||
integrity sha512-PnjUqfM2PpskbSLTJvAzp2Wv4CZsnAgTfcVRTwW03QR3MkXF8Uo7B1y/lWkAsmbKwuecto++4NlsYcvYpXpTHA==
|
||||
dependencies:
|
||||
d3-path "1 - 2"
|
||||
|
||||
"d3-time-format@2 - 3":
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-3.0.0.tgz#df8056c83659e01f20ac5da5fdeae7c08d5f1bb6"
|
||||
integrity sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag==
|
||||
dependencies:
|
||||
d3-time "1 - 2"
|
||||
|
||||
d3-time-format@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-4.1.0.tgz#7ab5257a5041d11ecb4fe70a5c7d16a195bb408a"
|
||||
integrity sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==
|
||||
dependencies:
|
||||
d3-time "1 - 3"
|
||||
|
||||
"d3-time@1 - 2", d3-time@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-2.1.1.tgz#e9d8a8a88691f4548e68ca085e5ff956724a6682"
|
||||
integrity sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==
|
||||
dependencies:
|
||||
d3-array "2"
|
||||
|
||||
"d3-time@1 - 3":
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-3.1.0.tgz#9310db56e992e3c0175e1ef385e545e48a9bb5c7"
|
||||
integrity sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==
|
||||
dependencies:
|
||||
d3-array "2 - 3"
|
||||
|
||||
debug@^4.1.0, debug@^4.1.1, debug@^4.3.2:
|
||||
version "4.3.4"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
|
||||
@ -819,6 +963,11 @@ define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0:
|
||||
has-property-descriptors "^1.0.0"
|
||||
object-keys "^1.1.1"
|
||||
|
||||
delaunator@4:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/delaunator/-/delaunator-4.0.1.tgz#3d779687f57919a7a418f8ab947d3bddb6846957"
|
||||
integrity sha512-WNPWi1IRKZfCt/qIDMfERkDp93+iZEmOxN2yy4Jg+Xhv8SLk2UTqqbe1sfiipn0and9QrE914/ihdx82Y/Giag==
|
||||
|
||||
didyoumean@^1.2.2:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037"
|
||||
@ -1381,6 +1530,16 @@ internal-slot@^1.0.3, internal-slot@^1.0.5:
|
||||
has "^1.0.3"
|
||||
side-channel "^1.0.4"
|
||||
|
||||
"internmap@1 - 2":
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/internmap/-/internmap-2.0.3.tgz#6685f23755e43c524e251d29cbc97248e3061009"
|
||||
integrity sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==
|
||||
|
||||
internmap@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/internmap/-/internmap-1.0.1.tgz#0017cc8a3b99605f0302f2b198d272e015e5df95"
|
||||
integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==
|
||||
|
||||
is-array-buffer@^3.0.1, is-array-buffer@^3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.2.tgz#f2653ced8412081638ecb0ebbd0c41c6e0aecbbe"
|
||||
@ -1634,6 +1793,11 @@ minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2:
|
||||
dependencies:
|
||||
brace-expansion "^1.1.7"
|
||||
|
||||
moment@^2.29.4:
|
||||
version "2.29.4"
|
||||
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108"
|
||||
integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==
|
||||
|
||||
ms@2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
|
||||
@ -1895,6 +2059,26 @@ queue-microtask@^1.2.2:
|
||||
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
|
||||
integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
|
||||
|
||||
react-charts@^3.0.0-beta.55:
|
||||
version "3.0.0-beta.55"
|
||||
resolved "https://registry.yarnpkg.com/react-charts/-/react-charts-3.0.0-beta.55.tgz#07b91432f18bd739030cb742bcde915a62760633"
|
||||
integrity sha512-PuPGoK/3B4SgmnANqh1+biuJAN/iYAvLO/juLKJ2dtF0+Wzfa0KarGbgAij2o8P83bAn9bZnu46RCevNvYwOjQ==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.14.6"
|
||||
"@types/d3-array" "^3.0.1"
|
||||
"@types/d3-scale" "^4.0.1"
|
||||
"@types/d3-shape" "^3.0.1"
|
||||
"@types/raf" "^3.4.0"
|
||||
"@types/react" "^17.0.14"
|
||||
"@types/react-dom" "^17.0.9"
|
||||
d3-array "^2.12.1"
|
||||
d3-delaunay "5.3.0"
|
||||
d3-scale "^3.3.0"
|
||||
d3-shape "^2.1.0"
|
||||
d3-time "^2.1.1"
|
||||
d3-time-format "^4.1.0"
|
||||
ts-toolbelt "^9.6.0"
|
||||
|
||||
react-dom@^18.2.0:
|
||||
version "18.2.0"
|
||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d"
|
||||
@ -1945,6 +2129,11 @@ react-router@6.15.0:
|
||||
dependencies:
|
||||
"@remix-run/router" "1.8.0"
|
||||
|
||||
react-table@^7.8.0:
|
||||
version "7.8.0"
|
||||
resolved "https://registry.yarnpkg.com/react-table/-/react-table-7.8.0.tgz#07858c01c1718c09f7f1aed7034fcfd7bda907d2"
|
||||
integrity sha512-hNaz4ygkZO4bESeFfnfOft73iBUj8K5oKi1EcSHPAibEydfsX2MyU6Z8KCr3mv3C9Kqqh71U+DhZkFvibbnPbA==
|
||||
|
||||
react@^18.2.0:
|
||||
version "18.2.0"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5"
|
||||
@ -2257,6 +2446,11 @@ ts-interface-checker@^0.1.9:
|
||||
resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699"
|
||||
integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==
|
||||
|
||||
ts-toolbelt@^9.6.0:
|
||||
version "9.6.0"
|
||||
resolved "https://registry.yarnpkg.com/ts-toolbelt/-/ts-toolbelt-9.6.0.tgz#50a25426cfed500d4a09bd1b3afb6f28879edfd5"
|
||||
integrity sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==
|
||||
|
||||
type-check@^0.4.0, type-check@~0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"
|
||||
|
Loading…
Reference in New Issue
Block a user