allWindows;dbDesktop

This commit is contained in:
Your Name 2025-05-01 14:26:13 +03:00
parent 1a4496c06b
commit ca093260e2
28 changed files with 1084 additions and 161 deletions

View File

@ -18,9 +18,38 @@ kotlin {
} }
jvm("desktop") jvm("desktop")
sourceSets { 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 { val commonMain by getting {
resources.srcDir("src/commonMain/composeResources") resources.srcDir("src/commonMain/composeResources")
@ -31,6 +60,23 @@ kotlin {
implementation(libs.androidx.activity.compose) implementation(libs.androidx.activity.compose)
implementation(libs.androidx.lifecycle.viewmodel) implementation(libs.androidx.lifecycle.viewmodel)
implementation("io.ktor:ktor-client-okhttp:2.3.2") 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 { commonMain.dependencies {
val voyagerVersion = "1.1.0-beta02" 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-core:2.3.2")
implementation("io.ktor:ktor-client-cio:2.3.2") implementation("io.ktor:ktor-client-cio:2.3.2")
implementation("io.ktor:ktor-client-okhttp:2.3.2") implementation("io.ktor:ktor-client-okhttp:2.3.2")
implementation ("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.2")
repositories { repositories {
google() google()
mavenCentral() mavenCentral()
} }
} }
desktopMain.dependencies { // desktopMain.dependencies {
implementation(compose.desktop.currentOs) // implementation(compose.desktop.currentOs)
implementation(libs.kotlinx.coroutines.swing) // implementation(libs.kotlinx.coroutines.swing)
implementation("io.ktor:ktor-client-okhttp:2.3.2") // 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 targetCompatibility = JavaVersion.VERSION_11
} }
} }
dependencies {
implementation(project(":composeApp"))
}
compose.desktop { compose.desktop {
application { application {

View File

@ -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
)
}

View File

@ -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<User> {
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<Fond> {
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
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

View File

@ -0,0 +1,9 @@
package org.example.project.Models
import java.time.LocalDate
data class Fond(
val id: Int,
val name: String,
val balance: Int
)

View File

@ -0,0 +1,17 @@
package org.example.project.Models
import java.time.LocalDate
import java.util.Date
data class User(
val id: Int,
val email: String,
val password: String,
val name: String,
val surname: String,
val gender: String,
val photopath: String,
val birthday: LocalDate,
val country: String,
val active: Boolean
)

View File

@ -0,0 +1,7 @@
package org.example.project.ViewModel
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
@Composable
expect fun IconPrinter(resourceName: String, modifier: Modifier = Modifier)

View File

@ -0,0 +1,33 @@
package org.example.project.ViewModel
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.dp
@Composable
fun InfoButton(text: String, fontSize: TextUnit, onClick: () -> 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)
}
}

View File

@ -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("")
}

View File

@ -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<User>
fun regUser(user: User): Boolean
fun fetchFonds(): List<Fond>
fun withdrawalBalance(idFond: Int, dedSum: Int): Boolean
fun getUserIdByEmail(email: String): Int
fun updateUserActive(idUser: Int): Boolean
fun topUpBalance(idFond: Int, sum: Int): Boolean
}

View File

@ -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<User> {
return userRepository.fetchUsers()
}
fun regUser(user: User): Boolean {
return userRepository.regUser(user)
}
fun getFond(): List<Fond>{
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)
}
}

View File

@ -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
)
}
}
}
}
}

View File

