Compare commits

...

15 Commits
master ... Lab4

Author SHA1 Message Date
2aa2e5bc60 di and pagination 2023-11-12 18:50:40 +04:00
4b7e5338ef вроде все 2023-11-01 22:08:07 +04:00
edeae3587f need to do ChangeHotel 2023-11-01 19:13:12 +04:00
6a8a539858 время сохраняется 2023-11-01 18:36:34 +04:00
71743e9166 заказы показываются 2023-11-01 13:58:14 +04:00
4c013ac345 осталось список заказов и панельку админа 2023-10-31 17:32:36 +04:00
25e1d97db5 работает все 2023-10-29 23:32:58 +04:00
2b9cd69ccb не работает ничего 2023-10-29 21:53:33 +04:00
d73bb9f1aa сдана 2023-10-29 14:23:22 +04:00
83d91169cc дезигн поправлен
потом можно исправить админ панель
2023-10-17 21:59:23 +04:00
35d89b440e впринципе все скрины есть
поправить дезигн нужно
2023-10-16 17:09:41 +04:00
9b61677603 добавила букинг
по хорошему нужно доделать дезигн всего
2023-10-05 00:29:25 +04:00
3b192d27cb first steps for hotel info 2023-10-04 16:12:27 +04:00
72c903a0b3 нужно исправить верстку входа 2023-10-03 14:45:00 +04:00
11bc140481 это только начало 2023-10-01 21:55:07 +04:00
68 changed files with 3345 additions and 52 deletions

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="17" />
<bytecodeTargetLevel target="19" />
</component>
</project>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetDropDown">
<targetSelectedWithDropDown>
<Target>
<type value="QUICK_BOOT_TARGET" />
<deviceKey>
<Key>
<type value="VIRTUAL_DEVICE_PATH" />
<value value="C:\Users\60652\.android\avd\Pixel_2_API_30.avd" />
</Key>
</deviceKey>
</Target>
</targetSelectedWithDropDown>
<timeTargetWasSelectedWithDropDown value="2023-10-29T18:27:39.718325100Z" />
</component>
</project>

View File

@ -7,7 +7,7 @@
<option name="testRunner" value="GRADLE" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="jbr-17" />
<option name="gradleJvm" value="19" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />

View File

@ -1,6 +1,6 @@
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_19" default="true" project-jdk-name="19" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@ -1,16 +1,17 @@
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id ("kotlin-kapt")
}
android {
namespace = "com.example.androidlabs"
compileSdk = 33
compileSdk = 34
defaultConfig {
applicationId = "com.example.androidlabs"
minSdk = 24
targetSdk = 33
targetSdk = 34
versionCode = 1
versionName = "1.0"
@ -23,15 +24,18 @@ android {
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
sourceCompatibility = JavaVersion.VERSION_19
targetCompatibility = JavaVersion.VERSION_19
}
kotlinOptions {
jvmTarget = "1.8"
jvmTarget = "19"
}
buildFeatures {
compose = true
@ -45,17 +49,18 @@ android {
}
}
}
apply(plugin = "kotlin-kapt")
dependencies {
implementation("androidx.core:core-ktx:1.9.0")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.1")
implementation("androidx.activity:activity-compose:1.7.0")
implementation("androidx.core:core-ktx:1.12.0")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2")
implementation("androidx.activity:activity-compose:1.8.0")
implementation(platform("androidx.compose:compose-bom:2023.03.00"))
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.ui:ui-graphics")
implementation("androidx.compose.ui:ui-tooling-preview")
implementation("androidx.compose.material3:material3")
implementation("androidx.compose.material:material")
implementation("androidx.navigation:navigation-runtime-ktx:2.7.4")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
@ -63,4 +68,23 @@ dependencies {
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
debugImplementation("androidx.compose.ui:ui-tooling")
debugImplementation("androidx.compose.ui:ui-test-manifest")
implementation ("androidx.activity:activity-ktx:1.8.0")
implementation ("androidx.fragment:fragment-ktx:1.6.1")
implementation ("io.coil-kt:coil-compose:1.4.0")
implementation ("com.google.code.gson:gson:2.8.8")
implementation("androidx.navigation:navigation-compose:2.7.4")
implementation ("androidx.lifecycle:lifecycle-viewmodel-compose:2.7.0-alpha02")
//ROOM
val room_version = "2.5.2"
implementation("androidx.room:room-runtime:$room_version")
annotationProcessor("androidx.room:room-compiler:$room_version")
kapt("androidx.room:room-compiler:$room_version")
implementation("androidx.room:room-ktx:$room_version")
implementation("androidx.room:room-paging:$room_version")
//Paging
implementation ("androidx.paging:paging-compose:3.2.1")
implementation ("androidx.paging:paging-runtime:3.2.1")
}

View File

@ -3,6 +3,7 @@
xmlns:tools="http://schemas.android.com/tools">
<application
android:name=".App"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"

View File

@ -0,0 +1,19 @@
package com.example.androidlabs
import android.app.Application
import com.example.androidlabs.DB.AppDatabase
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
class App : Application() {
lateinit var container: AppContainer
override fun onCreate() {
super.onCreate()
//this.deleteDatabase("my-db")
//CoroutineScope(Dispatchers.IO).launch {
// AppDatabase.populateDatabase()
//}
container = AppDataContainer(this)
}
}

View File

@ -0,0 +1,11 @@
package com.example.androidlabs
import com.example.androidlabs.DB.repository.HotelRepository
import com.example.androidlabs.DB.repository.OrderRepository
import com.example.androidlabs.DB.repository.UserRepository
interface AppContainer {
val hotelRepo: HotelRepository
val userRepo: UserRepository
val orderRepo: OrderRepository
}

View File

@ -0,0 +1,22 @@
package com.example.androidlabs
import android.content.Context
import com.example.androidlabs.DB.AppDatabase
import com.example.androidlabs.DB.repository.HotelRepImpl
import com.example.androidlabs.DB.repository.HotelRepository
import com.example.androidlabs.DB.repository.OrderRepImpl
import com.example.androidlabs.DB.repository.OrderRepository
import com.example.androidlabs.DB.repository.UserRepImpl
import com.example.androidlabs.DB.repository.UserRepository
class AppDataContainer(private val context: Context) : AppContainer {
override val hotelRepo: HotelRepository by lazy {
HotelRepImpl(AppDatabase.getInstance(context).hotelDao())
}
override val userRepo: UserRepository by lazy {
UserRepImpl(AppDatabase.getInstance(context).userDao())
}
override val orderRepo: OrderRepository by lazy {
OrderRepImpl(AppDatabase.getInstance(context).orderDao())
}
}

View File

@ -0,0 +1,79 @@
package com.example.androidlabs.Calendar
import android.app.DatePickerDialog
import android.os.Bundle
import android.widget.DatePicker
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import java.util.*
@Composable
fun MyDp(){
// Fetching the Local Context
val mContext = LocalContext.current
// Declaring integer values
// for year, month and day
val mYear: Int
val mMonth: Int
val mDay: Int
// Initializing a Calendar
val mCalendar = Calendar.getInstance()
// Fetching current year, month and day
mYear = mCalendar.get(Calendar.YEAR)
mMonth = mCalendar.get(Calendar.MONTH)
mDay = mCalendar.get(Calendar.DAY_OF_MONTH)
mCalendar.time = Date()
// Declaring a string value to
// store date in string format
val mDate = remember { mutableStateOf("") }
// Declaring DatePickerDialog and setting
// initial values as current values (present year, month and day)
val mDatePickerDialog = DatePickerDialog(
mContext,
{ _: DatePicker, mYear: Int, mMonth: Int, mDayOfMonth: Int ->
mDate.value = "$mDayOfMonth/${mMonth+1}/$mYear"
}, mYear, mMonth, mDay
)
Column(modifier = Modifier.fillMaxSize(), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally) {
// Creating a button that on
// click displays/shows the DatePickerDialog
Button(onClick = {
mDatePickerDialog.show()
}, colors = ButtonDefaults.buttonColors(backgroundColor = Color(0XFF0F9D58)) ) {
Text(text = "Open Date Picker", color = Color.White)
}
// Displaying the mDate value in the Text
Text(text = "Selected Date: ${mDate.value}", fontSize = 30.sp, textAlign = TextAlign.Center)
}
}
// For displaying preview in
// the Android Studio IDE emulator
@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
MyDp()
}

View File

@ -0,0 +1,77 @@
package com.example.androidlabs.DB
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.sqlite.db.SupportSQLiteDatabase
import com.example.androidlabs.DB.dao.HotelDao
import com.example.androidlabs.DB.dao.OrderDao
import com.example.androidlabs.DB.dao.UserDao
import com.example.androidlabs.DB.models.Hotel
import com.example.androidlabs.DB.models.Order
import com.example.androidlabs.DB.models.RoleEnum
import com.example.androidlabs.DB.models.User
import com.example.androidlabs.R
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@Database(entities = [Hotel::class, User::class, Order::class], version = 5)
abstract class AppDatabase : RoomDatabase() {
abstract fun hotelDao(): HotelDao
abstract fun userDao(): UserDao
abstract fun orderDao(): OrderDao
companion object {
private const val DB_NAME: String = "my-db"
@Volatile
private var INSTANCE: AppDatabase? = null
suspend fun populateDatabase() {
INSTANCE?.let { database ->
// User
val userDao = database.userDao()
val user1 = User(null, "Artem", "Emelyanov", "artem@mail.ru", "123", RoleEnum.User)
val user2 = User(null, "Danil", "Markov", "danil@mail.ru", "123", RoleEnum.User)
val user3 = User(null, "Viktoria", "Presnyakova", "vika@mail.ru", "123", RoleEnum.Admin)
userDao.createUser(user1)
userDao.createUser(user2)
userDao.createUser(user3)
// Sneaker
val hotelDao = database.hotelDao()
val hotel1 = Hotel(null, "Hotel1", 1000.0, R.drawable.img, 1, "location1", "info1")
val hotel2 = Hotel(null, "Hotel2", 2000.0, R.drawable.img_2, 2, "location2", "info2")
val hotel3 = Hotel(null, "Hotel3", 3000.0, R.drawable.img_3, 3, "location3", "info3")
val hotel4 = Hotel(null, "Hotel4", 4000.0, R.drawable.img_4, 4, "location4", "info4")
hotelDao.insert(hotel1)
hotelDao.insert(hotel2)
hotelDao.insert(hotel3)
hotelDao.insert(hotel4)
// Order
}
}
fun getInstance(appContext: Context): AppDatabase {
return INSTANCE ?: synchronized(this) {
Room.databaseBuilder(
appContext,
AppDatabase::class.java,
DB_NAME
)
.addCallback(object : Callback() {
override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db)
CoroutineScope(Dispatchers.IO).launch {
populateDatabase()
}
}
})
.fallbackToDestructiveMigration()
.build()
.also { INSTANCE = it }
}
}
}
}

