primeiro commit

This commit is contained in:
2026-04-15 12:46:50 +01:00
commit fa1accd4bb
961 changed files with 124535 additions and 0 deletions

BIN
app/src/.DS_Store vendored Normal file

Binary file not shown.

BIN
app/src/main/.DS_Store vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Fluxup">
<activity
android:name=".LoginActivity"
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=".RegisterActivity" />
<activity android:name=".ForgotPasswordActivity" />
<activity android:name=".MainActivity" />
</application>
</manifest>

View File

@@ -0,0 +1,49 @@
package com.fluxup.app;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
public class ForgotPasswordActivity extends AppCompatActivity {
private EditText etEmail;
private Button btnSend;
private TextView tvBack;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_forgot_password);
etEmail = findViewById(R.id.etForgotEmail);
btnSend = findViewById(R.id.btnSendReset);
tvBack = findViewById(R.id.tvForgotBack);
btnSend.setOnClickListener(v -> {
String email = etEmail.getText().toString();
if (email.isEmpty()) {
Toast.makeText(ForgotPasswordActivity.this, "Por favor insira o seu email", Toast.LENGTH_SHORT).show();
} else if (!email.contains("@")) {
Toast.makeText(ForgotPasswordActivity.this, "O email deve conter um '@'", Toast.LENGTH_SHORT).show();
} else {
UsuariosService.recuperarPalavraPasse(ForgotPasswordActivity.this, email, new UsuariosService.ServiceCallback<Void>() {
@Override
public void onSuccess(Void data) {
Toast.makeText(ForgotPasswordActivity.this, "Um email com instruções foi enviado.", Toast.LENGTH_SHORT).show();
finish();
}
@Override
public void onError(String error) {
Toast.makeText(ForgotPasswordActivity.this, "Erro: " + error, Toast.LENGTH_LONG).show();
}
});
}
});
tvBack.setOnClickListener(v -> finish());
}
}

View File

@@ -0,0 +1,109 @@
package com.fluxup.app;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import java.util.Locale;
public class InicioFragment extends Fragment {
private TextView tvTimer;
private FrameLayout timerBlock;
private LinearLayout tasksContainer;
private CountDownTimer countDownTimer;
private boolean isTimerRunning = false;
private long timeLeftInMillis = 25 * 60 * 1000; // 25 minutos
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_inicio, container, false);
tvTimer = view.findViewById(R.id.tvTimer);
timerBlock = view.findViewById(R.id.timerBlock);
tasksContainer = view.findViewById(R.id.tasksContainer);
addSampleTasks();
timerBlock.setOnClickListener(v -> {
if (!isTimerRunning) {
startTimer();
} else {
pauseTimer();
}
});
view.findViewById(R.id.btnAddTasks).setOnClickListener(v -> {
Toast.makeText(getContext(), "Adicionar tarefas: Implementação futura", Toast.LENGTH_SHORT).show();
});
updateCountDownText();
return view;
}
private void addSampleTasks() {
if(getContext() == null) return;
String[] sampleTasks = {
"Estudar para intermédio",
"Ler artigo técnico",
"Fazer exercícios"
};
tasksContainer.removeAllViews();
for (String taskLabel : sampleTasks) {
CheckBox cb = new CheckBox(getContext());
cb.setText(taskLabel);
cb.setTextColor(getResources().getColor(R.color.black));
tasksContainer.addView(cb);
}
}
private void startTimer() {
countDownTimer = new CountDownTimer(timeLeftInMillis, 1000) {
@Override
public void onTick(long millisUntilFinished) {
timeLeftInMillis = millisUntilFinished;
updateCountDownText();
}
@Override
public void onFinish() {
isTimerRunning = false;
if(getContext() != null) Toast.makeText(getContext(), "Foco concluído!", Toast.LENGTH_LONG).show();
}
}.start();
isTimerRunning = true;
}
private void pauseTimer() {
if (countDownTimer != null) {
countDownTimer.cancel();
}
isTimerRunning = false;
}
private void updateCountDownText() {
int minutes = (int) (timeLeftInMillis / 1000) / 60;
int seconds = (int) (timeLeftInMillis / 1000) % 60;
String timeLeftFormatted = String.format(Locale.getDefault(), "%02d:%02d", minutes, seconds);
if(tvTimer != null) tvTimer.setText(timeLeftFormatted);
}
@Override
public void onDestroyView() {
super.onDestroyView();
pauseTimer(); // Parar o timer se a view for destruída
}
}

