ja da login cria conta e vai para o menu principal.
This commit is contained in:
21
.idea/deploymentTargetSelector.xml
generated
21
.idea/deploymentTargetSelector.xml
generated
@@ -6,15 +6,28 @@
|
||||
<option name="selectionMode" value="DROPDOWN" />
|
||||
</SelectionState>
|
||||
<SelectionState runConfigName="login_activity">
|
||||
<option name="selectionMode" value="DROPDOWN" />
|
||||
<DropdownSelection timestamp="2026-01-07T08:41:59.573594Z">
|
||||
<option name="selectionMode" value="DIALOG" />
|
||||
<DropdownSelection timestamp="2026-02-03T16:06:11.417598Z">
|
||||
<Target type="DEFAULT_BOOT">
|
||||
<handle>
|
||||
<DeviceId pluginId="LocalEmulator" identifier="path=/Users/230408/.android/avd/Medium_Phone.avd" />
|
||||
<DeviceId pluginId="LocalEmulator" identifier="path=/Users/230408/.android/avd/Medium_Phone_2.avd" />
|
||||
</handle>
|
||||
</Target>
|
||||
</DropdownSelection>
|
||||
<DialogSelection />
|
||||
<DialogSelection>
|
||||
<targets>
|
||||
<Target type="DEFAULT_BOOT">
|
||||
<handle>
|
||||
<DeviceId pluginId="LocalEmulator" identifier="path=/Users/230408/.android/avd/Medium_Phone_2.avd" />
|
||||
</handle>
|
||||
</Target>
|
||||
<Target type="DEFAULT_BOOT">
|
||||
<handle>
|
||||
<DeviceId pluginId="LocalEmulator" identifier="path=/Users/230408/.android/avd/Medium_Phone.avd" />
|
||||
</handle>
|
||||
</Target>
|
||||
</targets>
|
||||
</DialogSelection>
|
||||
</SelectionState>
|
||||
</selectionStates>
|
||||
</component>
|
||||
|
||||
1
.idea/misc.xml
generated
1
.idea/misc.xml
generated
@@ -1,4 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
|
||||
|
||||
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"java.configuration.updateBuildConfiguration": "interactive"
|
||||
}
|
||||
@@ -1,3 +1,6 @@
|
||||
import java.util.Properties
|
||||
import java.io.FileInputStream
|
||||
|
||||
plugins {
|
||||
alias(libs.plugins.android.application)
|
||||
alias(libs.plugins.google.gms.google.services)
|
||||
@@ -15,6 +18,16 @@ android {
|
||||
versionName = "1.0"
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
|
||||
// Read the API key from local.properties
|
||||
val localProperties = Properties()
|
||||
val localPropertiesFile = rootProject.file("local.properties")
|
||||
if (localPropertiesFile.exists()) {
|
||||
localProperties.load(FileInputStream(localPropertiesFile))
|
||||
}
|
||||
val mapsApiKey = localProperties.getProperty("MAPS_API_KEY") ?: ""
|
||||
|
||||
manifestPlaceholders["MAPS_API_KEY"] = mapsApiKey
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
@@ -52,7 +65,11 @@ dependencies {
|
||||
implementation(libs.googleid)
|
||||
implementation("com.google.android.gms:play-services-maps:18.2.0")
|
||||
implementation("com.google.android.gms:play-services-location:21.0.1")
|
||||
implementation(libs.firebase.firestore)
|
||||
testImplementation(libs.junit)
|
||||
androidTestImplementation(libs.ext.junit)
|
||||
androidTestImplementation(libs.espresso.core)
|
||||
implementation("com.github.bumptech.glide:glide:4.16.0")
|
||||
annotationProcessor("com.github.bumptech.glide:compiler:4.16.0")
|
||||
implementation("com.google.firebase:firebase-storage:21.0.1")
|
||||
}
|
||||
@@ -15,10 +15,11 @@
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.PAP_FindU">
|
||||
|
||||
|
||||
<meta-data
|
||||
android:name="com.google.android.geo.API_KEY"
|
||||
android:value="YOUR_API_KEY_HERE" />
|
||||
android:value="AIzaSyAxen212OKqkfpu1AbWajLGTCTSdRhJWlM" />
|
||||
|
||||
<activity
|
||||
android:name=".CriarConta"
|
||||
android:exported="false" />
|
||||
@@ -28,24 +29,31 @@
|
||||
<activity
|
||||
android:name=".ChatActivity"
|
||||
android:exported="false" />
|
||||
|
||||
<activity
|
||||
android:name=".login_activity"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".AddZoneActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name">
|
||||
android:label="@string/app_name" />
|
||||
|
||||
<activity
|
||||
android:name=".EditProfileActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:name=".SecurityActivity"
|
||||
android:exported="false" />
|
||||
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
47
app/src/main/java/com/example/pap_findu/AddZoneActivity.java
Normal file
47
app/src/main/java/com/example/pap_findu/AddZoneActivity.java
Normal file
@@ -0,0 +1,47 @@
|
||||
package com.example.pap_findu;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
public class AddZoneActivity extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_add_zone);
|
||||
|
||||
ImageButton btnBack = findViewById(R.id.btnBack);
|
||||
Button btnSave = findViewById(R.id.btnSave);
|
||||
EditText editName = findViewById(R.id.editZoneName);
|
||||
EditText editAddress = findViewById(R.id.editZoneAddress);
|
||||
|
||||
// Check if opened from Map with coordinates
|
||||
if (getIntent().hasExtra("lat") && getIntent().hasExtra("lng")) {
|
||||
double lat = getIntent().getDoubleExtra("lat", 0);
|
||||
double lng = getIntent().getDoubleExtra("lng", 0);
|
||||
editAddress.setText(String.format(java.util.Locale.getDefault(), "Lat: %.5f, Lng: %.5f", lat, lng));
|
||||
}
|
||||
|
||||
btnBack.setOnClickListener(v -> finish());
|
||||
|
||||
btnSave.setOnClickListener(v -> {
|
||||
String name = editName.getText().toString();
|
||||
String address = editAddress.getText().toString();
|
||||
|
||||
if (name.isEmpty() || address.isEmpty()) {
|
||||
Toast.makeText(this, "Preencha todos os campos", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
// Here we would save to Firebase/Database
|
||||
Toast.makeText(this, "Zona '" + name + "' adicionada com sucesso!", Toast.LENGTH_LONG).show();
|
||||
finish();
|
||||
});
|
||||
}
|
||||
}
|
||||
77
app/src/main/java/com/example/pap_findu/ChatActivity.java
Normal file
77
app/src/main/java/com/example/pap_findu/ChatActivity.java
Normal file
@@ -0,0 +1,77 @@
|
||||
package com.example.pap_findu;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageButton;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.example.pap_findu.adapters.ChatAdapter;
|
||||
import com.example.pap_findu.models.ChatMessage;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class ChatActivity extends AppCompatActivity {
|
||||
|
||||
private RecyclerView recyclerChat;
|
||||
private EditText editChatMessage;
|
||||
private ImageButton btnSend;
|
||||
private ImageButton btnBack;
|
||||
private ChatAdapter adapter;
|
||||
private List<ChatMessage> messageList;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.chat_activity);
|
||||
|
||||
recyclerChat = findViewById(R.id.recycler_chat);
|
||||
editChatMessage = findViewById(R.id.edit_chat_message);
|
||||
btnSend = findViewById(R.id.btnSend);
|
||||
btnBack = findViewById(R.id.btnBack);
|
||||
|
||||
// Initialize Message List with some dummy data
|
||||
messageList = new ArrayList<>();
|
||||
messageList.add(new ChatMessage("Olá Miguel! Tudo bem?", true, "10:30"));
|
||||
messageList.add(new ChatMessage("Cheguei bem à escola.", false, "10:32"));
|
||||
messageList.add(new ChatMessage("Ainda bem! Qualquer coisa avisa.", true, "10:33"));
|
||||
|
||||
// Setup Adapter
|
||||
adapter = new ChatAdapter(messageList);
|
||||
recyclerChat.setLayoutManager(new LinearLayoutManager(this));
|
||||
recyclerChat.setAdapter(adapter);
|
||||
|
||||
// Scroll to bottom
|
||||
recyclerChat.scrollToPosition(messageList.size() - 1);
|
||||
|
||||
// Send Button Logic
|
||||
btnSend.setOnClickListener(v -> {
|
||||
String text = editChatMessage.getText().toString().trim();
|
||||
if (!TextUtils.isEmpty(text)) {
|
||||
sendMessage(text);
|
||||
}
|
||||
});
|
||||
|
||||
// Back Button Logic
|
||||
btnBack.setOnClickListener(v -> finish());
|
||||
}
|
||||
|
||||
private void sendMessage(String text) {
|
||||
String currentTime = new SimpleDateFormat("HH:mm", Locale.getDefault()).format(new Date());
|
||||
ChatMessage newMessage = new ChatMessage(text, true, currentTime);
|
||||
|
||||
messageList.add(newMessage);
|
||||
adapter.notifyItemInserted(messageList.size() - 1);
|
||||
recyclerChat.scrollToPosition(messageList.size() - 1);
|
||||
|
||||
editChatMessage.setText("");
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,10 @@ import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.example.pap_findu.models.User;
|
||||
import com.google.firebase.database.DatabaseReference;
|
||||
import com.google.firebase.database.FirebaseDatabase;
|
||||
|
||||
import androidx.activity.EdgeToEdge;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.graphics.Insets;
|
||||
@@ -62,27 +66,49 @@ public class CriarConta extends AppCompatActivity {
|
||||
} else if (!password.equals(confirmPassword)) {
|
||||
Toast.makeText(CriarConta.this, "As palavras-passe não coincidem.", Toast.LENGTH_SHORT).show();
|
||||
} else if (!checkTerms.isChecked()) {
|
||||
Toast.makeText(CriarConta.this, "Você deve concordar com os Termos de Serviço.", Toast.LENGTH_SHORT).show();
|
||||
Toast.makeText(CriarConta.this, "Você deve concordar com os Termos de Serviço.", Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
} else {
|
||||
mAuth.createUserWithEmailAndPassword(email, password)
|
||||
.addOnCompleteListener(CriarConta.this, new com.google.android.gms.tasks.OnCompleteListener<com.google.firebase.auth.AuthResult>() {
|
||||
@Override
|
||||
public void onComplete(@androidx.annotation.NonNull com.google.android.gms.tasks.Task<com.google.firebase.auth.AuthResult> task) {
|
||||
if (task.isSuccessful()) {
|
||||
// Sign in success, update UI with the signed-in user's information
|
||||
Toast.makeText(CriarConta.this, "Conta criada com sucesso!", Toast.LENGTH_SHORT).show();
|
||||
com.google.firebase.auth.FirebaseUser user = mAuth.getCurrentUser();
|
||||
// You could save the full name to the database or profile here
|
||||
Intent intent = new Intent(CriarConta.this, MainActivity.class);
|
||||
startActivity(intent);
|
||||
finish();
|
||||
} else {
|
||||
// If sign in fails, display a message to the user.
|
||||
Toast.makeText(CriarConta.this, "Falha ao criar conta: " + task.getException().getMessage(),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
});
|
||||
.addOnCompleteListener(CriarConta.this,
|
||||
new com.google.android.gms.tasks.OnCompleteListener<com.google.firebase.auth.AuthResult>() {
|
||||
@Override
|
||||
public void onComplete(
|
||||
@androidx.annotation.NonNull com.google.android.gms.tasks.Task<com.google.firebase.auth.AuthResult> task) {
|
||||
if (task.isSuccessful()) {
|
||||
// Sign in success, update UI with the signed-in user's information
|
||||
Toast.makeText(CriarConta.this, "Conta criada com sucesso!",
|
||||
Toast.LENGTH_SHORT).show();
|
||||
com.google.firebase.auth.FirebaseUser firebaseUser = mAuth
|
||||
.getCurrentUser();
|
||||
|
||||
// Save user data to Realtime Database
|
||||
if (firebaseUser != null) {
|
||||
String userId = firebaseUser.getUid();
|
||||
DatabaseReference mDatabase = FirebaseDatabase.getInstance()
|
||||
.getReference("users");
|
||||
User user = new User(fullName, email);
|
||||
|
||||
mDatabase.child(userId).setValue(user)
|
||||
.addOnCompleteListener(task1 -> {
|
||||
if (!task1.isSuccessful()) {
|
||||
Toast.makeText(CriarConta.this,
|
||||
"Falha ao salvar dados do perfil.",
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
Intent intent = new Intent(CriarConta.this, MainActivity.class);
|
||||
startActivity(intent);
|
||||
finish();
|
||||
} else {
|
||||
// If sign in fails, display a message to the user.
|
||||
Toast.makeText(CriarConta.this,
|
||||
"Falha ao criar conta: " + task.getException().getMessage(),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
201
app/src/main/java/com/example/pap_findu/EditProfileActivity.java
Normal file
201
app/src/main/java/com/example/pap_findu/EditProfileActivity.java
Normal file
@@ -0,0 +1,201 @@
|
||||
package com.example.pap_findu;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.provider.MediaStore;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.activity.result.contract.ActivityResultContracts;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.example.pap_findu.models.User;
|
||||
import com.example.pap_findu.ui.profile.ProfileFragment;
|
||||
import com.google.android.gms.tasks.OnFailureListener;
|
||||
import com.google.android.gms.tasks.OnSuccessListener;
|
||||
import com.google.android.material.button.MaterialButton;
|
||||
import com.google.android.material.textfield.TextInputEditText;
|
||||
import com.google.firebase.auth.FirebaseAuth;
|
||||
import com.google.firebase.auth.FirebaseUser;
|
||||
import com.google.firebase.database.DataSnapshot;
|
||||
import com.google.firebase.database.DatabaseError;
|
||||
import com.google.firebase.database.DatabaseReference;
|
||||
import com.google.firebase.database.FirebaseDatabase;
|
||||
import com.google.firebase.database.ValueEventListener;
|
||||
import com.google.firebase.storage.FirebaseStorage;
|
||||
import com.google.firebase.storage.StorageReference;
|
||||
import com.google.firebase.storage.UploadTask;
|
||||
|
||||
public class EditProfileActivity extends AppCompatActivity {
|
||||
|
||||
private ImageView btnBack;
|
||||
private ImageView editProfileImage;
|
||||
private View btnChangePhoto;
|
||||
private TextInputEditText editName;
|
||||
private TextInputEditText editEmail;
|
||||
private TextInputEditText editPhone;
|
||||
private MaterialButton btnSaveProfile;
|
||||
|
||||
private FirebaseAuth mAuth;
|
||||
private DatabaseReference mDatabase;
|
||||
private StorageReference mStorageRef;
|
||||
private FirebaseUser currentUser;
|
||||
private Uri selectedImageUri;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_edit_profile);
|
||||
|
||||
mAuth = FirebaseAuth.getInstance();
|
||||
currentUser = mAuth.getCurrentUser();
|
||||
mDatabase = FirebaseDatabase.getInstance().getReference("users");
|
||||
mStorageRef = FirebaseStorage.getInstance().getReference("profile_images");
|
||||
|
||||
if (currentUser == null) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
initViews();
|
||||
loadUserData();
|
||||
setupListeners();
|
||||
}
|
||||
|
||||
private void initViews() {
|
||||
btnBack = findViewById(R.id.btnBack);
|
||||
editProfileImage = findViewById(R.id.editProfileImage);
|
||||
btnChangePhoto = findViewById(R.id.btnChangePhoto);
|
||||
editName = findViewById(R.id.editName);
|
||||
editEmail = findViewById(R.id.editEmail);
|
||||
editPhone = findViewById(R.id.editPhone);
|
||||
btnSaveProfile = findViewById(R.id.btnSaveProfile);
|
||||
}
|
||||
|
||||
private void loadUserData() {
|
||||
mDatabase.child(currentUser.getUid()).addListenerForSingleValueEvent(new ValueEventListener() {
|
||||
@Override
|
||||
public void onDataChange(@NonNull DataSnapshot snapshot) {
|
||||
User user = snapshot.getValue(User.class);
|
||||
if (user != null) {
|
||||
editName.setText(user.getName());
|
||||
editEmail.setText(user.getEmail());
|
||||
editPhone.setText(user.getPhone());
|
||||
|
||||
if (user.getProfileImageUrl() != null && !user.getProfileImageUrl().isEmpty()) {
|
||||
Glide.with(EditProfileActivity.this)
|
||||
.load(user.getProfileImageUrl())
|
||||
.placeholder(R.drawable.logo)
|
||||
.into(editProfileImage);
|
||||
}
|
||||
} else {
|
||||
// Fallback to auth data if DB is empty
|
||||
editName.setText(currentUser.getDisplayName());
|
||||
editEmail.setText(currentUser.getEmail());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancelled(@NonNull DatabaseError error) {
|
||||
Toast.makeText(EditProfileActivity.this, "Erro ao carregar dados", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setupListeners() {
|
||||
btnBack.setOnClickListener(v -> finish());
|
||||
|
||||
// Image Picker Launcher
|
||||
ActivityResultLauncher<Intent> imagePickerLauncher = registerForActivityResult(
|
||||
new ActivityResultContracts.StartActivityForResult(),
|
||||
result -> {
|
||||
if (result.getResultCode() == RESULT_OK && result.getData() != null) {
|
||||
selectedImageUri = result.getData().getData();
|
||||
editProfileImage.setImageURI(selectedImageUri);
|
||||
}
|
||||
});
|
||||
|
||||
btnChangePhoto.setOnClickListener(v -> {
|
||||
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
|
||||
imagePickerLauncher.launch(intent);
|
||||
});
|
||||
|
||||
btnSaveProfile.setOnClickListener(v -> saveProfile());
|
||||
}
|
||||
|
||||
private void saveProfile() {
|
||||
String name = editName.getText().toString().trim();
|
||||
String email = editEmail.getText().toString().trim();
|
||||
String phone = editPhone.getText().toString().trim();
|
||||
|
||||
if (name.isEmpty() || email.isEmpty()) {
|
||||
Toast.makeText(this, "Nome e Email são obrigatórios", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
btnSaveProfile.setEnabled(false);
|
||||
btnSaveProfile.setText("Salvando...");
|
||||
|
||||
if (selectedImageUri != null) {
|
||||
uploadImageAndSaveUser(name, email, phone);
|
||||
} else {
|
||||
saveUserToDb(name, email, phone, null);
|
||||
}
|
||||
}
|
||||
|
||||
private void uploadImageAndSaveUser(String name, String email, String phone) {
|
||||
final StorageReference fileRef = mStorageRef.child(currentUser.getUid() + ".jpg");
|
||||
|
||||
fileRef.putFile(selectedImageUri)
|
||||
.addOnSuccessListener(taskSnapshot -> fileRef.getDownloadUrl().addOnSuccessListener(uri -> {
|
||||
String imageUrl = uri.toString();
|
||||
saveUserToDb(name, email, phone, imageUrl);
|
||||
}))
|
||||
.addOnFailureListener(e -> {
|
||||
Toast.makeText(EditProfileActivity.this, "Erro ao enviar imagem: " + e.getMessage(),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
btnSaveProfile.setEnabled(true);
|
||||
btnSaveProfile.setText("Salvar Alterações");
|
||||
});
|
||||
}
|
||||
|
||||
private void saveUserToDb(String name, String email, String phone, String imageUrl) {
|
||||
mDatabase.child(currentUser.getUid()).addListenerForSingleValueEvent(new ValueEventListener() {
|
||||
@Override
|
||||
public void onDataChange(@NonNull DataSnapshot snapshot) {
|
||||
User user = snapshot.getValue(User.class);
|
||||
if (user == null)
|
||||
user = new User();
|
||||
|
||||
user.setName(name);
|
||||
user.setEmail(email);
|
||||
user.setPhone(phone);
|
||||
if (imageUrl != null) {
|
||||
user.setProfileImageUrl(imageUrl);
|
||||
}
|
||||
|
||||
mDatabase.child(currentUser.getUid()).setValue(user)
|
||||
.addOnSuccessListener(aVoid -> {
|
||||
Toast.makeText(EditProfileActivity.this, "Perfil atualizado!", Toast.LENGTH_SHORT).show();
|
||||
finish();
|
||||
})
|
||||
.addOnFailureListener(e -> {
|
||||
Toast.makeText(EditProfileActivity.this, "Erro ao salvar perfil: " + e.getMessage(),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
btnSaveProfile.setEnabled(true);
|
||||
btnSaveProfile.setText("Salvar Alterações");
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancelled(@NonNull DatabaseError error) {
|
||||
btnSaveProfile.setEnabled(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,13 @@
|
||||
package com.example.pap_findu;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.google.android.material.bottomnavigation.BottomNavigationView;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.navigation.NavController;
|
||||
import androidx.navigation.Navigation;
|
||||
import androidx.navigation.ui.AppBarConfiguration;
|
||||
import androidx.navigation.ui.NavigationUI;
|
||||
|
||||
import com.example.pap_findu.databinding.ActivityMainBinding;
|
||||
|
||||
import androidx.navigation.fragment.NavHostFragment;
|
||||
import com.example.pap_findu.databinding.ActivityMainBinding;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
|
||||
@@ -26,6 +21,7 @@ public class MainActivity extends AppCompatActivity {
|
||||
setContentView(binding.getRoot());
|
||||
|
||||
BottomNavigationView navView = binding.navView;
|
||||
// Configurações da barra de navegação
|
||||
AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(
|
||||
R.id.navigation_map, R.id.navigation_zones, R.id.navigation_alerts,
|
||||
R.id.navigation_history, R.id.navigation_profile)
|
||||
@@ -33,8 +29,10 @@ public class MainActivity extends AppCompatActivity {
|
||||
|
||||
NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager()
|
||||
.findFragmentById(R.id.nav_host_fragment_activity_main);
|
||||
NavController navController = navHostFragment.getNavController();
|
||||
NavigationUI.setupWithNavController(binding.navView, navController);
|
||||
}
|
||||
|
||||
if (navHostFragment != null) {
|
||||
NavController navController = navHostFragment.getNavController();
|
||||
NavigationUI.setupWithNavController(binding.navView, navController);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package com.example.pap_findu;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.google.android.material.button.MaterialButton;
|
||||
import com.google.android.material.textfield.TextInputEditText;
|
||||
import com.google.firebase.auth.AuthCredential;
|
||||
import com.google.firebase.auth.EmailAuthProvider;
|
||||
import com.google.firebase.auth.FirebaseAuth;
|
||||
import com.google.firebase.auth.FirebaseUser;
|
||||
|
||||
public class SecurityActivity extends AppCompatActivity {
|
||||
|
||||
private ImageView btnBack;
|
||||
private TextInputEditText inputCurrentPassword;
|
||||
private TextInputEditText inputNewPassword;
|
||||
private TextInputEditText inputConfirmNewPassword;
|
||||
private MaterialButton btnChangePassword;
|
||||
|
||||
private FirebaseAuth mAuth;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_security);
|
||||
|
||||
mAuth = FirebaseAuth.getInstance();
|
||||
|
||||
btnBack = findViewById(R.id.btnBack);
|
||||
inputCurrentPassword = findViewById(R.id.inputCurrentPassword);
|
||||
inputNewPassword = findViewById(R.id.inputNewPassword);
|
||||
inputConfirmNewPassword = findViewById(R.id.inputConfirmNewPassword);
|
||||
btnChangePassword = findViewById(R.id.btnChangePassword);
|
||||
|
||||
btnBack.setOnClickListener(v -> finish());
|
||||
btnChangePassword.setOnClickListener(v -> changePassword());
|
||||
}
|
||||
|
||||
private void changePassword() {
|
||||
String currentPass = inputCurrentPassword.getText().toString();
|
||||
String newPass = inputNewPassword.getText().toString();
|
||||
String confirmPass = inputConfirmNewPassword.getText().toString();
|
||||
|
||||
if (currentPass.isEmpty() || newPass.isEmpty() || confirmPass.isEmpty()) {
|
||||
Toast.makeText(this, "Preencha todos os campos", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!newPass.equals(confirmPass)) {
|
||||
Toast.makeText(this, "Nova senha e confirmação não coincidem", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if (newPass.length() < 6) {
|
||||
Toast.makeText(this, "A nova senha deve ter pelo menos 6 caracteres", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
FirebaseUser user = mAuth.getCurrentUser();
|
||||
if (user != null && user.getEmail() != null) {
|
||||
btnChangePassword.setEnabled(false);
|
||||
btnChangePassword.setText("Verificando...");
|
||||
|
||||
AuthCredential credential = EmailAuthProvider.getCredential(user.getEmail(), currentPass);
|
||||
|
||||
user.reauthenticate(credential).addOnCompleteListener(task -> {
|
||||
if (task.isSuccessful()) {
|
||||
btnChangePassword.setText("Atualizando...");
|
||||
user.updatePassword(newPass).addOnCompleteListener(task1 -> {
|
||||
if (task1.isSuccessful()) {
|
||||
Toast.makeText(SecurityActivity.this, "Senha atualizada com sucesso!", Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
finish();
|
||||
} else {
|
||||
Toast.makeText(SecurityActivity.this, "Erro ao atualizar senha", Toast.LENGTH_SHORT).show();
|
||||
btnChangePassword.setEnabled(true);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Toast.makeText(SecurityActivity.this, "Senha atual incorreta", Toast.LENGTH_SHORT).show();
|
||||
btnChangePassword.setEnabled(true);
|
||||
btnChangePassword.setText("Atualizar Senha");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package com.example.pap_findu.adapters;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.example.pap_findu.R;
|
||||
import com.example.pap_findu.models.ChatMessage;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ChatAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||
private static final int VIEW_TYPE_SENT = 1;
|
||||
private static final int VIEW_TYPE_RECEIVED = 2;
|
||||
|
||||
private List<ChatMessage> messages;
|
||||
|
||||
public ChatAdapter(List<ChatMessage> messages) {
|
||||
this.messages = messages;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
ChatMessage message = messages.get(position);
|
||||
if (message.isSentByMe()) {
|
||||
return VIEW_TYPE_SENT;
|
||||
} else {
|
||||
return VIEW_TYPE_RECEIVED;
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
if (viewType == VIEW_TYPE_SENT) {
|
||||
View view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.item_chat_sent, parent, false);
|
||||
return new SentMessageHolder(view);
|
||||
} else {
|
||||
View view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.item_chat_received, parent, false);
|
||||
return new ReceivedMessageHolder(view);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
|
||||
ChatMessage message = messages.get(position);
|
||||
if (holder.getItemViewType() == VIEW_TYPE_SENT) {
|
||||
((SentMessageHolder) holder).bind(message);
|
||||
} else {
|
||||
((ReceivedMessageHolder) holder).bind(message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return messages.size();
|
||||
}
|
||||
|
||||
private static class SentMessageHolder extends RecyclerView.ViewHolder {
|
||||
TextView messageText, timeText;
|
||||
|
||||
SentMessageHolder(View itemView) {
|
||||
super(itemView);
|
||||
messageText = itemView.findViewById(R.id.text_message_body);
|
||||
timeText = itemView.findViewById(R.id.text_message_time);
|
||||
}
|
||||
|
||||
void bind(ChatMessage message) {
|
||||
messageText.setText(message.getMessage());
|
||||
timeText.setText(message.getTimestamp());
|
||||
}
|
||||
}
|
||||
|
||||
private static class ReceivedMessageHolder extends RecyclerView.ViewHolder {
|
||||
TextView messageText, timeText;
|
||||
|
||||
ReceivedMessageHolder(View itemView) {
|
||||
super(itemView);
|
||||
messageText = itemView.findViewById(R.id.text_message_body);
|
||||
timeText = itemView.findViewById(R.id.text_message_time);
|
||||
}
|
||||
|
||||
void bind(ChatMessage message) {
|
||||
messageText.setText(message.getMessage());
|
||||
timeText.setText(message.getTimestamp());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,8 @@ package com.example.pap_findu;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.text.InputType;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
@@ -9,38 +11,63 @@ import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.activity.EdgeToEdge;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.graphics.Insets;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.core.view.WindowInsetsCompat;
|
||||
|
||||
import com.google.android.gms.tasks.OnCompleteListener;
|
||||
import com.google.android.gms.tasks.Task;
|
||||
import com.google.android.material.button.MaterialButton;
|
||||
import com.google.firebase.Timestamp;
|
||||
import com.google.firebase.auth.AuthResult;
|
||||
import com.google.firebase.auth.FirebaseAuth;
|
||||
import com.google.firebase.auth.FirebaseUser;
|
||||
import com.google.firebase.firestore.DocumentSnapshot;
|
||||
import com.google.firebase.firestore.FirebaseFirestore;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class login_activity extends AppCompatActivity {
|
||||
|
||||
private EditText emailEditText;
|
||||
private EditText passwordEditText;
|
||||
private Button btnLogin;
|
||||
private TextView criarContaTextView;
|
||||
private com.google.firebase.auth.FirebaseAuth mAuth;
|
||||
|
||||
// --- NOVAS VARIÁVEIS PARA O FILHO ---
|
||||
private MaterialButton btnChildLogin;
|
||||
private FirebaseFirestore db;
|
||||
private FirebaseAuth mAuth;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
EdgeToEdge.enable(this);
|
||||
setContentView(R.layout.login_activity);
|
||||
|
||||
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;
|
||||
});
|
||||
|
||||
// Initialize Firebase Auth
|
||||
mAuth = com.google.firebase.auth.FirebaseAuth.getInstance();
|
||||
// Inicializar Firebase Auth e Firestore
|
||||
mAuth = FirebaseAuth.getInstance();
|
||||
db = FirebaseFirestore.getInstance();
|
||||
|
||||
// Vincular componentes
|
||||
emailEditText = findViewById(R.id.emailEditText);
|
||||
passwordEditText = findViewById(R.id.passwordEditText);
|
||||
btnLogin = findViewById(R.id.btnLogin);
|
||||
criarContaTextView = findViewById(R.id.criarContaTextView);
|
||||
|
||||
// Novo botão do filho (Certifique-se que adicionou no XML com id btnChildLogin)
|
||||
btnChildLogin = findViewById(R.id.btnChildLogin);
|
||||
|
||||
// --- LÓGICA 1: LOGIN DO PAI (Seu código original) ---
|
||||
btnLogin.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
@@ -53,27 +80,29 @@ public class login_activity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
mAuth.signInWithEmailAndPassword(email, password)
|
||||
.addOnCompleteListener(login_activity.this, new com.google.android.gms.tasks.OnCompleteListener<com.google.firebase.auth.AuthResult>() {
|
||||
.addOnCompleteListener(login_activity.this, new OnCompleteListener<AuthResult>() {
|
||||
@Override
|
||||
public void onComplete(@androidx.annotation.NonNull com.google.android.gms.tasks.Task<com.google.firebase.auth.AuthResult> task) {
|
||||
public void onComplete(@NonNull Task<AuthResult> task) {
|
||||
if (task.isSuccessful()) {
|
||||
// Sign in success, update UI with the signed-in user's information
|
||||
com.google.firebase.auth.FirebaseUser user = mAuth.getCurrentUser();
|
||||
Toast.makeText(login_activity.this, "Login com sucesso.",
|
||||
Toast.LENGTH_SHORT).show();
|
||||
Intent intent = new Intent(login_activity.this, MainActivity.class);
|
||||
startActivity(intent);
|
||||
finish();
|
||||
Toast.makeText(login_activity.this, "Login com sucesso.", Toast.LENGTH_SHORT).show();
|
||||
goToMainActivity();
|
||||
} else {
|
||||
// If sign in fails, display a message to the user.
|
||||
Toast.makeText(login_activity.this, "Falha na autenticação.",
|
||||
Toast.LENGTH_SHORT).show();
|
||||
Toast.makeText(login_activity.this, "Falha na autenticação.", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// --- LÓGICA 2: LOGIN DO FILHO (Novo código) ---
|
||||
btnChildLogin.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
showChildLoginDialog();
|
||||
}
|
||||
});
|
||||
|
||||
// --- LÓGICA 3: CRIAR CONTA ---
|
||||
criarContaTextView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
@@ -86,12 +115,92 @@ public class login_activity extends AppCompatActivity {
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
// Check if user is signed in (non-null) and update UI accordingly.
|
||||
com.google.firebase.auth.FirebaseUser currentUser = mAuth.getCurrentUser();
|
||||
// Verifica se já está logado
|
||||
FirebaseUser currentUser = mAuth.getCurrentUser();
|
||||
if(currentUser != null){
|
||||
Intent intent = new Intent(login_activity.this, MainActivity.class);
|
||||
startActivity(intent);
|
||||
finish();
|
||||
goToMainActivity();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void goToMainActivity() {
|
||||
Intent intent = new Intent(login_activity.this, MainActivity.class);
|
||||
// Limpa a pilha para não voltar ao login com o botão voltar
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
startActivity(intent);
|
||||
finish();
|
||||
}
|
||||
|
||||
// ==========================================================
|
||||
// MÉTODOS DE LOGIN DO FILHO
|
||||
// ==========================================================
|
||||
|
||||
private void showChildLoginDialog() {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setTitle("Acesso do Filho");
|
||||
builder.setMessage("Digite o código de 6 dígitos gerado pelo pai:");
|
||||
|
||||
// Cria uma caixa de texto dentro do alerta
|
||||
final EditText inputCode = new EditText(this);
|
||||
inputCode.setInputType(InputType.TYPE_CLASS_NUMBER);
|
||||
inputCode.setHint("Ex: 123456");
|
||||
builder.setView(inputCode);
|
||||
|
||||
// Botão Entrar do Alerta
|
||||
builder.setPositiveButton("Entrar", (dialog, which) -> {
|
||||
String code = inputCode.getText().toString().trim();
|
||||
if (!TextUtils.isEmpty(code)) {
|
||||
verifyChildCode(code);
|
||||
} else {
|
||||
Toast.makeText(login_activity.this, "Código vazio.", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
|
||||
builder.setNegativeButton("Cancelar", (dialog, which) -> dialog.cancel());
|
||||
builder.show();
|
||||
}
|
||||
|
||||
private void verifyChildCode(String code) {
|
||||
// Verifica no Firestore se o código existe
|
||||
db.collection("login_codes").document(code).get()
|
||||
.addOnSuccessListener(document -> {
|
||||
if (document.exists()) {
|
||||
boolean used = Boolean.TRUE.equals(document.getBoolean("used"));
|
||||
Timestamp expiresAt = document.getTimestamp("expiresAt");
|
||||
|
||||
// Validações
|
||||
if (used) {
|
||||
Toast.makeText(this, "Este código já foi usado.", Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
if (expiresAt != null && expiresAt.toDate().before(new Date())) {
|
||||
Toast.makeText(this, "O código expirou.", Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
// SUCESSO: O código é bom!
|
||||
String parentId = document.getString("parentId");
|
||||
loginChildAnonymously(code, parentId);
|
||||
|
||||
} else {
|
||||
Toast.makeText(this, "Código inválido.", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
})
|
||||
.addOnFailureListener(e -> Toast.makeText(this, "Erro de conexão.", Toast.LENGTH_SHORT).show());
|
||||
}
|
||||
|
||||
private void loginChildAnonymously(String code, String parentId) {
|
||||
// Faz login anônimo (sem email)
|
||||
mAuth.signInAnonymously()
|
||||
.addOnCompleteListener(this, task -> {
|
||||
if (task.isSuccessful()) {
|
||||
// 1. Invalida o código para ninguém usar de novo
|
||||
db.collection("login_codes").document(code).update("used", true);
|
||||
|
||||
Toast.makeText(this, "Conectado como Filho!", Toast.LENGTH_SHORT).show();
|
||||
goToMainActivity();
|
||||
} else {
|
||||
Toast.makeText(this, "Erro no login anônimo.", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.example.pap_findu.models;
|
||||
|
||||
public class ChatMessage {
|
||||
private String message;
|
||||
private boolean isSentByMe;
|
||||
private String timestamp;
|
||||
|
||||
public ChatMessage(String message, boolean isSentByMe, String timestamp) {
|
||||
this.message = message;
|
||||
this.isSentByMe = isSentByMe;
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public boolean isSentByMe() {
|
||||
return isSentByMe;
|
||||
}
|
||||
|
||||
public String getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
}
|
||||
49
app/src/main/java/com/example/pap_findu/models/User.java
Normal file
49
app/src/main/java/com/example/pap_findu/models/User.java
Normal file
@@ -0,0 +1,49 @@
|
||||
package com.example.pap_findu.models;
|
||||
|
||||
public class User {
|
||||
private String name;
|
||||
private String email;
|
||||
private String profileImageUrl;
|
||||
private String phone;
|
||||
|
||||
public User() {
|
||||
// Default constructor required for calls to DataSnapshot.getValue(User.class)
|
||||
}
|
||||
|
||||
public User(String name, String email) {
|
||||
this.name = name;
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getProfileImageUrl() {
|
||||
return profileImageUrl;
|
||||
}
|
||||
|
||||
public void setProfileImageUrl(String profileImageUrl) {
|
||||
this.profileImageUrl = profileImageUrl;
|
||||
}
|
||||
|
||||
public String getPhone() {
|
||||
return phone;
|
||||
}
|
||||
|
||||
public void setPhone(String phone) {
|
||||
this.phone = phone;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package com.example.pap_findu.ui.home;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.example.pap_findu.R;
|
||||
import com.google.firebase.Timestamp;
|
||||
import com.google.firebase.firestore.FirebaseFirestore;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class HomeFragment extends Fragment {
|
||||
|
||||
private Button btnAddChild;
|
||||
private FirebaseFirestore db;
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||
ViewGroup container, Bundle savedInstanceState) {
|
||||
|
||||
// 1. AQUI É O SEGREDO: Ele vai carregar o design do 'fragment_home.xml'
|
||||
// Se o seu arquivo XML com o design azul tiver outro nome, mude aqui.
|
||||
View root = inflater.inflate(R.layout.fragment_home, container, false);
|
||||
|
||||
// 2. Inicializar o Firebase e o Botão
|
||||
db = FirebaseFirestore.getInstance();
|
||||
btnAddChild = root.findViewById(R.id.btnAddChild);
|
||||
|
||||
// 3. Ação do Botão
|
||||
if (btnAddChild != null) {
|
||||
btnAddChild.setOnClickListener(v -> {
|
||||
// Substitua pelo ID real do pai logado depois
|
||||
String parentId = "ID_DO_PAI_TESTE";
|
||||
generateCode(parentId);
|
||||
});
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
private void generateCode(String parentId) {
|
||||
String code = String.valueOf((int)(Math.random() * 900000) + 100000);
|
||||
Timestamp expiresAt = new Timestamp(new Date(System.currentTimeMillis() + 10 * 60 * 1000));
|
||||
|
||||
Map<String, Object> codeMap = new HashMap<>();
|
||||
codeMap.put("parentId", parentId);
|
||||
codeMap.put("expiresAt", expiresAt);
|
||||
codeMap.put("used", false);
|
||||
|
||||
db.collection("login_codes").document(code)
|
||||
.set(codeMap)
|
||||
.addOnSuccessListener(aVoid -> showCodeDialog(code))
|
||||
.addOnFailureListener(e -> Toast.makeText(getContext(), "Erro ao criar código", Toast.LENGTH_SHORT).show());
|
||||
}
|
||||
|
||||
private void showCodeDialog(String code) {
|
||||
if (getContext() == null) return;
|
||||
|
||||
new AlertDialog.Builder(getContext())
|
||||
.setTitle("Adicionar Novo Filho")
|
||||
.setMessage("Código de acesso: " + code)
|
||||
.setPositiveButton("Copiar", (dialog, which) -> {
|
||||
ClipboardManager clipboard = (ClipboardManager) requireContext().getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
ClipData clip = ClipData.newPlainText("Código", code);
|
||||
clipboard.setPrimaryClip(clip);
|
||||
Toast.makeText(getContext(), "Copiado!", Toast.LENGTH_SHORT).show();
|
||||
})
|
||||
.setNegativeButton("Fechar", null)
|
||||
.show();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
package com.example.pap_findu.ui.map;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.example.pap_findu.R;
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
|
||||
import com.google.android.material.textfield.TextInputEditText;
|
||||
import com.google.firebase.Timestamp;
|
||||
import com.google.firebase.auth.FirebaseAuth;
|
||||
import com.google.firebase.firestore.FirebaseFirestore;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class AddChildBottomSheet extends BottomSheetDialogFragment {
|
||||
|
||||
private TextInputEditText etChildName;
|
||||
private Button btnSaveChild;
|
||||
private FirebaseFirestore db;
|
||||
private FirebaseAuth auth;
|
||||
|
||||
// Interface para avisar o MapFragment que o código foi gerado
|
||||
public interface OnChildCreatedListener {
|
||||
void onCodeGenerated(String code);
|
||||
}
|
||||
|
||||
private OnChildCreatedListener listener;
|
||||
|
||||
public void setListener(OnChildCreatedListener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
|
||||
// ⚠️ IMPORTANTE: O nome aqui deve ser igual ao do seu arquivo XML
|
||||
// Se o seu arquivo XML se chama 'bottom_add_child.xml', mude abaixo para R.layout.bottom_add_child
|
||||
View view = inflater.inflate(R.layout.bottom_sheet_add_child, container, false);
|
||||
|
||||
db = FirebaseFirestore.getInstance();
|
||||
auth = FirebaseAuth.getInstance();
|
||||
|
||||
// Vincula os campos do XML
|
||||
// Certifique-se que no seu XML os IDs são: @+id/etChildName e @+id/btnSaveChild
|
||||
etChildName = view.findViewById(R.id.etChildName);
|
||||
btnSaveChild = view.findViewById(R.id.btnSaveChild);
|
||||
|
||||
if (btnSaveChild != null) {
|
||||
btnSaveChild.setOnClickListener(v -> saveChildData());
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
private void saveChildData() {
|
||||
if (etChildName == null) return;
|
||||
|
||||
String name = etChildName.getText().toString().trim();
|
||||
|
||||
if (TextUtils.isEmpty(name)) {
|
||||
etChildName.setError("Nome é obrigatório");
|
||||
return;
|
||||
}
|
||||
|
||||
if (auth.getCurrentUser() == null) return;
|
||||
String parentId = auth.getCurrentUser().getUid();
|
||||
|
||||
// 1. Gera código aleatório de 6 dígitos
|
||||
String code = String.valueOf((int)(Math.random() * 900000) + 100000);
|
||||
Timestamp createdAt = new Timestamp(new Date());
|
||||
|
||||
// 2. Prepara os dados do filho
|
||||
Map<String, Object> childMap = new HashMap<>();
|
||||
childMap.put("name", name);
|
||||
childMap.put("parentId", parentId);
|
||||
childMap.put("createdAt", createdAt);
|
||||
childMap.put("linked", false);
|
||||
childMap.put("accessCode", code);
|
||||
|
||||
// 3. Salva na coleção 'children'
|
||||
db.collection("children")
|
||||
.add(childMap)
|
||||
.addOnSuccessListener(documentReference -> {
|
||||
// 4. Se salvou o filho, agora salva o código de login
|
||||
saveLoginCode(parentId, code);
|
||||
})
|
||||
.addOnFailureListener(e -> {
|
||||
Toast.makeText(getContext(), "Erro ao salvar", Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
}
|
||||
|
||||
private void saveLoginCode(String parentId, String code) {
|
||||
// Código válido por 10 minutos
|
||||
Timestamp expiresAt = new Timestamp(new Date(System.currentTimeMillis() + 10 * 60 * 1000));
|
||||
|
||||
Map<String, Object> codeMap = new HashMap<>();
|
||||
codeMap.put("parentId", parentId);
|
||||
codeMap.put("expiresAt", expiresAt);
|
||||
codeMap.put("used", false); // Importante para ser usado apenas uma vez
|
||||
|
||||
db.collection("login_codes").document(code)
|
||||
.set(codeMap)
|
||||
.addOnSuccessListener(aVoid -> {
|
||||
// Sucesso! Avisa a tela anterior e fecha a janela
|
||||
if (listener != null) {
|
||||
listener.onCodeGenerated(code);
|
||||
}
|
||||
dismiss();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,105 +1,138 @@
|
||||
package com.example.pap_findu.ui.map;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.example.pap_findu.R;
|
||||
import com.example.pap_findu.databinding.FragmentMapBinding;
|
||||
import com.google.android.gms.maps.SupportMapFragment;
|
||||
import com.google.firebase.auth.FirebaseAuth;
|
||||
import com.google.firebase.auth.FirebaseUser;
|
||||
import com.google.firebase.firestore.FirebaseFirestore;
|
||||
import com.google.firebase.firestore.QuerySnapshot;
|
||||
|
||||
public class MapFragment extends Fragment {
|
||||
|
||||
private FragmentMapBinding binding;
|
||||
private com.google.android.gms.maps.GoogleMap mMap;
|
||||
private Button btnAddChild;
|
||||
private View layoutEmptyState;
|
||||
private View mapContainer;
|
||||
private FirebaseFirestore db;
|
||||
private FirebaseAuth auth;
|
||||
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
binding = FragmentMapBinding.inflate(inflater, container, false);
|
||||
View root = binding.getRoot();
|
||||
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||
ViewGroup container, Bundle savedInstanceState) {
|
||||
|
||||
// Initialize Map
|
||||
com.google.android.gms.maps.SupportMapFragment mapFragment = (com.google.android.gms.maps.SupportMapFragment) getChildFragmentManager()
|
||||
.findFragmentById(R.id.map);
|
||||
if (mapFragment != null) {
|
||||
mapFragment.getMapAsync(googleMap -> {
|
||||
mMap = googleMap;
|
||||
// Check permissions and enable My Location
|
||||
if (androidx.core.content.ContextCompat.checkSelfPermission(requireContext(),
|
||||
android.Manifest.permission.ACCESS_FINE_LOCATION) == android.content.pm.PackageManager.PERMISSION_GRANTED) {
|
||||
mMap.setMyLocationEnabled(true);
|
||||
View root = inflater.inflate(R.layout.fragment_map, container, false);
|
||||
|
||||
// Move camera to finding User or Default
|
||||
com.google.android.gms.location.LocationServices.getFusedLocationProviderClient(requireActivity())
|
||||
.getLastLocation()
|
||||
.addOnSuccessListener(location -> {
|
||||
if (location != null) {
|
||||
com.google.android.gms.maps.model.LatLng current = new com.google.android.gms.maps.model.LatLng(
|
||||
location.getLatitude(), location.getLongitude());
|
||||
mMap.moveCamera(com.google.android.gms.maps.CameraUpdateFactory
|
||||
.newLatLngZoom(current, 15f));
|
||||
} else {
|
||||
// Default to Escola Profissional de Vila do Conde
|
||||
com.google.android.gms.maps.model.LatLng school = new com.google.android.gms.maps.model.LatLng(
|
||||
41.3536, -8.7424);
|
||||
mMap.moveCamera(
|
||||
com.google.android.gms.maps.CameraUpdateFactory.newLatLngZoom(school, 15f));
|
||||
}
|
||||
});
|
||||
db = FirebaseFirestore.getInstance();
|
||||
auth = FirebaseAuth.getInstance();
|
||||
|
||||
// Agora o Java vai encontrar estes IDs porque colocamos no XML acima
|
||||
layoutEmptyState = root.findViewById(R.id.layoutEmptyState);
|
||||
mapContainer = root.findViewById(R.id.mapContainer);
|
||||
btnAddChild = root.findViewById(R.id.btnAddChild);
|
||||
|
||||
if (btnAddChild != null) {
|
||||
btnAddChild.setOnClickListener(v -> {
|
||||
FirebaseUser user = auth.getCurrentUser();
|
||||
if (user != null) {
|
||||
openAddChildScreen(); // Agora esta função existe lá embaixo
|
||||
} else {
|
||||
// Request permissions (Simplified for brevity, usually should use
|
||||
// RequestPermissionLauncher)
|
||||
requestPermissions(new String[] { android.Manifest.permission.ACCESS_FINE_LOCATION }, 100);
|
||||
Toast.makeText(getContext(), "Erro: Utilizador não autenticado", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
mMap.setOnMapLongClickListener(latLng -> {
|
||||
android.content.Intent intent = new android.content.Intent(getContext(),
|
||||
com.example.pap_findu.AddZoneActivity.class);
|
||||
intent.putExtra("lat", latLng.latitude);
|
||||
intent.putExtra("lng", latLng.longitude);
|
||||
startActivity(intent);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Implement SOS Button logic
|
||||
binding.sosButton.setOnClickListener(v -> {
|
||||
android.content.Intent intent = new android.content.Intent(android.content.Intent.ACTION_DIAL);
|
||||
intent.setData(android.net.Uri.parse("tel:112"));
|
||||
startActivity(intent);
|
||||
});
|
||||
|
||||
// Add dummy listeners for other interactive elements
|
||||
binding.zoomInButton.setOnClickListener(v -> {
|
||||
// Placeholder: Zoom In logic would go here if we had a real map
|
||||
android.widget.Toast.makeText(getContext(), "Zoom In", android.widget.Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
|
||||
binding.zoomOutButton.setOnClickListener(v -> {
|
||||
// Placeholder: Zoom Out logic
|
||||
android.widget.Toast.makeText(getContext(), "Zoom Out", android.widget.Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
|
||||
binding.navigationFab.setOnClickListener(v -> {
|
||||
android.widget.Toast.makeText(getContext(), "Centrar Localização", android.widget.Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
});
|
||||
|
||||
binding.messagesFab.setOnClickListener(v -> {
|
||||
android.content.Intent intent = new android.content.Intent(getContext(),
|
||||
com.example.pap_findu.ChatActivity.class);
|
||||
startActivity(intent);
|
||||
});
|
||||
checkUserTypeAndShowScreen();
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
binding = null;
|
||||
private void checkUserTypeAndShowScreen() {
|
||||
FirebaseUser user = auth.getCurrentUser();
|
||||
if (user == null) return;
|
||||
|
||||
if (user.isAnonymous()) {
|
||||
if (btnAddChild != null) btnAddChild.setVisibility(View.GONE);
|
||||
showMapState();
|
||||
return;
|
||||
}
|
||||
|
||||
checkIfHasChildren();
|
||||
}
|
||||
}
|
||||
|
||||
private void checkIfHasChildren() {
|
||||
FirebaseUser user = auth.getCurrentUser();
|
||||
if (user == null) return;
|
||||
|
||||
db.collection("children")
|
||||
.whereEqualTo("parentId", user.getUid())
|
||||
.limit(1)
|
||||
.get()
|
||||
.addOnCompleteListener(task -> {
|
||||
if (task.isSuccessful()) {
|
||||
QuerySnapshot snapshot = task.getResult();
|
||||
if (snapshot != null && !snapshot.isEmpty()) {
|
||||
showMapState();
|
||||
} else {
|
||||
showEmptyState();
|
||||
}
|
||||
} else {
|
||||
showEmptyState();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void showMapState() {
|
||||
if (layoutEmptyState != null) layoutEmptyState.setVisibility(View.GONE);
|
||||
if (mapContainer != null) mapContainer.setVisibility(View.VISIBLE);
|
||||
|
||||
Fragment existingMap = getChildFragmentManager().findFragmentById(R.id.mapContainer);
|
||||
if (existingMap == null) {
|
||||
SupportMapFragment googleMapFragment = SupportMapFragment.newInstance();
|
||||
getChildFragmentManager().beginTransaction()
|
||||
.replace(R.id.mapContainer, googleMapFragment)
|
||||
.commit();
|
||||
}
|
||||
}
|
||||
|
||||
private void showEmptyState() {
|
||||
if (layoutEmptyState != null) layoutEmptyState.setVisibility(View.VISIBLE);
|
||||
if (mapContainer != null) mapContainer.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
// Esta é a função que estava faltando ou mal fechada
|
||||
private void openAddChildScreen() {
|
||||
AddChildBottomSheet bottomSheet = new AddChildBottomSheet();
|
||||
|
||||
bottomSheet.setListener(code -> {
|
||||
showCodeDialog(code);
|
||||
});
|
||||
|
||||
bottomSheet.show(getParentFragmentManager(), "AddChildSheet");
|
||||
}
|
||||
|
||||
private void showCodeDialog(String code) {
|
||||
if (getContext() == null) return;
|
||||
new AlertDialog.Builder(getContext())
|
||||
.setTitle("Perfil Criado!")
|
||||
.setMessage("Digite este código no telemóvel do filho:\n\n" + code)
|
||||
.setPositiveButton("Copiar Código", (dialog, which) -> {
|
||||
ClipboardManager clipboard = (ClipboardManager) requireContext().getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
ClipData clip = ClipData.newPlainText("Código", code);
|
||||
clipboard.setPrimaryClip(clip);
|
||||
Toast.makeText(getContext(), "Copiado!", Toast.LENGTH_SHORT).show();
|
||||
})
|
||||
.show();
|
||||
}
|
||||
}
|
||||
@@ -1,41 +1,126 @@
|
||||
package com.example.pap_findu.ui.profile;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.example.pap_findu.EditProfileActivity;
|
||||
import com.example.pap_findu.R;
|
||||
import com.example.pap_findu.SecurityActivity;
|
||||
import com.example.pap_findu.databinding.FragmentProfileBinding;
|
||||
import com.example.pap_findu.models.User;
|
||||
import com.google.firebase.auth.FirebaseAuth;
|
||||
import com.google.firebase.auth.FirebaseUser;
|
||||
import com.google.firebase.database.DataSnapshot;
|
||||
import com.google.firebase.database.DatabaseError;
|
||||
import com.google.firebase.database.DatabaseReference;
|
||||
import com.google.firebase.database.FirebaseDatabase;
|
||||
import com.google.firebase.database.ValueEventListener;
|
||||
|
||||
public class ProfileFragment extends Fragment {
|
||||
|
||||
private FragmentProfileBinding binding;
|
||||
private FirebaseAuth mAuth;
|
||||
private DatabaseReference mDatabase;
|
||||
private ValueEventListener mUserListener;
|
||||
private DatabaseReference mUserRef;
|
||||
|
||||
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||
ViewGroup container, Bundle savedInstanceState) {
|
||||
binding = FragmentProfileBinding.inflate(inflater, container, false);
|
||||
View root = binding.getRoot();
|
||||
|
||||
binding.btnLogout.setOnClickListener(v -> {
|
||||
// Sign out of Firebase
|
||||
com.google.firebase.auth.FirebaseAuth.getInstance().signOut();
|
||||
mAuth = FirebaseAuth.getInstance();
|
||||
FirebaseUser currentUser = mAuth.getCurrentUser();
|
||||
|
||||
// Navigate back to Login Activity
|
||||
android.content.Intent intent = new android.content.Intent(getActivity(),
|
||||
com.example.pap_findu.login_activity.class);
|
||||
intent.setFlags(
|
||||
android.content.Intent.FLAG_ACTIVITY_NEW_TASK | android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
startActivity(intent);
|
||||
});
|
||||
if (currentUser == null) {
|
||||
// Should prompt login or handle error
|
||||
return root;
|
||||
}
|
||||
|
||||
mDatabase = FirebaseDatabase.getInstance().getReference("users");
|
||||
mUserRef = mDatabase.child(currentUser.getUid());
|
||||
|
||||
setupListeners();
|
||||
|
||||
// Listen for user data changes
|
||||
mUserListener = new ValueEventListener() {
|
||||
@Override
|
||||
public void onDataChange(@NonNull DataSnapshot snapshot) {
|
||||
if (getContext() == null)
|
||||
return;
|
||||
|
||||
User user = snapshot.getValue(User.class);
|
||||
if (user != null) {
|
||||
binding.profileName.setText(user.getName());
|
||||
binding.profileEmail.setText(user.getEmail());
|
||||
|
||||
if (user.getProfileImageUrl() != null && !user.getProfileImageUrl().isEmpty()) {
|
||||
Glide.with(ProfileFragment.this)
|
||||
.load(user.getProfileImageUrl())
|
||||
.placeholder(R.drawable.logo) // Make sure logo exists or use R.mipmap.ic_launcher
|
||||
.into(binding.profileImage);
|
||||
} else {
|
||||
binding.profileImage.setImageResource(R.drawable.logo);
|
||||
}
|
||||
} else {
|
||||
// Fallback to Auth data if DB is empty
|
||||
binding.profileName.setText(
|
||||
currentUser.getDisplayName() != null ? currentUser.getDisplayName() : "Utilizador");
|
||||
binding.profileEmail.setText(currentUser.getEmail());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancelled(@NonNull DatabaseError error) {
|
||||
if (getContext() != null)
|
||||
Toast.makeText(getContext(), "Erro ao carregar perfil", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
};
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
private void setupListeners() {
|
||||
binding.layoutEditProfile.setOnClickListener(v -> {
|
||||
startActivity(new Intent(getActivity(), EditProfileActivity.class));
|
||||
});
|
||||
|
||||
binding.layoutSecurity.setOnClickListener(v -> {
|
||||
startActivity(new Intent(getActivity(), SecurityActivity.class));
|
||||
});
|
||||
|
||||
binding.btnLogout.setOnClickListener(v -> {
|
||||
mAuth.signOut();
|
||||
Intent intent = new Intent(getActivity(), com.example.pap_findu.login_activity.class);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
startActivity(intent);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
if (mUserRef != null && mUserListener != null) {
|
||||
mUserRef.addValueEventListener(mUserListener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
if (mUserRef != null && mUserListener != null) {
|
||||
mUserRef.removeEventListener(mUserListener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
|
||||
7
app/src/main/res/drawable/bg_chat_received.xml
Normal file
7
app/src/main/res/drawable/bg_chat_received.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="#FFFFFF"/>
|
||||
<stroke android:width="1dp" android:color="#E5E7EB"/>
|
||||
<corners android:radius="16dp"
|
||||
android:bottomLeftRadius="4dp"/>
|
||||
</shape>
|
||||
6
app/src/main/res/drawable/bg_chat_sent.xml
Normal file
6
app/src/main/res/drawable/bg_chat_sent.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="#1F6AEF"/>
|
||||
<corners android:radius="16dp"
|
||||
android:bottomRightRadius="4dp"/>
|
||||
</shape>
|
||||
4
app/src/main/res/drawable/bg_circle_button.xml
Normal file
4
app/src/main/res/drawable/bg_circle_button.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="oval">
|
||||
<solid android:color="#3B82F6"/>
|
||||
</shape>
|
||||
3
app/src/main/res/drawable/bg_circle_light_blue.xml
Normal file
3
app/src/main/res/drawable/bg_circle_light_blue.xml
Normal file
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
|
||||
<solid android:color="#E3F2FD"/> </shape>
|
||||
4
app/src/main/res/drawable/bg_header_rounded.xml
Normal file
4
app/src/main/res/drawable/bg_header_rounded.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
|
||||
<solid android:color="#3D6DFF"/> <corners android:bottomLeftRadius="30dp" android:bottomRightRadius="30dp" />
|
||||
</shape>
|
||||
9
app/src/main/res/drawable/ic_add.xml
Normal file
9
app/src/main/res/drawable/ic_add.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
|
||||
</vector>
|
||||
9
app/src/main/res/drawable/ic_arrow_back.xml
Normal file
9
app/src/main/res/drawable/ic_arrow_back.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
|
||||
</vector>
|
||||
86
app/src/main/res/layout/activity_add_zone.xml
Normal file
86
app/src/main/res/layout/activity_add_zone.xml
Normal file
@@ -0,0 +1,86 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#F3F6FB"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/bg_header_top"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:padding="20dp">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/btnBack"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:rotation="180"
|
||||
android:src="@drawable/ic_navigation_plane"
|
||||
android:tint="#FFFFFF" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:text="Adicionar Zona"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="24dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Nome da Zona"
|
||||
android:textColor="#1F2937"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/editZoneName"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:background="@drawable/edit_text_background"
|
||||
android:hint="Ex: Casa, Escola"
|
||||
android:padding="16dp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:text="Endereço ou Localização"
|
||||
android:textColor="#1F2937"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/editZoneAddress"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:background="@drawable/edit_text_background"
|
||||
android:hint="Digite o endereço..."
|
||||
android:padding="16dp" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnSave"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="32dp"
|
||||
android:backgroundTint="#1F6AEF"
|
||||
android:text="Guardar Zona"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
139
app/src/main/res/layout/activity_edit_profile.xml
Normal file
139
app/src/main/res/layout/activity_edit_profile.xml
Normal file
@@ -0,0 +1,139 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/main"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:background="#F6F7FB"
|
||||
tools:context=".EditProfileActivity">
|
||||
|
||||
<!-- Header -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="16dp"
|
||||
android:background="#FFFFFF"
|
||||
android:elevation="4dp"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/btnBack"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:src="@drawable/ic_arrow_back"
|
||||
app:tint="#1F2937"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:clickable="true" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:text="Editar Perfil"
|
||||
android:textColor="#1F2937"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="24dp"
|
||||
android:gravity="center_horizontal">
|
||||
|
||||
<!-- Profile Image -->
|
||||
<FrameLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.google.android.material.imageview.ShapeableImageView
|
||||
android:id="@+id/editProfileImage"
|
||||
android:layout_width="120dp"
|
||||
android:layout_height="120dp"
|
||||
android:background="#E5E7EB"
|
||||
android:scaleType="centerCrop"
|
||||
app:shapeAppearanceOverlay="@style/ShapeAppearance.MaterialComponents.MediumComponent"
|
||||
android:src="@drawable/logo" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:background="@drawable/bg_circle_button"
|
||||
android:padding="6dp"
|
||||
android:src="@android:drawable/ic_menu_camera"
|
||||
app:tint="#FFFFFF" />
|
||||
</FrameLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/btnChangePhoto"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="Alterar Foto"
|
||||
android:textColor="#3B82F6"
|
||||
android:textStyle="bold"
|
||||
android:clickable="true"
|
||||
android:background="?attr/selectableItemBackground" />
|
||||
|
||||
<!-- Form -->
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="32dp"
|
||||
android:hint="Nome Completo"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/editName"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="textPersonName" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:hint="Email"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/editEmail"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="textEmailAddress" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:hint="Telefone (Opcional)"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/editPhone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="phone" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btnSaveProfile"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="60dp"
|
||||
android:layout_marginTop="40dp"
|
||||
android:text="Salvar Alterações"
|
||||
app:cornerRadius="12dp" />
|
||||
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
</LinearLayout>
|
||||
@@ -1,12 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#F3F6FB"
|
||||
tools:context=".MainActivity">
|
||||
android:background="#F3F6FB">
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/nav_host_fragment_activity_main"
|
||||
@@ -14,29 +12,20 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:defaultNavHost="true"
|
||||
app:navGraph="@navigation/mobile_navigation"
|
||||
app:layout_constraintBottom_toTopOf="@+id/nav_view"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:navGraph="@navigation/mobile_navigation" />
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<com.google.android.material.bottomnavigation.BottomNavigationView
|
||||
android:id="@+id/nav_view"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:background="@drawable/bg_bottom_nav"
|
||||
android:paddingTop="6dp"
|
||||
android:paddingBottom="10dp"
|
||||
app:itemIconSize="24dp"
|
||||
app:itemIconTint="@color/bottom_nav_selector"
|
||||
app:itemTextColor="@color/bottom_nav_selector"
|
||||
app:labelVisibilityMode="labeled"
|
||||
app:menu="@menu/bottom_tabs"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:menu="@menu/bottom_tabs" />
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
113
app/src/main/res/layout/activity_security.xml
Normal file
113
app/src/main/res/layout/activity_security.xml
Normal file
@@ -0,0 +1,113 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/main"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:background="#F6F7FB"
|
||||
tools:context=".SecurityActivity">
|
||||
|
||||
<!-- Header -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="16dp"
|
||||
android:background="#FFFFFF"
|
||||
android:elevation="4dp"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/btnBack"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:src="@drawable/ic_arrow_back"
|
||||
app:tint="#1F2937"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:clickable="true" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:text="Segurança e Senha"
|
||||
android:textColor="#1F2937"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="24dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Alterar Palavra-passe"
|
||||
android:textColor="#374151"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
android:layout_marginBottom="16dp"/>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="Palavra-passe Atual"
|
||||
app:endIconMode="password_toggle"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/inputCurrentPassword"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="textPassword" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:hint="Nova Palavra-passe"
|
||||
app:endIconMode="password_toggle"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/inputNewPassword"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="textPassword" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:hint="Confirmar Nova Palavra-passe"
|
||||
app:endIconMode="password_toggle"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/inputConfirmNewPassword"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="textPassword" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btnChangePassword"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="60dp"
|
||||
android:layout_marginTop="32dp"
|
||||
android:text="Atualizar Senha"
|
||||
app:cornerRadius="12dp" />
|
||||
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
</LinearLayout>
|
||||
55
app/src/main/res/layout/bottom_sheet_add_child.xml
Normal file
55
app/src/main/res/layout/bottom_sheet_add_child.xml
Normal file
@@ -0,0 +1,55 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="24dp"
|
||||
android:background="@android:color/white">
|
||||
|
||||
<View
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="4dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginBottom="20dp"
|
||||
android:background="#E0E0E0" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Adicionar Novo Filho"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="#333" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Preencha as informações abaixo"
|
||||
android:textColor="#757575"
|
||||
android:layout_marginBottom="16dp" />
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="Nome do Filho"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/etChildName"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="textPersonName" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btnSaveChild"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="55dp"
|
||||
android:layout_marginTop="24dp"
|
||||
android:text="Criar Perfil e Gerar Código"
|
||||
android:textStyle="bold"
|
||||
app:cornerRadius="8dp"
|
||||
app:backgroundTint="#3D6DFF" />
|
||||
|
||||
</LinearLayout>
|
||||
105
app/src/main/res/layout/chat_activity.xml
Normal file
105
app/src/main/res/layout/chat_activity.xml
Normal file
@@ -0,0 +1,105 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#F3F6FB">
|
||||
|
||||
<!-- Header -->
|
||||
<FrameLayout
|
||||
android:id="@+id/chatHeader"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="90dp"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/bg_header_top" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="16dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/btnBack"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:src="@drawable/ic_navigation_plane"
|
||||
android:rotation="180"
|
||||
app:tint="#FFFFFF" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Chat de Família"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="3 membros online"
|
||||
android:textColor="#E1EAFF"
|
||||
android:textSize="12sp" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
|
||||
<!-- Message List -->
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_chat"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:paddingBottom="16dp"
|
||||
android:clipToPadding="false"
|
||||
app:layout_constraintBottom_toTopOf="@+id/footerInput"
|
||||
app:layout_constraintTop_toBottomOf="@+id/chatHeader" />
|
||||
|
||||
<!-- Input Footer -->
|
||||
<LinearLayout
|
||||
android:id="@+id/footerInput"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="#FFFFFF"
|
||||
android:elevation="8dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:padding="12dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/edit_chat_message"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/edit_text_background_light_gray"
|
||||
android:hint="Escreve uma mensagem..."
|
||||
android:padding="12dp"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/btnSend"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:src="@drawable/ic_navigation_plane"
|
||||
app:tint="#1F6AEF" />
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -5,7 +5,6 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#F6F7FB"
|
||||
android:paddingBottom="96dp"
|
||||
tools:context=".ui.alerts.AlertsFragment">
|
||||
|
||||
<LinearLayout
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#F6F7FB"
|
||||
android:paddingBottom="96dp"
|
||||
tools:context=".ui.history.HistoryFragment">
|
||||
|
||||
<LinearLayout
|
||||
|
||||
128
app/src/main/res/layout/fragment_home.xml
Normal file
128
app/src/main/res/layout/fragment_home.xml
Normal file
@@ -0,0 +1,128 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#F3F6FB">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/layoutEmptyState"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="visible"> <View
|
||||
android:id="@+id/viewHeader"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="160dp"
|
||||
android:background="@drawable/bg_header_rounded"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvAppTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="24dp"
|
||||
android:text="FindU"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="22sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/cardEmptyState"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginHorizontal="24dp"
|
||||
android:layout_marginTop="30dp"
|
||||
android:layout_marginBottom="24dp"
|
||||
app:cardCornerRadius="20dp"
|
||||
app:cardElevation="4dp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/btnSOS"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tvAppTitle">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="24dp">
|
||||
|
||||
<View
|
||||
android:id="@+id/bgIcon"
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="100dp"
|
||||
android:background="@drawable/bg_circle_light_blue"
|
||||
app:layout_constraintBottom_toTopOf="@+id/tvNoChildTitle"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_chainStyle="packed" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:src="@android:drawable/ic_menu_add"
|
||||
app:tint="#3D6DFF"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/bgIcon"
|
||||
app:layout_constraintEnd_toEndOf="@+id/bgIcon"
|
||||
app:layout_constraintStart_toStartOf="@+id/bgIcon"
|
||||
app:layout_constraintTop_toTopOf="@+id/bgIcon" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvNoChildTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="24dp"
|
||||
android:text="Nenhum filho adicionado"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toTopOf="@+id/tvNoChildDesc"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/bgIcon" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvNoChildDesc"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:gravity="center"
|
||||
android:text="Adicione o seu primeiro filho para começar."
|
||||
app:layout_constraintBottom_toTopOf="@+id/btnAddChild"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tvNoChildTitle" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btnAddChild"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="60dp"
|
||||
android:text="Adicionar Filho"
|
||||
android:textStyle="bold"
|
||||
app:backgroundTint="#3D6DFF"
|
||||
app:cornerRadius="12dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btnSOS"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="65dp"
|
||||
android:layout_marginHorizontal="24dp"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:text="SOS"
|
||||
app:backgroundTint="#D32F2F"
|
||||
app:cornerRadius="16dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/mapContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="gone" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -1,457 +1,132 @@
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#F3F6FB"
|
||||
tools:context=".ui.map.MapFragment">
|
||||
android:background="#F3F6FB">
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:id="@+id/scrollView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/sosButton"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/layoutEmptyState"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="visible">
|
||||
|
||||
<LinearLayout
|
||||
<View
|
||||
android:id="@+id/viewHeader"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="24dp">
|
||||
android:layout_height="160dp"
|
||||
android:background="@drawable/bg_header_rounded"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<FrameLayout
|
||||
<TextView
|
||||
android:id="@+id/tvAppTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="24dp"
|
||||
android:text="FindU"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="22sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/cardEmptyState"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginHorizontal="24dp"
|
||||
android:layout_marginTop="30dp"
|
||||
android:layout_marginBottom="24dp"
|
||||
app:cardCornerRadius="20dp"
|
||||
app:cardElevation="4dp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/btnSOS"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tvAppTitle">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="210dp">
|
||||
android:layout_height="match_parent"
|
||||
android:padding="24dp">
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="210dp"
|
||||
android:background="@drawable/bg_header_top" />
|
||||
android:id="@+id/bgIcon"
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="100dp"
|
||||
android:background="@drawable/bg_circle_light_blue"
|
||||
app:layout_constraintBottom_toTopOf="@+id/tvNoChildTitle"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_chainStyle="packed" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
<ImageView
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:src="@android:drawable/ic_menu_add"
|
||||
app:tint="#3D6DFF"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/bgIcon"
|
||||
app:layout_constraintEnd_toEndOf="@+id/bgIcon"
|
||||
app:layout_constraintStart_toStartOf="@+id/bgIcon"
|
||||
app:layout_constraintTop_toTopOf="@+id/bgIcon" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/headerTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="sans-serif-medium"
|
||||
android:text="@string/header_title"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="28sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/headerSubtitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="6dp"
|
||||
android:text="@string/header_subtitle"
|
||||
android:textColor="#E1EAFF"
|
||||
android:textSize="14sp" />
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/userStatusCard"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:layout_marginTop="-60dp"
|
||||
android:elevation="6dp"
|
||||
android:translationZ="6dp"
|
||||
app:cardCornerRadius="22dp"
|
||||
app:cardUseCompatPadding="false">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
<TextView
|
||||
android:id="@+id/tvNoChildTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="20dp">
|
||||
android:layout_marginTop="24dp"
|
||||
android:text="Nenhum filho adicionado"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toTopOf="@+id/tvNoChildDesc"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/bgIcon" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
<TextView
|
||||
android:id="@+id/tvNoChildDesc"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:gravity="center"
|
||||
android:text="Adicione o seu primeiro filho para começar."
|
||||
app:layout_constraintBottom_toTopOf="@+id/btnAddChild"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tvNoChildTitle" />
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="60dp"
|
||||
android:background="@drawable/bg_avatar_placeholder"
|
||||
android:padding="6dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:text="@string/status_avatar_emoji"
|
||||
android:textSize="26sp" />
|
||||
</FrameLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/status_name"
|
||||
android:textColor="#111827"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<View
|
||||
android:layout_width="10dp"
|
||||
android:layout_height="10dp"
|
||||
android:background="@drawable/bg_status_online" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="6dp"
|
||||
android:text="@string/status_online"
|
||||
android:textColor="#1FB66F"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="end"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:src="@drawable/ic_battery" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="4dp"
|
||||
android:text="@string/battery_percent"
|
||||
android:textColor="#111827"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="6dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:src="@drawable/ic_signal_gps" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="4dp"
|
||||
android:text="@string/gps_label"
|
||||
android:textColor="#111827"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:background="@drawable/bg_safe_banner"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:padding="16dp">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:background="@drawable/bg_safe_banner_icon">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_gravity="center"
|
||||
android:src="@drawable/ic_location_pin" />
|
||||
</FrameLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/status_safe_zone_line1"
|
||||
android:textColor="#0B6635"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:text="@string/status_safe_zone_line2"
|
||||
android:textColor="#0B6635" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/mapContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
app:cardCornerRadius="36dp"
|
||||
app:cardElevation="4dp">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btnAddChild"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="380dp"
|
||||
android:background="@drawable/bg_map_card"
|
||||
android:clipToPadding="false"
|
||||
android:padding="24dp">
|
||||
android:layout_height="60dp"
|
||||
android:text="Adicionar Filho"
|
||||
android:textStyle="bold"
|
||||
app:backgroundTint="#3D6DFF"
|
||||
app:cornerRadius="12dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent" />
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/map"
|
||||
android:name="com.google.android.gms.maps.SupportMapFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<View
|
||||
android:id="@+id/safeZone"
|
||||
android:layout_width="280dp"
|
||||
android:layout_height="280dp"
|
||||
android:background="@drawable/bg_safe_zone_circle"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btnSOS"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="65dp"
|
||||
android:layout_marginHorizontal="24dp"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:text="SOS"
|
||||
app:backgroundTint="#D32F2F"
|
||||
app:cornerRadius="16dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/userMarker"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:background="@drawable/bg_marker_user" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="6dp"
|
||||
android:text="@string/map_marker_miguel"
|
||||
android:textColor="#111827"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/homeMarker"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginBottom="48dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:background="@drawable/bg_marker_avatar">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:text="@string/zone_home_icon"
|
||||
android:textSize="18sp" />
|
||||
</FrameLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:background="@drawable/bg_marker_label"
|
||||
android:text="@string/map_marker_home"
|
||||
android:textColor="#111827"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/schoolMarker"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginTop="24dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintEnd_toEndOf="@+id/safeZone"
|
||||
app:layout_constraintTop_toTopOf="@+id/safeZone">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:background="@drawable/bg_marker_avatar">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:text="@string/zone_school_icon"
|
||||
android:textSize="18sp" />
|
||||
</FrameLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:background="@drawable/bg_marker_label"
|
||||
android:text="@string/map_marker_school"
|
||||
android:textColor="#111827"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/zoomControls"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/zoomInButton"
|
||||
android:layout_width="52dp"
|
||||
android:layout_height="52dp"
|
||||
android:background="@drawable/bg_zoom_button"
|
||||
android:contentDescription="@string/zoom_in"
|
||||
android:src="@drawable/ic_zoom_plus" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/zoomOutButton"
|
||||
android:layout_width="52dp"
|
||||
android:layout_height="52dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:background="@drawable/bg_zoom_button"
|
||||
android:contentDescription="@string/zoom_out"
|
||||
android:src="@drawable/ic_zoom_minus" />
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/navigationFab"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginBottom="12dp"
|
||||
android:contentDescription="@string/navigate"
|
||||
app:backgroundTint="#1F6AEF"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:srcCompat="@drawable/ic_navigation_plane" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/messagesFabContainer"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:layout_marginBottom="12dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent">
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/messagesFab"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:contentDescription="@string/messages"
|
||||
app:backgroundTint="#1DB45A"
|
||||
app:srcCompat="@drawable/ic_chat_bubble" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/messagesBadge"
|
||||
android:layout_width="22dp"
|
||||
android:layout_height="22dp"
|
||||
android:layout_gravity="top|end"
|
||||
android:background="@drawable/bg_badge"
|
||||
android:gravity="center"
|
||||
android:text="@string/messages_badge"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="12sp"
|
||||
android:textStyle="bold" />
|
||||
</FrameLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
</LinearLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/sosButton"
|
||||
style="@style/Widget.MaterialComponents.Button"
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/mapContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="64dp"
|
||||
android:layout_marginStart="24dp"
|
||||
android:layout_marginEnd="24dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:backgroundTint="#E53935"
|
||||
app:cornerRadius="18dp"
|
||||
android:drawablePadding="12dp"
|
||||
android:drawableEnd="@android:drawable/ic_menu_call"
|
||||
app:icon="@android:drawable/ic_dialog_alert"
|
||||
app:iconPadding="12dp"
|
||||
app:iconTint="#FFFFFF"
|
||||
android:text="@string/sos_button_text"
|
||||
android:textAllCaps="true"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textStyle="bold"
|
||||
app:iconGravity="textStart"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="gone" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -5,7 +5,6 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#F6F7FB"
|
||||
android:paddingBottom="96dp"
|
||||
tools:context=".ui.profile.ProfileFragment">
|
||||
|
||||
<LinearLayout
|
||||
@@ -30,6 +29,7 @@
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.google.android.material.imageview.ShapeableImageView
|
||||
android:id="@+id/profileImage"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="80dp"
|
||||
android:background="#FFFFFF"
|
||||
@@ -40,6 +40,7 @@
|
||||
android:src="@drawable/logo" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/profileName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
@@ -49,6 +50,7 @@
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/profileEmail"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
@@ -88,6 +90,7 @@
|
||||
|
||||
<!-- Item 1 -->
|
||||
<LinearLayout
|
||||
android:id="@+id/layoutEditProfile"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
@@ -125,6 +128,7 @@
|
||||
|
||||
<!-- Item 2 -->
|
||||
<LinearLayout
|
||||
android:id="@+id/layoutSecurity"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#F5F7FB"
|
||||
android:paddingBottom="96dp"
|
||||
tools:context=".ui.zones.ZonesFragment">
|
||||
|
||||
<LinearLayout
|
||||
|
||||
28
app/src/main/res/layout/item_chat_received.xml
Normal file
28
app/src/main/res/layout/item_chat_received.xml
Normal file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="start"
|
||||
android:orientation="vertical"
|
||||
android:padding="8dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_message_body"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/bg_chat_received"
|
||||
android:maxWidth="260dp"
|
||||
android:padding="12dp"
|
||||
android:text="Message Text"
|
||||
android:textColor="#1F2937"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_message_time"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:text="12:00"
|
||||
android:textColor="#9CA3AF"
|
||||
android:textSize="10sp" />
|
||||
</LinearLayout>
|
||||
28
app/src/main/res/layout/item_chat_sent.xml
Normal file
28
app/src/main/res/layout/item_chat_sent.xml
Normal file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="end"
|
||||
android:orientation="vertical"
|
||||
android:padding="8dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_message_body"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/bg_chat_sent"
|
||||
android:maxWidth="260dp"
|
||||
android:padding="12dp"
|
||||
android:text="Message Text"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_message_time"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:text="12:00"
|
||||
android:textColor="#9CA3AF"
|
||||
android:textSize="10sp" />
|
||||
</LinearLayout>
|
||||
@@ -95,6 +95,48 @@
|
||||
android:textSize="16sp"
|
||||
app:cornerRadius="12dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<View
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="1dp"
|
||||
android:layout_weight="1"
|
||||
android:background="#E0E0E0" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="8dp"
|
||||
android:text="OU"
|
||||
android:textColor="#9E9E9E"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<View
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="1dp"
|
||||
android:layout_weight="1"
|
||||
android:background="#E0E0E0" />
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btnChildLogin"
|
||||
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="55dp"
|
||||
android:text="Sou Filho (Entrar com Código)"
|
||||
android:textAllCaps="false"
|
||||
android:textColor="#3D6DFF"
|
||||
android:textSize="16sp"
|
||||
app:strokeColor="#3D6DFF"
|
||||
app:strokeWidth="1dp"
|
||||
app:cornerRadius="12dp" />
|
||||
|
||||
</LinearLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
<style name="Theme.PAP_FindU" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
||||
<style name="Theme.PAP_FindU" parent="Theme.MaterialComponents.DayNight.NoActionBar">
|
||||
<!-- Primary brand color. -->
|
||||
<item name="colorPrimary">@color/purple_200</item>
|
||||
<item name="colorPrimaryVariant">@color/purple_700</item>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
<style name="Theme.PAP_FindU" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
||||
<style name="Theme.PAP_FindU" parent="Theme.MaterialComponents.DayNight.NoActionBar">
|
||||
<!-- Primary brand color. -->
|
||||
<item name="colorPrimary">@color/purple_500</item>
|
||||
<item name="colorPrimaryVariant">@color/purple_700</item>
|
||||
|
||||
@@ -17,6 +17,7 @@ firebaseAuth = "24.0.1"
|
||||
credentials = "1.5.0"
|
||||
credentialsPlayServicesAuth = "1.5.0"
|
||||
googleid = "1.1.1"
|
||||
firebaseFirestore = "26.1.0"
|
||||
|
||||
[libraries]
|
||||
junit = { group = "junit", name = "junit", version.ref = "junit" }
|
||||
@@ -35,6 +36,7 @@ firebase-auth = { group = "com.google.firebase", name = "firebase-auth", version
|
||||
credentials = { group = "androidx.credentials", name = "credentials", version.ref = "credentials" }
|
||||
credentials-play-services-auth = { group = "androidx.credentials", name = "credentials-play-services-auth", version.ref = "credentialsPlayServicesAuth" }
|
||||
googleid = { group = "com.google.android.libraries.identity.googleid", name = "googleid", version.ref = "googleid" }
|
||||
firebase-firestore = { group = "com.google.firebase", name = "firebase-firestore", version.ref = "firebaseFirestore" }
|
||||
|
||||
[plugins]
|
||||
android-application = { id = "com.android.application", version.ref = "agp" }
|
||||
|
||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,4 +1,4 @@
|
||||
#Tue Nov 25 08:59:16 WET 2025
|
||||
#Tue Jan 27 16:46:23 WET 2026
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
|
||||
|
||||
Reference in New Issue
Block a user