tango-app-api-client 3.3.3-beta.1 → 3.3.3-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,43 +1,42 @@
1
- {
2
- "name": "tango-app-api-client",
3
- "version": "3.3.3-beta.1",
4
- "description": "client",
5
- "main": "index.js",
6
- "type": "module",
7
- "scripts": {
8
- "start": "nodemon --exec \"eslint --fix . && node index.js\""
9
- },
10
- "engines": {
11
- "node": ">=18.10.0"
12
- },
13
- "author": "praveenraj",
14
- "license": "ISC",
15
- "dependencies": {
16
- "aws-sdk": "^2.1560.0",
17
- "cors": "^2.8.5",
18
- "dotenv": "^16.4.4",
19
- "express": "^4.18.2",
20
- "express-fileupload": "^1.4.3",
21
- "handlebars": "^4.7.8",
22
- "i": "^0.3.7",
23
- "joi": "^17.12.1",
24
- "joi-to-swagger": "^6.2.0",
25
- "lodash": "^4.17.21",
26
- "mongodb": "^6.3.0",
27
- "nodemon": "^3.0.3",
28
- "npm": "^10.9.1",
29
- "swagger-ui-express": "^5.0.0",
30
- "tango-api-schema": "^2.1.92",
31
- "tango-app-api-middleware": "^3.1.43-alpha.10",
32
- "winston": "^3.11.0",
33
- "winston-daily-rotate-file": "^5.0.0"
34
- },
35
- "devDependencies": {
36
- "eslint": "^8.56.0",
37
- "eslint-config-google": "^0.14.0",
38
- "eslint-config-semistandard": "^17.0.0",
39
- "eslint-config-standard": "^17.1.0",
40
- "eslint-plugin-import": "^2.29.1",
41
- "eslint-plugin-promise": "^6.1.1"
42
- }
43
- }
1
+ {
2
+ "name": "tango-app-api-client",
3
+ "version": "3.3.3-beta.10",
4
+ "description": "client",
5
+ "main": "index.js",
6
+ "type": "module",
7
+ "scripts": {
8
+ "start": "nodemon --exec \"eslint --fix . && node index.js\""
9
+ },
10
+ "engines": {
11
+ "node": ">=18.10.0"
12
+ },
13
+ "author": "praveenraj",
14
+ "license": "ISC",
15
+ "dependencies": {
16
+ "aws-sdk": "^2.1560.0",
17
+ "cors": "^2.8.5",
18
+ "dotenv": "^16.4.4",
19
+ "express": "^4.18.2",
20
+ "express-fileupload": "^1.4.3",
21
+ "handlebars": "^4.7.8",
22
+ "joi": "^17.12.1",
23
+ "joi-to-swagger": "^6.2.0",
24
+ "lodash": "^4.17.21",
25
+ "mongodb": "^6.7.0",
26
+ "nodemon": "^3.0.3",
27
+ "npm": "^10.9.1",
28
+ "swagger-ui-express": "^5.0.0",
29
+ "tango-api-schema": "^2.2.59",
30
+ "tango-app-api-middleware": "^3.1.60",
31
+ "winston": "^3.11.0",
32
+ "winston-daily-rotate-file": "^5.0.0"
33
+ },
34
+ "devDependencies": {
35
+ "eslint": "^8.56.0",
36
+ "eslint-config-google": "^0.14.0",
37
+ "eslint-config-semistandard": "^17.0.0",
38
+ "eslint-config-standard": "^17.1.0",
39
+ "eslint-plugin-import": "^2.29.1",
40
+ "eslint-plugin-promise": "^6.1.1"
41
+ }
42
+ }
@@ -1,5 +1,5 @@
1
1
  import { billingDetailsUpdate, brandInfoUpdate, domainDetailsConfigurationUpdate, featureConfigurationUpdate, getClientData, signatoryDetailsUpdate, ticketConfigurationUpdate, documentsUpdate, getUserData, CsmUsersGet, OpsUsersGet, userConfigurationUpdate, findClient, aggregateClient, createAuditQueue, findOne, insert, update, findOneClient, updateOneClient } from '../service/client.service.js';
