allWindows;dbDesktop
This commit is contained in:
parent
1a4496c06b
commit
ca093260e2
@ -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 {
|
||||
|
@ -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
|
||||
)
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
BIN
composeApp/src/androidMain/res/drawable/map.jpg
Normal file
BIN
composeApp/src/androidMain/res/drawable/map.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 45 KiB |
BIN
composeApp/src/commonMain/composeResources/drawable/map.jpg
Normal file
BIN
composeApp/src/commonMain/composeResources/drawable/map.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 45 KiB |
@ -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
|
||||
)
|
@ -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
|
||||
)
|
@ -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)
|
@ -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)
|
||||
}
|
||||
}
|
@ -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("")
|
||||
}
|
@ -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
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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),
|
||||
|
@ -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),
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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),
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
//}
|
@ -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"
|
||||
)
|
||||
}
|
@ -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)
|
||||
}
|
@ -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)
|
||||
}
|
@ -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
|
||||
)
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user