Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 28 additions & 8 deletions src/components/BotChat/widgets/ItemDetailModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
ActivityIndicator,
} from 'react-native';
import { Ionicons } from '@expo/vector-icons';
import { useTranslation } from 'react-i18next';
import { ItemDetailModalProps } from '../types';
import * as taskService from '../../../services/taskService';

Expand All @@ -23,6 +24,7 @@ const ItemDetailModal: React.FC<ItemDetailModalProps> = ({
itemType,
onClose,
}) => {
const { t } = useTranslation();
const [isLoading, setIsLoading] = useState(false);

// Handler per completare un task
Expand All @@ -35,24 +37,39 @@ const ItemDetailModal: React.FC<ItemDetailModalProps> = ({
...item,
status: item.completed ? 'pending' : 'completed',
});
Alert.alert('Successo', `Task ${item.completed ? 'riaperto' : 'completato'}`);
Alert.alert(
t('itemDetailModal.success'),
item.completed ? t('itemDetailModal.reopenTask') : t('itemDetailModal.completeTask')
);
onClose();
} catch (error: any) {
Alert.alert('Errore', error.message || 'Impossibile aggiornare il task');
Alert.alert(
t('itemDetailModal.error'),
error.message || t('itemDetailModal.updateTaskError')
);
} finally {
setIsLoading(false);
}
};