View File

@ -0,0 +1,27 @@
package com.example.androidlabs.DB.dao
import androidx.paging.PagingSource
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import com.example.androidlabs.DB.models.Hotel
import kotlinx.coroutines.flow.Flow
@Dao
interface HotelDao {
@Insert
suspend fun insert(hotel: Hotel)
@Update
suspend fun update(hotel: Hotel)
@Delete
suspend fun delete(hotel: Hotel)
@Query("SELECT*FROM Hotel")
fun getAllHotelsPaged(): PagingSource<Int, Hotel>
@Query("SELECT * FROM Hotel WHERE hotelId = :id")
suspend fun getHotelById(id: Int): Hotel
}

View File

@ -0,0 +1,28 @@
package com.example.androidlabs.DB.dao
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import com.example.androidlabs.DB.models.Order
import com.example.androidlabs.DB.models.UserWithOrder
import kotlinx.coroutines.flow.Flow
@Dao
interface OrderDao {
@Insert
suspend fun createOrder(order: Order): Long
@Query("SELECT * FROM 'Order' WHERE orderId = :id")
fun getOrder(id: Int): Order
@Query("SELECT * FROM `Order`")
fun getAllOrder(): Flow<List<Order>>
@Delete
suspend fun delete(order: Order)
@Query("SELECT * FROM users WHERE userId =:id")
fun getUserOrders(id: Int) : Flow<UserWithOrder>
}

View File

@ -0,0 +1,29 @@
package com.example.androidlabs.DB.dao
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import com.example.androidlabs.DB.models.User
import com.example.androidlabs.DB.models.UserWithOrder
import kotlinx.coroutines.flow.Flow
@Dao
interface UserDao {
@Insert
suspend fun createUser(user: User)
@Update
suspend fun updateUser(user: User)
@Delete
suspend fun deleteUser(user: User)
@Query("SELECT * FROM users WHERE userId = :id")
suspend fun getUserById(id: Int): User
@Query("SELECT * FROM users WHERE email = :email")
suspend fun getUserByEmail(email: String): User
}

View File

@ -0,0 +1,29 @@
package com.example.androidlabs.DB.models
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity
data class Hotel (
@PrimaryKey(autoGenerate = true)
val hotelId: Int? = null,
@ColumnInfo(name = "Name")
val name: String,
@ColumnInfo(name = "Price")//
val price: Double,
@ColumnInfo(name = "Img")//
val img: Int,
@ColumnInfo(name = "Stars")//
val stars: Int,
@ColumnInfo(name = "Location")//
val location: String,
@ColumnInfo(name = "Info")//
val info: String,
)

View File

@ -0,0 +1,26 @@
package com.example.androidlabs.DB.models
import androidx.room.ColumnInfo
import androidx.room.Embedded
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity
data class Order(
@PrimaryKey(autoGenerate = true)
val orderId: Int? = null,
@ColumnInfo(name = "DateFrom")
val dateFrom: String,
@ColumnInfo(name = "DateTo")
val dateTo: String,
@ColumnInfo(name = "Rooms")
val rooms: Int,
@ColumnInfo(name = "Total")
val total: Double,
@ColumnInfo(name = "CreatorUserId")
val creatorUserId: Int,
@ColumnInfo(name = "BookedHotelId")
val bookedHotelId: Int,
@Embedded
val hotel: Hotel
)

View File

@ -0,0 +1,29 @@
package com.example.androidlabs.DB.models
import com.example.androidlabs.R
class PhotoManager {
private val photos = listOf(
R.drawable.img,
R.drawable.img_1,
R.drawable.img_2,
R.drawable.img_3,
R.drawable.img_4,
)
private var currentIndex = 0
fun changePhoto(int: Int): Int {
currentIndex = photos.indexOf(int)
if (photos.isNotEmpty()) {
if(currentIndex + 1 >= photos.size){
currentIndex = 0
}else{
currentIndex += 1
}
return photos[currentIndex]
} else {
return -1
}
}
}

View File

@ -0,0 +1,6 @@
package com.example.androidlabs.DB.models
enum class RoleEnum {
Admin,
User
}

View File

@ -0,0 +1,23 @@
package com.example.androidlabs.DB.models
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "users")
data class User(
@PrimaryKey(autoGenerate = true)
val userId: Int? = null,
@ColumnInfo(name = "Name")
val name: String,
@ColumnInfo(name = "Surname")
val surname: String,
@ColumnInfo(name = "Email")
val email: String,
@ColumnInfo(name = "Password")
val password: String,
@ColumnInfo(name = "Role")
val role: RoleEnum,
@ColumnInfo(name = "Photo")
val photo: Int? = null,
)

View File

@ -0,0 +1,13 @@
package com.example.androidlabs.DB.models
import androidx.room.Embedded
import androidx.room.Relation
data class UserWithOrder(
@Embedded val user: User,
@Relation(
parentColumn = "userId",
entityColumn = "CreatorUserId"
)
val orders: List<Order>
)

View File

@ -0,0 +1,29 @@
package com.example.androidlabs.DB.repository
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import com.example.androidlabs.DB.dao.HotelDao
import com.example.androidlabs.DB.models.Hotel
import androidx.paging.PagingSource
import kotlinx.coroutines.flow.Flow
class HotelRepImpl (private val hotelDao: HotelDao) : HotelRepository {
override suspend fun insertHotel(hotel: Hotel) = hotelDao.insert(hotel)
override suspend fun updateHotel(hotel: Hotel) = hotelDao.update(hotel)
override suspend fun deleteHotel(hotel: Hotel) = hotelDao.delete(hotel)
override suspend fun getHotelById(id: Int): Hotel = hotelDao.getHotelById(id)
override fun getAllHotelsPaged(): PagingSource<Int, Hotel> = hotelDao.getAllHotelsPaged()
override fun call(): Flow<PagingData<Hotel>> {
return Pager(
PagingConfig(pageSize = 5)
) {
hotelDao.getAllHotelsPaged()
}.flow
}
}

View File

@ -0,0 +1,14 @@
package com.example.androidlabs.DB.repository
import androidx.paging.PagingSource
import com.example.androidlabs.DB.models.Hotel
import kotlinx.coroutines.flow.Flow
import androidx.paging.PagingData
interface HotelRepository {
suspend fun insertHotel(hotel: Hotel)
suspend fun updateHotel(hotel: Hotel)
suspend fun deleteHotel(hotel: Hotel)
suspend fun getHotelById(id: Int): Hotel
fun getAllHotelsPaged(): PagingSource<Int, Hotel>
fun call(): Flow<PagingData<Hotel>>
}

View File

@ -0,0 +1,17 @@
package com.example.androidlabs.DB.repository
import com.example.androidlabs.DB.dao.OrderDao
import com.example.androidlabs.DB.models.Order
import com.example.androidlabs.DB.models.UserWithOrder
import kotlinx.coroutines.flow.Flow
class OrderRepImpl (private val orderDao: OrderDao) : OrderRepository {
override suspend fun createOrder(order: Order): Long = orderDao.createOrder(order)
override suspend fun delete(order: Order) = orderDao.delete(order)
override fun getAllOrder(): Flow<List<Order>> = orderDao.getAllOrder()
override fun getUserOrders(id: Int): Flow<UserWithOrder> = orderDao.getUserOrders(id)
}

View File

@ -0,0 +1,12 @@
package com.example.androidlabs.DB.repository
import com.example.androidlabs.DB.models.Order
import com.example.androidlabs.DB.models.UserWithOrder
import kotlinx.coroutines.flow.Flow
interface OrderRepository {
suspend fun createOrder(order: Order): Long
suspend fun delete(order: Order)
fun getAllOrder(): Flow<List<Order>>
fun getUserOrders(id: Int) : Flow<UserWithOrder>
}

