This commit is contained in:
1billy17 2025-05-09 12:35:00 +03:00
parent 4b6bf8a1d7
commit 565abdca18
42 changed files with 4056 additions and 326 deletions

View File

@ -18,10 +18,42 @@ 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")
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")
implementation("org.jetbrains.exposed:exposed-java-time:$exposedVersion")
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")
implementation("io.ktor:ktor-server-core:2.3.4")
implementation("io.ktor:ktor-server-netty:2.3.4")
implementation("io.ktor:ktor-server-content-negotiation:2.3.4")
implementation("io.ktor:ktor-serialization-kotlinx-json:2.3.4")
implementation("io.ktor:ktor-server-status-pages:2.3.4")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0")
}
}
val commonMain by getting {
resources.srcDir("src/commonMain/composeResources")
}
androidMain.dependencies {
implementation(compose.preview)
implementation(libs.androidx.activity.compose)
@ -40,10 +72,16 @@ kotlin {
implementation("cafe.adriel.voyager:voyager-screenmodel:$voyagerVersion")
implementation(compose.preview)
implementation(libs.androidx.lifecycle.viewmodel)
}
desktopMain.dependencies {
implementation(compose.desktop.currentOs)
implementation(libs.kotlinx.coroutines.swing)
implementation("media.kamel:kamel-image:0.7.0")
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()
}
}
}
}
@ -72,8 +110,12 @@ android {
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
isCoreLibraryDesugaringEnabled = true
}
}
dependencies {
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.4")
}
compose.desktop {
application {

View File

@ -0,0 +1,33 @@
package org.example.project.ViewModel
import android.app.DatePickerDialog
import android.widget.DatePicker
import androidx.compose.runtime.*
import androidx.compose.ui.platform.LocalContext
import java.util.*
@Composable
actual fun DatePickerField(
onDateSelected: (String) -> Unit,
trigger: Boolean,
onDismissRequest: () -> Unit
) {
val context = LocalContext.current
if (trigger) {
LaunchedEffect(Unit) {
val calendar = Calendar.getInstance()
DatePickerDialog(
context,
{ _: DatePicker, year: Int, month: Int, dayOfMonth: Int ->
val formatted = "%02d.%02d.%04d".format(dayOfMonth, month + 1, year)
onDateSelected(formatted)
onDismissRequest()
},
calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH)
).show()
}
}
}

View File

@ -0,0 +1,50 @@
package org.example.project.ViewModel
import android.net.Uri
import android.provider.OpenableColumns
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.runtime.*
import androidx.compose.ui.platform.LocalContext
import java.io.File
import java.io.FileOutputStream
@Composable
actual fun GetPath(onPathSelected: (String) -> Unit) {
val context = LocalContext.current
var launched by remember { mutableStateOf(false) }
val launcher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.GetContent(),
onResult = { uri: Uri? ->
if (uri != null) {
val inputStream = context.contentResolver.openInputStream(uri)
val fileName = getFileName(context.contentResolver, uri) ?: "temp_image.jpg"
val file = File(context.cacheDir, fileName)
val outputStream = FileOutputStream(file)
inputStream?.copyTo(outputStream)
inputStream?.close()
outputStream.close()
onPathSelected(file.absolutePath)
}
}
)
LaunchedEffect(Unit) {
if (!launched) {
launched = true
launcher.launch("image/*")
}
}
}
fun getFileName(contentResolver: android.content.ContentResolver, uri: Uri): String? {
val returnCursor = contentResolver.query(uri, null, null, null, null)
returnCursor?.use {
val nameIndex = it.getColumnIndex(OpenableColumns.DISPLAY_NAME)
if (it.moveToFirst()) {
return it.getString(nameIndex)
}
}
return null
}

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
}
Image(
painter = painterResource(id = resId),
contentDescription = null,
modifier = modifier,
contentScale = ContentScale.FillBounds
)
}

View File

@ -0,0 +1,44 @@
package org.example.project.ViewModel
import android.graphics.BitmapFactory
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.graphics.painter.BitmapPainter
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.imageResource
import org.example.project.R
import java.io.File
@Composable
actual fun ImageFromPath(path: String, modifier: Modifier) {
val imageBitmap: ImageBitmap? = when {
path.isEmpty() -> {
ImageBitmap.imageResource(id = R.drawable.basic_photo)
}
else -> {
val file = File(path)
if (file.exists()) {
val bitmap = BitmapFactory.decodeFile(file.absolutePath)
bitmap?.asImageBitmap()
} else null
}
}
if (imageBitmap != null) {
Image(
painter = BitmapPainter(imageBitmap),
contentDescription = null,
modifier = modifier,
contentScale = ContentScale.Crop
)
} else {
Box(modifier = modifier.fillMaxSize())
}
}

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: 10 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,10 @@
package org.example.project.ViewModel
import androidx.compose.runtime.Composable
@Composable
expect fun DatePickerField(
onDateSelected: (String) -> Unit,
trigger: Boolean,
onDismissRequest: () -> Unit
)

View File

@ -0,0 +1,106 @@
package org.example.project.ViewModel
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.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.DropdownMenu
import androidx.compose.material.DropdownMenuItem
import androidx.compose.material.Icon
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowDropDown
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.dp
@Composable
fun FieldWithDropdown(
label: String,
options: List<String>,
selectedOption: String,
onOptionSelected: (String) -> Unit,
fontSize: TextUnit,
labelWidth: Float
) {
var expanded by remember { mutableStateOf(false) }
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center,
modifier = Modifier.fillMaxWidth()
) {
Box(modifier = Modifier.weight(labelWidth)) {
Text(
text = label,
color = Color.DarkGray,
textAlign = TextAlign.Start,
fontSize = fontSize,
)
}
Box(
modifier = Modifier
.weight(1f)
.fillMaxWidth()
.background(Color.White, shape = RoundedCornerShape(4.dp))
.border(
width = 1.dp,
color = Color(0xFFCCCCCC),
shape = RoundedCornerShape(4.dp)
)
.clickable { expanded = true }
.padding(12.dp)
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween,
modifier = Modifier.fillMaxWidth()
) {
Text(
text = selectedOption.ifEmpty { "..." },
fontSize = fontSize,
color = if (selectedOption.isEmpty()) Color.LightGray else Color.Black
)
Icon(
imageVector = Icons.Default.ArrowDropDown,
contentDescription = "Dropdown Arrow",
tint = Color.Gray
)
}
DropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false },
modifier = Modifier
.background(Color.White)
.fillMaxWidth()
) {
options.forEach { option ->
DropdownMenuItem(
onClick = {
onOptionSelected(option)
expanded = false
}
) {
Text(option, fontSize = fontSize, color = Color.Black)
}
}
}
}
}
}

View File

@ -0,0 +1,71 @@
package org.example.project.ViewModel
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.material.OutlinedTextField
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.TextUnit
@Composable
fun FieldWithLabel(
label: String,
value: String,
onValueChange: (String) -> Unit,
placeholder: String,
fontSize: TextUnit,
labelWidth: Float,
enabled: Boolean = true,
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center,
modifier = Modifier.fillMaxWidth()
) {
Box(modifier = Modifier.weight(labelWidth)) {
Text(
text = label,
color = Color.DarkGray,
textAlign = TextAlign.Start,
fontSize = fontSize,
modifier = Modifier
)
}
OutlinedTextField(
value = value,
onValueChange = onValueChange,
placeholder = {
if (placeholder.isNotEmpty()) {
Text(
text = placeholder,
fontSize = fontSize,
color = Color.LightGray
)
}
},
textStyle = androidx.compose.ui.text.TextStyle(
fontSize = fontSize,
color = Color.Black
),
enabled = enabled,
colors = androidx.compose.material.TextFieldDefaults.outlinedTextFieldColors(
backgroundColor = Color.White,
cursorColor = Color.Black,
textColor = Color.Black,
placeholderColor = Color.LightGray,
focusedBorderColor = Color(0xFFCCCCCC),
unfocusedBorderColor = Color(0xFFCCCCCC),
disabledBorderColor = Color(0xFFCCCCCC)
),
modifier = Modifier.weight(1f).wrapContentWidth().fillMaxWidth()
)
}
}

