diff --git a/backend/migrations/20250619000001-add-recurring-parent-id.js b/backend/migrations/20250619000001-add-recurring-parent-id.js
index 419e6ed..c592739 100644
--- a/backend/migrations/20250619000001-add-recurring-parent-id.js
+++ b/backend/migrations/20250619000001-add-recurring-parent-id.js
@@ -47,4 +47,4 @@ module.exports = {
await queryInterface.removeIndex('tasks', ['recurring_parent_id']);
await queryInterface.removeColumn('tasks', 'recurring_parent_id');
},
-};
\ No newline at end of file
+};
diff --git a/backend/migrations/20250619000002-add-project-image-url.js b/backend/migrations/20250619000002-add-project-image-url.js
index 35270d6..0150e36 100644
--- a/backend/migrations/20250619000002-add-project-image-url.js
+++ b/backend/migrations/20250619000002-add-project-image-url.js
@@ -18,4 +18,4 @@ module.exports = {
down: async (queryInterface, Sequelize) => {
await queryInterface.removeColumn('projects', 'image_url');
},
-};
\ No newline at end of file
+};
diff --git a/backend/migrations/20250620000001-add-task-intelligence-enabled.js b/backend/migrations/20250620000001-add-task-intelligence-enabled.js
index 2e49d8d..7bfab68 100644
--- a/backend/migrations/20250620000001-add-task-intelligence-enabled.js
+++ b/backend/migrations/20250620000001-add-task-intelligence-enabled.js
@@ -19,4 +19,4 @@ module.exports = {
down: async (queryInterface, Sequelize) => {
await queryInterface.removeColumn('users', 'task_intelligence_enabled');
},
-};
\ No newline at end of file
+};
diff --git a/backend/migrations/20250620000002-add-auto-suggest-next-actions-enabled.js b/backend/migrations/20250620000002-add-auto-suggest-next-actions-enabled.js
index b8bc796..2539f0a 100644
--- a/backend/migrations/20250620000002-add-auto-suggest-next-actions-enabled.js
+++ b/backend/migrations/20250620000002-add-auto-suggest-next-actions-enabled.js
@@ -22,4 +22,4 @@ module.exports = {
'auto_suggest_next_actions_enabled'
);
},
-};
\ No newline at end of file
+};
diff --git a/backend/migrations/20250621221841-add-completed-at-to-tasks.js b/backend/migrations/20250621221841-add-completed-at-to-tasks.js
index c9b751b..6de0df0 100644
--- a/backend/migrations/20250621221841-add-completed-at-to-tasks.js
+++ b/backend/migrations/20250621221841-add-completed-at-to-tasks.js
@@ -21,4 +21,4 @@ module.exports = {
await queryInterface.removeIndex('tasks', ['completed_at']);
await queryInterface.removeColumn('tasks', 'completed_at');
},
-};
\ No newline at end of file
+};
diff --git a/backend/migrations/20250621223000-create-calendar-tokens.js b/backend/migrations/20250621223000-create-calendar-tokens.js
index 836bd3f..f3dfcf7 100644
--- a/backend/migrations/20250621223000-create-calendar-tokens.js
+++ b/backend/migrations/20250621223000-create-calendar-tokens.js
@@ -75,4 +75,4 @@ module.exports = {
down: async (queryInterface, Sequelize) => {
await queryInterface.dropTable('calendar_tokens');
},
-};
\ No newline at end of file
+};
diff --git a/backend/migrations/20250622000001-create-task-events.js b/backend/migrations/20250622000001-create-task-events.js
index 0d03f1d..daf06b2 100644
--- a/backend/migrations/20250622000001-create-task-events.js
+++ b/backend/migrations/20250622000001-create-task-events.js
@@ -62,13 +62,25 @@ module.exports = {
await safeAddIndex(queryInterface, 'task_events', ['user_id']);
await safeAddIndex(queryInterface, 'task_events', ['event_type']);
await safeAddIndex(queryInterface, 'task_events', ['created_at']);
- await safeAddIndex(queryInterface, 'task_events', ['task_id', 'event_type']);
- await safeAddIndex(queryInterface, 'task_events', ['task_id', 'created_at']);
+ await safeAddIndex(queryInterface, 'task_events', [
+ 'task_id',
+ 'event_type',
+ ]);
+ await safeAddIndex(queryInterface, 'task_events', [
+ 'task_id',
+ 'created_at',
+ ]);
},
async down(queryInterface, Sequelize) {
- await queryInterface.removeIndex('task_events', ['task_id', 'created_at']);
- await queryInterface.removeIndex('task_events', ['task_id', 'event_type']);
+ await queryInterface.removeIndex('task_events', [
+ 'task_id',
+ 'created_at',
+ ]);
+ await queryInterface.removeIndex('task_events', [
+ 'task_id',
+ 'event_type',
+ ]);
await queryInterface.removeIndex('task_events', ['created_at']);
await queryInterface.removeIndex('task_events', ['event_type']);
await queryInterface.removeIndex('task_events', ['user_id']);
@@ -76,4 +88,4 @@ module.exports = {
await queryInterface.dropTable('task_events');
},
-};
\ No newline at end of file
+};
diff --git a/backend/migrations/20250622053925-add-pomodoro-enabled-to-users.js b/backend/migrations/20250622053925-add-pomodoro-enabled-to-users.js
index c426d1e..6e095d9 100644
--- a/backend/migrations/20250622053925-add-pomodoro-enabled-to-users.js
+++ b/backend/migrations/20250622053925-add-pomodoro-enabled-to-users.js
@@ -19,4 +19,4 @@ module.exports = {
async down(queryInterface, Sequelize) {
await queryInterface.removeColumn('users', 'pomodoro_enabled');
},
-};
\ No newline at end of file
+};
diff --git a/backend/migrations/20250623000001-add-uuid-to-tasks.js b/backend/migrations/20250623000001-add-uuid-to-tasks.js
index 15f94ea..45bd7dd 100644
--- a/backend/migrations/20250623000001-add-uuid-to-tasks.js
+++ b/backend/migrations/20250623000001-add-uuid-to-tasks.js
@@ -5,7 +5,6 @@ const { safeAddColumns, safeAddIndex } = require('../utils/migration-utils');
module.exports = {
async up(queryInterface, Sequelize) {
-
await safeAddColumns(queryInterface, 'tasks', [
{
name: 'uuid',
@@ -36,7 +35,6 @@ module.exports = {
},
async down(queryInterface, Sequelize) {
-
await queryInterface.removeIndex('tasks', 'tasks_uuid_unique');
await queryInterface.removeColumn('tasks', 'uuid');
diff --git a/backend/migrations/20250623000003-create-notes-tags-table.js b/backend/migrations/20250623000003-create-notes-tags-table.js
index 5639e62..de7ffc6 100644
--- a/backend/migrations/20250623000003-create-notes-tags-table.js
+++ b/backend/migrations/20250623000003-create-notes-tags-table.js
@@ -2,7 +2,6 @@
module.exports = {
async up(queryInterface, Sequelize) {
-
const tables = await queryInterface.showAllTables();
if (!tables.includes('notes_tags')) {
await queryInterface.createTable('notes_tags', {
diff --git a/backend/migrations/20250623000004-add-timestamps-to-notes-tags.js b/backend/migrations/20250623000004-add-timestamps-to-notes-tags.js
index 038ee79..6810b0e 100644
--- a/backend/migrations/20250623000004-add-timestamps-to-notes-tags.js
+++ b/backend/migrations/20250623000004-add-timestamps-to-notes-tags.js
@@ -28,4 +28,4 @@ module.exports = {
await queryInterface.removeColumn('notes_tags', 'created_at');
await queryInterface.removeColumn('notes_tags', 'updated_at');
},
-};
\ No newline at end of file
+};
diff --git a/backend/migrations/20250623000005-add-timestamps-to-projects-tags.js b/backend/migrations/20250623000005-add-timestamps-to-projects-tags.js
index 6ab3f90..ec85c82 100644
--- a/backend/migrations/20250623000005-add-timestamps-to-projects-tags.js
+++ b/backend/migrations/20250623000005-add-timestamps-to-projects-tags.js
@@ -4,7 +4,6 @@ const { safeCreateTable, safeAddColumns } = require('../utils/migration-utils');
module.exports = {
async up(queryInterface, Sequelize) {
-
const tableExists = await queryInterface
.showAllTables()
.then((tables) => tables.includes('projects_tags'));
@@ -49,7 +48,6 @@ module.exports = {
name: 'projects_tags_pkey',
});
} else {
-
await safeAddColumns(queryInterface, 'projects_tags', [
{
name: 'created_at',
@@ -72,12 +70,9 @@ module.exports = {
},
async down(queryInterface, Sequelize) {
-
try {
await queryInterface.removeColumn('projects_tags', 'created_at');
await queryInterface.removeColumn('projects_tags', 'updated_at');
- } catch (error) {
-
- }
+ } catch (error) {}
},
-};
\ No newline at end of file
+};
diff --git a/backend/migrations/20250711000001-add-suggestion-metadata-to-inbox-items.js b/backend/migrations/20250711000001-add-suggestion-metadata-to-inbox-items.js
index f0fd6de..ec3f2e6 100644
--- a/backend/migrations/20250711000001-add-suggestion-metadata-to-inbox-items.js
+++ b/backend/migrations/20250711000001-add-suggestion-metadata-to-inbox-items.js
@@ -10,7 +10,7 @@ module.exports = {
definition: {
type: Sequelize.STRING,
allowNull: true,
- comment: 'AI suggested item type: task, note, or null'
+ comment: 'AI suggested item type: task, note, or null',
},
},
{
@@ -18,7 +18,8 @@ module.exports = {
definition: {
type: Sequelize.STRING,
allowNull: true,
- comment: 'Reason for suggestion: verb_detected, bookmark_tag, etc.'
+ comment:
+ 'Reason for suggestion: verb_detected, bookmark_tag, etc.',
},
},
{
@@ -26,7 +27,7 @@ module.exports = {
definition: {
type: Sequelize.JSON,
allowNull: true,
- comment: 'Array of parsed hashtags from content'
+ comment: 'Array of parsed hashtags from content',
},
},
{
@@ -34,7 +35,7 @@ module.exports = {
definition: {
type: Sequelize.JSON,
allowNull: true,
- comment: 'Array of parsed project references from content'
+ comment: 'Array of parsed project references from content',
},
},
{
@@ -42,7 +43,7 @@ module.exports = {
definition: {
type: Sequelize.STRING,
allowNull: true,
- comment: 'Content with tags and project references removed'
+ comment: 'Content with tags and project references removed',
},
},
]);
@@ -54,5 +55,5 @@ module.exports = {
await queryInterface.removeColumn('inbox_items', 'parsed_tags');
await queryInterface.removeColumn('inbox_items', 'parsed_projects');
await queryInterface.removeColumn('inbox_items', 'cleaned_content');
- }
-};
\ No newline at end of file
+ },
+};
diff --git a/backend/migrations/20250713072131-add-productivity-assistant-columns.js b/backend/migrations/20250713072131-add-productivity-assistant-columns.js
index 4d61ca7..0d664b8 100644
--- a/backend/migrations/20250713072131-add-productivity-assistant-columns.js
+++ b/backend/migrations/20250713072131-add-productivity-assistant-columns.js
@@ -3,7 +3,6 @@
module.exports = {
async up(queryInterface, Sequelize) {
try {
-
const tableInfo = await queryInterface.describeTable('users');
const columnsToAdd = [
@@ -41,7 +40,6 @@ module.exports = {
},
async down(queryInterface, Sequelize) {
-
await queryInterface.removeColumn(
'users',
'productivity_assistant_enabled'
diff --git a/backend/routes/inbox.js b/backend/routes/inbox.js
index a643974..5a97505 100644
--- a/backend/routes/inbox.js
+++ b/backend/routes/inbox.js
@@ -176,7 +176,9 @@ router.post('/inbox/analyze-text', async (req, res) => {
const { content } = req.body;
if (!content || typeof content !== 'string') {
- return res.status(400).json({ error: 'Content is required and must be a string' });
+ return res
+ .status(400)
+ .json({ error: 'Content is required and must be a string' });
}
// Process the text using the inbox processing service
diff --git a/backend/routes/projects.js b/backend/routes/projects.js
index 30c0f63..e9542f3 100644
--- a/backend/routes/projects.js
+++ b/backend/routes/projects.js
@@ -234,7 +234,13 @@ router.get('/project/:id', async (req, res) => {
{
model: Note,
required: false,
- attributes: ['id', 'title', 'content', 'created_at', 'updated_at'],
+ attributes: [
+ 'id',
+ 'title',
+ 'content',
+ 'created_at',
+ 'updated_at',
+ ],
},
{ model: Area, required: false, attributes: ['id', 'name'] },
{
@@ -250,19 +256,25 @@ router.get('/project/:id', async (req, res) => {
}
const projectJson = project.toJSON();
-
+
// Normalize task data to match frontend expectations
- const normalizedTasks = projectJson.Tasks ? projectJson.Tasks.map(task => {
- const normalizedTask = {
- ...task,
- tags: task.Tags || [], // Normalize Tags to tags for each task
- due_date: task.due_date ? (typeof task.due_date === 'string' ? task.due_date.split('T')[0] : task.due_date.toISOString().split('T')[0]) : null
- };
- // Remove the original Tags property to avoid confusion
- delete normalizedTask.Tags;
- return normalizedTask;
- }) : [];
-
+ const normalizedTasks = projectJson.Tasks
+ ? projectJson.Tasks.map((task) => {
+ const normalizedTask = {
+ ...task,
+ tags: task.Tags || [], // Normalize Tags to tags for each task
+ due_date: task.due_date
+ ? typeof task.due_date === 'string'
+ ? task.due_date.split('T')[0]
+ : task.due_date.toISOString().split('T')[0]
+ : null,
+ };
+ // Remove the original Tags property to avoid confusion
+ delete normalizedTask.Tags;
+ return normalizedTask;
+ })
+ : [];
+
const result = {
...projectJson,
tags: projectJson.Tags || [], // Normalize Tags to tags
diff --git a/backend/routes/tags.js b/backend/routes/tags.js
index 27f5936..a8db10f 100644
--- a/backend/routes/tags.js
+++ b/backend/routes/tags.js
@@ -22,11 +22,14 @@ router.get('/tag/:identifier', async (req, res) => {
try {
const identifier = req.params.identifier;
let whereClause;
-
+
// Check if identifier is a number (ID) or string (name)
if (/^\d+$/.test(identifier)) {
// It's a numeric ID
- whereClause = { id: parseInt(identifier), user_id: req.currentUser.id };
+ whereClause = {
+ id: parseInt(identifier),
+ user_id: req.currentUser.id,
+ };
} else {
// It's a tag name - decode URI component to handle special characters
const tagName = decodeURIComponent(identifier);
@@ -80,11 +83,14 @@ router.patch('/tag/:identifier', async (req, res) => {
try {
const identifier = req.params.identifier;
let whereClause;
-
+
// Check if identifier is a number (ID) or string (name)
if (/^\d+$/.test(identifier)) {
// It's a numeric ID
- whereClause = { id: parseInt(identifier), user_id: req.currentUser.id };
+ whereClause = {
+ id: parseInt(identifier),
+ user_id: req.currentUser.id,
+ };
} else {
// It's a tag name - decode URI component to handle special characters
const tagName = decodeURIComponent(identifier);
@@ -126,11 +132,14 @@ router.delete('/tag/:identifier', async (req, res) => {
try {
const identifier = req.params.identifier;
let whereClause;
-
+
// Check if identifier is a number (ID) or string (name)
if (/^\d+$/.test(identifier)) {
// It's a numeric ID
- whereClause = { id: parseInt(identifier), user_id: req.currentUser.id };
+ whereClause = {
+ id: parseInt(identifier),
+ user_id: req.currentUser.id,
+ };
} else {
// It's a tag name - decode URI component to handle special characters
const tagName = decodeURIComponent(identifier);
diff --git a/backend/routes/users.js b/backend/routes/users.js
index 8799b5b..9f55ba0 100644
--- a/backend/routes/users.js
+++ b/backend/routes/users.js
@@ -433,12 +433,13 @@ router.put('/profile/today-settings', async (req, res) => {
profileUpdates.productivity_assistant_enabled = showProductivity;
}
if (showNextTaskSuggestion !== undefined) {
- profileUpdates.next_task_suggestion_enabled = showNextTaskSuggestion;
+ profileUpdates.next_task_suggestion_enabled =
+ showNextTaskSuggestion;
}
- await user.update({
+ await user.update({
today_settings: todaySettings,
- ...profileUpdates
+ ...profileUpdates,
});
res.json({
diff --git a/backend/services/inboxProcessingService.js b/backend/services/inboxProcessingService.js
index a831dd1..253aa6a 100644
--- a/backend/services/inboxProcessingService.js
+++ b/backend/services/inboxProcessingService.js
@@ -13,27 +13,50 @@ class InboxProcessingService {
*/
static isActionVerb(word) {
if (!word || typeof word !== 'string') return false;
-
+
try {
const doc = nlp(word.toLowerCase());
const verbs = doc.verbs();
-
+
if (verbs.length === 0) return false;
-
+
// Check if it's an action verb (not auxiliary/linking verbs when used alone)
const text = verbs.text().toLowerCase();
-
+
// Allow "do" when it's part of an action phrase like "do something"
if (text === 'do') {
// Check the original word context to see if it's followed by a noun/action
return true; // For now, allow "do" - could refine this logic later
}
-
- const auxiliaryVerbs = ['be', 'is', 'am', 'are', 'was', 'were', 'being', 'been',
- 'have', 'has', 'had', 'having', 'does', 'did', 'doing',
- 'will', 'would', 'shall', 'should', 'may', 'might', 'can',
- 'could', 'must', 'ought'];
-
+
+ const auxiliaryVerbs = [
+ 'be',
+ 'is',
+ 'am',
+ 'are',
+ 'was',
+ 'were',
+ 'being',
+ 'been',
+ 'have',
+ 'has',
+ 'had',
+ 'having',
+ 'does',
+ 'did',
+ 'doing',
+ 'will',
+ 'would',
+ 'shall',
+ 'should',
+ 'may',
+ 'might',
+ 'can',
+ 'could',
+ 'must',
+ 'ought',
+ ];
+
return !auxiliaryVerbs.includes(text);
} catch (error) {
console.error('Error checking verb:', error);
@@ -51,11 +74,11 @@ class InboxProcessingService {
let currentToken = '';
let inQuotes = false;
let i = 0;
-
+
while (i < text.length) {
const char = text[i];
-
- if (char === '"' && (i === 0 || text[i-1] === '+')) {
+
+ if (char === '"' && (i === 0 || text[i - 1] === '+')) {
// Start of a quoted string after +
inQuotes = true;
currentToken += char;
@@ -75,12 +98,12 @@ class InboxProcessingService {
}
i++;
}
-
+
// Add final token
if (currentToken) {
tokens.push(currentToken);
}
-
+
return tokens;
}
@@ -92,11 +115,11 @@ class InboxProcessingService {
static parseHashtags(text) {
const trimmedText = text.trim();
const matches = [];
-
+
// Split text into words
const words = trimmedText.split(/\s+/);
if (words.length === 0) return matches;
-
+
// Find all consecutive groups of tags/projects
let i = 0;
while (i < words.length) {
@@ -104,27 +127,35 @@ class InboxProcessingService {
if (words[i].startsWith('#') || words[i].startsWith('+')) {
// Found start of a group, collect all consecutive tags/projects
let groupEnd = i;
- while (groupEnd < words.length && (words[groupEnd].startsWith('#') || words[groupEnd].startsWith('+'))) {
+ while (
+ groupEnd < words.length &&
+ (words[groupEnd].startsWith('#') ||
+ words[groupEnd].startsWith('+'))
+ ) {
groupEnd++;
}
-
+
// Process all hashtags in this group
for (let j = i; j < groupEnd; j++) {
if (words[j].startsWith('#')) {
const tagName = words[j].substring(1);
- if (tagName && /^[a-zA-Z0-9_-]+$/.test(tagName) && !matches.includes(tagName)) {
+ if (
+ tagName &&
+ /^[a-zA-Z0-9_-]+$/.test(tagName) &&
+ !matches.includes(tagName)
+ ) {
matches.push(tagName);
}
}
}
-
+
// Skip to end of this group
i = groupEnd;
} else {
i++;
}
}
-
+
return matches;
}
@@ -136,10 +167,10 @@ class InboxProcessingService {
static parseProjectRefs(text) {
const trimmedText = text.trim();
const matches = [];
-
+
// Tokenize the text handling quoted strings properly
const tokens = this.tokenizeText(trimmedText);
-
+
// Find consecutive groups of tags/projects
let i = 0;
while (i < tokens.length) {
@@ -147,33 +178,40 @@ class InboxProcessingService {
if (tokens[i].startsWith('#') || tokens[i].startsWith('+')) {
// Found start of a group, collect all consecutive tags/projects
let groupEnd = i;
- while (groupEnd < tokens.length && (tokens[groupEnd].startsWith('#') || tokens[groupEnd].startsWith('+'))) {
+ while (
+ groupEnd < tokens.length &&
+ (tokens[groupEnd].startsWith('#') ||
+ tokens[groupEnd].startsWith('+'))
+ ) {
groupEnd++;
}
-
+
// Process all project references in this group
for (let j = i; j < groupEnd; j++) {
if (tokens[j].startsWith('+')) {
let projectName = tokens[j].substring(1);
-
+
// Handle quoted project names
- if (projectName.startsWith('"') && projectName.endsWith('"')) {
+ if (
+ projectName.startsWith('"') &&
+ projectName.endsWith('"')
+ ) {
projectName = projectName.slice(1, -1);
}
-
+
if (projectName && !matches.includes(projectName)) {
matches.push(projectName);
}
}
}
-
+
// Skip to end of this group
i = groupEnd;
} else {
i++;
}
}
-
+
return matches;
}
@@ -186,13 +224,16 @@ class InboxProcessingService {
const trimmedText = text.trim();
const tokens = this.tokenizeText(trimmedText);
const cleanedTokens = [];
-
+
let i = 0;
while (i < tokens.length) {
// Check if current token starts a tag/project group
if (tokens[i].startsWith('#') || tokens[i].startsWith('+')) {
// Skip this entire consecutive group
- while (i < tokens.length && (tokens[i].startsWith('#') || tokens[i].startsWith('+'))) {
+ while (
+ i < tokens.length &&
+ (tokens[i].startsWith('#') || tokens[i].startsWith('+'))
+ ) {
i++;
}
} else {
@@ -201,7 +242,7 @@ class InboxProcessingService {
i++;
}
}
-
+
return cleanedTokens.join(' ').trim();
}
@@ -212,11 +253,11 @@ class InboxProcessingService {
*/
static startsWithVerb(text) {
if (!text.trim()) return false;
-
+
try {
const firstWord = text.trim().split(/\s+/)[0];
if (!firstWord) return false;
-
+
return this.isActionVerb(firstWord);
} catch (error) {
console.error('Error checking if text starts with verb:', error);
@@ -244,38 +285,40 @@ class InboxProcessingService {
*/
static generateSuggestion(content, tags, projects, cleanedContent) {
const hasProject = projects.length > 0;
- const hasBookmarkTag = tags.some(tag => tag.toLowerCase() === 'bookmark');
+ const hasBookmarkTag = tags.some(
+ (tag) => tag.toLowerCase() === 'bookmark'
+ );
const textStartsWithVerb = this.startsWithVerb(cleanedContent);
const containsUrl = this.containsUrl(content);
-
+
if (!hasProject) {
return { type: null, reason: null };
}
-
+
// Suggest note for bookmark items with project (explicit bookmark tag)
if (hasBookmarkTag) {
return {
type: 'note',
- reason: 'bookmark_tag'
+ reason: 'bookmark_tag',
};
}
-
+
// Suggest note for URLs with project (auto-bookmark)
if (containsUrl) {
return {
type: 'note',
- reason: 'url_detected'
+ reason: 'url_detected',
};
}
-
+
// Suggest task for items with project that start with a verb
if (textStartsWithVerb) {
return {
type: 'task',
- reason: 'verb_detected'
+ reason: 'verb_detected',
};
}
-
+
return { type: null, reason: null };
}
@@ -289,18 +332,23 @@ class InboxProcessingService {
const tags = this.parseHashtags(content);
const projects = this.parseProjectRefs(content);
const cleanedContent = this.cleanTextFromTagsAndProjects(content);
-
+
// Generate suggestion
- const suggestion = this.generateSuggestion(content, tags, projects, cleanedContent);
-
+ const suggestion = this.generateSuggestion(
+ content,
+ tags,
+ projects,
+ cleanedContent
+ );
+
return {
parsed_tags: tags,
parsed_projects: projects,
cleaned_content: cleanedContent,
suggested_type: suggestion.type,
- suggested_reason: suggestion.reason
+ suggested_reason: suggestion.reason,
};
}
}
-module.exports = InboxProcessingService;
\ No newline at end of file
+module.exports = InboxProcessingService;
diff --git a/backend/services/telegramApi.js b/backend/services/telegramApi.js
index 0adf167..14afb65 100644
--- a/backend/services/telegramApi.js
+++ b/backend/services/telegramApi.js
@@ -2,7 +2,7 @@
async function getBotInfo(token) {
return new Promise((resolve, reject) => {
const url = `https://api.telegram.org/bot${token}/getMe`;
-
+
const options = {
method: 'GET',
headers: {
@@ -12,18 +12,21 @@ async function getBotInfo(token) {
const req = require('https').request(url, options, (res) => {
let data = '';
-
+
res.on('data', (chunk) => {
data += chunk;
});
-
+
res.on('end', () => {
try {
const response = JSON.parse(data);
if (response.ok) {
resolve(response.result);
} else {
- console.error('Telegram API error:', response.description);
+ console.error(
+ 'Telegram API error:',
+ response.description
+ );
resolve(null);
}
} catch (error) {
@@ -42,4 +45,4 @@ async function getBotInfo(token) {
});
}
-module.exports = { getBotInfo };
\ No newline at end of file
+module.exports = { getBotInfo };
diff --git a/frontend/components/Areas.tsx b/frontend/components/Areas.tsx
index 858d0f6..5c4b6f2 100644
--- a/frontend/components/Areas.tsx
+++ b/frontend/components/Areas.tsx
@@ -109,9 +109,7 @@ const Areas: React.FC = () => {
{/* Areas Header */}
-
- {t('areas.title')}
-
+ {t('areas.title')}
{/* Areas List */}
diff --git a/frontend/components/Icons/TelegramIcon.tsx b/frontend/components/Icons/TelegramIcon.tsx
index e1da951..475ef0d 100644
--- a/frontend/components/Icons/TelegramIcon.tsx
+++ b/frontend/components/Icons/TelegramIcon.tsx
@@ -5,7 +5,10 @@ interface TelegramIconProps {
title?: string;
}
-const TelegramIcon: React.FC = ({ className = "h-5 w-5", title }) => {
+const TelegramIcon: React.FC = ({
+ className = 'h-5 w-5',
+ title,
+}) => {
return (