View File

@ -0,0 +1,17 @@
package com.example.androidlabs.DB.repository
import com.example.androidlabs.DB.dao.UserDao
import com.example.androidlabs.DB.models.User
class UserRepImpl(private val userDao: UserDao) : UserRepository {
override suspend fun createUser(user: User) = userDao.createUser(user)
override suspend fun updateUser(user: User) = userDao.updateUser(user)
override suspend fun deleteUser(user: User) = userDao.deleteUser(user)
override suspend fun getUserById(id: Int): User = userDao.getUserById(id)
override suspend fun getUserByEmail(email: String): User = userDao.getUserByEmail(email)
}

View File

@ -0,0 +1,11 @@
package com.example.androidlabs.DB.repository
import com.example.androidlabs.DB.models.User
interface UserRepository {
suspend fun createUser(user: User)
suspend fun updateUser(user: User)
suspend fun deleteUser(user: User)
suspend fun getUserById(id: Int): User
suspend fun getUserByEmail(email: String): User
}

View File

@ -0,0 +1,24 @@
package com.example.androidlabs.DB.viewModels
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewmodel.CreationExtras
import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory
import com.example.androidlabs.App
object AppViewModelProvider {
val Factory = viewModelFactory {
initializer {
HotelViewModel(app().container.hotelRepo)
}
initializer {
UserViewModel(app().container.userRepo)
}
initializer {
OrderViewModel(app().container.orderRepo)
}
}
}
fun CreationExtras.app(): App =
(this[ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY] as App)

View File

@ -0,0 +1,51 @@
package com.example.androidlabs.DB.viewModels
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory.Companion.APPLICATION_KEY
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.CreationExtras
import androidx.paging.cachedIn
import com.example.androidlabs.App
import com.example.androidlabs.DB.AppDatabase
import com.example.androidlabs.DB.models.Hotel
import com.example.androidlabs.DB.repository.HotelRepository
import com.example.androidlabs.R
import kotlinx.coroutines.launch
class HotelViewModel(private val hotelRepository: HotelRepository): ViewModel() {
var name = mutableStateOf("")
val price = mutableStateOf("")
val location = mutableStateOf("")
val stars = mutableStateOf("")
val info = mutableStateOf("")
val img = mutableStateOf(R.drawable.img)
val HotelList = hotelRepository.call().cachedIn(viewModelScope)
var hotel: Hotel? = null
fun insertHotel() = viewModelScope.launch {
val hotel = Hotel(
name = name.value,
location = location.value,
price = price.value.toDouble(),
img = img.value,
stars = stars.value.toInt(),
info = info.value
)
hotelRepository.insertHotel(hotel)
}
fun deleteHotel(hotel : Hotel) = viewModelScope.launch {
hotelRepository.deleteHotel(hotel)
}
fun getHotelById(id: Int) = viewModelScope.launch {
hotelRepository.getHotelById(id)
}
fun UpdateHotel(hotel: Hotel) = viewModelScope.launch {
hotelRepository.updateHotel(hotel)
}
}

View File

@ -0,0 +1,58 @@
package com.example.androidlabs.DB.viewModels
import android.util.Log
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.CreationExtras
import com.example.androidlabs.App
import com.example.androidlabs.DB.AppDatabase
import com.example.androidlabs.DB.models.Hotel
import com.example.androidlabs.DB.models.Order
import com.example.androidlabs.DB.models.UserWithOrder
import com.example.androidlabs.DB.repository.OrderRepository
import com.example.androidlabs.GlobalUser
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.launch
import java.util.Date
class OrderViewModel(private val orderRepository: OrderRepository) : ViewModel() {
var selectedItem: Hotel? = null
val rooms = mutableStateOf("")
var dateFrom = mutableStateOf("")
var dateTo = mutableStateOf("")
fun deleteOrder(order: Order) = viewModelScope.launch {
orderRepository.delete(order)
}
fun getOrderList(id: Int) : Flow<UserWithOrder> {
return orderRepository.getUserOrders(id)
}
fun createOrder() = viewModelScope.launch {
Log.d("MyLog", GlobalUser.getInstance().getUser()?.userId.toString())
val order = Order(
dateFrom = dateFrom.value,
dateTo = dateTo.value,
rooms = rooms.value.toInt(),
total = getSubTotal(),
bookedHotelId = selectedItem?.hotelId!!,
creatorUserId = GlobalUser.getInstance().getUser()?.userId!!,
hotel = selectedItem!!
)
val orderId = orderRepository.createOrder(order)
rooms.value = ""
selectedItem = null
}
fun getSubTotal(): Double {
return selectedItem!!.price * rooms.value.toInt()
}
}

View File

@ -0,0 +1,47 @@
package com.example.androidlabs.DB.viewModels
import android.util.Log
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.CreationExtras
import com.example.androidlabs.App
import com.example.androidlabs.DB.AppDatabase
import com.example.androidlabs.DB.models.RoleEnum
import com.example.androidlabs.DB.models.User
import com.example.androidlabs.DB.repository.UserRepository
import com.example.androidlabs.GlobalUser
import kotlinx.coroutines.launch
class UserViewModel(private val userRepository: UserRepository): ViewModel() {
var name = mutableStateOf("")
val surname = mutableStateOf("")
val email = mutableStateOf("")
val password = mutableStateOf("")
fun createUser() = viewModelScope.launch {
val user = User(
name = name.value,
surname = surname.value,
email = email.value,
password = password.value,
role = RoleEnum.User
)
userRepository.createUser(user)
}
fun authUser() = viewModelScope.launch {
val user = userRepository.getUserByEmail(email.value)
if (password.value != "" && user.password == password.value) {
val globalUser = GlobalUser.getInstance()
globalUser.setUser(user)
Log.d("MyLog", GlobalUser.getInstance().getUser()?.userId.toString())
println()
}
}
fun isValidEmail(email: String): Boolean {
return android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches()
}
}

View File

@ -3,41 +3,40 @@ package com.example.androidlabs
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import com.example.androidlabs.ui.theme.AndroidLabsTheme
import com.example.androidlabs.DB.models.User
import com.example.androidlabs.Navigation.Navigate
import com.example.androidlabs.hotelScreen.HotelInfo
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
AndroidLabsTheme {
// A surface container using the 'background' color from the theme
Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) {
Greeting("Android")
}
Navigate()
}
}
}
class GlobalUser private constructor() {
private var user: User? = null
fun setUser(user: User?) {
this.user = user
}
fun getUser(): User? {
return user
}
companion object {
private var instance: GlobalUser? = null
fun getInstance(): GlobalUser {
return instance ?: synchronized(this) {
instance ?: GlobalUser().also { instance = it }
}
}
}
}
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
Text(
text = "Hello $name!",
modifier = modifier
)
}
@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
AndroidLabsTheme {
Greeting("Android")
}
}

View File

@ -0,0 +1,57 @@
package com.example.androidlabs.MyOrderScreen
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.MaterialTheme
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.FontWeight
import androidx.compose.ui.unit.dp
import com.example.androidlabs.DB.models.Order
import com.example.androidlabs.DB.viewModels.OrderViewModel
import com.example.androidlabs.GlobalUser
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
@Composable
fun MyOrderScreen(orderViewModel: OrderViewModel) {
// val userWithOrder by orderViewModel.database.userDao().getUserOrders(GlobalUser.getInstance().getUser()?.userId!!).collectAsState(null)
val userId = GlobalUser.getInstance().getUser()?.userId
val userWithOrder = orderViewModel.getOrderList(userId!!).collectAsState(null).value?.orders
println()
Column(
modifier = Modifier
.padding(bottom = 50.dp)
.fillMaxSize()
.background(Color.White)
.verticalScroll(rememberScrollState())
){
Text(
text = "My order",
style = MaterialTheme.typography.h5,
fontWeight = FontWeight.Bold,
modifier = Modifier
.padding(10.dp, 10.dp)
)
Row {
Column(
modifier = Modifier
.fillMaxSize()
) {
if (userWithOrder != null) {
for (item in userWithOrder) {
OrderCard(item, orderViewModel)
}
}
}
}
}
}

View File

@ -0,0 +1,84 @@
package com.example.androidlabs.MyOrderScreen
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
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.runtime.LaunchedEffect
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import com.example.androidlabs.DB.AppDatabase
import com.example.androidlabs.DB.models.Hotel
import com.example.androidlabs.DB.models.Order
import com.example.androidlabs.DB.viewModels.OrderViewModel
import com.example.androidlabs.R
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.util.Date
@Composable
fun OrderCard(order: Order, orderViewModel: OrderViewModel){
Row(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp, 16.dp, 16.dp, 0.dp)
.clip(RoundedCornerShape(16.dp))
.background(colorResource(id = R.color.figma))
){
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
verticalArrangement = Arrangement.Center
){
Text("${order.orderId}")
Text("From " + order.dateFrom)
Text("To " + order.dateTo)
Text("Sum ${order.total}")
Row(){
Image(
contentScale = ContentScale.FillBounds,
painter = painterResource(id =order.hotel.img),
contentDescription = null,
modifier = Modifier
.size(70.dp)
.padding(0.dp, 10.dp, 10.dp, 10.dp)
)
}
Button(
colors = ButtonDefaults.buttonColors(
backgroundColor = colorResource(id = R.color.figma_blue),
contentColor = Color.White
),
onClick = {
orderViewModel.deleteOrder(order)
},
modifier = Modifier
.fillMaxWidth()
.padding(16.dp, 16.dp, 16.dp, 0.dp)
) {
Text("Cancel")
}
}
}
}