View File

@@ -0,0 +1,91 @@
package com.fluxup.app;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
public class LoginActivity extends AppCompatActivity {
private EditText etEmail, etPassword, etUsuario;
private Button btnLogin;
private TextView tvGoToRegister, tvForgotPassword;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Verificar se o utilizador já está logado
if (com.google.firebase.auth.FirebaseAuth.getInstance().getCurrentUser() != null) {
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent);
finish();
return;
}
setContentView(R.layout.activity_login);
etEmail = findViewById(R.id.etEmail);
etPassword = findViewById(R.id.etPassword);
etUsuario = findViewById(R.id.etUsuario);
btnLogin = findViewById(R.id.btnLogin);
tvGoToRegister = findViewById(R.id.tvGoToRegister);
tvForgotPassword = findViewById(R.id.tvForgotPassword);
btnLogin.setOnClickListener(v -> {
String email = etEmail.getText().toString();
String password = etPassword.getText().toString();
if (email.isEmpty() || password.isEmpty()) {
Toast.makeText(LoginActivity.this, "Por favor, preencha o email e a palavra-passe", Toast.LENGTH_SHORT).show();
return;
}
if (!email.contains("@")) {
Toast.makeText(LoginActivity.this, "O email deve conter um '@'", Toast.LENGTH_SHORT).show();
return;
}
if (password.length() < 8) {
Toast.makeText(LoginActivity.this, "A palavra-passe deve ter no mínimo 8 caracteres", Toast.LENGTH_SHORT).show();
return;
}
// Validar utilizador se estiver visível/preenchido
String user = etUsuario.getText().toString();
if (!user.isEmpty() && !user.matches("[a-zA-ZáàâãéèêíïóôõöúçÁÀÂÃÉÈÊÍÏÓÔÕÖÚÇ ]+")) {
Toast.makeText(LoginActivity.this, "O nome de utilizador deve conter apenas letras", Toast.LENGTH_SHORT).show();
return;
}
UsuariosService.login(LoginActivity.this, email, password, new UsuariosService.ServiceCallback<Usuario>() {
@Override
public void onSuccess(Usuario data) {
Toast.makeText(LoginActivity.this, "Bem-vindo!", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent);
finish();
}
@Override
public void onError(String error) {
Toast.makeText(LoginActivity.this, "Erro: " + error, Toast.LENGTH_LONG).show();
}
});
});
tvGoToRegister.setOnClickListener(v -> {
Intent intent = new Intent(LoginActivity.this, RegisterActivity.class);
startActivity(intent);
});
tvForgotPassword.setOnClickListener(v -> {
Intent intent = new Intent(LoginActivity.this, ForgotPasswordActivity.class);
startActivity(intent);
});
}
}

View File

@@ -0,0 +1,42 @@
package com.fluxup.app;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import com.google.android.material.bottomnavigation.BottomNavigationView;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BottomNavigationView bottomNav = findViewById(R.id.bottom_navigation);
// Define o fragment inicial
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.nav_host_fragment, new InicioFragment())
.commit();
}
bottomNav.setOnItemSelectedListener(item -> {
Fragment selectedFragment = null;
int itemId = item.getItemId();
if (itemId == R.id.nav_inicio) {
selectedFragment = new InicioFragment();
} else if (itemId == R.id.nav_profile) {
selectedFragment = new ProfileFragment();
}
if (selectedFragment != null) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.nav_host_fragment, selectedFragment)
.commit();
}
return true;
});
}
}

View File

@@ -0,0 +1,16 @@
package com.fluxup.app;
import android.os.Bundle;
import android.widget.Button;
import androidx.appcompat.app.AppCompatActivity;
public class ModalActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_modal);
findViewById(R.id.btnModalBack).setOnClickListener(v -> finish());
}
}

View File