View File

@ -0,0 +1,85 @@
package org.example.project.ViewModel
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.OutlinedTextField
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.TextUnit
@Composable
fun FieldWithLabelInt(
label: String,
value: Int,
onValueChange: (Int) -> Unit,
placeholder: String,
fontSize: TextUnit,
labelWidth: Float,
enabled: Boolean = true,
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center,
modifier = Modifier.fillMaxWidth()
) {
Box(modifier = Modifier.weight(labelWidth)) {
Text(
text = label,
color = Color.DarkGray,
textAlign = TextAlign.Start,
fontSize = fontSize,
)
}
OutlinedTextField(
value = value.toString(),
onValueChange = { newValue ->
val intValue = newValue.toIntOrNull()
if (intValue != null) {
onValueChange(intValue)
}
},
placeholder = {
if (placeholder.isNotEmpty()) {
Text(
text = placeholder,
fontSize = fontSize,
color = Color.LightGray
)
}
},
textStyle = androidx.compose.ui.text.TextStyle(
fontSize = fontSize,
color = Color.Black
),
enabled = enabled,
colors = androidx.compose.material.TextFieldDefaults.outlinedTextFieldColors(
backgroundColor = Color.White,
cursorColor = Color.Black,
textColor = Color.Black,
placeholderColor = Color.LightGray,
focusedBorderColor = Color(0xFFCCCCCC),
unfocusedBorderColor = Color(0xFFCCCCCC),
disabledBorderColor = Color(0xFFCCCCCC)
),
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Number,
imeAction = ImeAction.Done
),
modifier = Modifier
.weight(1f)
.wrapContentWidth()
.fillMaxWidth()
)
}
}

View File

@ -0,0 +1,7 @@
package org.example.project.ViewModel
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
@Composable
expect fun GetPath(onPathSelected: (String) -> Unit)

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,7 @@
package org.example.project.ViewModel
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
@Composable
expect fun ImageFromPath(path: 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

@ -6,16 +6,21 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import java.time.temporal.ChronoUnit
import java.util.Locale
class TimerViewModel : ViewModel() {
private val _remainingTime = MutableStateFlow("18 дней 17 часов и 10 минут до старта марафона")
val remainingTime: StateFlow<String> = _remainingTime
init {
startTimer()
}
private val _remainingTime = MutableStateFlow("18 дней 17 часов и 10 минут до старта марафона")
val remainingTime: StateFlow<String> = _remainingTime
private fun startTimer() {
viewModelScope.launch {
var remainingMillis = (18 * 24 * 60 * 60 * 1000) + (17 * 60 * 60 * 1000) + (10 * 60 * 1000)

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,346 @@
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
.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()
)
}
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()
)
}
}
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()
)
}
}
}
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

