package com.example.lifegrid; import android.os.Bundle; import android.content.Intent; import android.widget.ImageView; import android.widget.TextView; import android.content.Context; import android.content.SharedPreferences; import android.net.Uri; import androidx.activity.EdgeToEdge; import androidx.appcompat.app.AppCompatActivity; import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; import androidx.fragment.app.Fragment; import com.example.lifegrid.menu.AtivosFragment; import com.example.lifegrid.menu.GraficosFragment; import com.example.lifegrid.menu.HomeFragment; import com.example.lifegrid.menu.MetasFragment; import com.example.lifegrid.menu.TransacoesFragment; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Spinner; import android.widget.Toast; import com.example.lifegrid.utils.CustomToast; import com.google.firebase.auth.FirebaseAuth; import com.google.firebase.auth.FirebaseUser; import com.google.firebase.database.DatabaseReference; import com.google.firebase.database.FirebaseDatabase; import java.util.Calendar; import java.util.ArrayList; import java.util.List; /** * TelaInicialActivity funciona como a janela mestre (Container) de navegação da aplicação. * É a responsável por carregar e trocar as visualizações menores (Fragmentos) na área principal do ecrã * mediante o clique numa série de botões situados na barra de fundo. */ public class TelaInicialActivity extends AppCompatActivity { private ImageView ivHeaderProfilePicture; private TextView tvHeaderUsername; private Spinner spinnerMes; private Spinner spinnerAno; private String[] meses = {"Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"}; private androidx.activity.result.ActivityResultLauncher takePictureLauncher; private android.net.Uri currentPhotoUri; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); EdgeToEdge.enable(this); setContentView(R.layout.activity_tela_inicial); ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> { Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); return insets; }); takePictureLauncher = registerForActivityResult( new androidx.activity.result.contract.ActivityResultContracts.TakePicture(), success -> { if (success) { processInvoiceImage(currentPhotoUri); } } ); com.google.android.material.floatingactionbutton.FloatingActionButton fabScanInvoice = findViewById(R.id.fabScanInvoice); fabScanInvoice.setOnClickListener(v -> startInvoiceScan()); ivHeaderProfilePicture = findViewById(R.id.ivHeaderProfilePicture); tvHeaderUsername = findViewById(R.id.tvHeaderUsername); spinnerMes = findViewById(R.id.spinnerMes); spinnerAno = findViewById(R.id.spinnerAno); setupSpinners(); Fragment homeFragment = new HomeFragment(); getSupportFragmentManager().beginTransaction() .replace(R.id.fragmentContainerView, homeFragment) .commit(); android.view.View.OnClickListener openTransacoesListener = v -> { updateNavSelection(findViewById(R.id.carteiraImageView)); Fragment transacoesFragment = new TransacoesFragment(); getSupportFragmentManager().beginTransaction() .replace(R.id.fragmentContainerView, transacoesFragment) .commit(); }; android.view.View.OnClickListener openHomeListener = v -> { updateNavSelection(findViewById(R.id.homeImageView)); Fragment newHomeFragment = new HomeFragment(); getSupportFragmentManager().beginTransaction() .replace(R.id.fragmentContainerView, newHomeFragment) .commit(); }; ImageView homeImageView = findViewById(R.id.homeImageView); homeImageView.setOnClickListener(openHomeListener); ImageView carteiraImageView = findViewById(R.id.carteiraImageView); carteiraImageView.setOnClickListener(openTransacoesListener); ImageView setaImageView = findViewById(R.id.setaImageView); setaImageView.setOnClickListener(v -> { updateNavSelection(setaImageView); Fragment ativosFragment = new AtivosFragment(); getSupportFragmentManager().beginTransaction() .replace(R.id.fragmentContainerView, ativosFragment) .commit(); }); ImageView graficoImageView = findViewById(R.id.graficoImageView); graficoImageView.setOnClickListener(v -> { updateNavSelection(graficoImageView); Fragment graficosFragment = new GraficosFragment(); getSupportFragmentManager().beginTransaction() .replace(R.id.fragmentContainerView, graficosFragment) .commit(); }); ImageView alvoImageView = findViewById(R.id.alvoImageView); alvoImageView.setOnClickListener(v -> { updateNavSelection(alvoImageView); Fragment metasFragment = new MetasFragment(); getSupportFragmentManager().beginTransaction() .replace(R.id.fragmentContainerView, metasFragment) .commit(); }); ImageView definicoesImageView = findViewById(R.id.definicoesImageView); definicoesImageView.setOnClickListener(v -> { updateNavSelection(definicoesImageView); Intent intent = new Intent(TelaInicialActivity.this, DefinicoesActivity.class); startActivity(intent); }); } public void startInvoiceScan() { java.io.File photoFile = new java.io.File(getFilesDir(), "invoice_" + System.currentTimeMillis() + ".jpg"); currentPhotoUri = androidx.core.content.FileProvider.getUriForFile(this, getPackageName() + ".fileprovider", photoFile); takePictureLauncher.launch(currentPhotoUri); } private void processInvoiceImage(android.net.Uri imageUri) { CustomToast.info(this, "A processar fatura com IA..."); InvoiceScannerHelper.scanInvoice(this, imageUri, new InvoiceScannerHelper.ScanCallback() { @Override public void onSuccess(double valor, String descricao, String categoria, String data) { runOnUiThread(() -> { Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.fragmentContainerView); TransacoesFragment transFragment; if (currentFragment instanceof TransacoesFragment) { transFragment = (TransacoesFragment) currentFragment; } else { updateNavSelection(findViewById(R.id.carteiraImageView)); transFragment = new TransacoesFragment(); getSupportFragmentManager().beginTransaction() .replace(R.id.fragmentContainerView, transFragment) .commit(); getSupportFragmentManager().executePendingTransactions(); } transFragment.showNovaTransacaoDialog(valor, descricao, categoria, data); // Save document to Firebase uploadDocumentoToFirebase(imageUri, descricao, data); }); } @Override public void onError(String error) { runOnUiThread(() -> CustomToast.error(TelaInicialActivity.this, error)); } }); } private void uploadDocumentoToFirebase(android.net.Uri imageUri, String descricao, String data) { FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser(); if (user == null) { CustomToast.error(this, "Utilizador não autenticado."); return; } CustomToast.info(this, "A guardar documento na Cloud..."); String fileName = "invoice_" + System.currentTimeMillis() + ".jpg"; com.google.firebase.storage.StorageReference storageRef = com.google.firebase.storage.FirebaseStorage.getInstance().getReference() .child("users/" + user.getUid() + "/documentos/" + fileName); storageRef.putFile(imageUri).addOnSuccessListener(taskSnapshot -> { storageRef.getDownloadUrl().addOnSuccessListener(uri -> { String downloadUrl = uri.toString(); DatabaseReference dbRef = FirebaseDatabase.getInstance().getReference("users") .child(user.getUid()).child("documentos").push(); com.example.lifegrid.models.Documento doc = new com.example.lifegrid.models.Documento(descricao, data, downloadUrl); dbRef.setValue(doc).addOnCompleteListener(task -> { if (task.isSuccessful()) { CustomToast.success(TelaInicialActivity.this, "Documento guardado com sucesso!"); } else { CustomToast.error(TelaInicialActivity.this, "Erro ao guardar dados na Cloud."); } }); }); }).addOnFailureListener(e -> { CustomToast.error(this, "Erro ao enviar imagem para a Cloud."); }); } @Override protected void onResume() { super.onResume(); SharedPreferences prefs = getSharedPreferences("LifeGridPrefs", Context.MODE_PRIVATE); String savedName = prefs.getString("username", ""); String savedPhotoUri = prefs.getString("profile_photo_uri", ""); if (ivHeaderProfilePicture != null && !savedPhotoUri.isEmpty()) { try { ivHeaderProfilePicture.setImageURI(Uri.parse(savedPhotoUri)); } catch (Exception e) { e.printStackTrace(); } } if (tvHeaderUsername != null) { if (!savedName.isEmpty()) { tvHeaderUsername.setText(savedName); } else { FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser(); if (user != null && user.getDisplayName() != null && !user.getDisplayName().isEmpty()) { tvHeaderUsername.setText(user.getDisplayName()); } else { tvHeaderUsername.setText("Utilizador"); } } } } private void scrollToFragment() { android.widget.ScrollView scrollView = findViewById(R.id.mainScrollView); android.view.View barraCardView = findViewById(R.id.barraCardView); if (scrollView != null && barraCardView != null) { scrollView.post(() -> scrollView.smoothScrollTo(0, barraCardView.getTop() - 20)); } } private void setupSpinners() { ArrayAdapter mesAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, meses); mesAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinnerMes.setAdapter(mesAdapter); int currentYear = Calendar.getInstance().get(Calendar.YEAR); List anos = new ArrayList<>(); for (int i = currentYear - 5; i <= currentYear + 5; i++) { anos.add(String.valueOf(i)); } ArrayAdapter anoAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, anos); anoAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinnerAno.setAdapter(anoAdapter); // Set current month and year spinnerMes.setSelection(Calendar.getInstance().get(Calendar.MONTH)); spinnerAno.setSelection(anos.indexOf(String.valueOf(currentYear))); AdapterView.OnItemSelectedListener listener = new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView parent, android.view.View view, int position, long id) { atualizarDadosHome(); } @Override public void onNothingSelected(AdapterView parent) {} }; spinnerMes.setOnItemSelectedListener(listener); spinnerAno.setOnItemSelectedListener(listener); } public void atualizarDadosHome() { Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.fragmentContainerView); int mesSelecionado = spinnerMes.getSelectedItemPosition() + 1; // 1 to 12 String anoSelecionado = spinnerAno.getSelectedItem().toString(); if (currentFragment instanceof HomeFragment) { String mesNome = meses[spinnerMes.getSelectedItemPosition()]; ((HomeFragment) currentFragment).carregarDados(mesSelecionado, anoSelecionado, mesNome); } else if (currentFragment instanceof TransacoesFragment) { ((TransacoesFragment) currentFragment).setFiltro(mesSelecionado, anoSelecionado); } else if (currentFragment instanceof GraficosFragment) { String mesNome = meses[spinnerMes.getSelectedItemPosition()]; ((GraficosFragment) currentFragment).setFiltro(mesSelecionado, anoSelecionado, mesNome); } } private void updateNavSelection(android.widget.ImageView selectedItem) { int[] ids = {R.id.homeImageView, R.id.carteiraImageView, R.id.setaImageView, R.id.graficoImageView, R.id.alvoImageView, R.id.definicoesImageView}; for (int id : ids) { android.widget.ImageView iv = findViewById(id); if (iv != null) { if (iv == selectedItem) { iv.setBackgroundResource(R.drawable.nav_item_selected_bg); } else { iv.setBackground(null); } } } } }