|
427 | 427 | </template> |
428 | 428 | </Column> |
429 | 429 |
|
| 430 | + <Column |
| 431 | + v-if="visibleColumns.includes('temperature')" |
| 432 | + field="temperature" |
| 433 | + data-type="numeric" |
| 434 | + sortable |
| 435 | + :show-filter-operator="false" |
| 436 | + :show-add-button="false" |
| 437 | + > |
| 438 | + <template #header> |
| 439 | + <div v-tooltip.top="t('temperature_definition')"> |
| 440 | + {{ t('temperature') }} |
| 441 | + </div> |
| 442 | + </template> |
| 443 | + <template #filter="{ filterModel }"> |
| 444 | + <InputNumber v-model="filterModel.value" /> |
| 445 | + </template> |
| 446 | + <template #body="{ data }"> |
| 447 | + <div |
| 448 | + v-if="data.temperature" |
| 449 | + class="flex items-center justify-center gap-3" |
| 450 | + > |
| 451 | + <div |
| 452 | + :style="getHeatColorStyle(data.temperature)" |
| 453 | + class="w-8 h-8 rounded-full text-xs font-bold text-white" |
| 454 | + > |
| 455 | + <span class="flex items-center justify-center w-full h-full"> |
| 456 | + {{ data.temperature }} |
| 457 | + </span> |
| 458 | + </div> |
| 459 | + </div> |
| 460 | + </template> |
| 461 | + </Column> |
| 462 | + |
430 | 463 | <!-- Tags --> |
431 | 464 | <Column |
432 | 465 | v-if="visibleColumns.includes('tags')" |
@@ -1054,6 +1087,7 @@ const visibleColumnsOptions = [ |
1054 | 1087 | { label: t('occurrence'), value: 'occurrence' }, |
1055 | 1088 | { label: t('recency'), value: 'recency' }, |
1056 | 1089 | { label: t('replies'), value: 'replied_conversations' }, |
| 1090 | + { label: t('temperature'), value: 'temperature' }, |
1057 | 1091 | { label: t('tags'), value: 'tags' }, |
1058 | 1092 | { label: t('reachable'), value: 'status' }, |
1059 | 1093 | { label: t('recipient'), value: 'recipient' }, |
@@ -1158,10 +1192,9 @@ onNuxtReady(async () => { |
1158 | 1192 | 'same_as', |
1159 | 1193 | 'telephone', |
1160 | 1194 | 'image', |
1161 | | - ...($screenStore.width > 550 ? ['occurrence'] : []), |
1162 | | - ...($screenStore.width > 700 ? ['recency'] : []), |
1163 | | - ...($screenStore.width > 800 ? ['tags'] : []), |
1164 | | - ...($screenStore.width > 950 ? ['status'] : []), |
| 1195 | + 'temperature', |
| 1196 | + ...($screenStore.width > 550 ? ['tags'] : []), |
| 1197 | + ...($screenStore.width > 700 ? ['status'] : []), |
1165 | 1198 | ]; |
1166 | 1199 |
|
1167 | 1200 | await $contactsStore.reloadContacts(); |
@@ -1189,6 +1222,32 @@ onUnmounted(() => { |
1189 | 1222 | $contactsStore.$reset(); |
1190 | 1223 | scrollHeightObserver.value?.disconnect(); |
1191 | 1224 | }); |
| 1225 | +
|
| 1226 | +const getHeatColorStyle = (temp: number | null) => { |
| 1227 | + if (temp === null) return { backgroundColor: '#9ca3af' }; |
| 1228 | +
|
| 1229 | + const normalizedTemperature = Math.min(Math.max(temp / 100, 0), 1); |
| 1230 | +
|
| 1231 | + if (normalizedTemperature < 0.3) { |
| 1232 | + // Cool blues |
| 1233 | + const temperatureRatio = normalizedTemperature / 0.3; |
| 1234 | + return { |
| 1235 | + backgroundColor: `hsl(${220 - temperatureRatio * 20}, 95%, ${55 - temperatureRatio * 10}%)`, |
| 1236 | + }; |
| 1237 | + } else if (normalizedTemperature < 0.7) { |
| 1238 | + // Warm oranges/ambers - skipping green |
| 1239 | + const temperatureRatio = (normalizedTemperature - 0.3) / 0.4; |
| 1240 | + return { |
| 1241 | + backgroundColor: `hsl(${40 - temperatureRatio * 20}, 95%, ${50 - temperatureRatio * 5}%)`, |
| 1242 | + }; |
| 1243 | + } else { |
| 1244 | + // Hot reds |
| 1245 | + const temperatureRatio = (normalizedTemperature - 0.7) / 0.3; |
| 1246 | + return { |
| 1247 | + backgroundColor: `hsl(${20 - temperatureRatio * 20}, 95%, ${45 - temperatureRatio * 10}%)`, |
| 1248 | + }; |
| 1249 | + } |
| 1250 | +}; |
1192 | 1251 | </script> |
1193 | 1252 |
|
1194 | 1253 | <style> |
@@ -1256,6 +1315,8 @@ table.p-datatable-table { |
1256 | 1315 | "source": "Source", |
1257 | 1316 | "occurrence_definition": "Total occurrences of this contact", |
1258 | 1317 | "occurrence": "Occurrence", |
| 1318 | + "temperature_definition": "The hotter, the more replies, recent activity, and engagement — and a higher chance of future replies.", |
| 1319 | + "temperature": "Temperature", |
1259 | 1320 | "recency": "Recency", |
1260 | 1321 | "recency_definition": "When was the last time this contact was seen", |
1261 | 1322 | "replies_definition": "How many times this contact replied", |
@@ -1308,6 +1369,8 @@ table.p-datatable-table { |
1308 | 1369 | "source": "Source", |
1309 | 1370 | "occurence_definition": "Occurrences totales de ce contact", |
1310 | 1371 | "occurrence": "Occurrence", |
| 1372 | + "temperature_definition": "Plus la température est élevée, plus il y a de réponses, d'activité récente et d'engagement, et plus les chances d'obtenir des réponses futures sont élevées.", |
| 1373 | + "temperature": "Temperature", |
1311 | 1374 | "recency": "Récence", |
1312 | 1375 | "recency_definition": "Dernière fois que ce contact a été vu", |
1313 | 1376 | "replies_definition": "Nombre de réponses de ce contact", |
|
0 commit comments