initialization
@@ -5,4 +5,8 @@ REACT_APP_STAFF_TOKEN=
|
|||||||
REACT_APP_GOOGLE_MAPS_API_KEY=AIzaSyCF4KatYCI3vqz1_H3kiHeyS3yCMfYToh8
|
REACT_APP_GOOGLE_MAPS_API_KEY=AIzaSyCF4KatYCI3vqz1_H3kiHeyS3yCMfYToh8
|
||||||
REACT_APP_RIDER_ACCESS_ID=AAAAILMpCEU:APA91bEavuOllBI6sFgYtxXAgNmAVwNA-MnCMHLGlR4_t7UqpLajAkdn3T0CZr_zaLBknLyim9ytFLMZgbeXmKqTad_PKCbqlYjHpaizVrLXtecxqyEy4UktIacK2UvHVUATHL-7VQQk
|
REACT_APP_RIDER_ACCESS_ID=AAAAILMpCEU:APA91bEavuOllBI6sFgYtxXAgNmAVwNA-MnCMHLGlR4_t7UqpLajAkdn3T0CZr_zaLBknLyim9ytFLMZgbeXmKqTad_PKCbqlYjHpaizVrLXtecxqyEy4UktIacK2UvHVUATHL-7VQQk
|
||||||
|
|
||||||
|
GENERATE_SOURCEMAP=false
|
||||||
|
DISABLE_ESLINT_PLUGIN=true
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
REACT_APP_URL=https://jupiter.nearle.app/live/api/v1
|
REACT_APP_URL=https://jupiter.nearle.app/live/api/v1
|
||||||
REACT_APP_URL2=
|
REACT_APP_URL2=
|
||||||
REACT_APP_STAFF_TOKEN=
|
REACT_APP_STAFF_TOKEN=
|
||||||
|
|
||||||
|
GENERATE_SOURCEMAP=false
|
||||||
|
DISABLE_ESLINT_PLUGIN=true
|
||||||
32
CLAUDE.md
@@ -174,43 +174,43 @@ const AccentAvatar = ({ color, selected, size = 24, children }) => (
|
|||||||
|
|
||||||
### Page anatomy (every operator page should follow this order)
|
### Page anatomy (every operator page should follow this order)
|
||||||
|
|
||||||
> **Use brand purple `#662582` (with light variant `#9255AB`) for every brand surface below.** Don't use indigo `#6366f1` — that's reserved for the "Accepted" status badge only.
|
> **Use brand red `#C01227` (with light variant `#D35968`) for every brand surface below.** Don't use indigo `#6366f1` — that's reserved for the "Accepted" status badge only.
|
||||||
|
|
||||||
1. **Gradient header `<Paper>`** — `linear-gradient(135deg, ${tint('#662582')} 0%, ${tint('#9255AB')} 100%)`, 48px filled `#662582` avatar with a page icon, `Typography variant="h3"` title, "Live · {zone}" sub-line with an 8px green pulsing dot, and a pill `LocationAutocomplete` on the right (`pill accentColor="#662582" paperComponent={SoftPaper}`).
|
1. **Gradient header `<Paper>`** — `linear-gradient(135deg, ${tint('#C01227')} 0%, ${tint('#D35968')} 100%)`, 48px filled `#C01227` avatar with a page icon, `Typography variant="h3"` title, "Live · {zone}" sub-line with an 8px green pulsing dot, and a pill `LocationAutocomplete` on the right (`pill accentColor="#C01227" paperComponent={SoftPaper}`).
|
||||||
2. **KPI tiles row** — `Grid` of 3–4 `Paper` cards, each with a 3px top stripe gradient, uppercase eyebrow label, large bold number, and a soft-tinted avatar holding an icon. The "primary" tile uses brand purple `#662582`; other tiles use semantic status colours.
|
2. **KPI tiles row** — `Grid` of 3–4 `Paper` cards, each with a 3px top stripe gradient, uppercase eyebrow label, large bold number, and a soft-tinted avatar holding an icon. The "primary" tile uses brand red `#C01227`; other tiles use semantic status colours.
|
||||||
3. **Filter bar `<Paper>`** (optional) — pill-style `Autocomplete`s using `pillFieldSx(color)` + `SoftPaper`, each with an `AccentAvatar` start-adornment.
|
3. **Filter bar `<Paper>`** (optional) — pill-style `Autocomplete`s using `pillFieldSx(color)` + `SoftPaper`, each with an `AccentAvatar` start-adornment.
|
||||||
4. **Pill status tabs + pill search** — tabs as clickable `<Box>` pills (active = filled accent + glow ring, inactive = `tint` bg + `edge` border), each with an avatar icon and a count badge. Tab accents use the **semantic status colour** for each tab (pending → amber, delivered → emerald, etc.). Search via `DebounceSearchBar` styled with brand purple `#662582` (tint bg, edge border, focus ring).
|
4. **Pill status tabs + pill search** — tabs as clickable `<Box>` pills (active = filled accent + glow ring, inactive = `tint` bg + `edge` border), each with an avatar icon and a count badge. Tab accents use the **semantic status colour** for each tab (pending → amber, delivered → emerald, etc.). Search via `DebounceSearchBar` styled with brand red `#C01227` (tint bg, edge border, focus ring).
|
||||||
5. **Table `<Paper>`** with `<TableContainer>` + sticky `<TableHead>` — uppercase muted headers on `DT.surfaceAlt`, rows with `borderBottom: 1px solid ${DT.divider}` and `:hover` row tint. Scrollbar thumb uses brand purple `edge('#662582')`.
|
5. **Table `<Paper>`** with `<TableContainer>` + sticky `<TableHead>` — uppercase muted headers on `DT.surfaceAlt`, rows with `borderBottom: 1px solid ${DT.divider}` and `:hover` row tint. Scrollbar thumb uses brand red `edge('#C01227')`.
|
||||||
6. **Status badges in cells** — `Stack` with `AccentAvatar` + label inside a soft pill (tint bg, edge border). Status colours come from a per-page `STATUS_META` map keyed by lowercase status string — these are **semantic**, not brand.
|
6. **Status badges in cells** — `Stack` with `AccentAvatar` + label inside a soft pill (tint bg, edge border). Status colours come from a per-page `STATUS_META` map keyed by lowercase status string — these are **semantic**, not brand.
|
||||||
7. **Edit / action icon buttons** — soft-pill `IconButton` using brand purple `#662582` (NOT `#8b5cf6` — that overlaps with the "Picked" status badge and confuses operators).
|
7. **Edit / action icon buttons** — soft-pill `IconButton` using brand red `#C01227` (NOT `#8b5cf6` — that overlaps with the "Picked" status badge and confuses operators).
|
||||||
8. **Empty state** — centered 64px avatar (soft grey), bold "No X to show" line, and a muted helper sentence. Do not use antd `<Empty />` for new code.
|
8. **Empty state** — centered 64px avatar (soft grey), bold "No X to show" line, and a muted helper sentence. Do not use antd `<Empty />` for new code.
|
||||||
|
|
||||||
### Universal brand colour
|
### Universal brand colour
|
||||||
|
|
||||||
**`#662582` — NearlExpress brand purple.** This is the canonical primary colour for this app, defined in `src/themes/theme/default.js` as `primary.main`. It drives the sidebar, the logo, and is what every new surface (page headers, KPI primary tile, search bars, edit-action buttons, dialog/popup headers, scrollbars) must use as the brand accent.
|
**`#C01227` — NearlExpress brand red.** This is the canonical primary colour for this app, defined in `src/themes/theme/default.js` as `primary.main`. It drives the sidebar, the logo, and is what every new surface (page headers, KPI primary tile, search bars, edit-action buttons, dialog/popup headers, scrollbars) must use as the brand accent.
|
||||||
|
|
||||||
Variants (also from `theme/default.js`):
|
Variants (also from `theme/default.js`):
|
||||||
|
|
||||||
| Token | Hex | Use |
|
| Token | Hex | Use |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `primary.lighter` | `#E8D9EF` | Very subtle wash bg |
|
| `primary.lighter` | `#F6DBDF` | Very subtle wash bg |
|
||||||
| `primary.light` / `primary.400` | `#9255AB` | Gradient pair with main |
|
| `primary.light` / `primary.400` | `#D35968` | Gradient pair with main |
|
||||||
| `primary.main` | `#662582` | Brand primary — default for all brand surfaces |
|
| `primary.main` | `#C01227` | Brand primary — default for all brand surfaces |
|
||||||
| `primary.dark` | `#4D1C61` | Hover / pressed states |
|
| `primary.dark` | `#900E1D` | Hover / pressed states |
|
||||||
| `primary.darker` | `#260E30` | Deep contrast text on light bg |
|
| `primary.darker` | `#47070E` | Deep contrast text on light bg |
|
||||||
|
|
||||||
**Page header / dialog header gradient:** `linear-gradient(135deg, ${tint('#662582')} 0%, ${tint('#9255AB')} 100%)` (subtle wash) or `linear-gradient(135deg, #662582 0%, #9255AB 100%)` (solid, for dialog titles).
|
**Page header / dialog header gradient:** `linear-gradient(135deg, ${tint('#C01227')} 0%, ${tint('#D35968')} 100%)` (subtle wash) or `linear-gradient(135deg, #C01227 0%, #D35968 100%)` (solid, for dialog titles).
|
||||||
|
|
||||||
> **Migration note:** `deliveries.js`, `Tenants.js`, and `clientPricing.js` currently use `#6366f1` (indigo) as their brand accent — a holdover from the first design pass before brand purple was canonicalised. They are scheduled to migrate to `#662582`. `customers.js` and the createorder1 Saved-Address dialog have already been migrated.
|
> **Migration note:** `deliveries.js`, `Tenants.js`, and `clientPricing.js` currently use `#6366f1` (indigo) as their brand accent — a holdover from the first design pass before brand red was canonicalised. They are scheduled to migrate to `#C01227`. `customers.js` and the createorder1 Saved-Address dialog have already been migrated.
|
||||||
|
|
||||||
### Status palette (semantic — distinct from brand)
|
### Status palette (semantic — distinct from brand)
|
||||||
|
|
||||||
These colour-code lifecycle states. Do **not** swap them for brand purple — operators rely on the colour to identify status at a glance.
|
These colour-code lifecycle states. Do **not** swap them for brand red — operators rely on the colour to identify status at a glance.
|
||||||
|
|
||||||
| Meaning | Colour |
|
| Meaning | Colour |
|
||||||
|--------------------------|-----------|
|
|--------------------------|-----------|
|
||||||
| Pending / waiting | `#f59e0b` (amber) |
|
| Pending / waiting | `#f59e0b` (amber) |
|
||||||
| Accepted / assigned | `#6366f1` (indigo — semantically distinct from brand purple) |
|
| Accepted / assigned | `#6366f1` (indigo — semantically distinct from brand red) |
|
||||||
| Arrived | `#06b6d4` (cyan) |
|
| Arrived | `#06b6d4` (cyan) |
|
||||||
| Picked up | `#8b5cf6` (light purple — distinct from brand) |
|
| Picked up | `#8b5cf6` (light purple — distinct from brand) |
|
||||||
| Active / in-transit | `#14b8a6` (teal) |
|
| Active / in-transit | `#14b8a6` (teal) |
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 69 KiB |
@@ -4,8 +4,8 @@
|
|||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<link rel="icon" href="%PUBLIC_URL%/favicon.png" />
|
<link rel="icon" href="%PUBLIC_URL%/favicon.png" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<meta name="theme-color" content="#000000" />
|
<meta name="theme-color" content="#C01227" />
|
||||||
<meta name="description" content="Nearle Neighbourhood commerce" />
|
<meta name="description" content="Doormile — corporate logistics & last-mile delivery admin console" />
|
||||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
||||||
<link
|
<link
|
||||||
rel="stylesheet"
|
rel="stylesheet"
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
work correctly both with client-side routing and a non-root public URL.
|
work correctly both with client-side routing and a non-root public URL.
|
||||||
Learn how to configure a non-root public URL by running `npm run build`.
|
Learn how to configure a non-root public URL by running `npm run build`.
|
||||||
-->
|
-->
|
||||||
<title>Nearle Console</title>
|
<title>Doormile Console</title>
|
||||||
|
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" />
|
<link rel="preconnect" href="https://fonts.gstatic.com" />
|
||||||
<link
|
<link
|
||||||
|
|||||||
BIN
public/logo192.png
Normal file
|
After Width: | Height: | Size: 82 KiB |
BIN
src/assets/images/doormile-logo.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
src/assets/images/doormile-mark.png
Normal file
|
After Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 4.5 KiB |
@@ -1,6 +1,6 @@
|
|||||||
import { styled } from '@mui/material/styles';
|
import { styled } from '@mui/material/styles';
|
||||||
import CircularProgress from '@mui/material/CircularProgress';
|
import CircularProgress from '@mui/material/CircularProgress';
|
||||||
import nelogo from '../assets/images/logo-sm.png';
|
import nelogo from '../assets/images/doormile-mark.png';
|
||||||
|
|
||||||
// Styled Loader Wrapper
|
// Styled Loader Wrapper
|
||||||
const LoaderWrapper = styled('div')(() => ({
|
const LoaderWrapper = styled('div')(() => ({
|
||||||
|
|||||||
@@ -26,13 +26,13 @@ The `DT` design tokens (palette, alpha helpers, `pillFieldSx`, `SoftPaper`, `Acc
|
|||||||
|
|
||||||
**Hard rules when editing components here:**
|
**Hard rules when editing components here:**
|
||||||
|
|
||||||
- **Universal brand colour is `#662582`** (NearlExpress purple — from `themes/theme/default.js` `primary.main`). Every brand surface (page header, dialog header, KPI primary tile, search bars, edit-action buttons, scrollbars) uses this. Gradient pair: `#662582 → #9255AB`.
|
- **Universal brand colour is `#C01227`** (Doormile red — from `themes/theme/default.js` `primary.main`). Every brand surface (page header, dialog header, KPI primary tile, search bars, edit-action buttons, scrollbars) uses this. Gradient pair: `#C01227 → #D35968`.
|
||||||
- **Semantic status palette is distinct** from the brand. Use these for lifecycle indicators only: sky `#0ea5e9`, emerald `#10b981`, amber `#f59e0b`, red `#ef4444`, status-purple `#8b5cf6` (lighter than brand), cyan `#06b6d4`, teal `#14b8a6`, orange `#f97316`, muted `#94a3b8`, indigo `#6366f1` (Accepted status). Don't replace these with brand purple — operators colour-code on them.
|
- **Semantic status palette is distinct** from the brand. Use these for lifecycle indicators only: sky `#0ea5e9`, emerald `#10b981`, amber `#f59e0b`, red `#ef4444`, status-purple `#8b5cf6` (lighter than brand), cyan `#06b6d4`, teal `#14b8a6`, orange `#f97316`, muted `#94a3b8`, indigo `#6366f1` (Accepted status). Don't replace these with brand red — operators colour-code on them.
|
||||||
- Don't introduce a colour from `theme.palette` for new surfaces — those are Mantis defaults and don't match the DT system. Use the hex values above directly.
|
- Don't introduce a colour from `theme.palette` for new surfaces — those are Mantis defaults and don't match the DT system. Use the hex values above directly.
|
||||||
- Border radii: `12` (inner), `16` (card), `999` (pill). No other values.
|
- Border radii: `12` (inner), `16` (card), `999` (pill). No other values.
|
||||||
- Shadows: `DT.shadowSoft` / `DT.shadowMd` / `DT.shadowPop`. No raw `box-shadow` strings.
|
- Shadows: `DT.shadowSoft` / `DT.shadowMd` / `DT.shadowPop`. No raw `box-shadow` strings.
|
||||||
|
|
||||||
> Some existing redesigned pages (`deliveries.js`, `Tenants.js`, `clientPricing.js`) still use `#6366f1` as the brand accent — this is a legacy from the first design pass. `customers.js` and the `createorder1` Saved-Address dialog are already on `#662582`. When you next edit one of the legacy pages, migrate it to brand purple in the same PR.
|
> Some existing redesigned pages (`deliveries.js`, `Tenants.js`, `clientPricing.js`) still use `#6366f1` as the brand accent — this is a legacy from the first design pass. `customers.js` and the `createorder1` Saved-Address dialog are already on `#C01227`. When you next edit one of the legacy pages, migrate it to brand red in the same PR.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// LoaderWithImage.jsx
|
// LoaderWithImage.jsx
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Box, CircularProgress } from '@mui/material';
|
import { Box, CircularProgress } from '@mui/material';
|
||||||
import nelogo from '../../assets/images/logo-sm.png';
|
import nelogo from '../../assets/images/doormile-mark.png';
|
||||||
|
|
||||||
export default function LoaderWithImage({ size = 70, imgSize = 40, alt = 'loader' }) {
|
export default function LoaderWithImage({ size = 70, imgSize = 40, alt = 'loader' }) {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ MobileCardList.propTypes = {
|
|||||||
|
|
||||||
// Card shell — coloured accent rail on the left, a header slot (status badge /
|
// Card shell — coloured accent rail on the left, a header slot (status badge /
|
||||||
// title / action buttons), then any field grid / collapse content as children.
|
// title / action buttons), then any field grid / collapse content as children.
|
||||||
export const MobileCard = ({ accent = '#662582', header, footer, selected = false, onClick, children, sx }) => (
|
export const MobileCard = ({ accent = '#C01227', header, footer, selected = false, onClick, children, sx }) => (
|
||||||
<Paper
|
<Paper
|
||||||
elevation={0}
|
elevation={0}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import { Avatar, Box, Card, CardContent, Skeleton, Stack, Typography } from '@mu
|
|||||||
// `color` is a hex accent (defaults to brand purple); `caption` is the small
|
// `color` is a hex accent (defaults to brand purple); `caption` is the small
|
||||||
// muted line under the value (e.g. "96% of total").
|
// muted line under the value (e.g. "96% of total").
|
||||||
|
|
||||||
export default function StatCard({ title, value, icon, color = '#662582', caption, loading = false }) {
|
export default function StatCard({ title, value, icon, color = '#C01227', caption, loading = false }) {
|
||||||
return (
|
return (
|
||||||
<Card sx={{ height: '100%' }}>
|
<Card sx={{ height: '100%' }}>
|
||||||
<CardContent sx={{ p: { xs: 1.75, md: 2 }, '&:last-child': { pb: { xs: 1.75, md: 2 } } }}>
|
<CardContent sx={{ p: { xs: 1.75, md: 2 }, '&:last-child': { pb: { xs: 1.75, md: 2 } } }}>
|
||||||
|
|||||||
@@ -234,13 +234,27 @@ const NavCollapse = ({ menu, level, parentId, setSelectedItems, selectedItems, s
|
|||||||
|
|
||||||
...(drawerOpen && {
|
...(drawerOpen && {
|
||||||
'&:hover': {
|
'&:hover': {
|
||||||
// bgcolor: theme.palette.mode === ThemeMode.DARK ? 'divider' : 'primary.lighter'
|
bgcolor: '#fff',
|
||||||
bgcolor: '#7b1fa2'
|
'& .MuiTypography-root': {
|
||||||
|
color: '#C01227 !important'
|
||||||
|
},
|
||||||
|
'& svg, & .anticon': {
|
||||||
|
color: '#C01227 !important'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
'&.Mui-selected': {
|
'&.Mui-selected': {
|
||||||
bgcolor: 'transparent',
|
bgcolor: 'transparent',
|
||||||
color: iconSelectedColor,
|
color: iconSelectedColor,
|
||||||
'&:hover': { color: iconSelectedColor, bgcolor: theme.palette.mode === ThemeMode.DARK ? 'divider' : 'transparent' }
|
'&:hover': {
|
||||||
|
bgcolor: '#fff',
|
||||||
|
color: '#C01227',
|
||||||
|
'& .MuiTypography-root': {
|
||||||
|
color: '#C01227 !important'
|
||||||
|
},
|
||||||
|
'& svg, & .anticon': {
|
||||||
|
color: '#C01227 !important'
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
...(!drawerOpen && {
|
...(!drawerOpen && {
|
||||||
@@ -273,20 +287,23 @@ const NavCollapse = ({ menu, level, parentId, setSelectedItems, selectedItems, s
|
|||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
'&:hover': {
|
'&:hover': {
|
||||||
// bgcolor: theme.palette.mode === ThemeMode.DARK ? 'secondary.light' : 'secondary.lighter'
|
bgcolor: '#fff',
|
||||||
bgcolor: '#7b1fa2',
|
'& svg': {
|
||||||
color: 'white'
|
color: '#C01227 !important'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
...(!drawerOpen &&
|
...(!drawerOpen &&
|
||||||
selected === menu.id && {
|
selected === menu.id && {
|
||||||
bgcolor: 'primary.light',
|
bgcolor: 'primary.light',
|
||||||
color: 'primary.main',
|
color: 'primary.main',
|
||||||
'&:hover': {
|
'&:hover': {
|
||||||
bgcolor: '#7b1fa2',
|
bgcolor: '#fff',
|
||||||
color: 'primary.main'
|
'& svg': {
|
||||||
|
color: '#C01227 !important'
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
})
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{menuIcon}
|
{menuIcon}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { forwardRef, useEffect, useState } from 'react';
|
import { forwardRef, useEffect } from 'react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ const NavItem = ({ item, level }) => {
|
|||||||
const isSelected = openItem.findIndex((id) => id === item.id) > -1;
|
const isSelected = openItem.findIndex((id) => id === item.id) > -1;
|
||||||
|
|
||||||
const itemIcon = item.icon ? (
|
const itemIcon = item.icon ? (
|
||||||
<Icon style={{ fontSize: drawerOpen ? '1rem' : '1.25rem', color: isSelected ? '#662582' : '#fff' }} />
|
<Icon style={{ fontSize: drawerOpen ? '1rem' : '1.25rem', color: isSelected ? '#C01227' : '#fff' }} />
|
||||||
) : (
|
) : (
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
@@ -97,87 +97,96 @@ const NavItem = ({ item, level }) => {
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
// dispatch(setSelectedMenu(item));
|
// dispatch(setSelectedMenu(item));
|
||||||
}}
|
}}
|
||||||
sx={{
|
sx={{
|
||||||
zIndex: 1201,
|
zIndex: 1201,
|
||||||
pl: drawerOpen ? `${level * 28}px` : 1.5,
|
pl: drawerOpen ? `${level * 28}px` : 1.5,
|
||||||
py: !drawerOpen && level === 1 ? 1.25 : 1,
|
py: !drawerOpen && level === 1 ? 1.25 : 1,
|
||||||
...(drawerOpen && {
|
...(drawerOpen && {
|
||||||
'&:hover': {
|
|
||||||
bgcolor: '#7b1fa2'
|
|
||||||
},
|
|
||||||
'&.Mui-selected': {
|
|
||||||
bgcolor: theme.palette.mode === ThemeMode.DARK ? 'divider' : 'primary.lighter',
|
|
||||||
borderRight: `2px solid ${theme.palette.primary.main}`,
|
|
||||||
color: iconSelectedColor,
|
|
||||||
'&:hover': {
|
'&:hover': {
|
||||||
color: iconSelectedColor,
|
bgcolor: '#fff',
|
||||||
bgcolor: theme.palette.mode === ThemeMode.DARK ? 'divider' : 'primary.lighter'
|
'& .MuiTypography-root': {
|
||||||
}
|
color: '#C01227 !important'
|
||||||
}
|
},
|
||||||
}),
|
'& svg, & .anticon': {
|
||||||
...(!drawerOpen && {
|
color: '#C01227 !important'
|
||||||
bgcolor: '#662582',
|
|
||||||
'&:hover': {
|
|
||||||
bgcolor: '#662582'
|
|
||||||
},
|
|
||||||
'&.Mui-selected': {
|
|
||||||
'&:hover': {
|
|
||||||
bgcolor: 'transparent'
|
|
||||||
},
|
|
||||||
bgcolor: 'transparent'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
{...(downLG && {
|
|
||||||
onClick: () => {
|
|
||||||
dispatch(openDrawer(false));
|
|
||||||
}
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
{itemIcon && (
|
|
||||||
<ListItemIcon
|
|
||||||
sx={{
|
|
||||||
minWidth: 28,
|
|
||||||
...(!drawerOpen && {
|
|
||||||
borderRadius: 1.5,
|
|
||||||
width: 36,
|
|
||||||
height: 36,
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
'&:hover': {
|
|
||||||
bgcolor: '#7b1fa2'
|
|
||||||
}
|
}
|
||||||
}),
|
},
|
||||||
...(!drawerOpen &&
|
'&.Mui-selected': {
|
||||||
isSelected && {
|
bgcolor: theme.palette.mode === ThemeMode.DARK ? 'divider' : 'primary.lighter',
|
||||||
|
borderRight: `2px solid ${theme.palette.primary.main}`,
|
||||||
|
color: iconSelectedColor,
|
||||||
|
'&:hover': {
|
||||||
|
color: iconSelectedColor,
|
||||||
|
bgcolor: theme.palette.mode === ThemeMode.DARK ? 'divider' : 'primary.lighter'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
...(!drawerOpen && {
|
||||||
|
bgcolor: '#C01227',
|
||||||
|
'&:hover': {
|
||||||
|
bgcolor: '#C01227'
|
||||||
|
},
|
||||||
|
'&.Mui-selected': {
|
||||||
|
'&:hover': {
|
||||||
|
bgcolor: 'transparent'
|
||||||
|
},
|
||||||
|
bgcolor: 'transparent'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
{...(downLG && {
|
||||||
|
onClick: () => {
|
||||||
|
dispatch(openDrawer(false));
|
||||||
|
}
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
{itemIcon && (
|
||||||
|
<ListItemIcon
|
||||||
|
sx={{
|
||||||
|
minWidth: 28,
|
||||||
|
...(!drawerOpen && {
|
||||||
|
borderRadius: 1.5,
|
||||||
|
width: 36,
|
||||||
|
height: 36,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
'&:hover': {
|
||||||
|
bgcolor: '#fff',
|
||||||
|
'& svg, & .anticon': {
|
||||||
|
color: '#C01227 !important'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
...(!drawerOpen &&
|
||||||
|
isSelected && {
|
||||||
bgcolor: theme.palette.mode === ThemeMode.DARK ? 'primary.900' : 'primary.lighter',
|
bgcolor: theme.palette.mode === ThemeMode.DARK ? 'primary.900' : 'primary.lighter',
|
||||||
'&:hover': {
|
'&:hover': {
|
||||||
bgcolor: theme.palette.mode === ThemeMode.DARK ? 'primary.darker' : 'primary.lighter'
|
bgcolor: theme.palette.mode === ThemeMode.DARK ? 'primary.darker' : 'primary.lighter'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{itemIcon}
|
{itemIcon}
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
)}
|
)}
|
||||||
{(drawerOpen || (!drawerOpen && level !== 1)) && (
|
{(drawerOpen || (!drawerOpen && level !== 1)) && (
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primary={
|
primary={
|
||||||
<Typography variant="h6" sx={{ color: isSelected ? iconSelectedColor : textColor, whiteSpace: 'nowrap' }}>
|
<Typography variant="h6" sx={{ color: isSelected ? iconSelectedColor : textColor, whiteSpace: 'nowrap' }}>
|
||||||
{item.title}
|
{item.title}
|
||||||
</Typography>
|
</Typography>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{(drawerOpen || (!drawerOpen && level !== 1)) && item.chip && (
|
{(drawerOpen || (!drawerOpen && level !== 1)) && item.chip && (
|
||||||
<Chip
|
<Chip
|
||||||
color={item.chip.color}
|
color={item.chip.color}
|
||||||
variant={item.chip.variant}
|
variant={item.chip.variant}
|
||||||
size={item.chip.size}
|
size={item.chip.size}
|
||||||
label={item.chip.label}
|
label={item.chip.label}
|
||||||
avatar={item.chip.avatar && <Avatar>{item.chip.avatar}</Avatar>}
|
avatar={item.chip.avatar && <Avatar>{item.chip.avatar}</Avatar>}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</ListItemButton>
|
</ListItemButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
) : (
|
) : (
|
||||||
@@ -229,11 +238,11 @@ const NavItem = ({ item, level }) => {
|
|||||||
}),
|
}),
|
||||||
...(!drawerOpen &&
|
...(!drawerOpen &&
|
||||||
isSelected && {
|
isSelected && {
|
||||||
bgcolor: 'transparent',
|
bgcolor: 'transparent',
|
||||||
'&:hover': {
|
'&:hover': {
|
||||||
bgcolor: 'transparent'
|
bgcolor: 'transparent'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{itemIcon}
|
{itemIcon}
|
||||||
@@ -254,11 +263,11 @@ const NavItem = ({ item, level }) => {
|
|||||||
}),
|
}),
|
||||||
...(!drawerOpen &&
|
...(!drawerOpen &&
|
||||||
isSelected && {
|
isSelected && {
|
||||||
bgcolor: 'transparent',
|
bgcolor: 'transparent',
|
||||||
'&:hover': {
|
'&:hover': {
|
||||||
bgcolor: 'transparent'
|
bgcolor: 'transparent'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Dot size={4} color={isSelected ? 'primary' : 'secondary'} />
|
<Dot size={4} color={isSelected ? 'primary' : 'secondary'} />
|
||||||
|
|||||||
@@ -10,8 +10,12 @@ import DrawerHeaderStyled from './DrawerHeaderStyled';
|
|||||||
import { MenuOrientation } from 'config';
|
import { MenuOrientation } from 'config';
|
||||||
import useConfig from 'hooks/useConfig';
|
import useConfig from 'hooks/useConfig';
|
||||||
|
|
||||||
import logo from 'assets/images/logo-nearle9.png'
|
import logo from 'assets/images/doormile-logo.png'
|
||||||
import logo1 from 'assets/images/logo-sm1.png'
|
import logo1 from 'assets/images/doormile-mark.png'
|
||||||
|
|
||||||
|
// doormile-logo.png is a white asset; this recolours it to brand red (#C01227) for the light sidebar background.
|
||||||
|
const DOORMILE_RED_FILTER = 'brightness(0) saturate(100%) invert(14%) sepia(85%) saturate(4649%) hue-rotate(345deg) brightness(97%) contrast(92%)';
|
||||||
|
|
||||||
// ==============================|| DRAWER HEADER ||============================== //
|
// ==============================|| DRAWER HEADER ||============================== //
|
||||||
|
|
||||||
const DrawerHeader = ({ open }) => {
|
const DrawerHeader = ({ open }) => {
|
||||||
@@ -37,15 +41,13 @@ const DrawerHeader = ({ open }) => {
|
|||||||
|
|
||||||
{(open) &&
|
{(open) &&
|
||||||
<img src={logo}
|
<img src={logo}
|
||||||
// width='160px'
|
style={{ height: '29px', width: 'auto' }}
|
||||||
// height='45px'
|
alt='Doormile'/>
|
||||||
// width='170px'
|
|
||||||
alt='logo'/>
|
|
||||||
}
|
}
|
||||||
{(!open) &&
|
{(!open) &&
|
||||||
<img src={logo1}
|
<img src={logo1}
|
||||||
width='40px'
|
width='50px'
|
||||||
alt='logo'/>
|
alt='Doormile'/>
|
||||||
}
|
}
|
||||||
</DrawerHeaderStyled>
|
</DrawerHeaderStyled>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ const openedMixin = (theme) => ({
|
|||||||
}),
|
}),
|
||||||
overflowX: 'hidden',
|
overflowX: 'hidden',
|
||||||
boxShadow: theme.palette.mode === ThemeMode.DARK ? theme.customShadows.z1 : 'none',
|
boxShadow: theme.palette.mode === ThemeMode.DARK ? theme.customShadows.z1 : 'none',
|
||||||
backgroundColor:'#662582',
|
backgroundColor:'#C01227',
|
||||||
});
|
});
|
||||||
|
|
||||||
const closedMixin = (theme) => ({
|
const closedMixin = (theme) => ({
|
||||||
@@ -27,7 +27,7 @@ const closedMixin = (theme) => ({
|
|||||||
width: theme.spacing(7.5),
|
width: theme.spacing(7.5),
|
||||||
borderRight: 'none',
|
borderRight: 'none',
|
||||||
boxShadow: theme.customShadows.z1,
|
boxShadow: theme.customShadows.z1,
|
||||||
backgroundColor:'#662582',
|
backgroundColor:'#C01227',
|
||||||
});
|
});
|
||||||
|
|
||||||
// ==============================|| DRAWER - MINI STYLED ||============================== //
|
// ==============================|| DRAWER - MINI STYLED ||============================== //
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ const MainDrawer = ({ window }) => {
|
|||||||
borderRight: `1px solid ${theme.palette.divider}`,
|
borderRight: `1px solid ${theme.palette.divider}`,
|
||||||
backgroundImage: 'none',
|
backgroundImage: 'none',
|
||||||
boxShadow: 'inherit',
|
boxShadow: 'inherit',
|
||||||
bgcolor:'#662582'
|
bgcolor:'#C01227'
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import { AppBar, Box, ClickAwayListener, Paper, Popper, Toolbar } from '@mui/mat
|
|||||||
import Profile from './Profile';
|
import Profile from './Profile';
|
||||||
import IconButton from 'components/@extended/IconButton';
|
import IconButton from 'components/@extended/IconButton';
|
||||||
import Transitions from 'components/@extended/Transitions';
|
import Transitions from 'components/@extended/Transitions';
|
||||||
import { ThemeMode } from 'config';
|
|
||||||
|
|
||||||
// assets
|
// assets
|
||||||
import { MoreOutlined } from '@ant-design/icons';
|
import { MoreOutlined } from '@ant-design/icons';
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import {
|
|||||||
import MainCard from 'components/MainCard';
|
import MainCard from 'components/MainCard';
|
||||||
import IconButton from 'components/@extended/IconButton';
|
import IconButton from 'components/@extended/IconButton';
|
||||||
import Transitions from 'components/@extended/Transitions';
|
import Transitions from 'components/@extended/Transitions';
|
||||||
import { ThemeMode } from 'config';
|
|
||||||
|
|
||||||
// assets
|
// assets
|
||||||
import { BellOutlined, CheckCircleOutlined, GiftOutlined, MessageOutlined, SettingOutlined } from '@ant-design/icons';
|
import { BellOutlined, CheckCircleOutlined, GiftOutlined, MessageOutlined, SettingOutlined } from '@ant-design/icons';
|
||||||
@@ -90,7 +89,7 @@ const Notification = () => {
|
|||||||
// color="primary"
|
// color="primary"
|
||||||
sx={{
|
sx={{
|
||||||
"& .MuiBadge-badge": {
|
"& .MuiBadge-badge": {
|
||||||
color: "#662582",
|
color: "#C01227",
|
||||||
backgroundColor: "white"
|
backgroundColor: "white"
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -13,8 +13,6 @@ import Avatar from 'components/@extended/Avatar';
|
|||||||
import MainCard from 'components/MainCard';
|
import MainCard from 'components/MainCard';
|
||||||
import Transitions from 'components/@extended/Transitions';
|
import Transitions from 'components/@extended/Transitions';
|
||||||
import IconButton from 'components/@extended/IconButton';
|
import IconButton from 'components/@extended/IconButton';
|
||||||
|
|
||||||
import { ThemeMode } from 'config';
|
|
||||||
// import useAuth from 'hooks/useAuth';
|
// import useAuth from 'hooks/useAuth';
|
||||||
|
|
||||||
// assets
|
// assets
|
||||||
@@ -83,13 +81,7 @@ const Profile = () => {
|
|||||||
<ButtonBase
|
<ButtonBase
|
||||||
sx={{
|
sx={{
|
||||||
p: 0.25,
|
p: 0.25,
|
||||||
// bgcolor: open ? iconBackColorOpen : 'transparent',
|
|
||||||
borderRadius: 1
|
borderRadius: 1
|
||||||
// '&:hover': { bgcolor: theme.palette.mode === ThemeMode.DARK ? 'secondary.light' : 'secondary.lighter' },
|
|
||||||
// '&:focus-visible': {
|
|
||||||
// outline: `2px solid ${theme.palette.secondary.dark}`,
|
|
||||||
// outlineOffset: 2
|
|
||||||
// }
|
|
||||||
}}
|
}}
|
||||||
aria-label="open profile"
|
aria-label="open profile"
|
||||||
ref={anchorRef}
|
ref={anchorRef}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useMemo, useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
|
||||||
// material-ui
|
// material-ui
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import AppBarStyled from './AppBarStyled';
|
|||||||
import HeaderContent from './HeaderContent';
|
import HeaderContent from './HeaderContent';
|
||||||
import IconButton from 'components/@extended/IconButton';
|
import IconButton from 'components/@extended/IconButton';
|
||||||
|
|
||||||
import { MenuOrientation, ThemeMode } from 'config';
|
import { MenuOrientation } from 'config';
|
||||||
import useConfig from 'hooks/useConfig';
|
import useConfig from 'hooks/useConfig';
|
||||||
import { dispatch, useSelector } from 'store';
|
import { dispatch, useSelector } from 'store';
|
||||||
import { openDrawer } from 'store/reducers/menu';
|
import { openDrawer } from 'store/reducers/menu';
|
||||||
@@ -66,7 +66,7 @@ const Header = () => {
|
|||||||
zIndex: 1200,
|
zIndex: 1200,
|
||||||
width: isHorizontal ? '100%' : drawerOpen ? 'calc(100% - 260px)' : { xs: '100%', lg: 'calc(100% - 60px)' },
|
width: isHorizontal ? '100%' : drawerOpen ? 'calc(100% - 260px)' : { xs: '100%', lg: 'calc(100% - 60px)' },
|
||||||
// boxShadow: theme.customShadows.z1
|
// boxShadow: theme.customShadows.z1
|
||||||
bgcolor:'#662582'
|
bgcolor:'#C01227'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ const icons = {
|
|||||||
|
|
||||||
const nearle = {
|
const nearle = {
|
||||||
id: 'nearle_Pages',
|
id: 'nearle_Pages',
|
||||||
title: <FormattedMessage id="Nearle" />,
|
title: <FormattedMessage id="Doormile" />,
|
||||||
icon: icons.FileDoneOutlined,
|
icon: icons.FileDoneOutlined,
|
||||||
type: 'group',
|
type: 'group',
|
||||||
children: [
|
children: [
|
||||||
|
|||||||
@@ -1,57 +0,0 @@
|
|||||||
import { Link } from 'react-router-dom';
|
|
||||||
|
|
||||||
// material-ui
|
|
||||||
import { useTheme } from '@mui/material/styles';
|
|
||||||
import { Box, Button, Grid, Divider, Typography, useMediaQuery } from '@mui/material';
|
|
||||||
|
|
||||||
// project import
|
|
||||||
import useAuth from 'hooks/useAuth';
|
|
||||||
import AnimateButton from 'components/@extended/AnimateButton';
|
|
||||||
import AuthWrapper from 'sections/auth/AuthWrapper';
|
|
||||||
|
|
||||||
// ================================|| CHECK MAIL ||================================ //
|
|
||||||
|
|
||||||
const CheckMail = () => {
|
|
||||||
const theme = useTheme();
|
|
||||||
const matchDownSM = useMediaQuery(theme.breakpoints.down('sm'));
|
|
||||||
|
|
||||||
const { isLoggedIn } = useAuth();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<AuthWrapper>
|
|
||||||
<Grid container spacing={3}>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Box sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
|
|
||||||
<Typography variant="h3">Hi, Check Your Mail</Typography>
|
|
||||||
<Typography color="secondary" sx={{ mb: 0.5, mt: 1.25 }}>
|
|
||||||
We have sent a password recover instructions to your email.
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<AnimateButton>
|
|
||||||
<Button
|
|
||||||
component={Link}
|
|
||||||
to={isLoggedIn ? '/auth/login' : '/login'}
|
|
||||||
disableElevation
|
|
||||||
fullWidth
|
|
||||||
size="large"
|
|
||||||
type="submit"
|
|
||||||
variant="contained"
|
|
||||||
color="primary"
|
|
||||||
>
|
|
||||||
Sign in
|
|
||||||
</Button>
|
|
||||||
</AnimateButton>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Divider>
|
|
||||||
<Typography variant={matchDownSM ? 'subtitle1' : 'h5'}>Sign up with</Typography>
|
|
||||||
</Divider>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</AuthWrapper>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default CheckMail;
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
// material-ui
|
|
||||||
import { Grid, Stack, Typography } from '@mui/material';
|
|
||||||
|
|
||||||
// project import
|
|
||||||
import AuthWrapper from 'sections/auth/AuthWrapper';
|
|
||||||
import AuthCodeVerification from 'sections/auth/auth-forms/AuthCodeVerification';
|
|
||||||
|
|
||||||
// ================================|| CODE VERIFICATION ||================================ //
|
|
||||||
|
|
||||||
const CodeVerification = () => (
|
|
||||||
<AuthWrapper>
|
|
||||||
<Grid container spacing={3}>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Stack spacing={1}>
|
|
||||||
<Typography variant="h3">Enter Verification Code</Typography>
|
|
||||||
<Typography color="secondary">We send you on mail.</Typography>
|
|
||||||
</Stack>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Typography>We`ve send you code on jone. ****@company.com</Typography>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<AuthCodeVerification />
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</AuthWrapper>
|
|
||||||
);
|
|
||||||
|
|
||||||
export default CodeVerification;
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
import { Link } from 'react-router-dom';
|
|
||||||
|
|
||||||
// material-ui
|
|
||||||
import { Grid, Stack, Typography } from '@mui/material';
|
|
||||||
|
|
||||||
// project import
|
|
||||||
import useAuth from 'hooks/useAuth';
|
|
||||||
import AuthWrapper from 'sections/auth/AuthWrapper';
|
|
||||||
import AuthForgotPassword from 'sections/auth/auth-forms/AuthForgotPassword';
|
|
||||||
|
|
||||||
// ================================|| FORGOT PASSWORD ||================================ //
|
|
||||||
|
|
||||||
const ForgotPassword = () => {
|
|
||||||
const { isLoggedIn } = useAuth();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<AuthWrapper>
|
|
||||||
<Grid container spacing={3}>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Stack direction="row" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
|
|
||||||
<Typography variant="h3">Forgot Password</Typography>
|
|
||||||
<Typography
|
|
||||||
component={Link}
|
|
||||||
to={isLoggedIn ? '/auth/login' : '/login'}
|
|
||||||
variant="body1"
|
|
||||||
sx={{ textDecoration: 'none' }}
|
|
||||||
color="primary"
|
|
||||||
>
|
|
||||||
Back to Login
|
|
||||||
</Typography>
|
|
||||||
</Stack>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<AuthForgotPassword />
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</AuthWrapper>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ForgotPassword;
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
import { Link } from 'react-router-dom';
|
|
||||||
|
|
||||||
// material-ui
|
|
||||||
import { Grid, Stack, Typography } from '@mui/material';
|
|
||||||
|
|
||||||
// project import
|
|
||||||
import useAuth from 'hooks/useAuth';
|
|
||||||
import AuthWrapper from 'sections/auth/AuthWrapper';
|
|
||||||
import AuthLogin from 'sections/auth/auth-forms/AuthLogin';
|
|
||||||
|
|
||||||
// ================================|| LOGIN ||================================ //
|
|
||||||
|
|
||||||
const Login = () => {
|
|
||||||
const { isLoggedIn } = useAuth();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<AuthWrapper>
|
|
||||||
<Grid container spacing={3}>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Stack direction="row" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
|
|
||||||
<Typography variant="h3">Login</Typography>
|
|
||||||
<Typography
|
|
||||||
component={Link}
|
|
||||||
to={isLoggedIn ? '/auth/register' : '/register'}
|
|
||||||
variant="body1"
|
|
||||||
sx={{ textDecoration: 'none' }}
|
|
||||||
color="primary"
|
|
||||||
>
|
|
||||||
Don't have an account?
|
|
||||||
</Typography>
|
|
||||||
</Stack>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<AuthLogin />
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</AuthWrapper>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Login;
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
import { Link } from 'react-router-dom';
|
|
||||||
|
|
||||||
// material-ui
|
|
||||||
import { Grid, Stack, Typography } from '@mui/material';
|
|
||||||
|
|
||||||
// project import
|
|
||||||
import useAuth from 'hooks/useAuth';
|
|
||||||
import AuthWrapper from 'sections/auth/AuthWrapper';
|
|
||||||
import FirebaseRegister from 'sections/auth/auth-forms/AuthRegister';
|
|
||||||
|
|
||||||
// ================================|| REGISTER ||================================ //
|
|
||||||
|
|
||||||
const Register = () => {
|
|
||||||
const { isLoggedIn } = useAuth();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<AuthWrapper>
|
|
||||||
<Grid container spacing={3}>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Stack direction="row" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
|
|
||||||
<Typography variant="h3">Sign up</Typography>
|
|
||||||
<Typography
|
|
||||||
component={Link}
|
|
||||||
to={isLoggedIn ? '/auth/login' : '/login'}
|
|
||||||
variant="body1"
|
|
||||||
sx={{ textDecoration: 'none' }}
|
|
||||||
color="primary"
|
|
||||||
>
|
|
||||||
Already have an account?
|
|
||||||
</Typography>
|
|
||||||
</Stack>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<FirebaseRegister />
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</AuthWrapper>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Register;
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
// material-ui
|
|
||||||
import { Grid, Stack, Typography } from '@mui/material';
|
|
||||||
|
|
||||||
// project import
|
|
||||||
import AuthWrapper from 'sections/auth/AuthWrapper';
|
|
||||||
import AuthResetPassword from 'sections/auth/auth-forms/AuthResetPassword';
|
|
||||||
|
|
||||||
// ================================|| RESET PASSWORD ||================================ //
|
|
||||||
|
|
||||||
const ResetPassword = () => (
|
|
||||||
<AuthWrapper>
|
|
||||||
<Grid container spacing={3}>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Stack sx={{ mb: { xs: -0.5, sm: 0.5 } }} spacing={1}>
|
|
||||||
<Typography variant="h3">Reset Password</Typography>
|
|
||||||
<Typography color="secondary">Please choose your new password</Typography>
|
|
||||||
</Stack>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<AuthResetPassword />
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</AuthWrapper>
|
|
||||||
);
|
|
||||||
|
|
||||||
export default ResetPassword;
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
import React, { useRef, useEffect } from 'react';
|
|
||||||
|
|
||||||
const CtrlK = () => {
|
|
||||||
useEffect(() => {
|
|
||||||
const handleKeyPress = (event) => {
|
|
||||||
if (event.key === 'k' && (event.metaKey || event.ctrlKey)) {
|
|
||||||
event.preventDefault();
|
|
||||||
textFieldRef.current.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.key === 'Escape' && document.activeElement === textFieldRef.current) {
|
|
||||||
textFieldRef.current.blur();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
document.addEventListener('keydown', handleKeyPress);
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
document.removeEventListener('keydown', handleKeyPress);
|
|
||||||
};
|
|
||||||
}, [textFieldRef]);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default CtrlK;
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
// material-ui
|
|
||||||
import { Typography } from '@mui/material';
|
|
||||||
|
|
||||||
// project import
|
|
||||||
import MainCard from 'components/MainCard';
|
|
||||||
|
|
||||||
// ==============================|| SAMPLE PAGE ||============================== //
|
|
||||||
|
|
||||||
const SamplePage = () => (
|
|
||||||
<MainCard title="Sample Card">
|
|
||||||
<Typography variant="body2">
|
|
||||||
Lorem ipsum dolor sit amen, consenter nipissing eli, sed do elusion tempos incident ut laborers et doolie magna alissa. Ut enif ad
|
|
||||||
minim venice, quin nostrum exercitation illampu laborings nisi ut liquid ex ea commons construal. Duos aube grue dolor in reprehended
|
|
||||||
in voltage veil esse colum doolie eu fujian bulla parian. Exceptive sin ocean cuspidate non president, sunk in culpa qui officiate
|
|
||||||
descent molls anim id est labours.
|
|
||||||
</Typography>
|
|
||||||
</MainCard>
|
|
||||||
);
|
|
||||||
|
|
||||||
export default SamplePage;
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
import { Grid, useMediaQuery, useTheme } from '@mui/material';
|
|
||||||
import { useQuery } from '@tanstack/react-query';
|
|
||||||
import CircularLoader from 'components/CircularLoader';
|
|
||||||
import Loader from 'components/Loader';
|
|
||||||
import MainCard from 'components/MainCard';
|
|
||||||
import { getusers } from 'pages/api/api';
|
|
||||||
|
|
||||||
const ViewProfile = () => {
|
|
||||||
const theme = useTheme();
|
|
||||||
const isMobile = useMediaQuery(theme.breakpoints.down('md'));
|
|
||||||
const {
|
|
||||||
data: userdata,
|
|
||||||
isLoading,
|
|
||||||
isError,
|
|
||||||
error
|
|
||||||
} = useQuery({
|
|
||||||
queryKey: ['getuser'],
|
|
||||||
queryFn: getusers
|
|
||||||
});
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{isLoading && (
|
|
||||||
<>
|
|
||||||
<Loader />
|
|
||||||
<CircularLoader />
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
<MainCard sx={{ p: { xs: 1.5, md: 3 } }}>
|
|
||||||
<Grid container spacing={isMobile ? 2 : 3}>
|
|
||||||
<Grid item xs={12} sm={6} md={4}>
|
|
||||||
{userdata?.firstname}
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12} sm={6} md={4}>
|
|
||||||
{' '}
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12} sm={6} md={4}>
|
|
||||||
{' '}
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</MainCard>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ViewProfile;
|
|
||||||
@@ -61,7 +61,7 @@ const DT = {
|
|||||||
divider: '#f1f5f9',
|
divider: '#f1f5f9',
|
||||||
surface: '#ffffff',
|
surface: '#ffffff',
|
||||||
surfaceAlt: '#f8fafc',
|
surfaceAlt: '#f8fafc',
|
||||||
brand: '#662582'
|
brand: '#C01227'
|
||||||
};
|
};
|
||||||
const a = (c, suffix) => `${c}${suffix}`;
|
const a = (c, suffix) => `${c}${suffix}`;
|
||||||
const tint = (c) => a(c, '08');
|
const tint = (c) => a(c, '08');
|
||||||
@@ -69,7 +69,7 @@ const soft = (c) => a(c, '18');
|
|||||||
const ring = (c) => a(c, '26');
|
const ring = (c) => a(c, '26');
|
||||||
const edge = (c) => a(c, '55');
|
const edge = (c) => a(c, '55');
|
||||||
|
|
||||||
const BRAND = '#662582';
|
const BRAND = '#C01227';
|
||||||
|
|
||||||
const SoftPaper = (props) => (
|
const SoftPaper = (props) => (
|
||||||
<Paper
|
<Paper
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ const pillFieldSx = (color) => ({
|
|||||||
'& fieldset': { borderColor: '#e2e8f0', borderWidth: 1 },
|
'& fieldset': { borderColor: '#e2e8f0', borderWidth: 1 },
|
||||||
'&:hover fieldset': { borderColor: '#cbd5e1' },
|
'&:hover fieldset': { borderColor: '#cbd5e1' },
|
||||||
'&.Mui-focused': { boxShadow: `0 0 0 3px ${ring(color)}` },
|
'&.Mui-focused': { boxShadow: `0 0 0 3px ${ring(color)}` },
|
||||||
'&.Mui-focused fieldset': { borderColor: '#662582', borderWidth: 1.5 }
|
'&.Mui-focused fieldset': { borderColor: '#C01227', borderWidth: 1.5 }
|
||||||
},
|
},
|
||||||
'& .MuiAutocomplete-endAdornment .MuiSvgIcon-root': { color: color }
|
'& .MuiAutocomplete-endAdornment .MuiSvgIcon-root': { color: color }
|
||||||
});
|
});
|
||||||
@@ -596,7 +596,7 @@ const Clients1 = () => {
|
|||||||
setLocoName={setLocoName}
|
setLocoName={setLocoName}
|
||||||
setPage={setPage}
|
setPage={setPage}
|
||||||
pill
|
pill
|
||||||
accentColor="#662582"
|
accentColor="#C01227"
|
||||||
icon={<MdMyLocation size={14} />}
|
icon={<MdMyLocation size={14} />}
|
||||||
placeholder="Select Zone"
|
placeholder="Select Zone"
|
||||||
paperComponent={SoftPaper}
|
paperComponent={SoftPaper}
|
||||||
@@ -622,7 +622,7 @@ const Clients1 = () => {
|
|||||||
title={item.label}
|
title={item.label}
|
||||||
value={value ?? 0}
|
value={value ?? 0}
|
||||||
icon={<Icon size={20} />}
|
icon={<Icon size={20} />}
|
||||||
color={idx === 0 ? '#662582' : item.color}
|
color={idx === 0 ? '#C01227' : item.color}
|
||||||
loading={summaryDataIsLoading}
|
loading={summaryDataIsLoading}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
@@ -749,11 +749,11 @@ const Clients1 = () => {
|
|||||||
m: 0,
|
m: 0,
|
||||||
width: '100%',
|
width: '100%',
|
||||||
borderRadius: 999,
|
borderRadius: 999,
|
||||||
bgcolor: tint('#662582'),
|
bgcolor: tint('#C01227'),
|
||||||
'& fieldset': { borderColor: edge('#662582'), borderWidth: 1.5 },
|
'& fieldset': { borderColor: edge('#C01227'), borderWidth: 1.5 },
|
||||||
'&:hover fieldset': { borderColor: '#662582' },
|
'&:hover fieldset': { borderColor: '#C01227' },
|
||||||
'&.Mui-focused fieldset': { borderColor: '#662582', borderWidth: 2 },
|
'&.Mui-focused fieldset': { borderColor: '#C01227', borderWidth: 2 },
|
||||||
'&.Mui-focused': { boxShadow: `0 0 0 3px ${ring('#662582')}` }
|
'&.Mui-focused': { boxShadow: `0 0 0 3px ${ring('#C01227')}` }
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
@@ -780,9 +780,9 @@ const Clients1 = () => {
|
|||||||
maxHeight: { xs: 'calc(100vh - 220px)', md: 'calc(100vh - 190px)' },
|
maxHeight: { xs: 'calc(100vh - 220px)', md: 'calc(100vh - 190px)' },
|
||||||
'&::-webkit-scrollbar': { width: '10px', height: '10px' },
|
'&::-webkit-scrollbar': { width: '10px', height: '10px' },
|
||||||
'&::-webkit-scrollbar-thumb': {
|
'&::-webkit-scrollbar-thumb': {
|
||||||
backgroundColor: edge('#662582'),
|
backgroundColor: edge('#C01227'),
|
||||||
borderRadius: '8px',
|
borderRadius: '8px',
|
||||||
'&:hover': { backgroundColor: '#662582' }
|
'&:hover': { backgroundColor: '#C01227' }
|
||||||
},
|
},
|
||||||
'&::-webkit-scrollbar-track': { backgroundColor: DT.surfaceAlt }
|
'&::-webkit-scrollbar-track': { backgroundColor: DT.surfaceAlt }
|
||||||
}}
|
}}
|
||||||
@@ -883,7 +883,7 @@ const Clients1 = () => {
|
|||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<Stack direction="row" alignItems="center" spacing={1}>
|
<Stack direction="row" alignItems="center" spacing={1}>
|
||||||
<AccentAvatar color="#662582" size={32}>
|
<AccentAvatar color="#C01227" size={32}>
|
||||||
<MdPersonPin size={16} />
|
<MdPersonPin size={16} />
|
||||||
</AccentAvatar>
|
</AccentAvatar>
|
||||||
<Stack>
|
<Stack>
|
||||||
@@ -996,10 +996,10 @@ const Clients1 = () => {
|
|||||||
<IconButton
|
<IconButton
|
||||||
size="small"
|
size="small"
|
||||||
sx={{
|
sx={{
|
||||||
bgcolor: openRowIndex1 === index ? '#662582' : soft('#662582'),
|
bgcolor: openRowIndex1 === index ? '#C01227' : soft('#C01227'),
|
||||||
color: openRowIndex1 === index ? '#fff' : '#662582',
|
color: openRowIndex1 === index ? '#fff' : '#C01227',
|
||||||
border: `1px solid ${edge('#662582')}`,
|
border: `1px solid ${edge('#C01227')}`,
|
||||||
'&:hover': { bgcolor: '#662582', color: '#fff' }
|
'&:hover': { bgcolor: '#C01227', color: '#fff' }
|
||||||
}}
|
}}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setSelectedCustomer(row);
|
setSelectedCustomer(row);
|
||||||
@@ -1913,7 +1913,7 @@ const Clients1 = () => {
|
|||||||
header={
|
header={
|
||||||
<Stack direction="row" alignItems="flex-start" justifyContent="space-between" spacing={1}>
|
<Stack direction="row" alignItems="flex-start" justifyContent="space-between" spacing={1}>
|
||||||
<Stack direction="row" alignItems="center" spacing={1} sx={{ minWidth: 0 }}>
|
<Stack direction="row" alignItems="center" spacing={1} sx={{ minWidth: 0 }}>
|
||||||
<AccentAvatar color="#662582" size={36}>
|
<AccentAvatar color="#C01227" size={36}>
|
||||||
<MdPersonPin size={18} />
|
<MdPersonPin size={18} />
|
||||||
</AccentAvatar>
|
</AccentAvatar>
|
||||||
<Stack sx={{ minWidth: 0 }}>
|
<Stack sx={{ minWidth: 0 }}>
|
||||||
@@ -2012,10 +2012,10 @@ const Clients1 = () => {
|
|||||||
<IconButton
|
<IconButton
|
||||||
size="small"
|
size="small"
|
||||||
sx={{
|
sx={{
|
||||||
bgcolor: expanded ? '#662582' : soft('#662582'),
|
bgcolor: expanded ? '#C01227' : soft('#C01227'),
|
||||||
color: expanded ? '#fff' : '#662582',
|
color: expanded ? '#fff' : '#C01227',
|
||||||
border: `1px solid ${edge('#662582')}`,
|
border: `1px solid ${edge('#C01227')}`,
|
||||||
'&:hover': { bgcolor: '#662582', color: '#fff' }
|
'&:hover': { bgcolor: '#C01227', color: '#fff' }
|
||||||
}}
|
}}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setSelectedCustomer(row);
|
setSelectedCustomer(row);
|
||||||
@@ -2108,7 +2108,7 @@ const Clients1 = () => {
|
|||||||
>
|
>
|
||||||
<DialogTitle
|
<DialogTitle
|
||||||
sx={{
|
sx={{
|
||||||
bgcolor: '#662582',
|
bgcolor: '#C01227',
|
||||||
color: '#fff',
|
color: '#fff',
|
||||||
fontSize: '20px'
|
fontSize: '20px'
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -396,7 +396,7 @@ export default function Customers() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
const KPI_META = [
|
const KPI_META = [
|
||||||
{ key: 'total', label: 'Total Customers', color: '#662582', icon: MdOutlineGroups, value: pageCount?.Total ?? 0 },
|
{ key: 'total', label: 'Total Customers', color: '#C01227', icon: MdOutlineGroups, value: pageCount?.Total ?? 0 },
|
||||||
{ key: 'loaded', label: 'Loaded in View', color: '#0ea5e9', icon: MdOutlineHowToReg, value: rows.length },
|
{ key: 'loaded', label: 'Loaded in View', color: '#0ea5e9', icon: MdOutlineHowToReg, value: rows.length },
|
||||||
{ key: 'zone', label: 'Active Zone', color: '#10b981', icon: MdOutlinePlace, value: locaName || 'All Zones' }
|
{ key: 'zone', label: 'Active Zone', color: '#10b981', icon: MdOutlinePlace, value: locaName || 'All Zones' }
|
||||||
];
|
];
|
||||||
@@ -416,7 +416,7 @@ export default function Customers() {
|
|||||||
setAppId={setAppId}
|
setAppId={setAppId}
|
||||||
setLocoName={setLocoName}
|
setLocoName={setLocoName}
|
||||||
pill
|
pill
|
||||||
accentColor="#662582"
|
accentColor="#C01227"
|
||||||
icon={<MdMyLocation size={14} />}
|
icon={<MdMyLocation size={14} />}
|
||||||
placeholder="Select Zone"
|
placeholder="Select Zone"
|
||||||
paperComponent={SoftPaper}
|
paperComponent={SoftPaper}
|
||||||
@@ -466,7 +466,7 @@ export default function Customers() {
|
|||||||
spacing={1.25}
|
spacing={1.25}
|
||||||
>
|
>
|
||||||
<Stack direction="row" alignItems="center" spacing={1.25}>
|
<Stack direction="row" alignItems="center" spacing={1.25}>
|
||||||
<AccentAvatar color="#662582" size={32}>
|
<AccentAvatar color="#C01227" size={32}>
|
||||||
<MdGroups size={18} />
|
<MdGroups size={18} />
|
||||||
</AccentAvatar>
|
</AccentAvatar>
|
||||||
<Stack>
|
<Stack>
|
||||||
@@ -491,11 +491,11 @@ export default function Customers() {
|
|||||||
m: 0,
|
m: 0,
|
||||||
width: '100%',
|
width: '100%',
|
||||||
borderRadius: 999,
|
borderRadius: 999,
|
||||||
bgcolor: tint('#662582'),
|
bgcolor: tint('#C01227'),
|
||||||
'& fieldset': { borderColor: edge('#662582'), borderWidth: 1.5 },
|
'& fieldset': { borderColor: edge('#C01227'), borderWidth: 1.5 },
|
||||||
'&:hover fieldset': { borderColor: '#662582' },
|
'&:hover fieldset': { borderColor: '#C01227' },
|
||||||
'&.Mui-focused fieldset': { borderColor: '#662582', borderWidth: 2 },
|
'&.Mui-focused fieldset': { borderColor: '#C01227', borderWidth: 2 },
|
||||||
'&.Mui-focused': { boxShadow: `0 0 0 3px ${ring('#662582')}` }
|
'&.Mui-focused': { boxShadow: `0 0 0 3px ${ring('#C01227')}` }
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
@@ -535,11 +535,11 @@ export default function Customers() {
|
|||||||
rows?.map((row, index) => (
|
rows?.map((row, index) => (
|
||||||
<MobileCard
|
<MobileCard
|
||||||
key={row.customerid || `${row.firstname}-${index}`}
|
key={row.customerid || `${row.firstname}-${index}`}
|
||||||
accent="#662582"
|
accent="#C01227"
|
||||||
header={
|
header={
|
||||||
<Stack direction="row" alignItems="center" justifyContent="space-between" spacing={1}>
|
<Stack direction="row" alignItems="center" justifyContent="space-between" spacing={1}>
|
||||||
<Stack direction="row" alignItems="center" spacing={1} sx={{ minWidth: 0 }}>
|
<Stack direction="row" alignItems="center" spacing={1} sx={{ minWidth: 0 }}>
|
||||||
<AccentAvatar color="#662582" size={36}>
|
<AccentAvatar color="#C01227" size={36}>
|
||||||
<MdPersonPin size={18} />
|
<MdPersonPin size={18} />
|
||||||
</AccentAvatar>
|
</AccentAvatar>
|
||||||
<Stack sx={{ minWidth: 0 }}>
|
<Stack sx={{ minWidth: 0 }}>
|
||||||
@@ -626,9 +626,9 @@ export default function Customers() {
|
|||||||
maxHeight: { xs: 'calc(100vh - 220px)', md: 'calc(100vh - 190px)' },
|
maxHeight: { xs: 'calc(100vh - 220px)', md: 'calc(100vh - 190px)' },
|
||||||
'&::-webkit-scrollbar': { width: 10, height: 10 },
|
'&::-webkit-scrollbar': { width: 10, height: 10 },
|
||||||
'&::-webkit-scrollbar-thumb': {
|
'&::-webkit-scrollbar-thumb': {
|
||||||
backgroundColor: edge('#662582'),
|
backgroundColor: edge('#C01227'),
|
||||||
borderRadius: 8,
|
borderRadius: 8,
|
||||||
'&:hover': { backgroundColor: '#662582' }
|
'&:hover': { backgroundColor: '#C01227' }
|
||||||
},
|
},
|
||||||
'&::-webkit-scrollbar-track': { backgroundColor: DT.surfaceAlt }
|
'&::-webkit-scrollbar-track': { backgroundColor: DT.surfaceAlt }
|
||||||
}}
|
}}
|
||||||
@@ -700,7 +700,7 @@ export default function Customers() {
|
|||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<Stack direction="row" alignItems="center" spacing={1}>
|
<Stack direction="row" alignItems="center" spacing={1}>
|
||||||
<AccentAvatar color="#662582" size={36}>
|
<AccentAvatar color="#C01227" size={36}>
|
||||||
<MdPersonPin size={18} />
|
<MdPersonPin size={18} />
|
||||||
</AccentAvatar>
|
</AccentAvatar>
|
||||||
<Stack>
|
<Stack>
|
||||||
@@ -829,7 +829,7 @@ export default function Customers() {
|
|||||||
<DialogTitle
|
<DialogTitle
|
||||||
id="alert-dialog-title"
|
id="alert-dialog-title"
|
||||||
sx={{
|
sx={{
|
||||||
background: `linear-gradient(135deg, #662582 0%, #9255AB 100%)`,
|
background: `linear-gradient(135deg, #C01227 0%, #D35968 100%)`,
|
||||||
color: '#fff',
|
color: '#fff',
|
||||||
py: 2
|
py: 2
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
const Dashboard = () => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<h1>Dashboard</h1>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Dashboard;
|
|
||||||
@@ -126,7 +126,7 @@ const DT = {
|
|||||||
divider: '#f1f5f9',
|
divider: '#f1f5f9',
|
||||||
surface: '#ffffff',
|
surface: '#ffffff',
|
||||||
surfaceAlt: '#f8fafc',
|
surfaceAlt: '#f8fafc',
|
||||||
brand: '#662582'
|
brand: '#C01227'
|
||||||
};
|
};
|
||||||
|
|
||||||
// Quick alpha helpers (hex + percentage suffix). Mirrors the batch-dropdown
|
// Quick alpha helpers (hex + percentage suffix). Mirrors the batch-dropdown
|
||||||
@@ -912,7 +912,7 @@ const Deliveries = () => {
|
|||||||
setLocoName={setLocoName}
|
setLocoName={setLocoName}
|
||||||
setPage={setPage}
|
setPage={setPage}
|
||||||
pill
|
pill
|
||||||
accentColor="#662582"
|
accentColor="#C01227"
|
||||||
icon={<MdMyLocation size={14} />}
|
icon={<MdMyLocation size={14} />}
|
||||||
placeholder="Select Zone"
|
placeholder="Select Zone"
|
||||||
paperComponent={SoftPaper}
|
paperComponent={SoftPaper}
|
||||||
@@ -962,7 +962,7 @@ const Deliveries = () => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Stack direction="row" alignItems="center" spacing={1} sx={{ mb: { xs: 1, md: 1.5 }, color: DT.textSecondary }}>
|
<Stack direction="row" alignItems="center" spacing={1} sx={{ mb: { xs: 1, md: 1.5 }, color: DT.textSecondary }}>
|
||||||
<Avatar sx={{ width: 28, height: 28, bgcolor: soft('#662582'), color: '#662582' }}>
|
<Avatar sx={{ width: 28, height: 28, bgcolor: soft('#C01227'), color: '#C01227' }}>
|
||||||
<MdTune size={16} />
|
<MdTune size={16} />
|
||||||
</Avatar>
|
</Avatar>
|
||||||
<Typography variant="caption" sx={{ fontWeight: 800, letterSpacing: 0.6, textTransform: 'uppercase', color: DT.textSecondary }}>
|
<Typography variant="caption" sx={{ fontWeight: 800, letterSpacing: 0.6, textTransform: 'uppercase', color: DT.textSecondary }}>
|
||||||
@@ -1125,8 +1125,8 @@ const Deliveries = () => {
|
|||||||
transition: 'border-color 0.15s, box-shadow 0.15s',
|
transition: 'border-color 0.15s, box-shadow 0.15s',
|
||||||
'& fieldset': { borderColor: '#e2e8f0', borderWidth: 1 },
|
'& fieldset': { borderColor: '#e2e8f0', borderWidth: 1 },
|
||||||
'&:hover fieldset': { borderColor: '#cbd5e1' },
|
'&:hover fieldset': { borderColor: '#cbd5e1' },
|
||||||
'&.Mui-focused': { boxShadow: `0 0 0 3px ${ring('#662582')}` },
|
'&.Mui-focused': { boxShadow: `0 0 0 3px ${ring('#C01227')}` },
|
||||||
'&.Mui-focused fieldset': { borderColor: '#662582', borderWidth: 1.5 }
|
'&.Mui-focused fieldset': { borderColor: '#C01227', borderWidth: 1.5 }
|
||||||
},
|
},
|
||||||
'& .MuiAutocomplete-endAdornment .MuiSvgIcon-root': { color: '#94a3b8' }
|
'& .MuiAutocomplete-endAdornment .MuiSvgIcon-root': { color: '#94a3b8' }
|
||||||
}}
|
}}
|
||||||
@@ -1442,10 +1442,10 @@ const Deliveries = () => {
|
|||||||
overflowX: 'auto',
|
overflowX: 'auto',
|
||||||
'&::-webkit-scrollbar': { width: '10px', height: '10px', cursor: 'pointer' },
|
'&::-webkit-scrollbar': { width: '10px', height: '10px', cursor: 'pointer' },
|
||||||
'&::-webkit-scrollbar-thumb': {
|
'&::-webkit-scrollbar-thumb': {
|
||||||
backgroundColor: edge('#662582'),
|
backgroundColor: edge('#C01227'),
|
||||||
borderRadius: '8px',
|
borderRadius: '8px',
|
||||||
cursor: 'pointer',
|
cursor: 'pointer',
|
||||||
'&:hover': { backgroundColor: '#662582' }
|
'&:hover': { backgroundColor: '#C01227' }
|
||||||
},
|
},
|
||||||
'&::-webkit-scrollbar-track': { backgroundColor: DT.surfaceAlt }
|
'&::-webkit-scrollbar-track': { backgroundColor: DT.surfaceAlt }
|
||||||
}}
|
}}
|
||||||
@@ -1562,7 +1562,7 @@ const Deliveries = () => {
|
|||||||
<IconButton
|
<IconButton
|
||||||
size="small"
|
size="small"
|
||||||
onClick={(e) => handleMenuOpen(e, row)}
|
onClick={(e) => handleMenuOpen(e, row)}
|
||||||
sx={{ borderRadius: 999, bgcolor: tint('#662582'), color: '#662582', border: `1px solid ${edge('#662582')}`, '&:hover': { bgcolor: soft('#662582') } }}
|
sx={{ borderRadius: 999, bgcolor: tint('#C01227'), color: '#C01227', border: `1px solid ${edge('#C01227')}`, '&:hover': { bgcolor: soft('#C01227') } }}
|
||||||
>
|
>
|
||||||
<EditOutlined />
|
<EditOutlined />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
@@ -1650,7 +1650,7 @@ const Deliveries = () => {
|
|||||||
</MobileField>
|
</MobileField>
|
||||||
<MobileField label="Step">
|
<MobileField label="Step">
|
||||||
{row.step ? (
|
{row.step ? (
|
||||||
<Box sx={{ ...chipSx('#662582'), minWidth: 30, fontWeight: 800 }}>{row.step}</Box>
|
<Box sx={{ ...chipSx('#C01227'), minWidth: 30, fontWeight: 800 }}>{row.step}</Box>
|
||||||
) : (
|
) : (
|
||||||
<Typography variant="caption" sx={{ color: DT.textMuted }}>—</Typography>
|
<Typography variant="caption" sx={{ color: DT.textMuted }}>—</Typography>
|
||||||
)}
|
)}
|
||||||
@@ -1664,8 +1664,8 @@ const Deliveries = () => {
|
|||||||
{isOpen && (
|
{isOpen && (
|
||||||
<Box sx={{ mt: 1.5, p: 1.25, borderRadius: 2, bgcolor: DT.surfaceAlt, border: `1px solid ${DT.divider}` }}>
|
<Box sx={{ mt: 1.5, p: 1.25, borderRadius: 2, bgcolor: DT.surfaceAlt, border: `1px solid ${DT.divider}` }}>
|
||||||
<Stack direction="row" alignItems="center" spacing={1} sx={{ mb: 1 }}>
|
<Stack direction="row" alignItems="center" spacing={1} sx={{ mb: 1 }}>
|
||||||
<AccentAvatar color="#662582" size={22}><MdInventory2 size={12} /></AccentAvatar>
|
<AccentAvatar color="#C01227" size={22}><MdInventory2 size={12} /></AccentAvatar>
|
||||||
<Typography variant="caption" sx={{ fontWeight: 800, letterSpacing: 0.5, textTransform: 'uppercase', color: '#662582' }}>
|
<Typography variant="caption" sx={{ fontWeight: 800, letterSpacing: 0.5, textTransform: 'uppercase', color: '#C01227' }}>
|
||||||
Product Details
|
Product Details
|
||||||
</Typography>
|
</Typography>
|
||||||
</Stack>
|
</Stack>
|
||||||
@@ -2065,9 +2065,9 @@ const Deliveries = () => {
|
|||||||
height: 24,
|
height: 24,
|
||||||
px: 0.875,
|
px: 0.875,
|
||||||
borderRadius: 999,
|
borderRadius: 999,
|
||||||
bgcolor: tint('#662582'),
|
bgcolor: tint('#C01227'),
|
||||||
border: `1px solid ${edge('#662582')}`,
|
border: `1px solid ${edge('#C01227')}`,
|
||||||
color: '#662582',
|
color: '#C01227',
|
||||||
fontWeight: 800,
|
fontWeight: 800,
|
||||||
fontSize: 11
|
fontSize: 11
|
||||||
}}
|
}}
|
||||||
@@ -2133,10 +2133,10 @@ const Deliveries = () => {
|
|||||||
onClick={(e) => handleMenuOpen(e, row)}
|
onClick={(e) => handleMenuOpen(e, row)}
|
||||||
sx={{
|
sx={{
|
||||||
borderRadius: 999,
|
borderRadius: 999,
|
||||||
bgcolor: tint('#662582'),
|
bgcolor: tint('#C01227'),
|
||||||
color: '#662582',
|
color: '#C01227',
|
||||||
border: `1px solid ${edge('#662582')}`,
|
border: `1px solid ${edge('#C01227')}`,
|
||||||
'&:hover': { bgcolor: soft('#662582') }
|
'&:hover': { bgcolor: soft('#C01227') }
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<EditOutlined />
|
<EditOutlined />
|
||||||
@@ -2168,9 +2168,9 @@ const Deliveries = () => {
|
|||||||
background: '#fff'
|
background: '#fff'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Stack direction="row" alignItems="center" spacing={1} sx={{ px: 2, py: 1.25, borderBottom: `1px solid ${DT.divider}`, bgcolor: tint('#662582') }}>
|
<Stack direction="row" alignItems="center" spacing={1} sx={{ px: 2, py: 1.25, borderBottom: `1px solid ${DT.divider}`, bgcolor: tint('#C01227') }}>
|
||||||
<AccentAvatar color="#662582"><MdInventory2 size={14} /></AccentAvatar>
|
<AccentAvatar color="#C01227"><MdInventory2 size={14} /></AccentAvatar>
|
||||||
<Typography variant="caption" sx={{ fontWeight: 800, letterSpacing: 0.5, textTransform: 'uppercase', color: '#662582' }}>
|
<Typography variant="caption" sx={{ fontWeight: 800, letterSpacing: 0.5, textTransform: 'uppercase', color: '#C01227' }}>
|
||||||
Product Details
|
Product Details
|
||||||
</Typography>
|
</Typography>
|
||||||
</Stack>
|
</Stack>
|
||||||
@@ -2778,14 +2778,14 @@ const Deliveries = () => {
|
|||||||
borderRadius: 2,
|
borderRadius: 2,
|
||||||
bgcolor: '#fff',
|
bgcolor: '#fff',
|
||||||
'& fieldset': { borderColor: DT.borderSubtle },
|
'& fieldset': { borderColor: DT.borderSubtle },
|
||||||
'&:hover fieldset': { borderColor: '#662582' },
|
'&:hover fieldset': { borderColor: '#C01227' },
|
||||||
'&.Mui-focused fieldset': { borderColor: '#662582', borderWidth: 2 },
|
'&.Mui-focused fieldset': { borderColor: '#C01227', borderWidth: 2 },
|
||||||
'&.Mui-focused': { boxShadow: `0 0 0 3px ${ring('#662582')}` }
|
'&.Mui-focused': { boxShadow: `0 0 0 3px ${ring('#C01227')}` }
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{['pending','accepted','started','arrived','delivered','cancelled'].map((s) => {
|
{['pending','accepted','started','arrived','delivered','cancelled'].map((s) => {
|
||||||
const m = STATUS_META[s] || { label: s, color: '#662582', icon: MdHistoryToggleOff };
|
const m = STATUS_META[s] || { label: s, color: '#C01227', icon: MdHistoryToggleOff };
|
||||||
const Ic = m.icon;
|
const Ic = m.icon;
|
||||||
return (
|
return (
|
||||||
<MenuItem key={s} value={s} sx={{ gap: 1 }}>
|
<MenuItem key={s} value={s} sx={{ gap: 1 }}>
|
||||||
@@ -2812,9 +2812,9 @@ const Deliveries = () => {
|
|||||||
borderRadius: 2,
|
borderRadius: 2,
|
||||||
bgcolor: '#fff',
|
bgcolor: '#fff',
|
||||||
'& fieldset': { borderColor: DT.borderSubtle },
|
'& fieldset': { borderColor: DT.borderSubtle },
|
||||||
'&:hover fieldset': { borderColor: '#662582' },
|
'&:hover fieldset': { borderColor: '#C01227' },
|
||||||
'&.Mui-focused fieldset': { borderColor: '#662582', borderWidth: 2 },
|
'&.Mui-focused fieldset': { borderColor: '#C01227', borderWidth: 2 },
|
||||||
'&.Mui-focused': { boxShadow: `0 0 0 3px ${ring('#662582')}` }
|
'&.Mui-focused': { boxShadow: `0 0 0 3px ${ring('#C01227')}` }
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ import logger from '../../../utils/logger';
|
|||||||
// emerald for the actual GPS trail (signals "live / real" data). Per-step
|
// emerald for the actual GPS trail (signals "live / real" data). Per-step
|
||||||
// distinction in Combined view is carried by the numbered drop pins, which
|
// distinction in Combined view is carried by the numbered drop pins, which
|
||||||
// keep STEP_PALETTE so the timeline link to a specific delivery survives.
|
// keep STEP_PALETTE so the timeline link to a specific delivery survives.
|
||||||
const COMBINED_PLANNED_COLOR = '#662582';
|
const COMBINED_PLANNED_COLOR = '#C01227';
|
||||||
const COMBINED_ACTUAL_COLOR = '#10b981';
|
const COMBINED_ACTUAL_COLOR = '#10b981';
|
||||||
|
|
||||||
const toNum = (v) => {
|
const toNum = (v) => {
|
||||||
@@ -5729,7 +5729,7 @@ const Dispatch = ({
|
|||||||
style={{
|
style={{
|
||||||
boxShadow: 'var(--shadow-lg)',
|
boxShadow: 'var(--shadow-lg)',
|
||||||
background: compareOpen
|
background: compareOpen
|
||||||
? 'linear-gradient(135deg, #662582, #9255AB)'
|
? 'linear-gradient(135deg, #C01227, #D35968)'
|
||||||
: '#fff',
|
: '#fff',
|
||||||
marginLeft: 8,
|
marginLeft: 8,
|
||||||
color: compareOpen ? '#fff' : undefined
|
color: compareOpen ? '#fff' : undefined
|
||||||
@@ -6328,7 +6328,7 @@ const Dispatch = ({
|
|||||||
<div className="da-section">
|
<div className="da-section">
|
||||||
<div className="da-hero-row">
|
<div className="da-hero-row">
|
||||||
<div className="da-hero-card">
|
<div className="da-hero-card">
|
||||||
<div className="da-hero-icon" style={{ background: '#6625821f', color: '#662582' }}>
|
<div className="da-hero-icon" style={{ background: '#C012271f', color: '#C01227' }}>
|
||||||
<MdOutlineInventory2 />
|
<MdOutlineInventory2 />
|
||||||
</div>
|
</div>
|
||||||
<div className="da-hero-value">{analysisFormatNum(fleet.total_orders)}</div>
|
<div className="da-hero-value">{analysisFormatNum(fleet.total_orders)}</div>
|
||||||
@@ -6809,7 +6809,7 @@ const Dispatch = ({
|
|||||||
<div className="da-pos-modal-title-wrap">
|
<div className="da-pos-modal-title-wrap">
|
||||||
<div
|
<div
|
||||||
className="da-pos-modal-avatar"
|
className="da-pos-modal-avatar"
|
||||||
style={{ background: `${riderPositionModal.color || '#662582'}22`, color: riderPositionModal.color || '#662582' }}
|
style={{ background: `${riderPositionModal.color || '#C01227'}22`, color: riderPositionModal.color || '#C01227' }}
|
||||||
>
|
>
|
||||||
<MdTwoWheeler />
|
<MdTwoWheeler />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ const soft = (c) => a(c, '18');
|
|||||||
const ring = (c) => a(c, '26');
|
const ring = (c) => a(c, '26');
|
||||||
const edge = (c) => a(c, '55');
|
const edge = (c) => a(c, '55');
|
||||||
|
|
||||||
const BRAND = '#662582';
|
const BRAND = '#C01227';
|
||||||
|
|
||||||
const AccentAvatar = ({ color, selected, size = 24, children }) => (
|
const AccentAvatar = ({ color, selected, size = 24, children }) => (
|
||||||
<Avatar
|
<Avatar
|
||||||
@@ -396,7 +396,7 @@ const Invoice = () => {
|
|||||||
bgcolor: '#ffffff',
|
bgcolor: '#ffffff',
|
||||||
'& fieldset': { borderColor: '#e2e8f0', borderWidth: 1 },
|
'& fieldset': { borderColor: '#e2e8f0', borderWidth: 1 },
|
||||||
'&:hover fieldset': { borderColor: '#cbd5e1' },
|
'&:hover fieldset': { borderColor: '#cbd5e1' },
|
||||||
'&.Mui-focused fieldset': { borderColor: '#662582', borderWidth: 1.5 },
|
'&.Mui-focused fieldset': { borderColor: '#C01227', borderWidth: 1.5 },
|
||||||
'&.Mui-focused': { boxShadow: `0 0 0 3px ${ring(BRAND)}` }
|
'&.Mui-focused': { boxShadow: `0 0 0 3px ${ring(BRAND)}` }
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -3,7 +3,10 @@ import { useLocation } from 'react-router-dom';
|
|||||||
import { useTheme } from '@mui/material/styles';
|
import { useTheme } from '@mui/material/styles';
|
||||||
import useMediaQuery from '@mui/material/useMediaQuery';
|
import useMediaQuery from '@mui/material/useMediaQuery';
|
||||||
// import nearleLogo from '../../../assets/images/nearleLogo.png';
|
// import nearleLogo from '../../../assets/images/nearleLogo.png';
|
||||||
import logo_nearle1 from '../../../assets/images/logo-nearle1.png';
|
import logo_nearle1 from '../../../assets/images/doormile-logo.png';
|
||||||
|
|
||||||
|
// doormile-logo.png is a white asset; this recolours it to brand red (#C01227) for the light invoice background.
|
||||||
|
const DOORMILE_RED_FILTER = 'brightness(0) saturate(100%) invert(15%) sepia(93%) saturate(5437%) hue-rotate(346deg) brightness(81%) contrast(92%)';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import Loader from 'components/Loader';
|
import Loader from 'components/Loader';
|
||||||
@@ -191,7 +194,7 @@ const InvoicePreview = () => {
|
|||||||
>
|
>
|
||||||
<Box sx={{ pt: 0.5 }}>
|
<Box sx={{ pt: 0.5 }}>
|
||||||
<Stack direction="row" spacing={2}>
|
<Stack direction="row" spacing={2}>
|
||||||
<img src={logo_nearle1} style={{ width: '150px', height: '50px' }} />{' '}
|
<img src={logo_nearle1} style={{ width: '150px', height: '20px', filter: DOORMILE_RED_FILTER }} />{' '}
|
||||||
</Stack>
|
</Stack>
|
||||||
{/* <Typography
|
{/* <Typography
|
||||||
sx={{ color: theme.palette.primary.main, py: 0.5 }}
|
sx={{ color: theme.palette.primary.main, py: 0.5 }}
|
||||||
|
|||||||
@@ -8,8 +8,7 @@ import { useTheme } from '@mui/material/styles';
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import Loader from 'components/Loader';
|
import Loader from 'components/Loader';
|
||||||
import logo from 'assets/images/logo-nearle1.png';
|
import doormileLogo from 'assets/images/doormile-logo.png';
|
||||||
import expressImage from 'assets/images/express.png';
|
|
||||||
import { useSelector, useDispatch } from 'react-redux';
|
import { useSelector, useDispatch } from 'react-redux';
|
||||||
import { OpenToast } from 'components/third-party/OpenToast';
|
import { OpenToast } from 'components/third-party/OpenToast';
|
||||||
import { closeGlobalToast, GlobalToast } from 'components/nearle_components/GlobalToast';
|
import { closeGlobalToast, GlobalToast } from 'components/nearle_components/GlobalToast';
|
||||||
@@ -18,6 +17,9 @@ import VisibilityOff from '@mui/icons-material/VisibilityOff';
|
|||||||
import { setLoginUser } from 'store/reducers/loginUserSlice';
|
import { setLoginUser } from 'store/reducers/loginUserSlice';
|
||||||
import { markSessionStart } from 'utils/session';
|
import { markSessionStart } from 'utils/session';
|
||||||
|
|
||||||
|
// doormile-logo.png is a white asset; this recolours it to brand red (#C01227) for light surfaces.
|
||||||
|
const DOORMILE_RED_FILTER = 'brightness(0) saturate(100%) invert(15%) sepia(93%) saturate(5437%) hue-rotate(346deg) brightness(81%) contrast(92%)';
|
||||||
|
|
||||||
const Login = () => {
|
const Login = () => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const fcmtoken = useSelector((state) => state.fcm);
|
const fcmtoken = useSelector((state) => state.fcm);
|
||||||
@@ -167,18 +169,18 @@ const Login = () => {
|
|||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
color: '#fff',
|
color: '#fff',
|
||||||
p: 6,
|
p: 6,
|
||||||
background: 'linear-gradient(150deg, #4D1C61 0%, #662582 52%, #9255AB 100%)'
|
background: 'linear-gradient(150deg, #900E1D 0%, #C01227 52%, #D35968 100%)'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{/* Logo at the top-left corner */}
|
{/* Logo at the top-left corner */}
|
||||||
<img
|
<img
|
||||||
src={expressImage}
|
src={doormileLogo}
|
||||||
alt="Operate your dispatch"
|
alt="Doormile"
|
||||||
style={{
|
style={{
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
top: 48,
|
top: 48,
|
||||||
left: 48,
|
left: 48,
|
||||||
maxHeight: 60
|
maxHeight: 40
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@@ -213,7 +215,7 @@ const Login = () => {
|
|||||||
end to end.
|
end to end.
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography sx={{ fontSize: 17.5, color: 'rgba(255,255,255,0.85)', mb: 4, lineHeight: 1.6 }}>
|
<Typography sx={{ fontSize: 17.5, color: 'rgba(255,255,255,0.85)', mb: 4, lineHeight: 1.6 }}>
|
||||||
Orders, AI route optimisation, live rider tracking and billing — all in the NearlExpress operator console.
|
Orders, AI route optimisation, live rider tracking and billing — all in the Doormile operator console.
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
<Stack spacing={1.5} sx={{ display: 'inline-flex', textAlign: 'left' }}>
|
<Stack spacing={1.5} sx={{ display: 'inline-flex', textAlign: 'left' }}>
|
||||||
@@ -255,7 +257,7 @@ const Login = () => {
|
|||||||
>
|
>
|
||||||
{/* Logo */}
|
{/* Logo */}
|
||||||
<Stack alignItems="center" mb={2.5}>
|
<Stack alignItems="center" mb={2.5}>
|
||||||
<img src={logo} alt="loginpagelogo" style={{ maxHeight: 48 }} />
|
<img src={doormileLogo} alt="Doormile" style={{ maxHeight: 40, filter: DOORMILE_RED_FILTER }} />
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
{/* Title */}
|
{/* Title */}
|
||||||
@@ -263,7 +265,7 @@ const Login = () => {
|
|||||||
Welcome back
|
Welcome back
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="body2" textAlign="center" sx={{ color: '#64748b', mb: 3 }}>
|
<Typography variant="body2" textAlign="center" sx={{ color: '#64748b', mb: 3 }}>
|
||||||
Sign in to the NearlExpress console
|
Sign in to the Doormile console
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
<CardContent sx={{ p: 0 }}>
|
<CardContent sx={{ p: 0 }}>
|
||||||
@@ -440,7 +442,7 @@ const Login = () => {
|
|||||||
component={Link}
|
component={Link}
|
||||||
href="https://nearle.in"
|
href="https://nearle.in"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
sx={{ color: '#94a3b8', textDecoration: 'none', fontWeight: 600, '&:hover': { color: '#662582' } }}
|
sx={{ color: '#94a3b8', textDecoration: 'none', fontWeight: 600, '&:hover': { color: '#C01227' } }}
|
||||||
>
|
>
|
||||||
© All rights reserved
|
© All rights reserved
|
||||||
</Typography>
|
</Typography>
|
||||||
@@ -449,7 +451,7 @@ const Login = () => {
|
|||||||
component={Link}
|
component={Link}
|
||||||
href="https://nearle.in/terms"
|
href="https://nearle.in/terms"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
sx={{ color: '#94a3b8', textDecoration: 'none', fontWeight: 600, '&:hover': { color: '#662582' } }}
|
sx={{ color: '#94a3b8', textDecoration: 'none', fontWeight: 600, '&:hover': { color: '#C01227' } }}
|
||||||
>
|
>
|
||||||
Terms and Conditions
|
Terms and Conditions
|
||||||
</Typography>
|
</Typography>
|
||||||
@@ -458,7 +460,7 @@ const Login = () => {
|
|||||||
component={Link}
|
component={Link}
|
||||||
href="https://nearle.in/privacy"
|
href="https://nearle.in/privacy"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
sx={{ color: '#94a3b8', textDecoration: 'none', fontWeight: 600, '&:hover': { color: '#662582' } }}
|
sx={{ color: '#94a3b8', textDecoration: 'none', fontWeight: 600, '&:hover': { color: '#C01227' } }}
|
||||||
>
|
>
|
||||||
Privacy Policy
|
Privacy Policy
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|||||||
@@ -22,7 +22,10 @@ import { useTheme } from '@mui/material/styles';
|
|||||||
import useMediaQuery from '@mui/material/useMediaQuery';
|
import useMediaQuery from '@mui/material/useMediaQuery';
|
||||||
import AnimateButton from 'components/@extended/AnimateButton';
|
import AnimateButton from 'components/@extended/AnimateButton';
|
||||||
|
|
||||||
import logo from 'assets/images/logo-nearle1.png';
|
import logo from 'assets/images/doormile-logo.png';
|
||||||
|
|
||||||
|
// doormile-logo.png is a white asset; this recolours it to brand red (#C01227) for light surfaces.
|
||||||
|
const DOORMILE_RED_FILTER = 'brightness(0) saturate(100%) invert(15%) sepia(93%) saturate(5437%) hue-rotate(346deg) brightness(81%) contrast(92%)';
|
||||||
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
@@ -228,7 +231,7 @@ const Login = () => {
|
|||||||
// sx={{ ml: 3, mt: 3 }}
|
// sx={{ ml: 3, mt: 3 }}
|
||||||
sx={{ ml: { xs: 0, md: 3 }, mt: { xs: 3, md: 1 }, textAlign: { xs: 'center', md: 'left' } }}
|
sx={{ ml: { xs: 0, md: 3 }, mt: { xs: 3, md: 1 }, textAlign: { xs: 'center', md: 'left' } }}
|
||||||
>
|
>
|
||||||
<img src={logo} alt="legendary" width={isMobile ? '160px' : '200px'} />
|
<img src={logo} alt="Doormile" width={isMobile ? '160px' : '200px'} style={{ filter: DOORMILE_RED_FILTER }} />
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Grid
|
<Grid
|
||||||
|
|||||||
@@ -696,7 +696,7 @@
|
|||||||
|
|
||||||
.weight-card-btn.active.weight-heavy {
|
.weight-card-btn.active.weight-heavy {
|
||||||
background: rgba(99, 102, 241, 0.04) !important;
|
background: rgba(99, 102, 241, 0.04) !important;
|
||||||
border-color: #662582 !important;
|
border-color: #C01227 !important;
|
||||||
box-shadow: 0 6px 16px rgba(99, 102, 241, 0.15) !important;
|
box-shadow: 0 6px 16px rgba(99, 102, 241, 0.15) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -707,7 +707,7 @@
|
|||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
height: 3px;
|
height: 3px;
|
||||||
background: #662582;
|
background: #C01227;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Premium Card Overrides */
|
/* Premium Card Overrides */
|
||||||
|
|||||||
@@ -159,9 +159,9 @@ const OrderMap = ({ startPoint, endPoint, appLocaLat, appLocaLng }) => {
|
|||||||
{hasPick && <Marker position={pickCoords} icon={pickupIcon} />}
|
{hasPick && <Marker position={pickCoords} icon={pickupIcon} />}
|
||||||
{hasDrop && <Marker position={dropCoords} icon={dropoffIcon} />}
|
{hasDrop && <Marker position={dropCoords} icon={dropoffIcon} />}
|
||||||
{routePoints.length > 0 ? (
|
{routePoints.length > 0 ? (
|
||||||
<Polyline positions={routePoints} color="#662582" weight={4} />
|
<Polyline positions={routePoints} color="#C01227" weight={4} />
|
||||||
) : (
|
) : (
|
||||||
hasPick && hasDrop && <Polyline positions={[pickCoords, dropCoords]} color="#662582" weight={4} />
|
hasPick && hasDrop && <Polyline positions={[pickCoords, dropCoords]} color="#C01227" weight={4} />
|
||||||
)}
|
)}
|
||||||
<MapBoundsController startPoint={startPoint} endPoint={endPoint} />
|
<MapBoundsController startPoint={startPoint} endPoint={endPoint} />
|
||||||
</MapContainer>
|
</MapContainer>
|
||||||
@@ -1388,7 +1388,7 @@ const Createorder1 = () => {
|
|||||||
InputProps={{
|
InputProps={{
|
||||||
startAdornment: (
|
startAdornment: (
|
||||||
<InputAdornment position="start">
|
<InputAdornment position="start">
|
||||||
<SearchOutlined style={{ fontSize: 15, color: '#662582' }} />
|
<SearchOutlined style={{ fontSize: 15, color: '#C01227' }} />
|
||||||
</InputAdornment>
|
</InputAdornment>
|
||||||
),
|
),
|
||||||
endAdornment: (
|
endAdornment: (
|
||||||
@@ -1424,7 +1424,7 @@ const Createorder1 = () => {
|
|||||||
InputProps={{
|
InputProps={{
|
||||||
startAdornment: (
|
startAdornment: (
|
||||||
<InputAdornment position="start">
|
<InputAdornment position="start">
|
||||||
<FaLocationDot style={{ fontSize: 14, color: '#662582' }} />
|
<FaLocationDot style={{ fontSize: 14, color: '#C01227' }} />
|
||||||
</InputAdornment>
|
</InputAdornment>
|
||||||
),
|
),
|
||||||
endAdornment: (
|
endAdornment: (
|
||||||
@@ -2166,7 +2166,7 @@ const Createorder1 = () => {
|
|||||||
{/* Map Card */}
|
{/* Map Card */}
|
||||||
<Card className="orders-card" sx={{ p: 1.5, display: 'flex', flexDirection: 'column' }}>
|
<Card className="orders-card" sx={{ p: 1.5, display: 'flex', flexDirection: 'column' }}>
|
||||||
<Typography sx={{ fontWeight: 700, mb: 1.25, display: 'flex', alignItems: 'center', gap: 0.75, color: '#1e293b', fontSize: '14px', letterSpacing: '-0.01em' }}>
|
<Typography sx={{ fontWeight: 700, mb: 1.25, display: 'flex', alignItems: 'center', gap: 0.75, color: '#1e293b', fontSize: '14px', letterSpacing: '-0.01em' }}>
|
||||||
<MyLocationIcon sx={{ color: '#662582', fontSize: 16 }} />
|
<MyLocationIcon sx={{ color: '#C01227', fontSize: 16 }} />
|
||||||
Live Route Preview
|
Live Route Preview
|
||||||
</Typography>
|
</Typography>
|
||||||
<div className="map-preview-wrapper">
|
<div className="map-preview-wrapper">
|
||||||
@@ -2345,7 +2345,7 @@ const Createorder1 = () => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<DialogTitle sx={{ background: 'linear-gradient(135deg, #662582 0%, #9255AB 100%)', color: 'white', py: 2.5 }}>
|
<DialogTitle sx={{ background: 'linear-gradient(135deg, #C01227 0%, #D35968 100%)', color: 'white', py: 2.5 }}>
|
||||||
<Stack spacing={1.5}>
|
<Stack spacing={1.5}>
|
||||||
<Typography variant="h4" sx={{ fontWeight: 600, color: 'white' }}>
|
<Typography variant="h4" sx={{ fontWeight: 600, color: 'white' }}>
|
||||||
{`Select Saved Address (${pickordrop === 1 ? 'Pickup' : 'Drop'})`}
|
{`Select Saved Address (${pickordrop === 1 ? 'Pickup' : 'Drop'})`}
|
||||||
|
|||||||
@@ -895,7 +895,7 @@ const Details = () => {
|
|||||||
{stafflist.map((val, i) => {
|
{stafflist.map((val, i) => {
|
||||||
const isSelected = staffarr.find((res) => res.userid == val.userid) ? true : false;
|
const isSelected = staffarr.find((res) => res.userid == val.userid) ? true : false;
|
||||||
return (
|
return (
|
||||||
<MobileCard key={i} accent="#662582" selected={isSelected}>
|
<MobileCard key={i} accent="#C01227" selected={isSelected}>
|
||||||
<Stack direction="row" justifyContent="space-between" alignItems="flex-start" spacing={1}>
|
<Stack direction="row" justifyContent="space-between" alignItems="flex-start" spacing={1}>
|
||||||
<Stack direction="row" alignItems="center" spacing={1}>
|
<Stack direction="row" alignItems="center" spacing={1}>
|
||||||
<Avatar alt="" src={''} sx={{ width: 32, height: 32 }} />
|
<Avatar alt="" src={''} sx={{ width: 32, height: 32 }} />
|
||||||
@@ -1549,14 +1549,14 @@ const Details = () => {
|
|||||||
{isMobile ? (
|
{isMobile ? (
|
||||||
<MobileCardList>
|
<MobileCardList>
|
||||||
{val5.orderdetails.length === 0 && (
|
{val5.orderdetails.length === 0 && (
|
||||||
<MobileCard accent="#662582">
|
<MobileCard accent="#C01227">
|
||||||
<Skeleton animation="wave" />
|
<Skeleton animation="wave" />
|
||||||
<Skeleton animation="wave" />
|
<Skeleton animation="wave" />
|
||||||
<Skeleton animation="wave" />
|
<Skeleton animation="wave" />
|
||||||
</MobileCard>
|
</MobileCard>
|
||||||
)}
|
)}
|
||||||
{val5.orderdetails.map((row, i) => (
|
{val5.orderdetails.map((row, i) => (
|
||||||
<MobileCard key={i + 1} accent="#662582" sx={{ opacity: row.status == 0 ? '' : '0.7' }}>
|
<MobileCard key={i + 1} accent="#C01227" sx={{ opacity: row.status == 0 ? '' : '0.7' }}>
|
||||||
<Stack direction="row" justifyContent="space-between" alignItems="flex-start" spacing={1}>
|
<Stack direction="row" justifyContent="space-between" alignItems="flex-start" spacing={1}>
|
||||||
<Stack direction="column">
|
<Stack direction="column">
|
||||||
<Typography sx={{ fontSize: 10, fontWeight: 800, color: '#94a3b8' }}>#{i + 1}</Typography>
|
<Typography sx={{ fontSize: 10, fontWeight: 800, color: '#94a3b8' }}>#{i + 1}</Typography>
|
||||||
|
|||||||
@@ -1,741 +0,0 @@
|
|||||||
import {
|
|
||||||
Autocomplete,
|
|
||||||
Button,
|
|
||||||
Chip,
|
|
||||||
Divider,
|
|
||||||
Grid,
|
|
||||||
Stack,
|
|
||||||
Table,
|
|
||||||
TableBody,
|
|
||||||
TableCell,
|
|
||||||
TableContainer,
|
|
||||||
TableHead,
|
|
||||||
TableRow,
|
|
||||||
TextField,
|
|
||||||
Tooltip,
|
|
||||||
Typography,
|
|
||||||
Backdrop,
|
|
||||||
IconButton,
|
|
||||||
Badge,
|
|
||||||
Accordion,
|
|
||||||
AccordionSummary,
|
|
||||||
AccordionActions,
|
|
||||||
AccordionDetails,
|
|
||||||
useMediaQuery
|
|
||||||
} from '@mui/material';
|
|
||||||
import React, { Fragment, useEffect, useMemo, useState } from 'react';
|
|
||||||
import { useTheme } from '@mui/material/styles';
|
|
||||||
import { MobileCard, MobileCardList, MobileField, MobileFieldGrid } from 'components/nearle_components/MobileCard';
|
|
||||||
import { useLocation, useNavigate } from 'react-router-dom';
|
|
||||||
import dayjs from 'dayjs';
|
|
||||||
import MainCard from 'components/MainCard';
|
|
||||||
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
|
|
||||||
import { createAutomationDeliveries, fetchPaymentType, fetchRidersList, finalCreatedeliveries, notifyRider } from 'pages/api/api';
|
|
||||||
import { OpenToast } from 'components/third-party/OpenToast';
|
|
||||||
import { useMutation, useQuery } from '@tanstack/react-query';
|
|
||||||
import Loader from 'components/Loader';
|
|
||||||
import CircularLoader from 'components/CircularLoader';
|
|
||||||
import { Empty } from 'antd';
|
|
||||||
import HoverSocialCard from 'components/cards/statistics/HoverSocialCard';
|
|
||||||
import { DashboardFilled, DashboardOutlined, OpenAIFilled } from '@ant-design/icons';
|
|
||||||
import { MdDirectionsBike } from 'react-icons/md';
|
|
||||||
import { FaMapLocationDot } from 'react-icons/fa6';
|
|
||||||
import { HiOutlineArrowLeft } from 'react-icons/hi';
|
|
||||||
import { IoReload } from 'react-icons/io5';
|
|
||||||
import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank';
|
|
||||||
import CheckBoxIcon from '@mui/icons-material/CheckBox';
|
|
||||||
import { GiProfit } from 'react-icons/gi';
|
|
||||||
import { ArrowRightAltOutlined } from '@mui/icons-material';
|
|
||||||
import LocalShippingIcon from '@mui/icons-material/LocalShipping';
|
|
||||||
import WarningIcon from '@mui/icons-material/Warning';
|
|
||||||
import BoltIcon from '@mui/icons-material/Bolt';
|
|
||||||
import CurrencyRupeeIcon from '@mui/icons-material/CurrencyRupee';
|
|
||||||
import SavingsIcon from '@mui/icons-material/Savings';
|
|
||||||
import EnergySavingsLeafIcon from '@mui/icons-material/EnergySavingsLeaf';
|
|
||||||
import DirectionsBikeOutlinedIcon from '@mui/icons-material/DirectionsBikeOutlined';
|
|
||||||
import DownloadOutlinedIcon from '@mui/icons-material/DownloadOutlined';
|
|
||||||
import { exportToExcel } from 'components/exportToExcel';
|
|
||||||
import CSVExport from 'components/third-party/ReactTable';
|
|
||||||
|
|
||||||
var utc = require('dayjs/plugin/utc');
|
|
||||||
dayjs.extend(utc);
|
|
||||||
|
|
||||||
const OptimisedOrderPreview = () => {
|
|
||||||
const theme = useTheme();
|
|
||||||
const isMobile = useMediaQuery(theme.breakpoints.down('md'));
|
|
||||||
const navigate = useNavigate();
|
|
||||||
const location = useLocation();
|
|
||||||
console.log('location.state', location.state);
|
|
||||||
const [rider, setRider] = useState(null);
|
|
||||||
const [payment, setPayment] = useState(null);
|
|
||||||
const [finaldeliveryList, setFinalDeliveryList] = useState([]);
|
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
|
||||||
const [deliverylist, setDeliverylist] = useState(location.state?.deliverylist);
|
|
||||||
const [zoneData, setZoneData] = useState(location?.state?.zoneData);
|
|
||||||
const [metaData, setMetaData] = useState(location.state?.metaData);
|
|
||||||
const riderToken = location.state?.riderToken;
|
|
||||||
const appId = location.state?.appId;
|
|
||||||
const aiMode = location.state?.aiMode;
|
|
||||||
const reassignOrders = location.state?.reassignOrders;
|
|
||||||
const [csvExportData, setCsvExportData] = useState([]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
console.log('called');
|
|
||||||
|
|
||||||
console.log('aiMode', aiMode);
|
|
||||||
console.log('riderToken', riderToken);
|
|
||||||
console.log('zoneData', zoneData);
|
|
||||||
console.log('metaData', metaData);
|
|
||||||
console.log('reassignOrders', reassignOrders);
|
|
||||||
}, [zoneData, metaData, deliverylist]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const filtered = finaldeliveryList.map((item) => ({
|
|
||||||
zone_name: item.zone_name,
|
|
||||||
ordernotes: item.ordernotes,
|
|
||||||
rider: item.rider,
|
|
||||||
step: item.step,
|
|
||||||
ordertype: item.ordertype,
|
|
||||||
orderamount: item.orderamount,
|
|
||||||
riderkms: item.riderkms,
|
|
||||||
cumulativekms: item.cumulativekms,
|
|
||||||
baseprice: item.baseprice,
|
|
||||||
minkm: item.minkm,
|
|
||||||
priceperkm: item.priceperkm,
|
|
||||||
kms: item.kms,
|
|
||||||
actualkms: item.actualkms,
|
|
||||||
rider_charge: item.rider_charge,
|
|
||||||
deliveryamt: item.deliveryamt,
|
|
||||||
deliverycharges: item.deliverycharges,
|
|
||||||
profit: item.profit
|
|
||||||
}));
|
|
||||||
|
|
||||||
setCsvExportData(filtered);
|
|
||||||
|
|
||||||
console.log('csvExportData', filtered);
|
|
||||||
}, [finaldeliveryList]);
|
|
||||||
useEffect(() => {
|
|
||||||
if (!deliverylist?.length) return;
|
|
||||||
const updateDeliveryAmtList = deliverylist.map((list) => {
|
|
||||||
const cumulativeKms = Number(list.cumulativekms || 0);
|
|
||||||
const minKm = Number(list.minkm || 0);
|
|
||||||
const basePrice = Number(list.baseprice || 0);
|
|
||||||
const pricePerKm = Number(list.priceperkm || 0);
|
|
||||||
if (cumulativeKms <= minKm) {
|
|
||||||
return {
|
|
||||||
...list,
|
|
||||||
deliveryamt: basePrice
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
...list,
|
|
||||||
deliveryamt: (cumulativeKms - minKm) * pricePerKm + basePrice
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
setFinalDeliveryList(updateDeliveryAmtList);
|
|
||||||
console.log('finaldeliveryList', updateDeliveryAmtList);
|
|
||||||
}, [deliverylist]);
|
|
||||||
|
|
||||||
// ==============================|| fetchPaymentType ||============================== //
|
|
||||||
|
|
||||||
const {
|
|
||||||
data: paymentModes = [],
|
|
||||||
isLoading: paymentModesLoading,
|
|
||||||
isError: paymentModesError,
|
|
||||||
error: paymentModesErrorMessage
|
|
||||||
} = useQuery({
|
|
||||||
queryKey: ['paymentmodes'],
|
|
||||||
queryFn: fetchPaymentType
|
|
||||||
});
|
|
||||||
|
|
||||||
// ==============================|| fetchRidersList ||============================== //
|
|
||||||
|
|
||||||
const {
|
|
||||||
data: ridersList = [],
|
|
||||||
isLoading: ridersListLoading,
|
|
||||||
isError: ridersListError,
|
|
||||||
error: ridersListErrorMessage,
|
|
||||||
refetch: ridersListRefetch
|
|
||||||
} = useQuery({
|
|
||||||
queryKey: ['ridersList', appId], // Unique key for caching & re-fetching
|
|
||||||
queryFn: fetchRidersList,
|
|
||||||
enabled: appId !== 0 // Ensures query runs only when appId is valid
|
|
||||||
});
|
|
||||||
|
|
||||||
const getRiderName = async (userid) => {
|
|
||||||
await ridersList.map((rider) => {
|
|
||||||
if (rider.userid == userid) {
|
|
||||||
return rider.firstname;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// ======================================================= || notifyRiderMutation || =======================================================
|
|
||||||
|
|
||||||
const notifyRiderMutation = useMutation({
|
|
||||||
mutationFn: notifyRider, // Using the separate function
|
|
||||||
onSuccess: () => {
|
|
||||||
OpenToast('Notification sent Successfully', 'success', 2000);
|
|
||||||
},
|
|
||||||
onError: (error) => {
|
|
||||||
OpenToast(error.message, 'error', 2000);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const createFinalDeliveryMutation = useMutation({
|
|
||||||
mutationFn: finalCreatedeliveries, // for optimised delivery create
|
|
||||||
|
|
||||||
onSuccess: (data, variables) => {
|
|
||||||
console.log('data', data);
|
|
||||||
console.log('varialbles', variables);
|
|
||||||
notifyRiderMutation.mutate(rider.userfcmtoken || riderToken); // Call notifyRider after success
|
|
||||||
if (data.status == 'accepted') {
|
|
||||||
OpenToast('Delivery Created Successfully', 'success', 2000);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onError: (error) => {
|
|
||||||
OpenToast(error.message, 'error', 4000);
|
|
||||||
},
|
|
||||||
onSettled: () => {
|
|
||||||
setTimeout(() => {
|
|
||||||
setIsLoading(false);
|
|
||||||
navigate('/nearle/deliveries');
|
|
||||||
}, 2000);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleFinalCreateDelivery = async () => {
|
|
||||||
// console.log('Final delivery list:', finaldeliveryList);
|
|
||||||
|
|
||||||
setIsLoading(true);
|
|
||||||
createFinalDeliveryMutation.mutate({
|
|
||||||
deliveries: finaldeliveryList
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const createDeliveryMutation = useMutation({
|
|
||||||
// 0 -> manual rider assign 1 -> ai rider assign
|
|
||||||
mutationFn: createAutomationDeliveries,
|
|
||||||
onSuccess: (data, variables) => {
|
|
||||||
console.log('data', data);
|
|
||||||
console.log('varialbles', variables);
|
|
||||||
OpenToast('Orders Optimised Successfully', 'success', 2000);
|
|
||||||
// notifyRiderMutation.mutate(variables?.riderToken); // Call notifyRider after success
|
|
||||||
setZoneData(data?.zones);
|
|
||||||
setDeliverylist(data?.details);
|
|
||||||
setMetaData(data?.meta);
|
|
||||||
setIsLoading(false);
|
|
||||||
},
|
|
||||||
onError: (error) => {
|
|
||||||
OpenToast(error.message, 'error', 4000);
|
|
||||||
setIsLoading(false);
|
|
||||||
},
|
|
||||||
onSettled: () => {
|
|
||||||
setIsLoading(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const tuningTypes = [
|
|
||||||
{
|
|
||||||
tuneid: 1,
|
|
||||||
type: 'Rider'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tuneid: 2,
|
|
||||||
type: 'Pickup'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tuneid: 3,
|
|
||||||
type: 'Zone'
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Fragment>
|
|
||||||
{
|
|
||||||
<Backdrop
|
|
||||||
sx={{
|
|
||||||
color: '#fff',
|
|
||||||
zIndex: (theme) => theme.zIndex.drawer + 1
|
|
||||||
}}
|
|
||||||
open={paymentModesLoading || ridersListLoading || isLoading} // when loader = true, backdrop covers the page
|
|
||||||
>
|
|
||||||
<CircularLoader color="inherit" />
|
|
||||||
</Backdrop>
|
|
||||||
}
|
|
||||||
{(paymentModesLoading || ridersListLoading || isLoading) && (
|
|
||||||
<>
|
|
||||||
<Loader />
|
|
||||||
<CircularLoader />
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
<Stack
|
|
||||||
direction={{ xs: 'column', md: 'row' }}
|
|
||||||
alignItems={{ xs: 'stretch', md: 'center' }}
|
|
||||||
justifyContent="space-between"
|
|
||||||
spacing={{ xs: 1.5, md: 0 }}
|
|
||||||
sx={{}}
|
|
||||||
>
|
|
||||||
<Stack direction="row" alignItems="center" spacing={1}>
|
|
||||||
<Tooltip title="Back to orders" placement="top">
|
|
||||||
<IconButton
|
|
||||||
onClick={() => navigate('/nearle/orders')}
|
|
||||||
sx={{
|
|
||||||
bgcolor: 'action.hover',
|
|
||||||
'&:hover': { bgcolor: 'action.selected' }
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<HiOutlineArrowLeft size={20} />
|
|
||||||
</IconButton>
|
|
||||||
</Tooltip>
|
|
||||||
<Typography variant="h3" fontWeight={600}>
|
|
||||||
Assign Orders
|
|
||||||
</Typography>
|
|
||||||
</Stack>
|
|
||||||
|
|
||||||
{/* <Button
|
|
||||||
variant="contained"
|
|
||||||
color="primary"
|
|
||||||
startIcon={<IoReload />}
|
|
||||||
onClick={() => {
|
|
||||||
setIsLoading(true);
|
|
||||||
createDeliveryMutation.mutate({ deliveries: reassignOrders });
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Tuning
|
|
||||||
</Button> */}
|
|
||||||
<Autocomplete
|
|
||||||
multiple
|
|
||||||
id="checkboxes-tags-demo"
|
|
||||||
options={tuningTypes}
|
|
||||||
disableCloseOnSelect
|
|
||||||
getOptionLabel={(option) => option.type}
|
|
||||||
renderOption={(props, option, { selected }) => {
|
|
||||||
const { id, ...optionProps } = props;
|
|
||||||
const SelectionIcon = selected ? CheckBoxIcon : CheckBoxOutlineBlankIcon;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<li key={id} {...optionProps}>
|
|
||||||
<SelectionIcon fontSize="small" style={{ marginRight: 8, padding: 9, boxSizing: 'content-box' }} />
|
|
||||||
{option.type}
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
sx={{ width: { xs: '100%', md: 400 } }}
|
|
||||||
renderInput={(params) => (
|
|
||||||
<TextField
|
|
||||||
{...params}
|
|
||||||
sx={{
|
|
||||||
'& .MuiInputBase-input': {
|
|
||||||
lineHeight: '1.5' // 👈 important
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
label="Hyper Tuning"
|
|
||||||
// placeholder="Favorites"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
{/* <Button
|
|
||||||
variant="outlined"
|
|
||||||
size="small"
|
|
||||||
startIcon={<DownloadOutlinedIcon />}
|
|
||||||
onClick={() => {
|
|
||||||
exportToExcel(finaldeliveryList, 'users', 'UsersData');
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Export Report
|
|
||||||
</Button> */}
|
|
||||||
<CSVExport
|
|
||||||
data={csvExportData}
|
|
||||||
filename={`Orders_Detail_${dayjs().format('YYYY-MM-DD_HHmmss')}.csv`}
|
|
||||||
label=" CSV"
|
|
||||||
style={{ m: 1 }}
|
|
||||||
/>
|
|
||||||
</Stack>
|
|
||||||
<Stack sx={{ my: 2 }}>
|
|
||||||
<Grid container spacing={2}>
|
|
||||||
<Grid item xs={6} sm={6} md={3}>
|
|
||||||
<HoverSocialCard
|
|
||||||
secondary={metaData?.total_orders}
|
|
||||||
primary={'Orders'}
|
|
||||||
percentage={<DashboardFilled />}
|
|
||||||
color={theme.palette.success.main}
|
|
||||||
sx={{ cursor: 'pointer' }}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={6} sm={6} md={3}>
|
|
||||||
<HoverSocialCard
|
|
||||||
secondary={metaData?.utilized_riders}
|
|
||||||
primary={'Riders'}
|
|
||||||
percentage={<MdDirectionsBike />}
|
|
||||||
color={theme.palette.warning.main}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={6} sm={6} md={3}>
|
|
||||||
<HoverSocialCard
|
|
||||||
secondary={zoneData?.length}
|
|
||||||
primary={'Zones'}
|
|
||||||
percentage={<FaMapLocationDot />}
|
|
||||||
color={theme.palette.info.main}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={6} sm={6} md={3}>
|
|
||||||
<HoverSocialCard
|
|
||||||
secondary={metaData?.total_profit}
|
|
||||||
primary={'Profit'}
|
|
||||||
percentage={<GiProfit />}
|
|
||||||
color={theme.palette.error.main}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</Stack>
|
|
||||||
<MainCard content={false}>
|
|
||||||
{zoneData?.map((zone, index) => {
|
|
||||||
const riders = zone?.riders.flatMap((rider) => rider);
|
|
||||||
const orders = zone?.riders?.flatMap((rider) => rider.orders);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Accordion key={index}>
|
|
||||||
<AccordionSummary>
|
|
||||||
<Stack direction="row" alignItems="center" spacing={2} sx={{ m: 2 }}>
|
|
||||||
<Typography variant="h5" fontWeight={1000}>
|
|
||||||
Zone {index + 1} :
|
|
||||||
</Typography>
|
|
||||||
<Chip label={zone.zone_name} color="primary" variant="light" size="small" sx={{ minWidth: 100 }} />
|
|
||||||
<Tooltip title={`Orders`} placement="top">
|
|
||||||
<Badge badgeContent={zone.total_orders} color="secondary">
|
|
||||||
<DashboardOutlined style={{ fontSize: 20 }} />
|
|
||||||
</Badge>
|
|
||||||
</Tooltip>
|
|
||||||
<Tooltip title={`Riders`} placement="top">
|
|
||||||
<Badge color="secondary" badgeContent={zone.active_riders_count}>
|
|
||||||
<DirectionsBikeOutlinedIcon style={{ fontSize: 20 }} />
|
|
||||||
</Badge>
|
|
||||||
</Tooltip>
|
|
||||||
</Stack>
|
|
||||||
</AccordionSummary>
|
|
||||||
<AccordionDetails sx={{ p: { xs: 0, md: 1 } }}>
|
|
||||||
{isMobile ? (
|
|
||||||
<MobileCardList>
|
|
||||||
{orders.map((val, i) => {
|
|
||||||
const typeAccent =
|
|
||||||
val.ordertype === 'Economy' ? '#10b981' : val.ordertype === 'Risky' ? '#ef4444' : '#662582';
|
|
||||||
return (
|
|
||||||
<MobileCard key={i} accent={typeAccent}>
|
|
||||||
<Stack direction="row" alignItems="center" justifyContent="space-between" spacing={1}>
|
|
||||||
<Stack direction="row" alignItems="center" spacing={1} sx={{ minWidth: 0 }}>
|
|
||||||
<Chip size="small" label={`#${i + 1}`} variant="light" color="primary" />
|
|
||||||
<Typography variant="subtitle2" noWrap sx={{ minWidth: 0 }}>
|
|
||||||
{`${val.locationname}-(${val.locationsuburb})`}
|
|
||||||
</Typography>
|
|
||||||
</Stack>
|
|
||||||
<Chip
|
|
||||||
size="small"
|
|
||||||
label={val.ordertype}
|
|
||||||
icon={
|
|
||||||
val.ordertype === 'Economy' ? (
|
|
||||||
<EnergySavingsLeafIcon />
|
|
||||||
) : val.ordertype === 'Risky' ? (
|
|
||||||
<WarningIcon />
|
|
||||||
) : (
|
|
||||||
<BoltIcon />
|
|
||||||
)
|
|
||||||
}
|
|
||||||
color={val.ordertype === 'Economy' ? 'success' : val.ordertype === 'Risky' ? 'error' : 'primary'}
|
|
||||||
variant="light"
|
|
||||||
/>
|
|
||||||
</Stack>
|
|
||||||
<MobileFieldGrid>
|
|
||||||
<MobileField label="Order Id" value={val.orderid} />
|
|
||||||
<MobileField label="Rider">
|
|
||||||
<Typography sx={{ fontSize: 13, fontWeight: 600 }} noWrap>
|
|
||||||
{val.rider}
|
|
||||||
</Typography>
|
|
||||||
<Typography variant="caption">ID : {val.userid}</Typography>
|
|
||||||
</MobileField>
|
|
||||||
<MobileField label="Pickup">
|
|
||||||
<Stack spacing={0.25} sx={{ minWidth: 0 }}>
|
|
||||||
<Typography variant="caption" noWrap>
|
|
||||||
{val.pickupcustomer}
|
|
||||||
</Typography>
|
|
||||||
<Typography variant="caption" noWrap>
|
|
||||||
{val.pickupcontactno}
|
|
||||||
</Typography>
|
|
||||||
<Tooltip title={val.pickupaddress}>
|
|
||||||
<Typography variant="caption" noWrap sx={{ cursor: 'pointer' }}>
|
|
||||||
{val.pickupsuburb || val.pickupaddress.slice(0, 20)}
|
|
||||||
</Typography>
|
|
||||||
</Tooltip>
|
|
||||||
<Chip
|
|
||||||
size="small"
|
|
||||||
label={dayjs(val.pickupslot).format('DD/MM/YYYY hh:mm A')}
|
|
||||||
variant="light"
|
|
||||||
sx={{ color: '#0a803b', bgcolor: '#c3f3c7', alignSelf: 'flex-start' }}
|
|
||||||
/>
|
|
||||||
</Stack>
|
|
||||||
</MobileField>
|
|
||||||
<MobileField label="Delivery">
|
|
||||||
<Stack spacing={0.25} sx={{ minWidth: 0 }}>
|
|
||||||
<Typography variant="caption" noWrap>
|
|
||||||
{val.deliverycustomer}
|
|
||||||
</Typography>
|
|
||||||
<Typography variant="caption" noWrap>
|
|
||||||
{val.deliverycontactno}
|
|
||||||
</Typography>
|
|
||||||
<Tooltip title={val.deliveryaddress}>
|
|
||||||
<Typography variant="caption" noWrap sx={{ cursor: 'pointer' }}>
|
|
||||||
{val.deliverysuburb || val.deliveryaddress.slice(0, 20)}
|
|
||||||
</Typography>
|
|
||||||
</Tooltip>
|
|
||||||
<Chip
|
|
||||||
size="small"
|
|
||||||
label={dayjs(val.expecteddeliverytime).format('DD/MM/YYYY hh:mm A')}
|
|
||||||
variant="light"
|
|
||||||
sx={{ color: '#DD2C00', background: '#FBE9E7', alignSelf: 'flex-start' }}
|
|
||||||
/>
|
|
||||||
</Stack>
|
|
||||||
</MobileField>
|
|
||||||
{val.ordernotes ? <MobileField full label="Notes" value={val.ordernotes} /> : null}
|
|
||||||
<MobileField label="Profit">
|
|
||||||
<Chip
|
|
||||||
size="small"
|
|
||||||
label={`₹ ${parseFloat(val?.profit).toFixed(2)}`}
|
|
||||||
variant="light"
|
|
||||||
sx={{ color: '#009688', bgcolor: '#b2dfdb' }}
|
|
||||||
/>
|
|
||||||
</MobileField>
|
|
||||||
<MobileField label="Charges">
|
|
||||||
<Chip
|
|
||||||
size="small"
|
|
||||||
label={`₹ ${val.deliverycharge.toFixed(2)} `}
|
|
||||||
variant="light"
|
|
||||||
sx={{ color: '#0074e7', bgcolor: '#cce3fa' }}
|
|
||||||
/>
|
|
||||||
</MobileField>
|
|
||||||
<MobileField label="KMS">
|
|
||||||
<Chip size="small" label={`${val.kms} km`} color="error" variant="light" />
|
|
||||||
</MobileField>
|
|
||||||
<MobileField label="Cumulative KMS">
|
|
||||||
<Chip size="small" label={`${val.cumulativekms} km`} color="success" variant="light" />
|
|
||||||
</MobileField>
|
|
||||||
</MobileFieldGrid>
|
|
||||||
</MobileCard>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</MobileCardList>
|
|
||||||
) : (
|
|
||||||
<TableContainer sx={{ p: 0, m: 0 }}>
|
|
||||||
<Table stickyHeader>
|
|
||||||
<TableHead>
|
|
||||||
<TableRow>
|
|
||||||
<TableCell>#</TableCell>
|
|
||||||
{/* <TableCell>Tenant</TableCell> */}
|
|
||||||
<TableCell>Order Location</TableCell>
|
|
||||||
<TableCell>Pickup</TableCell>
|
|
||||||
<TableCell>Delivery</TableCell>
|
|
||||||
<TableCell>Notes</TableCell>
|
|
||||||
<TableCell>Rider</TableCell>
|
|
||||||
<TableCell align="center">Type</TableCell>
|
|
||||||
<TableCell align="center">Profit</TableCell>
|
|
||||||
<TableCell align="center">Charges</TableCell>
|
|
||||||
<TableCell align="center">KMS</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
</TableHead>
|
|
||||||
|
|
||||||
<TableBody>
|
|
||||||
{orders.map((val, i) => (
|
|
||||||
<Fragment key={i}>
|
|
||||||
<TableRow sx={{}}>
|
|
||||||
<TableCell>
|
|
||||||
<Typography> {i + 1}</Typography>
|
|
||||||
</TableCell>
|
|
||||||
{/* <TableCell>
|
|
||||||
<Tooltip title={val.tenantaddress}>
|
|
||||||
<Typography variant="body1" noWrap>
|
|
||||||
{val.tenantname}
|
|
||||||
</Typography>
|
|
||||||
<Typography noWrap sx={{ fontSize: '11px' }}>
|
|
||||||
{val.tenantsuburb}
|
|
||||||
<br />
|
|
||||||
</Typography>
|
|
||||||
|
|
||||||
<Typography noWrap variant="body2">
|
|
||||||
{val.applocation}
|
|
||||||
</Typography>
|
|
||||||
</Tooltip>
|
|
||||||
</TableCell> */}
|
|
||||||
<TableCell align="left">
|
|
||||||
<Tooltip title={val.locationaddress} placement="top">
|
|
||||||
<Typography variant="body1" noWrap>
|
|
||||||
{`${val.locationname}-(${val.locationsuburb})`}
|
|
||||||
</Typography>
|
|
||||||
</Tooltip>
|
|
||||||
<Tooltip title="Order Id">
|
|
||||||
<Typography variant="body2" noWrap>
|
|
||||||
{val.orderid}
|
|
||||||
</Typography>
|
|
||||||
</Tooltip>
|
|
||||||
<Stack display={'flex'} flexDirection={'row'} gap={3} sx={{ cursor: 'pointer' }}>
|
|
||||||
<Tooltip title="Pickup Time">
|
|
||||||
<Typography noWrap sx={{ fontSize: '12px' }}>
|
|
||||||
{dayjs(val.pickupslot).format('DD/MM/YYYY')}
|
|
||||||
</Typography>
|
|
||||||
<Chip
|
|
||||||
size="small"
|
|
||||||
label={dayjs(val.pickupslot).format('hh:mm A')}
|
|
||||||
variant="light"
|
|
||||||
sx={{ color: '#0a803b', bgcolor: '#c3f3c7' }}
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
|
||||||
<ArrowRightAltOutlined />
|
|
||||||
<Tooltip title="Estimated Delivery time">
|
|
||||||
<Typography noWrap sx={{ fontSize: '12px' }}>
|
|
||||||
{dayjs(val.expecteddeliverytime).format('DD/MM/YYYY')}
|
|
||||||
</Typography>
|
|
||||||
<Chip
|
|
||||||
size="small"
|
|
||||||
label={dayjs(val.expecteddeliverytime).format('hh:mm A')}
|
|
||||||
variant="light"
|
|
||||||
sx={{ color: '#DD2C00', background: '#FBE9E7' }}
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
|
||||||
</Stack>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell align="left">
|
|
||||||
<Stack direction={'row'} spacing={1}>
|
|
||||||
<Stack direction="column">
|
|
||||||
<Typography variant="caption">{val.pickupcustomer}</Typography>
|
|
||||||
<Typography variant="caption">{val.pickupcontactno}</Typography>
|
|
||||||
<Tooltip title={val.pickupaddress}>
|
|
||||||
<Typography sx={{ cursor: 'pointer' }} variant="caption">
|
|
||||||
{val.pickupsuburb || val.pickupaddress.slice(0, 20)}
|
|
||||||
</Typography>
|
|
||||||
</Tooltip>
|
|
||||||
</Stack>
|
|
||||||
</Stack>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell align="left">
|
|
||||||
<Stack direction={'row'} spacing={1}>
|
|
||||||
<Stack direction="column">
|
|
||||||
<Typography variant="caption">{val.deliverycustomer}</Typography>
|
|
||||||
<Typography variant="caption">{val.deliverycontactno}</Typography>
|
|
||||||
<Tooltip title={val.deliveryaddress}>
|
|
||||||
<Typography sx={{ cursor: 'pointer' }} variant="caption">
|
|
||||||
{val.deliverysuburb || val.deliveryaddress.slice(0, 20)}
|
|
||||||
</Typography>
|
|
||||||
</Tooltip>
|
|
||||||
</Stack>
|
|
||||||
</Stack>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell align="left">
|
|
||||||
<Typography variant="caption" sx={{ whiteSpace: 'nowrap' }}>
|
|
||||||
{val.ordernotes}
|
|
||||||
</Typography>
|
|
||||||
</TableCell>
|
|
||||||
|
|
||||||
<TableCell align="left">
|
|
||||||
<Typography variant="caption" sx={{ whiteSpace: 'nowrap' }}>
|
|
||||||
{val.rider}
|
|
||||||
</Typography>
|
|
||||||
<br />
|
|
||||||
<Typography variant="caption">ID : {val.userid}</Typography>
|
|
||||||
</TableCell>
|
|
||||||
|
|
||||||
<TableCell align="center">
|
|
||||||
<Chip
|
|
||||||
size="small"
|
|
||||||
label={val.ordertype}
|
|
||||||
icon={
|
|
||||||
val.ordertype === 'Economy' ? (
|
|
||||||
<EnergySavingsLeafIcon />
|
|
||||||
) : val.ordertype === 'Risky' ? (
|
|
||||||
<WarningIcon />
|
|
||||||
) : (
|
|
||||||
<BoltIcon />
|
|
||||||
)
|
|
||||||
}
|
|
||||||
color={val.ordertype === 'Economy' ? 'success' : val.ordertype === 'Risky' ? 'error' : 'primary'}
|
|
||||||
variant="light"
|
|
||||||
/>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell align="center">
|
|
||||||
<Chip
|
|
||||||
size="small"
|
|
||||||
label={`₹ ${parseFloat(val?.profit).toFixed(2)}`}
|
|
||||||
variant="light"
|
|
||||||
sx={{ color: '#009688', bgcolor: '#b2dfdb' }}
|
|
||||||
/>
|
|
||||||
</TableCell>
|
|
||||||
|
|
||||||
<TableCell align="center">
|
|
||||||
<Stack display={'flex'} flexDirection={'column'} gap={1} sx={{ cursor: 'pointer' }}>
|
|
||||||
<Tooltip title="Charges" placement="top">
|
|
||||||
<Chip
|
|
||||||
size="small"
|
|
||||||
label={`₹ ${val.deliverycharge.toFixed(2)} `}
|
|
||||||
variant="light"
|
|
||||||
sx={{ color: '#0074e7', bgcolor: '#cce3fa' }}
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
|
||||||
{/* <Tooltip title="Amount" placement="left">
|
|
||||||
<Chip size="small" label={`₹ ${val.deliveryamt.toFixed(2)} `} color="success" variant="light" />
|
|
||||||
</Tooltip> */}
|
|
||||||
</Stack>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell align="center">
|
|
||||||
<Stack display={'flex'} flexDirection={'column'} gap={1} sx={{ cursor: 'pointer' }}>
|
|
||||||
<Tooltip title="KMS" placement="top">
|
|
||||||
<Chip size="small" label={`${val.kms} km`} color="error" variant="light" />
|
|
||||||
</Tooltip>
|
|
||||||
<Tooltip title="Cumulative Kms" placement="right">
|
|
||||||
<Chip size="small" label={`${val.cumulativekms} km`} color="success" variant="light" />
|
|
||||||
</Tooltip>
|
|
||||||
</Stack>
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
</Fragment>
|
|
||||||
))}
|
|
||||||
</TableBody>
|
|
||||||
</Table>
|
|
||||||
</TableContainer>
|
|
||||||
)}
|
|
||||||
</AccordionDetails>
|
|
||||||
</Accordion>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
|
|
||||||
<Divider />
|
|
||||||
<Stack
|
|
||||||
display={'flex'}
|
|
||||||
flexDirection={{ xs: 'column', sm: 'row' }}
|
|
||||||
gap={2}
|
|
||||||
alignItems={{ xs: 'stretch', sm: 'center' }}
|
|
||||||
justifyContent={'end'}
|
|
||||||
sx={{ p: 2 }}
|
|
||||||
>
|
|
||||||
<Button
|
|
||||||
sx={{ width: { xs: '100%', sm: 'auto' } }}
|
|
||||||
variant="contained"
|
|
||||||
color="secondary"
|
|
||||||
startIcon={<ArrowBackIcon />}
|
|
||||||
onClick={() => {
|
|
||||||
navigate('/nearle/orders');
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Back
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
sx={{ my: { xs: 0, sm: 2 }, width: { xs: '100%', sm: 'auto' } }}
|
|
||||||
variant="contained"
|
|
||||||
disabled={aiMode === 0 && (!rider || !payment)}
|
|
||||||
onClick={handleFinalCreateDelivery}
|
|
||||||
>
|
|
||||||
Assign Orders
|
|
||||||
</Button>
|
|
||||||
</Stack>
|
|
||||||
</MainCard>
|
|
||||||
</Fragment>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default OptimisedOrderPreview;
|
|
||||||
@@ -144,7 +144,7 @@ const dtSoft = (c) => dtA(c, '18');
|
|||||||
const dtRing = (c) => dtA(c, '26');
|
const dtRing = (c) => dtA(c, '26');
|
||||||
const dtEdge = (c) => dtA(c, '55');
|
const dtEdge = (c) => dtA(c, '55');
|
||||||
|
|
||||||
const BRAND = '#662582';
|
const BRAND = '#C01227';
|
||||||
|
|
||||||
const SoftPaper = (props) => (
|
const SoftPaper = (props) => (
|
||||||
<Paper
|
<Paper
|
||||||
@@ -181,8 +181,8 @@ const pillFieldSx = () => ({
|
|||||||
fontWeight: 600,
|
fontWeight: 600,
|
||||||
'& fieldset': { borderColor: '#e2e8f0', borderWidth: 1 },
|
'& fieldset': { borderColor: '#e2e8f0', borderWidth: 1 },
|
||||||
'&:hover fieldset': { borderColor: '#cbd5e1' },
|
'&:hover fieldset': { borderColor: '#cbd5e1' },
|
||||||
'&.Mui-focused': { boxShadow: `0 0 0 3px ${dtRing('#662582')}` },
|
'&.Mui-focused': { boxShadow: `0 0 0 3px ${dtRing('#C01227')}` },
|
||||||
'&.Mui-focused fieldset': { borderColor: '#662582', borderWidth: 1.5 }
|
'&.Mui-focused fieldset': { borderColor: '#C01227', borderWidth: 1.5 }
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -967,7 +967,7 @@ const Orders = () => {
|
|||||||
{/* ============================================= || KPI Cards || ============================================= */}
|
{/* ============================================= || KPI Cards || ============================================= */}
|
||||||
<Grid container spacing={{ xs: 2, md: 2.5 }} sx={{ mb: { xs: 1.5, md: 2 } }}>
|
<Grid container spacing={{ xs: 2, md: 2.5 }} sx={{ mb: { xs: 1.5, md: 2 } }}>
|
||||||
{[
|
{[
|
||||||
{ key: 'created', label: 'Created Orders', color: '#662582', icon: MdOutlineReceiptLong, value: percentageData?.created, percentage: percentageData?.percentage1 },
|
{ key: 'created', label: 'Created Orders', color: '#C01227', icon: MdOutlineReceiptLong, value: percentageData?.created, percentage: percentageData?.percentage1 },
|
||||||
{ key: 'pending', label: 'Pending Orders', color: '#f59e0b', icon: MdOutlinePendingActions, value: percentageData?.uncoveredOrders, percentage: percentageData?.percentage2 },
|
{ key: 'pending', label: 'Pending Orders', color: '#f59e0b', icon: MdOutlinePendingActions, value: percentageData?.uncoveredOrders, percentage: percentageData?.percentage2 },
|
||||||
{ key: 'delivered', label: 'Delivered Orders', color: '#10b981', icon: MdOutlineCheckCircle, value: percentageData?.coveredOrders, percentage: percentageData?.percentage3 },
|
{ key: 'delivered', label: 'Delivered Orders', color: '#10b981', icon: MdOutlineCheckCircle, value: percentageData?.coveredOrders, percentage: percentageData?.percentage3 },
|
||||||
{ key: 'cancelled', label: 'Cancelled Orders', color: '#ef4444', icon: MdOutlineCancel, value: percentageData?.cancelled, percentage: percentageData?.percentage4 }
|
{ key: 'cancelled', label: 'Cancelled Orders', color: '#ef4444', icon: MdOutlineCancel, value: percentageData?.cancelled, percentage: percentageData?.percentage4 }
|
||||||
@@ -1279,7 +1279,7 @@ const Orders = () => {
|
|||||||
bgcolor: dtTint(BRAND),
|
bgcolor: dtTint(BRAND),
|
||||||
'& fieldset': { borderColor: dtEdge(BRAND), borderWidth: 1.5 },
|
'& fieldset': { borderColor: dtEdge(BRAND), borderWidth: 1.5 },
|
||||||
'&:hover fieldset': { borderColor: '#cbd5e1' },
|
'&:hover fieldset': { borderColor: '#cbd5e1' },
|
||||||
'&.Mui-focused fieldset': { borderColor: '#662582', borderWidth: 1.5 },
|
'&.Mui-focused fieldset': { borderColor: '#C01227', borderWidth: 1.5 },
|
||||||
'&.Mui-focused': { boxShadow: `0 0 0 3px ${dtRing(BRAND)}` }
|
'&.Mui-focused': { boxShadow: `0 0 0 3px ${dtRing(BRAND)}` }
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ export default function RidersRoutes({ details, loading, riderName, dateRange, o
|
|||||||
// brand purple to match the planned-route polyline below.
|
// brand purple to match the planned-route polyline below.
|
||||||
const stepIcon = (n, isFocused) => {
|
const stepIcon = (n, isFocused) => {
|
||||||
const size = isFocused ? 38 : 32;
|
const size = isFocused ? 38 : 32;
|
||||||
const color = isFocused ? '#4D1C61' : '#662582';
|
const color = isFocused ? '#900E1D' : '#C01227';
|
||||||
const svg = encodeURIComponent(
|
const svg = encodeURIComponent(
|
||||||
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="${size}" height="${size}">` +
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="${size}" height="${size}">` +
|
||||||
`<circle cx="16" cy="16" r="14" fill="${color}" stroke="white" stroke-width="3"/>` +
|
`<circle cx="16" cy="16" r="14" fill="${color}" stroke="white" stroke-width="3"/>` +
|
||||||
@@ -126,7 +126,7 @@ export default function RidersRoutes({ details, loading, riderName, dateRange, o
|
|||||||
px: 2,
|
px: 2,
|
||||||
py: 1.25,
|
py: 1.25,
|
||||||
borderBottom: '1px solid rgba(15, 23, 42, 0.08)',
|
borderBottom: '1px solid rgba(15, 23, 42, 0.08)',
|
||||||
background: 'linear-gradient(135deg, #662582 0%, #9255AB 100%)',
|
background: 'linear-gradient(135deg, #C01227 0%, #D35968 100%)',
|
||||||
color: '#fff',
|
color: '#fff',
|
||||||
flexShrink: 0
|
flexShrink: 0
|
||||||
}}
|
}}
|
||||||
@@ -207,12 +207,12 @@ export default function RidersRoutes({ details, loading, riderName, dateRange, o
|
|||||||
{/* Translucent backdrop so the route stays legible on busy tiles. */}
|
{/* Translucent backdrop so the route stays legible on busy tiles. */}
|
||||||
<Polyline
|
<Polyline
|
||||||
path={routePath}
|
path={routePath}
|
||||||
options={{ strokeColor: '#662582', strokeOpacity: 0.25, strokeWeight: 8 }}
|
options={{ strokeColor: '#C01227', strokeOpacity: 0.25, strokeWeight: 8 }}
|
||||||
/>
|
/>
|
||||||
{/* Road-following planned route from the Directions API. */}
|
{/* Road-following planned route from the Directions API. */}
|
||||||
<Polyline
|
<Polyline
|
||||||
path={routePath}
|
path={routePath}
|
||||||
options={{ strokeColor: '#662582', strokeOpacity: 0.95, strokeWeight: 4 }}
|
options={{ strokeColor: '#C01227', strokeOpacity: 0.95, strokeWeight: 4 }}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
@@ -221,7 +221,7 @@ export default function RidersRoutes({ details, loading, riderName, dateRange, o
|
|||||||
<Polyline
|
<Polyline
|
||||||
path={dropPath}
|
path={dropPath}
|
||||||
options={{
|
options={{
|
||||||
strokeColor: '#662582',
|
strokeColor: '#C01227',
|
||||||
strokeOpacity: 0,
|
strokeOpacity: 0,
|
||||||
strokeWeight: 0,
|
strokeWeight: 0,
|
||||||
icons: [
|
icons: [
|
||||||
@@ -229,7 +229,7 @@ export default function RidersRoutes({ details, loading, riderName, dateRange, o
|
|||||||
icon: {
|
icon: {
|
||||||
path: 'M 0,-1 0,1',
|
path: 'M 0,-1 0,1',
|
||||||
strokeOpacity: 0.6,
|
strokeOpacity: 0.6,
|
||||||
strokeColor: '#662582',
|
strokeColor: '#C01227',
|
||||||
scale: 3
|
scale: 3
|
||||||
},
|
},
|
||||||
offset: '0',
|
offset: '0',
|
||||||
|
|||||||
@@ -114,8 +114,8 @@ const soft = (c) => a(c, '18');
|
|||||||
const ring = (c) => a(c, '26');
|
const ring = (c) => a(c, '26');
|
||||||
const edge = (c) => a(c, '55');
|
const edge = (c) => a(c, '55');
|
||||||
|
|
||||||
const BRAND = '#662582';
|
const BRAND = '#C01227';
|
||||||
const BRAND_LIGHT = '#9255AB';
|
const BRAND_LIGHT = '#D35968';
|
||||||
|
|
||||||
const SoftPaper = (props) => (
|
const SoftPaper = (props) => (
|
||||||
<Paper
|
<Paper
|
||||||
@@ -153,7 +153,7 @@ const pillFieldSx = (color) => ({
|
|||||||
'& fieldset': { borderColor: '#e2e8f0', borderWidth: 1 },
|
'& fieldset': { borderColor: '#e2e8f0', borderWidth: 1 },
|
||||||
'&:hover fieldset': { borderColor: '#cbd5e1' },
|
'&:hover fieldset': { borderColor: '#cbd5e1' },
|
||||||
'&.Mui-focused': { boxShadow: `0 0 0 3px ${ring(color)}` },
|
'&.Mui-focused': { boxShadow: `0 0 0 3px ${ring(color)}` },
|
||||||
'&.Mui-focused fieldset': { borderColor: '#662582', borderWidth: 1.5 }
|
'&.Mui-focused fieldset': { borderColor: '#C01227', borderWidth: 1.5 }
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1172,7 +1172,7 @@ export default function OrdersDetails() {
|
|||||||
bgcolor: '#ffffff',
|
bgcolor: '#ffffff',
|
||||||
'& fieldset': { borderColor: '#e2e8f0', borderWidth: 1 },
|
'& fieldset': { borderColor: '#e2e8f0', borderWidth: 1 },
|
||||||
'&:hover fieldset': { borderColor: '#cbd5e1' },
|
'&:hover fieldset': { borderColor: '#cbd5e1' },
|
||||||
'&.Mui-focused fieldset': { borderColor: '#662582', borderWidth: 1.5 },
|
'&.Mui-focused fieldset': { borderColor: '#C01227', borderWidth: 1.5 },
|
||||||
'&.Mui-focused': { boxShadow: `0 0 0 3px ${ring(BRAND)}` }
|
'&.Mui-focused': { boxShadow: `0 0 0 3px ${ring(BRAND)}` }
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -87,8 +87,8 @@ const soft = (c) => a(c, '18');
|
|||||||
const ring = (c) => a(c, '26');
|
const ring = (c) => a(c, '26');
|
||||||
const edge = (c) => a(c, '55');
|
const edge = (c) => a(c, '55');
|
||||||
|
|
||||||
const BRAND = '#662582';
|
const BRAND = '#C01227';
|
||||||
const BRAND_LIGHT = '#9255AB';
|
const BRAND_LIGHT = '#D35968';
|
||||||
|
|
||||||
const SoftPaper = (props) => (
|
const SoftPaper = (props) => (
|
||||||
<Paper
|
<Paper
|
||||||
@@ -190,7 +190,7 @@ const pillFieldSx = (color) => ({
|
|||||||
'& fieldset': { borderColor: '#e2e8f0', borderWidth: 1 },
|
'& fieldset': { borderColor: '#e2e8f0', borderWidth: 1 },
|
||||||
'&:hover fieldset': { borderColor: '#cbd5e1' },
|
'&:hover fieldset': { borderColor: '#cbd5e1' },
|
||||||
'&.Mui-focused': { boxShadow: `0 0 0 3px ${ring(color)}` },
|
'&.Mui-focused': { boxShadow: `0 0 0 3px ${ring(color)}` },
|
||||||
'&.Mui-focused fieldset': { borderColor: '#662582', borderWidth: 1.5 }
|
'&.Mui-focused fieldset': { borderColor: '#C01227', borderWidth: 1.5 }
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -588,7 +588,7 @@ export default function OrdersReport() {
|
|||||||
bgcolor: '#ffffff',
|
bgcolor: '#ffffff',
|
||||||
'& fieldset': { borderColor: '#e2e8f0', borderWidth: 1 },
|
'& fieldset': { borderColor: '#e2e8f0', borderWidth: 1 },
|
||||||
'&:hover fieldset': { borderColor: '#cbd5e1' },
|
'&:hover fieldset': { borderColor: '#cbd5e1' },
|
||||||
'&.Mui-focused fieldset': { borderColor: '#662582', borderWidth: 1.5 },
|
'&.Mui-focused fieldset': { borderColor: '#C01227', borderWidth: 1.5 },
|
||||||
'&.Mui-focused': { boxShadow: `0 0 0 3px ${ring(BRAND)}` }
|
'&.Mui-focused': { boxShadow: `0 0 0 3px ${ring(BRAND)}` }
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ const tint = (c) => aColor(c, '08');
|
|||||||
const edge = (c) => aColor(c, '55');
|
const edge = (c) => aColor(c, '55');
|
||||||
const ring = (c) => aColor(c, '26');
|
const ring = (c) => aColor(c, '26');
|
||||||
|
|
||||||
const BRAND = '#662582';
|
const BRAND = '#C01227';
|
||||||
|
|
||||||
const SoftPaper = (props) => (
|
const SoftPaper = (props) => (
|
||||||
<Paper
|
<Paper
|
||||||
@@ -552,7 +552,7 @@ export default function ProfitabilityReport() {
|
|||||||
bgcolor: '#ffffff',
|
bgcolor: '#ffffff',
|
||||||
'& fieldset': { borderColor: '#e2e8f0', borderWidth: 1 },
|
'& fieldset': { borderColor: '#e2e8f0', borderWidth: 1 },
|
||||||
'&:hover fieldset': { borderColor: '#cbd5e1' },
|
'&:hover fieldset': { borderColor: '#cbd5e1' },
|
||||||
'&.Mui-focused fieldset': { borderColor: '#662582', borderWidth: 1.5 },
|
'&.Mui-focused fieldset': { borderColor: '#C01227', borderWidth: 1.5 },
|
||||||
'&.Mui-focused': { boxShadow: `0 0 0 3px ${ring(BRAND)}` }
|
'&.Mui-focused': { boxShadow: `0 0 0 3px ${ring(BRAND)}` }
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -86,8 +86,8 @@ const soft = (c) => a(c, '18');
|
|||||||
const ring = (c) => a(c, '26');
|
const ring = (c) => a(c, '26');
|
||||||
const edge = (c) => a(c, '55');
|
const edge = (c) => a(c, '55');
|
||||||
|
|
||||||
const BRAND = '#662582';
|
const BRAND = '#C01227';
|
||||||
const BRAND_LIGHT = '#9255AB';
|
const BRAND_LIGHT = '#D35968';
|
||||||
|
|
||||||
const SoftPaper = (props) => (
|
const SoftPaper = (props) => (
|
||||||
<Paper
|
<Paper
|
||||||
@@ -456,7 +456,7 @@ export default function RidersSummary() {
|
|||||||
bgcolor: '#ffffff',
|
bgcolor: '#ffffff',
|
||||||
'& fieldset': { borderColor: '#e2e8f0', borderWidth: 1 },
|
'& fieldset': { borderColor: '#e2e8f0', borderWidth: 1 },
|
||||||
'&:hover fieldset': { borderColor: '#cbd5e1' },
|
'&:hover fieldset': { borderColor: '#cbd5e1' },
|
||||||
'&.Mui-focused fieldset': { borderColor: '#662582', borderWidth: 1.5 },
|
'&.Mui-focused fieldset': { borderColor: '#C01227', borderWidth: 1.5 },
|
||||||
'&.Mui-focused': { boxShadow: `0 0 0 3px ${ring(BRAND)}` }
|
'&.Mui-focused': { boxShadow: `0 0 0 3px ${ring(BRAND)}` }
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -902,7 +902,7 @@ const Requests = () => {
|
|||||||
<MobileCardList scroll>
|
<MobileCardList scroll>
|
||||||
{loading &&
|
{loading &&
|
||||||
[0, 1, 2, 3, 4].map((item) => (
|
[0, 1, 2, 3, 4].map((item) => (
|
||||||
<MobileCard key={item} accent="#662582">
|
<MobileCard key={item} accent="#C01227">
|
||||||
<Stack direction="row" alignItems="center" spacing={1}>
|
<Stack direction="row" alignItems="center" spacing={1}>
|
||||||
<Skeleton variant="circular" width={32} height={32} />
|
<Skeleton variant="circular" width={32} height={32} />
|
||||||
<Stack sx={{ flex: 1 }}>
|
<Stack sx={{ flex: 1 }}>
|
||||||
@@ -923,13 +923,13 @@ const Requests = () => {
|
|||||||
return (
|
return (
|
||||||
<MobileCard
|
<MobileCard
|
||||||
key={row.sno}
|
key={row.sno}
|
||||||
accent="#662582"
|
accent="#C01227"
|
||||||
selected={isItemSelected}
|
selected={isItemSelected}
|
||||||
onClick={(event) => handleClick(event, row.sno)}
|
onClick={(event) => handleClick(event, row.sno)}
|
||||||
header={
|
header={
|
||||||
<Stack direction="row" alignItems="center" justifyContent="space-between" spacing={1}>
|
<Stack direction="row" alignItems="center" justifyContent="space-between" spacing={1}>
|
||||||
<Stack direction="row" alignItems="center" spacing={1} sx={{ minWidth: 0 }}>
|
<Stack direction="row" alignItems="center" spacing={1} sx={{ minWidth: 0 }}>
|
||||||
<Avatar sx={{ width: 32, height: 32, bgcolor: '#66258218', color: '#662582', fontSize: 13 }}>
|
<Avatar sx={{ width: 32, height: 32, bgcolor: '#C0122718', color: '#C01227', fontSize: 13 }}>
|
||||||
{row.requestor ? String(row.requestor).charAt(0).toUpperCase() : '#'}
|
{row.requestor ? String(row.requestor).charAt(0).toUpperCase() : '#'}
|
||||||
</Avatar>
|
</Avatar>
|
||||||
<Stack sx={{ minWidth: 0 }}>
|
<Stack sx={{ minWidth: 0 }}>
|
||||||
@@ -942,7 +942,7 @@ const Requests = () => {
|
|||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
{row.amount != null && (
|
{row.amount != null && (
|
||||||
<Chip label={row.amount} size="small" sx={{ bgcolor: '#66258218', color: '#662582', fontWeight: 700 }} />
|
<Chip label={row.amount} size="small" sx={{ bgcolor: '#C0122718', color: '#C01227', fontWeight: 700 }} />
|
||||||
)}
|
)}
|
||||||
</Stack>
|
</Stack>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -269,7 +269,7 @@ export default function RiderSubstitution({
|
|||||||
bgcolor: BRAND,
|
bgcolor: BRAND,
|
||||||
color: '#fff',
|
color: '#fff',
|
||||||
'&:hover': {
|
'&:hover': {
|
||||||
bgcolor: '#4D1C61'
|
bgcolor: '#900E1D'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -657,7 +657,7 @@ export default function RiderSubstitution({
|
|||||||
fontWeight: 700,
|
fontWeight: 700,
|
||||||
textTransform: 'none',
|
textTransform: 'none',
|
||||||
'&:hover': {
|
'&:hover': {
|
||||||
bgcolor: '#4D1C61'
|
bgcolor: '#900E1D'
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ import RiderSubstitution from './RiderSubstitution';
|
|||||||
// ============================================================================
|
// ============================================================================
|
||||||
// Design tokens — shared with the deliveries / tenants / customers pages so
|
// Design tokens — shared with the deliveries / tenants / customers pages so
|
||||||
// every surface (header, KPI tiles, table, badges, dialog) speaks the same
|
// every surface (header, KPI tiles, table, badges, dialog) speaks the same
|
||||||
// visual language. Brand purple `#662582` is the canonical primary; status
|
// visual language. Brand purple `#C01227` is the canonical primary; status
|
||||||
// colours are semantic and distinct from the brand.
|
// colours are semantic and distinct from the brand.
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
const DT = {
|
const DT = {
|
||||||
@@ -100,7 +100,7 @@ const soft = (c) => a(c, '18');
|
|||||||
const ring = (c) => a(c, '26');
|
const ring = (c) => a(c, '26');
|
||||||
const edge = (c) => a(c, '55');
|
const edge = (c) => a(c, '55');
|
||||||
|
|
||||||
const BRAND = '#662582';
|
const BRAND = '#C01227';
|
||||||
|
|
||||||
const SoftPaper = (props) => (
|
const SoftPaper = (props) => (
|
||||||
<Paper
|
<Paper
|
||||||
@@ -763,7 +763,7 @@ const Riders = () => {
|
|||||||
bgcolor: '#ffffff',
|
bgcolor: '#ffffff',
|
||||||
'& fieldset': { borderColor: '#e2e8f0', borderWidth: 1 },
|
'& fieldset': { borderColor: '#e2e8f0', borderWidth: 1 },
|
||||||
'&:hover fieldset': { borderColor: '#cbd5e1' },
|
'&:hover fieldset': { borderColor: '#cbd5e1' },
|
||||||
'&.Mui-focused fieldset': { borderColor: '#662582', borderWidth: 1.5 },
|
'&.Mui-focused fieldset': { borderColor: '#C01227', borderWidth: 1.5 },
|
||||||
'&.Mui-focused': { boxShadow: `0 0 0 3px ${ring(BRAND)}` }
|
'&.Mui-focused': { boxShadow: `0 0 0 3px ${ring(BRAND)}` }
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@@ -813,7 +813,7 @@ const Riders = () => {
|
|||||||
bgcolor: BRAND,
|
bgcolor: BRAND,
|
||||||
color: '#fff',
|
color: '#fff',
|
||||||
'&:hover': {
|
'&:hover': {
|
||||||
bgcolor: '#4D1C61'
|
bgcolor: '#900E1D'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1914,7 +1914,7 @@ const Riders = () => {
|
|||||||
fontWeight: 600,
|
fontWeight: 600,
|
||||||
bgcolor: BRAND,
|
bgcolor: BRAND,
|
||||||
color: '#fff',
|
color: '#fff',
|
||||||
'&:hover': { bgcolor: '#4D1C61' }
|
'&:hover': { bgcolor: '#900E1D' }
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Save Changes
|
Save Changes
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ const DT = {
|
|||||||
surface: '#ffffff',
|
surface: '#ffffff',
|
||||||
surfaceAlt: '#f8fafc'
|
surfaceAlt: '#f8fafc'
|
||||||
};
|
};
|
||||||
const BRAND = '#662582';
|
const BRAND = '#C01227';
|
||||||
const BRAND_LIGHT = '#9255AB';
|
const BRAND_LIGHT = '#D35968';
|
||||||
const tint = (c) => `${c}08`;
|
const tint = (c) => `${c}08`;
|
||||||
const soft = (c) => `${c}18`;
|
const soft = (c) => `${c}18`;
|
||||||
|
|
||||||
@@ -143,7 +143,7 @@ const ViewProfile = () => {
|
|||||||
color: '#fff',
|
color: '#fff',
|
||||||
fontSize: { xs: 24, md: 28 },
|
fontSize: { xs: 24, md: 28 },
|
||||||
fontWeight: 700,
|
fontWeight: 700,
|
||||||
boxShadow: '0 10px 24px rgba(102, 37, 130, 0.35)'
|
boxShadow: '0 10px 24px rgba(192, 18, 39, 0.35)'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{initialsOf(fullname)}
|
{initialsOf(fullname)}
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { useTheme } from '@mui/material/styles';
|
|
||||||
import { CardActions, Grid, Stack, Typography } from '@mui/material';
|
|
||||||
|
|
||||||
const TitleCard = ({ title, secondary, sx }) => {
|
|
||||||
const theme = useTheme();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<CardActions
|
|
||||||
sx={{
|
|
||||||
position: 'sticky',
|
|
||||||
top: '30px',
|
|
||||||
bgcolor: theme.palette.background.default,
|
|
||||||
zIndex: 10,
|
|
||||||
width: '100%',
|
|
||||||
...sx
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Grid container>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Stack direction="row" justifyContent="space-between" alignItems="center" gap={2} sx={{ flexWrap: 'wrap' }}>
|
|
||||||
<Typography variant="h3">{title}</Typography>
|
|
||||||
{secondary}
|
|
||||||
</Stack>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</CardActions>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default TitleCard;
|
|
||||||
@@ -121,7 +121,7 @@ export default function ThemeCustomization({ children }) {
|
|||||||
// soft slate that tints toward brand purple on hover.
|
// soft slate that tints toward brand purple on hover.
|
||||||
'*': {
|
'*': {
|
||||||
scrollbarWidth: 'thin', // Firefox
|
scrollbarWidth: 'thin', // Firefox
|
||||||
scrollbarColor: 'rgba(102, 37, 130, 0.28) transparent'
|
scrollbarColor: 'rgba(192, 18, 39, 0.28) transparent'
|
||||||
},
|
},
|
||||||
'*::-webkit-scrollbar': {
|
'*::-webkit-scrollbar': {
|
||||||
width: '10px',
|
width: '10px',
|
||||||
@@ -131,13 +131,13 @@ export default function ThemeCustomization({ children }) {
|
|||||||
backgroundColor: 'transparent'
|
backgroundColor: 'transparent'
|
||||||
},
|
},
|
||||||
'*::-webkit-scrollbar-thumb': {
|
'*::-webkit-scrollbar-thumb': {
|
||||||
backgroundColor: 'rgba(102, 37, 130, 0.26)',
|
backgroundColor: 'rgba(192, 18, 39, 0.26)',
|
||||||
borderRadius: '8px',
|
borderRadius: '8px',
|
||||||
border: '2px solid transparent',
|
border: '2px solid transparent',
|
||||||
backgroundClip: 'padding-box'
|
backgroundClip: 'padding-box'
|
||||||
},
|
},
|
||||||
'*::-webkit-scrollbar-thumb:hover': {
|
'*::-webkit-scrollbar-thumb:hover': {
|
||||||
backgroundColor: 'rgba(102, 37, 130, 0.45)'
|
backgroundColor: 'rgba(192, 18, 39, 0.45)'
|
||||||
},
|
},
|
||||||
'*::-webkit-scrollbar-corner': {
|
'*::-webkit-scrollbar-corner': {
|
||||||
backgroundColor: 'transparent'
|
backgroundColor: 'transparent'
|
||||||
|
|||||||
@@ -23,10 +23,10 @@ export default function Autocomplete() {
|
|||||||
borderRadius: 8,
|
borderRadius: 8,
|
||||||
margin: '1px 0',
|
margin: '1px 0',
|
||||||
'&[aria-selected="true"]': {
|
'&[aria-selected="true"]': {
|
||||||
backgroundColor: 'rgba(102, 37, 130, 0.08)'
|
backgroundColor: 'rgba(192, 18, 39, 0.08)'
|
||||||
},
|
},
|
||||||
'&.Mui-focused': {
|
'&.Mui-focused': {
|
||||||
backgroundColor: 'rgba(102, 37, 130, 0.06)'
|
backgroundColor: 'rgba(192, 18, 39, 0.06)'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -40,16 +40,16 @@ const Default = (colors) => {
|
|||||||
// contrastText
|
// contrastText
|
||||||
// },
|
// },
|
||||||
primary: {
|
primary: {
|
||||||
lighter: '#E8D9EF',
|
lighter: '#F6DBDF',
|
||||||
100: '#CBA7DA',
|
100: '#E9ACB3',
|
||||||
200: '#AE76C4',
|
200: '#DD7F8A',
|
||||||
light: '#9255AB',
|
light: '#D35968',
|
||||||
400: '#9255AB',
|
400: '#D35968',
|
||||||
main: '#662582',
|
main: '#C01227',
|
||||||
dark: '#4D1C61',
|
dark: '#900E1D',
|
||||||
700: '#3A1549',
|
700: '#6D0A16',
|
||||||
darker: '#260E30',
|
darker: '#47070E',
|
||||||
900: '#17081D',
|
900: '#2A0409',
|
||||||
contrastText: '#FFFFFF'
|
contrastText: '#FFFFFF'
|
||||||
},
|
},
|
||||||
secondary: {
|
secondary: {
|
||||||
|
|||||||
@@ -18,5 +18,6 @@
|
|||||||
"riderslogs": "Riders Logs",
|
"riderslogs": "Riders Logs",
|
||||||
"invoice": "Invoice",
|
"invoice": "Invoice",
|
||||||
"dispatch": "Dispatch",
|
"dispatch": "Dispatch",
|
||||||
"profitability": "Profitability"
|
"profitability": "Profitability",
|
||||||
|
"Doormile": "Doormile"
|
||||||
}
|
}
|
||||||
|
|||||||