feat: add lucide-vue-next and plantuml-encoder dependencies, update documentation structure for TrackGo
- Added `lucide-vue-next` and `plantuml-encoder` as dependencies in the project for enhanced icon usage and diagram support. - Updated the documentation to reflect the new structure, including user guides for TrackGo, emphasizing the separation of web and mobile functionalities. - Revised the main index and user documentation to provide clearer navigation and improved user experience. - Introduced new mobile documentation covering check-in and daily work processes, enhancing guidance for field users. These changes improve the overall functionality and usability of the TrackGo platform, ensuring a better experience for both web and mobile users.
This commit is contained in:
@@ -12,6 +12,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@repo/ui": "workspace:*",
|
"@repo/ui": "workspace:*",
|
||||||
"dayjs": "^1.11.19",
|
"dayjs": "^1.11.19",
|
||||||
|
"lucide-vue-next": "^1.0.0",
|
||||||
"react": "^19.2.3",
|
"react": "^19.2.3",
|
||||||
"react-dom": "^19.2.3"
|
"react-dom": "^19.2.3"
|
||||||
},
|
},
|
||||||
@@ -20,6 +21,7 @@
|
|||||||
"@repo/typescript-config": "workspace:*",
|
"@repo/typescript-config": "workspace:*",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^8.57.0",
|
||||||
"mermaid": "^11.15.0",
|
"mermaid": "^11.15.0",
|
||||||
|
"plantuml-encoder": "^1.4.0",
|
||||||
"typescript": "5.5.4",
|
"typescript": "5.5.4",
|
||||||
"vitepress": "^1.6.4",
|
"vitepress": "^1.6.4",
|
||||||
"vitepress-plugin-mermaid": "^2.0.17",
|
"vitepress-plugin-mermaid": "^2.0.17",
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
import { defineConfig } from 'vitepress';
|
import { defineConfig } from 'vitepress';
|
||||||
import { withMermaid } from 'vitepress-plugin-mermaid';
|
import { withMermaid } from 'vitepress-plugin-mermaid';
|
||||||
|
import { plantumlPlugin } from './plantuml';
|
||||||
|
|
||||||
const config = withMermaid(
|
const config = withMermaid(
|
||||||
defineConfig({
|
defineConfig({
|
||||||
// title: "Frontend Monorepo",
|
title: 'TrackGo',
|
||||||
title: 'Frontend Arch',
|
description: 'User guides for TrackGo web and mobile',
|
||||||
description: 'Centralized documentation for the Enterprise Frontend Monorepo',
|
head: [['link', { rel: 'icon', href: '/favicon.svg' }]],
|
||||||
head: [
|
markdown: {
|
||||||
['link', { rel: 'icon', href: '/favicon.svg' }], // Jika Anda menggunakan favicon.svg
|
config(md) {
|
||||||
],
|
plantumlPlugin(md);
|
||||||
|
},
|
||||||
|
},
|
||||||
themeConfig: {
|
themeConfig: {
|
||||||
search: {
|
search: {
|
||||||
provider: 'local',
|
provider: 'local',
|
||||||
@@ -17,58 +20,57 @@ const config = withMermaid(
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
logo: '/logo.svg',
|
logo: '/logo.svg',
|
||||||
nav: [{ text: 'Docs', link: '/overview' }],
|
nav: [
|
||||||
|
{ text: 'User guides', link: '/user/' },
|
||||||
|
{ text: 'Web', link: '/user/web/' },
|
||||||
|
{ text: 'Mobile', link: '/user/mobile/' },
|
||||||
|
],
|
||||||
|
|
||||||
sidebar: [
|
sidebar: [
|
||||||
{
|
{
|
||||||
text: 'Getting Started',
|
text: 'User guides',
|
||||||
|
items: [{ text: 'What is TrackGo', link: '/user/' }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'Web',
|
||||||
|
collapsed: false,
|
||||||
|
items: [
|
||||||
|
{ text: 'Overview', link: '/user/web/' },
|
||||||
|
{ text: 'Set up your company', link: '/user/web/setup' },
|
||||||
|
{ text: 'Plans and visits', link: '/user/web/plans' },
|
||||||
|
{ text: 'Sales workflow', link: '/user/web/sales-workflow' },
|
||||||
|
{ text: 'Logistics', link: '/user/web/logistics' },
|
||||||
|
{ text: 'Timeline', link: '/user/web/timeline' },
|
||||||
|
{ text: 'Import CSV', link: '/user/web/import' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'Mobile',
|
||||||
|
collapsed: false,
|
||||||
|
items: [
|
||||||
|
{ text: 'Overview', link: '/user/mobile/' },
|
||||||
|
{ text: 'Check in', link: '/user/mobile/check-in' },
|
||||||
|
{ text: 'Daily work', link: '/user/mobile/daily-work' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'Developer reference',
|
||||||
|
collapsed: true,
|
||||||
items: [
|
items: [
|
||||||
{ text: 'Project Overview', link: '/overview' },
|
{ text: 'Project Overview', link: '/overview' },
|
||||||
{ text: 'Development Setup', link: '/setup' },
|
{ text: 'Development Setup', link: '/setup' },
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Core Architecture',
|
|
||||||
collapsed: false,
|
|
||||||
items: [
|
|
||||||
// { text: 'API & Domain Logic', link: '/packages/core-api/' },
|
|
||||||
{
|
|
||||||
text: 'API & Domain Logic',
|
|
||||||
collapsed: false,
|
|
||||||
items: [
|
|
||||||
{ text: 'API Engine', link: '/packages/core-api' },
|
{ text: 'API Engine', link: '/packages/core-api' },
|
||||||
{ text: 'Data Transformers', link: '/packages/core-api/transformers' },
|
{ text: 'Data Transformers', link: '/packages/core-api/transformers' },
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
{ text: 'Event Bus System', link: '/packages/core-events/' },
|
{ text: 'Event Bus System', link: '/packages/core-events/' },
|
||||||
{ text: 'Storage & Persistence', link: '/packages/core-storage/' },
|
{ text: 'Storage & Persistence', link: '/packages/core-storage/' },
|
||||||
{ text: 'I18n & Localization', link: '/packages/core-i18n/' },
|
{ text: 'I18n & Localization', link: '/packages/core-i18n/' },
|
||||||
],
|
{ text: 'UI Overview', link: '/packages/ui/' },
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'UI System',
|
|
||||||
collapsed: false,
|
|
||||||
items: [
|
|
||||||
{ text: 'Overview', link: '/packages/ui/' },
|
|
||||||
{ text: 'App Layout', link: '/packages/ui/CORE-APP-SHELL' },
|
{ text: 'App Layout', link: '/packages/ui/CORE-APP-SHELL' },
|
||||||
{ text: 'Action Tools', link: '/packages/ui/ACTION-TOOLS' },
|
{ text: 'Action Tools', link: '/packages/ui/ACTION-TOOLS' },
|
||||||
{ text: 'Form Primitives', link: '/packages/ui/FORM-COMPONENTS' },
|
{ text: 'Form Primitives', link: '/packages/ui/FORM-COMPONENTS' },
|
||||||
],
|
{ text: 'Web Overview', link: '/apps/web/' },
|
||||||
},
|
{ text: 'Sales Workflow (legacy)', link: '/apps/web/SALES_WORKFLOW' },
|
||||||
{
|
{ text: 'Desktop Overview', link: '/apps/desktop/' },
|
||||||
text: 'TrackGo Web',
|
|
||||||
collapsed: false,
|
|
||||||
items: [
|
|
||||||
{ text: 'Overview', link: '/apps/web/' },
|
|
||||||
{ text: 'Sales Workflow', link: '/apps/web/SALES_WORKFLOW' },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Desktop Ecosystem',
|
|
||||||
collapsed: false,
|
|
||||||
items: [
|
|
||||||
{ text: 'Overview', link: '/apps/desktop/' },
|
|
||||||
{ text: 'Lifecycle & Configuration', link: '/apps/desktop/CONFIGURATION' },
|
{ text: 'Lifecycle & Configuration', link: '/apps/desktop/CONFIGURATION' },
|
||||||
{ text: 'IPC & Bridge Architecture', link: '/apps/desktop/IPC_ARCHITECTURE' },
|
{ text: 'IPC & Bridge Architecture', link: '/apps/desktop/IPC_ARCHITECTURE' },
|
||||||
{ text: 'Distribution & Auto-Update', link: '/apps/desktop/AUTO_UPDATER' },
|
{ text: 'Distribution & Auto-Update', link: '/apps/desktop/AUTO_UPDATER' },
|
||||||
@@ -87,25 +89,21 @@ const config = withMermaid(
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
// Mermaid configuration
|
|
||||||
mermaid: {
|
mermaid: {
|
||||||
theme: 'default',
|
theme: 'default',
|
||||||
},
|
},
|
||||||
|
|
||||||
// Fix cascading CJS/ESM SyntaxErrors caused by Vite dynamically discovering mermaid
|
|
||||||
vite: {
|
vite: {
|
||||||
|
ssr: {
|
||||||
|
noExternal: ['lucide-vue-next'],
|
||||||
|
},
|
||||||
optimizeDeps: {
|
optimizeDeps: {
|
||||||
include: ['mermaid'],
|
include: ['mermaid', 'lucide-vue-next'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Pnpm strict workspace workaround:
|
|
||||||
// vitepress-plugin-mermaid aggressively injects sub-dependencies into optimizeDeps.include.
|
|
||||||
// Because pnpm uses strict symlinks, Vite fails to resolve these sub-dependencies from the project root,
|
|
||||||
// causing pre-bundling to fail and cascading CJS/ESM SyntaxErrors in the browser.
|
|
||||||
// We strip them out so esbuild can naturally inline them into the 'mermaid' chunk instead.
|
|
||||||
if (config.vite?.optimizeDeps?.include) {
|
if (config.vite?.optimizeDeps?.include) {
|
||||||
config.vite.optimizeDeps.include = config.vite.optimizeDeps.include.filter(
|
config.vite.optimizeDeps.include = config.vite.optimizeDeps.include.filter(
|
||||||
(dep) => !['@braintree/sanitize-url', 'debug', 'cytoscape-cose-bilkent', 'cytoscape'].includes(dep),
|
(dep) => !['@braintree/sanitize-url', 'debug', 'cytoscape-cose-bilkent', 'cytoscape'].includes(dep),
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
declare module 'plantuml-encoder' {
|
||||||
|
export function encode(source: string): string;
|
||||||
|
export function decode(encoded: string): string;
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { createRequire } from 'node:module';
|
||||||
|
import type MarkdownIt from 'markdown-it';
|
||||||
|
|
||||||
|
const require = createRequire(import.meta.url);
|
||||||
|
const plantumlEncoder = require('plantuml-encoder') as {
|
||||||
|
encode: (source: string) => string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function plantumlPlugin(md: MarkdownIt): void {
|
||||||
|
const defaultFence = md.renderer.rules.fence;
|
||||||
|
if (!defaultFence) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
md.renderer.rules.fence = (tokens, idx, options, env, slf) => {
|
||||||
|
const token = tokens[idx];
|
||||||
|
const info = token.info.trim().split(/\s+/)[0];
|
||||||
|
if (info === 'plantuml') {
|
||||||
|
const encoded = plantumlEncoder.encode(token.content);
|
||||||
|
const src = `https://www.plantuml.com/plantuml/svg/${encoded}`;
|
||||||
|
return `<div class="plantuml-diagram"><img src="${src}" alt="diagram" /></div>\n`;
|
||||||
|
}
|
||||||
|
return defaultFence(tokens, idx, options, env, slf);
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -114,3 +114,34 @@
|
|||||||
flex-grow: 0;
|
flex-grow: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.doc-lead {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
color: var(--vp-c-text-2);
|
||||||
|
margin-top: -0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doc-icon {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: -0.2em;
|
||||||
|
color: var(--vp-c-brand-1);
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.plantuml-diagram {
|
||||||
|
background: #ffffff;
|
||||||
|
border: 1px solid var(--vp-c-divider);
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 12px;
|
||||||
|
margin: 16px 0;
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.plantuml-diagram img {
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
display: block;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
@@ -1,188 +1,3 @@
|
|||||||
# Sales Workflow
|
# Sales Workflow
|
||||||
|
|
||||||
How to run a sale in TrackGo: from a request or order, through packing and invoicing, to payment.
|
This guide moved to [Sales workflow](/user/web/sales-workflow).
|
||||||
|
|
||||||
You need permission to view each menu. Status buttons (Process, Complete, Submit, Approve, and so on) appear only if you are allowed to edit.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Before you start
|
|
||||||
|
|
||||||
Set up the records that every sales document needs:
|
|
||||||
|
|
||||||
| You need | Where to create it |
|
|
||||||
| ----------------------------------- | ---------------------------- |
|
|
||||||
| Division, branch, customer, product | **Settings → Data** |
|
|
||||||
| Salesperson | **Sales → Data → Employees** |
|
|
||||||
|
|
||||||
If a menu is missing, ask an administrator to give your privilege **View** (and **Update** for status buttons) on that area.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## The usual flow
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
flowchart LR
|
|
||||||
subgraph sales [Sales]
|
|
||||||
R[Sales Request]
|
|
||||||
O[Sales Order]
|
|
||||||
P[Process]
|
|
||||||
I[Sales Invoice]
|
|
||||||
PAY[Sales Payment]
|
|
||||||
end
|
|
||||||
subgraph logistics [Logistics]
|
|
||||||
PS[Packing Slip]
|
|
||||||
C[Complete]
|
|
||||||
end
|
|
||||||
R -.->|optional| O
|
|
||||||
O --> P
|
|
||||||
P --> I
|
|
||||||
P -->|unless you skip it| PS
|
|
||||||
PS --> C
|
|
||||||
I --> PAY
|
|
||||||
```
|
|
||||||
|
|
||||||
1. Optionally create and approve a **sales request**.
|
|
||||||
2. Create a **sales order** (from the request, or from scratch).
|
|
||||||
3. Open the draft order and click **Process**. Leave **Generate packing slip** checked unless you do not need delivery paperwork. Processing creates a **sales invoice**, and a **packing slip** unless you skip it.
|
|
||||||
4. If there is a packing slip, open **Logistics → Packing slips**, then **Complete** and enter how much was delivered.
|
|
||||||
5. Open the invoice and click **Create Sales Payment**. **Submit** the payment, then **Approve** it (or **Reject** / **Rollback**).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Sales request
|
|
||||||
|
|
||||||
**Menu:** Sales → Activities → Sales Requests
|
|
||||||
|
|
||||||
A request is optional. You can go straight to a sales order.
|
|
||||||
|
|
||||||
1. Click **Create**. Fill in date, salesperson, branch, division, customer, address, and at least one product with a quantity. Product price and document code are optional. Save.
|
|
||||||
2. While the status is **Draft**, click **Submit** to send it for approval. You can also use **Change status** to mark it **Rejected**.
|
|
||||||
3. While it is **Pending**, click **Approve** or **Reject**. **Change status** can send it back to **Draft**.
|
|
||||||
4. After it is **Approved**, there is nothing more to do on the request itself.
|
|
||||||
5. On the request detail page, click **Create Sales Order**. The order form opens with the request’s customer, location, and products already filled in.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Sales order
|
|
||||||
|
|
||||||
**Menu:** Sales → Activities → Sales Orders
|
|
||||||
|
|
||||||
1. Click **Create**. Fill in the same kind of details as a request. On a new order you can pick a sales request under **Source**; that copies the request into the form. Save. A new order starts as **Draft**.
|
|
||||||
2. On a **Draft** order, click **Process**.
|
|
||||||
- You will see: _Processing creates a sales invoice and, unless skipped, a packing slip._
|
|
||||||
- **Generate packing slip** is checked by default. Uncheck it if you do not want a packing slip.
|
|
||||||
3. On **Draft** or **Processed**, you can **Cancel**. There is no **Complete** button on orders. If the order later shows **Completed**, that was not something you clicked on this screen.
|
|
||||||
4. On the order detail page you can see linked packing slips and invoices, and click **Create Sales Invoice**.
|
|
||||||
|
|
||||||
You can select several orders and Process or Cancel them together, as long as they are all in a status that allows that action.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Packing slip
|
|
||||||
|
|
||||||
**Menu:** Logistics → Activities → Packing slips
|
|
||||||
|
|
||||||
Packing slips live under **Logistics**, not Sales. You can also create one by hand and link it to a sales order.
|
|
||||||
|
|
||||||
1. If the status is **Draft**, use **Change status** to move it to **Processed**, or **Cancel** it. There is no **Process** button here.
|
|
||||||
2. When it is **Processed**, click **Complete**. Enter the **delivered quantity** for each product. Remaining quantity opens a **new packing slip**.
|
|
||||||
3. You can **Cancel** a slip while it is **Draft** or **Processed**.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Sales invoice
|
|
||||||
|
|
||||||
**Menu:** Sales → Activities → Sales Invoices
|
|
||||||
|
|
||||||
Invoices appear when you **Process** an order. You can also create one yourself, optionally from an order or a packing slip.
|
|
||||||
|
|
||||||
On the invoice, the only status button is **Cancel** (while the invoice is **Draft**, **Processed**, or **Partial**). You cannot choose Processed, Partial, or Completed yourself. Those labels can still show on the invoice.
|
|
||||||
|
|
||||||
On the invoice detail page, click **Create Sales Payment**. The payment form opens with that invoice and its remaining balance.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Sales plan
|
|
||||||
|
|
||||||
**Menu:** Sales → Activities → Sales Plans
|
|
||||||
|
|
||||||
When you create or edit a **sales** plan, you can attach one or more invoices. Saving the plan does not change the invoice status.
|
|
||||||
|
|
||||||
(Logistics plans attach packing slips instead.)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Sales payment
|
|
||||||
|
|
||||||
**Menu:** Sales → Activities → Sales Payments
|
|
||||||
|
|
||||||
1. Click **Create**. Enter the date and at least one line: an invoice and an amount. Images and notes are optional. Save. A new payment starts as **Draft**.
|
|
||||||
2. Click **Submit** to move it to **Pending**. You can also use **Change status** to mark it **Rejected**.
|
|
||||||
3. While it is **Pending**, click **Approve**, **Reject**, or **Rollback** (back to **Draft**).
|
|
||||||
4. After **Approved**, you cannot change the status further. A **Rejected** payment can be sent back to **Draft** with **Change status**.
|
|
||||||
|
|
||||||
Approving a payment does not change the invoice status from this screen. Refresh the invoice if you need to see an updated balance.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## What you can do at each status
|
|
||||||
|
|
||||||
**Buttons** are the labelled actions on the list or detail page. **Change status** is a separate dialog that lists the statuses you may pick. Invoices do not have Change status.
|
|
||||||
|
|
||||||
### Sales request and sales payment
|
|
||||||
|
|
||||||
Both use Draft → Pending → Approved or Rejected.
|
|
||||||
|
|
||||||
| Current status | Buttons | Change status |
|
|
||||||
| -------------- | ------------------------------------------------------------ | ------------------------- |
|
|
||||||
| Draft | Submit | Rejected |
|
|
||||||
| Pending | Approve, Reject. Payments also have Rollback (back to Draft) | Draft, Approved, Rejected |
|
|
||||||
| Approved | — | — |
|
|
||||||
| Rejected | — | Draft |
|
|
||||||
|
|
||||||
### Sales order
|
|
||||||
|
|
||||||
| Current status | Buttons | Change status |
|
|
||||||
| -------------- | --------------- | -------------------- |
|
|
||||||
| Draft | Process, Cancel | Processed, Cancelled |
|
|
||||||
| Processed | Cancel | Cancelled |
|
|
||||||
| Completed | — | — |
|
|
||||||
| Cancelled | — | — |
|
|
||||||
|
|
||||||
**Process** always opens the packing-slip checkbox dialog (not Change status).
|
|
||||||
|
|
||||||
### Packing slip
|
|
||||||
|
|
||||||
| Current status | Buttons | Change status |
|
|
||||||
| -------------- | ---------------- | -------------------- |
|
|
||||||
| Draft | Cancel | Processed, Cancelled |
|
|
||||||
| Processed | Complete, Cancel | Completed, Cancelled |
|
|
||||||
| Completed | — | — |
|
|
||||||
| Cancelled | — | — |
|
|
||||||
|
|
||||||
**Complete** always asks for delivered quantities.
|
|
||||||
|
|
||||||
### Sales invoice
|
|
||||||
|
|
||||||
You may see Draft, Processed, Partial, Completed, or Cancelled.
|
|
||||||
|
|
||||||
| Current status | What you can do |
|
|
||||||
| ---------------------------- | ----------------- |
|
|
||||||
| Draft, Processed, or Partial | Cancel |
|
|
||||||
| Completed | No status buttons |
|
|
||||||
| Cancelled | No status buttons |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## What you should not expect to click
|
|
||||||
|
|
||||||
These are not buttons on the screens:
|
|
||||||
|
|
||||||
- **Complete** on a sales order
|
|
||||||
- Setting an invoice to Processed, Partial, or Completed yourself
|
|
||||||
- Changing an invoice’s status by putting it on a sales plan
|
|
||||||
- Changing an invoice’s status by approving a payment
|
|
||||||
- Cancelling an order, packing slip, or invoice in one click for all related documents — **Cancel** applies only to the document you are looking at
|
|
||||||
|
|
||||||
If a related document’s status changes after you act, open that document again to see the latest value.
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ Use the sidebar to open **Sales** for day-to-day selling, **Logistics** for pack
|
|||||||
## Where to find things
|
## Where to find things
|
||||||
|
|
||||||
| Area | Menu | What you do there |
|
| Area | Menu | What you do there |
|
||||||
| ------------ | ---------------------- | ------------------------------------------------- |
|
| --- | --- | --- |
|
||||||
| Sales | Sales → Activities | Requests, orders, invoices, payments, visit plans |
|
| Sales | Sales → Activities | Requests, orders, invoices, payments, visit plans |
|
||||||
| Logistics | Logistics → Activities | Packing slips, delivery plans |
|
| Logistics | Logistics → Activities | Packing slips, delivery plans |
|
||||||
| Company data | Settings → Data | Divisions, branches, customers, products |
|
| Company data | Settings → Data | Divisions, branches, customers, products |
|
||||||
@@ -21,4 +21,11 @@ If a menu item is missing, your privilege does not include **View** for that are
|
|||||||
|
|
||||||
## Guides
|
## Guides
|
||||||
|
|
||||||
- [Sales workflow](/apps/web/SALES_WORKFLOW) — from a sales request or order through packing, invoicing, and payment
|
User guides now live under **User guides** in the sidebar:
|
||||||
|
|
||||||
|
- [Web overview](/user/web/)
|
||||||
|
- [Set up your company](/user/web/setup)
|
||||||
|
- [Sales workflow](/user/web/sales-workflow)
|
||||||
|
- [Plans and visits](/user/web/plans)
|
||||||
|
- [Logistics](/user/web/logistics)
|
||||||
|
- [Timeline](/user/web/timeline)
|
||||||
|
|||||||
+45
-34
@@ -2,63 +2,74 @@
|
|||||||
layout: home
|
layout: home
|
||||||
|
|
||||||
hero:
|
hero:
|
||||||
name: 'Frontend Architecture'
|
name: TrackGo
|
||||||
text: 'Enterprise Monorepo'
|
text: Sales and logistics guides
|
||||||
tagline: 'A scalable, standardized foundation for Web & Desktop applications. Built for performance, consistency, and velocity.'
|
tagline: How operators, sales, and drivers use TrackGo on the web and on mobile.
|
||||||
actions:
|
actions:
|
||||||
- theme: brand
|
- theme: brand
|
||||||
text: Get Started
|
text: User guides
|
||||||
link: /setup
|
link: /user/
|
||||||
- theme: alt
|
- theme: alt
|
||||||
text: View Architecture
|
text: Web
|
||||||
link: /overview
|
link: /user/web/
|
||||||
|
|
||||||
features:
|
features:
|
||||||
- title: 🧩 App Layout Engine
|
- title: Web
|
||||||
details: Core App Shell wrapping Mantine for rapid, consistent layout creation across all products.
|
details: Set up company data, users, plans, invoices, payments, packing slips, and activity history.
|
||||||
link: /packages/ui/CORE-APP-SHELL
|
link: /user/web/
|
||||||
linkText: Explore App Shell
|
linkText: Web guides
|
||||||
- title: 📝 Form Primitives
|
- title: Mobile
|
||||||
details: RHF + Zod + Mantine components designed for O(1) render cost and deep type safety.
|
details: Check in at a branch, follow today's plan, visit customers, and collect payments in the field.
|
||||||
link: /packages/ui/FORM-COMPONENTS
|
link: /user/mobile/
|
||||||
linkText: View Forms
|
linkText: Mobile guides
|
||||||
- title: 🖥️ Desktop Ecosystem
|
- title: Sales
|
||||||
details: Complete Electron integration with secure Inter-Process Communication (IPC) and Bridge Architecture.
|
details: Move from a sales request or order through invoicing and payment.
|
||||||
link: /apps/desktop/
|
link: /user/web/sales-workflow
|
||||||
linkText: Desktop Docs
|
linkText: Sales workflow
|
||||||
- title: 🔌 Core Architecture
|
- title: Plans
|
||||||
details: Robust state management, Event Bus, first-class i18n, and unified Storage layers.
|
details: Create a one-off daily plan, or generate plans from weekly visit cycles.
|
||||||
link: /packages/core-api/
|
link: /user/web/plans
|
||||||
linkText: Explore Core
|
linkText: Plans and visits
|
||||||
---
|
---
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ShoppingCart, Truck, Smartphone, MapPin } from 'lucide-vue-next'
|
||||||
|
</script>
|
||||||
|
|
||||||
<div class="custom-divider"></div>
|
<div class="custom-divider"></div>
|
||||||
<div class="bento-container">
|
<div class="bento-container">
|
||||||
<div class="bento-header">
|
<div class="bento-header">
|
||||||
<h2>Why this Monorepo Exists</h2>
|
<h2>How TrackGo is used</h2>
|
||||||
<p>Building high-end enterprise applications requires strict consistency, shared tooling, and well-defined boundaries. This monorepo serves as the absolute source of truth for our frontend ecosystem.</p>
|
<p>Operators prepare master data and daily plans on the web. Sales and drivers check in on mobile, then work the plan: visit customers, collect invoices, or complete deliveries.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="bento-grid">
|
<div class="bento-grid">
|
||||||
<div class="bento-card">
|
<div class="bento-card">
|
||||||
<div class="bento-icon">
|
<div class="bento-icon">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"></path></svg>
|
<ShoppingCart :size="24" />
|
||||||
</div>
|
</div>
|
||||||
<h3>Unified Tooling</h3>
|
<h3>Sales on the web</h3>
|
||||||
<p>By enforcing strict linting, formatting, and building patterns at the root (powered by Turborepo), we ensure that every application in the ecosystem adheres to our high standards without duplicate configuration.</p>
|
<p>Create requests, orders, invoices, and payments. Attach invoices to a sales plan so field staff know what to collect.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="bento-card">
|
<div class="bento-card">
|
||||||
<div class="bento-icon">
|
<div class="bento-icon">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"></path><polyline points="3.27 6.96 12 12.01 20.73 6.96"></polyline><line x1="12" y1="22.08" x2="12" y2="12"></line></svg>
|
<Truck :size="24" />
|
||||||
</div>
|
</div>
|
||||||
<h3>Shared Domain Logic</h3>
|
<h3>Logistics on the web</h3>
|
||||||
<p>The separation of UI components and Core logic guarantees that our web and desktop applications all share the exact same state management and event-driven architecture, drastically reducing cognitive load.</p>
|
<p>Manage packing slips and delivery plans. Complete delivered quantities so orders can finish.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="bento-card">
|
<div class="bento-card">
|
||||||
<div class="bento-icon">
|
<div class="bento-icon">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"></polygon></svg>
|
<Smartphone :size="24" />
|
||||||
</div>
|
</div>
|
||||||
<h3>Accelerated Velocity</h3>
|
<h3>Field work on mobile</h3>
|
||||||
<p>With a rich library of 22+ advanced Form components, pre-configured Vite/TypeScript environments, and an enterprise App Shell, teams can stop reinventing the wheel and start building product features on day one.</p>
|
<p>Clock in at the plan start branch, open today's destinations, check in to a customer, and record a payment.</p>
|
||||||
|
</div>
|
||||||
|
<div class="bento-card">
|
||||||
|
<div class="bento-icon">
|
||||||
|
<MapPin :size="24" />
|
||||||
|
</div>
|
||||||
|
<h3>Activity history</h3>
|
||||||
|
<p>Review a day's footprints and field events on Timeline. Live map streaming on the web is Coming soon.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ outline: [2, 3]
|
|||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
The **Core App Shell** is a configuration-driven layout engine that wraps Mantine's `AppShell` component. It provides a single `<CoreAppShell>` component that renders enterprise-grade application frames — complete with headers, sidebars, aside panels, utility bars, and footers — controlled entirely through a declarative `config` object and slot-based content injection.
|
The **Core App Shell** is a configuration-driven layout engine that wraps Mantine's `AppShell` component. It provides a single `CoreAppShell` component that renders enterprise-grade application frames — complete with headers, sidebars, aside panels, utility bars, and footers — controlled entirely through a declarative `config` object and slot-based content injection.
|
||||||
|
|
||||||
Key capabilities:
|
Key capabilities:
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ The layout engine uses a **Provider → Inner** composition pattern:
|
|||||||
CoreAppShell (Public API)
|
CoreAppShell (Public API)
|
||||||
└── CoreAppShellProvider (Context — state management)
|
└── CoreAppShellProvider (Context — state management)
|
||||||
└── CoreAppShellInner (Layout rendering — consumes context)
|
└── CoreAppShellInner (Layout rendering — consumes context)
|
||||||
└── Mantine <AppShell> (CSS Grid engine)
|
└── Mantine AppShell (CSS Grid engine)
|
||||||
├── AppShell.Header ← slots.utilityBar + slots.header
|
├── AppShell.Header ← slots.utilityBar + slots.header
|
||||||
├── AppShell.Navbar ← slots.sidebar | slots.sidebarRail + slots.sidebarPanel
|
├── AppShell.Navbar ← slots.sidebar | slots.sidebarRail + slots.sidebarPanel
|
||||||
├── AppShell.Main ← children
|
├── AppShell.Main ← children
|
||||||
@@ -120,7 +120,7 @@ type LayoutVariant = 'header-first' | 'sidebar-first' | 'top-nav';
|
|||||||
| `top-nav` | `default` | Header-only layout with **no visible desktop sidebar**. The sidebar is hidden on desktop but remains accessible as a mobile drawer on small screens. Ideal for documentation sites or marketing pages. |
|
| `top-nav` | `default` | Header-only layout with **no visible desktop sidebar**. The sidebar is hidden on desktop but remains accessible as a mobile drawer on small screens. Ideal for documentation sites or marketing pages. |
|
||||||
|
|
||||||
> [!IMPORTANT]
|
> [!IMPORTANT]
|
||||||
> When `variant` is set to `top-nav`, the desktop navbar is visually hidden via `collapsed.desktop: true` and width `0`. However, the `<AppShell.Navbar>` DOM element remains mounted with responsive width props so the mobile drawer continues to function. This is an intentional design choice to avoid conditional DOM removal.
|
> When `variant` is set to `top-nav`, the desktop navbar is visually hidden via `collapsed.desktop: true` and width `0`. However, the `AppShell.Navbar` DOM element remains mounted with responsive width props so the mobile drawer continues to function. This is an intentional design choice to avoid conditional DOM removal.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -201,7 +201,7 @@ interface CoreAppShellSlots {
|
|||||||
| Slot | Location | Notes |
|
| Slot | Location | Notes |
|
||||||
| --------------- | --------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
|
| --------------- | --------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| `utilityBar` | Above the header, hidden on mobile (`display: none` below `sm`) | Typically used for environment banners, announcements, or top-level links. |
|
| `utilityBar` | Above the header, hidden on mobile (`display: none` below `sm`) | Typically used for environment banners, announcements, or top-level links. |
|
||||||
| `header` | Main application header | Must contain its own `<Burger>` for mobile toggle (use `useCoreAppShell()` context). |
|
| `header` | Main application header | Must contain its own `Burger` for mobile toggle (use `useCoreAppShell()` context). |
|
||||||
| `sidebar` | Desktop navbar body (single-sidebar mode) | Ignored when `withDoubleSidebar` is `true` — use `sidebarRail` + `sidebarPanel` instead. |
|
| `sidebar` | Desktop navbar body (single-sidebar mode) | Ignored when `withDoubleSidebar` is `true` — use `sidebarRail` + `sidebarPanel` instead. |
|
||||||
| `sidebarMobile` | Mobile drawer content | Falls back to `sidebar` if not provided. Use this to render a simplified mobile-specific navigation. |
|
| `sidebarMobile` | Mobile drawer content | Falls back to `sidebar` if not provided. Use this to render a simplified mobile-specific navigation. |
|
||||||
| `sidebarRail` | Narrow icon rail (double-sidebar mode) | Only rendered when `withDoubleSidebar` is `true`. Separated from `sidebarPanel` by a 1px border. |
|
| `sidebarRail` | Narrow icon rail (double-sidebar mode) | Only rendered when `withDoubleSidebar` is `true`. Separated from `sidebarPanel` by a 1px border. |
|
||||||
@@ -233,7 +233,7 @@ import { useCoreAppShell } from '@repo/ui/components';
|
|||||||
| `toggleNavbarPanel()` | `() => void` | Toggle the double-sidebar panel open/closed |
|
| `toggleNavbarPanel()` | `() => void` | Toggle the double-sidebar panel open/closed |
|
||||||
| `setSidebarVariant()` | `(variant: SidebarVariant) => void` | Programmatically set the sidebar to `'expanded'`, `'mini'`, or `'hidden'` |
|
| `setSidebarVariant()` | `(variant: SidebarVariant) => void` | Programmatically set the sidebar to `'expanded'`, `'mini'`, or `'hidden'` |
|
||||||
|
|
||||||
> [!WARNING] > `useCoreAppShell()` **must** be called from within a `<CoreAppShell>` subtree. Calling it outside the provider will throw: `"useCoreAppShell must be used within CoreAppShellProvider"`. If you need context access in the header slot, pass a component (not inline JSX) so it mounts inside the provider tree.
|
> [!WARNING] > `useCoreAppShell()` **must** be called from within a `CoreAppShell` subtree. Calling it outside the provider will throw: `"useCoreAppShell must be used within CoreAppShellProvider"`. If you need context access in the header slot, pass a component (not inline JSX) so it mounts inside the provider tree.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -416,8 +416,9 @@ function App() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
> [!NOTE]
|
::: info
|
||||||
> When `withDoubleSidebar` is `true`, the `sidebar` slot is ignored on desktop. The navbar renders `sidebarRail` (fixed-width icon column) and `sidebarPanel` (collapsible contextual panel) side-by-side. On mobile, `sidebarMobile` takes priority, falling back to `sidebar` if not provided.
|
When `withDoubleSidebar` is `true`, the `sidebar` slot is ignored on desktop. The navbar renders `sidebarRail` (fixed-width icon column) and `sidebarPanel` (collapsible contextual panel) side-by-side. On mobile, `sidebarMobile` takes priority, falling back to `sidebar` if not provided.
|
||||||
|
:::
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -458,7 +459,7 @@ function ShellDemo() {
|
|||||||
|
|
||||||
## CorePageContainer
|
## CorePageContainer
|
||||||
|
|
||||||
A companion component for structuring page-level content within the `<AppShell.Main>` area. It provides a sticky page header and a contained, padded content region.
|
A companion component for structuring page-level content within the `AppShell.Main` area. It provides a sticky page header and a contained, padded content region.
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
import { CorePageContainer } from '@repo/ui/components';
|
import { CorePageContainer } from '@repo/ui/components';
|
||||||
@@ -508,7 +509,7 @@ interface CorePageContainerProps extends ContainerProps {
|
|||||||
|
|
||||||
### Mobile Navbar Lifecycle
|
### Mobile Navbar Lifecycle
|
||||||
|
|
||||||
The `<AppShell.Navbar>` DOM element is **always mounted**, even when the layout variant is `top-nav`. The desktop content is hidden via `visibleFrom="sm"` and mobile content via `hiddenFrom="sm"`. This ensures Mantine's native drawer engine works correctly on mobile without conditional DOM removal breaking the transition animations.
|
The `AppShell.Navbar` DOM element is **always mounted**, even when the layout variant is `top-nav`. The desktop content is hidden via `visibleFrom="sm"` and mobile content via `hiddenFrom="sm"`. This ensures Mantine's native drawer engine works correctly on mobile without conditional DOM removal breaking the transition animations.
|
||||||
|
|
||||||
### Footer Positioning in `header-first` Mode
|
### Footer Positioning in `header-first` Mode
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
# What is TrackGo
|
||||||
|
|
||||||
|
TrackGo is a sales and logistics platform. Office staff run the **web** app. Sales, drivers, and crew work from the **mobile** app.
|
||||||
|
|
||||||
|
You set up the company, people, products, and customers first. Then you plan the day's visits, attach invoices or packing slips, and follow field activity.
|
||||||
|
|
||||||
|
## Who uses it
|
||||||
|
|
||||||
|
| Role | Where they work | Typical tasks |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| Operator / admin | Web | Company data, users, privileges, plans, documents |
|
||||||
|
| Sales | Web and mobile | Requests, orders, invoices, payments, customer visits |
|
||||||
|
| Driver / crew | Web (plans) and mobile | Delivery plans, packing slips, customer stops |
|
||||||
|
|
||||||
|
What you can open depends on the **privilege** assigned to your user. If a menu is missing, ask an administrator to grant **View** for that area.
|
||||||
|
|
||||||
|
## The usual flow
|
||||||
|
|
||||||
|
```plantuml
|
||||||
|
@startuml
|
||||||
|
actor Operator
|
||||||
|
actor Field as "Sales or driver"
|
||||||
|
|
||||||
|
Operator -> Web: Set up company, users, and master data
|
||||||
|
Operator -> Web: Create cycles or a one-off plan
|
||||||
|
Operator -> Web: Attach invoices or packing slips
|
||||||
|
Field -> Mobile: Clock in at the plan start branch
|
||||||
|
Field -> Mobile: Visit customers on the plan
|
||||||
|
Field -> Mobile: Collect payment or follow packing tasks
|
||||||
|
Operator -> Web: Review documents and Timeline
|
||||||
|
@enduml
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Add company settings, branches, divisions, customers, products, and employees.
|
||||||
|
2. Create users and privileges so each person only sees what they need.
|
||||||
|
3. Build **weekly cycles** (recurring) or a **one-off plan** for a date. Attach invoices (sales) or packing slips (logistics).
|
||||||
|
4. Field staff check in at the branch on mobile, then work the plan.
|
||||||
|
5. Sales collect payment on mobile or web. Drivers complete packing slips on the web.
|
||||||
|
|
||||||
|
## Sales documents
|
||||||
|
|
||||||
|
The sales path is:
|
||||||
|
|
||||||
|
**Sales request (optional) → Sales order → Invoice → Payment**
|
||||||
|
|
||||||
|
Processing an order can also create a packing slip for delivery. Details: [Sales workflow](/user/web/sales-workflow).
|
||||||
|
|
||||||
|
## Web and mobile
|
||||||
|
|
||||||
|
- [Web](/user/web/) — setup, plans, sales, logistics, timeline, CSV import
|
||||||
|
- [Mobile](/user/mobile/) — login, branch check-in, today's plan, customers, payments
|
||||||
|
|
||||||
|
## Coming soon
|
||||||
|
|
||||||
|
These items are not in the product yet:
|
||||||
|
|
||||||
|
- Web **Dashboard** (the menu exists; the page is a placeholder)
|
||||||
|
- **Live** position on the web map (Timeline plays back a recorded day instead)
|
||||||
|
- Mobile **packing slip status** updates (logistics tasks are listed, not updated on the phone)
|
||||||
|
- Forgot password, remember me, and sign-up on login screens
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
<script setup>
|
||||||
|
import { MapPin } from 'lucide-vue-next'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
# Check in
|
||||||
|
|
||||||
|
<p class="doc-lead"><MapPin :size="20" class="doc-icon" /> Clock in at the plan start branch before field work</p>
|
||||||
|
|
||||||
|
|
||||||
|
Sales and drivers **clock in at the plan start branch** before they start field work. The app does not block browsing Home, Plan, or Customers without check-in, but create-customer, customer visit check-in, sales documents, and payments stay disabled until you are on duty.
|
||||||
|
|
||||||
|
## Before you clock in
|
||||||
|
|
||||||
|
You need **today's plan** with a start branch. If there is no plan, Clock In is unavailable and the screen explains there is no plan for today. An operator must [create or generate the plan](/user/web/plans) on the web.
|
||||||
|
|
||||||
|
## Clock in and out
|
||||||
|
|
||||||
|
1. From Home, tap **Check in now** if you see **You have not checked in**, or open the check-in screen.
|
||||||
|
2. Confirm your location on the map (OpenStreetMap). Use recenter if needed.
|
||||||
|
3. Tap **Clock In Now**. The app sends GPS coordinates for the plan **start branch**.
|
||||||
|
4. While on duty, the app records location footprints in the background (the interval comes from company GPS settings).
|
||||||
|
5. Tap **Clock Out** when the shift ends. Tracking stops.
|
||||||
|
|
||||||
|
The screen shows your name, date, coordinates, and clock-in / clock-out times.
|
||||||
|
|
||||||
|
A circle on the map is a visual guide. The Clock In button is enabled when a plan exists and you are not already checked in — it is not blocked by standing outside that circle.
|
||||||
|
|
||||||
|
## After check-in
|
||||||
|
|
||||||
|
While branch attendance is open:
|
||||||
|
|
||||||
|
- You can create a customer
|
||||||
|
- You can check in to a customer on a visit
|
||||||
|
- Sales actions (request, order, payment) also need a **customer visit** check-in for that customer
|
||||||
|
|
||||||
|
If GPS moves too far from a customer visit, Home can show a checkout warning so you can check out of the visit.
|
||||||
|
|
||||||
|
## Coming soon
|
||||||
|
|
||||||
|
- Check-in by **NFC** or **QR** (the screen always uses GPS)
|
||||||
|
- Enforcing the check-in radius before Clock In is enabled
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
<script setup>
|
||||||
|
import { Calendar } from 'lucide-vue-next'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
# Daily work
|
||||||
|
|
||||||
|
<p class="doc-lead"><Calendar :size="20" class="doc-icon" /> Home, Plan, and Customers after you are on duty</p>
|
||||||
|
|
||||||
|
|
||||||
|
After [branch check-in](/user/mobile/check-in), use Home, Plan, and Customers to work the day.
|
||||||
|
|
||||||
|
## Home
|
||||||
|
|
||||||
|
Home has two tabs: **Plan** and **Timeline**.
|
||||||
|
|
||||||
|
**Plan tab**
|
||||||
|
|
||||||
|
- Greeting and your position (Sales, Driver, or Crew)
|
||||||
|
- Banner if you have not checked in at the branch
|
||||||
|
- Today's destinations — **Open** starts a customer visit
|
||||||
|
- Active visit card with checkout
|
||||||
|
- **Today Task** — invoices (sales) or packing-slip codes (driver/crew)
|
||||||
|
|
||||||
|
**Timeline tab**
|
||||||
|
|
||||||
|
Today's field events grouped by customer (check-in/out, sales documents, new customers). Pull down to refresh.
|
||||||
|
|
||||||
|
Logout is on the avatar menu.
|
||||||
|
|
||||||
|
### Coming soon on Home
|
||||||
|
|
||||||
|
- Work **performance** totals (customer / invoice / payment / packing counts are not shown on the screen)
|
||||||
|
- Messages and Notifications icons do nothing yet
|
||||||
|
|
||||||
|
## Plan
|
||||||
|
|
||||||
|
The **Plan** tab lists today's destinations. Open a stop to go to the customer visit screen.
|
||||||
|
|
||||||
|
If a plan exists, use **Add customer to plan**:
|
||||||
|
|
||||||
|
1. Search customers who are not already on the plan.
|
||||||
|
2. For **sales** plans, you can pick outstanding invoices to attach.
|
||||||
|
3. Confirm **Add to plan**.
|
||||||
|
|
||||||
|
You cannot create a new daily plan on the phone — only extend an existing one.
|
||||||
|
|
||||||
|
### Coming soon on Plan
|
||||||
|
|
||||||
|
- Picking **packing slips** when adding a customer to a logistics plan
|
||||||
|
|
||||||
|
## Customers
|
||||||
|
|
||||||
|
Search and sort the list by **Name**, **Code**, or **Distance**. Tap a row for the profile.
|
||||||
|
|
||||||
|
**Create** (FAB) is available only after branch check-in. The form includes code, name, phone, NFC ID (typed), address, map location, and optional contacts.
|
||||||
|
|
||||||
|
### Visit a customer
|
||||||
|
|
||||||
|
Open a destination from the plan, or open the visit route from the profile.
|
||||||
|
|
||||||
|
1. Complete **Customer check-in (GPS)** when sales actions are locked.
|
||||||
|
2. Then you can use **Sales actions**.
|
||||||
|
|
||||||
|
Without branch check-in you see **Branch check-in is required**. Without a visit check-in for that customer you see that you must check in to the customer.
|
||||||
|
|
||||||
|
### Sales request and sales order
|
||||||
|
|
||||||
|
**Create sales request** and **Create sales order (no packing)** send a document with the **first loaded product** and quantity **1**. There is no product picker or cart on the phone.
|
||||||
|
|
||||||
|
For full line items, create the documents on the [web](/user/web/sales-workflow).
|
||||||
|
|
||||||
|
### Payments
|
||||||
|
|
||||||
|
Outstanding invoices on the profile/visit list have **Create payment**.
|
||||||
|
|
||||||
|
1. Confirm invoice code, status, and balance.
|
||||||
|
2. Enter **amount** (starts at the remaining balance) and optional **notes**.
|
||||||
|
3. Record the payment. GPS is attached when available.
|
||||||
|
|
||||||
|
Amount must be greater than zero and not more than the balance. The same branch + customer visit rules apply.
|
||||||
|
|
||||||
|
## What drivers can do today
|
||||||
|
|
||||||
|
Drivers and crew follow the logistics plan and see packing-slip codes on Home. **Changing packing slip status on mobile is Coming soon** — complete slips on the [web](/user/web/logistics).
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
<script setup>
|
||||||
|
import { Smartphone } from 'lucide-vue-next'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
# Mobile overview
|
||||||
|
|
||||||
|
<p class="doc-lead"><Smartphone :size="20" class="doc-icon" /> Field app for sales, drivers, and crew</p>
|
||||||
|
|
||||||
|
|
||||||
|
The TrackGo mobile app is for **sales**, **drivers**, and **crew** in the field. Bottom tabs are **Home**, **Plan**, and **Customers**. Branch check-in is a separate screen.
|
||||||
|
|
||||||
|
Your employee position decides which plan you get:
|
||||||
|
|
||||||
|
| Position | Plan type | Today's tasks on Home |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| Sales | Sales | Invoices on today's plan |
|
||||||
|
| Driver or crew | Logistics | Packing slip codes on today's plan |
|
||||||
|
|
||||||
|
If the account is not linked to an employee, Home and Plan explain that the profile is not linked.
|
||||||
|
|
||||||
|
## Sign in
|
||||||
|
|
||||||
|
1. Open the app.
|
||||||
|
2. Enter **Employee ID** and **Password**.
|
||||||
|
3. Tap **Sign In**.
|
||||||
|
|
||||||
|
Username rules: 3–32 characters. Password: 8–72 characters.
|
||||||
|
|
||||||
|
## A typical day
|
||||||
|
|
||||||
|
```plantuml
|
||||||
|
@startuml
|
||||||
|
start
|
||||||
|
:Sign in;
|
||||||
|
:Open Home or Check in;
|
||||||
|
:Clock in at the plan start branch;
|
||||||
|
:Open today's plan;
|
||||||
|
:Check in to a customer;
|
||||||
|
:Collect payment or create a sales document;
|
||||||
|
:Clock out of the visit and the branch;
|
||||||
|
stop
|
||||||
|
@enduml
|
||||||
|
```
|
||||||
|
|
||||||
|
1. [Check in](/user/mobile/check-in) at the branch (required before most field actions).
|
||||||
|
2. [Daily work](/user/mobile/daily-work) — plan, customers, visits, payments, Home timeline.
|
||||||
|
|
||||||
|
## Coming soon on login
|
||||||
|
|
||||||
|
These controls are visible but do not work yet:
|
||||||
|
|
||||||
|
- Remember Me
|
||||||
|
- Forgot Password
|
||||||
|
- Sign in with email or phone
|
||||||
|
- Sign up
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
<script setup>
|
||||||
|
import { FileText } from 'lucide-vue-next'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
# Import CSV
|
||||||
|
|
||||||
|
<p class="doc-lead"><FileText :size="20" class="doc-icon" /> Import on document lists when your privilege includes Import</p>
|
||||||
|
|
||||||
|
You can bulk-load documents from a **.csv** file on these index pages:
|
||||||
|
|
||||||
|
| Document | Menu |
|
||||||
|
| --- | --- |
|
||||||
|
| Sales requests | Sales → Activities → Sales Requests |
|
||||||
|
| Sales orders | Sales → Activities → Sales Orders |
|
||||||
|
| Sales invoices | Sales → Activities → Sales Invoices |
|
||||||
|
| Sales payments | Sales → Activities → Sales Payments |
|
||||||
|
| Packing slips | Logistics → Activities → Packing slips |
|
||||||
|
|
||||||
|
## How to import
|
||||||
|
|
||||||
|
1. Open the list.
|
||||||
|
2. Click **Import CSV** (hidden if you do not have **Import** on that area).
|
||||||
|
3. Choose a `.csv` file and confirm.
|
||||||
|
|
||||||
|
There is no separate import wizard beyond the file upload.
|
||||||
|
|
||||||
|
## What you cannot import here
|
||||||
|
|
||||||
|
Master data (branches, customers, products), users, privileges, cycles, and plans do **not** have an Import CSV button. Create those records in their own screens, or generate plans from cycles.
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
<script setup>
|
||||||
|
import { LayoutDashboard, MapPin, ShoppingCart, Truck, Settings } from 'lucide-vue-next'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
# Web overview
|
||||||
|
|
||||||
|
<p class="doc-lead"><LayoutDashboard :size="20" class="doc-icon" /> Browser and desktop app for operators, sales, and logistics.</p>
|
||||||
|
|
||||||
|
Sign in with **Username** and **Password** on the login page. You can switch the language between English and Indonesian.
|
||||||
|
|
||||||
|
After login, the sidebar shows only the menus your privilege allows.
|
||||||
|
|
||||||
|
## Menus
|
||||||
|
|
||||||
|
| Menu | Icon | What you do there |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| Dashboard | <LayoutDashboard :size="16" class="doc-icon" /> | Coming soon |
|
||||||
|
| Timeline | <MapPin :size="16" class="doc-icon" /> | Play back a day's GPS footprints and field activities for sales employees |
|
||||||
|
| Sales | <ShoppingCart :size="16" class="doc-icon" /> | Employees, cycles, requests, orders, invoices, payments, plans, reports |
|
||||||
|
| Logistics | <Truck :size="16" class="doc-icon" /> | Drivers and crew, cycles, packing slips, plans, reports |
|
||||||
|
| Settings | <Settings :size="16" class="doc-icon" /> | Branches, divisions, customers, products, company settings, users, privileges |
|
||||||
|
|
||||||
|
## Suggested order
|
||||||
|
|
||||||
|
1. [Set up your company](/user/web/setup) — master data, users, and privileges
|
||||||
|
2. [Plans and visits](/user/web/plans) — one-off plans and weekly cycles
|
||||||
|
3. [Sales workflow](/user/web/sales-workflow) — request, order, invoice, payment
|
||||||
|
4. [Logistics](/user/web/logistics) — packing slips and delivery plans
|
||||||
|
5. [Timeline](/user/web/timeline) — activity history on the map
|
||||||
|
6. [Import CSV](/user/web/import) — bulk load documents
|
||||||
|
|
||||||
|
## Reports
|
||||||
|
|
||||||
|
**Sales → Sales Reports** and **Logistics → Logistics Reports** show report tables from the server. If none are configured, the page says there are no reports available.
|
||||||
|
|
||||||
|
## Status and permissions
|
||||||
|
|
||||||
|
Most master-data records use **Draft**, **Active**, and **Archived**. Sales and logistics documents use their own statuses (see each guide).
|
||||||
|
|
||||||
|
Buttons such as Create, Process, Submit, and Approve appear only when your privilege includes that action (**Create**, **Update**, **Delete**, or **Import**).
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
<script setup>
|
||||||
|
import { Truck, Package, Calendar } from 'lucide-vue-next'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
# Logistics
|
||||||
|
|
||||||
|
<p class="doc-lead"><Truck :size="20" class="doc-icon" /> Logistics menus for drivers, crew, packing slips, and delivery plans</p>
|
||||||
|
|
||||||
|
Use Logistics when you need delivery paperwork and driver routes. Sales still owns requests, orders, invoices, and payments.
|
||||||
|
|
||||||
|
## Employees and cycles
|
||||||
|
|
||||||
|
- **Logistics → Data → Employees** — positions **driver** and **crew**
|
||||||
|
- **Logistics → Data → Logistics Cycles** — weekly visit templates for those employees
|
||||||
|
|
||||||
|
Generate daily plans from cycles the same way as sales. See [Plans and visits](/user/web/plans).
|
||||||
|
|
||||||
|
## Packing slips
|
||||||
|
|
||||||
|
<p class="doc-lead"><Package :size="18" class="doc-icon" /> Logistics → Activities → Packing slips</p>
|
||||||
|
|
||||||
|
Packing slips are created when you **Process** a sales order with **Generate packing slip** checked. You can also create one by hand and link it to a sales order.
|
||||||
|
|
||||||
|
Typical fields: code, date, customer, sales order, location, products, notes.
|
||||||
|
|
||||||
|
```plantuml
|
||||||
|
@startuml
|
||||||
|
start
|
||||||
|
if (Status is Draft?) then (yes)
|
||||||
|
:Change status to Processed\nor Cancel;
|
||||||
|
endif
|
||||||
|
if (Status is Processed?) then (yes)
|
||||||
|
:Complete;
|
||||||
|
:Enter delivered quantity per product;
|
||||||
|
if (Remaining quantity?) then (yes)
|
||||||
|
:A new packing slip is created\nfor the remainder;
|
||||||
|
else (no)
|
||||||
|
:Slip is Completed;
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
stop
|
||||||
|
@enduml
|
||||||
|
```
|
||||||
|
|
||||||
|
1. If the status is **Draft**, use **Change status** to move it to **Processed**, or **Cancel** it. There is no **Process** button here.
|
||||||
|
2. When it is **Processed**, click **Complete**. Enter the **delivered quantity** for each product. Remaining quantity opens a **new packing slip**.
|
||||||
|
3. You can **Cancel** a slip while it is **Draft** or **Processed**.
|
||||||
|
|
||||||
|
When every related packing slip is completed, the linked sales order can move to **Completed**. If you skip packing on the order, the order does not wait for a slip.
|
||||||
|
|
||||||
|
### Status actions
|
||||||
|
|
||||||
|
| Current status | Buttons | Change status |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| Draft | Cancel | Processed, Cancelled |
|
||||||
|
| Processed | Complete, Cancel | Completed, Cancelled |
|
||||||
|
| Completed | — | — |
|
||||||
|
| Cancelled | — | — |
|
||||||
|
|
||||||
|
**Complete** always asks for delivered quantities.
|
||||||
|
|
||||||
|
You can [import packing slips from CSV](/user/web/import) if your privilege includes **Import**.
|
||||||
|
|
||||||
|
## Logistics plans
|
||||||
|
|
||||||
|
<p class="doc-lead"><Calendar :size="18" class="doc-icon" /> Logistics → Activities → Logistics Plans</p>
|
||||||
|
|
||||||
|
Same plan model as sales: employee, date, start/end branch, customers. Attach **packing slips** instead of invoices.
|
||||||
|
|
||||||
|
Drivers and crew open today's plan on [mobile](/user/mobile/daily-work). Home shows packing-slip codes as today's tasks.
|
||||||
|
|
||||||
|
## Coming soon
|
||||||
|
|
||||||
|
**Updating packing slip status on mobile** is not available. Drivers see assigned packing codes on Home; they complete slips in the web app (or an operator does).
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
<script setup>
|
||||||
|
import { Calendar, Repeat } from 'lucide-vue-next'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
# Plans and visits
|
||||||
|
|
||||||
|
<p class="doc-lead"><Calendar :size="20" class="doc-icon" /> Sales → Activities → Sales Plans, or Logistics → Activities → Logistics Plans</p>
|
||||||
|
|
||||||
|
A **plan** is one employee's work for **one date**: start branch, end branch, customers to visit, and documents to collect.
|
||||||
|
|
||||||
|
There is no recurrence switch on the plan form. Recurring work uses **cycles**, then **Generate**.
|
||||||
|
|
||||||
|
```plantuml
|
||||||
|
@startuml
|
||||||
|
start
|
||||||
|
if (Need a repeating weekly route?) then (yes)
|
||||||
|
:Create a cycle with weekday routes;
|
||||||
|
:Generate plans for a date range;
|
||||||
|
else (no)
|
||||||
|
:Create a one-off plan for a date;
|
||||||
|
endif
|
||||||
|
:Attach invoices (sales) or packing slips (logistics);
|
||||||
|
:Field staff open the plan on mobile;
|
||||||
|
stop
|
||||||
|
@enduml
|
||||||
|
```
|
||||||
|
|
||||||
|
## One-off plan
|
||||||
|
|
||||||
|
**Create page description in the app:** "Create a one-off daily plan for an employee."
|
||||||
|
|
||||||
|
1. Open **Sales Plans** or **Logistics Plans**.
|
||||||
|
2. Click **Create**.
|
||||||
|
3. Choose the **employee**, **date** (today or later), **start branch**, and **end branch**.
|
||||||
|
4. Add **customers** as destinations (order matters for the route).
|
||||||
|
5. After customers are selected:
|
||||||
|
- Sales plans: attach **invoices** for those customers
|
||||||
|
- Logistics plans: attach **packing slips** for those customers
|
||||||
|
6. Save. Status is **Draft**, **Active**, or **Archived** like other master records.
|
||||||
|
|
||||||
|
You can preview customers and attached documents on the form.
|
||||||
|
|
||||||
|
Saving a sales plan does **not** change invoice status.
|
||||||
|
|
||||||
|
## Weekly cycles (recurring)
|
||||||
|
|
||||||
|
<p class="doc-lead"><Repeat :size="18" class="doc-icon" /> Sales → Data → Sales Cycles, or Logistics → Data → Logistics Cycles</p>
|
||||||
|
|
||||||
|
A cycle is a **weekly visit template** for one employee: cycle number and, for each weekday, whether the day is active, start/end branch, and customers.
|
||||||
|
|
||||||
|
1. Create a cycle for the employee.
|
||||||
|
2. Enable the weekdays they work and fill the route.
|
||||||
|
3. Set the cycle to **Active**.
|
||||||
|
|
||||||
|
## Generate plans from cycles
|
||||||
|
|
||||||
|
On the plans list, click **Generate**.
|
||||||
|
|
||||||
|
1. Choose the **employee**.
|
||||||
|
2. Choose **from** and **to** dates.
|
||||||
|
3. Confirm. The app creates daily plans from the cycle and reports how many were **created** and **skipped** (for example if a plan already exists).
|
||||||
|
|
||||||
|
## Who uses the plan
|
||||||
|
|
||||||
|
- **Web operators** create and generate plans, then attach documents.
|
||||||
|
- **Sales and drivers on mobile** see today's plan after they exist. They can add a customer to an existing plan; they cannot create a new plan on the phone.
|
||||||
|
|
||||||
|
See [Mobile daily work](/user/mobile/daily-work).
|
||||||
@@ -0,0 +1,154 @@
|
|||||||
|
<script setup>
|
||||||
|
import { ShoppingCart, ClipboardList, Box, Receipt, CreditCard } from 'lucide-vue-next'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
# Sales workflow
|
||||||
|
|
||||||
|
<p class="doc-lead"><ShoppingCart :size="20" class="doc-icon" /> Sales → Activities</p>
|
||||||
|
|
||||||
|
How to run a sale: from a request or order, through packing and invoicing, to payment.
|
||||||
|
|
||||||
|
You need permission to view each menu. Status buttons (Process, Complete, Submit, Approve, and so on) appear only if you are allowed to edit.
|
||||||
|
|
||||||
|
## Before you start
|
||||||
|
|
||||||
|
Set up the records that every sales document needs:
|
||||||
|
|
||||||
|
| You need | Where to create it |
|
||||||
|
| --- | --- |
|
||||||
|
| Division, branch, customer, product | [Settings → Data](/user/web/setup) |
|
||||||
|
| Salesperson | Sales → Data → Employees |
|
||||||
|
|
||||||
|
If a menu is missing, ask an administrator to give your privilege **View** (and **Update** for status buttons) on that area.
|
||||||
|
|
||||||
|
## The usual flow
|
||||||
|
|
||||||
|
```plantuml
|
||||||
|
@startuml
|
||||||
|
start
|
||||||
|
:Sales request (optional);
|
||||||
|
:Sales order (Draft);
|
||||||
|
:Process order;
|
||||||
|
fork
|
||||||
|
:Sales invoice created;
|
||||||
|
fork again
|
||||||
|
:Packing slip created\n(unless you skip it);
|
||||||
|
end fork
|
||||||
|
if (Packing slip exists?) then (yes)
|
||||||
|
:Complete delivered quantities;
|
||||||
|
endif
|
||||||
|
:Create sales payment;
|
||||||
|
:Submit then Approve;
|
||||||
|
stop
|
||||||
|
@enduml
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Optionally create and approve a **sales request**.
|
||||||
|
2. Create a **sales order** (from the request, or from scratch).
|
||||||
|
3. Open the draft order and click **Process**. Leave **Generate packing slip** checked unless you do not need delivery paperwork. Processing creates a **sales invoice**, and a **packing slip** unless you skip it.
|
||||||
|
4. If there is a packing slip, open **Logistics → Packing slips**, then **Complete** and enter how much was delivered.
|
||||||
|
5. Open the invoice and click **Create Sales Payment**. **Submit** the payment, then **Approve** it (or **Reject** / **Rollback**).
|
||||||
|
|
||||||
|
You can also [import CSV](/user/web/import) for requests, orders, invoices, and payments.
|
||||||
|
|
||||||
|
## Sales request
|
||||||
|
|
||||||
|
<p class="doc-lead"><ClipboardList :size="18" class="doc-icon" /> Sales → Activities → Sales Requests</p>
|
||||||
|
|
||||||
|
A request is optional. You can go straight to a sales order.
|
||||||
|
|
||||||
|
1. Click **Create**. Fill in date, salesperson, branch, division, customer, address, and at least one product with a quantity. Product price and document code are optional. Save.
|
||||||
|
2. While the status is **Draft**, click **Submit** to send it for approval. You can also use **Change status** to mark it **Rejected**.
|
||||||
|
3. While it is **Pending**, click **Approve** or **Reject**. **Change status** can send it back to **Draft**.
|
||||||
|
4. After it is **Approved**, there is nothing more to do on the request itself.
|
||||||
|
5. On the request detail page, click **Create Sales Order**. The order form opens with the request's customer, location, and products already filled in.
|
||||||
|
|
||||||
|
## Sales order
|
||||||
|
|
||||||
|
<p class="doc-lead"><Box :size="18" class="doc-icon" /> Sales → Activities → Sales Orders</p>
|
||||||
|
|
||||||
|
1. Click **Create**. Fill in the same kind of details as a request. On a new order you can pick a sales request under **Source**; that copies the request into the form. Save. A new order starts as **Draft**.
|
||||||
|
2. On a **Draft** order, click **Process**.
|
||||||
|
- You will see: *Processing creates a sales invoice and, unless skipped, a packing slip.*
|
||||||
|
- **Generate packing slip** is checked by default. Uncheck it if you do not want a packing slip.
|
||||||
|
3. On **Draft** or **Processed**, you can **Cancel**. There is no **Complete** button on orders. If the order later shows **Completed**, that was not something you clicked on this screen.
|
||||||
|
4. On the order detail page you can see linked packing slips and invoices, and click **Create Sales Invoice**.
|
||||||
|
|
||||||
|
You can select several orders and Process or Cancel them together, as long as they are all in a status that allows that action.
|
||||||
|
|
||||||
|
## Packing slip
|
||||||
|
|
||||||
|
Packing slips live under **Logistics**, not Sales. See [Logistics](/user/web/logistics).
|
||||||
|
|
||||||
|
## Sales invoice
|
||||||
|
|
||||||
|
<p class="doc-lead"><Receipt :size="18" class="doc-icon" /> Sales → Activities → Sales Invoices</p>
|
||||||
|
|
||||||
|
Invoices appear when you **Process** an order. You can also create one yourself, optionally from an order or a packing slip.
|
||||||
|
|
||||||
|
On the invoice, the only status button is **Cancel** (while the invoice is **Draft**, **Processed**, or **Partial**). You cannot choose Processed, Partial, or Completed yourself. Those labels can still show on the invoice.
|
||||||
|
|
||||||
|
On the invoice detail page, click **Create Sales Payment**. The payment form opens with that invoice and its remaining balance.
|
||||||
|
|
||||||
|
You can attach invoices to a [sales plan](/user/web/plans). Saving the plan does not change invoice status.
|
||||||
|
|
||||||
|
## Sales payment
|
||||||
|
|
||||||
|
<p class="doc-lead"><CreditCard :size="18" class="doc-icon" /> Sales → Activities → Sales Payments</p>
|
||||||
|
|
||||||
|
1. Click **Create**. Enter the date and at least one line: an invoice and an amount. Images and notes are optional. Save. A new payment starts as **Draft**.
|
||||||
|
2. Click **Submit** to move it to **Pending**. You can also use **Change status** to mark it **Rejected**.
|
||||||
|
3. While it is **Pending**, click **Approve**, **Reject**, or **Rollback** (back to **Draft**).
|
||||||
|
4. After **Approved**, you cannot change the status further. A **Rejected** payment can be sent back to **Draft** with **Change status**.
|
||||||
|
|
||||||
|
Approving a payment does not change the invoice status from this screen. Refresh the invoice if you need to see an updated balance.
|
||||||
|
|
||||||
|
Field staff can also [record a payment on mobile](/user/mobile/daily-work) from an outstanding invoice.
|
||||||
|
|
||||||
|
## What you can do at each status
|
||||||
|
|
||||||
|
**Buttons** are the labelled actions on the list or detail page. **Change status** is a separate dialog that lists the statuses you may pick. Invoices do not have Change status.
|
||||||
|
|
||||||
|
### Sales request and sales payment
|
||||||
|
|
||||||
|
Both use Draft → Pending → Approved or Rejected.
|
||||||
|
|
||||||
|
| Current status | Buttons | Change status |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| Draft | Submit | Rejected |
|
||||||
|
| Pending | Approve, Reject. Payments also have Rollback (back to Draft) | Draft, Approved, Rejected |
|
||||||
|
| Approved | — | — |
|
||||||
|
| Rejected | — | Draft |
|
||||||
|
|
||||||
|
### Sales order
|
||||||
|
|
||||||
|
| Current status | Buttons | Change status |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| Draft | Process, Cancel | Processed, Cancelled |
|
||||||
|
| Processed | Cancel | Cancelled |
|
||||||
|
| Completed | — | — |
|
||||||
|
| Cancelled | — | — |
|
||||||
|
|
||||||
|
**Process** always opens the packing-slip checkbox dialog (not Change status).
|
||||||
|
|
||||||
|
### Sales invoice
|
||||||
|
|
||||||
|
You may see Draft, Processed, Partial, Completed, or Cancelled.
|
||||||
|
|
||||||
|
| Current status | What you can do |
|
||||||
|
| --- | --- |
|
||||||
|
| Draft, Processed, or Partial | Cancel |
|
||||||
|
| Completed | No status buttons |
|
||||||
|
| Cancelled | No status buttons |
|
||||||
|
|
||||||
|
## What you should not expect to click
|
||||||
|
|
||||||
|
These are not buttons on the screens:
|
||||||
|
|
||||||
|
- **Complete** on a sales order
|
||||||
|
- Setting an invoice to Processed, Partial, or Completed yourself
|
||||||
|
- Changing an invoice's status by putting it on a sales plan
|
||||||
|
- Changing an invoice's status by approving a payment
|
||||||
|
- Cancelling an order, packing slip, or invoice in one click for all related documents — **Cancel** applies only to the document you are looking at
|
||||||
|
|
||||||
|
If a related document's status changes after you act, open that document again to see the latest value.
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
<script setup>
|
||||||
|
import { Settings, Users, Shield } from 'lucide-vue-next'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
# Set up your company
|
||||||
|
|
||||||
|
<p class="doc-lead"><Settings :size="20" class="doc-icon" /> Settings → Data and Settings → User</p>
|
||||||
|
|
||||||
|
Do this before you create plans or sales documents. Records that other screens need (branch, division, customer, product, employee) must exist first.
|
||||||
|
|
||||||
|
## Company settings
|
||||||
|
|
||||||
|
**Menu:** Settings → Data → Company settings
|
||||||
|
|
||||||
|
This is a single form, not a list. Save:
|
||||||
|
|
||||||
|
| Field | Used for |
|
||||||
|
| --- | --- |
|
||||||
|
| Cycle start date | When weekly visit cycles start counting |
|
||||||
|
| Check-in radius (meters) | How close field staff should be when checking in |
|
||||||
|
| GPS interval (seconds) | How often the mobile app records a footprint while on duty |
|
||||||
|
| Checkout warning radius (meters) | When mobile warns that the user left a customer visit |
|
||||||
|
|
||||||
|
## Divisions, branches, customers, products
|
||||||
|
|
||||||
|
**Menu:** Settings → Data
|
||||||
|
|
||||||
|
Each of these is a list with Create, Detail, Edit, and Duplicate. Status is **Draft**, **Active**, or **Archived**.
|
||||||
|
|
||||||
|
| Record | Typical fields |
|
||||||
|
| --- | --- |
|
||||||
|
| Divisions | Name, code |
|
||||||
|
| Branches | Code, name, phone, NFC ID, address, map location, division, working days and hours |
|
||||||
|
| Customers | Code, name, phone, address, map location, NFC ID; contacts on create |
|
||||||
|
| Products | Code, name, unit, price, brand |
|
||||||
|
|
||||||
|
Pick a location on the map for branches and customers (or type latitude and longitude).
|
||||||
|
|
||||||
|
## Employees
|
||||||
|
|
||||||
|
Employees are split by purpose:
|
||||||
|
|
||||||
|
| Menu | Positions |
|
||||||
|
| --- | --- |
|
||||||
|
| Sales → Data → Employees | Sales |
|
||||||
|
| Logistics → Data → Employees | Driver, crew |
|
||||||
|
|
||||||
|
Fields: code, name, phone, position. Link a **user** to an employee later so mobile knows whether to load a sales or logistics plan.
|
||||||
|
|
||||||
|
## Privileges
|
||||||
|
|
||||||
|
<p class="doc-lead"><Shield :size="18" class="doc-icon" /> Settings → User → Privileges</p>
|
||||||
|
|
||||||
|
A privilege is a named access set. On the form, set **name**, **code**, and a permission matrix. For each area you can allow:
|
||||||
|
|
||||||
|
- **View** — show the menu and open the pages
|
||||||
|
- **Create** — create and duplicate
|
||||||
|
- **Update** — edit and change status
|
||||||
|
- **Delete** — delete
|
||||||
|
- **Import** — CSV import on supported lists
|
||||||
|
|
||||||
|
Without **View**, the sidebar hides that item.
|
||||||
|
|
||||||
|
## Users
|
||||||
|
|
||||||
|
<p class="doc-lead"><Users :size="18" class="doc-icon" /> Settings → User → Users</p>
|
||||||
|
|
||||||
|
1. Click **Create**.
|
||||||
|
2. Enter **username** and **password** (password is required on create; on edit you can leave it blank to keep the current one).
|
||||||
|
3. Choose a **privilege**.
|
||||||
|
4. Optionally link an **employee** so field login maps to sales or logistics.
|
||||||
|
|
||||||
|
Activate the user when they should be able to sign in.
|
||||||
|
|
||||||
|
## Coming soon
|
||||||
|
|
||||||
|
- **Remember me** on the web login form is not saved
|
||||||
|
- **Forgot password** is not available
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
<script setup>
|
||||||
|
import { MapPin } from 'lucide-vue-next'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
# Timeline
|
||||||
|
|
||||||
|
<p class="doc-lead"><MapPin :size="20" class="doc-icon" /> Timeline in the sidebar</p>
|
||||||
|
|
||||||
|
Timeline shows **one day's** recorded GPS footprints and field activities for **sales** employees. It is a playback of what the mobile app stored while the person was on duty, not a live feed.
|
||||||
|
|
||||||
|
## How to use it
|
||||||
|
|
||||||
|
1. Open **Timeline**.
|
||||||
|
2. Pick a **date**.
|
||||||
|
3. Optionally filter by **employee** (sales employees), or leave all employees.
|
||||||
|
4. Search activities if the list is long.
|
||||||
|
5. Switch tabs **On the way** and **Completed**.
|
||||||
|
6. Use **Playback** (play, pause, time) to move along the recorded path. The overlay **Current location** is the playback cursor, not a live GPS point.
|
||||||
|
|
||||||
|
If there is no data for that day, the map shows that there is no timeline data.
|
||||||
|
|
||||||
|
## What activities look like
|
||||||
|
|
||||||
|
The list can include:
|
||||||
|
|
||||||
|
- Branch check-in / check-out
|
||||||
|
- Customer check-in / check-out
|
||||||
|
- Sales order created
|
||||||
|
- Sales request created
|
||||||
|
- Sales payment created
|
||||||
|
- Customer created
|
||||||
|
|
||||||
|
Footprints are recorded on mobile after branch clock-in, using the **GPS interval** in [company settings](/user/web/setup).
|
||||||
|
|
||||||
|
## Coming soon
|
||||||
|
|
||||||
|
- **Live** tracking of sales or drivers on the web map
|
||||||
|
- A dedicated **logistics / driver** timeline (this screen loads sales employees)
|
||||||
Generated
+19
-18
@@ -54,6 +54,9 @@ importers:
|
|||||||
dayjs:
|
dayjs:
|
||||||
specifier: ^1.11.19
|
specifier: ^1.11.19
|
||||||
version: 1.11.19
|
version: 1.11.19
|
||||||
|
lucide-vue-next:
|
||||||
|
specifier: ^1.0.0
|
||||||
|
version: 1.0.0(vue@3.5.38)
|
||||||
react:
|
react:
|
||||||
specifier: ^19.2.3
|
specifier: ^19.2.3
|
||||||
version: 19.2.3
|
version: 19.2.3
|
||||||
@@ -73,6 +76,9 @@ importers:
|
|||||||
mermaid:
|
mermaid:
|
||||||
specifier: ^11.15.0
|
specifier: ^11.15.0
|
||||||
version: 11.15.0
|
version: 11.15.0
|
||||||
|
plantuml-encoder:
|
||||||
|
specifier: ^1.4.0
|
||||||
|
version: 1.4.0
|
||||||
typescript:
|
typescript:
|
||||||
specifier: 5.5.4
|
specifier: 5.5.4
|
||||||
version: 5.5.4
|
version: 5.5.4
|
||||||
@@ -1041,7 +1047,6 @@ packages:
|
|||||||
/@babel/helper-string-parser@7.29.7:
|
/@babel/helper-string-parser@7.29.7:
|
||||||
resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==}
|
resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
dev: true
|
|
||||||
|
|
||||||
/@babel/helper-validator-identifier@7.28.5:
|
/@babel/helper-validator-identifier@7.28.5:
|
||||||
resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==}
|
resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==}
|
||||||
@@ -1050,7 +1055,6 @@ packages:
|
|||||||
/@babel/helper-validator-identifier@7.29.7:
|
/@babel/helper-validator-identifier@7.29.7:
|
||||||
resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==}
|
resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
dev: true
|
|
||||||
|
|
||||||
/@babel/helper-validator-option@7.27.1:
|
/@babel/helper-validator-option@7.27.1:
|
||||||
resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==}
|
resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==}
|
||||||
@@ -1076,7 +1080,6 @@ packages:
|
|||||||
hasBin: true
|
hasBin: true
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/types': 7.29.7
|
'@babel/types': 7.29.7
|
||||||
dev: true
|
|
||||||
|
|
||||||
/@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.28.5):
|
/@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.28.5):
|
||||||
resolution: {integrity: sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==}
|
resolution: {integrity: sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==}
|
||||||
@@ -1147,7 +1150,6 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@babel/helper-string-parser': 7.29.7
|
'@babel/helper-string-parser': 7.29.7
|
||||||
'@babel/helper-validator-identifier': 7.29.7
|
'@babel/helper-validator-identifier': 7.29.7
|
||||||
dev: true
|
|
||||||
|
|
||||||
/@braintree/sanitize-url@6.0.4:
|
/@braintree/sanitize-url@6.0.4:
|
||||||
resolution: {integrity: sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==}
|
resolution: {integrity: sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==}
|
||||||
@@ -4791,14 +4793,12 @@ packages:
|
|||||||
entities: 7.0.1
|
entities: 7.0.1
|
||||||
estree-walker: 2.0.2
|
estree-walker: 2.0.2
|
||||||
source-map-js: 1.2.1
|
source-map-js: 1.2.1
|
||||||
dev: true
|
|
||||||
|
|
||||||
/@vue/compiler-dom@3.5.38:
|
/@vue/compiler-dom@3.5.38:
|
||||||
resolution: {integrity: sha512-JTqp25l8aFfJYF7/KmsXZjAxJz7T+SjmTJLoXVjHtc2BrSgSiW2n9Aem/cWq1OPe68A8JL06B3eVdhlP0H4TVw==}
|
resolution: {integrity: sha512-JTqp25l8aFfJYF7/KmsXZjAxJz7T+SjmTJLoXVjHtc2BrSgSiW2n9Aem/cWq1OPe68A8JL06B3eVdhlP0H4TVw==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@vue/compiler-core': 3.5.38
|
'@vue/compiler-core': 3.5.38
|
||||||
'@vue/shared': 3.5.38
|
'@vue/shared': 3.5.38
|
||||||
dev: true
|
|
||||||
|
|
||||||
/@vue/compiler-sfc@3.5.38:
|
/@vue/compiler-sfc@3.5.38:
|
||||||
resolution: {integrity: sha512-DuA2GiZawSEW442iw/9+Fkol8hTgb4Ke5KkhmSry65QA7YuyMbIdy8p0XZRMvNwJdgRz307W8g1CSzdvS4nuNg==}
|
resolution: {integrity: sha512-DuA2GiZawSEW442iw/9+Fkol8hTgb4Ke5KkhmSry65QA7YuyMbIdy8p0XZRMvNwJdgRz307W8g1CSzdvS4nuNg==}
|
||||||
@@ -4812,14 +4812,12 @@ packages:
|
|||||||
magic-string: 0.30.21
|
magic-string: 0.30.21
|
||||||
postcss: 8.5.15
|
postcss: 8.5.15
|
||||||
source-map-js: 1.2.1
|
source-map-js: 1.2.1
|
||||||
dev: true
|
|
||||||
|
|
||||||
/@vue/compiler-ssr@3.5.38:
|
/@vue/compiler-ssr@3.5.38:
|
||||||
resolution: {integrity: sha512-7s+W5Gc42FGxZMcuwl8H5B29T8BJPMdBT7KHFE+BbAuZ/iTEdTtv7z2XiMjiaUUw4w3ZcCEdHs36RuYJ2VA7bA==}
|
resolution: {integrity: sha512-7s+W5Gc42FGxZMcuwl8H5B29T8BJPMdBT7KHFE+BbAuZ/iTEdTtv7z2XiMjiaUUw4w3ZcCEdHs36RuYJ2VA7bA==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@vue/compiler-dom': 3.5.38
|
'@vue/compiler-dom': 3.5.38
|
||||||
'@vue/shared': 3.5.38
|
'@vue/shared': 3.5.38
|
||||||
dev: true
|
|
||||||
|
|
||||||
/@vue/devtools-api@7.7.9:
|
/@vue/devtools-api@7.7.9:
|
||||||
resolution: {integrity: sha512-kIE8wvwlcZ6TJTbNeU2HQNtaxLx3a84aotTITUuL/4bzfPxzajGBOoqjMhwZJ8L9qFYDU/lAYMEEm11dnZOD6g==}
|
resolution: {integrity: sha512-kIE8wvwlcZ6TJTbNeU2HQNtaxLx3a84aotTITUuL/4bzfPxzajGBOoqjMhwZJ8L9qFYDU/lAYMEEm11dnZOD6g==}
|
||||||
@@ -4849,14 +4847,12 @@ packages:
|
|||||||
resolution: {integrity: sha512-pG6LV/NDNRbKizcUjFFLAfjaL8mcv4DmR9avNcUw2gDHBzZneuS2TWCmp633ynzxz9YYKNeEPK2I8Wraqy2HUQ==}
|
resolution: {integrity: sha512-pG6LV/NDNRbKizcUjFFLAfjaL8mcv4DmR9avNcUw2gDHBzZneuS2TWCmp633ynzxz9YYKNeEPK2I8Wraqy2HUQ==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@vue/shared': 3.5.38
|
'@vue/shared': 3.5.38
|
||||||
dev: true
|
|
||||||
|
|
||||||
/@vue/runtime-core@3.5.38:
|
/@vue/runtime-core@3.5.38:
|
||||||
resolution: {integrity: sha512-iyW8WVfF1CpCXxncZY5Ei6rSd6oZr5DgEom//fUjRBRl56AXPD+s9ATvukRt77ZFTuYlnVA1bxY+dJB94tWVYw==}
|
resolution: {integrity: sha512-iyW8WVfF1CpCXxncZY5Ei6rSd6oZr5DgEom//fUjRBRl56AXPD+s9ATvukRt77ZFTuYlnVA1bxY+dJB94tWVYw==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@vue/reactivity': 3.5.38
|
'@vue/reactivity': 3.5.38
|
||||||
'@vue/shared': 3.5.38
|
'@vue/shared': 3.5.38
|
||||||
dev: true
|
|
||||||
|
|
||||||
/@vue/runtime-dom@3.5.38:
|
/@vue/runtime-dom@3.5.38:
|
||||||
resolution: {integrity: sha512-apX2wt9sdfDshS+a2xueFZLVpt0GkRJZSoPmrW/SA4yzXTznhfcMVW59gr7h4YQeY0vJhdJkk2rsIDwgfFgC5A==}
|
resolution: {integrity: sha512-apX2wt9sdfDshS+a2xueFZLVpt0GkRJZSoPmrW/SA4yzXTznhfcMVW59gr7h4YQeY0vJhdJkk2rsIDwgfFgC5A==}
|
||||||
@@ -4865,7 +4861,6 @@ packages:
|
|||||||
'@vue/runtime-core': 3.5.38
|
'@vue/runtime-core': 3.5.38
|
||||||
'@vue/shared': 3.5.38
|
'@vue/shared': 3.5.38
|
||||||
csstype: 3.2.3
|
csstype: 3.2.3
|
||||||
dev: true
|
|
||||||
|
|
||||||
/@vue/server-renderer@3.5.38(vue@3.5.38):
|
/@vue/server-renderer@3.5.38(vue@3.5.38):
|
||||||
resolution: {integrity: sha512-vue8vbf2QlV4quHqzwmJy6dWfmRhP1J8l4wtZg60CL6VoKqcPY2oe7may3+1d9qfpedjK5PRLFqd5k3Isj9mUw==}
|
resolution: {integrity: sha512-vue8vbf2QlV4quHqzwmJy6dWfmRhP1J8l4wtZg60CL6VoKqcPY2oe7may3+1d9qfpedjK5PRLFqd5k3Isj9mUw==}
|
||||||
@@ -4875,11 +4870,9 @@ packages:
|
|||||||
'@vue/compiler-ssr': 3.5.38
|
'@vue/compiler-ssr': 3.5.38
|
||||||
'@vue/shared': 3.5.38
|
'@vue/shared': 3.5.38
|
||||||
vue: 3.5.38(typescript@5.5.4)
|
vue: 3.5.38(typescript@5.5.4)
|
||||||
dev: true
|
|
||||||
|
|
||||||
/@vue/shared@3.5.38:
|
/@vue/shared@3.5.38:
|
||||||
resolution: {integrity: sha512-FTW0AFZNaK5/mOqvGBwVfUlNLU38TiQn4+DQgIFUnrBBJQ1crMJ82yeGQLV5jyKFsO8yRukpbuP7x+nRbH6aug==}
|
resolution: {integrity: sha512-FTW0AFZNaK5/mOqvGBwVfUlNLU38TiQn4+DQgIFUnrBBJQ1crMJ82yeGQLV5jyKFsO8yRukpbuP7x+nRbH6aug==}
|
||||||
dev: true
|
|
||||||
|
|
||||||
/@vueuse/core@12.8.2(typescript@5.5.4):
|
/@vueuse/core@12.8.2(typescript@5.5.4):
|
||||||
resolution: {integrity: sha512-HbvCmZdzAu3VGi/pWYm5Ut+Kd9mn1ZHnn4L5G8kOQTPs/IwIAmJoBrmYk2ckLArgMXZj0AW3n5CAejLUO+PhdQ==}
|
resolution: {integrity: sha512-HbvCmZdzAu3VGi/pWYm5Ut+Kd9mn1ZHnn4L5G8kOQTPs/IwIAmJoBrmYk2ckLArgMXZj0AW3n5CAejLUO+PhdQ==}
|
||||||
@@ -6733,7 +6726,6 @@ packages:
|
|||||||
/entities@7.0.1:
|
/entities@7.0.1:
|
||||||
resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==}
|
resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==}
|
||||||
engines: {node: '>=0.12'}
|
engines: {node: '>=0.12'}
|
||||||
dev: true
|
|
||||||
|
|
||||||
/env-paths@2.2.1:
|
/env-paths@2.2.1:
|
||||||
resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==}
|
resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==}
|
||||||
@@ -7442,7 +7434,6 @@ packages:
|
|||||||
|
|
||||||
/estree-walker@2.0.2:
|
/estree-walker@2.0.2:
|
||||||
resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
|
resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
|
||||||
dev: true
|
|
||||||
|
|
||||||
/estree-walker@3.0.3:
|
/estree-walker@3.0.3:
|
||||||
resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
|
resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
|
||||||
@@ -9007,6 +8998,15 @@ packages:
|
|||||||
react: 19.2.3
|
react: 19.2.3
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/lucide-vue-next@1.0.0(vue@3.5.38):
|
||||||
|
resolution: {integrity: sha512-V6SPvx1IHTj/UY+FrIYWV5faISsPSb8BnWSFDxAtezWKvWc9ZZ40PDrdu1/Qb5vg4lHWr1hs1BAMGVGm6V1Xdg==}
|
||||||
|
deprecated: Package deprecated. Please use @lucide/vue instead.
|
||||||
|
peerDependencies:
|
||||||
|
vue: '>=3.0.1'
|
||||||
|
dependencies:
|
||||||
|
vue: 3.5.38(typescript@5.5.4)
|
||||||
|
dev: false
|
||||||
|
|
||||||
/lz-string@1.5.0:
|
/lz-string@1.5.0:
|
||||||
resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==}
|
resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
@@ -9661,7 +9661,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==}
|
resolution: {integrity: sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==}
|
||||||
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
dev: true
|
|
||||||
|
|
||||||
/napi-postinstall@0.3.4:
|
/napi-postinstall@0.3.4:
|
||||||
resolution: {integrity: sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==}
|
resolution: {integrity: sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==}
|
||||||
@@ -10117,6 +10116,10 @@ packages:
|
|||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/plantuml-encoder@1.4.0:
|
||||||
|
resolution: {integrity: sha512-sxMwpDw/ySY1WB2CE3+IdMuEcWibJ72DDOsXLkSmEaSzwEUaYBT6DWgOfBiHGCux4q433X6+OEFWjlVqp7gL6g==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/playwright-core@1.62.1:
|
/playwright-core@1.62.1:
|
||||||
resolution: {integrity: sha512-wPYSwEBJY9GHraISXqyqtx0na0LpO3XEX7jNDhntbex7tzUS7kLnZsOlFruFJB4Hi/rhDMjXGqHewDZ68nYZVw==}
|
resolution: {integrity: sha512-wPYSwEBJY9GHraISXqyqtx0na0LpO3XEX7jNDhntbex7tzUS7kLnZsOlFruFJB4Hi/rhDMjXGqHewDZ68nYZVw==}
|
||||||
engines: {node: '>=20'}
|
engines: {node: '>=20'}
|
||||||
@@ -10170,7 +10173,6 @@ packages:
|
|||||||
nanoid: 3.3.15
|
nanoid: 3.3.15
|
||||||
picocolors: 1.1.1
|
picocolors: 1.1.1
|
||||||
source-map-js: 1.2.1
|
source-map-js: 1.2.1
|
||||||
dev: true
|
|
||||||
|
|
||||||
/postcss@8.5.3:
|
/postcss@8.5.3:
|
||||||
resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==}
|
resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==}
|
||||||
@@ -12718,7 +12720,6 @@ packages:
|
|||||||
'@vue/server-renderer': 3.5.38(vue@3.5.38)
|
'@vue/server-renderer': 3.5.38(vue@3.5.38)
|
||||||
'@vue/shared': 3.5.38
|
'@vue/shared': 3.5.38
|
||||||
typescript: 5.5.4
|
typescript: 5.5.4
|
||||||
dev: true
|
|
||||||
|
|
||||||
/vuvuzela@1.0.3:
|
/vuvuzela@1.0.3:
|
||||||
resolution: {integrity: sha512-Tm7jR1xTzBbPW+6y1tknKiEhz04Wf/1iZkcTJjSFcpNko43+dFW6+OOeQe9taJIug3NdfUAjFKgUSyQrIKaDvQ==}
|
resolution: {integrity: sha512-Tm7jR1xTzBbPW+6y1tknKiEhz04Wf/1iZkcTJjSFcpNko43+dFW6+OOeQe9taJIug3NdfUAjFKgUSyQrIKaDvQ==}
|
||||||
|
|||||||
Reference in New Issue
Block a user