@@ -0,0 +1,19 @@
package com.fluxup.app;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
public class ProfileFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_profile, container, false);
}
}

View File

@@ -0,0 +1,122 @@
package com.fluxup.app;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
public class RegisterActivity extends AppCompatActivity {
private EditText etUsername, etEmail, etPhone, etPassword, etConfirmPassword;
private Button btnRegister;
private TextView tvBackToLogin;
private android.widget.ProgressBar pbRegister;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
etUsername = findViewById(R.id.etRegUsername);
etEmail = findViewById(R.id.etRegEmail);
etPhone = findViewById(R.id.etRegPhone);
etPassword = findViewById(R.id.etRegPassword);
etConfirmPassword = findViewById(R.id.etRegConfirmPassword);
btnRegister = findViewById(R.id.btnRegister);
tvBackToLogin = findViewById(R.id.tvBackToLogin);
pbRegister = findViewById(R.id.pbRegister);
btnRegister.setOnClickListener(v -> {
String username = etUsername.getText().toString();
String email = etEmail.getText().toString();
String phone = etPhone.getText().toString();
String pass = etPassword.getText().toString();
String confirmPass = etConfirmPassword.getText().toString();
if (username.isEmpty()) {
etUsername.setError("Nome de utilizador é obrigatório");
etUsername.requestFocus();
return;
}
if (email.isEmpty()) {
etEmail.setError("Email é obrigatório");
etEmail.requestFocus();
return;
}
if (phone.isEmpty()) {
etPhone.setError("Número de telemóvel é obrigatório");
etPhone.requestFocus();
return;
}
if (pass.isEmpty()) {
etPassword.setError("Palavra-passe é obrigatória");
etPassword.requestFocus();
return;
}
if (!pass.equals(confirmPass)) {
etConfirmPassword.setError("As palavras-passe não coincidem");
etConfirmPassword.requestFocus();
return;
}
if (!username.matches("[a-zA-ZáàâãéèêíïóôõöúçÁÀÂÃÉÈÊÍÏÓÔÕÖÚÇ ]+")) {
etUsername.setError("O nome de utilizador deve conter apenas letras");
etUsername.requestFocus();
return;
}
if (!email.contains("@")) {
etEmail.setError("O email deve conter um '@'");
etEmail.requestFocus();
return;
}
if (phone.length() < 9) {
etPhone.setError("O número de telefone deve ter no mínimo 9 dígitos");
etPhone.requestFocus();
return;
}
if (pass.length() < 8) {
etPassword.setError("A palavra-passe deve ter no mínimo 8 caracteres");
etPassword.requestFocus();
return;
}
// Mostrar progresso e desativar botão
pbRegister.setVisibility(View.VISIBLE);
btnRegister.setEnabled(false);
Usuario novoUsuario = new Usuario(null, username, email, pass, phone);
UsuariosService.registar(RegisterActivity.this, novoUsuario, new UsuariosService.ServiceCallback<Usuario>() {
@Override
public void onSuccess(Usuario data) {
pbRegister.setVisibility(View.GONE);
Toast.makeText(RegisterActivity.this, "Conta criada com sucesso!", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(RegisterActivity.this, MainActivity.class);
startActivity(intent);
finish();
}
@Override
public void onError(String error) {
pbRegister.setVisibility(View.GONE);
btnRegister.setEnabled(true);
Toast.makeText(RegisterActivity.this, "Erro: " + error, Toast.LENGTH_LONG).show();
}
});
});
tvBackToLogin.setOnClickListener(v -> finish());
}
}

View File

@@ -0,0 +1,22 @@
package com.fluxup.app;
public class Usuario {
public String id;
public String id_usuario;
public String usuario;
public String email;
public String palavra_passe;
public String numero;
public String created_at;
public String updated_at;
public Usuario() {}
public Usuario(String id_usuario, String usuario, String email, String palavra_passe, String numero) {
this.id_usuario = id_usuario;
this.usuario = usuario;
this.email = email;
this.palavra_passe = palavra_passe;
this.numero = numero;
}
}

View File

