progress to exporting filtered content
This commit is contained in:
@@ -27,7 +27,7 @@ fun LoginScreen(viewModel: AuthViewModel) {
|
||||
modifier = modifier,
|
||||
uiState = uiState,
|
||||
onRegister = viewModel::signUp,
|
||||
onTogleForm = viewModel::setFormType
|
||||
onToggleForm = viewModel::setFormType
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -23,10 +23,8 @@ import androidx.compose.material.icons.filled.Settings
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteScaffold
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
@@ -36,7 +34,6 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.capitalize
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.core.os.LocaleListCompat
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
@@ -45,12 +42,10 @@ import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.launch
|
||||
import net.tinsae.clocked.biometric.GlobalAuthenticator
|
||||
import net.tinsae.clocked.ui.components.ShowLoadingScreen
|
||||
import net.tinsae.clocked.ui.screens.dashboard.DashboardScreen
|
||||
import net.tinsae.clocked.data.Locale
|
||||
import net.tinsae.clocked.data.LogRepository
|
||||
import net.tinsae.clocked.data.Theme
|
||||
import net.tinsae.clocked.ui.components.TopBar
|
||||
import net.tinsae.clocked.ui.screens.dashboard.DashboardScreen
|
||||
import net.tinsae.clocked.ui.screens.history.HistoryScreen
|
||||
import net.tinsae.clocked.ui.screens.settings.SettingsScreen
|
||||
import net.tinsae.clocked.ui.screens.settings.SettingsViewModel
|
||||
@@ -92,17 +87,13 @@ class MainActivity : AppCompatActivity() {
|
||||
settingsViewModel.uiState
|
||||
.map { it.pendingCsvContent }
|
||||
.distinctUntilChanged()
|
||||
.collect { csvContent ->
|
||||
.collect {
|
||||
csvContent ->
|
||||
if (csvContent != null) {
|
||||
val timestamp = SimpleDateFormat("yyyyMMdd_HHmmss", java.util.Locale.US).format(Date())
|
||||
createDocumentLauncher.launch("Clocked-Export-$timestamp.csv")
|
||||
}
|
||||
}
|
||||
/*authViewModel.sessionStatus.collect {
|
||||
if (it is SessionStatus.Authenticated) {
|
||||
LogRepository.subscribeRealTime()
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
enableEdgeToEdge()
|
||||
@@ -114,23 +105,14 @@ class MainActivity : AppCompatActivity() {
|
||||
|
||||
|
||||
}
|
||||
/*override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
// When the app is being completely destroyed, ensure the connection is closed.
|
||||
LogRepository.unsubscribeRealTime()
|
||||
}*/
|
||||
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun AppEntry(settingsViewModel: SettingsViewModel, authViewModel: AuthViewModel) {
|
||||
val settingsState by settingsViewModel.uiState.collectAsState()
|
||||
val sessionStatus by authViewModel.sessionStatus.collectAsState()
|
||||
// Trigger fetching of logs when the session status changes.
|
||||
LaunchedEffect(sessionStatus) {
|
||||
if (sessionStatus is SessionStatus.Authenticated){
|
||||
//LogRepository.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
val useDarkTheme = when (settingsState.theme) {
|
||||
@@ -148,21 +130,6 @@ fun AppEntry(settingsViewModel: SettingsViewModel, authViewModel: AuthViewModel)
|
||||
}else{
|
||||
ClockedApp(settingsViewModel, authViewModel)
|
||||
}
|
||||
/*when (sessionStatus) {
|
||||
/*is SessionStatus.Initializing -> {
|
||||
// Only show loading for the initial session check.
|
||||
ShowLoadingScreen()
|
||||
}*/
|
||||
|
||||
is SessionStatus.Authenticated -> {
|
||||
// Just show the app. The ViewModels inside will manage their own loading UI.
|
||||
ClockedApp(settingsViewModel, authViewModel)
|
||||
}
|
||||
|
||||
else -> {
|
||||
LoginScreen(authViewModel)
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,7 +147,6 @@ fun updateLocale(context: Context, locale: Locale) {
|
||||
fun ClockedApp(settingsViewModel: SettingsViewModel, authViewModel: AuthViewModel) {
|
||||
var currentDestination by rememberSaveable { mutableStateOf(AppDestinations.HOME) }
|
||||
|
||||
|
||||
NavigationSuiteScaffold(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
navigationSuiteItems = {
|
||||
@@ -190,16 +156,18 @@ fun ClockedApp(settingsViewModel: SettingsViewModel, authViewModel: AuthViewMode
|
||||
Icon(
|
||||
imageVector = destination.icon,
|
||||
contentDescription = stringResource(destination.label),
|
||||
modifier = Modifier.padding(1.dp).size(24.dp)
|
||||
modifier = Modifier
|
||||
//.padding(1.dp)
|
||||
.size(24.dp)
|
||||
)
|
||||
},
|
||||
alwaysShowLabel = false,
|
||||
label = { Text(stringResource(destination.label)) },
|
||||
//label = { Text(stringResource(destination.label)) },
|
||||
selected = destination == currentDestination,
|
||||
onClick = { currentDestination = destination }
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
) {
|
||||
Scaffold(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
@@ -235,10 +203,6 @@ fun ClockedApp(settingsViewModel: SettingsViewModel, authViewModel: AuthViewMode
|
||||
modifier = modifier,
|
||||
viewModel = settingsViewModel
|
||||
)
|
||||
|
||||
/*AppDestinations.LOGOUT -> {
|
||||
authViewModel.logout()
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,9 +41,6 @@ class BiometricAuthenticator(private val activity: FragmentActivity) {
|
||||
onSuccess()
|
||||
}
|
||||
|
||||
override fun onAuthenticationFailed() {
|
||||
super.onAuthenticationFailed()
|
||||
}
|
||||
})
|
||||
|
||||
when (biometricManager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_STRONG or BiometricManager.Authenticators.DEVICE_CREDENTIAL)) {
|
||||
|
||||
@@ -42,11 +42,14 @@ fun RegistrationForm(
|
||||
modifier: Modifier = Modifier,
|
||||
uiState: AuthUiState,
|
||||
onRegister: (String, String, String) -> Unit,
|
||||
onTogleForm: (FormType) -> Unit
|
||||
onToggleForm: (FormType) -> Unit
|
||||
) {
|
||||
var name by rememberSaveable { mutableStateOf("") }
|
||||
var email by rememberSaveable { mutableStateOf("") }
|
||||
var password by rememberSaveable { mutableStateOf("") }
|
||||
var cPassword by rememberSaveable { mutableStateOf("") }
|
||||
var error: String? by rememberSaveable { mutableStateOf(null) }
|
||||
|
||||
|
||||
Scaffold(modifier = modifier.fillMaxSize()) { innerPadding ->
|
||||
Column(
|
||||
@@ -103,6 +106,31 @@ fun RegistrationForm(
|
||||
singleLine = true,
|
||||
isError = uiState.error != null
|
||||
)
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
OutlinedTextField(
|
||||
value = cPassword,
|
||||
onValueChange = {
|
||||
run {
|
||||
cPassword = it
|
||||
error = if (it != password) {
|
||||
"Passwords do not match"
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
},
|
||||
label = { Text(stringResource(R.string.confirm_password)) },
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
visualTransformation = PasswordVisualTransformation(),
|
||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
|
||||
singleLine = true,
|
||||
isError = error != null,
|
||||
supportingText = {
|
||||
error?.let {
|
||||
Text(text = it, color = MaterialTheme.colorScheme.error)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
uiState.error?.let {
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
@@ -112,7 +140,12 @@ fun RegistrationForm(
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
|
||||
Button(
|
||||
onClick = { onRegister(name,email, password) },
|
||||
onClick = {
|
||||
if (password == cPassword) {
|
||||
onRegister(name, email, password)
|
||||
error = null
|
||||
}
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
enabled = !uiState.isLoading
|
||||
) {
|
||||
@@ -128,7 +161,7 @@ fun RegistrationForm(
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Text("Have an account?")
|
||||
TextButton(onClick = { onTogleForm(FormType.LOGIN) }) {
|
||||
TextButton(onClick = { onToggleForm(FormType.LOGIN) }) {
|
||||
Text("Sign in", color = Color.Blue)
|
||||
}
|
||||
}
|
||||
@@ -144,7 +177,7 @@ fun RegisterPreview(){
|
||||
RegistrationForm(
|
||||
uiState = AuthUiState(),
|
||||
onRegister = { _, _, _ -> },
|
||||
onTogleForm = { _ ->}
|
||||
onToggleForm = { _ ->}
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package net.tinsae.clocked.ui.screens.editor
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import net.tinsae.clocked.data.Log
|
||||
import net.tinsae.clocked.ui.components.ListItem
|
||||
|
||||
@Composable
|
||||
private fun EditorScreen(modifier: Modifier = Modifier){
|
||||
|
||||
val viewModel = EditorViewModel()
|
||||
Surface(modifier = modifier.padding(16.dp).fillMaxSize()) {
|
||||
|
||||
FilterLogs(modifier = modifier, viewModel = viewModel)
|
||||
|
||||
ShowLogs(modifier = modifier, logs = listOf())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Composable
|
||||
private fun FilterLogs(modifier: Modifier = Modifier, viewModel: EditorViewModel){
|
||||
Column(modifier = modifier) {
|
||||
Text(modifier = Modifier.fillMaxWidth().padding(16.dp), text = "Filter")
|
||||
Row(modifier = Modifier.fillMaxWidth()) {
|
||||
Text(modifier = Modifier.weight(1f).padding(16.dp), text = "By date")
|
||||
Text(modifier = Modifier.weight(1f).padding(16.dp), text = "from")
|
||||
Text(modifier = Modifier.weight(1f).padding(16.dp), text = "to")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Composable
|
||||
private fun ShowLogs(logs: List<Log>, modifier: Modifier = Modifier){
|
||||
|
||||
LazyColumn {
|
||||
items(logs, key = { it.id }) { log ->
|
||||
ListItem(
|
||||
modifier = Modifier.padding(horizontal = 16.dp),
|
||||
log = log,
|
||||
onEdit = { },
|
||||
onDelete = { },
|
||||
// When the item is clicked, set it as the selected log for the dialog
|
||||
onClick = { }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun EditorPreview () {
|
||||
EditorScreen();
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package net.tinsae.clocked.ui.screens.editor
|
||||
|
||||
class EditorViewModel {
|
||||
}
|
||||
@@ -74,5 +74,6 @@
|
||||
<string name="add_entry">Add a new entry</string>
|
||||
<string name="logout">Log out</string>
|
||||
<string name="loading">loading</string>
|
||||
<string name="confirm_password">Confirm password</string>
|
||||
|
||||
</resources>
|
||||
Reference in New Issue
Block a user