Skip to content

Commit 8c219c1

Browse files
authored
Merge pull request #8 from Gabry848/copilot/organize-components-structure
Reorganize components into topic-based subfolders under src/components
2 parents 4f8db00 + 6df2039 commit 8c219c1

125 files changed

Lines changed: 2722 additions & 1319 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/settings.local.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@
3636
"Bash(npm run lint:*)",
3737
"Bash(node_modules/.bin/tsc:*)",
3838
"Bash(cat:*)",
39-
"Bash(npm run docs:generate:*)"
39+
"Bash(npm run docs:generate:*)",
40+
"Bash(powershell -Command \"Get-ChildItem -Path . -Recurse | Select-Object -ExpandProperty FullName | Sort-Object\")",
41+
"Bash(git log:*)"
4042
],
4143
"deny": [],
4244
"defaultMode": "acceptEdits"

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,4 @@ docs/
5050

5151
# Firebase secrets
5252

53-
*firebase-adminsdk*.json
53+
*firebase-adminsdk*.json
Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
# 🔔 Sistema di Invio Token Notifiche con Autenticazione
2+
3+
## 📋 Panoramica
4+
5+
Il sistema di notifiche push è stato modificato per inviare il token Expo al backend **solo dopo un login corretto** e ritentare automaticamente l'invio ad ogni apertura dell'app se il primo tentativo fallisce.
6+
7+
## 🎯 Funzionalità Implementate
8+
9+
### 1. **Invio Token Solo Dopo Login**
10+
- Il token push viene ottenuto all'avvio dell'app
11+
- **NON viene inviato immediatamente** al backend
12+
- L'invio avviene solo quando `isAuthenticated === true`
13+
14+
### 2. **Salvataggio Token Pendente**
15+
- Se l'invio fallisce o l'utente non è autenticato, il token viene salvato in AsyncStorage
16+
- Chiave di storage: `@MyTaskly:pendingNotificationToken`
17+
- Il token rimane salvato fino all'invio riuscito
18+
19+
### 3. **Retry Automatico**
20+
- **All'apertura dell'app**: Se l'utente è già autenticato, viene ritentato l'invio del token pendente
21+
- **Al login**: Quando l'utente effettua il login, il sistema tenta di inviare sia il token corrente che eventuali token pendenti
22+
- Il token viene rimosso da AsyncStorage solo dopo un invio riuscito
23+
24+
## 🔧 Modifiche Apportate
25+
26+
### File Modificato: `src/services/notificationService.ts`
27+
28+
#### 1. **Nuovi Import**
29+
```typescript
30+
import AsyncStorage from '@react-native-async-storage/async-storage';
31+
import eventEmitter from '../utils/eventEmitter';
32+
```
33+
34+
#### 2. **Nuova Costante**
35+
```typescript
36+
const PENDING_TOKEN_KEY = '@MyTaskly:pendingNotificationToken';
37+
```
38+
39+
#### 3. **Funzione `sendTokenToBackend` Modificata**
40+
```typescript
41+
export async function sendTokenToBackend(token: string, isAuthenticated: boolean = false): Promise<boolean>
42+
```
43+
44+
**Comportamento:**
45+
- Verifica se l'utente è autenticato prima di inviare
46+
- Se non autenticato, salva il token in AsyncStorage per retry futuro
47+
- Se l'invio ha successo, rimuove il token pendente
48+
- Se l'invio fallisce, mantiene il token salvato per retry
49+
50+
#### 4. **Nuova Funzione `retryPendingTokenSend`**
51+
```typescript
52+
export async function retryPendingTokenSend(isAuthenticated: boolean): Promise<boolean>
53+
```
54+
55+
**Comportamento:**
56+
- Controlla se esiste un token pendente in AsyncStorage
57+
- Se esiste e l'utente è autenticato, tenta l'invio al backend
58+
- Rimuove il token se l'invio ha successo
59+
- Mantiene il token se l'invio fallisce
60+
61+
#### 5. **Hook `useNotifications` Aggiornato**
62+
63+
**Nuove Funzionalità:**
64+
- State `isAuthenticated` per tracciare lo stato di autenticazione
65+
- Controllo autenticazione all'avvio con retry automatico
66+
- Listener per eventi `loginSuccess` e `logoutSuccess`
67+
- Dipendenza `expoPushToken` nell'useEffect per aggiornamenti dinamici
68+
69+
**Flusso:**
70+
1. **All'avvio dell'app:**
71+
- Ottiene il token Expo
72+
- Controlla se l'utente è già autenticato
73+
- Se autenticato, ritenta l'invio di token pendenti
74+
75+
2. **Al login (`loginSuccess` event):**
76+
- Imposta `isAuthenticated = true`
77+
- Invia il token corrente al backend
78+
- Ritenta l'invio di token pendenti
79+
80+
3. **Al logout (`logoutSuccess` event):**
81+
- Imposta `isAuthenticated = false`
82+
- Il token verrà salvato come pendente al prossimo tentativo
83+
84+
## 📊 Flusso di Esecuzione
85+
86+
```
87+
┌─────────────────────────────────────────┐
88+
│ App si apre │
89+
└───────────────┬─────────────────────────┘
90+
91+
92+
┌─────────────────────────────────────────┐
93+
│ registerForPushNotificationsAsync() │
94+
│ Ottiene token Expo │
95+
└───────────────┬─────────────────────────┘
96+
97+
98+
┌─────────────────────────────────────────┐
99+
│ Controlla autenticazione │
100+
└───────────────┬─────────────────────────┘
101+
102+
┌───────┴───────┐
103+
│ │
104+
▼ ▼
105+
┌──────────────┐ ┌──────────────────┐
106+
│ Autenticato │ │ Non Autenticato │
107+
└──────┬───────┘ └────────┬─────────┘
108+
│ │
109+
▼ ▼
110+
┌──────────────┐ ┌──────────────────┐
111+
│ Retry token │ │ Attende login │
112+
│ pendente │ │ Salva token │
113+
└──────────────┘ └────────┬─────────┘
114+
115+
116+
┌─────────────────┐
117+
│ Utente fa login │
118+
└────────┬────────┘
119+
120+
121+
┌─────────────────┐
122+
│ Event: │
123+
│ loginSuccess │
124+
└────────┬────────┘
125+
126+
127+
┌─────────────────┐
128+
│ Invia token al │
129+
│ backend │
130+
└────────┬────────┘
131+
132+
┌───────┴───────┐
133+
│ │
134+
▼ ▼
135+
┌────────────┐ ┌────────────┐
136+
│ Successo │ │ Fallito │
137+
│ Rimuovi │ │ Mantieni │
138+
│ pendente │ │ pendente │
139+
└────────────┘ └────────────┘
140+
```
141+
142+
## 🧪 Testing
143+
144+
### Test Case 1: Primo Avvio (Non Autenticato)
145+
**Scenario:** L'utente apre l'app per la prima volta senza essere autenticato.
146+
147+
**Comportamento Atteso:**
148+
1. Token Expo ottenuto ✅
149+
2. Token NON inviato al backend ⏸️
150+
3. Token salvato in AsyncStorage come pendente 💾
151+
4. Log: "⏸️ Utente non autenticato, salvataggio token per invio successivo"
152+
153+
### Test Case 2: Login Dopo Primo Avvio
154+
**Scenario:** L'utente fa login dopo aver ottenuto il token.
155+
156+
**Comportamento Atteso:**
157+
1. Event `loginSuccess` emesso ✅
158+
2. Listener rileva l'evento 👂
159+
3. Token inviato al backend 📤
160+
4. Token pendente rimosso da AsyncStorage 🗑️
161+
5. Log: "✅ Token inviato al backend dopo il login"
162+
163+
### Test Case 3: Apertura App con Utente Già Autenticato
164+
**Scenario:** L'utente riapre l'app essendo già autenticato.
165+
166+
**Comportamento Atteso:**
167+
1. Controllo autenticazione all'avvio ✅
168+
2. `isAuthenticated = true` 🔐
169+
3. Retry automatico di token pendenti 🔄
170+
4. Log: "✅ Utente già autenticato all'avvio"
171+
172+
### Test Case 4: Fallimento Invio al Backend
173+
**Scenario:** L'invio del token al backend fallisce (errore di rete/endpoint non disponibile).
174+
175+
**Comportamento Atteso:**
176+
1. Tentativo di invio fallisce ❌
177+
2. Token rimane salvato in AsyncStorage 💾
178+
3. Al prossimo login, nuovo tentativo di invio 🔄
179+
4. Log: "❌ Errore nell'invio del token al backend"
180+
181+
### Test Case 5: Logout
182+
**Scenario:** L'utente effettua il logout.
183+
184+
**Comportamento Atteso:**
185+
1. Event `logoutSuccess` emesso ✅
186+
2. `isAuthenticated = false` 🔓
187+
3. Token future non verranno inviati fino al prossimo login ⏸️
188+
189+
## 📝 Log di Debug
190+
191+
Il sistema genera log dettagliati per facilitare il debugging:
192+
193+
```typescript
194+
// Token ottenuto
195+
"🔔 Token ottenuto, attendendo autenticazione per l'invio al backend"
196+
197+
// Utente non autenticato
198+
"⏸️ Utente non autenticato, salvataggio token per invio successivo"
199+
"💾 Token salvato in AsyncStorage"
200+
201+
// Login riuscito
202+
"🔐 Login riuscito, tentativo di invio token al backend..."
203+
"✅ Token inviato al backend dopo il login"
204+
205+
// Retry all'avvio
206+
"✅ Utente già autenticato all'avvio"
207+
"🔄 Trovato token pendente, tentativo di invio al backend..."
208+
209+
// Invio fallito
210+
"❌ Errore nell'invio del token al backend"
211+
"💾 Token salvato per retry futuro"
212+
213+
// Successo
214+
"✅ Token inviato al backend con successo"
215+
"🗑️ Token pendente rimosso da AsyncStorage"
216+
217+
// Nessun token pendente
218+
"ℹ️ Nessun token pendente da inviare"
219+
```
220+
221+
## ⚠️ Note Importanti
222+
223+
### Backend Requirements
224+
Il backend deve implementare l'endpoint:
225+
```
226+
POST /notifications/token
227+
Headers: Authorization: Bearer <jwt_token>
228+
Body: { "token": "ExponentPushToken[...]" }
229+
```
230+
231+
### Sicurezza
232+
- Il token viene inviato **solo con autenticazione JWT valida**
233+
- L'invio avviene tramite `axiosInstance` che gestisce automaticamente il Bearer token
234+
- Il token è memorizzato localmente ma non esposto
235+
236+
### Performance
237+
- Il retry è automatico ma non impatta le performance
238+
- Il controllo autenticazione all'avvio è asincrono
239+
- Il token viene salvato in AsyncStorage per persistenza
240+
241+
## 🔄 Compatibilità
242+
243+
- ✅ Expo Go (modalità limitata)
244+
- ✅ Development Build
245+
- ✅ Android & iOS
246+
- ✅ Funziona con sistema di autenticazione esistente
247+
248+
## 📚 Riferimenti
249+
250+
- [Expo Notifications](https://docs.expo.dev/versions/latest/sdk/notifications/)
251+
- [AsyncStorage](https://react-native-async-storage.github.io/async-storage/)
252+
- [Event Emitter Pattern](../src/utils/eventEmitter.ts)
253+
- [Auth Service](../src/services/authService.ts)
254+
255+
---
256+
257+
**Ultima Modifica:** 29 Novembre 2025
258+
**Autore:** GitHub Copilot
259+
**Versione:** 1.0

components/CategoryBadge.tsx

Lines changed: 0 additions & 74 deletions
This file was deleted.

0 commit comments

Comments
 (0)