Apis benerin dong

This commit is contained in:
202310715082 FAZRI ABDURRAHMAN 2025-11-17 14:48:17 +07:00
parent f64bff7933
commit 912c489123
3 changed files with 467 additions and 326 deletions

View File

@ -4,6 +4,14 @@
<selectionStates>
<SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2025-11-14T10:53:18.219362400Z">
<Target type="DEFAULT_BOOT">
<handle>
<DeviceId pluginId="PhysicalDevice" identifier="serial=10DEC90GZE0004R" />
</handle>
</Target>
</DropdownSelection>
<DialogSelection />
</SelectionState>
</selectionStates>
</component>

View File

@ -5,7 +5,7 @@
<list>
<ColumnSorterState>
<option name="column" value="Name" />
<option name="order" value="ASCENDING" />
<option name="order" value="DESCENDING" />
</ColumnSorterState>
</list>
</option>

View File

@ -6,8 +6,9 @@ import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.viewModels
import androidx.compose.animation.*
import androidx.compose.animation.core.*
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
@ -15,16 +16,16 @@ import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.Send
import androidx.compose.material.icons.filled.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
@ -40,8 +41,6 @@ class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Initialize PDFBox
com.example.notebook.utils.PdfHelper.initialize(this)
setContent {
@ -50,9 +49,9 @@ class MainActivity : ComponentActivity() {
NotebookTheme(darkTheme = isDarkMode) {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
color = MaterialTheme.colorScheme.background // [DIUBAH] Menggunakan warna tema
) {
NotebookApp(
NotebookBottomSheetApp(
viewModel = viewModel,
isDarkMode = isDarkMode,
onThemeChange = { isDarkMode = it }
@ -63,130 +62,26 @@ class MainActivity : ComponentActivity() {
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun NotebookApp(viewModel: NotebookViewModel, isDarkMode: Boolean, onThemeChange: (Boolean) -> Unit) {
var selectedTabIndex by remember { mutableIntStateOf(0) }
val tabs = listOf("Studio", "Chat", "Sources")
var showGoogleAppsMenu by remember { mutableStateOf(false) }
var showSettingsMenu by remember { mutableStateOf(false) }
var showAccountScreen by remember { mutableStateOf(false) }
var chatInput by remember { mutableStateOf("") }
fun NotebookBottomSheetApp(
viewModel: NotebookViewModel,
isDarkMode: Boolean,
onThemeChange: (Boolean) -> Unit
) {
val notebooks by viewModel.notebooks.collectAsState()
var selectedNotebookId by remember { mutableIntStateOf(-1) }
var showCreateDialog by remember { mutableStateOf(false) }
var showAccountScreen by remember { mutableStateOf(false) }
// Log setiap kali selectedNotebookId berubah
LaunchedEffect(selectedNotebookId) {
println("🎯 selectedNotebookId berubah menjadi: $selectedNotebookId")
}
// Kalau ada notebook yang dipilih, tampilkan detail screen
if (selectedNotebookId != -1) {
println("✨ Menampilkan NotebookDetailScreen untuk ID: $selectedNotebookId")
com.example.notebook.ui.screens.NotebookDetailScreen(
viewModel = viewModel,
notebookId = selectedNotebookId,
onBack = {
println("⬅️ Kembali dari detail screen")
selectedNotebookId = -1
}
onBack = { selectedNotebookId = -1 }
)
return
}
if (showAccountScreen) {
AccountScreen(onDismiss = { showAccountScreen = false })
}
Scaffold(
topBar = {
TopAppBar(
title = { Text("NoteBook") },
actions = {
Box {
IconButton(onClick = { showSettingsMenu = true }) {
Icon(Icons.Filled.Settings, contentDescription = "Settings")
}
SettingsMenu(
expanded = showSettingsMenu,
onDismiss = { showSettingsMenu = false },
isDarkMode = isDarkMode,
onThemeChange = onThemeChange
)
}
Box(
modifier = Modifier
.size(32.dp)
.clip(CircleShape)
.background(Color.Magenta)
.clickable { showAccountScreen = true },
contentAlignment = Alignment.Center
) {
Text("M", color = Color.White, fontWeight = FontWeight.Bold)
}
Spacer(modifier = Modifier.width(8.dp))
}
)
},
bottomBar = {
if (selectedTabIndex == 1) {
BottomAppBar {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.padding(horizontal = 8.dp)
) {
OutlinedTextField(
value = chatInput,
onValueChange = { chatInput = it },
placeholder = { Text("Message...") },
modifier = Modifier.weight(1f)
)
IconButton(
onClick = {
if (chatInput.isNotBlank()) {
// TODO: Kirim ke notebook yang aktif
// viewModel.sendUserMessage(notebookId, chatInput)
chatInput = ""
}
}
) {
Icon(Icons.AutoMirrored.Filled.Send, contentDescription = "Send")
}
}
}
}
}
) { innerPadding ->
Column(modifier = Modifier.padding(innerPadding)) {
TabRow(selectedTabIndex = selectedTabIndex) {
tabs.forEachIndexed { index, title ->
Tab(
selected = selectedTabIndex == index,
onClick = { selectedTabIndex = index },
text = { Text(title) }
)
}
}
when (selectedTabIndex) {
0 -> StudioScreen(
viewModel = viewModel,
onNotebookClick = { notebookId ->
println("📱 Navigasi ke notebook ID: $notebookId")
selectedNotebookId = notebookId
}
)
1 -> ChatScreen(viewModel)
2 -> SourcesScreen(viewModel)
}
}
}
}
// === STUDIO SCREEN (UPDATED) ===
@Composable
fun StudioScreen(viewModel: NotebookViewModel, onNotebookClick: (Int) -> Unit) {
val notebooks by viewModel.notebooks.collectAsState()
var showCreateDialog by remember { mutableStateOf(false) }
if (showCreateDialog) {
CreateNotebookDialog(
onDismiss = { showCreateDialog = false },
@ -197,154 +92,468 @@ fun StudioScreen(viewModel: NotebookViewModel, onNotebookClick: (Int) -> Unit) {
)
}
Column(
if (showAccountScreen) {
AccountScreen(onDismiss = { showAccountScreen = false })
}
Box(
modifier = Modifier
.fillMaxSize()
.background(Color.White)
.padding(16.dp)
.background(MaterialTheme.colorScheme.background) // [DIUBAH] Menggunakan warna tema
) {
Text(
"Notebook terbaru",
style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.Bold,
color = Color.Black
)
Spacer(modifier = Modifier.height(16.dp))
LazyColumn(
verticalArrangement = Arrangement.spacedBy(12.dp)
Column(
modifier = Modifier
.fillMaxSize()
.shadow(
elevation = 8.dp,
shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp)
)
.clip(RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp))
.background(MaterialTheme.colorScheme.surface) // [DIUBAH] Menggunakan warna tema
) {
// Card untuk buat notebook baru
item {
NewNotebookCard(onClick = { showCreateDialog = true })
NotebookHeader(
isDarkMode = isDarkMode,
onThemeChange = onThemeChange,
onAccountClick = { showAccountScreen = true }
)
Divider(color = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.5f), thickness = 1.dp)
Column(
modifier = Modifier
.fillMaxSize()
.padding(horizontal = 16.dp)
.padding(top = 16.dp)
) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Text(
"Notebook Saya",
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.onSurface // [DIUBAH]
)
Text(
"${notebooks.size} notebook tersimpan",
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant // [DIUBAH]
)
}
Spacer(modifier = Modifier.height(16.dp))
CreateNotebookButton(onClick = { showCreateDialog = true })
Spacer(modifier = Modifier.height(20.dp))
if (notebooks.isEmpty()) {
EmptyNotebookMessage()
} else {
LazyColumn(
verticalArrangement = Arrangement.spacedBy(12.dp),
contentPadding = PaddingValues(bottom = 16.dp)
) {
items(notebooks, key = { it.id }) { notebook ->
NotebookCardItem(
notebook = notebook,
onClick = { selectedNotebookId = notebook.id },
onDelete = { viewModel.deleteNotebook(notebook) }
)
}
}
}
}
}
}
}
@Composable
fun NotebookHeader(
isDarkMode: Boolean,
onThemeChange: (Boolean) -> Unit,
onAccountClick: () -> Unit
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 12.dp),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Row(verticalAlignment = Alignment.CenterVertically) {
Box(
modifier = Modifier
.size(32.dp)
.clip(RoundedCornerShape(8.dp))
.background(
Brush.linearGradient(
listOf(Color(0xFF7C3AED), Color(0xFF9333EA))
)
),
contentAlignment = Alignment.Center
) {
Icon(
Icons.Default.Book,
contentDescription = null,
tint = Color.White,
modifier = Modifier.size(20.dp)
)
}
Spacer(modifier = Modifier.width(8.dp))
Column {
Text(
"NoteBook",
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.onSurface // [DIUBAH]
)
Text(
"Selamat datang kembali!",
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant, // [DIUBAH]
fontSize = 11.sp
)
}
}
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
IconButton(onClick = { onThemeChange(!isDarkMode) }) {
Icon(
imageVector = if (isDarkMode) Icons.Default.LightMode else Icons.Default.DarkMode,
contentDescription = "Toggle Theme",
tint = MaterialTheme.colorScheme.onSurfaceVariant // [DIUBAH]
)
}
// List notebooks yang sudah ada
items(notebooks) { notebook ->
NotebookCard(
notebook = notebook,
onClick = {
println("🟢 onClick triggered untuk notebook ID: ${notebook.id}")
onNotebookClick(notebook.id)
},
onDelete = {
println("🔴 Delete triggered untuk notebook ID: ${notebook.id}")
viewModel.deleteNotebook(notebook)
}
IconButton(onClick = onAccountClick) {
Icon(
Icons.Default.AccountCircle,
contentDescription = "Account",
tint = Color(0xFF7C3AED),
modifier = Modifier.size(28.dp)
)
}
}
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun NewNotebookCard(onClick: () -> Unit) {
Card(
modifier = Modifier
.fillMaxWidth()
.height(120.dp)
.clickable(onClick = onClick),
shape = RoundedCornerShape(16.dp),
colors = CardDefaults.cardColors(containerColor = Color(0xFFF0F4F7))
) {
Column(
fun AccountScreen(onDismiss: () -> Unit) {
Dialog(onDismissRequest = onDismiss, properties = DialogProperties(usePlatformDefaultWidth = false)) {
Scaffold(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Box(
modifier = Modifier
.size(40.dp)
.clip(CircleShape)
.background(Color(0xFFE1E3E6)),
contentAlignment = Alignment.Center
) {
Icon(Icons.Default.Add, contentDescription = "Buat notebook baru", tint = Color.Black)
topBar = {
TopAppBar(
title = { Text("Akun") },
navigationIcon = {
IconButton(onClick = onDismiss) {
Icon(Icons.Default.Close, contentDescription = "Tutup")
}
}
)
}
) { paddingValues ->
Column(
modifier = Modifier
.fillMaxSize()
.padding(paddingValues)
.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Spacer(modifier = Modifier.height(32.dp))
Box(
modifier = Modifier
.size(80.dp)
.clip(CircleShape)
.background(MaterialTheme.colorScheme.primary), // [DIUBAH]
contentAlignment = Alignment.Center
) {
Text("A", fontSize = 40.sp, color = MaterialTheme.colorScheme.onPrimary, fontWeight = FontWeight.Bold) // [DIUBAH]
}
Spacer(modifier = Modifier.height(16.dp))
Text("user@google.com", fontWeight = FontWeight.Bold, fontSize = 20.sp, color = MaterialTheme.colorScheme.onSurface)
Spacer(modifier = Modifier.height(8.dp))
Text("Fazri Abdurrahman", fontSize = 16.sp, color = MaterialTheme.colorScheme.onSurfaceVariant)
Spacer(modifier = Modifier.height(24.dp))
// [DIUBAH] Tombol Kelola Akun menjadi OutlinedButton
OutlinedButton(onClick = { /* TODO: Logika Google Sign-In */ }, modifier = Modifier.fillMaxWidth()) {
Text("Kelola Akun Google Anda")
}
Spacer(modifier = Modifier.height(24.dp))
// [BARU] Kartu untuk menambah dan mengelola akun
Card(
modifier = Modifier.fillMaxWidth(),
shape = RoundedCornerShape(16.dp),
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surfaceContainer)
) {
Column {
Row(
modifier = Modifier
.fillMaxWidth()
.clickable { /* TODO */ }
.padding(16.dp),
verticalAlignment = Alignment.CenterVertically
) {
Icon(Icons.Default.PersonAdd, contentDescription = null, tint = MaterialTheme.colorScheme.onSurfaceVariant)
Spacer(modifier = Modifier.width(16.dp))
Text("Tambah akun lain", color = MaterialTheme.colorScheme.onSurface)
}
Divider(modifier = Modifier.padding(horizontal = 16.dp))
Row(
modifier = Modifier
.fillMaxWidth()
.clickable { /* TODO */ }
.padding(16.dp),
verticalAlignment = Alignment.CenterVertically
) {
Icon(Icons.Default.ManageAccounts, contentDescription = null, tint = MaterialTheme.colorScheme.onSurfaceVariant)
Spacer(modifier = Modifier.width(16.dp))
Text("Kelola akun di perangkat ini", color = MaterialTheme.colorScheme.onSurface)
}
}
}
Spacer(modifier = Modifier.weight(1f))
Row(
modifier = Modifier.padding(bottom = 16.dp),
horizontalArrangement = Arrangement.spacedBy(8.dp),
) {
Text("Kebijakan Privasi", fontSize = 12.sp, color = MaterialTheme.colorScheme.onSurfaceVariant)
Text("", fontSize = 12.sp, color = MaterialTheme.colorScheme.onSurfaceVariant)
Text("Persyaratan Layanan", fontSize = 12.sp, color = MaterialTheme.colorScheme.onSurfaceVariant)
}
}
Spacer(modifier = Modifier.height(8.dp))
Text("Buat notebook baru", color = Color.Black)
}
}
}
@Composable
fun NotebookCard(
fun CreateNotebookButton(onClick: () -> Unit) {
Button(
onClick = onClick,
modifier = Modifier
.fillMaxWidth()
.height(56.dp),
shape = RoundedCornerShape(12.dp),
colors = ButtonDefaults.buttonColors(
containerColor = Color.Transparent
),
contentPadding = PaddingValues(0.dp)
) {
Box(
modifier = Modifier
.fillMaxSize()
.background(
Brush.horizontalGradient(
listOf(Color(0xFF7C3AED), Color(0xFF9333EA))
)
),
contentAlignment = Alignment.Center
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center
) {
Icon(
Icons.Default.Add,
contentDescription = null,
tint = Color.White,
modifier = Modifier.size(24.dp)
)
Spacer(modifier = Modifier.width(8.dp))
Column(horizontalAlignment = Alignment.Start) {
Text(
"Buat notebook baru",
color = Color.White,
fontWeight = FontWeight.Bold,
fontSize = 15.sp
)
}
}
}
}
}
@Composable
fun NotebookCardItem(
notebook: com.example.notebook.data.NotebookEntity,
onClick: () -> Unit,
onDelete: () -> Unit
) {
val dateFormat = SimpleDateFormat("dd MMM yyyy, HH:mm", Locale.getDefault())
val dateFormat = SimpleDateFormat("dd MMM yyyy, HH:mm", Locale("id", "ID"))
var showMenu by remember { mutableStateOf(false) }
var showDeleteDialog by remember { mutableStateOf(false) }
val iconColors = listOf(
Color(0xFFEC4899), // Pink
Color(0xFF8B5CF6), // Purple
Color(0xFF3B82F6), // Blue
Color(0xFF10B981), // Green
Color(0xFFF59E0B), // Orange
)
val iconColor = remember { iconColors.random() }
if (showDeleteDialog) {
AlertDialog(
onDismissRequest = { showDeleteDialog = false },
icon = { Icon(Icons.Default.Delete, contentDescription = null) },
title = { Text("Hapus Notebook?") },
text = { Text("Notebook \"${notebook.title}\" dan semua isinya akan dihapus permanen.") },
confirmButton = {
Button(
onClick = {
onDelete()
showDeleteDialog = false
},
colors = ButtonDefaults.buttonColors(
containerColor = Color(0xFFEF4444)
)
) {
Text("Hapus")
}
},
dismissButton = {
TextButton(onClick = { showDeleteDialog = false }) {
Text("Batal")
}
}
)
}
Card(
modifier = Modifier.fillMaxWidth(),
modifier = Modifier
.fillMaxWidth()
.clickable(onClick = onClick),
shape = RoundedCornerShape(12.dp),
colors = CardDefaults.cardColors(containerColor = Color(0xFFF8F9FA)),
onClick = {
println("🔵 Card onClick: ID=${notebook.id}, Title=${notebook.title}")
onClick()
}
colors = CardDefaults.cardColors(
containerColor = MaterialTheme.colorScheme.surfaceContainerLowest // [DIUBAH]
),
elevation = CardDefaults.cardElevation(defaultElevation = 0.dp)
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
.padding(12.dp),
verticalAlignment = Alignment.CenterVertically
) {
// Icon notebook
Box(
modifier = Modifier
.size(48.dp)
.clip(RoundedCornerShape(8.dp))
.background(Color(0xFFE8EAF6)),
.size(44.dp)
.clip(RoundedCornerShape(10.dp))
.background(iconColor),
contentAlignment = Alignment.Center
) {
Icon(
Icons.Default.Description,
contentDescription = null,
tint = Color(0xFF5C6BC0)
tint = Color.White,
modifier = Modifier.size(24.dp)
)
}
Spacer(modifier = Modifier.width(12.dp))
// Info notebook
Column(modifier = Modifier.weight(1f)) {
Text(
text = notebook.title,
style = MaterialTheme.typography.titleMedium,
style = MaterialTheme.typography.titleSmall,
fontWeight = FontWeight.Bold,
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
Spacer(modifier = Modifier.height(4.dp))
Text(
text = if (notebook.description.isNotBlank()) notebook.description
else "Belum ada deskripsi",
style = MaterialTheme.typography.bodySmall,
color = Color.Gray,
maxLines = 1,
overflow = TextOverflow.Ellipsis
overflow = TextOverflow.Ellipsis,
color = MaterialTheme.colorScheme.onSurface // [DIUBAH]
)
Spacer(modifier = Modifier.height(4.dp))
Text(
text = dateFormat.format(Date(notebook.updatedAt)),
style = MaterialTheme.typography.bodySmall,
color = Color.Gray
color = MaterialTheme.colorScheme.onSurfaceVariant, // [DIUBAH]
fontSize = 12.sp
)
if (notebook.description.isNotBlank()) {
Spacer(modifier = Modifier.height(4.dp))
Text(
text = notebook.description,
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.outline, // [DIUBAH]
maxLines = 1,
overflow = TextOverflow.Ellipsis,
fontSize = 12.sp
)
}
}
// Delete button
IconButton(onClick = onDelete) {
Icon(
Icons.Default.Delete,
contentDescription = "Hapus",
tint = Color.Gray
)
Box {
IconButton(
onClick = { showMenu = true },
modifier = Modifier.size(32.dp)
) {
Icon(
Icons.Default.MoreVert,
contentDescription = "Menu",
tint = MaterialTheme.colorScheme.onSurfaceVariant // [DIUBAH]
)
}
DropdownMenu(
expanded = showMenu,
onDismissRequest = { showMenu = false }
) {
DropdownMenuItem(
text = { Text("Hapus") },
onClick = {
showMenu = false
showDeleteDialog = true
},
leadingIcon = {
Icon(
Icons.Default.Delete,
contentDescription = null,
tint = Color(0xFFEF4444)
)
}
)
}
}
}
}
}
@Composable
fun EmptyNotebookMessage() {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 32.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Icon(
Icons.Default.Description,
contentDescription = null,
modifier = Modifier.size(64.dp),
tint = MaterialTheme.colorScheme.surfaceVariant // [DIUBAH]
)
Spacer(modifier = Modifier.height(16.dp))
Text(
"Belum ada notebook",
style = MaterialTheme.typography.titleMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant // [DIUBAH]
)
Text(
"Klik tombol di atas untuk membuat notebook baru",
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.outline // [DIUBAH]
)
}
}
@Composable
fun CreateNotebookDialog(
onDismiss: () -> Unit,
@ -355,23 +564,58 @@ fun CreateNotebookDialog(
AlertDialog(
onDismissRequest = onDismiss,
title = { Text("Buat Notebook Baru") },
icon = {
Box(
modifier = Modifier
.size(56.dp)
.clip(CircleShape)
.background(
Brush.linearGradient(
listOf(Color(0xFF7C3AED), Color(0xFF9333EA))
)
),
contentAlignment = Alignment.Center
) {
Icon(
Icons.Default.Add,
contentDescription = null,
tint = Color.White,
modifier = Modifier.size(28.dp)
)
}
},
title = {
Text(
"Buat Notebook Baru",
fontWeight = FontWeight.Bold
)
},
text = {
Column {
OutlinedTextField(
value = title,
onValueChange = { title = it },
label = { Text("Judul Notebook") },
placeholder = { Text("Contoh: Catatan Kuliah") },
singleLine = true,
modifier = Modifier.fillMaxWidth()
modifier = Modifier.fillMaxWidth(),
colors = OutlinedTextFieldDefaults.colors(
focusedBorderColor = Color(0xFF7C3AED),
focusedLabelColor = Color(0xFF7C3AED)
)
)
Spacer(modifier = Modifier.height(8.dp))
Spacer(modifier = Modifier.height(12.dp))
OutlinedTextField(
value = description,
onValueChange = { description = it },
label = { Text("Deskripsi (opsional)") },
placeholder = { Text("Tambahkan deskripsi singkat...") },
maxLines = 3,
modifier = Modifier.fillMaxWidth()
modifier = Modifier.fillMaxWidth(),
colors = OutlinedTextFieldDefaults.colors(
focusedBorderColor = Color(0xFF7C3AED),
focusedLabelColor = Color(0xFF7C3AED)
)
)
}
},
@ -382,129 +626,18 @@ fun CreateNotebookDialog(
onConfirm(title, description)
}
},
enabled = title.isNotBlank()
enabled = title.isNotBlank(),
colors = ButtonDefaults.buttonColors(
containerColor = Color(0xFF7C3AED)
)
) {
Text("Buat")
}
},
dismissButton = {
TextButton(onClick = onDismiss) {
Text("Batal")
Text("Batal", color = MaterialTheme.colorScheme.onSurfaceVariant) // [DIUBAH]
}
}
)
}
// === CHAT & SOURCES SCREEN (Placeholder - akan diupdate nanti) ===
@Composable
fun ChatScreen(viewModel: NotebookViewModel) {
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
Text("Chat Screen - Coming Soon")
}
}
@Composable
fun SourcesScreen(viewModel: NotebookViewModel) {
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
Text("Sources Screen - Coming Soon")
}
}
// === MENU COMPONENTS (Tetap sama) ===
@Composable
fun AccountScreen(onDismiss: () -> Unit) {
Dialog(
onDismissRequest = onDismiss,
properties = DialogProperties(usePlatformDefaultWidth = false)
) {
Scaffold(
topBar = {
TopAppBar(
title = {
Column {
Text("202310715190@mhs.ubharajaya.ac.id", fontSize = 14.sp)
Text("Managed by mhs.ubharajay.ac.id", fontSize = 12.sp, color = Color.Gray)
}
},
actions = {
IconButton(onClick = onDismiss) {
Icon(Icons.Default.Close, contentDescription = "Close")
}
}
)
}
) { paddingValues ->
Column(
modifier = Modifier
.fillMaxSize()
.padding(paddingValues)
.padding(horizontal = 16.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Spacer(modifier = Modifier.height(48.dp))
Box {
Box(
modifier = Modifier
.size(80.dp)
.clip(CircleShape)
.background(Color.Magenta),
contentAlignment = Alignment.Center
) {
Text("M", color = Color.White, fontWeight = FontWeight.Bold, fontSize = 40.sp)
}
}
Spacer(modifier = Modifier.height(16.dp))
Text("Hi, 202310715190!", fontSize = 20.sp)
}
}
}
}
@Composable
fun SettingsMenu(
expanded: Boolean,
onDismiss: () -> Unit,
isDarkMode: Boolean,
onThemeChange: (Boolean) -> Unit
) {
DropdownMenu(expanded = expanded, onDismissRequest = onDismiss) {
// Dark Mode Toggle
DropdownMenuItem(
text = {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Row(verticalAlignment = Alignment.CenterVertically) {
Icon(
if (isDarkMode) Icons.Default.DarkMode else Icons.Default.LightMode,
contentDescription = null
)
Spacer(modifier = Modifier.width(12.dp))
Text(if (isDarkMode) "Mode Gelap" else "Mode Terang")
}
Switch(
checked = isDarkMode,
onCheckedChange = onThemeChange
)
}
},
onClick = { onThemeChange(!isDarkMode) }
)
Divider()
DropdownMenuItem(
text = { Text("NotebookLM Help") },
onClick = { },
leadingIcon = { Icon(Icons.Default.HelpOutline, contentDescription = null) }
)
}
}