@@ -0,0 +1,74 @@
package com.fluxup.app;
import android.content.Context;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.firestore.FirebaseFirestore;
import java.util.HashMap;
import java.util.Map;
public class UsuariosService {
private static final FirebaseAuth mAuth = FirebaseAuth.getInstance();
private static final FirebaseFirestore mFirestore = FirebaseFirestore.getInstance();
public static void login(Context context, String email, String password, ServiceCallback<Usuario> callback) {
mAuth.signInWithEmailAndPassword(email, password)
.addOnCompleteListener(task -> {
if (task.isSuccessful()) {
FirebaseUser user = mAuth.getCurrentUser();
if (user != null) {
// Buscar detalhes no Firestore
mFirestore.collection("users").document(user.getUid()).get()
.addOnSuccessListener(documentSnapshot -> {
Usuario usuario = documentSnapshot.toObject(Usuario.class);
if (usuario == null) {
// Fallback if document not found
usuario = new Usuario(user.getUid(), "", user.getEmail(), "", "");
}
callback.onSuccess(usuario);
})
.addOnFailureListener(e -> callback.onError(e.getMessage()));
}
} else {
callback.onError(task.getException() != null ? task.getException().getMessage() : "Erro ao entrar");
}
});
}
public static void registar(Context context, Usuario usuario, ServiceCallback<Usuario> callback) {
mAuth.createUserWithEmailAndPassword(usuario.email, usuario.palavra_passe)
.addOnCompleteListener(task -> {
if (task.isSuccessful()) {
FirebaseUser firebaseUser = mAuth.getCurrentUser();
if (firebaseUser != null) {
usuario.id_usuario = firebaseUser.getUid();
// Não salvar a senha no Firestore por segurança
usuario.palavra_passe = null;
mFirestore.collection("users").document(firebaseUser.getUid()).set(usuario)
.addOnSuccessListener(aVoid -> callback.onSuccess(usuario))
.addOnFailureListener(e -> callback.onError(e.getMessage()));
}
} else {
callback.onError(task.getException() != null ? task.getException().getMessage() : "Erro ao criar conta");
}
});
}
public static void recuperarPalavraPasse(Context context, String email, ServiceCallback<Void> callback) {
mAuth.sendPasswordResetEmail(email)
.addOnCompleteListener(task -> {
if (task.isSuccessful()) {
callback.onSuccess(null);
} else {
callback.onError(task.getException() != null ? task.getException().getMessage() : "Erro ao enviar email");
}
});
}
public interface ServiceCallback<T> {
void onSuccess(T data);
void onError(String error);
}
}

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@color/white" />
</shape>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@android:color/transparent" />
<stroke
android:width="2dp"
android:color="#FFFFFF"
android:dashWidth="8dp"
android:dashGap="4dp" />
</shape>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/white" />
<corners android:radius="16dp" />
</shape>

View 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="#F9F9F9" />
<stroke android:width="1dp" android:color="#DDDDDD" />
<corners android:radius="8dp" />
</shape>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="@color/primary_light"
android:pathData="M0,0h108v108h-108z" />
</vector>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="@color/white"
android:pathData="M31,31h46v46h-46z" />
</vector>

View 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="#000000"
android:pathData="M10,20v-6h4v6h5v-8h3L12,3 2,12h3v8z"/>
</vector>

View 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="#000000"
android:pathData="M12,12c2.21,0 4,-1.79 4,-4s-1.79,-4 -4,-4 -4,1.79 -4,4 1.79,4 4,4zM12,14c-2.67,0 -8,1.34 -8,4v2h16v-2c0,-2.66 -5.33,-4 -8,-4z"/>
</vector>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#3b44f6" />
<corners android:radius="12dp" />
</shape>

View File

@@ -0,0 +1,57 @@
<?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:orientation="vertical"
android:padding="20dp"
android:gravity="center"
android:background="@color/white">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Fluxup"
android:textColor="@color/purple_500"
android:textSize="32sp"
android:textStyle="bold"
android:layout_marginBottom="8dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Recuperar palavrapasse"
android:textColor="#999999"
android:textSize="16sp"
android:layout_marginBottom="24dp"/>
<EditText
android:id="@+id/etForgotEmail"
android:layout_width="match_parent"
android:layout_height="50dp"
android:hint="Email"
android:background="@drawable/edit_text_bg"
android:paddingHorizontal="15dp"
android:layout_marginBottom="15dp"
android:inputType="textEmailAddress"/>
<Button
android:id="@+id/btnSendReset"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="Enviar"
android:backgroundTint="@color/purple_500"
android:textColor="@color/white"
android:textAllCaps="false"
android:textSize="18sp"
android:textStyle="bold"
android:layout_marginBottom="20dp"/>
<TextView
android:id="@+id/tvForgotBack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Voltar"
android:textColor="@color/purple_500"
android:padding="10dp"/>
</LinearLayout>