2
- import { checkFileExist, fileUpload, signedUrl, chunkArray, download, logger, getOpenSearchData, insertOpenSearchData, sendEmailWithSES, createCustomer, createVirtualAccount } from 'tango-app-api-middleware';
2
+ import { checkFileExist, fileUpload, signedUrl, chunkArray, download, logger, getOpenSearchData, insertOpenSearchData, sendEmailWithSES, createCustomer, createVirtualAccount, getUuid } from 'tango-app-api-middleware';
3
3
  import { countDocumentsUser, findOneAndUpdateUser, findOneUser, getUserNameEmailById, updateManyUser } from '../service/user.service.js';
4
4
  import { aggregateStore, countDocumentsStore, findStore, updateManyStore } from '../service/store.service.js';
5
5
  import { aggregateCamera, countDocumentsCamera } from '../service/camera.service.js';
@@ -37,7 +37,6 @@ export async function create( req, res ) {
37
37
  ];
38
38
  const ID = await aggregateClient( countQuery );
39
39
  const count = ID[0]?.tangoId || 0;
40
- logger.info( { count: count } );
41
40
  const query = { clientName: inputData.clientName };
42
41
  const leadRecord = await findOne( query );
43
42
  const tangoId = count + 1;
@@ -71,7 +70,6 @@ export async function create( req, res ) {
71
70
  'planDetails.product': product,
72
71
  'profileDetails.website': leadRecord?.websiteUrl,
73
72
  'reportConfigs.reportName': generatedName,
74
- 'auditConfigs.queueName': generatedName,
75
73
  'auditConfigs.zoneQueueName': `${generatedName}-zone`,
76
74
  'auditConfigs.trafficQueueName': `${generatedName}-traffic`,
77
75
  'auditConfigs.traxQueueName.unattendedCustomer': `${generatedName}-unattendedCustomer`,
@@ -79,6 +77,10 @@ export async function create( req, res ) {
79
77
  'auditConfigs.traxQueueName.uniformDetection': `${generatedName}-uniformDetection`,
80
78
  'auditConfigs.traxQueueName.mobileDetection': `${generatedName}-mobileDetection`,
81
79
  'auditConfigs.traxQueueName.cameraAngleChange': `${generatedName}-cameraAngleChange`,
80
+ 'auditConfigs.traxQueueName.hygiene': `${generatedName}-hygiene`,
81
+ 'clientApi.apiKey': await getUuid(),
82
+ 'clientApi.status': true,
83
+
82
84
  };
83
85
 
84
86
  record.featureConfigs = {};
@@ -330,7 +332,6 @@ export async function create( req, res ) {
330
332
  // await deleteOneAuthentication( { user: user?._id, type: 'retail' } );
331
333
  await findOneAndUpdateUser( userQuery, userRecord );
332
334
  await Promise.all( [
333
- createAuditQueue( generatedName ),
334
335
  createAuditQueue( `${generatedName}-zone` ),
335
336
  createAuditQueue( `${generatedName}-traffic` ),
336
337
  createAuditQueue( `${generatedName}-unattendedCustomer` ),
@@ -338,7 +339,7 @@ export async function create( req, res ) {
338
339
  createAuditQueue( `${generatedName}-uniformDetection` ),
339
340
  createAuditQueue( `${generatedName}-mobileDetection` ),
340
341
  createAuditQueue( `${generatedName}-cameraAngleChange` ),
341
- ] );
342
+ createAuditQueue( `${generatedName}-hygiene` ) ] );
342
343
  return res.sendSuccess( { result: { clientId: String( tangoId ) } } );
343
344
  }
