Compare commits
2 Commits
6211096ad8
...
359d3aa9a8
| Author | SHA1 | Date | |
|---|---|---|---|
| 359d3aa9a8 | |||
| f2da1792b1 |
@ -9,6 +9,7 @@ import androidx.compose.foundation.ExperimentalFoundationApi
|
|||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.combinedClickable
|
import androidx.compose.foundation.combinedClickable
|
||||||
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
@ -53,6 +54,7 @@ import androidx.compose.material.icons.filled.ContentCopy
|
|||||||
import androidx.compose.material.icons.outlined.StarBorder
|
import androidx.compose.material.icons.outlined.StarBorder
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
|
import androidx.compose.ui.zIndex
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
|
|
||||||
// Data Classes
|
// Data Classes
|
||||||
@ -129,7 +131,7 @@ fun NotesApp() {
|
|||||||
var showFullScreenNote by remember { mutableStateOf(false) }
|
var showFullScreenNote by remember { mutableStateOf(false) }
|
||||||
var fullScreenNote by remember { mutableStateOf<Note?>(null) }
|
var fullScreenNote by remember { mutableStateOf<Note?>(null) }
|
||||||
|
|
||||||
// Load data dari DataStore - dengan error handling
|
// Load data dari DataStore
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
try {
|
try {
|
||||||
dataStoreManager.categoriesFlow.collect { loadedCategories ->
|
dataStoreManager.categoriesFlow.collect { loadedCategories ->
|
||||||
@ -174,6 +176,7 @@ fun NotesApp() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Box(modifier = Modifier.fillMaxSize()) {
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
if (!showFullScreenNote) {
|
if (!showFullScreenNote) {
|
||||||
@ -181,13 +184,14 @@ fun NotesApp() {
|
|||||||
title = when(currentScreen) {
|
title = when(currentScreen) {
|
||||||
"main" -> if (selectedCategory != null) selectedCategory!!.name else "AI Notes"
|
"main" -> if (selectedCategory != null) selectedCategory!!.name else "AI Notes"
|
||||||
"ai" -> "AI Helper"
|
"ai" -> "AI Helper"
|
||||||
|
"starred" -> "Berbintang"
|
||||||
"archive" -> "Arsip"
|
"archive" -> "Arsip"
|
||||||
"trash" -> "Sampah"
|
"trash" -> "Sampah"
|
||||||
else -> "AI Notes"
|
else -> "AI Notes"
|
||||||
},
|
},
|
||||||
showBackButton = (selectedCategory != null && currentScreen == "main") || currentScreen == "ai",
|
showBackButton = (selectedCategory != null && currentScreen == "main") || currentScreen == "ai" || currentScreen == "starred",
|
||||||
onBackClick = {
|
onBackClick = {
|
||||||
if (currentScreen == "ai") {
|
if (currentScreen == "ai" || currentScreen == "starred") {
|
||||||
currentScreen = "main"
|
currentScreen = "main"
|
||||||
} else {
|
} else {
|
||||||
selectedCategory = null
|
selectedCategory = null
|
||||||
@ -324,6 +328,22 @@ fun NotesApp() {
|
|||||||
notes = notes.filter { it.categoryId != category.id }
|
notes = notes.filter { it.categoryId != category.id }
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
"starred" -> StarredNotesScreen(
|
||||||
|
notes = notes,
|
||||||
|
categories = categories,
|
||||||
|
onNoteClick = { note ->
|
||||||
|
fullScreenNote = note
|
||||||
|
showFullScreenNote = true
|
||||||
|
},
|
||||||
|
onMenuClick = { drawerState = true },
|
||||||
|
onBack = { currentScreen = "main" },
|
||||||
|
onUnpin = { note ->
|
||||||
|
notes = notes.map {
|
||||||
|
if (it.id == note.id) it.copy(isPinned = false)
|
||||||
|
else it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
"ai" -> AIHelperScreen(
|
"ai" -> AIHelperScreen(
|
||||||
categories = categories,
|
categories = categories,
|
||||||
notes = notes.filter { !it.isDeleted }
|
notes = notes.filter { !it.isDeleted }
|
||||||
@ -361,25 +381,6 @@ fun NotesApp() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Drawer with Animation
|
|
||||||
AnimatedVisibility(
|
|
||||||
visible = drawerState,
|
|
||||||
enter = fadeIn() + slideInHorizontally(),
|
|
||||||
exit = fadeOut() + slideOutHorizontally()
|
|
||||||
) {
|
|
||||||
DrawerMenu(
|
|
||||||
currentScreen = currentScreen,
|
|
||||||
onDismiss = { drawerState = false },
|
|
||||||
onItemClick = { screen ->
|
|
||||||
currentScreen = screen
|
|
||||||
selectedCategory = null
|
|
||||||
drawerState = false
|
|
||||||
showSearch = false
|
|
||||||
searchQuery = ""
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dialogs
|
// Dialogs
|
||||||
if (showCategoryDialog) {
|
if (showCategoryDialog) {
|
||||||
CategoryDialog(
|
CategoryDialog(
|
||||||
@ -437,6 +438,31 @@ fun NotesApp() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Drawer with Animation - DI LUAR SCAFFOLD agar di atas semua
|
||||||
|
AnimatedVisibility(
|
||||||
|
visible = drawerState,
|
||||||
|
enter = fadeIn() + slideInHorizontally(
|
||||||
|
initialOffsetX = { -it }
|
||||||
|
),
|
||||||
|
exit = fadeOut() + slideOutHorizontally(
|
||||||
|
targetOffsetX = { -it }
|
||||||
|
),
|
||||||
|
modifier = Modifier.zIndex(100f) // Z-index tinggi
|
||||||
|
) {
|
||||||
|
DrawerMenu(
|
||||||
|
currentScreen = currentScreen,
|
||||||
|
onDismiss = { drawerState = false },
|
||||||
|
onItemClick = { screen ->
|
||||||
|
currentScreen = screen
|
||||||
|
selectedCategory = null
|
||||||
|
drawerState = false
|
||||||
|
showSearch = false
|
||||||
|
searchQuery = ""
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@ -952,12 +978,15 @@ fun NoteCard(
|
|||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
verticalAlignment = Alignment.Top
|
verticalAlignment = Alignment.Top
|
||||||
) {
|
) {
|
||||||
|
// Judul
|
||||||
Text(
|
Text(
|
||||||
note.title,
|
note.title,
|
||||||
style = MaterialTheme.typography.titleMedium,
|
style = MaterialTheme.typography.titleLarge,
|
||||||
fontWeight = FontWeight.Bold,
|
fontWeight = FontWeight.Bold,
|
||||||
color = Color.White,
|
color = Color.White,
|
||||||
modifier = Modifier.weight(1f)
|
modifier = Modifier.weight(1f),
|
||||||
|
maxLines = 2,
|
||||||
|
overflow = TextOverflow.Ellipsis
|
||||||
)
|
)
|
||||||
IconButton(
|
IconButton(
|
||||||
onClick = onPinClick,
|
onClick = onPinClick,
|
||||||
@ -966,24 +995,43 @@ fun NoteCard(
|
|||||||
Icon(
|
Icon(
|
||||||
if (note.isPinned) Icons.Filled.Star else Icons.Outlined.StarBorder,
|
if (note.isPinned) Icons.Filled.Star else Icons.Outlined.StarBorder,
|
||||||
contentDescription = "Pin",
|
contentDescription = "Pin",
|
||||||
tint = if (note.isPinned) Color(0xFFFBBF24) else Color(0xFF94A3B8),
|
tint = if (note.isPinned) Color(0xFFFBBF24) else Color.Gray,
|
||||||
modifier = Modifier.size(18.dp)
|
modifier = Modifier.size(18.dp)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deskripsi
|
||||||
if (note.content.isNotEmpty()) {
|
if (note.content.isNotEmpty()) {
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
Spacer(modifier = Modifier.height(12.dp))
|
||||||
|
Text(
|
||||||
|
text = "Deskripsi",
|
||||||
|
style = MaterialTheme.typography.labelSmall,
|
||||||
|
color = Color(0xFF94A3B8),
|
||||||
|
fontWeight = FontWeight.SemiBold
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.height(4.dp))
|
||||||
Text(
|
Text(
|
||||||
note.content,
|
note.content,
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
maxLines = 6,
|
maxLines = 4,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
color = Color(0xFFCBD5E1),
|
color = Color(0xFFCBD5E1),
|
||||||
lineHeight = 20.sp
|
lineHeight = 20.sp
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(12.dp))
|
Spacer(modifier = Modifier.height(12.dp))
|
||||||
|
|
||||||
|
// Divider
|
||||||
|
Divider(
|
||||||
|
color = Color(0xFF334155),
|
||||||
|
thickness = 1.dp
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
|
||||||
|
// Timestamp
|
||||||
Text(
|
Text(
|
||||||
dateFormat.format(Date(note.timestamp)),
|
dateFormat.format(Date(note.timestamp)),
|
||||||
style = MaterialTheme.typography.bodySmall,
|
style = MaterialTheme.typography.bodySmall,
|
||||||
@ -1002,20 +1050,32 @@ fun DrawerMenu(
|
|||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.background(Color.Black.copy(alpha = 0.6f))
|
.statusBarsPadding() // Padding untuk status bar
|
||||||
.clickable(onClick = onDismiss)
|
.background(Color.Black.copy(alpha = 0.5f))
|
||||||
|
.clickable(
|
||||||
|
onClick = onDismiss,
|
||||||
|
indication = null,
|
||||||
|
interactionSource = remember { MutableInteractionSource() }
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
Card(
|
Card(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxHeight()
|
.fillMaxHeight()
|
||||||
.width(280.dp)
|
.width(250.dp)
|
||||||
.clickable(enabled = false) {},
|
.align(Alignment.CenterStart)
|
||||||
shape = RoundedCornerShape(0.dp),
|
.clickable(
|
||||||
|
onClick = {},
|
||||||
|
indication = null,
|
||||||
|
interactionSource = remember { MutableInteractionSource() }
|
||||||
|
),
|
||||||
|
shape = RoundedCornerShape(topEnd = 0.dp, bottomEnd = 0.dp),
|
||||||
colors = CardDefaults.cardColors(
|
colors = CardDefaults.cardColors(
|
||||||
containerColor = Color(0xFF1E293B)
|
containerColor = Color(0xFF1E293B)
|
||||||
)
|
),
|
||||||
|
elevation = CardDefaults.cardElevation(defaultElevation = 16.dp)
|
||||||
) {
|
) {
|
||||||
Column(modifier = Modifier.fillMaxSize()) {
|
Column(modifier = Modifier.fillMaxSize()) {
|
||||||
|
// Header Drawer dengan tombol close
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
@ -1024,14 +1084,19 @@ fun DrawerMenu(
|
|||||||
colors = listOf(Color(0xFF6366F1), Color(0xFFA855F7))
|
colors = listOf(Color(0xFF6366F1), Color(0xFFA855F7))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.padding(32.dp)
|
.padding(24.dp)
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
Column {
|
Column {
|
||||||
Icon(
|
Icon(
|
||||||
Icons.Default.Create,
|
Icons.Default.Create,
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
tint = Color.White,
|
tint = Color.White,
|
||||||
modifier = Modifier.size(40.dp)
|
modifier = Modifier.size(36.dp)
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.height(12.dp))
|
Spacer(modifier = Modifier.height(12.dp))
|
||||||
Text(
|
Text(
|
||||||
@ -1046,10 +1111,30 @@ fun DrawerMenu(
|
|||||||
color = Color.White.copy(0.8f)
|
color = Color.White.copy(0.8f)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// // Tombol Close
|
||||||
|
// IconButton(
|
||||||
|
// onClick = onDismiss,
|
||||||
|
// modifier = Modifier
|
||||||
|
// .size(40.dp)
|
||||||
|
// .background(
|
||||||
|
// Color.White.copy(alpha = 0.2f),
|
||||||
|
// shape = CircleShape
|
||||||
|
// )
|
||||||
|
// ) {
|
||||||
|
// Icon(
|
||||||
|
// Icons.Default.Close,
|
||||||
|
// contentDescription = "Tutup Menu",
|
||||||
|
// tint = Color.White,
|
||||||
|
// modifier = Modifier.size(24.dp)
|
||||||
|
// )
|
||||||
|
// }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
|
// Menu Items
|
||||||
MenuItem(
|
MenuItem(
|
||||||
icon = Icons.Default.Home,
|
icon = Icons.Default.Home,
|
||||||
text = "Beranda",
|
text = "Beranda",
|
||||||
@ -1073,6 +1158,21 @@ fun DrawerMenu(
|
|||||||
text = "Sampah",
|
text = "Sampah",
|
||||||
isSelected = currentScreen == "trash"
|
isSelected = currentScreen == "trash"
|
||||||
) { onItemClick("trash") }
|
) { onItemClick("trash") }
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
|
|
||||||
|
// Footer
|
||||||
|
Divider(
|
||||||
|
color = Color.White.copy(alpha = 0.1f),
|
||||||
|
modifier = Modifier.padding(horizontal = 16.dp)
|
||||||
|
)
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = "Version 1.0.0",
|
||||||
|
style = MaterialTheme.typography.bodySmall,
|
||||||
|
color = Color.White.copy(alpha = 0.5f),
|
||||||
|
modifier = Modifier.padding(16.dp)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1803,10 +1903,11 @@ fun ChatBubble(
|
|||||||
horizontalArrangement = if (message.isUser) Arrangement.End else Arrangement.Start
|
horizontalArrangement = if (message.isUser) Arrangement.End else Arrangement.Start
|
||||||
) {
|
) {
|
||||||
if (!message.isUser) {
|
if (!message.isUser) {
|
||||||
|
// Ganti ikon bintang dengan ikon robot/sparkles
|
||||||
Icon(
|
Icon(
|
||||||
Icons.Default.AutoAwesome,
|
Icons.Default.AutoAwesome, // Atau bisa diganti dengan ikon lain seperti AutoAwesome
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
tint = Color(0xFFFBBF24),
|
tint = Color(0xFF6366F1), // Warna ungu/biru untuk AI
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(32.dp)
|
.size(32.dp)
|
||||||
.padding(end = 8.dp)
|
.padding(end = 8.dp)
|
||||||
@ -2176,118 +2277,39 @@ fun TrashNoteCard(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun StarredNotesScreen(
|
fun StarredNotesScreen(
|
||||||
notes: List<Note>,
|
notes: List<Note>,
|
||||||
|
categories: List<Category>,
|
||||||
onNoteClick: (Note) -> Unit,
|
onNoteClick: (Note) -> Unit,
|
||||||
onMenuClick: () -> Unit,
|
onMenuClick: () -> Unit,
|
||||||
onBack: () -> Unit
|
onBack: () -> Unit,
|
||||||
|
onUnpin: (Note) -> Unit
|
||||||
) {
|
) {
|
||||||
val starredNotes = notes.filter { it.isPinned && !it.isArchived && !it.isDeleted }
|
val starredNotes = notes.filter { it.isPinned && !it.isArchived && !it.isDeleted }
|
||||||
|
|
||||||
Scaffold(
|
|
||||||
containerColor = MaterialTheme.colorScheme.background,
|
|
||||||
topBar = {
|
|
||||||
TopAppBar(
|
|
||||||
title = {
|
|
||||||
Text(
|
|
||||||
"Berbintang",
|
|
||||||
style = MaterialTheme.typography.titleLarge,
|
|
||||||
fontWeight = FontWeight.Bold,
|
|
||||||
color = MaterialTheme.colorScheme.onBackground
|
|
||||||
)
|
|
||||||
},
|
|
||||||
navigationIcon = {
|
|
||||||
IconButton(onClick = onBack) {
|
|
||||||
Icon(
|
|
||||||
Icons.AutoMirrored.Filled.ArrowBack,
|
|
||||||
contentDescription = "Kembali",
|
|
||||||
tint = MaterialTheme.colorScheme.onBackground
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
actions = {
|
|
||||||
IconButton(onClick = onMenuClick) {
|
|
||||||
Icon(
|
|
||||||
Icons.Default.Menu,
|
|
||||||
contentDescription = "Menu",
|
|
||||||
tint = MaterialTheme.colorScheme.onBackground
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
colors = TopAppBarDefaults.topAppBarColors(
|
|
||||||
containerColor = Color.Transparent
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
) { padding ->
|
|
||||||
if (starredNotes.isEmpty()) {
|
if (starredNotes.isEmpty()) {
|
||||||
// Tampilan kosong
|
EmptyState(
|
||||||
Box(
|
icon = Icons.Default.Star,
|
||||||
modifier = Modifier
|
message = "Belum ada catatan berbintang",
|
||||||
.fillMaxSize()
|
subtitle = "Catatan yang ditandai berbintang akan muncul di sini"
|
||||||
.padding(padding),
|
|
||||||
contentAlignment = Alignment.Center
|
|
||||||
) {
|
|
||||||
Column(
|
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
|
||||||
verticalArrangement = Arrangement.Center,
|
|
||||||
modifier = Modifier.padding(horizontal = 32.dp)
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
Icons.Default.Star,
|
|
||||||
contentDescription = null,
|
|
||||||
tint = Color(0xFF64748B),
|
|
||||||
modifier = Modifier.size(80.dp)
|
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
|
||||||
Text(
|
|
||||||
"Belum Ada Catatan Berbintang",
|
|
||||||
style = MaterialTheme.typography.titleMedium,
|
|
||||||
color = Color(0xFF64748B),
|
|
||||||
fontWeight = FontWeight.SemiBold,
|
|
||||||
textAlign = TextAlign.Center
|
|
||||||
)
|
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
|
||||||
Text(
|
|
||||||
"Tandai catatan penting dengan bintang agar mudah ditemukan",
|
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
|
||||||
color = Color(0xFF94A3B8),
|
|
||||||
textAlign = TextAlign.Center
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Daftar catatan berbintang
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
modifier = Modifier
|
contentPadding = PaddingValues(16.dp),
|
||||||
.fillMaxSize()
|
|
||||||
.padding(padding)
|
|
||||||
.padding(horizontal = 16.dp),
|
|
||||||
verticalArrangement = Arrangement.spacedBy(12.dp)
|
verticalArrangement = Arrangement.spacedBy(12.dp)
|
||||||
) {
|
) {
|
||||||
item {
|
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
|
||||||
Text(
|
|
||||||
text = "${starredNotes.size} catatan berbintang",
|
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
|
||||||
color = Color(0xFF64748B),
|
|
||||||
modifier = Modifier.padding(start = 4.dp, bottom = 4.dp)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
items(starredNotes) { note ->
|
items(starredNotes) { note ->
|
||||||
|
val category = categories.find { it.id == note.categoryId }
|
||||||
StarredNoteCard(
|
StarredNoteCard(
|
||||||
note = note,
|
note = note,
|
||||||
onClick = { onNoteClick(note) }
|
categoryName = category?.name ?: "Unknown",
|
||||||
|
onClick = { onNoteClick(note) },
|
||||||
|
onUnpin = { onUnpin(note) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
item {
|
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2295,114 +2317,90 @@ fun StarredNotesScreen(
|
|||||||
@Composable
|
@Composable
|
||||||
fun StarredNoteCard(
|
fun StarredNoteCard(
|
||||||
note: Note,
|
note: Note,
|
||||||
onClick: () -> Unit
|
categoryName: String,
|
||||||
|
onClick: () -> Unit,
|
||||||
|
onUnpin: () -> Unit
|
||||||
) {
|
) {
|
||||||
val dateFormat = remember { SimpleDateFormat("dd MMM yyyy · HH:mm", Locale("id", "ID")) }
|
|
||||||
|
|
||||||
Card(
|
Card(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.clickable(onClick = onClick),
|
.clickable(onClick = onClick),
|
||||||
colors = CardDefaults.cardColors(
|
|
||||||
containerColor = MaterialTheme.colorScheme.surface
|
|
||||||
),
|
|
||||||
shape = RoundedCornerShape(16.dp),
|
shape = RoundedCornerShape(16.dp),
|
||||||
elevation = CardDefaults.cardElevation(
|
colors = CardDefaults.cardColors(
|
||||||
defaultElevation = 2.dp,
|
containerColor = Color(0xFF1E293B)
|
||||||
pressedElevation = 4.dp
|
),
|
||||||
)
|
elevation = CardDefaults.cardElevation(defaultElevation = 2.dp)
|
||||||
) {
|
) {
|
||||||
Column(
|
Column(modifier = Modifier.padding(16.dp)) {
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(20.dp)
|
|
||||||
) {
|
|
||||||
// Header dengan judul dan ikon bintang
|
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
verticalAlignment = Alignment.Top
|
verticalAlignment = Alignment.Top
|
||||||
) {
|
) {
|
||||||
Text(
|
Column(modifier = Modifier.weight(1f)) {
|
||||||
text = note.title,
|
Row(
|
||||||
style = MaterialTheme.typography.titleLarge,
|
verticalAlignment = Alignment.CenterVertically
|
||||||
fontWeight = FontWeight.Bold,
|
|
||||||
color = MaterialTheme.colorScheme.onSurface,
|
|
||||||
maxLines = 2,
|
|
||||||
overflow = TextOverflow.Ellipsis,
|
|
||||||
modifier = Modifier.weight(1f)
|
|
||||||
)
|
|
||||||
|
|
||||||
Spacer(modifier = Modifier.width(12.dp))
|
|
||||||
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.size(32.dp)
|
|
||||||
.background(
|
|
||||||
color = Color(0xFFFBBF24).copy(alpha = 0.15f),
|
|
||||||
shape = CircleShape
|
|
||||||
),
|
|
||||||
contentAlignment = Alignment.Center
|
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
Icons.Default.Star,
|
Icons.Default.Star,
|
||||||
contentDescription = "Berbintang",
|
|
||||||
tint = Color(0xFFFBBF24),
|
|
||||||
modifier = Modifier.size(18.dp)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Konten catatan
|
|
||||||
if (note.content.isNotBlank()) {
|
|
||||||
Spacer(modifier = Modifier.height(12.dp))
|
|
||||||
Text(
|
|
||||||
text = note.content,
|
|
||||||
style = MaterialTheme.typography.bodyLarge,
|
|
||||||
color = Color(0xFF64748B),
|
|
||||||
maxLines = 4,
|
|
||||||
overflow = TextOverflow.Ellipsis,
|
|
||||||
lineHeight = 24.sp
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Footer dengan timestamp
|
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
|
||||||
|
|
||||||
Row(
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
|
||||||
verticalAlignment = Alignment.CenterVertically
|
|
||||||
) {
|
|
||||||
Row(
|
|
||||||
verticalAlignment = Alignment.CenterVertically
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
Icons.Default.Schedule,
|
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
tint = Color(0xFF94A3B8),
|
tint = Color(0xFFFBBF24),
|
||||||
modifier = Modifier.size(14.dp)
|
modifier = Modifier.size(16.dp)
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.width(8.dp))
|
||||||
|
Text(
|
||||||
|
note.title,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
color = Color.White,
|
||||||
|
style = MaterialTheme.typography.titleMedium
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Spacer(modifier = Modifier.height(4.dp))
|
||||||
|
Text(
|
||||||
|
categoryName,
|
||||||
|
color = Color(0xFF64748B),
|
||||||
|
style = MaterialTheme.typography.bodySmall
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (note.content.isNotEmpty()) {
|
||||||
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
Text(
|
||||||
|
note.content,
|
||||||
|
maxLines = 2,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
color = Color(0xFF94A3B8),
|
||||||
|
style = MaterialTheme.typography.bodyMedium
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(top = 12.dp),
|
||||||
|
horizontalArrangement = Arrangement.End
|
||||||
|
) {
|
||||||
|
TextButton(onClick = onClick) {
|
||||||
|
Icon(
|
||||||
|
Icons.Default.Info,
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier.size(18.dp),
|
||||||
|
tint = Color(0xFF6366F1)
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.width(4.dp))
|
Spacer(modifier = Modifier.width(4.dp))
|
||||||
Text(
|
Text("Lihat Detail", color = Color(0xFF6366F1), fontWeight = FontWeight.Bold)
|
||||||
text = dateFormat.format(Date(note.timestamp)),
|
|
||||||
style = MaterialTheme.typography.bodySmall,
|
|
||||||
color = Color(0xFF94A3B8)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
Spacer(modifier = Modifier.width(8.dp))
|
||||||
// Badge indicator
|
TextButton(onClick = onUnpin) {
|
||||||
Surface(
|
Icon(
|
||||||
color = Color(0xFFA855F7).copy(alpha = 0.15f),
|
Icons.Outlined.StarBorder,
|
||||||
shape = RoundedCornerShape(8.dp)
|
contentDescription = null,
|
||||||
) {
|
modifier = Modifier.size(18.dp),
|
||||||
Text(
|
tint = Color(0xFFFBBF24)
|
||||||
text = "Penting",
|
|
||||||
style = MaterialTheme.typography.labelSmall,
|
|
||||||
color = Color(0xFFA855F7),
|
|
||||||
fontWeight = FontWeight.SemiBold,
|
|
||||||
modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp)
|
|
||||||
)
|
)
|
||||||
|
Spacer(modifier = Modifier.width(4.dp))
|
||||||
|
Text("Hapus Bintang", color = Color(0xFFFBBF24), fontWeight = FontWeight.Bold)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user