View File

@@ -0,0 +1,85 @@
<?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:orientation="vertical"
android:padding="20dp"
android:gravity="center"
android:background="@color/white">
<TextView
android:id="@+id/tvTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Fluxup"
android:textColor="@color/purple_500"
android:textSize="32sp"
android:textStyle="bold"
android:layout_marginBottom="8dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Entre na sua conta"
android:textColor="#666666"
android:textSize="16sp"
android:layout_marginBottom="24dp"/>
<EditText
android:id="@+id/etEmail"
android:layout_width="match_parent"
android:layout_height="50dp"
android:hint="Email"
android:background="@drawable/edit_text_bg"
android:paddingHorizontal="15dp"
android:layout_marginBottom="15dp"
android:inputType="textEmailAddress"/>
<EditText
android:id="@+id/etPassword"
android:layout_width="match_parent"
android:layout_height="50dp"
android:hint="Palavra Passe"
android:background="@drawable/edit_text_bg"
android:paddingHorizontal="15dp"
android:layout_marginBottom="15dp"
android:inputType="textPassword"/>
<EditText
android:id="@+id/etUsuario"
android:layout_width="match_parent"
android:layout_height="50dp"
android:hint="Usuário"
android:background="@drawable/edit_text_bg"
android:paddingHorizontal="15dp"
android:layout_marginBottom="20dp"/>
<Button
android:id="@+id/btnLogin"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="Entrar"
android:backgroundTint="@color/purple_500"
android:textColor="@color/white"
android:textAllCaps="false"
android:textSize="18sp"
android:textStyle="bold"
android:layout_marginBottom="20dp"/>
<TextView
android:id="@+id/tvGoToRegister"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Não tem conta? Registe-se"
android:textColor="@color/purple_500"
android:padding="10dp"/>
<TextView
android:id="@+id/tvForgotPassword"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Esqueci a palavrapasse"
android:textColor="@color/purple_500"
android:padding="10dp"/>
</LinearLayout>

View File

@@ -0,0 +1,28 @@
<?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="@color/background_purple">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@id/bottom_navigation"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/windowBackground"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="@menu/bottom_nav_menu" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,42 @@
<?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:orientation="vertical"
android:gravity="center"
android:padding="20dp"
android:background="#80000000"> <!-- Semi-transparent background -->
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="16dp"
xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="24dp"
android:gravity="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="This is a modal"
android:textSize="20sp"
android:textStyle="bold"
android:layout_marginBottom="16dp"/>
<Button
android:id="@+id/btnModalBack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Go to home screen"
android:backgroundTint="@color/purple_500"
android:textColor="@color/white"
android:textAllCaps="false"/>
</LinearLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>

View File

