Загрузка данных


package com.example.myapplication

import android.content.Context
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.*
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import java.text.SimpleDateFormat
import java.util.*
import androidx.core.content.edit

val Green = Color(0xFF4CAF50)
val Bg = Color(0xFFF2F2F2)

//////////////// MAIN //////////////////

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent { App() }
    }
}

//////////////// USER STORAGE //////////////////

object UserStorage {
    private const val PREFS = "prefs"
    private const val USER = "user"
    private const val PASS = "pass"

    fun save(context: Context, u: String, p: String) {
        context.getSharedPreferences(PREFS, Context.MODE_PRIVATE)
            .edit { putString(USER, u).putString(PASS, p) }
    }

    fun get(context: Context): Pair<String, String>? {
        val sp = context.getSharedPreferences(PREFS, Context.MODE_PRIVATE)
        val u = sp.getString(USER, null)
        val p = sp.getString(PASS, null)
        return if (u != null && p != null) Pair(u, p) else null
    }

    fun check(context: Context, u: String, p: String): Boolean {
        val saved = get(context)
        return saved?.first == u && saved.second == p
    }
}

//////////////// APP //////////////////

@Composable
fun App() {
    val ctx = LocalContext.current

    var isLogged by remember { mutableStateOf(UserStorage.get(ctx) != null) }
    var screen by remember { mutableStateOf("login") }

    var isDark by remember { mutableStateOf(false) }
    var lang by remember { mutableStateOf("ru") }

    MaterialTheme(
        colorScheme = if (isDark) darkColorScheme(
            primary = Green,
            background = Color(0xFF121212),
            surface = Color(0xFF1E1E1E),
            onBackground = Color.White,
            onSurface = Color.White
        ) else lightColorScheme(
            primary = Green,
            background = Bg,
            surface = Color.White,
            onBackground = Color.Black,
            onSurface = Color.Black
        )
    ) {

        when (screen) {

            "login" -> LoginScreen(
                lang = lang,
                onLogin = {
                    if (UserStorage.get(ctx) != null) {
                        isLogged = true
                        screen = "notes"
                    }
                },
                onGoRegister = { screen = "register" }
            )

            "register" -> RegisterScreen(
                lang = lang,
                onRegister = {
                    isLogged = true
                    screen = "notes"
                },
                onBack = { screen = "login" }
            )

            "notes" -> NotesScreen(
                lang = lang,
                onOpenSettings = { screen = "settings" }
            )

            "settings" -> SettingsScreen(
                lang = lang,
                dark = isDark,
                onBack = { screen = "notes" },
                onThemeChange = { isDark = it },
                onLangChange = { lang = it },
                onLogout = {
                    isLogged = false
                    screen = "login"
                }
            )
        }
    }
}

//////////////// LOGIN //////////////////

@Composable
fun LoginScreen(
    lang: String,
    onLogin: () -> Unit,
    onGoRegister: () -> Unit
) {
    val ctx = LocalContext.current
    var u by remember { mutableStateOf("") }
    var p by remember { mutableStateOf("") }
    var err by remember { mutableStateOf("") }

    Surface(
        modifier = Modifier.fillMaxSize(),
        color = MaterialTheme.colorScheme.background
    ) {
        Column(
            Modifier
                .fillMaxSize()
                .padding(24.dp),
            verticalArrangement = Arrangement.Center
        ) {

            Text(if (lang == "ru") "Вход" else "Login")

            OutlinedTextField(
                value = u,
                onValueChange = { u = it },
                label = { Text("Login") }
            )

            OutlinedTextField(
                value = p,
                onValueChange = { p = it },
                label = { Text("Password") }
            )

            if (err.isNotEmpty()) {
                Text(err, color = Color.Red)
            }

            Button(onClick = {
                if (UserStorage.check(ctx, u, p)) {
                    onLogin()
                } else {
                    err = if (lang == "ru") "Ошибка входа" else "Login error"
                }
            }) {
                Text(if (lang == "ru") "Войти" else "Sign in")
            }

            TextButton(onClick = onGoRegister) {
                Text(if (lang == "ru") "Регистрация" else "Sign up")
            }
        }
    }
}

//////////////// REGISTER //////////////////

@Composable
fun RegisterScreen(
    lang: String,
    onRegister: () -> Unit,
    onBack: () -> Unit
) {
    val ctx = LocalContext.current
    var u by remember { mutableStateOf("") }
    var p by remember { mutableStateOf("") }
    var p2 by remember { mutableStateOf("") }
    var err by remember { mutableStateOf("") }

    Surface(
        modifier = Modifier.fillMaxSize(),
        color = MaterialTheme.colorScheme.background
    ) {
        Column(
            Modifier.padding(16.dp)
        ) {}

            Text(if (lang == "ru") "Регистрация" else "Register")

            OutlinedTextField(u, { u = it }, label = { Text("Login") })
            OutlinedTextField(p, { p = it }, label = { Text("Password") })
            OutlinedTextField(p2, { p2 = it }, label = { Text("Repeat") })

            if (err.isNotEmpty()) Text(err, color = Color.Red)

            Button(onClick = {
                when {
                    u.isBlank() -> err = "Empty login"
                    p != p2 -> err = "Passwords mismatch"
                    else -> {
                        UserStorage.save(ctx, u, p)
                        onRegister()
                    }
                }
            }) {
                Text(if (lang == "ru") "Создать аккаунт" else "Create account")
            }

            TextButton(onClick = onBack) {
                Text(if (lang == "ru") "Назад" else "Back")
            }
        }
    }