344
345
  } catch ( error ) {
@@ -395,7 +396,7 @@ export async function changeStatus( req, res, next ) {
395
396
 
396
397
  export async function getClients( req, res ) {
397
398
  try {
398
- const field = { clientName: 1, clientId: 1 };
399
+ const field = { clientName: 1, clientId: 1, traxDateRange: '$featureConfigs.traxDateRange', trafficDateRange: '$featureConfigs.trafficDateRange' };
399
400
  let result = [];
400
401
  if ( req?.user?.role === 'superadmin' ) {
401
402
  result = await findClient( {}, field );
@@ -405,18 +406,6 @@ export async function getClients( req, res ) {
405
406
  $match: {
406
407
  userEmail: req?.user?.email,
407
408
  assignedType: { $eq: 'client' },
408
- // $expr: {
409
- // $cond: {
410
- // if: {
411
- // $and: [
412
- // { $eq: [ '$userType', 'tango' ] },
413
- // { $eq: [ '$tangoUserType', 'csm' ] },
414
- // ],
415
- // },
416
- // then: { $eq: [ '$isClientApproved', true ] },
417
- // else: true,
418
- // },
419
- // },
420
409
  },
421
410
  },
422
411
  {
@@ -450,9 +439,9 @@ export async function getClients( req, res ) {
450
439
  },
451
440
  {
452
441
  $project: {
453
- _id: 0,
454
442
  clientId: 1,
455
443
  clientName: 1,
444
+ traxDateRange: '$featureConfigs.traxDateRange',
456
445
  },
457
446
  },
458
447
  ];
@@ -889,6 +878,7 @@ export async function updateSignatoryDetails( req, res ) {
889
878
  export async function updateTicketConfiguration( req, res ) {
890
879
  try {
891
880
  const openSearch = JSON.parse( process.env.OPENSEARCH );
881
+ let findClient = await findOneClient({clientId:req.params?.id})
892
882
  const updateAck = await ticketConfigurationUpdate( {
893
883
  clientId: req.params?.id, MinFilesCount: req.body?.MinFilesCount, accuracyPercentage: req.body?.accuracyPercentage, downTimeType: req.body?.downTimeType,
894
884
  infraDownTime: req.body?.infraDownTime, installationReAssign: req.body?.installationReAssign, isRcaTicketAssign: req.body?.isRcaTicketAssign,
@@ -904,6 +894,7 @@ export async function updateTicketConfiguration( req, res ) {
904
894
  }
905
895
 
906
896
  const user = await getUserNameEmailById( req.userId );
897
+ let updatedClient = await findOneClient({clientId:req.params?.id})
907
898
 
908
899
  const logObj = {
909
900
  clientId: req.params?.id,
@@ -915,6 +906,8 @@ export async function updateTicketConfiguration( req, res ) {
915
906
  changes: updateKeys,
916
907
  eventType: 'update',
917
908
  showTo: [ 'tango' ],
909
+ current:updatedClient.ticketConfigs,
910
+ previous:findClient.ticketConfigs
918
911
  };
919
912
 
920
913
  if ( updateKeys.length ) {
@@ -2026,7 +2019,7 @@ export async function getActivityLogs( req, res ) {
2026
2019
  const query = {
2027
2020
  '_source': [
2028
2021
  'userId', 'userName', 'email', 'date', 'logType', 'logSubType',
2029
- 'changes', 'eventType',
2022
+ 'changes', 'eventType', 'previous', 'current',
2030
2023
  ],
2031
2024
  'query': {
2032
2025
  'bool': {
@@ -2083,9 +2076,24 @@ export async function getActivityLogs( req, res ) {
2083
2076
 
2084
2077
  const hits = logs?.body?.hits?.hits;
2085
2078
  const totalDocuments = logs?.body?.hits?.total?.value;
2079
+ let temp = [];
2086
2080
  if ( totalDocuments ) {
2087
- const dataArray = hits.map( ( hit ) => hit._source );
2088
- res.sendSuccess( { data: dataArray, count: totalDocuments } );
2081
+ hits.map( ( hit, i ) => {
2082
+ let respo ={};
2083
+
2084
+ if ( ( ( hit?._source?.eventType ).match( /update/ ) || ( hit?._source?.eventType ).match( /edit/ ) )&& hit?._source?.previous ) {
2085
+ const previous = hit?._source?.previous;
2086
+ const current=hit?._source?.current;
2087
+ const logType =hit?._source?.logType;
2088
+ respo = findDifferences( previous, current, logType );
2089
+ hit._source.updatedValue = respo;
2090
+ temp.push( hit?._source );
2091
+ } else {
2092
+ temp.push( hit?._source );
2093
+ }
2094
+ },
2095
+ );
2096
+ res.sendSuccess( { data: temp, count: totalDocuments } );
2089
2097
  } else {
2090
2098
  res.sendError( 'No data found', 204 );
2091
2099
  }
@@ -2096,6 +2104,112 @@ export async function getActivityLogs( req, res ) {
2096
2104
  }
2097
2105
 
2098
2106
 
2107
+ function findDifferences( previous, current, logType, path = '' ) {
2108
+ const dbKeys = JSON.parse( process.env.DB_KEYS );
2109
+ const ignoredKeys = new Set( [
2110
+ '_id', 'updatedAt', 'createdAt', 'password', 'clientId',
2111
+ 'storeId', 'refreshToken', 'employeeId', 'fcmToken', 'permission',
2112
+ ] );
2113
+
2114
+ // Get correct key mapping based on logType
2115
+ const keyMapping = dbKeys.DOCUMENTS[logType] || {};
2116
+
2117
+ let differences = {};
2118
+
2119
+ for ( const key in current ) {
2120
+ if ( !Object.prototype.hasOwnProperty.call( current, key ) || ignoredKeys.has( key ) ) continue;
2121
+
2122
+ const prevValue = previous[key];
2123
+ const currValue = current[key];
2124
+
2125
+ if ( typeof prevValue === 'object' && typeof currValue === 'object' && prevValue !== null && currValue !== null ) {
2126
+ const nestedDiffs = findDifferences( prevValue, currValue, logType, `${path}${key}.` );
2127
+ Object.assign( differences, nestedDiffs );
2128
+ } else if ( prevValue !== currValue ) {
2129
+ if (
2130
+ ( prevValue === '' && currValue === '' ) ||
2131
+ ( Array.isArray( prevValue ) && Array.isArray( currValue ) && prevValue.length === 0 && currValue.length === 0 )
2132
+ ) {
2133
+ continue;
2134
+ }
2135
+ differences[`${path}${key}`] = { previous: prevValue, current: currValue };
2136
+ }
2137
+ }
2138
+
2139
+ // **Transform & Filter Differences**
2140
+ let updatedDifferences = {};
2141
+ Object.keys( differences ).forEach( ( key ) => {
2142
+ let newKey = key.replace( /spocDetails\.\d+\./, 'spocDetails.' );
2143
+ let diff = differences[key];
2144
+
2145
+ if ( newKey.toLowerCase().includes( 'isactive' ) ) {
2146
+ diff = {
2147
+ previous: diff.previous ? 'Active' : 'Deactive',
2148
+ current: diff.current ? 'Active' : 'Deactive',
2149
+ };
2150
+ }
2151
+
2152
+ const userFriendlyKey = getUserFriendlyKey( newKey, keyMapping );
2153
+ if ( userFriendlyKey ) {
2154
+ newKey = userFriendlyKey;
2155
+ }
2156
+
2157
+ if ( newKey === 'Infra Email Alert' ) {
2158
+ diff.previous = diff.previous ? 'Enabled' : 'Disabled';
2159
+ diff.current = diff.current ? 'Enabled' : 'Disabled';
2160
+ }
2161
+
2162
+ // **Transform Roles Permission Keys**
2163
+ const rolesPermissionMatch = newKey.match( /rolespermission\.(\d+)\.modules\.(\d+)\.(isAdd|isEdit)/ );
2164
+ if ( rolesPermissionMatch ) {
2165
+ const [ , roleIndex, moduleIndex, action ] = rolesPermissionMatch;
2166
+ const role = previous.rolespermission?.[roleIndex];
2167
+ const module = role?.modules?.[moduleIndex];
2168
+
2169
+ if ( module ) {
2170
+ newKey = `User's ${module.name} Module ${action === 'isAdd' ? 'Add' : 'Edit'}`;
2171
+ diff.previous = diff.previous ? 'Enabled' : 'Disabled';
2172
+ diff.current = diff.current ? 'Enabled' : 'Disabled';
2173
+ }
2174
+ }
2175
+
2176
+ if ( !newKey || ( diff.previous === '' && !diff.current ) ) return;
2177
+
2178
+ if (
2179
+ ( diff.previous === '' || diff.previous === null || ( Array.isArray( diff.previous ) && diff.previous.length === 0 ) ) &&
2180
+ diff.current === undefined
2181
+ ) {
2182
+ return;
2183
+ }
2184
+ if (
2185
+ ( diff.current === '' || diff.current === null || ( Array.isArray( diff.current ) && diff.current.length === 0 ) ) &&
2186
+ diff.previous === undefined
2187
+ ) {
2188
+ return;
2189
+ }
2190
+
2191
+ updatedDifferences[newKey] = diff;
2192
+ } );
2193
+
2194
+ return updatedDifferences;
2195
+ }
2196
+
2197
+
2198
+ function getUserFriendlyKey( keyPath, mapping ) {
2199
+ const keys = keyPath.split( '.' ); // Split the key path (e.g., storeProfile.pincode → ['storeProfile', 'pincode'])
2200
+ let value = mapping;
2201
+
2202
+ for ( const key of keys ) {
2203
+ if ( value && typeof value === 'object' && key in value ) {
2204
+ value = value[key]; // Traverse down the object
2205
+ } else {
2206
+ return null; // Return original if not found
2207
+ }
2208
+ }
2209
+
2210
+ return typeof value === 'string' ? value : keyPath; // Return mapped value or original key
2211
+ }
2212
+
2099
2213
  async function postApi( url, data ) {
2100
2214
  const requestOptions = {
2101
2215
  method: 'POST',
@@ -121,6 +121,9 @@ export const featureConfigurationSchemaBody = joi.object(
121
121
  isNewZoneV2: joi.boolean().optional(),
122
122
  isTrax: joi.boolean().optional(),
123
123
  isControlCenter: joi.boolean().optional(),
124
+ isFootfallDirectoryAudit: joi.boolean().optional(),
125
+ isFootfallDirectoryLimit: joi.boolean().optional(),
126
+ streamBy: joi.string().optional(),
124
127
  },
125
128
  );
126
129
 
@@ -1,171 +1,171 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8">
5
- <meta http-equiv="x-ua-compatible" content="ie=edge">
6
- <title>Your account was approved!</title>
7
- <meta name="viewport" content="width=device-width, initial-scale=1">
8
- <style type="text/css">
9
- @media screen {
10
- @font-face {
11
- font-family: 'Inter';
12
- font-style: normal;
13
- font-weight: 400;
14
- font-display: swap;
15
- src: local("Inter"), local("Inter-Regular"), url(https://fonts.gstatic.com/s/inter/v12/UcCO3FwrK3iLTeHuS_fvQtMwCp50KnMw2boKoduKmMEVuLyfAZJhiI2B.woff2) format('woff2');
16
- unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
17
- }
18
- }
19
-
20
- body {
21
- font-family: "Inter", sans-serif !important;
22
- }
23
-
24
- body,
25
- table,
26
- td,
27
- a {
28
- -ms-text-size-adjust: 100%;
29
- -webkit-text-size-adjust: 100%;
30
- }
31
-
32
- table,
33
- td {
34
- mso-table-rspace: 0pt;
35
- mso-table-lspace: 0pt;
36
- }
37
-
38
- img {
39
- -ms-interpolation-mode: bicubic;
40
- }
41
-
42
- a[x-apple-data-detectors] {
43
- font-family: "inherit" !important;
44
- font-size: inherit !important;
45
- font-weight: inherit !important;
46
- line-height: inherit !important;
47
- color: inherit !important;
48
- text-decoration: none !important;
49
- }
50
-
51
- div[style*="margin: 16px 0;"] {
52
- margin: 0 !important;
53
- }
54
-
55
- body {
56
- width: 100% !important;
57
- height: 100% !important;
58
- padding: 0 !important;
59
- margin: 0 !important;
60
- }
61
-
62
- table {
63
- border-collapse: collapse !important;
64
- }
65
-
66
- a {
67
- color: #1a82e2;
68
- }
69
-
70
- img {
71
- height: auto;
72
- line-height: 100%;
73
- text-decoration: none;
74
- border: 0;
75
- outline: none;
76
- }
77
- </style>
78
- </head>
79
- <body style="background-color: #dbe5ea;">
80
- <div class="preheader" style="display: none; max-width: 0; max-height: 0; overflow: hidden; font-size: 1px; line-height: 1px; color: #fff; opacity: 0;"> Email Summary (Hidden) </div>
81
- <table border="0" cellpadding="0" cellspacing="0" width="100%" style="padding-left:10px;padding-right:10px">
82
- <tr>
83
- <td bgcolor="#dbe5ea" style="padding:32px 10px 0 10px">
84
- <table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 600px;" align="center">
85
- <tr>
86
- <td class="o_bg-white o_px-md o_py-md o_sans o_text" style="margin-top: 0px;margin-bottom: 0px;font-size: 16px;line-height: 24px;background-color: #ffffff;padding-left: 18px;padding-right: 24px;padding-top: 24px;padding-bottom: 24px;">
87
- <p style="margin-top: 0px;margin-bottom: 0px;">
88
- <a class="o_text-white" href="https://tangoeye.ai/" style="text-decoration: none;outline: none;color: #ffffff;">
89
- <img src={{logo}} width="200" height="100" alt="SimpleApp" style="-ms-interpolation-mode: bicubic;vertical-align: middle;border: 0;line-height: 100%;height: auto;outline: none;text-decoration: none;">
90
- </a>
91
- </p>
92
- </td>
93
- </tr>
94
- <tr>
95
- <td align="left" bgcolor="#ffffff" style="padding-left: 30px;padding-right: 24px; font-size: 14px; line-height: 24px;">
96
- <p class="o_heading o_mb-xxs" style="width: 544px;height: 0px;border: 1px solid #CBD5E1;flex: none;order: 1;flex-grow: 0;"></p>
97
- </td>
98
- </tr>
99
- </table>
100
- </td>
101
- </tr>
102
- <tr>
103
- <td align="center" bgcolor="#dbe5ea" style="padding:0 10px 0 10px">
104
- <table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 600px;">
105
- <tr>
106
- <td class="o_bg-white o_px-md o_py-xl o_xs-py-md" style="background-color: #ffffff;padding-left: 30px;padding-right: 24px;padding-top: 10px;padding-bottom: 10px;">
107
- <div class="o_col-6s o_sans o_text-md o_text-light o_center" style="margin-top: 0px;margin-bottom: 0px;font-size: 20px;line-height: 28px;color: #82899a;">
108
- <span class="o_heading o_text-dark o_mb-xxs" style="font-weight: 700;margin-top: 0px;margin-bottom: 4px;color: #242b3d;line-height: 39px;"> Your account was approved!</span>
109
- </div>
110
- </td>
111
- </tr>
112
- </table>
113
- </td>
114
- </tr>
115
- <tr>
116
- <td align="center" bgcolor="#dbe5ea" style="padding:0 10px 0 10px">
117
- <table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 600px;">
118
- <tr>
119
- <td align="left" bgcolor="#ffffff" style="padding-left: 30px;padding-right: 24px; font-size: 16px;padding-top:10px; line-height: 24px;font-weight:400;color:#384860">
120
- <p style="margin: 0;">As a verified user, you will be among the first to receive product updates, new feature announcements, enhanced security and personalised support.
121
- <br><br>
122
- Head over to the dashboard to finish your setup. </p>
123
- </td>
124
- </tr>
125
- </table>
126
- </td>
127
- </tr>
128
- <tr>
129
- <td align="center" bgcolor="#dbe5ea" style="padding:0 10px 0 10px">
130
- <table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 600px;">
131
- <tr>
132
- <td align="left" bgcolor="#fff" style="border-radius: 6px;padding:14px 30px">
133
- <a href={{url}} style="display: inline-block;padding: 10px 36px;font-size: 20px;color: #fff;text-decoration: none;border-radius: 6px;background-color: #00a3ff;"> Add Stores</a>
134
- </td>
135
- </tr>
136
- </table>
137
- </td>
138
- </tr>
139
- <tr>
140
- <td align="center" bgcolor="#dbe5ea" style="padding:0 10px 0 10px">
141
- <table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 600px;">
142
- <tr>
143
- <td align="left" bgcolor="#ffffff" style="padding-left: 30px;padding-right: 24px; font-size: 16px;padding-top:10px; line-height: 24px;font-weight:400;color:#384860">
144
- <p style="margin: 0;">Enjoy the full potential of Tango Traffic Module. If you have any questions or need assistance, our support team is here to help.
145
-
146
- <br><br>
147
-
148
- Happy exploring! </p>
149
- </td>
150
- </tr>
151
- </table>
152
- </td>
153
- </tr>
154
- <tr>
155
- <td align="center" bgcolor="#dbe5ea" style="padding:0 10px 32px 10px">
156
- <table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 600px;">
157
- <tr>
158
- <td class="o_bg-white o_px-md o_py-xl o_xs-py-md" style="background-color: #ffffff;padding-left: 30px;padding-right: 24px;padding-bottom:15px">
159
- <div class="o_col-6s o_sans o_text-md o_text-light o_center" style="margin-top: 0px;margin-bottom: 0px;font-size: 12px;color: #202B3C;font-style: normal;font-weight: 400;font-size: 12px;line-height: 150%;">
160
- <br>
161
- <p>If you'd rather not receive this kind of email, Don’t want any more emails from TangoEye?<u style="color:#00A3FF">Unsubscribe</u>.</p>
162
- <p> © Tango Eye. All rights reserved.</p>
163
- </div>
164
- </td>
165
- </tr>
166
- </table>
167
- </td>
168
- </tr>
169
- </table>
170
- </body>
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta http-equiv="x-ua-compatible" content="ie=edge">
6
+ <title>Your account was approved!</title>
7
+ <meta name="viewport" content="width=device-width, initial-scale=1">
8
+ <style type="text/css">
9
+ @media screen {
10
+ @font-face {
11
+ font-family: 'Inter';
12
+ font-style: normal;
13
+ font-weight: 400;
14
+ font-display: swap;
15
+ src: local("Inter"), local("Inter-Regular"), url(https://fonts.gstatic.com/s/inter/v12/UcCO3FwrK3iLTeHuS_fvQtMwCp50KnMw2boKoduKmMEVuLyfAZJhiI2B.woff2) format('woff2');
16
+ unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
17
+ }
18
+ }
19
+
20
+ body {
21
+ font-family: "Inter", sans-serif !important;
22
+ }
23
+
24
+ body,
25
+ table,
26
+ td,
27
+ a {
28
+ -ms-text-size-adjust: 100%;
29
+ -webkit-text-size-adjust: 100%;
30
+ }
31
+
32
+ table,
33
+ td {
34
+ mso-table-rspace: 0pt;
35
+ mso-table-lspace: 0pt;
36
+ }
37
+
38
+ img {
39
+ -ms-interpolation-mode: bicubic;
40
+ }
41
+
42
+ a[x-apple-data-detectors] {
43
+ font-family: "inherit" !important;
44
+ font-size: inherit !important;
45
+ font-weight: inherit !important;
46
+ line-height: inherit !important;
47
+ color: inherit !important;
48
+ text-decoration: none !important;
49
+ }
50
+
51
+ div[style*="margin: 16px 0;"] {
52
+ margin: 0 !important;
53
+ }
54
+
55
+ body {
56
+ width: 100% !important;
57
+ height: 100% !important;
58
+ padding: 0 !important;
59
+ margin: 0 !important;
60
+ }
61
+
62
+ table {
63
+ border-collapse: collapse !important;
64
+ }
65
+
66
+ a {
67
+ color: #1a82e2;
68
+ }
69
+
70
+ img {
71
+ height: auto;
72
+ line-height: 100%;
73
+ text-decoration: none;
74
+ border: 0;
75
+ outline: none;
76
+ }
77
+ </style>
78
+ </head>
79
+ <body style="background-color: #dbe5ea;">
80
+ <div class="preheader" style="display: none; max-width: 0; max-height: 0; overflow: hidden; font-size: 1px; line-height: 1px; color: #fff; opacity: 0;"> Email Summary (Hidden) </div>
81
+ <table border="0" cellpadding="0" cellspacing="0" width="100%" style="padding-left:10px;padding-right:10px">
82
+ <tr>
83
+ <td bgcolor="#dbe5ea" style="padding:32px 10px 0 10px">
84
+ <table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 600px;" align="center">
85
+ <tr>
86
+ <td class="o_bg-white o_px-md o_py-md o_sans o_text" style="margin-top: 0px;margin-bottom: 0px;font-size: 16px;line-height: 24px;background-color: #ffffff;padding-left: 18px;padding-right: 24px;padding-top: 24px;padding-bottom: 24px;">
87
+ <p style="margin-top: 0px;margin-bottom: 0px;">
88
+ <a class="o_text-white" href="https://tangoeye.ai/" style="text-decoration: none;outline: none;color: #ffffff;">
89
+ <img src={{logo}} width="200" height="100" alt="SimpleApp" style="-ms-interpolation-mode: bicubic;vertical-align: middle;border: 0;line-height: 100%;height: auto;outline: none;text-decoration: none;">
90
+ </a>
91
+ </p>
92
+ </td>
93
+ </tr>
94
+ <tr>
95
+ <td align="left" bgcolor="#ffffff" style="padding-left: 30px;padding-right: 24px; font-size: 14px; line-height: 24px;">
96
+ <p class="o_heading o_mb-xxs" style="width: 544px;height: 0px;border: 1px solid #CBD5E1;flex: none;order: 1;flex-grow: 0;"></p>
97
+ </td>
98
+ </tr>
99
+ </table>
100
+ </td>
101
+ </tr>
102
+ <tr>
103
+ <td align="center" bgcolor="#dbe5ea" style="padding:0 10px 0 10px">
104
+ <table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 600px;">
105
+ <tr>
106
+ <td class="o_bg-white o_px-md o_py-xl o_xs-py-md" style="background-color: #ffffff;padding-left: 30px;padding-right: 24px;padding-top: 10px;padding-bottom: 10px;">
107
+ <div class="o_col-6s o_sans o_text-md o_text-light o_center" style="margin-top: 0px;margin-bottom: 0px;font-size: 20px;line-height: 28px;color: #82899a;">
108
+ <span class="o_heading o_text-dark o_mb-xxs" style="font-weight: 700;margin-top: 0px;margin-bottom: 4px;color: #242b3d;line-height: 39px;"> Your account was approved!</span>
109
+ </div>
110
+ </td>
111
+ </tr>
112
+ </table>
113
+ </td>
114
+ </tr>
115
+ <tr>
116
+ <td align="center" bgcolor="#dbe5ea" style="padding:0 10px 0 10px">
117
+ <table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 600px;">
118
+ <tr>
119
+ <td align="left" bgcolor="#ffffff" style="padding-left: 30px;padding-right: 24px; font-size: 16px;padding-top:10px; line-height: 24px;font-weight:400;color:#384860">
120
+ <p style="margin: 0;">As a verified user, you will be among the first to receive product updates, new feature announcements, enhanced security and personalised support.
121
+ <br><br>
122
+ Head over to the dashboard to finish your setup. </p>
123
+ </td>
124
+ </tr>
125
+ </table>
126
+ </td>
127
+ </tr>
128
+ <tr>
129
+ <td align="center" bgcolor="#dbe5ea" style="padding:0 10px 0 10px">
130
+ <table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 600px;">
131
+ <tr>
132
+ <td align="left" bgcolor="#fff" style="border-radius: 6px;padding:14px 30px">
133
+ <a href={{url}} style="display: inline-block;padding: 10px 36px;font-size: 20px;color: #fff;text-decoration: none;border-radius: 6px;background-color: #00a3ff;"> Add Stores</a>
134
+ </td>
135
+ </tr>
136
+ </table>
137
+ </td>
138
+ </tr>
139
+ <tr>
140
+ <td align="center" bgcolor="#dbe5ea" style="padding:0 10px 0 10px">
141
+ <table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 600px;">
142
+ <tr>
143
+ <td align="left" bgcolor="#ffffff" style="padding-left: 30px;padding-right: 24px; font-size: 16px;padding-top:10px; line-height: 24px;font-weight:400;color:#384860">
144
+ <p style="margin: 0;">Enjoy the full potential of Tango Traffic Module. If you have any questions or need assistance, our support team is here to help.
145
+
146
+ <br><br>
147
+
148
+ Happy exploring! </p>
149
+ </td>
150
+ </tr>
151
+ </table>
152
+ </td>
153
+ </tr>
154
+ <tr>
155
+ <td align="center" bgcolor="#dbe5ea" style="padding:0 10px 32px 10px">
156
+ <table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 600px;">
157
+ <tr>
158
+ <td class="o_bg-white o_px-md o_py-xl o_xs-py-md" style="background-color: #ffffff;padding-left: 30px;padding-right: 24px;padding-bottom:15px">
159
+ <div class="o_col-6s o_sans o_text-md o_text-light o_center" style="margin-top: 0px;margin-bottom: 0px;font-size: 12px;color: #202B3C;font-style: normal;font-weight: 400;font-size: 12px;line-height: 150%;">
160
+ <br>
161
+ <p>If you'd rather not receive this kind of email, Don’t want any more emails from TangoEye?<u style="color:#00A3FF">Unsubscribe</u>.</p>
162
+ <p> © Tango Eye. All rights reserved.</p>
163
+ </div>
164
+ </td>
165
+ </tr>
166
+ </table>
167
+ </td>
168
+ </tr>
169
+ </table>
170
+ </body>
171
171
  </html> `
@@ -161,6 +161,9 @@ export function featureConfigurationUpdate( query, inputData ) {
161
161
  'featureConfigs.isNewZoneV2': inputData?.isNewZoneV2,
162
162
  'featureConfigs.isTrax': inputData?.isTrax,
163
163
  'featureConfigs.isControlCenter': inputData?.isControlCenter,
164
+ 'featureConfigs.isFootfallDirectoryAudit': inputData?.isFootfallDirectoryAudit,
165
+ 'featureConfigs.isFootfallDirectoryLimit': inputData?.isFootfallDirectoryLimit,
166
+ 'featureConfigs.streamBy': inputData?.streamBy,
164
167
  },
165
168
  } );
166
169
  }