View File

@ -0,0 +1,83 @@
package com.example.androidlabs.Navigation
import androidx.compose.runtime.Composable
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import com.example.androidlabs.DB.models.Hotel
import com.example.androidlabs.DB.viewModels.AppViewModelProvider
import com.example.androidlabs.DB.viewModels.OrderViewModel
import com.example.androidlabs.MyOrderScreen.MyOrderScreen
import com.example.androidlabs.booking.BookingScreen
import com.example.androidlabs.homeScreen.HomeScreen
import com.example.androidlabs.hotelScreen.HotelInfo
import com.example.androidlabs.profileScreen.profile.Person
import com.example.androidlabs.profileScreen.profile.ProfileScreen
import com.example.androidlabs.profileScreen.signIn.LoginScreen
import com.example.androidlabs.profileScreen.signUp.SignUpScreen
import com.example.androidlabs.adminPanel.AddPanel
import com.example.androidlabs.adminPanel.AdminPanel
import com.example.androidlabs.adminPanel.ChangeHotel
import com.example.androidlabs.adminPanel.ChangePanel
import com.google.gson.Gson
@Composable
fun NavController(navController: NavHostController) {
var orderViewModel: OrderViewModel = viewModel(factory = AppViewModelProvider.Factory)
NavHost(
navController = navController,
startDestination = NavItem.Home.route
) {
composable(NavItem.HotelInfo.route) {
//
backStackEntry ->
val hotelItemString = backStackEntry.arguments?.getString("hotelItem")
val hotelItem = Gson().fromJson(hotelItemString, Hotel::class.java)
hotelItem?.let { HotelInfo(it, navController)
}
}
composable(NavItem.Home.route) {
HomeScreen(navController)
}
composable(NavItem.MyOrder.route){
MyOrderScreen(orderViewModel)
}
composable(NavItem.Profile.route) {
ProfileScreen(navController)
}
composable(NavItem.SignIn.route){
LoginScreen(navController)
}
composable(NavItem.SignUp.route){
SignUpScreen(navController)
}
composable(NavItem.Booking.route) {
backStackEntry ->
val hotelItemString = backStackEntry.arguments?.getString("hotelItem")
val hotelItem = Gson().fromJson(hotelItemString, Hotel::class.java)
hotelItem?.let { BookingScreen(orderViewModel, it, navController)
}
}
composable(NavItem.ChangeHotel.route) { backStackEntry ->
val hotelItemString = backStackEntry.arguments?.getString("hotelItem")
val hotelItem = Gson().fromJson(hotelItemString, Hotel::class.java)
hotelItem?.let { ChangeHotel(it, onBackClick = {
navController.navigateUp() })
}
}
composable(NavItem.Person.route) {
Person(navController)
}
composable(NavItem.AdminPanel.route){
AdminPanel(navController)
}
composable(NavItem.AddPanel.route){
AddPanel(navController)
}
composable(NavItem.ChangePanel.route){
ChangePanel(navController)
}
}
}

View File

@ -0,0 +1,24 @@
package com.example.androidlabs.Navigation
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Build
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.material.icons.filled.Home
import androidx.compose.material.icons.filled.Person
import androidx.compose.ui.graphics.vector.ImageVector
sealed class NavItem(val route: String, val icon: ImageVector?){
object Home : NavItem("home", Icons.Default.Home)
object MyOrder : NavItem("myorder", null)
object Profile : NavItem("profile", Icons.Default.Person)
object SignIn : NavItem("login", null)
object SignUp : NavItem("signup", null)
object HotelInfo : NavItem("HotelInfo/{hotelItem}", null)
object Booking : NavItem("booking/{hotelItem}", null)
object Person : NavItem("person", null)
object AdminPanel : NavItem("admin", Icons.Default.Build)
object AddPanel : NavItem("add", null)
object ChangePanel : NavItem("change", null)
object ChangeHotel : NavItem("changeHotel/{hotelItem}", null)
}

View File

@ -0,0 +1,83 @@
package com.example.androidlabs.Navigation
import android.annotation.SuppressLint
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.BottomNavigation
import androidx.compose.material.BottomNavigationItem
import androidx.compose.material.Icon
import androidx.compose.material.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
@SuppressLint("UnusedMaterialScaffoldPaddingParameter")
@Composable
fun Navigate(){
val navController = rememberNavController()
val listItem = listOf(
NavItem.Home,
NavItem.Profile,
NavItem.AdminPanel
)
Scaffold(bottomBar = {
BottomNavigation(
backgroundColor = Color.White
) {
val navBackStackEntry = navController.currentBackStackEntryAsState()
val currentState = navBackStackEntry.value
listItem.forEach { it ->
val isSelected = currentState?.destination?.route == it.route
BottomNavigationItem(
selected = isSelected,
onClick = {
if(!isSelected){
navController.graph.startDestinationRoute?.let {
navController.popBackStack(it, inclusive = true)
}
navController.navigate(it.route){
launchSingleTop
}
}
navController.navigate(it.route)
},
icon = {
val iconModifier = if (isSelected) {
Modifier
.background(color = Color.LightGray, shape = CircleShape)
.padding(8.dp)
} else {
Modifier
}
it.icon?.let { it1 ->
Icon(
imageVector = it1,
contentDescription = null,
modifier = iconModifier.then(Modifier.size(24.dp))
)
}
}
)
}
}
}) {
NavController(navController = navController)
}
}
@Composable
@Preview
fun NavigatePreview(){
Navigate()
}

View File

@ -0,0 +1,253 @@
package com.example.androidlabs.adminPanel
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
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.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.Text
import androidx.compose.material.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
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.layout.ContentScale
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController
import com.example.androidlabs.DB.models.PhotoManager
import com.example.androidlabs.DB.viewModels.AppViewModelProvider
import com.example.androidlabs.DB.viewModels.HotelViewModel
import com.example.androidlabs.R
@Composable
fun AddPanel(navHostController: NavHostController, hotelViewModel: HotelViewModel = viewModel(factory = AppViewModelProvider.Factory)){
val photoManager = PhotoManager()
Row(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
.clip(RoundedCornerShape(16.dp))
.verticalScroll(rememberScrollState())
) {
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Image(
painter = painterResource(id = hotelViewModel.img.value),
contentDescription = "image",
contentScale = ContentScale.FillHeight,
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
.height(200.dp)
)
Button(
colors = ButtonDefaults.buttonColors(
backgroundColor = colorResource(id = R.color.figma_blue),
contentColor = Color.White
),
onClick = {
hotelViewModel.img.value = photoManager.changePhoto(hotelViewModel.img.value)
},
modifier = Modifier
.fillMaxWidth()
.padding(16.dp, 0.dp, 16.dp, 16.dp)
.height(50.dp)
) {
Text("Add image")
}
TextField(
value = hotelViewModel.name.value,
onValueChange = { hotelViewModel.name.value = it },
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.padding(16.dp, 0.dp)
.border(1.dp, Color.Gray, RoundedCornerShape(4.dp)),
singleLine = true,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Next
),
keyboardActions = KeyboardActions(
onNext = {
}
),
placeholder = {
Text(
text = "Name",
style = TextStyle(fontSize = 12.sp)
)
}
)
Spacer(modifier = Modifier.height(16.dp))
TextField(
value = hotelViewModel.stars.value,
onValueChange = { hotelViewModel.stars.value = it },
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.padding(16.dp, 0.dp)
.border(1.dp, Color.Gray, RoundedCornerShape(4.dp)),
singleLine = true,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Next
),
keyboardActions = KeyboardActions(
onNext = {
}
),
placeholder = {
Text(
text = "Stars",
style = TextStyle(fontSize = 12.sp)
)
}
)
Spacer(modifier = Modifier.height(16.dp))
TextField(
value = hotelViewModel.location.value,
onValueChange = { hotelViewModel.location.value = it },
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.padding(16.dp, 0.dp)
.border(1.dp, Color.Gray, RoundedCornerShape(4.dp)),
singleLine = true,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Next
),
keyboardActions = KeyboardActions(
onNext = {
}
),
placeholder = {
Text(
text = "Location",
style = TextStyle(fontSize = 12.sp)
)
}
)
Spacer(modifier = Modifier.height(16.dp))
TextField(
value = hotelViewModel.price.value,
onValueChange = { hotelViewModel.price.value = it },
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.padding(16.dp, 0.dp)
.border(1.dp, Color.Gray, RoundedCornerShape(4.dp)),
singleLine = true,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Next
),
keyboardActions = KeyboardActions(
onNext = {
}
),
placeholder = {
Text(
text = "Price",
style = TextStyle(fontSize = 12.sp)
)
}
)
Spacer(modifier = Modifier.height(16.dp))
TextField(
value = hotelViewModel.info.value,
onValueChange = { hotelViewModel.info.value = it },
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.padding(16.dp, 0.dp)
.border(1.dp, Color.Gray, RoundedCornerShape(4.dp)),
singleLine = true,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Next
),
keyboardActions = KeyboardActions(
onNext = {
}
),
placeholder = {
Text(
text = "Info",
style = TextStyle(fontSize = 12.sp)
)
}
)
Button(
colors = ButtonDefaults.buttonColors(
backgroundColor =colorResource(id = R.color.figma_blue),
contentColor = Color.White
),
onClick = {
hotelViewModel.insertHotel()
navHostController.navigate("home")
},
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
.height(50.dp)
) {
Text("Add hotel")
}
}
}
}
@Preview(showBackground = true)
@Composable
fun AddPreview() {
//AddPanel()
}