// Handler per eliminare un item
const handleDelete = () => {
let confirmMessage: string;
if (itemType === 'task') {
confirmMessage = t('itemDetailModal.deleteTaskConfirm');
} else if (itemType === 'category') {
confirmMessage = t('itemDetailModal.deleteCategoryConfirm');
} else {
confirmMessage = t('itemDetailModal.deleteNoteConfirm');
}

Alert.alert(
'Conferma eliminazione',
`Sei sicuro di voler eliminare ${itemType === 'task' ? 'questo task' : itemType === 'category' ? 'questa categoria' : 'questa nota'}?`,
t('itemDetailModal.deleteConfirm'),
confirmMessage,
[
{ text: 'Annulla', style: 'cancel' },
{ text: t('common.buttons.cancel'), style: 'cancel' },
{
text: 'Elimina',
text: t('common.buttons.delete'),
style: 'destructive',
onPress: async () => {
setIsLoading(true);
Expand All @@ -61,10 +78,13 @@ const ItemDetailModal: React.FC<ItemDetailModalProps> = ({
await taskService.deleteTask(item.task_id);
}
// TODO: Implementa delete per categorie e note se necessario
Alert.alert('Successo', 'Elemento eliminato');
Alert.alert(t('itemDetailModal.success'), t('itemDetailModal.itemDeleted'));
onClose();
} catch (error: any) {
Alert.alert('Errore', error.message || 'Impossibile eliminare');
Alert.alert(
t('itemDetailModal.error'),
error.message || t('itemDetailModal.deleteError')
);
} finally {
setIsLoading(false);
}
Expand Down
4 changes: 3 additions & 1 deletion src/components/Calendar/CalendarView.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { useState, useEffect, useCallback, useRef } from 'react';
import { View, ScrollView, StyleSheet, Alert, ActivityIndicator, Dimensions } from 'react-native';
import { useTranslation } from 'react-i18next';
import dayjs from 'dayjs';
import { Task as TaskType, getAllTasks, addTask, deleteTask, updateTask, completeTask, disCompleteTask } from '../../services/taskService';
import { TaskCacheService } from '../../services/TaskCacheService';
Expand All @@ -16,6 +17,7 @@ import { addTaskToList } from '../TaskList/types';
import { LoadingState, EmptyState, StatusChip, AppText } from '../UI/foundation';

const CalendarView: React.FC = () => {
const { t } = useTranslation();
const [selectedDate, setSelectedDate] = useState<string>(dayjs().format('YYYY-MM-DD'));
const [tasks, setTasks] = useState<TaskType[]>([]);
const [showAddTask, setShowAddTask] = useState(false);
Expand Down Expand Up @@ -339,7 +341,7 @@ const CalendarView: React.FC = () => {
));
} catch (error) {
console.error("Errore nell'eliminazione del task:", error);
Alert.alert("Errore", "Impossibile eliminare il task. Riprova.");
Alert.alert(t('itemDetailModal.error'), t('taskDelete.error'));
}
};

Expand Down
22 changes: 12 additions & 10 deletions src/components/Category/AddCategoryButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import Animated, {
} from "react-native-reanimated";
import { addCategory, CategoryLimitError } from "../../services/taskService";
import { emitCategoryAdded } from "../../utils/eventEmitter";
import { useTranslation } from "react-i18next";

// Definiamo un'interfaccia chiara per i dati della categoria
export interface CategoryData {
Expand All @@ -34,6 +35,7 @@ export interface AddCategoryButtonProps {
const AddCategoryButton: React.FC<AddCategoryButtonProps> = ({
onCategoryAdded,
}) => {
const { t } = useTranslation();
const [formVisible, setFormVisible] = useState(false);
const animationValue = useSharedValue(0);
const [name, setName] = useState("");
Expand All @@ -56,7 +58,7 @@ const AddCategoryButton: React.FC<AddCategoryButtonProps> = ({

const handleSave = async () => {
if (name.trim() === "") {
Alert.alert("Errore", "Il nome della categoria non può essere vuoto");
Alert.alert(t("categories.messages.error"), t("categories.messages.emptyTitle"));
return;
}

Expand Down Expand Up @@ -108,8 +110,8 @@ const AddCategoryButton: React.FC<AddCategoryButtonProps> = ({
} catch (error) {
if (error instanceof CategoryLimitError) {
Alert.alert(
"Limite categorie raggiunto",
"Hai raggiunto il numero massimo di categorie per il tuo piano. Fai l'upgrade per aggiungerne altre."
t("categories.addModal.limitReached"),
t("categories.addModal.limitReachedMessage")
);
return;
}
Expand All @@ -127,7 +129,7 @@ const AddCategoryButton: React.FC<AddCategoryButtonProps> = ({
handleCancel();
} catch (error) {
console.error("Errore nell'aggiunta della categoria:", error);
Alert.alert("Errore", "Non è stato possibile aggiungere la categoria");
Alert.alert(t("categories.messages.error"), t("categories.addModal.addError"));
} finally {
setIsSubmitting(false);
}
Expand All @@ -151,17 +153,17 @@ const AddCategoryButton: React.FC<AddCategoryButtonProps> = ({
<View style={styles.modalOverlay}>
<Animated.View style={[styles.formContainer, animatedStyle]}>
<KeyboardAvoidingView behavior="padding" style={styles.formContent}>
<Text style={styles.label}>Nome Categoria</Text>
<Text style={styles.label}>{t("categories.addModal.name")}</Text>
<TextInput
style={styles.input}
placeholder="Inserisci il nome della categoria"
placeholder={t("categories.addModal.namePlaceholder")}
value={name}
onChangeText={setName}
/>
<Text style={styles.label}>Descrizione</Text>
<Text style={styles.label}>{t("categories.addModal.description")}</Text>
<TextInput
style={styles.input}
placeholder="Inserisci la descrizione"
placeholder={t("categories.addModal.descriptionPlaceholder")}
multiline
value={description}
onChangeText={setDescription}
Expand All @@ -173,15 +175,15 @@ const AddCategoryButton: React.FC<AddCategoryButtonProps> = ({
disabled={isSubmitting}
>
<Text style={styles.submitButtonText}>
{isSubmitting ? "Salvataggio..." : "Salva"}
{isSubmitting ? t("categories.addModal.saving") : t("categories.addModal.save")}
</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.cancelButton}
onPress={handleCancel}
disabled={isSubmitting}
>
<Text style={styles.cancelButtonText}>Annulla</Text>
<Text style={styles.cancelButtonText}>{t("categories.addModal.cancel")}</Text>
</TouchableOpacity>
</View>
</KeyboardAvoidingView>
Expand Down
42 changes: 23 additions & 19 deletions src/components/Category/Category.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import ShareCategoryDialog from './ShareCategoryDialog';
import ManageCategoryShares from './ManageCategoryShares';
import eventEmitter, { emitCategoryDeleted, emitCategoryUpdated, emitTaskAdded , EVENTS } from '../../utils/eventEmitter';
import GoogleCalendarService from '../../services/googleCalendarService';
import { useTranslation } from "react-i18next";


export interface CategoryProps {
Expand Down Expand Up @@ -41,6 +42,7 @@ const Category: React.FC<CategoryProps> = ({
onEdit,
onPressCategory
}) => {
const { t } = useTranslation();
const [showMenu, setShowMenu] = useState(false);
const [showEditModal, setShowEditModal] = useState(false);
const [showDeleteModal, setShowDeleteModal] = useState(false);
Expand Down Expand Up @@ -145,8 +147,8 @@ const Category: React.FC<CategoryProps> = ({
// Only owners can delete
if (!isOwned) {
Alert.alert(
"Permesso negato",
"Solo il proprietario può eliminare questa categoria."
t("categories.permissions.denied"),
t("categories.permissions.ownerOnlyDelete")
);
closeMenu();
return;
Expand Down Expand Up @@ -183,7 +185,7 @@ const Category: React.FC<CategoryProps> = ({
} catch (error) {
console.error("Errore durante l'eliminazione della categoria:", error);
setShowDeleteModal(false);
Alert.alert("Errore", "Impossibile eliminare la categoria. Riprova più tardi.");
Alert.alert(t("categories.delete.error"), t("categories.delete.failed"));
} finally {
setIsDeleting(false);
}
Expand All @@ -199,8 +201,8 @@ const Category: React.FC<CategoryProps> = ({
// Check permissions - owners and READ_WRITE users can edit
if (!isOwned && permissionLevel === "READ_ONLY") {
Alert.alert(
"Permesso negato",
"Hai solo permessi di lettura per questa categoria. Non puoi modificarla."
t("categories.permissions.denied"),
t("categories.permissions.readOnly")
);
closeMenu();
return;
Expand All @@ -214,7 +216,7 @@ const Category: React.FC<CategoryProps> = ({

const handleSaveEdit = async () => {
if (!editName.trim()) {
Alert.alert("Errore", "Il titolo della categoria non può essere vuoto");
Alert.alert(t("categories.update.error"), t("categories.update.emptyTitle"));
return;
}

Expand All @@ -224,21 +226,21 @@ const Category: React.FC<CategoryProps> = ({
name: editName.trim(),
description: editDescription.trim()
});

// Emetti un evento per notificare la modifica della categoria
emitCategoryUpdated({
name: editName.trim(),
description: editDescription.trim(),
oldName: title
});

setShowEditModal(false);
if (onEdit) {
onEdit();
}
} catch (error) {
console.error("Errore durante l'aggiornamento della categoria:", error);
Alert.alert("Errore", "Impossibile aggiornare la categoria. Riprova più tardi.");
Alert.alert(t("categories.update.error"), t("categories.update.failed"));
} finally {
setIsEditing(false);
}
Expand All @@ -257,31 +259,33 @@ const Category: React.FC<CategoryProps> = ({
setShowShareDialog(true);
} else {
Alert.alert(
"Categoria condivisa",
`Questa categoria è condivisa da un altro utente. Il tuo permesso: ${permissionLevel === "READ_ONLY" ? "Sola lettura" : "Lettura/Scrittura"}`
t("categories.shared.title"),
t("categories.shared.info", {
permission: t(`categories.shared.permissions.${permissionLevel}`)
})
);
}
};

const handleManageShares = () => {
closeMenu();
if (!categoryId) {
Alert.alert("Errore", "ID categoria non disponibile");
Alert.alert(t("categories.shared.idError"), t("categories.shared.noId"));
return;
}
setShowManageShares(true);
};

const handleShareSuccess = (message: string) => {
Alert.alert("Successo", message);
Alert.alert(t("categories.shared.success"), message);
};

const handleAddTask = () => {
// Check permissions before allowing task creation
if (!isOwned && permissionLevel === "READ_ONLY") {
Alert.alert(
"Permesso negato",
"Hai solo permessi di lettura per questa categoria. Non puoi aggiungere task."
t("categories.permissions.denied"),
t("categories.permissions.readOnlyAdd")
);
return;
}
Expand All @@ -296,19 +300,19 @@ const Category: React.FC<CategoryProps> = ({
start_time: new Date().toISOString(),
priority: priority,
category_name: title,
status: "In sospeso",
status: t("categories.task.status"),
user: "" // Campo richiesto dal server
};
console.log("Nuovo task:", d);
addTask(d).then((addedTask) => {
// Emetti un evento per notificare l'aggiunta di un nuovo task
emitTaskAdded(addedTask || d);

fetchTaskCount();
setShowAddTask(false);
setShowAddTask(false);
}).catch(error => {
console.error("Errore durante l'aggiunta del task:", error);
Alert.alert("Errore", "Impossibile aggiungere il task. Riprova più tardi.");
Alert.alert(t("categories.task.error"), t("categories.task.addFailed"));
});
};

Expand Down
9 changes: 7 additions & 2 deletions src/components/Category/CategoryHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from "react";
import { View, Text, StyleSheet, Image } from "react-native";
import { MaterialIcons } from '@expo/vector-icons';
import { useTranslation } from "react-i18next";
import CategoryBadge from './CategoryBadge';

export interface CategoryHeaderProps {
Expand All @@ -20,6 +21,8 @@ const CategoryHeader: React.FC<CategoryHeaderProps> = ({
screenWidth,
badgeType
}) => {
const { t } = useTranslation();

return (
<View style={styles.headerContainer}>
<View
Expand Down Expand Up @@ -62,7 +65,9 @@ const CategoryHeader: React.FC<CategoryHeaderProps> = ({
fontSize: screenWidth < 350 ? 12 : 14,
marginLeft: screenWidth < 350 ? 4 : 6,
}]}>
{isLoading ? "Caricamento..." : `${taskCount} cose da fare`}
{isLoading
? t("common.messages.loading")
: t("categories.taskCount", { count: taskCount })}
</Text>
</View>
</View>
Expand Down Expand Up @@ -123,4 +128,4 @@ const styles = StyleSheet.create({
},
});

export default CategoryHeader;
export default CategoryHeader;
Loading
Loading