//////////////// NOTES //////////////////

    data class Note(val title: String, val text: String, val date: String)

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun NotesScreen(lang: String, onOpenSettings: () -> Unit) {

    val ctx = LocalContext.current

    var notes by remember {
        mutableStateOf(NotesStorage.load(ctx))
    }

    var showAdd by remember { mutableStateOf(false) }
    var editIndex by remember { mutableStateOf<Int?>(null) }

    Scaffold(
        containerColor = MaterialTheme.colorScheme.background,
        topBar = {
            TopAppBar(
                title = { Text(if (lang == "ru") "Quick Notes" else "Quick Notes") },
                actions = {
                    IconButton(onClick = onOpenSettings) {
                        Icon(Icons.Default.Settings, null)
                    }
                }
            )
        },
        floatingActionButton = {
            FloatingActionButton(onClick = { showAdd = true }) {
                Icon(Icons.Default.Add, null)
            }
        }
    ) { padding ->

        LazyColumn(Modifier.padding(padding)) {
            itemsIndexed(notes) { index, note ->

                Card(
                    modifier = Modifier
                        .padding(8.dp)
                        .fillMaxWidth()
                        .clickable { editIndex = index },
                    shape = RoundedCornerShape(16.dp)
                ) {
                    Column(Modifier.padding(16.dp)) {

                        Text(note.title)
                        Text(note.text)

                        Spacer(Modifier.height(6.dp))

                        Text(
                            note.date,
                            color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f)
                        )

                        Spacer(Modifier.height(8.dp))

                        IconButton(onClick = {
                            notes = notes.toMutableList().also { it.removeAt(index) }
                            NotesStorage.save(ctx, notes)
                        }) {
                            Icon(Icons.Default.Delete, null)
                        }
                    }
                }
            }
        }
    }

    // ➕ ADD NOTE
    if (showAdd) {
        var title by remember { mutableStateOf("") }
        var text by remember { mutableStateOf("") }

        AlertDialog(
            onDismissRequest = { showAdd = false },
            confirmButton = {
                Button(onClick = {
                    val date = SimpleDateFormat(
                        "dd.MM.yyyy HH:mm",
                        Locale.getDefault()
                    ).format(Date())

                    notes = notes + Note(title, text, date)
                    NotesStorage.save(ctx, notes)

                    showAdd = false
                }) {
                    Text(if (lang == "ru") "Добавить" else "Add")
                }
            },
            dismissButton = {
                TextButton(onClick = { showAdd = false }) {
                    Text(if (lang == "ru") "Отмена" else "Cancel")
                }
            },
            title = {
                Text(if (lang == "ru") "Новая заметка" else "New note")
            },
            text = {
                Column {

                    OutlinedTextField(
                        value = title,
                        onValueChange = { title = it },
                        label = { Text(if (lang == "ru") "Заголовок" else "Title") }
                    )

                    Spacer(Modifier.height(8.dp))

                    OutlinedTextField(
                        value = text,
                        onValueChange = { text = it },
                        label = { Text(if (lang == "ru") "Текст" else "Text") }
                    )
                }
            }
        )
    }

    // ✏️ EDIT NOTE
    editIndex?.let { index ->

        var title by remember { mutableStateOf(notes[index].title) }
        var text by remember { mutableStateOf(notes[index].text) }

        AlertDialog(onDismissRequest = { editIndex = null },
            confirmButton = {
                Button(onClick = {
                    val updated = notes.toMutableList()
                    updated[index] = updated[index].copy(title = title, text = text)

                    notes = updated
                    NotesStorage.save(ctx, notes)

                    editIndex = null
                }) {
                    Text(if (lang == "ru") "Сохранить" else "Save")
                }
            },
            dismissButton = {
                TextButton(onClick = { editIndex = null }) {
                    Text(if (lang == "ru") "Отмена" else "Cancel")
                }
            },
            title = {
                Text(if (lang == "ru") "Редактирование" else "Edit")
            },
            text = {
                Column {

                    OutlinedTextField(
                        value = title,
                        onValueChange = { title = it },
                        label = { Text(if (lang == "ru") "Заголовок" else "Title") }
                    )

                    Spacer(Modifier.height(8.dp))

                    OutlinedTextField(
                        value = text,
                        onValueChange = { text = it },
                        label = { Text(if (lang == "ru") "Текст" else "Text") }
                    )
                }
            }
        )
    }
}

//////////////// SETTINGS //////////////////

@Composable
fun SettingsScreen(
    lang: String,
    dark: Boolean,
    onBack: () -> Unit,
    onThemeChange: (Boolean) -> Unit,
    onLangChange: (String) -> Unit,
    onLogout: () -> Unit
) {
    Surface(
        modifier = Modifier.fillMaxSize(),
        color = MaterialTheme.colorScheme.background
    ) {
        Column(Modifier.padding(16.dp)) {

            IconButton(onClick = onBack) {
                Icon(Icons.Default.ArrowBack, null)
            }

            Row(verticalAlignment = Alignment.CenterVertically) {
                Text(if (lang == "ru") "Тёмная тема" else "Dark theme")
                Spacer(Modifier.weight(1f))
                Switch(checked = dark, onCheckedChange = onThemeChange)
            }

            Spacer(Modifier.height(16.dp))

            Row {
                Text("RU", Modifier.clickable { onLangChange("ru") })
                Spacer(Modifier.width(16.dp))
                Text("EN", Modifier.clickable { onLangChange("en") })
            }

            Spacer(Modifier.height(20.dp))

            Button(
                onClick = onLogout,
                colors = ButtonDefaults.buttonColors(containerColor = Color.Red)
            ) {
                Text(if (lang == "ru") "Выйти" else "Logout")
            }
        }
    }
}

//////////////// PREVIEW //////////////////