@@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="24dp"
android:gravity="center_horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Fluxup"
android:textColor="@color/purple_500"
android:textSize="32sp"
android:textStyle="bold"
android:layout_marginTop="20dp"
android:layout_marginBottom="8dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Registar nova conta"
android:textColor="#999999"
android:textSize="16sp"
android:layout_marginBottom="30dp"/>
<EditText
android:id="@+id/etRegUsername"
android:layout_width="match_parent"
android:layout_height="56dp"
android:hint="Nome de utilizador"
android:background="@drawable/edit_text_bg"
android:paddingHorizontal="16dp"
android:layout_marginBottom="16dp"/>
<EditText
android:id="@+id/etRegEmail"
android:layout_width="match_parent"
android:layout_height="56dp"
android:hint="Email"
android:background="@drawable/edit_text_bg"
android:paddingHorizontal="16dp"
android:layout_marginBottom="16dp"
android:inputType="textEmailAddress"/>
<EditText
android:id="@+id/etRegPhone"
android:layout_width="match_parent"
android:layout_height="56dp"
android:hint="Número de telemóvel"
android:background="@drawable/edit_text_bg"
android:paddingHorizontal="16dp"
android:layout_marginBottom="16dp"
android:inputType="phone"/>
<EditText
android:id="@+id/etRegPassword"
android:layout_width="match_parent"
android:layout_height="56dp"
android:hint="Palavra-passe"
android:background="@drawable/edit_text_bg"
android:paddingHorizontal="16dp"
android:layout_marginBottom="16dp"
android:inputType="textPassword"/>
<EditText
android:id="@+id/etRegConfirmPassword"
android:layout_width="match_parent"
android:layout_height="56dp"
android:hint="Confirmar palavra-passe"
android:background="@drawable/edit_text_bg"
android:paddingHorizontal="16dp"
android:layout_marginBottom="16dp"
android:inputType="textPassword"/>
<Button
android:id="@+id/btnRegister"
android:layout_width="match_parent"
android:layout_height="56dp"
android:text="Registar"
android:backgroundTint="@color/purple_500"
android:textColor="@color/white"
android:textAllCaps="false"
android:textSize="18sp"
android:textStyle="bold"
android:layout_marginTop="10dp"
android:layout_marginBottom="16dp"/>
<ProgressBar
android:id="@+id/pbRegister"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="24dp"
android:visibility="gone"
android:indeterminateTint="@color/purple_500"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginBottom="20dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Já tens conta? "
android:textColor="#999999"
android:textSize="16sp"/>
<TextView
android:id="@+id/tvBackToLogin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Entrar"
android:textColor="@color/purple_500"
android:textSize="16sp"
android:textStyle="bold"/>
</LinearLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>

View File

@@ -0,0 +1,150 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView 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="@color/background_purple">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="20dp">
<!-- Header -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/greeting"
android:textColor="@color/white"
android:textSize="24sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="@string/subtitle"
android:textColor="#EEEEEE"
android:textSize="14sp" />
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:text="👋"
android:textSize="28sp" />
</RelativeLayout>
<!-- Desafios do Dia Card -->
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
app:cardCornerRadius="24dp"
app:cardElevation="0dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp"
android:text="Desafios do Dia"
android:textColor="@color/black"
android:textSize="18sp"
android:textStyle="bold" />
<!-- Task List Placeholder (In Java we use RecyclerView) -->
<LinearLayout
android:id="@+id/tasksContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
<Button
android:id="@+id/btnAddTasks"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:backgroundTint="@color/purple_500"
android:text="+ Adicionar desafios diários"
android:textAllCaps="false"
android:textColor="@color/white" />
</LinearLayout>
</androidx.cardview.widget.CardView>
<!-- Modo Foco Card -->
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="24dp"
app:cardElevation="0dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp"
android:text="Modo Foco"
android:textColor="@color/black"
android:textSize="18sp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<FrameLayout
android:id="@+id/timerBlock"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginEnd="12dp"
android:background="@drawable/rounded_timer_bg">
<TextView
android:id="@+id/tvTimer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="25:00"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold" />
</FrameLayout>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Produtividade é o segredo do sucesso"
android:textColor="@color/black"
android:textSize="14sp" />
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
</androidx.core.widget.NestedScrollView>

View File