View File

@ -0,0 +1,82 @@
package com.example.androidlabs.adminPanel
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material.AlertDialog
import androidx.compose.material.Button
import androidx.compose.material.Text
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.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
import com.example.androidlabs.DB.models.RoleEnum
import com.example.androidlabs.GlobalUser
import com.example.androidlabs.profileScreen.signIn.LoginScreen
@Composable
fun AdminPanel(navHostController: NavHostController) {
var isAddPanelVisible by remember { mutableStateOf(false) }
var isChangePanelVisible by remember { mutableStateOf(true) }
var showDialog by remember { mutableStateOf(GlobalUser.getInstance().getUser()?.role == RoleEnum.User || GlobalUser.getInstance().getUser()?.role == null) }
if (showDialog) {
AlertDialog(
onDismissRequest = { showDialog = false },
title = {
Text("Access denied")
},
text = {
Text("You are not admin")
},
confirmButton = {
Button(
onClick = { navHostController.navigate("home") }
) {
Text("OK")
}
}
)
}
else{
Column(
modifier = Modifier
.fillMaxSize()
.background(Color.White)
.padding(bottom = 50.dp)
) {
ButtonAdmin(
onAddClick = {
isAddPanelVisible = true
isChangePanelVisible = false
},
onChangeClick = {
isChangePanelVisible = true
isAddPanelVisible = false
}
)
if (isAddPanelVisible) {
AddPanel(navHostController)
}
if (isChangePanelVisible) {
ChangePanel(navHostController)
}
}
}
}
@Composable
@Preview(showBackground = true)
fun SignInScreenPreview(){
val navController = rememberNavController()
AdminPanel(navController)
}

View File

@ -0,0 +1,70 @@
package com.example.androidlabs.adminPanel
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.Text
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.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController
import com.example.androidlabs.R
@Composable
fun ButtonAdmin(onAddClick: () -> Unit, onChangeClick: () -> Unit) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp, 16.dp, 16.dp, 0.dp)
.clip(RoundedCornerShape(16.dp))
.background(colorResource(id = R.color.figma))
){
Button(
colors = ButtonDefaults.buttonColors(
backgroundColor = colorResource(id = R.color.figma_blue),
contentColor = Color.White
),
onClick = {
onAddClick()
},
modifier = Modifier
.clip(RoundedCornerShape(20.dp))
.fillMaxWidth(0.5f)
.padding(16.dp)
) {
Text("Add")
}
Button(
colors = ButtonDefaults.buttonColors(
backgroundColor = colorResource(id = R.color.figma_blue),
contentColor = Color.White
),
onClick = {
onChangeClick()
},
modifier = Modifier
.clip(RoundedCornerShape(20.dp))
.fillMaxWidth()
.padding(16.dp)
) {
Text("Change/Del")
}
}
}

View File

@ -0,0 +1,114 @@
package com.example.androidlabs.adminPanel
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
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.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Create
import androidx.compose.material.icons.filled.Delete
import androidx.compose.runtime.Composable
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.layout.ContentScale
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
import com.example.androidlabs.DB.models.Hotel
import com.example.androidlabs.DB.viewModels.AppViewModelProvider
import com.example.androidlabs.DB.viewModels.HotelViewModel
import com.example.androidlabs.R
import com.google.gson.Gson
@Composable
fun CardHotelForChange(item: Hotel, navController: NavHostController, hotelViewModel: HotelViewModel = viewModel(factory = AppViewModelProvider.Factory)) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(10.dp)
.clip(RoundedCornerShape(10.dp))
.background(colorResource(id = R.color.figma)),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
Image(
painter = painterResource(id = item.img),
contentDescription = "image",
contentScale = ContentScale.FillWidth,
modifier = Modifier
.size(70.dp)
.padding(10.dp)
.clip(RoundedCornerShape(10.dp))
)
Column(
modifier = Modifier
.weight(1f)
.padding(start = 16.dp)
) {
item.name?.let { Text(text = it, fontSize = 20.sp) }
Text(text = "${item.location}", color = Color.Red, fontSize = 16.sp)
}
Button(
colors = ButtonDefaults.buttonColors(
backgroundColor = colorResource(id = R.color.figma_blue),
contentColor = Color.White
),
onClick = {
hotelViewModel.name.value = item.name ?: ""
hotelViewModel.price.value = item.price.toString()
hotelViewModel.stars.value = item.stars.toString()
hotelViewModel.location.value = item.location ?: ""
hotelViewModel.info.value = item.info ?: ""
val hotelItemString = Gson().toJson(item)
navController.navigate("changeHotel/${hotelItemString}") },
modifier = Modifier
.padding(end = 16.dp)
) {
Icon(imageVector = Icons.Default.Create, contentDescription = "change")
}
Button(
colors = ButtonDefaults.buttonColors(
backgroundColor = colorResource(id = R.color.figma_blue),
contentColor = Color.White
),
onClick = {
hotelViewModel.deleteHotel(item)
},
modifier = Modifier
.padding(end = 16.dp)
) {
Icon(imageVector = Icons.Default.Delete, contentDescription = "delete")
}
}
}
@Composable
@Preview
fun CardHotelLikePreview(){
val navController = rememberNavController()
//CardHotelForChange(Hotel("Hotel", R.drawable.img, 5, "location", "info", 4000), navController)
}

View File

@ -0,0 +1,255 @@
package com.example.androidlabs.adminPanel
import androidx.compose.foundation.Image
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
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.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.Text
import androidx.compose.material.TextField
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.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.androidlabs.DB.models.Hotel
import com.example.androidlabs.DB.viewModels.HotelViewModel
import androidx.lifecycle.viewmodel.compose.viewModel
import com.example.androidlabs.DB.models.PhotoManager
import com.example.androidlabs.DB.viewModels.AppViewModelProvider
import com.example.androidlabs.R
@Composable
fun ChangeHotel(hotel: Hotel, onBackClick: () -> Unit, hotelViewModel: HotelViewModel = viewModel(factory = AppViewModelProvider.Factory)) {
val name = remember { mutableStateOf(hotel.name) }
val price = remember{ mutableStateOf(hotel.price.toString()) }
val stars = remember{ mutableStateOf(hotel.stars.toString()) }
val location = remember{ mutableStateOf(hotel.location) }
val info = remember{ mutableStateOf(hotel.info) }
var img by remember { mutableStateOf(hotel.img) }
val photoManager = PhotoManager()
Row(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
.clip(RoundedCornerShape(16.dp))
.verticalScroll(rememberScrollState())
) {
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Image(
painter = painterResource(id = img),
contentDescription = "image",
contentScale = ContentScale.FillHeight,
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
.height(200.dp)
)
Button(
colors = ButtonDefaults.buttonColors(
backgroundColor = colorResource(id = R.color.figma_blue),
contentColor = Color.White
),
onClick = {
img = photoManager.changePhoto(img)
},
modifier = Modifier
.fillMaxWidth()
.padding(16.dp, 0.dp, 16.dp, 16.dp)
.height(50.dp)
) {
Text("Change image")
}
TextField(
value = name.value,
onValueChange = { newValue -> name.value = newValue },
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.padding(16.dp, 0.dp)
.border(1.dp, Color.Gray, RoundedCornerShape(4.dp)),
singleLine = true,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Next
),
keyboardActions = KeyboardActions(
onNext = {
}
),
placeholder = {
Text(
text = "Name",
style = TextStyle(fontSize = 12.sp)
)
}
)
Spacer(modifier = Modifier.height(16.dp))
TextField(
value = stars.value,
onValueChange = { stars.value = it },
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.padding(16.dp, 0.dp)
.border(1.dp, Color.Gray, RoundedCornerShape(4.dp)),
singleLine = true,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Next
),
keyboardActions = KeyboardActions(
onNext = {
}
),
placeholder = {
Text(
text = "Stars",
style = TextStyle(fontSize = 12.sp)
)
}
)
Spacer(modifier = Modifier.height(16.dp))
TextField(
value = location.value,
onValueChange = { location.value = it },
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.padding(16.dp, 0.dp)
.border(1.dp, Color.Gray, RoundedCornerShape(4.dp)),
singleLine = true,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Next
),
keyboardActions = KeyboardActions(
onNext = {
}
),
placeholder = {
Text(
text = "Location",
style = TextStyle(fontSize = 12.sp)
)
}
)
Spacer(modifier = Modifier.height(16.dp))
TextField(
value = price.value,
onValueChange = { price.value = it },
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.padding(16.dp, 0.dp)
.border(1.dp, Color.Gray, RoundedCornerShape(4.dp)),
singleLine = true,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Next
),
keyboardActions = KeyboardActions(
onNext = {
}
),
placeholder = {
Text(
text = "Price",
style = TextStyle(fontSize = 12.sp)
)
}
)
Spacer(modifier = Modifier.height(16.dp))
TextField(
value = info.value,
onValueChange = { info.value = it },
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.padding(16.dp, 0.dp)
.border(1.dp, Color.Gray, RoundedCornerShape(4.dp)),
singleLine = true,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Next
),
keyboardActions = KeyboardActions(
onNext = {
}
),
placeholder = {
Text(
text = "Info",
style = TextStyle(fontSize = 12.sp)
)
}
)
Button(
colors = ButtonDefaults.buttonColors(
backgroundColor = colorResource(id = R.color.figma_blue),
contentColor = Color.White
),
onClick = {
hotelViewModel.UpdateHotel(
Hotel(
hotelId = hotel.hotelId,
name = name.value,
price = price.value.toDouble(),
img = img,
stars = stars.value.toInt(),
location = location.value,
info = info.value
)
)
onBackClick()
},
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
.height(50.dp)
) {
Text("Change hotel")
}
}
}
}

