fix(projects): la lista salía vacía — el backend envuelve en {projects}

GET /projects responde { "projects": [...] } (ProjectApiController@index),
pero normalize() solo contemplaba un array o { data } → siempre [].
Ahora normalize acepta {projects}/{data}/array, los tipos de listProjects
y getTemplates reflejan la envoltura real ({projects}/{templates}), y el
fallback offline loguea el motivo en vez de tragarse el error.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-07-07 18:03:18 +02:00
co-authored by Claude Sonnet 4.6
parent fdf85e7cc9
commit 04859c281d
2 changed files with 11 additions and 5 deletions
+4 -2
View File
@@ -31,7 +31,8 @@ export function logout(): Promise<unknown> {
// --- PULL ---
export function listProjects(): Promise<{ data?: Project[] } | Project[]> {
/** El backend responde `{ projects: [...] }` (ver ProjectApiController@index). */
export function listProjects(): Promise<{ projects: Project[] }> {
return request('/projects');
}
@@ -45,7 +46,8 @@ export function getBundle(projectId: number, since?: string): Promise<Bundle> {
});
}
export function getTemplates(since?: string): Promise<{ data?: Template[] } | Template[]> {
/** El backend responde `{ templates: [...] }`. */
export function getTemplates(since?: string): Promise<{ templates: Template[] }> {
return request('/templates', { query: since ? { since } : undefined });
}
+7 -3
View File
@@ -19,8 +19,11 @@ import { RootStackParamList } from '../navigation/types';
type Props = NativeStackScreenProps<RootStackParamList, 'Projects'>;
function normalize(res: { data?: Project[] } | Project[]): Project[] {
return Array.isArray(res) ? res : res.data ?? [];
/** Tolerante con la forma de la respuesta: `{projects}` (actual), `{data}` o array. */
function normalize(res: unknown): Project[] {
if (Array.isArray(res)) return res as Project[];
const obj = (res ?? {}) as { projects?: Project[]; data?: Project[] };
return obj.projects ?? obj.data ?? [];
}
export function ProjectsScreen({ navigation }: Props) {
@@ -37,7 +40,8 @@ export function ProjectsScreen({ navigation }: Props) {
await saveProjectList(list);
}
setProjects(await getProjects());
} catch {
} catch (e) {
console.warn('No se pudo refrescar /projects, usando datos locales:', e);
setProjects(await getProjects()); // fallback offline
} finally {
setLoading(false);