@@ -0,0 +1,359 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView 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="@color/background_purple"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- HEADER AZUL -->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="20dp"
android:paddingBottom="20dp">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="top|end"
android:layout_marginEnd="16dp"
android:layout_marginTop="8dp"
android:src="@android:drawable/ic_menu_manage"
app:tint="@color/white" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:orientation="vertical">
<FrameLayout
android:layout_width="80dp"
android:layout_height="80dp"
android:background="@drawable/circle_bg">
<ImageView
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_gravity="center"
android:src="@drawable/ic_nav_profile"
app:tint="@color/purple_500"/>
</FrameLayout>
</LinearLayout>
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="20dp">
<!-- INFO DO UTILIZADOR -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Jvitor"
android:textColor="@color/white"
android:textSize="24sp"
android:textStyle="bold" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="@usuario"
android:textColor="#888888"
android:textSize="14sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="20dp"
android:text="🇬🇧 1 Curso"
android:textColor="#bbbbbb"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="20dp"
android:text="13 Seguindo"
android:textColor="@color/white"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="8 Seguidores"
android:textColor="@color/white"
android:textSize="14sp"
android:textStyle="bold" />
</LinearLayout>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:backgroundTint="#ffffff"
android:text="+ ADICIONAR AMIGOS"
android:textColor="@color/purple_500"
android:textStyle="bold" />
<!-- VISÃO GERAL -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:layout_marginBottom="12dp"
android:text="Visão Geral"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold" />
<GridLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:columnCount="2"
android:rowCount="2">
<!-- CARD OFENSIVA -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_columnWeight="1"
android:layout_margin="6dp"
android:background="@drawable/dark_card_bg"
android:orientation="horizontal"
android:padding="16dp"
android:gravity="center_vertical">
<TextView
android:layout_width="32dp"
android:layout_height="32dp"
android:text="🔥"
android:textSize="24sp"
android:gravity="center"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="21"
android:textColor="@color/black"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Ofensiva"
android:textColor="#888888"
android:textSize="12sp" />
</LinearLayout>
</LinearLayout>
<!-- CARD XP -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_columnWeight="1"
android:layout_margin="6dp"
android:background="@drawable/dark_card_bg"
android:orientation="horizontal"
android:padding="16dp"
android:gravity="center_vertical">
<TextView
android:layout_width="32dp"
android:layout_height="32dp"
android:text="⚡"
android:textSize="24sp"
android:gravity="center"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1433"
android:textColor="@color/black"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Total de XP"
android:textColor="#888888"
android:textSize="12sp" />
</LinearLayout>
</LinearLayout>
<!-- CARD LIGA -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_columnWeight="1"
android:layout_margin="6dp"
android:background="@drawable/dark_card_bg"
android:orientation="horizontal"
android:padding="16dp"
android:gravity="center_vertical">
<TextView
android:layout_width="32dp"
android:layout_height="32dp"
android:text="🏆"
android:textSize="24sp"
android:gravity="center"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Esmeralda"
android:textColor="@color/black"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Liga Atual"
android:textColor="#888888"
android:textSize="12sp" />
</LinearLayout>
</LinearLayout>
<!-- CARD TOP 3 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_columnWeight="1"
android:layout_margin="6dp"
android:background="@drawable/dark_card_bg"
android:orientation="horizontal"
android:padding="16dp"
android:gravity="center_vertical">
<TextView
android:layout_width="32dp"
android:layout_height="32dp"
android:text="🏅"
android:textSize="24sp"
android:gravity="center"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2"
android:textColor="@color/black"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Pódios no Top 3"
android:textColor="#888888"
android:textSize="12sp" />
</LinearLayout>
</LinearLayout>
</GridLayout>
<!-- AMIGOS -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:layout_marginBottom="12dp"
android:text="Ofensivas dos Amigos"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold" />
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<!-- Amigo Vazio (Adicionar) -->
<LinearLayout
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:gravity="center"
android:orientation="vertical">
<FrameLayout
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@drawable/circle_dashed_bg">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="+"
android:textColor="@color/white"
android:textSize="32sp" />
</FrameLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="Convidar"
android:textColor="#888888"
android:textSize="12sp" />
</LinearLayout>
</LinearLayout>
</HorizontalScrollView>
</LinearLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/nav_inicio"
android:icon="@drawable/ic_nav_home"
android:title="Início" />
<item
android:id="@+id/nav_profile"
android:icon="@drawable/ic_nav_profile"
android:title="Perfil" />
</menu>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Basic Colors -->
<color name="white">#FFFFFF</color>
<color name="black">#11181C</color>
<!-- Missing Standard Colors -->
<color name="purple_200">#FFBB86FC</color>
<color name="purple_500">#6a00fa</color>
<color name="purple_700">#3700B3</color>
<color name="teal_200">#03DAC5</color>
<color name="teal_700">#018786</color>
<color name="background_purple">#F3E5F5</color>
<!-- Light Theme Tokens -->
<color name="text_light">#11181C</color>
<color name="text_muted_light">#6B7280</color>
<color name="background_light">#FFFFFF</color>
<color name="surface_light">#F8FAFC</color>
<color name="card_light">#FFFFFF</color>
<color name="border_light">#E5E7EB</color>
<color name="icon_light">#687076</color>
<color name="primary_light">#6a00fa</color> <!-- Mantendo o roxo premium solicitado -->
<color name="secondary_light">#64748B</color>
<color name="success_light">#16A34A</color>
<color name="error_light">#DC2626</color>
<color name="warning_light">#F59E0B</color>
<color name="info_light">#0EA5E9</color>
<!-- Dark Theme Tokens (for future use in values-night) -->
<color name="text_dark">#ECEDEE</color>
<color name="text_muted_dark">#94A3B8</color>
<color name="background_dark">#0F172A</color>
<color name="surface_dark">#1E293B</color>
<color name="card_dark">#111827</color>
<color name="border_dark">#334155</color>
<color name="icon_dark">#9BA1A6</color>
<color name="primary_dark">#38bdf8</color>
<color name="secondary_dark">#94A3B8</color>
<color name="success_dark">#22C55E</color>
</resources>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Spacing -->
<dimen name="spacing_xxs">4dp</dimen>
<dimen name="spacing_xs">8dp</dimen>
<dimen name="spacing_sm">12dp</dimen>
<dimen name="spacing_md">16dp</dimen>
<dimen name="spacing_lg">20dp</dimen>
<dimen name="spacing_xl">24dp</dimen>
<dimen name="spacing_xxl">32dp</dimen>
<!-- Radius -->
<dimen name="radius_sm">4dp</dimen>
<dimen name="radius_md">8dp</dimen>
<dimen name="radius_lg">12dp</dimen>
<dimen name="radius_xl">16dp</dimen>
<!-- Font Sizes -->
<dimen name="font_heading1">32sp</dimen>
<dimen name="font_heading2">28sp</dimen>
<dimen name="font_heading3">24sp</dimen>
<dimen name="font_subtitle">20sp</dimen>
<dimen name="font_body">16sp</dimen>
<dimen name="font_caption">12sp</dimen>
</resources>