View File

@ -0,0 +1,44 @@
package com.example.androidlabs.adminPanel
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController
import androidx.paging.compose.collectAsLazyPagingItems
import com.example.androidlabs.DB.viewModels.AppViewModelProvider
import com.example.androidlabs.DB.viewModels.HotelViewModel
@Composable
fun ChangePanel(navHostController: NavHostController, hotelViewModel: HotelViewModel = viewModel(factory = AppViewModelProvider.Factory)){
val list = hotelViewModel.HotelList.collectAsLazyPagingItems()
Column(
modifier = Modifier
.fillMaxSize()
.background(Color.White)
.padding(16.dp)
){
Row {
LazyColumn(
modifier = Modifier
.fillMaxSize()
) {
items(list.itemCount) { index ->
list[index]?.let { hotel ->
CardHotelForChange(item = hotel, navHostController)
}
}
}
}
}
}

View File

@ -0,0 +1,242 @@
package com.example.androidlabs.booking
import android.widget.DatePicker
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
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.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.Text
import androidx.compose.material.TextField
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.res.colorResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavHostController
import com.example.androidlabs.DB.models.Hotel
import com.example.androidlabs.DB.viewModels.OrderViewModel
import com.example.androidlabs.GlobalUser
import com.example.androidlabs.R
import android.app.DatePickerDialog
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.style.TextAlign
import java.util.Calendar
import java.util.Date
@Composable
fun BookingScreen(orderViewModel: OrderViewModel, hotel: Hotel, navHostController: NavHostController) {
Column(
modifier = Modifier
.fillMaxSize()
.background(Color.White)
.padding(16.dp)
,
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = "Booking",
fontSize = 24.sp,
fontWeight = FontWeight.Bold,
modifier = Modifier
.padding(16.dp)
)
TextField(
value = orderViewModel.rooms.value,
onValueChange = { orderViewModel.rooms.value = it},
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.padding(16.dp, 0.dp)
.border(1.dp, Color.Gray, RoundedCornerShape(4.dp)),
singleLine = true,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Next
),
keyboardActions = KeyboardActions(
onNext = {
}
),
placeholder = {
Text(
text = "Rooms",
style = TextStyle(fontSize = 12.sp)
)
}
)
Spacer(modifier = Modifier.height(16.dp))
// Fetching the Local Context
val mContext = LocalContext.current
// Declaring integer values
// for year, month and day
val mYearFrom: Int
val mMonthFrom: Int
val mDayFrom: Int
// Initializing a Calendar
val mCalendarFrom = Calendar.getInstance()
// Fetching current year, month and day
mYearFrom = mCalendarFrom.get(Calendar.YEAR)
mMonthFrom = mCalendarFrom.get(Calendar.MONTH)
mDayFrom = mCalendarFrom.get(Calendar.DAY_OF_MONTH)
mCalendarFrom.time = Date()
// Declaring a string value to
// store date in string format
val mDateFrom = remember { mutableStateOf("") }
// Declaring DatePickerDialog and setting
// initial values as current values (present year, month and day)
val mDatePickerDialogFrom = DatePickerDialog(
mContext,
{ _: DatePicker, mYear: Int, mMonth: Int, mDayOfMonth: Int ->
mDateFrom.value = "$mDayOfMonth/${mMonth+1}/$mYear"
}, mYearFrom, mMonthFrom, mDayFrom
)
// Creating a button that on
// click displays/shows the DatePickerDialog
Button(
colors = ButtonDefaults.buttonColors(
backgroundColor = (colorResource(id = R.color.figma_blue)),
contentColor = Color.White
),
onClick = {
mDatePickerDialogFrom.show()
},
modifier = Modifier
.fillMaxWidth()
.padding(16.dp, 16.dp, 16.dp, 0.dp)
.height(50.dp)
) {
Text("Open Date Picker")
}
// Displaying the mDate value in the Text
Text(text = "Selected Date From: ${mDateFrom.value}", fontSize = 15.sp)
Spacer(modifier = Modifier.height(16.dp))
// Fetching the Local Context
// Declaring integer values
// for year, month and day
val mYear: Int
val mMonth: Int
val mDay: Int
// Initializing a Calendar
val mCalendar = Calendar.getInstance()
// Fetching current year, month and day
mYear = mCalendar.get(Calendar.YEAR)
mMonth = mCalendar.get(Calendar.MONTH)
mDay = mCalendar.get(Calendar.DAY_OF_MONTH)
mCalendar.time = Date()
// Declaring a string value to
// store date in string format
val mDate = remember { mutableStateOf("") }
// Declaring DatePickerDialog and setting
// initial values as current values (present year, month and day)
val mDatePickerDialog = DatePickerDialog(
mContext,
{ _: DatePicker, mYear: Int, mMonth: Int, mDayOfMonth: Int ->
mDate.value = "$mDayOfMonth/${mMonth+1}/$mYear"
}, mYear, mMonth, mDay
)
// Creating a button that on
// click displays/shows the DatePickerDialog
Button(
colors = ButtonDefaults.buttonColors(
backgroundColor = (colorResource(id = R.color.figma_blue)),
contentColor = Color.White
),
onClick = {
mDatePickerDialog.show()
},
modifier = Modifier
.fillMaxWidth()
.padding(16.dp, 16.dp, 16.dp, 0.dp)
.height(50.dp)
) {
Text("Open Date Picker")
}
// Displaying the mDate value in the Text
Text(text = "Selected Date To: ${mDate.value}", fontSize = 15.sp,)
Button(
colors = ButtonDefaults.buttonColors(
backgroundColor = (colorResource(id = R.color.figma_blue)),
contentColor = Color.White
),
onClick = {
if(GlobalUser.getInstance().getUser() != null){
orderViewModel.selectedItem = hotel
orderViewModel.dateFrom = mDateFrom
orderViewModel.dateTo = mDate
orderViewModel.createOrder()
navHostController.navigate("home")
}else{
navHostController.navigate("login")
}
},
modifier = Modifier
.fillMaxWidth()
.padding(16.dp, 16.dp, 16.dp, 0.dp)
.height(50.dp)
) {
Text("Book")
}
}
}
//@Composable
//@Preview(showBackground = true)
//fun BookingScreenPreview(){
// val navController = rememberNavController()
// BookingScreen()
//}

View File

@ -0,0 +1,109 @@
package com.example.androidlabs.homeScreen.CardItem
import android.util.Log
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.LocationOn
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.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavHostController
import com.example.androidlabs.DB.models.Hotel
import com.example.androidlabs.R
import com.google.gson.Gson
@Composable
fun HotelCard (hotel: Hotel, navController: NavHostController){
androidx.compose.material.Card(
modifier = Modifier
.fillMaxWidth()
.padding(10.dp)
.clickable {
val hotelItemString = Gson().toJson(hotel)
navController.navigate("HotelInfo/${hotelItemString}")
},
shape = RoundedCornerShape(15.dp),
elevation = 5.dp
) {
Box(
modifier = Modifier.background(Color.White)
) {
Row(
modifier = Modifier
//.background(Color.Yellow)
.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically
) {
Image(
painter = painterResource(id = hotel.img),
contentDescription = "hotel",
contentScale = ContentScale.Fit,
modifier = Modifier
.padding(4.dp)
.size(150.dp)
)
Column(
modifier = Modifier
//.background(Color.Red)
.padding(start = 20.dp),
//horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(20.dp)
) {
Text(text = hotel.name, fontSize = 40.sp, fontWeight = FontWeight.Bold)
Row() {
for (i in 1..hotel.stars){
Image(
painter = painterResource(id = R.drawable.star_rate),
contentDescription = "star",
modifier = Modifier
.size(20.dp)
)
}
for (i in 1.. 5 - hotel.stars){
Image(
painter = painterResource(id = R.drawable.star_outline),
contentDescription = "star",
modifier = Modifier.size(20.dp)
)
}
}
Text(text = hotel.location)
}
Image(
imageVector = Icons.Filled.LocationOn,
contentDescription = "location",
modifier = Modifier.size(40.dp)
)
}
}
}
}
@Preview(showBackground = true)
@Composable
fun CardPreview() {
//HotelCard(Hotel("hotel", R.drawable.img, 4, "location"))
}

View File

