feat: implement authentication flow and session management

- Update RootLayout to handle authentication state and redirect users based on their auth status.
- Create an Index component to redirect unauthenticated users to the login page.
- Modify ApiAuthRepository to fetch user session data using access and refresh tokens.
- Introduce a new container file to manage use case instances for authentication and filament operations.
- Enhance authStore to validate tokens and fetch user data from the API.
- Add babel-plugin-module-resolver for improved module imports.
- Update package.json scripts for running the app on Android and iOS.
- Add expo-camera dependency for camera functionalities.
- Update tsconfig.json to include infrastructure path mapping.
This commit is contained in:
2026-03-14 13:22:17 -03:00
parent d7fb768d3b
commit 416e13893c
68 changed files with 1778 additions and 99 deletions
+30 -4
View File
@@ -1,4 +1,4 @@
import React, { useState } from 'react';
import React, { useState, useEffect } from 'react';
import {
View, Text, ScrollView, TouchableOpacity, TextInput, StyleSheet, Alert,
} from 'react-native';
@@ -10,6 +10,7 @@ import { Ionicons } from '@expo/vector-icons';
import { SafeAreaView } from 'react-native-safe-area-context';
import { usePresetStore } from '@store/presetStore';
import { useFilamentStore } from '@store/filamentStore';
import { useAuthStore } from '@store/authStore';
import { Input } from '@presentation/components/ui/Input';
import { Button } from '@presentation/components/ui/Button';
import { Card } from '@presentation/components/ui/Card';
@@ -17,6 +18,7 @@ import { calcNetWeight } from '@domain/Filament';
import { colors, typography, spacing, radius } from '@shared/theme';
import { MATERIALS, type Material } from '@shared/constants';
import { formatWeight } from '@shared/utils/filament';
import { createFilamentUseCase } from '@infrastructure/container';
const schema = z.object({
brand: z.string().min(1, 'Marca obrigatória'),
@@ -39,6 +41,7 @@ export default function NewFilamentScreen(): React.ReactElement {
const router = useRouter();
const { presets, systemPresets } = usePresetStore();
const { addFilament } = useFilamentStore();
const { user } = useAuthStore();
const [selectedColor, setSelectedColor] = useState('#E05533');
const [hexInput, setHexInput] = useState('#E05533');
@@ -46,6 +49,13 @@ export default function NewFilamentScreen(): React.ReactElement {
const [selectedPresetId, setSelectedPresetId] = useState<string | null>(systemPresets[0]?.id ?? null);
const [isLoading, setIsLoading] = useState(false);
// Quando os presets carregam (via layout), seleciona o primeiro sistema automaticamente
useEffect(() => {
if (selectedPresetId === null && presets.length > 0) {
setSelectedPresetId(presets.find((p) => p.isSystem)?.id ?? presets[0].id);
}
}, [presets, selectedPresetId]);
const { control, handleSubmit, watch, formState: { errors } } = useForm<FormData>({
resolver: zodResolver(schema),
defaultValues: { brand: '', model: '', totalWeightG: 0, tempHotendC: 210, tempBedC: 60, flowFactorPct: 100 },
@@ -63,12 +73,28 @@ export default function NewFilamentScreen(): React.ReactElement {
Alert.alert('Atenção', 'Selecione um preset de carretel.');
return;
}
if (!user) {
Alert.alert('Erro', 'Usuário não autenticado.');
return;
}
setIsLoading(true);
try {
// TODO: CreateFilamentUseCase via container DI
console.log('create filament', { ...data, material: selectedMaterial, colorHex: selectedColor, spoolPresetId: selectedPresetId });
const filament = await createFilamentUseCase.execute(user.id, {
material: selectedMaterial,
brand: data.brand,
model: data.model ?? null,
colorHex: selectedColor,
spoolPresetId: selectedPresetId,
totalWeightG: data.totalWeightG,
tempHotendC: data.tempHotendC ?? null,
tempBedC: data.tempBedC ?? null,
flowFactorPct: data.flowFactorPct ?? null,
notes: data.notes ?? null,
});
addFilament(filament);
router.back();
} catch {
} catch (err) {
console.error('create filament error', err);
Alert.alert('Erro', 'Não foi possível salvar o filamento.');
} finally {
setIsLoading(false);