View File

@@ -0,0 +1,5 @@
<resources>
<string name="app_name">Fluxup</string>
<string name="greeting">Hoje é um bom dia</string>
<string name="subtitle">Olá, Matheus! Preparado para o seu dia de produtividade?</string>
</resources>

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Reusable Styles Replicating React Native Components -->
<style name="ThemedText">
<item name="android:textColor">@color/text_light</item>
</style>
<style name="ThemedText.Heading1">
<item name="android:textSize">@dimen/font_heading1</item>
<item name="android:textStyle">bold</item>
<item name="android:textColor">@color/text_light</item>
</style>
<style name="ThemedText.Heading2">
<item name="android:textSize">@dimen/font_heading2</item>
<item name="android:textStyle">bold</item>
<item name="android:textColor">@color/text_light</item>
</style>
<style name="ThemedText.Body">
<item name="android:textSize">@dimen/font_body</item>
<item name="android:textColor">@color/text_light</item>
</style>
<style name="FluxupButton" parent="Widget.MaterialComponents.Button">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">56dp</item>
<item name="android:insetTop">0dp</item>
<item name="android:insetBottom">0dp</item>
<item name="cornerRadius">@dimen/radius_lg</item>
<item name="android:textAllCaps">false</item>
<item name="android:letterSpacing">0</item>
<item name="android:textSize">@dimen/font_body</item>
<item name="android:textStyle">bold</item>
</style>
<style name="FluxupInput">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">56dp</item>
<item name="android:background">@drawable/edit_text_bg</item>
<item name="android:paddingHorizontal">@dimen/spacing_md</item>
<item name="android:textSize">@dimen/font_body</item>
<item name="android:textColor">@color/text_light</item>
<item name="android:layout_marginBottom">@dimen/spacing_md</item>
</style>
</resources>

View File

@@ -0,0 +1,16 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.Fluxup" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_500</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/white</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_200</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
</style>
</resources>