@ -0,0 +1,97 @@
package com.example.androidlabs.homeScreen
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
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.res.colorResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
import androidx.paging.compose.collectAsLazyPagingItems
import androidx.paging.compose.itemKey
import com.example.androidlabs.DB.models.Hotel
import com.example.androidlabs.DB.viewModels.AppViewModelProvider
import com.example.androidlabs.DB.viewModels.HotelViewModel
import com.example.androidlabs.R
import com.example.androidlabs.homeScreen.CardItem.HotelCard
import com.example.androidlabs.homeScreen.SearchField.SearchField
@Composable
fun HomeScreen(navController: NavHostController, hotelViewModel: HotelViewModel = viewModel(factory = AppViewModelProvider.Factory)) {
val list = hotelViewModel.HotelList.collectAsLazyPagingItems()
//Log.d("MyLog", list.toString())
Column(
modifier = Modifier
.fillMaxSize()
.background(Color.White)
//.padding(bottom = 60.dp)
) {
Box(modifier = Modifier
.background(colorResource(id = R.color.figma_blue))
.fillMaxHeight(0.18f)
){
Column(
modifier = Modifier
.fillMaxHeight(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.SpaceEvenly
){
Text(text= "Beautiful Place to Live", fontSize = 20.sp, fontWeight = FontWeight.Bold,
color = Color.White)
Text(text="Find a Source you want to spent times", color = Color.White)
SearchField(
modifier = Modifier
.padding(horizontal = 10.dp, vertical = 20.dp),
) { searchText ->
// Обработка введенного текста поиска
}
}
}
Column (
modifier = Modifier
//.verticalScroll(rememberScrollState())
.padding(bottom = 60.dp)
){
LazyVerticalGrid(
columns = GridCells.Fixed(1)
) {
items(
count = list.itemCount,
key = list.itemKey { hotel -> hotel.hotelId!! }
) { index: Int ->
val hotel: Hotel? = list[index]
if (hotel != null) {
HotelCard(hotel, navController)
}
}
}
}
}
}
@Preview(showBackground = true)
@Composable
fun HotelPreview() {
var nc = rememberNavController()
HomeScreen(nc)
}

View File

@ -0,0 +1,76 @@
package com.example.androidlabs.homeScreen.SearchField
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
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.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Search
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.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@Composable
fun SearchField(
modifier: Modifier = Modifier,
onSearch: (String) -> Unit
) {
var searchText by remember { mutableStateOf("") }
Box(
modifier = modifier
.clip(RoundedCornerShape(30.dp))
.fillMaxWidth()
.background(Color.White)
,
) {
Row(
modifier = Modifier
.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
content = {
BasicTextField(
value = searchText,
singleLine = true,
onValueChange = {
searchText = it
onSearch(it)
},
textStyle = TextStyle(color = Color.Black),
modifier = Modifier
.weight(1f)
)
Image(
imageVector = Icons.Filled.Search,
contentDescription = "search",
modifier = Modifier.size(50.dp)
.padding(3.dp)
)
}
)
}
}
@Preview(showBackground = true)
@Composable
fun FieldPreview() {
SearchField(
) { searchText ->
// Обработка введенного текста поиска
}
}

View File

@ -0,0 +1,171 @@
package com.example.androidlabs.hotelScreen
import android.util.Log
import androidx.compose.animation.shrinkVertically
import androidx.compose.foundation.Image
import androidx.compose.foundation.ScrollState
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.Button
import androidx.compose.material.ButtonColors
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.Divider
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
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.layout.ContentScale
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
import com.example.androidlabs.DB.models.Hotel
import com.example.androidlabs.R
import com.example.androidlabs.homeScreen.CardItem.HotelCard
import com.google.gson.Gson
@Composable
fun HotelInfo(hotel: Hotel, navController: NavHostController) {
Log.d("MyLog", hotel.toString())
Column (
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight()
.background(Color.White)
.verticalScroll(rememberScrollState()),
verticalArrangement = Arrangement.SpaceBetween,
){
Image(
painter = painterResource(id = hotel.img),
contentDescription = "hotel",
contentScale = ContentScale.FillWidth,
modifier = Modifier
.fillMaxWidth()
)
Box(
modifier = Modifier.background(Color.White)
){
Row (
modifier = Modifier
.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceEvenly
){
Text(text = hotel.name)
// stars
}
}
Divider(color = Color.Black, thickness = 1.dp)
Box(
modifier = Modifier.background(Color.White)
){
Row (
modifier = Modifier
.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceEvenly
){
Text(text = "1 room | 1 Night")
Text(text = "Rs. 4000")
}
}
Divider(color = Color.Black, thickness = 1.dp)
Box(
modifier = Modifier
.background(Color.White)
){
Column (
modifier = Modifier
.fillMaxWidth()
,
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.SpaceEvenly
){
Text(text = "Location")
Text(text = hotel.location)
}
}
Divider(color = Color.Black, thickness = 1.dp)
Box(
modifier = Modifier
.background(Color.White)
){
Column (
modifier = Modifier
.fillMaxWidth()
,
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.SpaceEvenly
){
Text(text = "Amenties")
Text(text = "wifi")
}
}
Divider(color = Color.Black, thickness = 1.dp)
Box(
modifier = Modifier
.background(Color.White)
){
Column (
modifier = Modifier
.fillMaxWidth()
,
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.SpaceEvenly
){
Text(text = "Info")
Text(text = "inf")
}
}
Row(
modifier = Modifier
.padding(bottom = 60.dp),
verticalAlignment = Alignment.Bottom
){
Button(
colors = ButtonDefaults.buttonColors(
backgroundColor = (colorResource(id = R.color.figma_blue)),
contentColor = Color.White
),
onClick = {
val hotelItemString = Gson().toJson(hotel)
navController.navigate("booking/${hotelItemString}")
},
modifier = Modifier
.fillMaxWidth()
.padding(16.dp, 16.dp, 16.dp, 5.dp)
.height(50.dp)
) {
Text("Select Room")
}
}
}
}
@Preview(showBackground = true)
@Composable
fun HotelInfoPreview() {
val navController = rememberNavController()
// HotelInfo(Hotel("hotel", R.drawable.img_1, 4, "location", "info", 4000), navController)
}

View File

@ -0,0 +1,65 @@
package com.example.androidlabs.profileScreen.profile
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
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.layout.ContentScale
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
import com.example.androidlabs.GlobalUser
import com.example.androidlabs.R
@Composable
fun Person(navHostController: NavHostController) {
Column(
modifier = Modifier
.background(Color.White)
.fillMaxSize(),
verticalArrangement = Arrangement.Center
) {
Button(
onClick = {
GlobalUser.getInstance().setUser(null)
navHostController.navigate("profile")
},
colors = ButtonDefaults.buttonColors(
backgroundColor = colorResource(id = R.color.white),
contentColor = Color.Black
),
modifier = Modifier
.padding(16.dp, 0.dp)
) {
Text("Exit")
}
ProfileCard(navHostController)
}
}
@Preview
@Composable
fun PersonPreview(){
val navController = rememberNavController()
Person(navController)
}

View File

@ -0,0 +1,90 @@
package com.example.androidlabs.profileScreen.profile
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
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.shape.CircleShape
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.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.drawWithContent
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavHostController
import com.example.androidlabs.GlobalUser
import com.example.androidlabs.R
@Composable
fun ProfileCard(navHostController: NavHostController) {
val globalUser = GlobalUser.getInstance().getUser()
Row(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
.clip(RoundedCornerShape(16.dp))
.background(colorResource(id = R.color.figma))
){
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
){
Image(
contentScale = ContentScale.Crop,
painter = painterResource(id = R.drawable.img_1),
contentDescription = null,
modifier = Modifier
.size(150.dp)
.border(2.dp, Color.White, CircleShape)
.padding(16.dp)
.clip(CircleShape)
)
if (globalUser != null) {
Text(
text = "${globalUser.name} ${globalUser.surname}",
fontSize = 18.sp,
fontWeight = FontWeight.Bold
)
Text(
text = globalUser.email,
fontSize = 16.sp,
color = Color.Gray
)
}
Button(
colors = ButtonDefaults.buttonColors(
backgroundColor = colorResource(id = R.color.figma_blue),
contentColor = Color.White
),
onClick = {
navHostController.navigate("myorder")
},
modifier = Modifier
.fillMaxWidth()
.padding(16.dp, 16.dp, 16.dp, 0.dp)
) {
Text("My order")
}
}
}
}

View File

@ -0,0 +1,47 @@
package com.example.androidlabs.profileScreen.profile
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.requiredSize
import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
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.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.colorResource
import com.example.androidlabs.GlobalUser
import com.example.androidlabs.R
import com.example.androidlabs.profileScreen.signIn.LoginScreen
@Composable
fun ProfileScreen(navController: NavHostController) {
val globalUser: GlobalUser = GlobalUser.getInstance()
if(globalUser.getUser() != null){
Person(navController)
}else{
LoginScreen(navController = navController)
}
}
@Composable
@Preview
fun ProfileScreenPreview(){
val navController = rememberNavController()
ProfileScreen(navController = navController)
}

View File