@ -0,0 +1,217 @@
package org.example.project.ui.Screens
import androidx.compose.foundation.background
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.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
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.MaterialTheme
import androidx.compose.material.Scaffold
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
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.TimerViewModel
class ConfirmRunnerScreen(private val timerViewModel: TimerViewModel, private val idRunner: Int) :
Screen {
@Composable
override fun Content() {
val navigator = LocalNavigator.currentOrThrow
Scaffold(
topBar = { ConfirmRunnerTopBar() },
bottomBar = { ConfirmRunnerBottomBar(timerViewModel = timerViewModel) }
) { paddingValues ->
Box(
modifier = Modifier.padding(paddingValues)
) {
BoxWithConstraints(
modifier = Modifier
.fillMaxWidth()
.align(Alignment.Center)
.padding(horizontal = 100.dp)
) {
val fontSizeFirst = (maxWidth.value / 30).sp
val fontSizeSecond = (maxWidth.value / 40).sp
Column(
modifier = Modifier
.fillMaxWidth().padding(bottom = 16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Spacer(modifier = Modifier.weight(0.2f))
Box(modifier = Modifier.fillMaxWidth()) {
Text(
text = "Спасибо за вашу регистрацию в качестве бегуна!",
color = Color.Gray,
textAlign = TextAlign.Center,
fontSize = fontSizeFirst,
modifier = Modifier.align(Alignment.Center)
)
}
Spacer(modifier = Modifier.weight(0.2f))
Box(modifier = Modifier.fillMaxWidth()) {
Text(
text = "Спасибо за вашу регистрацию в качестве бегуна в Marathon Skills 2016!\n С вами свяжутся по поводу оплаты.",
color = Color.Black,
textAlign = TextAlign.Center,
fontSize = fontSizeFirst,
modifier = Modifier.align(Alignment.Center)
)
}
Spacer(modifier = Modifier.weight(0.2f))
Button(
onClick = { navigator.push(InfoRunnerScreen(timerViewModel, idRunner)) },
modifier = Modifier
.fillMaxWidth()
.height(48.dp),
colors = ButtonDefaults.buttonColors(
backgroundColor = Color.LightGray,
contentColor = Color.Black
),
shape = RoundedCornerShape(15.dp)
) {
Text("Ок", fontSize = fontSizeSecond)
}
Spacer(modifier = Modifier.weight(1f))
}
}
}
}
}
@Composable
private fun ConfirmRunnerTopBar() {
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 = { },
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 ConfirmRunnerBottomBar(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

@ -0,0 +1,234 @@
package org.example.project.ui.Screens
import androidx.compose.foundation.background
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.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
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.MaterialTheme
import androidx.compose.material.Scaffold
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
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.TimerViewModel
class ConfirmSponsorScreen(private val timerViewModel: TimerViewModel, private val sumSpons: String, private val runner: String, private val blagot: String) :
Screen {
@Composable
override fun Content() {
val navigator = LocalNavigator.currentOrThrow
Scaffold(
topBar = { ConfirmSponsorTopBar() },
bottomBar = { ConfirmSponsorBottomBar(timerViewModel = timerViewModel) }
) { paddingValues ->
Box(
modifier = Modifier.padding(paddingValues)
) {
BoxWithConstraints(
modifier = Modifier
.fillMaxWidth()
.align(Alignment.Center)
.padding(horizontal = 100.dp)
) {
val fontSize = (maxWidth.value / 60).sp
val fontSizeFirst = (maxWidth.value / 30).sp
val fontSizeSecond = (maxWidth.value / 40).sp
val fontSizeThird = (maxWidth.value / 50).sp
val fontSizeFourth = (maxWidth.value / 10).sp
val fontSizeFiveth = (maxWidth.value / 20).sp
Column(
modifier = Modifier
.fillMaxWidth().padding(bottom = 16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Spacer(modifier = Modifier.weight(0.1f))
Box(modifier = Modifier.fillMaxWidth()) {
Text(
text = "Спасибо за вашу спонсорскую поддержку!",
color = Color.Gray,
textAlign = TextAlign.Center,
fontSize = fontSizeFirst,
modifier = Modifier.align(Alignment.Center)
)
}
Spacer(modifier = Modifier.weight(0.1f))
Box(modifier = Modifier.fillMaxWidth()) {
Text(
text = "Спасибо за поддержку бегуна в Marathon Skills 2016! Ваше пожертвование пойдёт в его благотворительную организацию",
color = Color.Black,
textAlign = TextAlign.Center,
fontSize = fontSizeFirst,
modifier = Modifier.align(Alignment.Center)
)
}
Spacer(modifier = Modifier.weight(0.1f))
Box(modifier = Modifier.fillMaxWidth()) {
Text(
text = runner,
color = Color.Black,
textAlign = TextAlign.Center,
fontSize = fontSizeFirst,
modifier = Modifier.align(Alignment.Center)
)
}
Spacer(modifier = Modifier.weight(0.1f))
Box(modifier = Modifier.fillMaxWidth()) {
Text(
text = blagot,
color = Color.LightGray,
textAlign = TextAlign.Center,
fontSize = fontSizeFiveth,
modifier = Modifier.align(Alignment.Center)
)
}
Spacer(modifier = Modifier.weight(0.1f))
Box(modifier = Modifier.fillMaxWidth()) {
Text(
text = sumSpons,
color = Color.LightGray,
textAlign = TextAlign.Center,
fontSize = fontSizeFourth,
modifier = Modifier.align(Alignment.Center)
)
}
Spacer(modifier = Modifier.weight(0.1f))
Button(
onClick = { navigator.push(MainScreen()) },
modifier = Modifier
.fillMaxWidth()
.height(48.dp),
colors = ButtonDefaults.buttonColors(
backgroundColor = Color.LightGray,
contentColor = Color.Black
),
shape = RoundedCornerShape(15.dp)
) {
Text("Назад", fontSize = fontSizeSecond)
}
}
}
}
}
}
@Composable
private fun ConfirmSponsorTopBar() {
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 = { },
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
)
}
}
}
}
@Composable
private fun ConfirmSponsorBottomBar(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

@ -23,71 +23,88 @@ import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontStyle
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 {
@Composable
override fun Content() {
val buttonSize = Modifier
.width(400.dp)
.height(80.dp)
val navigator = LocalNavigator.currentOrThrow
Scaffold(
topBar = { RunnerTopBar() },
bottomBar = { RunnerBottomBar(timerViewModel = timerViewModel) }
) { paddingValues ->
Box(
modifier = Modifier
.padding(paddingValues)
.fillMaxSize()
) {
Column(
BoxWithConstraints(
modifier = Modifier
.fillMaxWidth()
.align(Alignment.Center)
.padding(horizontal = 30.dp),
horizontalAlignment = Alignment.CenterHorizontally,
.padding(horizontal = 100.dp)
) {
Button(
onClick = { },
modifier = buttonSize,
colors = ButtonDefaults.buttonColors(
backgroundColor = Color.LightGray,
contentColor = Color.Black
),
shape = RoundedCornerShape(15.dp)
) {
Text("Я участвовал ранее",
fontSize = 16.sp
)
}
val fontSize = (maxWidth.value / 25).sp
Spacer(modifier = Modifier.height(16.dp))
Button(
onClick = { },
modifier = buttonSize,
colors = ButtonDefaults.buttonColors(
backgroundColor = Color.LightGray,
contentColor = Color.Black
),
shape = RoundedCornerShape(15.dp)
Column(
modifier = Modifier
.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text("Я новый участник",
fontSize = 16.sp
)
Spacer(Modifier.weight(1f))
Button(
onClick = { navigator.push(LoginScreen(timerViewModel)) },
modifier = Modifier
.fillMaxWidth()
.weight(1f),
colors = ButtonDefaults.buttonColors(
backgroundColor = Color.LightGray,
contentColor = Color.Black
),
shape = RoundedCornerShape(15.dp)
) {
Text(
"Я участвовал ранее",
fontSize = fontSize
)
}
Spacer(modifier = Modifier.weight(0.25f))
Button(
onClick = { navigator.push(RegRunnerScreen(timerViewModel)) },
modifier = Modifier
.fillMaxWidth()
.weight(1f),
colors = ButtonDefaults.buttonColors(
backgroundColor = Color.LightGray,
contentColor = Color.Black
),
shape = RoundedCornerShape(15.dp)
) {
Text(
"Я новый участник",
fontSize = fontSize
)
}
Spacer(Modifier.weight(1f))
}
}
Button(
onClick = { },
onClick = { navigator.push(LoginScreen(timerViewModel)) },
modifier = Modifier
.align(Alignment.BottomEnd)
.height(65.dp)
@ -108,61 +125,85 @@ class RunnerScreen(private val timerViewModel: TimerViewModel) : Screen {
private fun RunnerTopBar() {
val navigator = LocalNavigator.currentOrThrow
Row(
modifier = Modifier
.fillMaxWidth()
.background(Color.DarkGray)
.padding(16.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
Button(
onClick = { navigator.pop() },
colors = ButtonDefaults.buttonColors(
backgroundColor = Color.LightGray,
contentColor = Color.Black
),
elevation = null,
shape = RoundedCornerShape(15.dp),
Box {
BoxWithConstraints(
modifier = Modifier
.wrapContentWidth()
.fillMaxWidth()
.align(Alignment.Center)
) {
Text(text = "Назад",
color = Color.Black,
)
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.pop() },
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))
}
}
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 = MaterialTheme.typography.h4.fontSize,
color = Color.White
)
Spacer(modifier = Modifier.width(64.dp))
}
}
@Composable
private fun RunnerBottomBar(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)
Column(
modifier = Modifier
.fillMaxWidth()
.background(Color.DarkGray)
.padding(8.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = remainingTime,
color = Color.White,
fontSize = fontSize
)
}
}
}
}
}

View File

@ -0,0 +1,466 @@
package org.example.project.ui.Screens
import androidx.compose.foundation.background
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.fillMaxWidth
import androidx.compose.foundation.layout.padding
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.MaterialTheme
import androidx.compose.material.OutlinedTextField
import androidx.compose.material.Scaffold
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
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.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() },
bottomBar = { ForSposnorBottomBar(timerViewModel = timerViewModel) }
) { paddingValues ->
Box(
modifier = Modifier.padding(paddingValues)
) {
BoxWithConstraints(
modifier = Modifier
.fillMaxWidth()
.align(Alignment.Center)
.padding(horizontal = 100.dp)
) {
val fontSizeFirst = (maxWidth.value / 30).sp
val fontSizeSecond = (maxWidth.value / 40).sp
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("") }
var runner by remember { mutableStateOf("") }
var cardName by remember { mutableStateOf("") }
var cardNum by remember { mutableStateOf("") }
var srokM by remember { mutableStateOf("") }
var srokY by remember { mutableStateOf("") }
var cvc by remember { mutableStateOf("") }
var sumChangStr by remember { mutableStateOf("10")}
var sumChang by remember { mutableStateOf(sumChangStr.toInt()) }
var sumSpons by remember { mutableStateOf(0)}
Column(
modifier = Modifier
.fillMaxWidth().padding(bottom = 16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
text = "Спонсор бегуна",
color = Color.DarkGray,
textAlign = TextAlign.Center,
fontSize = fontSizeFirst,
modifier = Modifier.fillMaxWidth()
)
Spacer(Modifier.weight(0.1f))
Text(
text = "Пожалуйста выберите бегуна, которого вы хотели бы спонсировать и сумму, которую вы хотели бы спонсировать. Спасибо за вашу поддержку бегунов и их благотворительных учреждений.",
color = Color.DarkGray,
textAlign = TextAlign.Center,
fontSize = fontSizeSecond,
modifier = Modifier.fillMaxWidth(),
)
Spacer(Modifier.weight(0.2f))
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(16.dp)
) {
Column(modifier = Modifier.weight(1f),) {
Spacer(modifier = Modifier.weight(0.1f))
Box(modifier = Modifier.fillMaxWidth()) {
Text(
text = "Информация о спонсоре",
color = Color.LightGray,
textAlign = TextAlign.Center,
fontSize = fontSizeFirst,
modifier = Modifier.align(Alignment.Center)
)
}
Spacer(modifier = Modifier.weight(0.1f))
FieldWithLabel(
label = "Ваше имя:",
value = fio,
onValueChange = { fio = it },
placeholder = "Ваше имя",
fontSize = fontSizeSecond,
labelWidth = labelWidth,
)
Spacer(modifier = Modifier.weight(0.1f))
FieldWithDropdown(
label = "Бегун:",
options = runnersNames,
selectedOption = runner,
onOptionSelected = { runner = it },
fontSize = fontSizeSecond,
labelWidth = labelWidth
)
Spacer(modifier = Modifier.weight(0.1f))
FieldWithLabel(
label = "Карта:",
value = cardName,
onValueChange = { cardName = it },
placeholder = "Владелец карты",
fontSize = fontSizeSecond,
labelWidth = labelWidth,
)
Spacer(modifier = Modifier.weight(0.1f))
FieldWithLabel(
label = "Номер карты#:",
value = cardNum,
onValueChange = { cardNum = it },
placeholder = "...",
fontSize = fontSizeSecond,
labelWidth = labelWidth,
)
Spacer(modifier = Modifier.weight(0.1f))
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.fillMaxWidth()
) {
Text(
text = "Срок действия:",
fontSize = fontSizeSecond,
color = Color.Black,
modifier = Modifier.weight(labelWidth)
)
OutlinedTextField(
value = srokM,
onValueChange = { srokM = it },
placeholder = { Text("MM", fontSize = fontSizeSecond) },
textStyle = androidx.compose.ui.text.TextStyle(
fontSize = fontSizeSecond,
color = Color.Black
),
modifier = Modifier
.weight((1f - labelWidth) / 2)
.padding(end = 4.dp),
singleLine = true
)
OutlinedTextField(
value = srokY,
onValueChange = { srokY = it },
placeholder = { Text("YY", fontSize = fontSizeSecond) },
textStyle = androidx.compose.ui.text.TextStyle(
fontSize = fontSizeSecond,
color = Color.Black
),
modifier = Modifier
.weight((1f - labelWidth) / 2)
.padding(start = 4.dp),
singleLine = true
)
}
Spacer(modifier = Modifier.weight(0.1f))
FieldWithLabel(
label = "CVC:",
value = cvc,
onValueChange = { cvc = it },
placeholder = "...",
fontSize = fontSizeSecond,
labelWidth = labelWidth,
)
}
Column(modifier = Modifier.weight(1f),) {
Spacer(modifier = Modifier.weight(0.1f))
Box(modifier = Modifier.fillMaxWidth()) {
Text(
text = "Благотворительность",
color = Color.LightGray,
textAlign = TextAlign.Center,
fontSize = fontSizeFirst,
modifier = Modifier.align(Alignment.Center)
)
}
Spacer(modifier = Modifier.weight(0.1f))
FieldWithDropdown(
label = "",
options = fondsNames,
selectedOption = selectedFondName,
onOptionSelected = { selectedFondName = it },
fontSize = fontSizeSecond,
labelWidth = 0.5f
)
Spacer(modifier = Modifier.weight(0.5f))
Box(modifier = Modifier.fillMaxWidth()) {
Text(
text = "Сумма пожертвования",
color = Color.LightGray,
textAlign = TextAlign.Center,
fontSize = fontSizeFirst,
modifier = Modifier.align(Alignment.Center)
)
}
Spacer(modifier = Modifier.weight(0.1f))
Box(modifier = Modifier.fillMaxWidth()) {
Text(
text = "$" + sumSpons.toString(),
color = Color.LightGray,
textAlign = TextAlign.Center,
fontSize = fontSizeFourth,
modifier = Modifier.align(Alignment.Center)
)
}
Spacer(modifier = Modifier.weight(0.1f))
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.fillMaxWidth()
) {
Button(
modifier = Modifier
.weight(0.2f)
.aspectRatio(1f),
onClick = {
sumSpons -= sumChang
},
shape = RoundedCornerShape(8.dp),
colors = ButtonDefaults.buttonColors(
backgroundColor = Color.LightGray,
contentColor = Color.Black
),
) {
Text("-", fontSize = fontSizeSecond)
}
OutlinedTextField(
value = sumChangStr,
onValueChange = {
sumChangStr = it
sumChang = it.toIntOrNull() ?: 0
},
placeholder = { Text("...", fontSize = fontSizeSecond) },
textStyle = androidx.compose.ui.text.TextStyle(
fontSize = fontSizeSecond,
color = Color.Black,
textAlign = TextAlign.Center
),
modifier = Modifier
.weight(0.6f)
.padding(horizontal = 4.dp),
singleLine = true
)
Button(
modifier = Modifier
.weight(0.2f)
.aspectRatio(1f),
onClick = {
sumSpons += sumChang
},
shape = RoundedCornerShape(8.dp),
colors = ButtonDefaults.buttonColors(
backgroundColor = Color.LightGray,
contentColor = Color.Black
),
) {
Text("+", fontSize = fontSizeSecond)
}
}
Spacer(modifier = Modifier.weight(0.5f))
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceEvenly,
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 8.dp)
) {
Button(
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,
contentColor = Color.Black
),
shape = RoundedCornerShape(15.dp)
) {
Text("Заплатить", fontSize = fontSizeThird)
}
Spacer(modifier = Modifier.weight(0.1f))
Button(
onClick = { navigator.push(MainScreen()) },
modifier = Modifier.weight(1f),
colors = ButtonDefaults.buttonColors(
backgroundColor = Color.LightGray,
contentColor = Color.Black
),
shape = RoundedCornerShape(15.dp)
) {
Text("Отмена", fontSize = fontSizeThird)
}
}
}
}
}
}
}
}
}
@Composable
private fun ForSponsorTopBar() {
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
)
}
}
}
}
@Composable
private fun ForSposnorBottomBar(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

@ -0,0 +1,215 @@
package org.example.project.ui.Screens
import androidx.compose.foundation.background
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.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
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.MaterialTheme
import androidx.compose.material.Scaffold
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
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.InfoButton
import org.example.project.ViewModel.TimerViewModel
class InfoRunnerScreen(private val timerViewModel: TimerViewModel, private val idRunner: Int) : Screen {
@Composable
override fun Content() {
val navigator = LocalNavigator.currentOrThrow
Scaffold(
topBar = { InfoRunnerTopBar() },
bottomBar = { InfoRunnerBottomBar(timerViewModel = timerViewModel) }
) { paddingValues ->
Box(
modifier = Modifier
.padding(paddingValues)
) {
BoxWithConstraints(
modifier = Modifier
.fillMaxWidth()
.align(Alignment.Center)
.padding(horizontal = 100.dp)
) {
val fontSize = (maxWidth.value / 25).sp
val fontSizeButton = (maxWidth.value / 40).sp
Column(
modifier = Modifier
.padding(16.dp)
.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.SpaceBetween
) {
Text(
text = "Подробная информация",
color = Color.DarkGray,
textAlign = TextAlign.Center,
fontSize = fontSize,
)
Row(
modifier = Modifier
.fillMaxWidth()
.weight(1f),
horizontalArrangement = Arrangement.SpaceEvenly,
verticalAlignment = Alignment.CenterVertically
) {
Column(
modifier = Modifier
.weight(1f)
.padding(end = 8.dp),
verticalArrangement = Arrangement.spacedBy(16.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
InfoButton("Регистрация на марафон", fontSizeButton, {navigator.push(RegMaraphonScreen(timerViewModel, idRunner))})
InfoButton("Редактирование профиля", fontSizeButton, {})
InfoButton("Контакты", fontSizeButton, {})
}
Column(
modifier = Modifier
.weight(1f)
.padding(start = 8.dp),
verticalArrangement = Arrangement.spacedBy(16.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
InfoButton("Мои результаты", fontSizeButton, {})
InfoButton("Мои спонсоры", fontSizeButton, {})
}
}
}
}
}
}
}
@Composable
private fun InfoRunnerTopBar() {
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 InfoRunnerBottomBar(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

@ -0,0 +1,258 @@
package org.example.project.ui.Screens
import androidx.compose.foundation.background
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.fillMaxWidth
import androidx.compose.foundation.layout.padding
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.MaterialTheme
import androidx.compose.material.Scaffold
import androidx.compose.material.Text
import androidx.compose.ui.Modifier
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
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.FieldWithLabel
import org.example.project.ViewModel.TimerViewModel
import org.example.project.ViewModel.UserViewModel
class LoginScreen(private val timerViewModel: TimerViewModel) : Screen {
@Composable
override fun Content() {
val navigator = LocalNavigator.currentOrThrow
Scaffold(
topBar = { LoginTopBar() },
bottomBar = { LoginBottomBar(timerViewModel = timerViewModel) }
) { paddingValues ->
val viewModel = UserViewModel()
val users = viewModel.getUsers()
Box(
modifier = Modifier.padding(paddingValues)
) {
BoxWithConstraints(
modifier = Modifier
.fillMaxWidth()
.align(Alignment.Center)
.padding(horizontal = 100.dp)
) {
val fontSize = (maxWidth.value / 25).sp
val fontSizeFirst = (maxWidth.value / 20).sp
val fontSizeSecond = (maxWidth.value / 35).sp
val labelWidth = 0.25f
var email by remember { mutableStateOf("") }
var password by remember { mutableStateOf("") }
Column(
modifier = Modifier
.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Spacer(Modifier.weight(0.25f))
Text(
text = "Форма авторизации",
color = Color.DarkGray,
textAlign = TextAlign.Center,
fontSize = fontSizeFirst,
modifier = Modifier.fillMaxWidth()
)
Spacer(Modifier.weight(0.25f))
Text(
text = "Пожалуйста, авторизуйтесь в системе, используя\n ваш адрес электронной почты и пароль",
color = Color.DarkGray,
textAlign = TextAlign.Center,
fontSize = fontSizeSecond,
modifier = Modifier.fillMaxWidth(),
)
Spacer(Modifier.weight(0.25f))
FieldWithLabel(
label = "Email:",
value = email,
onValueChange = { email = it },
placeholder = "Enter your email address",
fontSize = fontSize,
labelWidth = labelWidth,
)
Spacer(Modifier.weight(0.25f))
FieldWithLabel(
label = "Password:",
value = password,
onValueChange = { password = it },
placeholder = "Enter your password",
fontSize = fontSize,
labelWidth = labelWidth,
)
Spacer(Modifier.weight(0.25f))
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center
) {
Button(
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),
colors = ButtonDefaults.buttonColors(
backgroundColor = Color.LightGray,
contentColor = Color.Black
),
shape = RoundedCornerShape(15.dp)
) {
Text(
"Login",
fontSize = fontSize
)
}
Spacer(Modifier.weight(0.25f))
Button(
onClick = { navigator.push(MainScreen()) },
modifier = Modifier
.fillMaxWidth()
.weight(1f),
colors = ButtonDefaults.buttonColors(
backgroundColor = Color.LightGray,
contentColor = Color.Black
),
shape = RoundedCornerShape(15.dp)
) {
Text(
"Cancel",
fontSize = fontSize
)
}
}
Spacer(Modifier.weight(1f))
}
}
}
}
}
@Composable
private fun LoginTopBar() {
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))
}
}
}
}
@Composable
private fun LoginBottomBar(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

@ -17,7 +17,6 @@ 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 kotlinx.coroutines.delay
class MainScreen : Screen {
@ -26,10 +25,6 @@ class MainScreen : Screen {
val navigator = LocalNavigator.currentOrThrow
val timerViewModel = TimerViewModel()
val buttonSize = Modifier
.width(400.dp)
.height(80.dp)
Scaffold(
topBar = { MainWindowTopBar() },
bottomBar = { MainWindowBottomBar(timerViewModel) }
@ -37,65 +32,73 @@ class MainScreen : Screen {
Box(
modifier = Modifier
.padding(paddingValues)
.fillMaxSize()
) {
Column(
BoxWithConstraints(
modifier = Modifier
.fillMaxWidth()
.align(Alignment.Center)
.padding(horizontal = 30.dp),
horizontalAlignment = Alignment.CenterHorizontally,
.padding(horizontal = 100.dp)
) {
Button(
onClick = { navigator.push(RunnerScreen(timerViewModel)) },
modifier = buttonSize,
colors = ButtonDefaults.buttonColors(
backgroundColor = Color.LightGray,
contentColor = Color.Black
),
shape = RoundedCornerShape(15.dp)
val fontSize = (maxWidth.value / 25).sp
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text("Я хочу стать бегуном",
fontSize = 16.sp
)
}
Spacer(modifier = Modifier.weight(0.25f))
Spacer(modifier = Modifier.height(16.dp))
Button(
onClick = { navigator.push(RunnerScreen(timerViewModel)) },
modifier = Modifier
.fillMaxWidth()
.weight(1f),
colors = ButtonDefaults.buttonColors(
backgroundColor = Color.LightGray,
contentColor = Color.Black
),
shape = RoundedCornerShape(15.dp)
) {
Text("Я хочу стать бегуном", fontSize = fontSize)
}
Button(
onClick = { },
modifier = buttonSize,
colors = ButtonDefaults.buttonColors(
backgroundColor = Color.LightGray,
contentColor = Color.Black
),
shape = RoundedCornerShape(15.dp)
) {
Text("Я хочу стать спонсором бегуна",
fontSize = 16.sp
)
}
Spacer(modifier = Modifier.height(16.dp))
Spacer(modifier = Modifier.height(16.dp))
Button(
onClick = { navigator.push(ForSponsorScreen(timerViewModel))},
modifier = Modifier
.fillMaxWidth()
.weight(1f),
colors = ButtonDefaults.buttonColors(
backgroundColor = Color.LightGray,
contentColor = Color.Black
),
shape = RoundedCornerShape(15.dp)
) {
Text("Я хочу стать спонсором бегуна", fontSize = fontSize)
}
Button(
onClick = { navigator.push(MoreInfoScreen(timerViewModel)) },
modifier = buttonSize,
colors = ButtonDefaults.buttonColors(
backgroundColor = Color.LightGray,
contentColor = Color.Black
),
shape = RoundedCornerShape(15.dp)
) {
Text(text = "Я хочу узнать больше о событии",
fontSize = 16.sp
)
Spacer(modifier = Modifier.height(16.dp))
Button(
onClick = { navigator.push(MoreInfoScreen(timerViewModel)) },
modifier = Modifier
.fillMaxWidth()
.weight(1f),
colors = ButtonDefaults.buttonColors(
backgroundColor = Color.LightGray,
contentColor = Color.Black
),
shape = RoundedCornerShape(15.dp)
) {
Text("Я хочу узнать больше о событии", fontSize = fontSize)
}
Spacer(modifier = Modifier.weight(0.5f))
}
}
Button(
onClick = { },
onClick = { navigator.push(LoginScreen(timerViewModel)) },
modifier = Modifier
.align(Alignment.BottomEnd)
.height(65.dp)
@ -106,7 +109,7 @@ class MainScreen : Screen {
),
shape = RoundedCornerShape(15.dp)
) {
Text(text = "Login", color = Color.Black)
Text("Login")
}
}
}
@ -114,29 +117,39 @@ class MainScreen : Screen {
@Composable
private fun MainWindowTopBar() {
Column(
modifier = Modifier
.fillMaxWidth()
.background(Color.DarkGray)
.padding(32.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = "MARATHON SKILLS 2016",
fontSize = MaterialTheme.typography.h4.fontSize,
fontWeight = FontWeight.Bold,
color = Color.White
)
Box {
BoxWithConstraints(
modifier = Modifier
.fillMaxWidth()
.align(Alignment.Center)
) {
val fontSize = (maxWidth.value / 25).sp
Spacer(modifier = Modifier.height(20.dp))
Column(
modifier = Modifier
.fillMaxWidth()
.background(Color.DarkGray)
.padding(32.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = "MARATHON SKILLS 2016",
fontSize = fontSize,
fontWeight = FontWeight.Bold,
color = Color.White
)
Text(
text = "Москва, Россия\nсреда 21 октября 2016",
textAlign = TextAlign.Center,
fontSize = MaterialTheme.typography.subtitle1.fontSize,
fontStyle = FontStyle.Italic,
color = Color.LightGray
)
Spacer(modifier = Modifier.height(20.dp))
Text(
text = "Москва, Россия\nсреда 21 октября 2016",
textAlign = TextAlign.Center,
fontSize = fontSize,
fontStyle = FontStyle.Italic,
color = Color.LightGray
)
}
}
}
}
@ -144,15 +157,25 @@ class MainScreen : Screen {
private fun MainWindowBottomBar(timerViewModel: TimerViewModel) {
val remainingTime = timerViewModel.remainingTime.collectAsState().value
Column(
modifier = Modifier
.fillMaxWidth()
.background(Color.DarkGray)
.padding(8.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = remainingTime,
color = Color.White)
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

@ -3,12 +3,12 @@ package org.example.project.ui.Screens
import androidx.compose.foundation.background
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.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentWidth
@ -23,7 +23,6 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
@ -31,6 +30,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
@ -38,133 +38,69 @@ class MoreInfoScreen(private val timerViewModel: TimerViewModel) : Screen {
@Composable
override fun Content() {
val buttonSize = Modifier
.width(300.dp)
.height(80.dp)
val navigator = LocalNavigator.currentOrThrow
Scaffold(
topBar = { InfoTopBar() },
bottomBar = { InfoBottomBar(timerViewModel = timerViewModel) }
) { paddingValues ->
Box(
modifier = Modifier
.padding(paddingValues)
.fillMaxSize()
) {
Column(
BoxWithConstraints(
modifier = Modifier
.padding(16.dp)
.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.SpaceBetween
.fillMaxWidth()
.align(Alignment.Center)
.padding(horizontal = 100.dp)
) {
Text(
text = "Подробная информация",
color = Color.DarkGray,
textAlign = TextAlign.Center,
fontSize = MaterialTheme.typography.h5.fontSize,
)
val fontSize = (maxWidth.value / 25).sp
val fontSizeButton = (maxWidth.value / 40).sp
Row(
Column(
modifier = Modifier
.fillMaxWidth()
.weight(1f),
horizontalArrangement = Arrangement.SpaceEvenly,
verticalAlignment = Alignment.CenterVertically
.padding(16.dp)
.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.SpaceBetween
) {
Column(
Text(
text = "Подробная информация",
color = Color.DarkGray,
textAlign = TextAlign.Center,
fontSize = fontSize,
)
Row(
modifier = Modifier
.weight(1f)
.padding(end = 8.dp),
verticalArrangement = Arrangement.spacedBy(16.dp),
horizontalAlignment = Alignment.CenterHorizontally
.fillMaxWidth()
.weight(1f),
horizontalArrangement = Arrangement.SpaceEvenly,
verticalAlignment = Alignment.CenterVertically
) {
Button(
onClick = { },
modifier = buttonSize,
colors = ButtonDefaults.buttonColors(
backgroundColor = Color.LightGray,
contentColor = Color.Black
),
shape = RoundedCornerShape(15.dp)
Column(
modifier = Modifier
.weight(1f)
.padding(end = 8.dp),
verticalArrangement = Arrangement.spacedBy(16.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = "Marathon Skills 2016", fontSize = 16.sp,
fontStyle = FontStyle.Italic
)
InfoButton("Marathon Skills 2016", fontSizeButton, {navigator.push(AboutMarathonScreen(timerViewModel))})
InfoButton("Предыдущие результаты", fontSizeButton, {})
InfoButton("BMI калькулятор", fontSizeButton, {})
}
Button(
onClick = { },
modifier = buttonSize,
colors = ButtonDefaults.buttonColors(
backgroundColor = Color.LightGray,
contentColor = Color.Black
),
shape = RoundedCornerShape(15.dp)
Column(
modifier = Modifier
.weight(1f)
.padding(start = 8.dp),
verticalArrangement = Arrangement.spacedBy(16.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = "Предыдущие\nрезультаты", fontSize = 16.sp,
fontStyle = FontStyle.Italic)
}
Button(
onClick = { },
modifier = buttonSize,
colors = ButtonDefaults.buttonColors(
backgroundColor = Color.LightGray,
contentColor = Color.Black
),
shape = RoundedCornerShape(15.dp)
) {
Text(text = "BMI калькулятор", fontSize = 16.sp,
fontStyle = FontStyle.Italic)
}
}
Column(
modifier = Modifier
.weight(1f)
.padding(end = 8.dp),
verticalArrangement = Arrangement.spacedBy(16.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Button(
onClick = { },
modifier = buttonSize,
colors = ButtonDefaults.buttonColors(
backgroundColor = Color.LightGray,
contentColor = Color.Black
),
shape = RoundedCornerShape(15.dp)
) {
Text(text = "Насколько долгий\nмарафон", fontSize = 16.sp,
fontStyle = FontStyle.Italic)
}
Button(
onClick = { },
modifier = buttonSize,
colors = ButtonDefaults.buttonColors(
backgroundColor = Color.LightGray,
contentColor = Color.Black
),
shape = RoundedCornerShape(15.dp)
) {
Text(text = "Список\nблаготворительных\nорганизаций", fontSize = 16.sp,
fontStyle = FontStyle.Italic)
}
Button(
onClick = { },
modifier = buttonSize,
colors = ButtonDefaults.buttonColors(
backgroundColor = Color.LightGray,
contentColor = Color.Black
),
shape = RoundedCornerShape(15.dp)
) {
Text(text = "BMR калькулятор", fontSize = 16.sp,
fontStyle = FontStyle.Italic)
InfoButton("Насколько долгий марафон", fontSizeButton, {})
InfoButton("Список\nблаготворительных организаций", fontSizeButton, {})
InfoButton("BMR калькулятор", fontSizeButton, {})
}
}
}
@ -177,61 +113,85 @@ class MoreInfoScreen(private val timerViewModel: TimerViewModel) : Screen {
private fun InfoTopBar() {
val navigator = LocalNavigator.currentOrThrow
Row(
modifier = Modifier
.fillMaxWidth()
.background(Color.DarkGray)
.padding(16.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
Button(
onClick = { navigator.pop() },
colors = ButtonDefaults.buttonColors(
backgroundColor = Color.LightGray,
contentColor = Color.Black
),
elevation = null,
shape = RoundedCornerShape(15.dp),
Box {
BoxWithConstraints(
modifier = Modifier
.wrapContentWidth()
.fillMaxWidth()
.align(Alignment.Center)
) {
Text(text = "Назад",
color = Color.Black,
)
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.pop() },
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))
}
}
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 = MaterialTheme.typography.h4.fontSize,
color = Color.White
)
Spacer(modifier = Modifier.width(64.dp))
}
}
@Composable
private fun InfoBottomBar(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)
Column(
modifier = Modifier
.fillMaxWidth()
.background(Color.DarkGray)
.padding(8.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = remainingTime,
color = Color.White,
fontSize = fontSize
)
}
}
}
}
}

View File

@ -0,0 +1,422 @@
package org.example.project.ui.Screens
import androidx.compose.foundation.background
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.fillMaxWidth
import androidx.compose.foundation.layout.padding
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.Checkbox
import androidx.compose.material.MaterialTheme
import androidx.compose.material.RadioButton
import androidx.compose.material.Scaffold
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
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.FieldWithDropdown
import org.example.project.ViewModel.FieldWithLabelInt
import org.example.project.ViewModel.TimerViewModel
import org.example.project.ViewModel.UserViewModel
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() },
bottomBar = { RegMaraphonBottomBar(timerViewModel = timerViewModel) }
) { paddingValues ->
Box(
modifier = Modifier.padding(paddingValues)
) {
BoxWithConstraints(
modifier = Modifier
.fillMaxWidth()
.align(Alignment.Center)
.padding(horizontal = 100.dp)
) {
val fontSizeFirst = (maxWidth.value / 30).sp
val fontSizeSecond = (maxWidth.value / 40).sp
val fontSizeThird = (maxWidth.value / 50).sp
val fontSizeFourth = (maxWidth.value / 10).sp
var finalSum by remember { mutableStateOf(0) }
var previousAddonPrice by remember { mutableStateOf(0) }
var checked1 by remember { mutableStateOf(false) }
var checked2 by remember { mutableStateOf(false) }
var checked3 by remember { mutableStateOf(false) }
val options = listOf(
"Вариант А($0): Номер бегуна + RFID браслет",
"Вариант B($20): вариант A + бейсболка + бутылка воды",
"Вариант C($45): Вариант B + футболка + сувенирный буклет"
)
var fondsNames = fonds.map { it.name }
var selectedOption by remember { mutableStateOf(options[0]) }
var vznos by remember { mutableStateOf("")}
Column(
modifier = Modifier
.fillMaxWidth().padding(bottom = 16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
text = "Регистрация на марафон",
color = Color.DarkGray,
textAlign = TextAlign.Center,
fontSize = fontSizeFirst,
modifier = Modifier.fillMaxWidth()
)
Spacer(Modifier.weight(0.1f))
Text(
text = "Пожалуйста, заполните всю информацию, чтобы зарегестрироваться на Skills Marathon 2016 проводимом в Москве. Russia. С вами свяжутся после регистрации для уточнения оплаты и другой информации.",
color = Color.DarkGray,
textAlign = TextAlign.Center,
fontSize = fontSizeSecond,
modifier = Modifier.fillMaxWidth(),
)
Spacer(Modifier.weight(0.2f))
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(16.dp)
) {
Column(modifier = Modifier.weight(1f), ) {
Spacer(modifier = Modifier.weight(0.1f))
Text(
text = "Вид марафона",
color = Color.LightGray,
textAlign = TextAlign.Center,
fontSize = fontSizeFirst,
modifier = Modifier
)
Row(verticalAlignment = Alignment.CenterVertically) {
Checkbox(
checked = checked1,
onCheckedChange = { isChecked ->
checked1 = isChecked
if (isChecked) {
finalSum += 145
} else {
finalSum -= 145
}
}
)
Spacer(modifier = Modifier.width(8.dp))
Text(text = "42km Полный марафон($145)", fontSize = fontSizeSecond)
}
Row(verticalAlignment = Alignment.CenterVertically) {
Checkbox(
checked = checked2,
onCheckedChange = { isChecked ->
checked2 = isChecked
if (isChecked) {
finalSum += 75
} else {
finalSum -= 75
}
}
)
Spacer(modifier = Modifier.width(8.dp))
Text(text = "21km Поулмарафон($75)", fontSize = fontSizeSecond)
}
Row(verticalAlignment = Alignment.CenterVertically) {
Checkbox(
checked = checked3,
onCheckedChange = { isChecked ->
checked3 = isChecked
if (isChecked) {
finalSum += 20
} else {
finalSum -= 20
}
}
)
Spacer(modifier = Modifier.width(8.dp))
Text(text = "5km Малая дистанция($20)", fontSize = fontSizeSecond)
}
Text(
text = "Детали спонсорства",
color = Color.LightGray,
textAlign = TextAlign.Center,
fontSize = fontSizeFirst,
modifier = Modifier
)
FieldWithDropdown(
label = "Взнос:",
options = fondsNames,
selectedOption = vznos,
onOptionSelected = { vznos = it },
fontSize = fontSizeSecond,
labelWidth = 0.5f
)
Spacer(modifier = Modifier.weight(0.1f))
FieldWithLabelInt(
label = "Сумма взноса:",
value = finalSum,
onValueChange = { finalSum = it },
placeholder = "$$$",
fontSize = fontSizeSecond,
labelWidth = 0.5f,
enabled = false
)
Spacer(modifier = Modifier.weight(0.1f))
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceEvenly,
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 8.dp)
) {
Button(
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,
contentColor = Color.Black
),
shape = RoundedCornerShape(15.dp)
) {
Text("Регистрация", fontSize = fontSizeThird)
}
Spacer(modifier = Modifier.weight(0.1f))
Button(
onClick = { navigator.push(InfoRunnerScreen(timerViewModel, userId)) },
modifier = Modifier.weight(1f),
colors = ButtonDefaults.buttonColors(
backgroundColor = Color.LightGray,
contentColor = Color.Black
),
shape = RoundedCornerShape(15.dp)
) {
Text("Отмена", fontSize = fontSizeThird)
}
}
}
Column(modifier = Modifier.weight(1f)) {
Spacer(modifier = Modifier.weight(0.1f))
Box(modifier = Modifier.fillMaxWidth()) {
Text(
text = "Варианты комплектов",
color = Color.LightGray,
textAlign = TextAlign.Center,
fontSize = fontSizeFirst,
modifier = Modifier.align(Alignment.Center)
)
}
options.forEach { text ->
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center
) {
RadioButton(
selected = (text == selectedOption),
onClick = {
val newAddonPrice = when (text) {
options[0] -> 0
options[1] -> 20
options[2] -> 45
else -> 0
}
finalSum = finalSum - previousAddonPrice + newAddonPrice
previousAddonPrice = newAddonPrice
selectedOption = text
}
)
Spacer(modifier = Modifier.weight(0.01f))
Text(text = text, fontSize = fontSizeSecond)
}
}
Spacer(modifier = Modifier.weight(0.1f))
Box(modifier = Modifier.fillMaxWidth()) {
Text(
text = "Регистрационный взнос",
color = Color.LightGray,
textAlign = TextAlign.Center,
fontSize = fontSizeFirst,
modifier = Modifier.align(Alignment.Center)
)
}
Spacer(modifier = Modifier.weight(0.1f))
Box(modifier = Modifier.fillMaxWidth()) {
Text(
text = "$" + finalSum.toString(),
color = Color.LightGray,
textAlign = TextAlign.Center,
fontSize = fontSizeFourth,
modifier = Modifier.align(Alignment.Center)
)
}
}
}
}
}
}
}
}
@Composable
private fun RegMaraphonTopBar() {
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(InfoRunnerScreen(timerViewModel, userId)) },
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 RegMaraphonBottomBar(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

@ -0,0 +1,540 @@
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.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.OutlinedTextField
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.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
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.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 {
@Composable
override fun Content() {
val viewModel = UserViewModel()
var users = viewModel.getUsers()
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,
email, password, secondPassword, name, surname, gender, photoPath, dateBirthday, country
)
}
) { paddingValues ->
Box(
modifier = Modifier.padding(paddingValues).fillMaxSize()
) {
BoxWithConstraints(
modifier = Modifier
.fillMaxWidth()
.align(Alignment.Center)
.padding(horizontal = 10.dp)
) {
val fontSize = (maxWidth.value / 60).sp
val fontSizeFirst = (maxWidth.value / 30).sp
val fontSizeSecond = (maxWidth.value / 40).sp
val labelWidth = 0.5f
Column(
modifier = Modifier
.fillMaxWidth().padding(bottom = 16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
text = "Регистрация бегуна",
color = Color.DarkGray,
textAlign = TextAlign.Center,
fontSize = fontSizeFirst,
modifier = Modifier.fillMaxWidth()
)
Spacer(Modifier.weight(0.1f))
Text(
text = "Пожалуйста, заполните всю информацию, чтобы зарегестрироваться в качестве участника",
color = Color.DarkGray,
textAlign = TextAlign.Center,
fontSize = fontSizeSecond,
modifier = Modifier.fillMaxWidth(),
)
Spacer(Modifier.weight(0.2f))
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(16.dp)
) {
Column(modifier = Modifier.weight(0.8f)) {
Spacer(modifier = Modifier.weight(0.1f))
FieldWithLabel(
label = "Email:",
value = email,
onValueChange = { email = it
println(email)},
placeholder = "Email",
fontSize = fontSize,
labelWidth = labelWidth,
)
Spacer(modifier = Modifier.weight(0.1f))
FieldWithLabel(
label = "Пароль:",
value = password,
onValueChange = { password = it },
placeholder = "Пароль",
fontSize = fontSize,
labelWidth = labelWidth,
)
Spacer(modifier = Modifier.weight(0.1f))
FieldWithLabel(
label = "Повторите пароль:",
value = secondPassword,
onValueChange = { secondPassword = it },
placeholder = "Повторите пароль",
fontSize = fontSize,
labelWidth = labelWidth,
)
Spacer(modifier = Modifier.weight(0.1f))
FieldWithLabel(
label = "Имя:",
value = name,
onValueChange = { name = it },
placeholder = "Имя",
fontSize = fontSize,
labelWidth = labelWidth,
)
Spacer(modifier = Modifier.weight(0.1f))
FieldWithLabel(
label = "Фамилия:",
value = surname,
onValueChange = { surname = it },
placeholder = "Фамилия",
fontSize = fontSize,
labelWidth = labelWidth,
)
Spacer(modifier = Modifier.weight(0.1f))
FieldWithDropdown(
label = "Пол:",
options = listOf("Мужской", "Остальное"),
selectedOption = gender,
onOptionSelected = { gender = it },
fontSize = fontSize,
labelWidth = labelWidth
)
}
Column(modifier = Modifier.weight(1f)) {
ImageFromPath(
path = photoPath,
modifier = Modifier
.weight(0.4f)
.clip(RoundedCornerShape(8.dp))
.border(1.dp, Color.Gray, RoundedCornerShape(8.dp)).align(Alignment.End)
)
Spacer(modifier = Modifier.weight(0.05f))
Column(modifier = Modifier.weight(0.3f)) {
Text(
text = "Фото файл:",
color = Color.DarkGray,
textAlign = TextAlign.Start,
fontSize = fontSize,
modifier = Modifier
)
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center,
modifier = Modifier.fillMaxWidth()
) {
OutlinedTextField(
value = photoPath,
onValueChange = {photoPath = it},
placeholder = {
Text(
text = "Photo_logo.jpg",
fontSize = fontSize,
color = Color.LightGray
)
},
textStyle = androidx.compose.ui.text.TextStyle(
fontSize = fontSize,
color = Color.Black
),
enabled = true,
colors = androidx.compose.material.TextFieldDefaults.outlinedTextFieldColors(
backgroundColor = Color.White,
cursorColor = Color.Black,
textColor = Color.Black,
placeholderColor = Color.LightGray,
focusedBorderColor = Color(0xFFCCCCCC),
unfocusedBorderColor = Color(0xFFCCCCCC),
disabledBorderColor = Color(0xFFCCCCCC)
),
modifier = Modifier.weight(0.6f).wrapContentWidth().fillMaxWidth()
)
Spacer(modifier = Modifier.weight(0.05f))
Button(
onClick = { openPicker = true},
modifier = Modifier
.fillMaxWidth()
.weight(0.5f),
colors = ButtonDefaults.buttonColors(
backgroundColor = Color.LightGray,
contentColor = Color.Black
),
shape = RoundedCornerShape(15.dp)
) {
Text(
"Просмотр",
fontSize = fontSize
)
}
}
Spacer(modifier = Modifier.weight(0.05f))
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center,
modifier = Modifier.fillMaxWidth()
) {
Box(modifier = Modifier.weight(labelWidth)) {
Text(
text = "Дата рождения",
color = Color.DarkGray,
textAlign = TextAlign.Start,
fontSize = fontSize,
modifier = Modifier
)
}
OutlinedTextField(
value = dateBirthday,
onValueChange = {dateBirthday = it},
placeholder = {
Text(
text = "...",
fontSize = fontSize,
color = Color.LightGray
)
},
textStyle = androidx.compose.ui.text.TextStyle(
fontSize = fontSize,
color = Color.Black
),
enabled = true,
colors = androidx.compose.material.TextFieldDefaults.outlinedTextFieldColors(
backgroundColor = Color.White,
cursorColor = Color.Black,
textColor = Color.Black,
placeholderColor = Color.LightGray,
focusedBorderColor = Color(0xFFCCCCCC),
unfocusedBorderColor = Color(0xFFCCCCCC),
disabledBorderColor = Color(0xFFCCCCCC)
),
modifier = Modifier.weight(0.9f).wrapContentWidth()
)
Spacer(modifier = Modifier.weight(0.05f))
Box(
modifier = Modifier
.weight(0.5f)
.fillMaxWidth()
.clip(RoundedCornerShape(15.dp))
.background(Color.LightGray)
.clickable { showDatePicker = true }
.padding(vertical = 8.dp),
contentAlignment = Alignment.Center
) {
Icon(
imageVector = Icons.Default.DateRange,
contentDescription = "Выбрать дату",
tint = Color.Black,
modifier = Modifier.size(24.dp)
)
}
}
Spacer(modifier = Modifier.weight(0.05f))
FieldWithDropdown(
label = "Страна:",
options = listOf("Russia", "Other"),
selectedOption = country,
onOptionSelected = { country = it },
fontSize = fontSize,
labelWidth = labelWidth
)
Spacer(modifier = Modifier.width(16.dp))
}
}
}
}
}
}
}
}
@Composable
private fun RegRunnerTopBar() {
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))
}
}
}
}
@Composable
private fun RegRunnerBottomBar(timerViewModel: TimerViewModel) {
val remainingTime = timerViewModel.remainingTime.collectAsState().value
Box(
modifier = Modifier
.fillMaxWidth()
.background(Color.DarkGray)
.padding(8.dp),
contentAlignment = Alignment.Center
) {
Text(
text = remainingTime,
color = Color.White,
fontSize = 16.sp
)
}
}
@Composable
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)
) {
Button(
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,
contentColor = Color.Black
),
shape = RoundedCornerShape(15.dp)
) {
Text("Регистрация")
}
Spacer(modifier = Modifier.width(16.dp))
Button(
onClick = { navigator.push(MainScreen()) },
modifier = Modifier.weight(1f),
colors = ButtonDefaults.buttonColors(
backgroundColor = Color.LightGray,
contentColor = Color.Black
),
shape = RoundedCornerShape(15.dp)
) {
Text("Отмена")
}
}
RegRunnerBottomBar(timerViewModel = timerViewModel)
}
}
}

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:5447/multidb",
driver = "org.postgresql.Driver",
user = "multidb",
password = "multidb"
)
}

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,38 @@
package org.example.project.ViewModel
import androidx.compose.runtime.*
import java.text.SimpleDateFormat
import javax.swing.*
import java.util.*
@Composable
actual fun DatePickerField(
onDateSelected: (String) -> Unit,
trigger: Boolean,
onDismissRequest: () -> Unit
) {
if (trigger) {
LaunchedEffect(Unit) {
val dialog = JDialog()
dialog.title = "Выбор даты"
val model = SpinnerDateModel()
val spinner = JSpinner(model)
val panel = JPanel()
val button = JButton("OK")
panel.add(spinner)
panel.add(button)
dialog.contentPane = panel
dialog.setSize(200, 100)
button.addActionListener {
val date = model.date
val formatted = SimpleDateFormat("dd.MM.yyyy").format(date)
onDateSelected(formatted)
dialog.dispose()
onDismissRequest()
}
dialog.isVisible = true
}
}
}

