upates on the toast and createorder and allthose things

This commit is contained in:
2026-09-25 16:02:57 +05:30
parent 3e7aaf1e25
commit f86e4b853b
16 changed files with 1274 additions and 133 deletions

View File

@@ -189,6 +189,9 @@ export const executeCreateCustomer = async (payload) => {
return {
ok: false,
status,
// The server's own reason, unformatted, for callers that word the
// message themselves (the home page's plain-language toasts).
serverMessage,
message,
sourceCalls: [
{

View File

@@ -0,0 +1,168 @@
// ==============================|| MileTruth — greetings & "what can you do?" ||============================== //
//
// "good afternoon" used to reach the intent router, match nothing, and get
// "I could not answer that from live data" — the first thing a new user typed
// was answered with a failure. This module answers it instead: a greeting back,
// then what the assistant can actually do, with examples that run when clicked.
//
// Deliberately narrow. A greeting only counts when it is the WHOLE message, or
// the opening of one ("hi, how many orders today?") — then the greeting is
// stripped and the question is answered normally. Nothing here touches data.
//
// Keep CAPABILITIES honest: list only what the home page really does. Every
// example is sent as a real question when clicked, so a wrong one fails in
// front of the user.
const GREETING_RE =
/^\s*(?:(good\s*(?:morning|afternoon|evening|night|day))|(hi+|hello+|hey+|hiya|howdy|yo|namaste|vanakkam|greetings|gm|ge|ga))\b[\s,!.]*(?:(?:there|team|all|everyone|miletruth|mile\s*truth|ai|bot|assistant|buddy|friend|sir|madam)\b[\s,!.]*)?/i;
// ---- "What can you do?" -------------------------------------------------------
//
// Recognised by MEANING, not by an exact sentence. The first version listed
// fixed phrasings, and "what are things you can do ?" — an ordinary way to
// ask — wasn't one of them, so it got "Sorry, I didn't understand". People
// word this question a hundred ways; the rules below look for its shape:
// a question about YOU (the assistant) and what it does / offers / knows.
//
// Two guards keep real questions out:
// • DOMAIN words (orders, riders, hubs, revenue …) mean it's an operations
// question — "what can you tell me about orders today" goes to the router.
// • Long messages (> 14 words) are never treated as small talk.
const DOMAIN_RE =
/\b(?:orders?|bookings?|deliver(?:y|ies)|riders?|milers?|drivers?|hubs?|vehicles?|fleet|revenue|sales|profit|pricing|price|consignments?|parcels?|exceptions?|tripsheets?|customers?|clients?|tenants?|dispatch|batch|pincode|today|yesterday|week|month|dm-[a-z0-9-]+|\d{4,})\b/i;
// Exact short commands that mean "show me the menu".
const MENU_RE =
/^(?:help|help\s+me|menu|options|features|capabilities|commands|guide|start|get\s+started|how\s+are\s+you(?:\s+doing)?|what'?s\s+up|sup|what\s+now|now\s+what|anything\s+else|what\s+else)$/;
const CAPABILITY_PATTERNS = [
// what (are the / all / kind of) things can you do · what do you do · what else can u help with
/\b(?:what|wat|wht|which)\b.*\b(?:you|u|ya)\b.*\b(?:do|does|help|offer|handle|support|manage|provide|know|able)\b/,
// what can I (ask / do / use) · what should I ask · what questions can I ask
/\b(?:what|wat|which|how)\b.*\b(?:can|could|should|do)\b.*\b(?:i|we)\b.*\b(?:ask|do|use|say|type|try)\b/,
// can you help me · can you do anything · are you able to help
/^(?:can|could|will|would|are)\s+(?:you|u)\b.*\b(?:help|do|assist|able)\b/,
// your features / abilities / skills / functions / commands
/\b(?:your|ur)\b.*\b(?:features?|capabilit(?:y|ies)|abilit(?:y|ies)|skills?|functions?|commands?|uses?|job|purpose|role)\b/,
// list / show / tell me (all) your features · show me what you can do
/\b(?:list|show|tell|explain|give)\b.*\b(?:features?|capabilit(?:y|ies)|abilit(?:y|ies)|skills?|functions?|commands?|what\s+(?:you|u)\s+(?:can|do))\b/,
// who / what are you · what is this (ai / bot / tool / thing / page) · what is miletruth
/\bwho\b.*\b(?:are|r)\b.*\b(?:you|u)\b/,
/\bwhat\b.*\b(?:is|are|'s)\b.*\b(?:you|u|this|miletruth|mile\s*truth)\b/,
// how does this work · how do I use this / you · how to use · how to start
/\bhow\b.*\b(?:does|do|to|can)\b.*\b(?:work|use|start|begin|get\s+started)\b/,
// why should I use you · what are you for · what are you good at
/\b(?:good\s+at|for\s+what|what\s+for|used\s+for)\b/
];
const normalize = (text) =>
String(text || '')
.toLowerCase()
.replace(/[’`]/g, "'")
.replace(/[^a-z0-9' -]+/g, ' ')
.replace(/\s+/g, ' ')
.trim();
export const isCapabilitiesQuestion = (text) => {
const t = normalize(text);
if (!t) return false;
if (MENU_RE.test(t)) return true;
if (t.split(' ').length > 14) return false;
if (DOMAIN_RE.test(t)) return false;
return CAPABILITY_PATTERNS.some((re) => re.test(t));
};
// Short courtesies with no question in them — answered with a short reply, not
// the full capability list.
const THANKS_RE = /^\s*(?:thanks?|thank\s+you|thx|ty|ok(?:ay)?|cool|great|nice|super|awesome|got\s+it)\b[\s!.]*(?:(?:so\s+much|a\s+lot|miletruth|mile\s*truth)\b[\s!.]*)?$/i;
const clockGreeting = (now) => {
const h = now.getHours();
if (h < 12) return 'Good morning';
if (h < 17) return 'Good afternoon';
return 'Good evening';
};
/**
* Splits a leading greeting off a message.
* Returns { greeting, rest } — greeting is the phrase to answer with (null
* when there wasn't one), rest is whatever followed it, trimmed.
*/
export const splitGreeting = (text, now = new Date()) => {
const raw = String(text || '');
const m = raw.match(GREETING_RE);
if (!m) return { greeting: null, rest: raw.trim() };
// Mirror the greeting the user chose ("good afternoon" → "Good afternoon",
// "gm" → "Good morning"); answer a plain hi/hello by the clock.
const ABBREVIATIONS = { gm: 'morning', ga: 'afternoon', ge: 'evening' };
const part = m[1]
? m[1].replace(/^good\s*/i, '').toLowerCase()
: ABBREVIATIONS[String(m[2] || '').toLowerCase()];
const greeting = part ? `Good ${part}` : clockGreeting(now);
return { greeting, rest: raw.slice(m[0].length).trim() };
};
export const isThanks = (text) => THANKS_RE.test(String(text || ''));
/** What the home page does, grouped, each with examples that run on click. */
export const CAPABILITIES = [
{
title: 'Create & book',
description: 'I collect the details step by step, and nothing is saved until you press confirm.',
examples: ['Create a new order', 'Create a new customer', 'Assign a rider to an order', "Repeat yesterday's orders"]
},
{
title: 'Orders & deliveries',
description: 'Live counts, trends and status from the order board.',
examples: ['How many orders today?', 'Which orders are delayed?', 'Orders today vs yesterday']
},
{
title: 'Riders & fleet',
description: 'Who is working, which vehicles are free, and how each hub is doing.',
examples: ['How many riders are active?', 'How many vehicles are available?', 'Current hub status']
},
{
title: 'Money & reports',
description: 'Revenue, consignments and exceptions that need attention.',
examples: ['Total revenue today', 'How many consignments do we have?', 'Show open exceptions']
}
];
/**
* Answers a greeting / capability / thanks message, or returns null when the
* message is something else (the caller then routes it normally, using
* `rest` so the greeting doesn't confuse the router).
*
* Returns { kind, title, summary, capabilities?, rest }.
*/
export const answerSmallTalk = (text, { name = '', now = new Date() } = {}) => {
const { greeting, rest } = splitGreeting(text, now);
const who = String(name || '').trim().split(/\s+/)[0];
const hello = greeting ? `${greeting}${who ? `, ${who}` : ''}!` : '';
const intro =
'I’m MileTruth, your Doormile operations assistant. I read live data from the console to answer questions, and I can create orders and customers for you — always showing you exactly what will be saved before anything is sent.';
if (!rest || isCapabilitiesQuestion(rest)) {
return {
kind: greeting && !rest ? 'greeting' : 'capabilities',
title: hello ? `${hello} Here’s what I can do for you.` : 'Here’s what I can do for you.',
summary: `${intro} Click any example below to try it, or just type your question.`,
capabilities: CAPABILITIES,
rest: ''
};
}
if (isThanks(rest)) {
return {
kind: 'thanks',
title: 'You’re welcome! Anything else I can help with?',
summary: 'Ask about orders, riders, hubs or revenue — or say “what can you do?” to see everything.',
rest: ''
};
}
// A greeting in front of a real question: let the question through.
return greeting ? { kind: 'passthrough', greeting: hello, rest } : null;
};