@ -0,0 +1,178 @@
package com.example.androidlabs.profileScreen.signIn
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
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.shape.RoundedCornerShape
import androidx.compose.foundation.text.ClickableText
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.Text
import androidx.compose.material.TextField
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.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
import com.example.androidlabs.DB.viewModels.AppViewModelProvider
import com.example.androidlabs.DB.viewModels.UserViewModel
import com.example.androidlabs.R
@Composable
fun SignInCard(navController: NavHostController, userViewModel: UserViewModel = viewModel(factory = AppViewModelProvider.Factory)) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
.clip(RoundedCornerShape(16.dp))
){
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
){
var isEmailValid by remember { mutableStateOf(true) }
var isPasswordValid by remember { mutableStateOf(true) }
Text(
text = "Sign In",
fontSize = 24.sp,
fontWeight = FontWeight.Bold,
modifier = Modifier
.padding(16.dp)
)
TextField(
value = userViewModel.email.value,
onValueChange = {
userViewModel.email.value = it
isEmailValid = userViewModel.isValidEmail(it)},
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.padding(16.dp, 0.dp)
.border(1.dp, Color.Gray, RoundedCornerShape(4.dp)),
singleLine = true,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Next
),
keyboardActions = KeyboardActions(
onNext = {
}
),
placeholder = {
Text(
text = "Username",
style = TextStyle(fontSize = 12.sp)
)
}
)
if (!isEmailValid) {
Text(
text = "Invalid email format",
color = Color.Red,
style = TextStyle(fontSize = 12.sp)
)
}
Spacer(modifier = Modifier.height(16.dp))
TextField(
value = userViewModel.password.value,
onValueChange = {
userViewModel.password.value = it
isPasswordValid = it.isNotEmpty()
},
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.padding(16.dp, 0.dp)
.border(1.dp, Color.Gray, RoundedCornerShape(4.dp)),
singleLine = true,
visualTransformation = PasswordVisualTransformation(),
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Next
),
keyboardActions = KeyboardActions(
onNext = {
}
),
placeholder = {
Text(
text = "Password",
style = TextStyle(fontSize = 12.sp)
)
}
)
if (!isPasswordValid) {
Text(
text = "Password is required",
color = Color.Red,
style = TextStyle(fontSize = 12.sp)
)
}
Button(
colors = ButtonDefaults.buttonColors(
backgroundColor = (colorResource(id = R.color.figma_blue)),
contentColor = Color.White
),
onClick = {
userViewModel.authUser()
navController.navigate("person")
},
modifier = Modifier
.fillMaxWidth()
.padding(16.dp, 16.dp, 16.dp, 0.dp)
.height(50.dp)
) {
Text("Sign In")
}
ClickableText(
text = AnnotatedString("You do not have an account? Register!"),
modifier = Modifier
.padding(0.dp, 0.dp, 0.dp, 16.dp),
onClick = {
navController.navigate("signup")
}
)
}
}
}
@Composable
@Preview(showBackground = true)
fun SignInScreenPreview(){
val navController = rememberNavController()
LoginScreen(navController = navController)
}

View File

@ -0,0 +1,45 @@
package com.example.androidlabs.profileScreen.signIn
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
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.FontWeight
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavController
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
import com.example.androidlabs.profileScreen.profile.ProfileScreen
import androidx.compose.material.Text as Text1
@Composable
fun LoginScreen(navController: NavHostController) {
Column(modifier = Modifier
.fillMaxSize()
.background(Color.White),
verticalArrangement = Arrangement.Center
) {
SignInCard(navController)
}
}
@Composable
@Preview
fun LoginScreenPreview(){
val navController = rememberNavController()
LoginScreen(navController = navController)
}

View File

@ -0,0 +1,199 @@
package com.example.androidlabs.profileScreen.signUp
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
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.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.Text
import androidx.compose.material.TextField
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.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
import com.example.androidlabs.DB.viewModels.AppViewModelProvider
import com.example.androidlabs.DB.viewModels.UserViewModel
import com.example.androidlabs.R
import com.example.androidlabs.profileScreen.signIn.LoginScreen
@Composable
fun SignUpCard(navHostController: NavHostController, userViewModel: UserViewModel = viewModel(factory = AppViewModelProvider.Factory)) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
.clip(RoundedCornerShape(16.dp))
){
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
){
Text(
text = "Sign Up",
fontSize = 24.sp,
fontWeight = FontWeight.Bold,
modifier = Modifier
.padding(16.dp)
)
Spacer(modifier = Modifier.height(16.dp))
TextField(
value = userViewModel.name.value,
onValueChange = { userViewModel.name.value = it },
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.padding(16.dp, 0.dp)
.border(1.dp, Color.Gray, RoundedCornerShape(4.dp)),
singleLine = true,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Next
),
keyboardActions = KeyboardActions(
onNext = {
}
),
placeholder = {
Text(
text = "Name",
style = TextStyle(fontSize = 12.sp)
)
}
)
Spacer(modifier = Modifier.height(16.dp))
TextField(
value = userViewModel.surname.value,
onValueChange = { userViewModel.surname.value = it },
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.padding(16.dp, 0.dp)
.border(1.dp, Color.Gray, RoundedCornerShape(4.dp)),
singleLine = true,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Next
),
keyboardActions = KeyboardActions(
onNext = {
}
),
placeholder = {
Text(
text = "Surname",
style = TextStyle(fontSize = 12.sp)
)
}
)
Spacer(modifier = Modifier.height(16.dp))
TextField(
value = userViewModel.email.value,
onValueChange = { userViewModel.email.value = it },
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.padding(16.dp, 0.dp)
.border(1.dp, Color.Gray, RoundedCornerShape(4.dp)),
singleLine = true,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Next
),
keyboardActions = KeyboardActions(
onNext = {
}
),
placeholder = {
Text(
text = "Email",
style = TextStyle(fontSize = 12.sp)
)
}
)
Spacer(modifier = Modifier.height(16.dp))
TextField(
value = userViewModel.password.value,
onValueChange = { userViewModel.password.value = it },
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.padding(16.dp, 0.dp)
.border(1.dp, Color.Gray, RoundedCornerShape(4.dp)),
singleLine = true,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Next
),
keyboardActions = KeyboardActions(
onNext = {
}
),
placeholder = {
Text(
text = "Password",
style = TextStyle(fontSize = 12.sp)
)
}
)
Spacer(modifier = Modifier.height(16.dp))
Button(
colors = ButtonDefaults.buttonColors(
backgroundColor = (colorResource(id = R.color.figma_blue)),
contentColor = Color.White
),
onClick = {
userViewModel.createUser()
navHostController.navigate("login")
},
modifier = Modifier
.fillMaxWidth()
.padding(16.dp, 16.dp, 16.dp, 0.dp)
.height(50.dp)
) {
Text("Sign Up")
}
}
}
}

View File

@ -0,0 +1,48 @@
package com.example.androidlabs.profileScreen.signUp
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
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.shape.RoundedCornerShape
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.Button
import androidx.compose.material.DropdownMenu
import androidx.compose.material.Text
import androidx.compose.material.TextField
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.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavHostController
@Composable
fun SignUpScreen(navHostController: NavHostController) {
Column(modifier = Modifier
.fillMaxSize()
.background(Color.White),
verticalArrangement = Arrangement.Center
) {
SignUpCard(navHostController)
}
}

View File

@ -1,13 +1,14 @@
package com.example.androidlabs.ui.theme
package com.example.androidlabs.ui.theme
/*
import android.app.Activity
import android.os.Build
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.dynamicDarkColorScheme
import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.material.MaterialTheme
import androidx.compose.material.darkColorScheme
import androidx.compose.material.dynamicDarkColorScheme
import androidx.compose.material.dynamicLightColorScheme
import androidx.compose.material.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.SideEffect
import androidx.compose.ui.graphics.toArgb
@ -67,4 +68,6 @@ fun AndroidLabsTheme(
typography = Typography,
content = content
)
}
}
*/

View File

@ -1,5 +1,5 @@
package com.example.androidlabs.ui.theme
/*
import androidx.compose.material3.Typography
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily
@ -15,7 +15,7 @@ val Typography = Typography(
lineHeight = 24.sp,
letterSpacing = 0.5.sp
)
/* Other default text styles to override
Other default text styles to override
titleLarge = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Normal,
@ -30,5 +30,6 @@ val Typography = Typography(
lineHeight = 16.sp,
letterSpacing = 0.5.sp
)
*/
)
)
*/

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12zM19,4h-3.5l-1,-1h-5l-1,1H5v2h14V4z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z"/>
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M12,2C8.13,2 5,5.13 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13c0,-3.87 -3.13,-7 -7,-7zM12,11.5c-1.38,0 -2.5,-1.12 -2.5,-2.5s1.12,-2.5 2.5,-2.5 2.5,1.12 2.5,2.5 -1.12,2.5 -2.5,2.5z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M22,9.24l-7.19,-0.62L12,2 9.19,8.63 2,9.24l5.46,4.73L5.82,21 12,17.27 18.18,21l-1.63,-7.03L22,9.24zM12,15.4l-3.76,2.27 1,-4.28 -3.32,-2.88 4.38,-0.38L12,6.1l1.71,4.04 4.38,0.38 -3.32,2.88 1,4.28L12,15.4z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M14.43,10l-2.43,-8l-2.43,8l-7.57,0l6.18,4.41l-2.35,7.59l6.17,-4.69l6.18,4.69l-2.35,-7.59l6.17,-4.41z"/>
</vector>

View File

@ -7,4 +7,7 @@
<color name="teal_700">#FF018786</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<color name="figma">#F4F4F4</color>
<color name="figma_blue">#802A7DB9</color>
</resources>