View File

@ -0,0 +1,29 @@
package org.example.project.ViewModel
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.File
import javax.swing.JFileChooser
@Composable
actual fun GetPath(onPathSelected: (String) -> Unit) {
LaunchedEffect(Unit) {
val selectedPath = withContext(Dispatchers.IO) {
val chooser = JFileChooser()
chooser.dialogTitle = "Выберите изображение"
chooser.fileSelectionMode = JFileChooser.FILES_ONLY
val result = chooser.showOpenDialog(null)
if (result == JFileChooser.APPROVE_OPTION) {
val file: File = chooser.selectedFile
file.absolutePath
} else {
""
}
}
onPathSelected(selectedPath)
}
}

View File

@ -0,0 +1,33 @@
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.FillBounds
)
}
}

View File

@ -0,0 +1,45 @@
package org.example.project.ViewModel
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.painter.BitmapPainter
import androidx.compose.ui.graphics.toComposeImageBitmap
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import org.jetbrains.skia.Image
import java.io.File
import java.nio.file.Files
@Composable
actual fun ImageFromPath(path: String, modifier: Modifier) {
val imageBitmap: ImageBitmap? = try {
if (path.isBlank()) {
val resourceStream = Thread.currentThread().contextClassLoader.getResourceAsStream("drawable/defPhoto.png")
val bytes = resourceStream.readAllBytes()
Image.makeFromEncoded(bytes).toComposeImageBitmap()
} else {
val file = File(path)
if (file.exists()) {
val bytes = Files.readAllBytes(file.toPath())
Image.makeFromEncoded(bytes).toComposeImageBitmap()
} else null
}
} catch (e: Exception) {
println("Ошибка загрузки изображения: ${e.message}")
null
}
if (imageBitmap != null) {
Image(
painter = BitmapPainter(imageBitmap),
contentDescription = null,
modifier = modifier,
contentScale = ContentScale.Crop
)
} else {
Box(modifier = modifier.fillMaxSize())
}
}

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

View File

@ -5,6 +5,7 @@ import androidx.compose.ui.window.Window
import org.example.project.App
fun main() = application {
Window(
onCloseRequest = ::exitApplication,
title = "Marathon Skills 2016"