@ -33,7 +33,7 @@ import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow import cafe.adriel.voyager.navigator.currentOrThrow
import org.example.project.ViewModel.TimerViewModel import org.example.project.ViewModel.TimerViewModel
class ConfirmRunnerScreen(private val timerViewModel: TimerViewModel) : class ConfirmRunnerScreen(private val timerViewModel: TimerViewModel, private val idRunner: Int) :
Screen { Screen {
@Composable @Composable
@ -89,7 +89,7 @@ class ConfirmRunnerScreen(private val timerViewModel: TimerViewModel) :
Spacer(modifier = Modifier.weight(0.2f)) Spacer(modifier = Modifier.weight(0.2f))
Button( Button(
onClick = { navigator.push(InfoRunnerScreen(timerViewModel)) }, onClick = { navigator.push(InfoRunnerScreen(timerViewModel, idRunner)) },
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.height(48.dp), .height(48.dp),

View File

@ -28,6 +28,9 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp 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 import org.example.project.ViewModel.TimerViewModel
class RunnerScreen(private val timerViewModel: TimerViewModel) : Screen { class RunnerScreen(private val timerViewModel: TimerViewModel) : Screen {
@ -80,7 +83,11 @@ class RunnerScreen(private val timerViewModel: TimerViewModel) : Screen {
Spacer(modifier = Modifier.weight(0.25f)) Spacer(modifier = Modifier.weight(0.25f))
Button( Button(
onClick = { navigator.push(RegRunnerScreen(timerViewModel)) }, // onClick = { navigator.push(RegRunnerScreen(timerViewModel)) },
onClick = {
val regRunnerViewModel = RegRunnerViewModel()
navigator.push(RegRunnerScreen(timerViewModel))
},
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.weight(1f), .weight(1f),

View File

@ -1,6 +1,7 @@
package org.example.project.ui.Screens package org.example.project.ui.Screens
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box 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.foundation.shape.RoundedCornerShape
import androidx.compose.material.Button import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults import androidx.compose.material.ButtonDefaults
import androidx.compose.material.DropdownMenu
import androidx.compose.material.DropdownMenuItem
import androidx.compose.material.Icon import androidx.compose.material.Icon
import androidx.compose.material.MaterialTheme import androidx.compose.material.MaterialTheme
import androidx.compose.material.OutlinedTextField import androidx.compose.material.OutlinedTextField
import androidx.compose.material.Scaffold import androidx.compose.material.Scaffold
import androidx.compose.material.Text import androidx.compose.material.Text
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowDropDown
import androidx.compose.material.icons.filled.DateRange import androidx.compose.material.icons.filled.DateRange
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState 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.FieldWithDropdown
import org.example.project.ViewModel.FieldWithLabel import org.example.project.ViewModel.FieldWithLabel
import org.example.project.ViewModel.TimerViewModel import org.example.project.ViewModel.TimerViewModel
import org.example.project.ViewModel.UserViewModel
class ForSponsorScreen(private val timerViewModel: TimerViewModel) : Screen { class ForSponsorScreen(private val timerViewModel: TimerViewModel) : Screen {
@Composable @Composable
override fun Content() { override fun Content() {
val navigator = LocalNavigator.currentOrThrow val navigator = LocalNavigator.currentOrThrow
val viewModel = UserViewModel()
val fonds = viewModel.getFond()
val runners = viewModel.getUsers()
Scaffold( Scaffold(
topBar = { ForSponsorTopBar() }, topBar = { ForSponsorTopBar() },
@ -71,12 +79,10 @@ class ForSponsorScreen(private val timerViewModel: TimerViewModel) : Screen {
val fontSizeThird = (maxWidth.value / 50).sp val fontSizeThird = (maxWidth.value / 50).sp
val fontSizeFourth = (maxWidth.value / 10).sp val fontSizeFourth = (maxWidth.value / 10).sp
val labelWidth = 0.5f 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("") } var fio by remember { mutableStateOf("") }
val runners = listOf(
"bob",
"bobby",
"baby"
)
var runner by remember { mutableStateOf("") } var runner by remember { mutableStateOf("") }
var cardName by remember { mutableStateOf("") } var cardName by remember { mutableStateOf("") }
var cardNum 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 sumChangStr by remember { mutableStateOf("10")}
var sumChang by remember { mutableStateOf(sumChangStr.toInt()) } var sumChang by remember { mutableStateOf(sumChangStr.toInt()) }
var sumSpons by remember { mutableStateOf(0)} var sumSpons by remember { mutableStateOf(0)}
var expanded by remember { mutableStateOf(false) }
Column( Column(
modifier = Modifier modifier = Modifier
@ -144,7 +151,7 @@ class ForSponsorScreen(private val timerViewModel: TimerViewModel) : Screen {
FieldWithDropdown( FieldWithDropdown(
label = "Бегун:", label = "Бегун:",
options = runners, options = runnersNames,
selectedOption = runner, selectedOption = runner,
onOptionSelected = { runner = it }, onOptionSelected = { runner = it },
fontSize = fontSizeSecond, fontSize = fontSizeSecond,
@ -242,15 +249,14 @@ class ForSponsorScreen(private val timerViewModel: TimerViewModel) : Screen {
Spacer(modifier = Modifier.weight(0.1f)) Spacer(modifier = Modifier.weight(0.1f))
Box(modifier = Modifier.fillMaxWidth()) { FieldWithDropdown(
Text( label = "",
text = "blagot...", options = fondsNames,
color = Color.Black, selectedOption = selectedFondName,
textAlign = TextAlign.Center, onOptionSelected = { selectedFondName = it },
fontSize = fontSizeSecond, fontSize = fontSizeSecond,
modifier = Modifier.align(Alignment.Center) labelWidth = 0.5f
) )
}
Spacer(modifier = Modifier.weight(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) .padding(horizontal = 16.dp, vertical = 8.dp)
) { ) {
Button( 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), modifier = Modifier.weight(1f),
colors = ButtonDefaults.buttonColors( colors = ButtonDefaults.buttonColors(
backgroundColor = Color.LightGray, backgroundColor = Color.LightGray,
@ -399,7 +414,7 @@ class ForSponsorScreen(private val timerViewModel: TimerViewModel) : Screen {
) { ) {
Button( Button(
onClick = { }, onClick = { navigator.push(MainScreen()) },
colors = ButtonDefaults.buttonColors( colors = ButtonDefaults.buttonColors(
backgroundColor = Color.LightGray, backgroundColor = Color.LightGray,
contentColor = Color.Black contentColor = Color.Black

View File

@ -33,10 +33,11 @@ import androidx.compose.ui.unit.sp
import cafe.adriel.voyager.core.screen.Screen import cafe.adriel.voyager.core.screen.Screen
import cafe.adriel.voyager.navigator.LocalNavigator import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow import cafe.adriel.voyager.navigator.currentOrThrow
import org.example.project.ViewModel.InfoButton
import org.example.project.ViewModel.TimerViewModel 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 @Composable
override fun Content() { override fun Content() {
@ -88,9 +89,9 @@ class InfoRunnerScreen(private val timerViewModel: TimerViewModel) : Screen {
verticalArrangement = Arrangement.spacedBy(16.dp), verticalArrangement = Arrangement.spacedBy(16.dp),
horizontalAlignment = Alignment.CenterHorizontally horizontalAlignment = Alignment.CenterHorizontally
) { ) {
InfoButton("Регистрация на марафон", fontSizeButton) InfoButton("Регистрация на марафон", fontSizeButton, {navigator.push(RegMaraphonScreen(timerViewModel, idRunner))})
InfoButton("Редактирование профиля", fontSizeButton) InfoButton("Редактирование профиля", fontSizeButton, {})
InfoButton("Контакты", fontSizeButton) InfoButton("Контакты", fontSizeButton, {})
} }
Column( Column(
@ -100,8 +101,8 @@ class InfoRunnerScreen(private val timerViewModel: TimerViewModel) : Screen {
verticalArrangement = Arrangement.spacedBy(16.dp), verticalArrangement = Arrangement.spacedBy(16.dp),
horizontalAlignment = Alignment.CenterHorizontally 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 @Composable
private fun InfoRunnerTopBar() { private fun InfoRunnerTopBar() {
val navigator = LocalNavigator.currentOrThrow val navigator = LocalNavigator.currentOrThrow

View File

@ -35,11 +35,13 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.min import androidx.compose.ui.unit.min
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.lifecycle.ViewModel
import cafe.adriel.voyager.core.screen.Screen import cafe.adriel.voyager.core.screen.Screen
import cafe.adriel.voyager.navigator.LocalNavigator import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow import cafe.adriel.voyager.navigator.currentOrThrow
import org.example.project.ViewModel.FieldWithLabel import org.example.project.ViewModel.FieldWithLabel
import org.example.project.ViewModel.TimerViewModel import org.example.project.ViewModel.TimerViewModel
import org.example.project.ViewModel.UserViewModel
class LoginScreen(private val timerViewModel: TimerViewModel) : Screen { class LoginScreen(private val timerViewModel: TimerViewModel) : Screen {
@ -52,6 +54,9 @@ class LoginScreen(private val timerViewModel: TimerViewModel) : Screen {
bottomBar = { LoginBottomBar(timerViewModel = timerViewModel) } bottomBar = { LoginBottomBar(timerViewModel = timerViewModel) }
) { paddingValues -> ) { paddingValues ->
val viewModel = UserViewModel()
val users = viewModel.getUsers()
Box( Box(
modifier = Modifier.padding(paddingValues) modifier = Modifier.padding(paddingValues)
) { ) {
@ -122,7 +127,14 @@ class LoginScreen(private val timerViewModel: TimerViewModel) : Screen {
horizontalArrangement = Arrangement.Center horizontalArrangement = Arrangement.Center
) { ) {
Button( 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 modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.weight(1f), .weight(1f),

View File

@ -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( Button(
onClick = { navigator.push(LoginScreen(timerViewModel)) }, onClick = { navigator.push(LoginScreen(timerViewModel)) },
modifier = Modifier modifier = Modifier

View File

@ -33,6 +33,7 @@ import androidx.compose.ui.unit.sp
import cafe.adriel.voyager.core.screen.Screen import cafe.adriel.voyager.core.screen.Screen
import cafe.adriel.voyager.navigator.LocalNavigator import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow import cafe.adriel.voyager.navigator.currentOrThrow
import org.example.project.ViewModel.InfoButton
import org.example.project.ViewModel.TimerViewModel import org.example.project.ViewModel.TimerViewModel
@ -88,9 +89,9 @@ class MoreInfoScreen(private val timerViewModel: TimerViewModel) : Screen {
verticalArrangement = Arrangement.spacedBy(16.dp), verticalArrangement = Arrangement.spacedBy(16.dp),
horizontalAlignment = Alignment.CenterHorizontally horizontalAlignment = Alignment.CenterHorizontally
) { ) {
InfoButton("Marathon Skills 2016", fontSizeButton) InfoButton("Marathon Skills 2016", fontSizeButton, {navigator.push(AboutMarathonScreen(timerViewModel))})
InfoButton("Предыдущие результаты", fontSizeButton) InfoButton("Предыдущие результаты", fontSizeButton, {})
InfoButton("BMI калькулятор", fontSizeButton) InfoButton("BMI калькулятор", fontSizeButton, {})
} }
Column( Column(
@ -100,9 +101,9 @@ class MoreInfoScreen(private val timerViewModel: TimerViewModel) : Screen {
verticalArrangement = Arrangement.spacedBy(16.dp), verticalArrangement = Arrangement.spacedBy(16.dp),
horizontalAlignment = Alignment.CenterHorizontally horizontalAlignment = Alignment.CenterHorizontally
) { ) {
InfoButton("Насколько долгий марафон", fontSizeButton) InfoButton("Насколько долгий марафон", fontSizeButton, {})
InfoButton("Список\nблаготворительных организаций", fontSizeButton) InfoButton("Список\nблаготворительных организаций", fontSizeButton, {})
InfoButton("BMR калькулятор", 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 @Composable
private fun InfoTopBar() { private fun InfoTopBar() {
val navigator = LocalNavigator.currentOrThrow val navigator = LocalNavigator.currentOrThrow

View File

@ -39,12 +39,15 @@ import org.example.project.ViewModel.FieldWithDropdown
import org.example.project.ViewModel.FieldWithLabel import org.example.project.ViewModel.FieldWithLabel
import org.example.project.ViewModel.FieldWithLabelInt import org.example.project.ViewModel.FieldWithLabelInt
import org.example.project.ViewModel.TimerViewModel 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 @Composable
override fun Content() { override fun Content() {
val navigator = LocalNavigator.currentOrThrow val navigator = LocalNavigator.currentOrThrow
val viewModel = UserViewModel()
val fonds = viewModel.getFond()
Scaffold( Scaffold(
topBar = { RegMaraphonTopBar() }, topBar = { RegMaraphonTopBar() },
@ -75,10 +78,11 @@ class RegMaraphonScreen(private val timerViewModel: TimerViewModel) : Screen {
"Вариант B($20): вариант A + бейсболка + бутылка воды", "Вариант B($20): вариант A + бейсболка + бутылка воды",
"Вариант C($45): Вариант B + футболка + сувенирный буклет" "Вариант C($45): Вариант B + футболка + сувенирный буклет"
) )
var blagi = listOf( // var blagi = listOf(
"Что-то", // "Что-то",
"Ещё что-то" // "Ещё что-то"
) // )
var fondsNames = fonds.map { it.name }
var selectedOption by remember { mutableStateOf(options[0]) } var selectedOption by remember { mutableStateOf(options[0]) }
var vznos by remember { mutableStateOf("")} var vznos by remember { mutableStateOf("")}
var sumVznos by remember { mutableStateOf(0)} var sumVznos by remember { mutableStateOf(0)}
@ -181,7 +185,7 @@ class RegMaraphonScreen(private val timerViewModel: TimerViewModel) : Screen {
FieldWithDropdown( FieldWithDropdown(
label = "Взнос:", label = "Взнос:",
options = blagi, options = fondsNames,
selectedOption = vznos, selectedOption = vznos,
onOptionSelected = { vznos = it }, onOptionSelected = { vznos = it },
fontSize = fontSizeSecond, fontSize = fontSizeSecond,
@ -192,11 +196,12 @@ class RegMaraphonScreen(private val timerViewModel: TimerViewModel) : Screen {
FieldWithLabelInt( FieldWithLabelInt(
label = "Сумма взноса:", label = "Сумма взноса:",
value = sumVznos, value = finalSum,
onValueChange = { sumVznos = it }, onValueChange = { finalSum = it },
placeholder = "$$$", placeholder = "$$$",
fontSize = fontSizeSecond, fontSize = fontSizeSecond,
labelWidth = 0.5f, labelWidth = 0.5f,
enabled = false
) )
Spacer(modifier = Modifier.weight(0.1f)) Spacer(modifier = Modifier.weight(0.1f))
@ -209,7 +214,16 @@ class RegMaraphonScreen(private val timerViewModel: TimerViewModel) : Screen {
.padding(horizontal = 16.dp, vertical = 8.dp) .padding(horizontal = 16.dp, vertical = 8.dp)
) { ) {
Button( 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), modifier = Modifier.weight(1f),
colors = ButtonDefaults.buttonColors( colors = ButtonDefaults.buttonColors(
backgroundColor = Color.LightGray, backgroundColor = Color.LightGray,
@ -223,7 +237,7 @@ class RegMaraphonScreen(private val timerViewModel: TimerViewModel) : Screen {
Spacer(modifier = Modifier.weight(0.1f)) Spacer(modifier = Modifier.weight(0.1f))
Button( Button(
onClick = { navigator.push(MainScreen()) }, onClick = { navigator.push(InfoRunnerScreen(timerViewModel, userId)) },
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
colors = ButtonDefaults.buttonColors( colors = ButtonDefaults.buttonColors(
backgroundColor = Color.LightGray, backgroundColor = Color.LightGray,
@ -329,7 +343,7 @@ class RegMaraphonScreen(private val timerViewModel: TimerViewModel) : Screen {
) { ) {
Button( Button(
onClick = { }, onClick = { navigator.push(InfoRunnerScreen(timerViewModel, userId)) },
colors = ButtonDefaults.buttonColors( colors = ButtonDefaults.buttonColors(
backgroundColor = Color.LightGray, backgroundColor = Color.LightGray,
contentColor = Color.Black contentColor = Color.Black

View File

@ -1,8 +1,6 @@
package org.example.project.ui.Screens package org.example.project.ui.Screens
import androidx.compose.foundation.background 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.border
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement 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.Spacer
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentWidth import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Button import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults import androidx.compose.material.ButtonDefaults
import androidx.compose.material.DropdownMenu
import androidx.compose.material.DropdownMenuItem
import androidx.compose.material.Icon import androidx.compose.material.Icon
import androidx.compose.material.IconButton
import androidx.compose.material.MaterialTheme import androidx.compose.material.MaterialTheme
import androidx.compose.material.OutlinedTextField import androidx.compose.material.OutlinedTextField
import androidx.compose.material.Scaffold import androidx.compose.material.Scaffold
import androidx.compose.material.Text 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.Icons
import androidx.compose.material.icons.filled.ArrowDropDown
import androidx.compose.material.icons.filled.DateRange import androidx.compose.material.icons.filled.DateRange
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState 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.graphics.Color
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign 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.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import cafe.adriel.voyager.core.screen.Screen import cafe.adriel.voyager.core.screen.Screen
import cafe.adriel.voyager.navigator.LocalNavigator import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow import cafe.adriel.voyager.navigator.currentOrThrow
import org.example.project.Models.User
import org.example.project.ViewModel.DatePickerField import org.example.project.ViewModel.DatePickerField
import org.example.project.ViewModel.FieldWithDropdown import org.example.project.ViewModel.FieldWithDropdown
import org.example.project.ViewModel.FieldWithLabel import org.example.project.ViewModel.FieldWithLabel
import org.example.project.ViewModel.GetPath import org.example.project.ViewModel.GetPath
import org.example.project.ViewModel.ImageFromPath import org.example.project.ViewModel.ImageFromPath
import org.example.project.ViewModel.TimerViewModel 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 @Composable
override fun Content() { override fun Content() {
val navigator = LocalNavigator.currentOrThrow 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( Scaffold(
topBar = { RegRunnerTopBar() }, topBar = { RegRunnerTopBar() },
bottomBar = { BottomSection(timerViewModel = timerViewModel) } bottomBar = {
BottomSection(
timerViewModel,
email, password, secondPassword, name, surname, gender, photoPath, dateBirthday, country
)
}
) { paddingValues -> ) { paddingValues ->
Box( Box(
modifier = Modifier.padding(paddingValues).fillMaxSize() modifier = Modifier.padding(paddingValues).fillMaxSize()
@ -84,32 +113,6 @@ class RegRunnerScreen(private val timerViewModel: TimerViewModel) : Screen {
val fontSizeFirst = (maxWidth.value / 30).sp val fontSizeFirst = (maxWidth.value / 30).sp
val fontSizeSecond = (maxWidth.value / 40).sp val fontSizeSecond = (maxWidth.value / 40).sp
val labelWidth = 0.5f 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( Column(
modifier = Modifier modifier = Modifier
@ -146,7 +149,8 @@ class RegRunnerScreen(private val timerViewModel: TimerViewModel) : Screen {
FieldWithLabel( FieldWithLabel(
label = "Email:", label = "Email:",
value = email, value = email,
onValueChange = { email = it }, onValueChange = { email = it
println(email)},
placeholder = "Email", placeholder = "Email",
fontSize = fontSize, fontSize = fontSize,
labelWidth = labelWidth, labelWidth = labelWidth,
@ -355,6 +359,8 @@ class RegRunnerScreen(private val timerViewModel: TimerViewModel) : Screen {
fontSize = fontSize, fontSize = fontSize,
labelWidth = labelWidth labelWidth = labelWidth
) )
Spacer(modifier = Modifier.width(16.dp))
} }
} }
} }
@ -364,7 +370,6 @@ class RegRunnerScreen(private val timerViewModel: TimerViewModel) : Screen {
} }
} }
@Composable @Composable
private fun RegRunnerTopBar() { private fun RegRunnerTopBar() {
val navigator = LocalNavigator.currentOrThrow val navigator = LocalNavigator.currentOrThrow
@ -444,24 +449,68 @@ class RegRunnerScreen(private val timerViewModel: TimerViewModel) : Screen {
} }
@Composable @Composable
private fun BottomSection( private fun BottomSection(
timerViewModel: TimerViewModel timerViewModel: TimerViewModel,
) { email: String,
password: String,
secondPassword: String,
name: String,
surname: String,
gender: String,
photoPath: String,
dateBirthday: String,
country: String
){
val navigator = LocalNavigator.currentOrThrow val navigator = LocalNavigator.currentOrThrow
Column( Column(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.background(Color.White) .background(Color.White)
) { ) {
Row( Row(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceEvenly, horizontalArrangement = Arrangement.SpaceEvenly,
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 8.dp) .padding(horizontal = 16.dp)
) { ) {
Button( 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), modifier = Modifier.weight(1f),
colors = ButtonDefaults.buttonColors( colors = ButtonDefaults.buttonColors(
backgroundColor = Color.LightGray, backgroundColor = Color.LightGray,

View File

@ -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<Throwable> { 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)
//}

View File

@ -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"
)
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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
)
}
}

View File

@ -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<User> {
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<Fond>{
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
}
}
}