From ca093260e2c5b654078e93c04e3ae089bfdedeca Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 1 May 2025 14:26:13 +0300 Subject: [PATCH] allWindows;dbDesktop --- composeApp/build.gradle.kts | 68 +++- .../example/project/ViewModel/IconPrinter.kt | 23 ++ .../project/ViewModel/UserRepository.kt | 69 ++++ .../src/androidMain/res/drawable/map.jpg | Bin 0 -> 45634 bytes .../composeResources/drawable/map.jpg | Bin 0 -> 45634 bytes .../kotlin/org/example/project/Models/Fond.kt | 9 + .../kotlin/org/example/project/Models/User.kt | 17 + .../example/project/ViewModel/IconPrinter.kt | 7 + .../example/project/ViewModel/InfoButton.kt | 33 ++ .../project/ViewModel/RegRunnerViewModel.kt | 18 + .../project/ViewModel/UserRepository.kt | 14 + .../project/ViewModel/UserViewModel.kt | 36 ++ .../project/ui/Screens/AboutMarathon.kt | 353 ++++++++++++++++++ .../project/ui/Screens/ConfirmRunner.kt | 4 +- .../example/project/ui/Screens/ForRunner.kt | 9 +- .../example/project/ui/Screens/ForSponsor.kt | 49 ++- .../example/project/ui/Screens/InfoRunner.kt | 30 +- .../org/example/project/ui/Screens/Login.kt | 14 +- .../example/project/ui/Screens/MainScreen.kt | 25 -- .../example/project/ui/Screens/MoreInfo.kt | 30 +- .../example/project/ui/Screens/RegMaraphon.kt | 36 +- .../example/project/ui/Screens/RegRunner.kt | 151 +++++--- .../kotlin/org/example/project/Server.kt | 40 ++ .../org/example/project/Tables/Connect.kt | 17 + .../org/example/project/Tables/Fonds.kt | 13 + .../org/example/project/Tables/Users.kt | 18 + .../example/project/ViewModel/IconPrinter.kt | 34 ++ .../project/ViewModel/UserRepository.kt | 128 +++++++ 28 files changed, 1084 insertions(+), 161 deletions(-) create mode 100644 composeApp/src/androidMain/kotlin/org/example/project/ViewModel/IconPrinter.kt create mode 100644 composeApp/src/androidMain/kotlin/org/example/project/ViewModel/UserRepository.kt create mode 100644 composeApp/src/androidMain/res/drawable/map.jpg create mode 100644 composeApp/src/commonMain/composeResources/drawable/map.jpg create mode 100644 composeApp/src/commonMain/kotlin/org/example/project/Models/Fond.kt create mode 100644 composeApp/src/commonMain/kotlin/org/example/project/Models/User.kt create mode 100644 composeApp/src/commonMain/kotlin/org/example/project/ViewModel/IconPrinter.kt create mode 100644 composeApp/src/commonMain/kotlin/org/example/project/ViewModel/InfoButton.kt create mode 100644 composeApp/src/commonMain/kotlin/org/example/project/ViewModel/RegRunnerViewModel.kt create mode 100644 composeApp/src/commonMain/kotlin/org/example/project/ViewModel/UserRepository.kt create mode 100644 composeApp/src/commonMain/kotlin/org/example/project/ViewModel/UserViewModel.kt create mode 100644 composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/AboutMarathon.kt create mode 100644 composeApp/src/desktopMain/kotlin/org/example/project/Server.kt create mode 100644 composeApp/src/desktopMain/kotlin/org/example/project/Tables/Connect.kt create mode 100644 composeApp/src/desktopMain/kotlin/org/example/project/Tables/Fonds.kt create mode 100644 composeApp/src/desktopMain/kotlin/org/example/project/Tables/Users.kt create mode 100644 composeApp/src/desktopMain/kotlin/org/example/project/ViewModel/IconPrinter.kt create mode 100644 composeApp/src/desktopMain/kotlin/org/example/project/ViewModel/UserRepository.kt diff --git a/composeApp/build.gradle.kts b/composeApp/build.gradle.kts index cc9f46b..a659271 100644 --- a/composeApp/build.gradle.kts +++ b/composeApp/build.gradle.kts @@ -18,9 +18,38 @@ kotlin { } jvm("desktop") - + sourceSets { - val desktopMain by getting + val exposedVersion = "0.61.0" + + val desktopMain by getting { + dependencies { + implementation(compose.desktop.currentOs) + implementation(libs.kotlinx.coroutines.swing) + implementation("io.ktor:ktor-client-okhttp:2.3.2") + + // Exposed + PostgreSQL +// implementation("org.jetbrains.exposed:exposed-core:$exposedVersion") +// implementation("org.jetbrains.exposed:exposed-dao:$exposedVersion") +// implementation("org.jetbrains.exposed:exposed-jdbc:$exposedVersion") + implementation("org.postgresql:postgresql:42.7.1") + + implementation("org.jetbrains.exposed:exposed-core:$exposedVersion") + implementation("org.jetbrains.exposed:exposed-crypt:$exposedVersion") + implementation("org.jetbrains.exposed:exposed-dao:$exposedVersion") + implementation("org.jetbrains.exposed:exposed-jdbc:$exposedVersion") + + implementation("org.jetbrains.exposed:exposed-jodatime:$exposedVersion") + // or + implementation("org.jetbrains.exposed:exposed-java-time:$exposedVersion") + // or + implementation("org.jetbrains.exposed:exposed-kotlin-datetime:$exposedVersion") + + implementation("org.jetbrains.exposed:exposed-json:$exposedVersion") + implementation("org.jetbrains.exposed:exposed-money:$exposedVersion") + implementation("org.jetbrains.exposed:exposed-spring-boot-starter:$exposedVersion") + } + } val commonMain by getting { resources.srcDir("src/commonMain/composeResources") @@ -31,6 +60,23 @@ kotlin { implementation(libs.androidx.activity.compose) implementation(libs.androidx.lifecycle.viewmodel) implementation("io.ktor:ktor-client-okhttp:2.3.2") + + implementation("org.postgresql:postgresql:42.7.1") + + implementation("org.jetbrains.exposed:exposed-core:$exposedVersion") + implementation("org.jetbrains.exposed:exposed-crypt:$exposedVersion") + implementation("org.jetbrains.exposed:exposed-dao:$exposedVersion") + implementation("org.jetbrains.exposed:exposed-jdbc:$exposedVersion") + + implementation("org.jetbrains.exposed:exposed-jodatime:$exposedVersion") + // or + implementation("org.jetbrains.exposed:exposed-java-time:$exposedVersion") + // or + implementation("org.jetbrains.exposed:exposed-kotlin-datetime:$exposedVersion") + + implementation("org.jetbrains.exposed:exposed-json:$exposedVersion") + implementation("org.jetbrains.exposed:exposed-money:$exposedVersion") + implementation("org.jetbrains.exposed:exposed-spring-boot-starter:$exposedVersion") } commonMain.dependencies { val voyagerVersion = "1.1.0-beta02" @@ -49,17 +95,22 @@ kotlin { implementation("io.ktor:ktor-client-core:2.3.2") implementation("io.ktor:ktor-client-cio:2.3.2") implementation("io.ktor:ktor-client-okhttp:2.3.2") + implementation ("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.2") repositories { google() mavenCentral() } } - desktopMain.dependencies { - implementation(compose.desktop.currentOs) - implementation(libs.kotlinx.coroutines.swing) - implementation("io.ktor:ktor-client-okhttp:2.3.2") - } +// desktopMain.dependencies { +// implementation(compose.desktop.currentOs) +// implementation(libs.kotlinx.coroutines.swing) +// implementation("io.ktor:ktor-client-okhttp:2.3.2") +// implementation("org.jetbrains.exposed:exposed-core:$exposedVersion") +// implementation("org.jetbrains.exposed:exposed-dao:$exposedVersion") +// implementation("org.jetbrains.exposed:exposed-jdbc:$exposedVersion") +// implementation("org.postgresql:postgresql:42.7.3") +// } } } @@ -89,6 +140,9 @@ android { targetCompatibility = JavaVersion.VERSION_11 } } +dependencies { + implementation(project(":composeApp")) +} compose.desktop { application { diff --git a/composeApp/src/androidMain/kotlin/org/example/project/ViewModel/IconPrinter.kt b/composeApp/src/androidMain/kotlin/org/example/project/ViewModel/IconPrinter.kt new file mode 100644 index 0000000..6714df7 --- /dev/null +++ b/composeApp/src/androidMain/kotlin/org/example/project/ViewModel/IconPrinter.kt @@ -0,0 +1,23 @@ +package org.example.project.ViewModel + +import androidx.compose.foundation.Image +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.painterResource +import org.example.project.R + +@Composable +actual fun IconPrinter(resourceName: String, modifier: Modifier) { + val resId = when (resourceName) { + "calendar" -> R.drawable.map + else -> return // fallback + } + + Image( + painter = painterResource(id = resId), + contentDescription = null, + modifier = modifier, + contentScale = ContentScale.FillBounds + ) +} \ No newline at end of file diff --git a/composeApp/src/androidMain/kotlin/org/example/project/ViewModel/UserRepository.kt b/composeApp/src/androidMain/kotlin/org/example/project/ViewModel/UserRepository.kt new file mode 100644 index 0000000..fee7d8a --- /dev/null +++ b/composeApp/src/androidMain/kotlin/org/example/project/ViewModel/UserRepository.kt @@ -0,0 +1,69 @@ +package org.example.project.ViewModel + +import android.os.Build +import androidx.annotation.RequiresApi +import org.example.project.Models.Fond +import org.example.project.Models.User +import java.time.LocalDate + +actual class UserRepository { + @RequiresApi(Build.VERSION_CODES.O) + actual fun fetchUsers(): List { + var users = listOf( + User( + id = 1, + email = "email1@gmail.com", + password = "qwerty", + name = "bob", + surname = "bobby", + gender = "Мужской", + photopath = "/Users/rinchi/Desktop/vpn4ik.jpg", + LocalDate.of(2006, 1, 16), + country = "Russia", + active = false + ), + User( + id = 2, + email = "email2@gmail.com", + password = "qwerty", + name = "bob", + surname = "bobby", + gender = "Мужской", + photopath = "/Users/rinchi/Desktop/vpn4ik.jpg", + LocalDate.of(2006, 1, 16), + country = "Russia", + active = false + ), ) + return users + } + actual fun regUser(user: User): Boolean { + return true + } + actual fun fetchFonds(): List { + var fonds = listOf( + Fond( + id = 1, + name = "first", + balance = 1000 + ), + Fond( + id = 2, + name = "second", + balance = 2000 + ), + ) + return fonds + } + actual fun withdrawalBalance(idFond: Int, dedSum: Int): Boolean { + return true + } + actual fun getUserIdByEmail(email: String): Int { + return 0 + } + actual fun updateUserActive(idUser: Int): Boolean{ + return true + } + actual fun topUpBalance(idFond: Int, sum: Int): Boolean{ + return true + } +} \ No newline at end of file diff --git a/composeApp/src/androidMain/res/drawable/map.jpg b/composeApp/src/androidMain/res/drawable/map.jpg new file mode 100644 index 0000000000000000000000000000000000000000..dc4ae8057b20cf1456db3acd309a8fafd7ca6c0b GIT binary patch literal 45634 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 Unit) { + Button( + onClick = onClick, + modifier = Modifier + .fillMaxWidth() + .height(80.dp), + colors = ButtonDefaults.buttonColors( + backgroundColor = Color.LightGray, + contentColor = Color.Black + ), + shape = RoundedCornerShape(15.dp), + ) { + Text(text = text, fontStyle = FontStyle.Italic, fontSize = fontSize, textAlign = TextAlign.Center) + } +} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/org/example/project/ViewModel/RegRunnerViewModel.kt b/composeApp/src/commonMain/kotlin/org/example/project/ViewModel/RegRunnerViewModel.kt new file mode 100644 index 0000000..80de433 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/org/example/project/ViewModel/RegRunnerViewModel.kt @@ -0,0 +1,18 @@ +package org.example.project.ViewModel + +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import androidx.lifecycle.ViewModel + +class RegRunnerViewModel : ViewModel() { + var email by mutableStateOf("") + var password by mutableStateOf("") + var secondPassword by mutableStateOf("") + var name by mutableStateOf("") + var surname by mutableStateOf("") + var gender by mutableStateOf("") + var country by mutableStateOf("") + var photoPath by mutableStateOf("") + var dateBirthday by mutableStateOf("") +} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/org/example/project/ViewModel/UserRepository.kt b/composeApp/src/commonMain/kotlin/org/example/project/ViewModel/UserRepository.kt new file mode 100644 index 0000000..396d726 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/org/example/project/ViewModel/UserRepository.kt @@ -0,0 +1,14 @@ +package org.example.project.ViewModel + +import org.example.project.Models.Fond +import org.example.project.Models.User + +expect class UserRepository() { + fun fetchUsers(): List + fun regUser(user: User): Boolean + fun fetchFonds(): List + fun withdrawalBalance(idFond: Int, dedSum: Int): Boolean + fun getUserIdByEmail(email: String): Int + fun updateUserActive(idUser: Int): Boolean + fun topUpBalance(idFond: Int, sum: Int): Boolean +} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/org/example/project/ViewModel/UserViewModel.kt b/composeApp/src/commonMain/kotlin/org/example/project/ViewModel/UserViewModel.kt new file mode 100644 index 0000000..3719460 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/org/example/project/ViewModel/UserViewModel.kt @@ -0,0 +1,36 @@ +package org.example.project.ViewModel + +import org.example.project.Models.Fond +import org.example.project.Models.User + +class UserViewModel { + private val userRepository = UserRepository() + + fun getUsers(): List { + return userRepository.fetchUsers() + } + + fun regUser(user: User): Boolean { + return userRepository.regUser(user) + } + + fun getFond(): List{ + return userRepository.fetchFonds() + } + + fun withdrawalBalance(idFond: Int, dedSum: Int): Boolean{ + return userRepository.withdrawalBalance(idFond, dedSum) + } + + fun getUserIdByEmail(email: String): Int{ + return userRepository.getUserIdByEmail(email) + } + + fun updateUserActive(idUser: Int): Boolean{ + return userRepository.updateUserActive(idUser) + } + + fun topUpBalance(idFond: Int, sum: Int): Boolean{ + return userRepository.topUpBalance(idFond, sum) + } +} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/AboutMarathon.kt b/composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/AboutMarathon.kt new file mode 100644 index 0000000..bcd5de3 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/AboutMarathon.kt @@ -0,0 +1,353 @@ +package org.example.project.ui.Screens + +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.BoxWithConstraints +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.aspectRatio +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.layout.wrapContentWidth +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.Button +import androidx.compose.material.ButtonDefaults +import androidx.compose.material.Icon +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Scaffold +import androidx.compose.material.Text +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.DateRange +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import cafe.adriel.voyager.core.screen.Screen +import cafe.adriel.voyager.navigator.LocalNavigator +import cafe.adriel.voyager.navigator.currentOrThrow +import org.example.project.ViewModel.IconPrinter +import org.example.project.ViewModel.TimerViewModel + + +class AboutMarathonScreen(private val timerViewModel: TimerViewModel) : Screen { + + @Composable + override fun Content() { + val navigator = LocalNavigator.currentOrThrow + + Scaffold( + topBar = { AboutMarathonTopBar() }, + bottomBar = { AboutMarathonBottomBar(timerViewModel = timerViewModel) } + ) { paddingValues -> + + Box( + modifier = Modifier + .padding(paddingValues) + ) { + BoxWithConstraints( + modifier = Modifier + .fillMaxWidth() + .align(Alignment.Center) + .padding(horizontal = 20.dp) + ) { + val fontSize = (maxWidth.value / 25).sp + val fontSizeSecond = (maxWidth.value / 35).sp + + Column( + modifier = Modifier + .padding(16.dp) + .fillMaxSize(), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.SpaceBetween + ) { + Spacer(modifier = Modifier.weight(0.1f)) + + Text( + text = "Информация о Marathon Skills 2016", + color = Color.Black, + textAlign = TextAlign.Center, + fontSize = fontSize, + ) + + Spacer(modifier = Modifier.weight(0.1f)) + + Row( + modifier = Modifier + .fillMaxWidth() + .weight(1f), + horizontalArrangement = Arrangement.SpaceEvenly, + verticalAlignment = Alignment.CenterVertically + ) { + Column( + modifier = Modifier + .weight(0.6f) + .padding(end = 8.dp), + verticalArrangement = Arrangement.spacedBy(16.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Box( + modifier = Modifier +// .weight(3f) + .aspectRatio(3f) + .fillMaxWidth() + .border(width = 2.dp, color = Color.Black, shape = RoundedCornerShape(15.dp)) + .clip(RoundedCornerShape(15.dp)) + .background(Color.LightGray) + .clickable { }, + contentAlignment = Alignment.Center + ) { + IconPrinter( + resourceName = "map", + modifier = Modifier.fillMaxSize() + ) + } + +// Spacer(modifier = Modifier.weight(0.05f)) + + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(16.dp), + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp, vertical = 8.dp) + ) { + Box( + modifier = Modifier + .weight(1f) + .aspectRatio(1.7f) + .border(2.dp, Color.Black, RoundedCornerShape(15.dp)) + .clip(RoundedCornerShape(15.dp)) + .background(Color.LightGray) + .clickable { }, + contentAlignment = Alignment.Center + ) { + IconPrinter( + resourceName = "map", + modifier = Modifier.fillMaxSize() + ) + } + + Box( + modifier = Modifier + .weight(1f) + .aspectRatio(1.7f) + .border(2.dp, Color.Black, RoundedCornerShape(15.dp)) + .clip(RoundedCornerShape(15.dp)) + .background(Color.LightGray) + .clickable { }, + contentAlignment = Alignment.Center + ) { + IconPrinter( + resourceName = "map", + modifier = Modifier.fillMaxSize() + ) + } + } + +// Spacer(modifier = Modifier.weight(0.05f)) + + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(16.dp), + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp, vertical = 8.dp) + ) { + Box( + modifier = Modifier + .weight(1f) + .aspectRatio(1.7f) + .border(2.dp, Color.Black, RoundedCornerShape(15.dp)) + .clip(RoundedCornerShape(15.dp)) + .background(Color.LightGray) + .clickable { }, + contentAlignment = Alignment.Center + ) { + IconPrinter( + resourceName = "map", + modifier = Modifier.fillMaxSize() + ) + } + + Box( + modifier = Modifier + .weight(1f) + .aspectRatio(1.7f) + .border(2.dp, Color.Black, RoundedCornerShape(15.dp)) + .clip(RoundedCornerShape(15.dp)) + .background(Color.LightGray) + .clickable { }, + contentAlignment = Alignment.Center + ) { + IconPrinter( + resourceName = "map", + modifier = Modifier.fillMaxSize() + ) + } + } + +// Spacer(modifier = Modifier.weight(0.1f)) + } + + Column( + modifier = Modifier + .weight(1f) + .padding(start = 8.dp), + verticalArrangement = Arrangement.spacedBy(16.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Text( + text = "Информация о Marathon Skills 2016", + color = Color.Black, + textAlign = TextAlign.Center, + fontSize = fontSizeSecond, + modifier = Modifier.weight(1f) + ) + + Spacer(modifier = Modifier.weight(0.3f)) + + Text( + text = "Информация о Marathon Skills 2016", + color = Color.Black, + textAlign = TextAlign.Center, + fontSize = fontSizeSecond, + modifier = Modifier.weight(1f) + ) + + Spacer(modifier = Modifier.weight(0.3f)) + + Text( + text = "Информация о Marathon Skills 2016", + color = Color.Black, + textAlign = TextAlign.Center, + fontSize = fontSizeSecond, + modifier = Modifier.weight(1f) + ) + + Spacer(modifier = Modifier.weight(0.3f)) + } + } + } + } + } + } + } + + @Composable + private fun AboutMarathonTopBar() { + val navigator = LocalNavigator.currentOrThrow + + Box { + BoxWithConstraints( + modifier = Modifier + .fillMaxWidth() + .align(Alignment.Center) + ) { + val fontSizeButton = (maxWidth.value / 50).sp + val fontSizeText = (maxWidth.value / 25).sp + + Row( + modifier = Modifier + .fillMaxWidth() + .background(Color.DarkGray) + .padding(16.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween + ) { + + Button( + onClick = { navigator.push(MainScreen()) }, + colors = ButtonDefaults.buttonColors( + backgroundColor = Color.LightGray, + contentColor = Color.Black + ), + elevation = null, + shape = RoundedCornerShape(15.dp), + modifier = Modifier + .wrapContentWidth() + + ) { + Text( + text = "Назад", + color = Color.Black, + fontSize = fontSizeButton + ) + } + + Spacer(modifier = Modifier.width(24.dp)) + + Text( + text = "MARATHON SKILLS 2016", + style = MaterialTheme.typography.h6, + modifier = Modifier.weight(1f), + textAlign = TextAlign.Left, + fontWeight = FontWeight.Bold, + fontSize = fontSizeText, + color = Color.White + ) + + Spacer(modifier = Modifier.width(64.dp)) + + Button( + onClick = { navigator.push(MainScreen()) }, + colors = ButtonDefaults.buttonColors( + backgroundColor = Color.LightGray, + contentColor = Color.Black + ), + elevation = null, + shape = RoundedCornerShape(15.dp), + modifier = Modifier + .wrapContentWidth() + + ) { + Text( + text = "Logout", + color = Color.Black, + fontSize = fontSizeButton + ) + } + } + } + } + } + + @Composable + private fun AboutMarathonBottomBar(timerViewModel: TimerViewModel) { + val remainingTime = timerViewModel.remainingTime.collectAsState().value + Box { + BoxWithConstraints( + modifier = Modifier + .align(Alignment.Center) + ) { + val fontSize = (maxWidth.value / 50).sp + + Column( + modifier = Modifier + .fillMaxWidth() + .background(Color.DarkGray) + .padding(8.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Text( + text = remainingTime, + color = Color.White, + fontSize = fontSize + ) + } + } + } + } +} diff --git a/composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/ConfirmRunner.kt b/composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/ConfirmRunner.kt index a51a8df..9fae2ea 100644 --- a/composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/ConfirmRunner.kt +++ b/composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/ConfirmRunner.kt @@ -33,7 +33,7 @@ import cafe.adriel.voyager.navigator.LocalNavigator import cafe.adriel.voyager.navigator.currentOrThrow import org.example.project.ViewModel.TimerViewModel -class ConfirmRunnerScreen(private val timerViewModel: TimerViewModel) : +class ConfirmRunnerScreen(private val timerViewModel: TimerViewModel, private val idRunner: Int) : Screen { @Composable @@ -89,7 +89,7 @@ class ConfirmRunnerScreen(private val timerViewModel: TimerViewModel) : Spacer(modifier = Modifier.weight(0.2f)) Button( - onClick = { navigator.push(InfoRunnerScreen(timerViewModel)) }, + onClick = { navigator.push(InfoRunnerScreen(timerViewModel, idRunner)) }, modifier = Modifier .fillMaxWidth() .height(48.dp), diff --git a/composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/ForRunner.kt b/composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/ForRunner.kt index ae77492..86e0988 100644 --- a/composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/ForRunner.kt +++ b/composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/ForRunner.kt @@ -28,6 +28,9 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.viewmodel.compose.viewModel +import org.example.project.ViewModel.RegRunnerViewModel import org.example.project.ViewModel.TimerViewModel class RunnerScreen(private val timerViewModel: TimerViewModel) : Screen { @@ -80,7 +83,11 @@ class RunnerScreen(private val timerViewModel: TimerViewModel) : Screen { Spacer(modifier = Modifier.weight(0.25f)) Button( - onClick = { navigator.push(RegRunnerScreen(timerViewModel)) }, +// onClick = { navigator.push(RegRunnerScreen(timerViewModel)) }, + onClick = { + val regRunnerViewModel = RegRunnerViewModel() + navigator.push(RegRunnerScreen(timerViewModel)) + }, modifier = Modifier .fillMaxWidth() .weight(1f), diff --git a/composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/ForSponsor.kt b/composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/ForSponsor.kt index f9ab453..1f08982 100644 --- a/composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/ForSponsor.kt +++ b/composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/ForSponsor.kt @@ -1,6 +1,7 @@ package org.example.project.ui.Screens import androidx.compose.foundation.background +import androidx.compose.foundation.border import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -17,12 +18,15 @@ import androidx.compose.foundation.layout.wrapContentWidth import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.Button import androidx.compose.material.ButtonDefaults +import androidx.compose.material.DropdownMenu +import androidx.compose.material.DropdownMenuItem import androidx.compose.material.Icon import androidx.compose.material.MaterialTheme import androidx.compose.material.OutlinedTextField import androidx.compose.material.Scaffold import androidx.compose.material.Text import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ArrowDropDown import androidx.compose.material.icons.filled.DateRange import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState @@ -44,12 +48,16 @@ import cafe.adriel.voyager.navigator.currentOrThrow import org.example.project.ViewModel.FieldWithDropdown import org.example.project.ViewModel.FieldWithLabel import org.example.project.ViewModel.TimerViewModel +import org.example.project.ViewModel.UserViewModel class ForSponsorScreen(private val timerViewModel: TimerViewModel) : Screen { @Composable override fun Content() { val navigator = LocalNavigator.currentOrThrow + val viewModel = UserViewModel() + val fonds = viewModel.getFond() + val runners = viewModel.getUsers() Scaffold( topBar = { ForSponsorTopBar() }, @@ -71,12 +79,10 @@ class ForSponsorScreen(private val timerViewModel: TimerViewModel) : Screen { val fontSizeThird = (maxWidth.value / 50).sp val fontSizeFourth = (maxWidth.value / 10).sp val labelWidth = 0.5f + var fondsNames = fonds.map { it.name } + var runnersNames = runners.map { it.name } + var selectedFondName by remember { mutableStateOf("") } var fio by remember { mutableStateOf("") } - val runners = listOf( - "bob", - "bobby", - "baby" - ) var runner by remember { mutableStateOf("") } var cardName by remember { mutableStateOf("") } var cardNum by remember { mutableStateOf("") } @@ -86,6 +92,7 @@ class ForSponsorScreen(private val timerViewModel: TimerViewModel) : Screen { var sumChangStr by remember { mutableStateOf("10")} var sumChang by remember { mutableStateOf(sumChangStr.toInt()) } var sumSpons by remember { mutableStateOf(0)} + var expanded by remember { mutableStateOf(false) } Column( modifier = Modifier @@ -144,7 +151,7 @@ class ForSponsorScreen(private val timerViewModel: TimerViewModel) : Screen { FieldWithDropdown( label = "Бегун:", - options = runners, + options = runnersNames, selectedOption = runner, onOptionSelected = { runner = it }, fontSize = fontSizeSecond, @@ -242,15 +249,14 @@ class ForSponsorScreen(private val timerViewModel: TimerViewModel) : Screen { Spacer(modifier = Modifier.weight(0.1f)) - Box(modifier = Modifier.fillMaxWidth()) { - Text( - text = "blagot...", - color = Color.Black, - textAlign = TextAlign.Center, - fontSize = fontSizeSecond, - modifier = Modifier.align(Alignment.Center) - ) - } + FieldWithDropdown( + label = "", + options = fondsNames, + selectedOption = selectedFondName, + onOptionSelected = { selectedFondName = it }, + fontSize = fontSizeSecond, + labelWidth = 0.5f + ) Spacer(modifier = Modifier.weight(0.5f)) @@ -343,7 +349,16 @@ class ForSponsorScreen(private val timerViewModel: TimerViewModel) : Screen { .padding(horizontal = 16.dp, vertical = 8.dp) ) { Button( - onClick = { navigator.push(ConfirmSponsorScreen(timerViewModel, sumSpons.toString(), runner, "blagodat..."))}, +// onClick = { navigator.push(ConfirmSponsorScreen(timerViewModel, sumSpons.toString(), runner, "blagodat..."))}, + onClick = { + val selectedFond = fonds.find { it.name == selectedFondName } + if (selectedFond != null) { + val result = viewModel.topUpBalance(selectedFond.id, sumSpons) + if (result){ + navigator.push(ConfirmSponsorScreen(timerViewModel, sumSpons.toString(), runner, selectedFondName)) + } + } + }, modifier = Modifier.weight(1f), colors = ButtonDefaults.buttonColors( backgroundColor = Color.LightGray, @@ -399,7 +414,7 @@ class ForSponsorScreen(private val timerViewModel: TimerViewModel) : Screen { ) { Button( - onClick = { }, + onClick = { navigator.push(MainScreen()) }, colors = ButtonDefaults.buttonColors( backgroundColor = Color.LightGray, contentColor = Color.Black diff --git a/composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/InfoRunner.kt b/composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/InfoRunner.kt index 92aa58a..2ad40cd 100644 --- a/composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/InfoRunner.kt +++ b/composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/InfoRunner.kt @@ -33,10 +33,11 @@ import androidx.compose.ui.unit.sp import cafe.adriel.voyager.core.screen.Screen import cafe.adriel.voyager.navigator.LocalNavigator import cafe.adriel.voyager.navigator.currentOrThrow +import org.example.project.ViewModel.InfoButton import org.example.project.ViewModel.TimerViewModel -class InfoRunnerScreen(private val timerViewModel: TimerViewModel) : Screen { +class InfoRunnerScreen(private val timerViewModel: TimerViewModel, private val idRunner: Int) : Screen { @Composable override fun Content() { @@ -88,9 +89,9 @@ class InfoRunnerScreen(private val timerViewModel: TimerViewModel) : Screen { verticalArrangement = Arrangement.spacedBy(16.dp), horizontalAlignment = Alignment.CenterHorizontally ) { - InfoButton("Регистрация на марафон", fontSizeButton) - InfoButton("Редактирование профиля", fontSizeButton) - InfoButton("Контакты", fontSizeButton) + InfoButton("Регистрация на марафон", fontSizeButton, {navigator.push(RegMaraphonScreen(timerViewModel, idRunner))}) + InfoButton("Редактирование профиля", fontSizeButton, {}) + InfoButton("Контакты", fontSizeButton, {}) } Column( @@ -100,8 +101,8 @@ class InfoRunnerScreen(private val timerViewModel: TimerViewModel) : Screen { verticalArrangement = Arrangement.spacedBy(16.dp), horizontalAlignment = Alignment.CenterHorizontally ) { - InfoButton("Мои результаты", fontSizeButton) - InfoButton("Мои спонсоры", fontSizeButton) + InfoButton("Мои результаты", fontSizeButton, {}) + InfoButton("Мои спонсоры", fontSizeButton, {}) } } } @@ -110,23 +111,6 @@ class InfoRunnerScreen(private val timerViewModel: TimerViewModel) : Screen { } } - @Composable - private fun InfoButton(text: String, fontSize: TextUnit) { - Button( - onClick = { }, - modifier = Modifier - .fillMaxWidth() - .height(80.dp), - colors = ButtonDefaults.buttonColors( - backgroundColor = Color.LightGray, - contentColor = Color.Black - ), - shape = RoundedCornerShape(15.dp) - ) { - Text(text = text, fontStyle = FontStyle.Italic, fontSize = fontSize, textAlign = TextAlign.Center) - } - } - @Composable private fun InfoRunnerTopBar() { val navigator = LocalNavigator.currentOrThrow diff --git a/composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/Login.kt b/composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/Login.kt index 4c78cb1..23ead60 100644 --- a/composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/Login.kt +++ b/composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/Login.kt @@ -35,11 +35,13 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.min import androidx.compose.ui.unit.sp +import androidx.lifecycle.ViewModel import cafe.adriel.voyager.core.screen.Screen import cafe.adriel.voyager.navigator.LocalNavigator import cafe.adriel.voyager.navigator.currentOrThrow import org.example.project.ViewModel.FieldWithLabel import org.example.project.ViewModel.TimerViewModel +import org.example.project.ViewModel.UserViewModel class LoginScreen(private val timerViewModel: TimerViewModel) : Screen { @@ -52,6 +54,9 @@ class LoginScreen(private val timerViewModel: TimerViewModel) : Screen { bottomBar = { LoginBottomBar(timerViewModel = timerViewModel) } ) { paddingValues -> + val viewModel = UserViewModel() + val users = viewModel.getUsers() + Box( modifier = Modifier.padding(paddingValues) ) { @@ -122,7 +127,14 @@ class LoginScreen(private val timerViewModel: TimerViewModel) : Screen { horizontalArrangement = Arrangement.Center ) { Button( - onClick = { navigator.push(InfoRunnerScreen(timerViewModel))}, +// onClick = { navigator.push(InfoRunnerScreen(timerViewModel))}, + onClick = { + val user = users.find { it.email == email } + if (user != null && user.password == password) { + val userId = viewModel.getUserIdByEmail(user.email) + navigator.push(InfoRunnerScreen(timerViewModel, userId)) + } + }, modifier = Modifier .fillMaxWidth() .weight(1f), diff --git a/composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/MainScreen.kt b/composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/MainScreen.kt index 27db258..92b8d1f 100644 --- a/composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/MainScreen.kt +++ b/composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/MainScreen.kt @@ -98,31 +98,6 @@ class MainScreen : Screen { } } -// BoxWithConstraints( -// modifier = Modifier -// .align(Alignment.BottomEnd) -// .padding(end = 16.dp, bottom = 20.dp) -// ) { -// val buttonWidth = (maxWidth.value / 6).dp -// val buttonHeight = (buttonWidth.value / 3).dp -// val fontSize = (maxWidth.value / 50).sp -// -// Button( -// onClick = { }, -// modifier = Modifier -// .width(buttonWidth) -// .height(buttonHeight), -// colors = ButtonDefaults.buttonColors( -// backgroundColor = Color.LightGray, -// contentColor = Color.Black -// ), -// shape = RoundedCornerShape(15.dp) -// ) { -// Text("Login", fontSize = fontSize) -// } -// } - - //доделать кнопку login Button( onClick = { navigator.push(LoginScreen(timerViewModel)) }, modifier = Modifier diff --git a/composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/MoreInfo.kt b/composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/MoreInfo.kt index b87093b..8855cad 100644 --- a/composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/MoreInfo.kt +++ b/composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/MoreInfo.kt @@ -33,6 +33,7 @@ import androidx.compose.ui.unit.sp import cafe.adriel.voyager.core.screen.Screen import cafe.adriel.voyager.navigator.LocalNavigator import cafe.adriel.voyager.navigator.currentOrThrow +import org.example.project.ViewModel.InfoButton import org.example.project.ViewModel.TimerViewModel @@ -88,9 +89,9 @@ class MoreInfoScreen(private val timerViewModel: TimerViewModel) : Screen { verticalArrangement = Arrangement.spacedBy(16.dp), horizontalAlignment = Alignment.CenterHorizontally ) { - InfoButton("Marathon Skills 2016", fontSizeButton) - InfoButton("Предыдущие результаты", fontSizeButton) - InfoButton("BMI калькулятор", fontSizeButton) + InfoButton("Marathon Skills 2016", fontSizeButton, {navigator.push(AboutMarathonScreen(timerViewModel))}) + InfoButton("Предыдущие результаты", fontSizeButton, {}) + InfoButton("BMI калькулятор", fontSizeButton, {}) } Column( @@ -100,9 +101,9 @@ class MoreInfoScreen(private val timerViewModel: TimerViewModel) : Screen { verticalArrangement = Arrangement.spacedBy(16.dp), horizontalAlignment = Alignment.CenterHorizontally ) { - InfoButton("Насколько долгий марафон", fontSizeButton) - InfoButton("Список\nблаготворительных организаций", fontSizeButton) - InfoButton("BMR калькулятор", fontSizeButton) + InfoButton("Насколько долгий марафон", fontSizeButton, {}) + InfoButton("Список\nблаготворительных организаций", fontSizeButton, {}) + InfoButton("BMR калькулятор", fontSizeButton, {}) } } } @@ -111,23 +112,6 @@ class MoreInfoScreen(private val timerViewModel: TimerViewModel) : Screen { } } - @Composable - private fun InfoButton(text: String, fontSize: TextUnit) { - Button( - onClick = { }, - modifier = Modifier - .fillMaxWidth() - .height(80.dp), - colors = ButtonDefaults.buttonColors( - backgroundColor = Color.LightGray, - contentColor = Color.Black - ), - shape = RoundedCornerShape(15.dp) - ) { - Text(text = text, fontStyle = FontStyle.Italic, fontSize = fontSize, textAlign = TextAlign.Center) - } - } - @Composable private fun InfoTopBar() { val navigator = LocalNavigator.currentOrThrow diff --git a/composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/RegMaraphon.kt b/composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/RegMaraphon.kt index ffe27c4..ae0eb35 100644 --- a/composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/RegMaraphon.kt +++ b/composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/RegMaraphon.kt @@ -39,12 +39,15 @@ import org.example.project.ViewModel.FieldWithDropdown import org.example.project.ViewModel.FieldWithLabel import org.example.project.ViewModel.FieldWithLabelInt import org.example.project.ViewModel.TimerViewModel +import org.example.project.ViewModel.UserViewModel -class RegMaraphonScreen(private val timerViewModel: TimerViewModel) : Screen { +class RegMaraphonScreen(private val timerViewModel: TimerViewModel, private val userId: Int) : Screen { @Composable override fun Content() { val navigator = LocalNavigator.currentOrThrow + val viewModel = UserViewModel() + val fonds = viewModel.getFond() Scaffold( topBar = { RegMaraphonTopBar() }, @@ -75,10 +78,11 @@ class RegMaraphonScreen(private val timerViewModel: TimerViewModel) : Screen { "Вариант B($20): вариант A + бейсболка + бутылка воды", "Вариант C($45): Вариант B + футболка + сувенирный буклет" ) - var blagi = listOf( - "Что-то", - "Ещё что-то" - ) +// var blagi = listOf( +// "Что-то", +// "Ещё что-то" +// ) + var fondsNames = fonds.map { it.name } var selectedOption by remember { mutableStateOf(options[0]) } var vznos by remember { mutableStateOf("")} var sumVznos by remember { mutableStateOf(0)} @@ -181,7 +185,7 @@ class RegMaraphonScreen(private val timerViewModel: TimerViewModel) : Screen { FieldWithDropdown( label = "Взнос:", - options = blagi, + options = fondsNames, selectedOption = vznos, onOptionSelected = { vznos = it }, fontSize = fontSizeSecond, @@ -192,11 +196,12 @@ class RegMaraphonScreen(private val timerViewModel: TimerViewModel) : Screen { FieldWithLabelInt( label = "Сумма взноса:", - value = sumVznos, - onValueChange = { sumVznos = it }, + value = finalSum, + onValueChange = { finalSum = it }, placeholder = "$$$", fontSize = fontSizeSecond, labelWidth = 0.5f, + enabled = false ) Spacer(modifier = Modifier.weight(0.1f)) @@ -209,7 +214,16 @@ class RegMaraphonScreen(private val timerViewModel: TimerViewModel) : Screen { .padding(horizontal = 16.dp, vertical = 8.dp) ) { Button( - onClick = { navigator.push(ConfirmRunnerScreen(timerViewModel))}, + onClick = { + val selectedFond = fonds.find { it.name == vznos } + if (selectedFond != null && selectedFond.balance > finalSum) { + val result = viewModel.withdrawalBalance(selectedFond.id, finalSum) + val result2 = viewModel.updateUserActive(userId) + if (result && result2){ + navigator.push(ConfirmRunnerScreen(timerViewModel, userId)) + } + } + }, modifier = Modifier.weight(1f), colors = ButtonDefaults.buttonColors( backgroundColor = Color.LightGray, @@ -223,7 +237,7 @@ class RegMaraphonScreen(private val timerViewModel: TimerViewModel) : Screen { Spacer(modifier = Modifier.weight(0.1f)) Button( - onClick = { navigator.push(MainScreen()) }, + onClick = { navigator.push(InfoRunnerScreen(timerViewModel, userId)) }, modifier = Modifier.weight(1f), colors = ButtonDefaults.buttonColors( backgroundColor = Color.LightGray, @@ -329,7 +343,7 @@ class RegMaraphonScreen(private val timerViewModel: TimerViewModel) : Screen { ) { Button( - onClick = { }, + onClick = { navigator.push(InfoRunnerScreen(timerViewModel, userId)) }, colors = ButtonDefaults.buttonColors( backgroundColor = Color.LightGray, contentColor = Color.Black diff --git a/composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/RegRunner.kt b/composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/RegRunner.kt index 52dfe42..27a0422 100644 --- a/composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/RegRunner.kt +++ b/composeApp/src/commonMain/kotlin/org/example/project/ui/Screens/RegRunner.kt @@ -1,8 +1,6 @@ package org.example.project.ui.Screens import androidx.compose.foundation.background -import androidx.compose.foundation.Image -import androidx.compose.ui.res.painterResource import androidx.compose.foundation.border import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement @@ -13,27 +11,19 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.wrapContentWidth -import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.Button import androidx.compose.material.ButtonDefaults -import androidx.compose.material.DropdownMenu -import androidx.compose.material.DropdownMenuItem import androidx.compose.material.Icon -import androidx.compose.material.IconButton import androidx.compose.material.MaterialTheme import androidx.compose.material.OutlinedTextField import androidx.compose.material.Scaffold import androidx.compose.material.Text -import androidx.compose.material.TextField -import androidx.compose.material.contentColorFor import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.ArrowDropDown import androidx.compose.material.icons.filled.DateRange import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState @@ -47,29 +37,68 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.TextUnit import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import cafe.adriel.voyager.core.screen.Screen import cafe.adriel.voyager.navigator.LocalNavigator import cafe.adriel.voyager.navigator.currentOrThrow +import org.example.project.Models.User import org.example.project.ViewModel.DatePickerField import org.example.project.ViewModel.FieldWithDropdown import org.example.project.ViewModel.FieldWithLabel import org.example.project.ViewModel.GetPath import org.example.project.ViewModel.ImageFromPath import org.example.project.ViewModel.TimerViewModel +import org.example.project.ViewModel.UserViewModel +import java.time.LocalDate +import java.time.format.DateTimeFormatter +import java.time.format.DateTimeParseException -class RegRunnerScreen(private val timerViewModel: TimerViewModel) : Screen { +class RegRunnerScreen( + private val timerViewModel: TimerViewModel, +) : Screen { @Composable override fun Content() { val navigator = LocalNavigator.currentOrThrow + val viewModel = UserViewModel() + var users = viewModel.getUsers() + val nextId = (users.maxByOrNull { it.id }?.id ?: 0) + 1 + var email by remember { mutableStateOf("") } + var password by remember { mutableStateOf("") } + var secondPassword by remember { mutableStateOf("") } + var name by remember { mutableStateOf("") } + var surname by remember { mutableStateOf("") } + var gender by remember { mutableStateOf("") } + var country by remember { mutableStateOf("") } + var photoPath by remember { mutableStateOf("") } + var openPicker by remember { mutableStateOf(false) } + if (openPicker) { + GetPath { selected -> + photoPath = selected + openPicker = false + } + } + var showDatePicker by remember { mutableStateOf(false) } + var dateBirthday by remember { mutableStateOf("") } + if (showDatePicker) { + DatePickerField( + onDateSelected = { + dateBirthday = it + }, + trigger = true, + onDismissRequest = { showDatePicker = false } + ) + } Scaffold( topBar = { RegRunnerTopBar() }, - bottomBar = { BottomSection(timerViewModel = timerViewModel) } + bottomBar = { + BottomSection( + timerViewModel, + email, password, secondPassword, name, surname, gender, photoPath, dateBirthday, country + ) + } ) { paddingValues -> Box( modifier = Modifier.padding(paddingValues).fillMaxSize() @@ -84,32 +113,6 @@ class RegRunnerScreen(private val timerViewModel: TimerViewModel) : Screen { val fontSizeFirst = (maxWidth.value / 30).sp val fontSizeSecond = (maxWidth.value / 40).sp val labelWidth = 0.5f - var email by remember { mutableStateOf("") } - var password by remember { mutableStateOf("") } - var secondPassword by remember { mutableStateOf("") } - var name by remember { mutableStateOf("") } - var surname by remember { mutableStateOf("") } - var gender by remember { mutableStateOf("") } - var country by remember { mutableStateOf("") } - var photoPath by remember { mutableStateOf("") } - var openPicker by remember { mutableStateOf(false) } - if (openPicker) { - GetPath { selected -> - photoPath = selected - openPicker = false - } - } - var showDatePicker by remember { mutableStateOf(false) } - var dateBirthday by remember { mutableStateOf("") } - if (showDatePicker) { - DatePickerField( - onDateSelected = { - dateBirthday = it - }, - trigger = true, - onDismissRequest = { showDatePicker = false } - ) - } Column( modifier = Modifier @@ -146,7 +149,8 @@ class RegRunnerScreen(private val timerViewModel: TimerViewModel) : Screen { FieldWithLabel( label = "Email:", value = email, - onValueChange = { email = it }, + onValueChange = { email = it + println(email)}, placeholder = "Email", fontSize = fontSize, labelWidth = labelWidth, @@ -355,6 +359,8 @@ class RegRunnerScreen(private val timerViewModel: TimerViewModel) : Screen { fontSize = fontSize, labelWidth = labelWidth ) + + Spacer(modifier = Modifier.width(16.dp)) } } } @@ -364,7 +370,6 @@ class RegRunnerScreen(private val timerViewModel: TimerViewModel) : Screen { } } - @Composable private fun RegRunnerTopBar() { val navigator = LocalNavigator.currentOrThrow @@ -444,24 +449,68 @@ class RegRunnerScreen(private val timerViewModel: TimerViewModel) : Screen { } @Composable - private fun BottomSection( - timerViewModel: TimerViewModel - ) { + private fun BottomSection( + timerViewModel: TimerViewModel, + email: String, + password: String, + secondPassword: String, + name: String, + surname: String, + gender: String, + photoPath: String, + dateBirthday: String, + country: String + ){ val navigator = LocalNavigator.currentOrThrow + Column( modifier = Modifier .fillMaxWidth() .background(Color.White) ) { Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceEvenly, - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 8.dp) + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceEvenly, + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp) ) { Button( - onClick = { navigator.push(RegMaraphonScreen(timerViewModel)) }, + onClick = { + val viewModel = UserViewModel() + var users = viewModel.getUsers() + val nextId = (users.maxByOrNull { it.id }?.id ?: 0) + 1 + val formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy") + val birthdayDate = if (dateBirthday.isNotEmpty()) { + try { + LocalDate.parse(dateBirthday, formatter) + } catch (e: DateTimeParseException) { + LocalDate.now() + } + } else { + LocalDate.now() + } + + if (secondPassword == password) { + val result = viewModel.regUser( + User( + id = nextId, + email = email, + password = password, + name = name, + surname = surname, + gender = gender, + photopath = photoPath, + birthday = birthdayDate, + country = country, + active = false + ) + ) + if (result){ + navigator.push(InfoRunnerScreen(timerViewModel, nextId)) + } + } + }, modifier = Modifier.weight(1f), colors = ButtonDefaults.buttonColors( backgroundColor = Color.LightGray, diff --git a/composeApp/src/desktopMain/kotlin/org/example/project/Server.kt b/composeApp/src/desktopMain/kotlin/org/example/project/Server.kt new file mode 100644 index 0000000..6e7df22 --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/org/example/project/Server.kt @@ -0,0 +1,40 @@ +//package org.example.project +// +//import io.ktor.application.* +//import io.ktor.features.ContentNegotiation +//import io.ktor.http.HttpStatusCode +//import io.ktor.response.respond +//import io.ktor.routing.get +//import io.ktor.routing.routing +//import io.ktor.server.engine.embeddedServer +//import io.ktor.server.netty.Netty +//import io.ktor.server.plugins.statuspages.StatusPages +//import io.ktor.serialization.kotlinx.json +//import org.jetbrains.exposed.sql.Database +//import org.jetbrains.exposed.sql.selectAll +//import org.jetbrains.exposed.sql.transactions.transaction +//import org.example.project.Tables.Users +// +//fun startServer() { +// embeddedServer(Netty, port = 8080) { +// install(ContentNegotiation) { +// json() +// } +// +// install(StatusPages) { +// exception { cause -> +// call.respond(HttpStatusCode.InternalServerError, cause.localizedMessage) +// } +// } +// +// routing { +// get("/users") { +// Database.connect("jdbc:postgresql://localhost:5432/yourdb", driver = "org.postgresql.Driver", user = "user", password = "password") +// val users = transaction { +// Users.selectAll().map { it[Users.email] } +// } +// call.respond(users) +// } +// } +// }.start(wait = true) +//} \ No newline at end of file diff --git a/composeApp/src/desktopMain/kotlin/org/example/project/Tables/Connect.kt b/composeApp/src/desktopMain/kotlin/org/example/project/Tables/Connect.kt new file mode 100644 index 0000000..90f0397 --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/org/example/project/Tables/Connect.kt @@ -0,0 +1,17 @@ +package org.example.project.Tables + +import org.example.project.Models.User +import org.jetbrains.exposed.sql.Database +import org.jetbrains.exposed.sql.SchemaUtils +import org.jetbrains.exposed.sql.Table +import org.jetbrains.exposed.sql.selectAll +import org.jetbrains.exposed.sql.transactions.transaction + +fun connectToDatabase() { + Database.connect( + "jdbc:postgresql://localhost:5432/postgres", + driver = "org.postgresql.Driver", + user = "postgres", + password = "5432" + ) +} diff --git a/composeApp/src/desktopMain/kotlin/org/example/project/Tables/Fonds.kt b/composeApp/src/desktopMain/kotlin/org/example/project/Tables/Fonds.kt new file mode 100644 index 0000000..2b2b8b4 --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/org/example/project/Tables/Fonds.kt @@ -0,0 +1,13 @@ +package org.example.project.Tables + +import org.example.project.Tables.Users.autoIncrement +import org.jetbrains.exposed.sql.Table +import org.jetbrains.exposed.sql.javatime.date + +object Fonds : Table() { + val id = integer("id").autoIncrement() + val name = varchar("name", 255) + val balance = integer("balance") + + override val primaryKey = PrimaryKey(id) +} \ No newline at end of file diff --git a/composeApp/src/desktopMain/kotlin/org/example/project/Tables/Users.kt b/composeApp/src/desktopMain/kotlin/org/example/project/Tables/Users.kt new file mode 100644 index 0000000..d2a3490 --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/org/example/project/Tables/Users.kt @@ -0,0 +1,18 @@ +package org.example.project.Tables + +import org.jetbrains.exposed.sql.Table +import org.jetbrains.exposed.sql.javatime.date + +object Users : Table() { + val id = integer("id").autoIncrement() + val email = varchar("email", 255) + val password = varchar("password", 255) + val name = varchar("name", 255) + val surname = varchar("surname", 255) + val gender = varchar("gender", 255) + val photopath = varchar("photopath", 255) + val birthday = date("birthday") + val country = varchar("country", 255) + val active = bool("active").default(false) + override val primaryKey = PrimaryKey(id) +} diff --git a/composeApp/src/desktopMain/kotlin/org/example/project/ViewModel/IconPrinter.kt b/composeApp/src/desktopMain/kotlin/org/example/project/ViewModel/IconPrinter.kt new file mode 100644 index 0000000..99d1cf5 --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/org/example/project/ViewModel/IconPrinter.kt @@ -0,0 +1,34 @@ +package org.example.project.ViewModel + +import androidx.compose.runtime.Composable +import androidx.compose.foundation.Image +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.painter.BitmapPainter +import androidx.compose.ui.graphics.toComposeImageBitmap +import androidx.compose.ui.layout.ContentScale +import org.jetbrains.skia.Image +import java.io.IOException + +@Composable +actual fun IconPrinter(resourceName: String, modifier: Modifier) { + val imageBitmap = try { + val path = "drawable/${resourceName}.jpg" + val stream = Thread.currentThread().contextClassLoader.getResourceAsStream(path) + if (stream != null) { + Image.makeFromEncoded(stream.readAllBytes()).toComposeImageBitmap() + } else null + } catch (e: IOException) { + println("Ошибка загрузки иконки: ${e.message}") + null + } + + if (imageBitmap != null) { + Image( + painter = BitmapPainter(imageBitmap), + contentDescription = null, + modifier = modifier, +// contentScale = ContentScale.Fit + contentScale = ContentScale.FillBounds + ) + } +} \ No newline at end of file diff --git a/composeApp/src/desktopMain/kotlin/org/example/project/ViewModel/UserRepository.kt b/composeApp/src/desktopMain/kotlin/org/example/project/ViewModel/UserRepository.kt new file mode 100644 index 0000000..04bc18f --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/org/example/project/ViewModel/UserRepository.kt @@ -0,0 +1,128 @@ +package org.example.project.ViewModel + +import org.example.project.Models.Fond +import org.example.project.Models.User +import org.example.project.Tables.Fonds +import org.example.project.Tables.Users +import org.example.project.Tables.connectToDatabase +import org.jetbrains.exposed.sql.SchemaUtils +import org.jetbrains.exposed.sql.SqlExpressionBuilder +import org.jetbrains.exposed.sql.insert +import org.jetbrains.exposed.sql.selectAll +import org.jetbrains.exposed.sql.transactions.transaction +import org.jetbrains.exposed.sql.update + +actual class UserRepository { + actual fun fetchUsers(): List { + connectToDatabase() + + return transaction { + Users.selectAll().map { + User( + id = it[Users.id], + email = it[Users.email], + password = it[Users.password], + name = it[Users.name], + surname = it[Users.surname], + gender = it[Users.gender], + photopath = it[Users.photopath], + birthday = it[Users.birthday], + country = it[Users.country], + active = it[Users.active] + ) + } + } + } + actual fun regUser(user: User): Boolean{ + connectToDatabase() + + return try { + transaction { + Users.insert { + it[id] = user.id + it[email] = user.email + it[password] = user.password + it[name] = user.name + it[surname] = user.surname + it[gender] = user.gender + it[photopath] = user.photopath + it[birthday] = user.birthday + it[country] = user.country + } + } + true + } catch (e: Exception) { + println("Ошибка при регистрации: ${e.message}") + false + } + } + actual fun fetchFonds(): List{ + connectToDatabase() + + return transaction { + Fonds.selectAll().map { + Fond( + id = it[Fonds.id], + name = it[Fonds.name], + balance = it[Fonds.balance] + ) + } + } + } + actual fun withdrawalBalance(idFond: Int, dedSum: Int): Boolean{ + connectToDatabase() + + return try { + transaction { + Fonds.update({Fonds.id eq idFond}){ + with(SqlExpressionBuilder) { + it.update(balance, balance - dedSum) + } + } + } + true + } catch (e: Exception){ + println("Ошибка при снятии: ${e.message}") + false + } + } + actual fun getUserIdByEmail(email: String): Int { + connectToDatabase() + + return transaction { + Users.selectAll().where { Users.email eq email }.single()[Users.id] + } + } + actual fun updateUserActive(idUser: Int): Boolean{ + connectToDatabase() + + return try { + transaction { + Users.update({Users.id eq idUser}){ + it[active] = true + } + } + true + } catch (e: Exception){ + println("Ошибка при обновлении: ${e.message}") + false + } + } + actual fun topUpBalance(idFond: Int, sum: Int): Boolean{ + connectToDatabase() + + return try { + transaction { + Fonds.update({Fonds.id eq idFond}){ + with(SqlExpressionBuilder) { + it.update(balance, balance + sum) + } + } + } + true + } catch (e: Exception){ + println("Ошибка при пополнении: ${e.message}") + false + } + } +} \ No newline at end of file