diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ce8ea70 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,70 @@ +plugins { + id 'com.android.application' + id 'org.jetbrains.kotlin.android' +} + +android { + namespace 'com.lb.codetest' + compileSdk 34 + + defaultConfig { + applicationId "com.lb.codetest" + minSdk 26 + targetSdk 34 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + vectorDrawables { + useSupportLibrary true + } + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = '1.8' + } + buildFeatures { + compose true + } + composeOptions { + kotlinCompilerExtensionVersion '1.4.3' + } + packaging { + resources { + excludes += '/META-INF/{AL2.0,LGPL2.1}' + } + } +} + +dependencies { + + implementation 'androidx.core:core-ktx:1.12.0' + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.7.0' + implementation 'androidx.activity:activity-compose:1.8.2' + implementation platform('androidx.compose:compose-bom:2023.03.00') + implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.7.0") + implementation "androidx.lifecycle:lifecycle-runtime-compose:2.7.0" + implementation "me.onebone:toolbar-compose:2.3.5" + implementation 'androidx.compose.ui:ui' + implementation 'androidx.compose.ui:ui-graphics' + implementation 'androidx.compose.ui:ui-tooling-preview' + implementation 'androidx.compose.material3:material3' + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.5' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' + androidTestImplementation platform('androidx.compose:compose-bom:2023.03.00') + androidTestImplementation 'androidx.compose.ui:ui-test-junit4' + debugImplementation 'androidx.compose.ui:ui-tooling' + debugImplementation 'androidx.compose.ui:ui-test-manifest' +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/app/src/androidTest/java/com/lb/codetest/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/lb/codetest/ExampleInstrumentedTest.kt new file mode 100644 index 0000000..6ddcaea --- /dev/null +++ b/app/src/androidTest/java/com/lb/codetest/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package com.lb.codetest + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("com.lb.codetest", appContext.packageName) + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..cc59a6a --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/lb/codetest/ClubActivity.kt b/app/src/main/java/com/lb/codetest/ClubActivity.kt new file mode 100644 index 0000000..eb6d607 --- /dev/null +++ b/app/src/main/java/com/lb/codetest/ClubActivity.kt @@ -0,0 +1,238 @@ +package com.lb.codetest + +import android.app.Activity +import android.content.Intent +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +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.layout.size +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ArrowBack +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.Surface +import androidx.compose.material3.Tab +import androidx.compose.material3.TabRow +import androidx.compose.material3.TabRowDefaults +import androidx.compose.material3.TabRowDefaults.tabIndicatorOffset +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.TopAppBarDefaults +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.layout.ContentScale +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import androidx.lifecycle.viewmodel.compose.viewModel +import com.lb.codetest.models.Squad +import com.lb.codetest.ui.SquadUI +import com.lb.codetest.ui.theme.ClubTheme +import com.lb.codetest.ui.theme.CodeTestTheme +import com.lb.codetest.ui.theme.SecondaryTextColor +import com.lb.codetest.viewmodel.ClubViewModel +import me.onebone.toolbar.CollapsingToolbarScaffold +import me.onebone.toolbar.ScrollStrategy +import me.onebone.toolbar.rememberCollapsingToolbarScaffoldState + +const val CLUB_THEME = "ClubTheme" + +class ClubActivity : ComponentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + val clubTheme = getClubTheme(intent) + setContent { + CodeTestTheme(primaryColor = clubTheme.primary) { + Surface( + modifier = Modifier.fillMaxSize(), + color = clubTheme.background + ) { + ClubScreen(clubTheme) + } + } + } + } + + private fun getClubTheme(intent: Intent): ClubTheme { + return intent.getSerializableExtra(CLUB_THEME) as? ClubTheme ?: ClubTheme.UCL + } +} + +@Composable +fun ClubScreen(clubTheme: ClubTheme, clubViewModel: ClubViewModel = viewModel()) { + val squad by clubViewModel.squadFlow.collectAsStateWithLifecycle() + val state = rememberCollapsingToolbarScaffoldState() + + CollapsingToolbarScaffold( + state = state, + scrollStrategy = ScrollStrategy.ExitUntilCollapsed, + modifier = Modifier, + toolbar = { + TopBarContainer(clubTheme = clubTheme) + } + ) { + ClubTabsUI(clubTheme = clubTheme, squad = squad) + } +} + +@Composable +fun ClubTabsUI(clubTheme: ClubTheme, squad: Squad, modifier: Modifier = Modifier) { + val tabs = listOf( + stringResource(R.string.overview), + stringResource(R.string.matches), + stringResource(R.string.groups), + stringResource(R.string.stats), + stringResource(R.string.squad) + ) + + var selectedTabIndex by remember { mutableStateOf(tabs.lastIndex) } + + Column( + modifier = modifier.then(Modifier.fillMaxWidth()) + ) { + TabRow( + selectedTabIndex = selectedTabIndex, + containerColor = clubTheme.tabsContainerColor, + indicator = { tabPositions -> + TabRowDefaults.Indicator( + modifier = Modifier.tabIndicatorOffset(tabPositions[selectedTabIndex]), + color = clubTheme.accentColor + ) + }, + divider = {} + ) { + tabs.forEachIndexed { index, title -> + val isSelected = selectedTabIndex == index + val color = if (isSelected) clubTheme.accentColor else SecondaryTextColor + + Tab(text = { + Text( + text = title, + color = color, + fontSize = 13.sp + ) + }, + selected = isSelected, + onClick = { selectedTabIndex = index } + ) + } + } + + when (selectedTabIndex) { + tabs.lastIndex -> SquadUI(clubTheme, squad) + else -> EmptyTabUI(clubTheme = clubTheme) + } + } +} + +@Composable +fun EmptyTabUI(clubTheme: ClubTheme) { + Spacer( + modifier = Modifier + .fillMaxSize() + .background(clubTheme.primary) + ) +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun TopBarContainer(clubTheme: ClubTheme) { + Spacer( + modifier = Modifier + .fillMaxWidth() + .height(60.dp) + ) + + Box(modifier = Modifier.fillMaxWidth()) { + + Image( + painter = painterResource(id = clubTheme.topbarImage), + contentDescription = null, + modifier = Modifier.matchParentSize(), + contentScale = ContentScale.Crop + ) + + Column { + + TopAppBar( + colors = TopAppBarDefaults.smallTopAppBarColors( + containerColor = Color.Transparent, + titleContentColor = Color.White, + navigationIconContentColor = Color.White, + actionIconContentColor = Color.White, + scrolledContainerColor = clubTheme.primary + ), + title = {}, + navigationIcon = { + val activity = LocalContext.current as? Activity + IconButton(onClick = { activity?.finish() }) { + Icon( + imageVector = Icons.Filled.ArrowBack, + contentDescription = null + ) + } + }, + actions = { + IconButton(onClick = { /* do something */ }) { + Icon( + painter = painterResource(id = R.drawable.topbar_action), + contentDescription = null + ) + } + } + ) + + Text( + text = stringResource(id = R.string.barcelona), + modifier = Modifier.padding(top = 12.dp, start = 16.dp), + color = Color.White, + fontSize = 48.sp, + fontWeight = FontWeight.Bold + ) + + Text( + text = stringResource(id = R.string.playing), + modifier = Modifier.padding(top = 72.dp, start = 16.dp), + color = SecondaryTextColor, + fontSize = 14.sp + ) + + Text( + text = stringResource(id = R.string.round), + modifier = Modifier.padding(start = 16.dp, bottom = 24.dp), + color = Color.White, + fontSize = 16.sp + ) + } + + Image( + painter = painterResource(id = R.drawable.crest), + contentDescription = null, + modifier = Modifier + .align(Alignment.BottomEnd) + .padding(16.dp) + .size(110.dp) + ) + } +} + diff --git a/app/src/main/java/com/lb/codetest/MainActivity.kt b/app/src/main/java/com/lb/codetest/MainActivity.kt new file mode 100644 index 0000000..e7aa562 --- /dev/null +++ b/app/src/main/java/com/lb/codetest/MainActivity.kt @@ -0,0 +1,52 @@ +package com.lb.codetest + +import android.content.Intent +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Button +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import com.lb.codetest.ui.theme.ClubTheme + +class MainActivity : ComponentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContent { + ThemeSelectionScreen { showClub(it) } + } + } + + private fun showClub(clubTheme: ClubTheme) { + startActivity(Intent(this, ClubActivity::class.java).apply { + putExtra(CLUB_THEME, clubTheme) + }) + } +} + +@Composable +fun ThemeSelectionScreen(onThemeSelected: (clubTheme: ClubTheme) -> Unit) { + Row( + modifier = Modifier.fillMaxSize(), + horizontalArrangement = Arrangement.Center, + verticalAlignment = Alignment.CenterVertically + ) { + Button(onClick = { onThemeSelected(ClubTheme.UCL) }) { + Text(text = "Start UCL") + } + + Spacer(modifier = Modifier.width(50.dp)) + + Button(onClick = { onThemeSelected(ClubTheme.UEL) }) { + Text(text = "Start UEL") + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/lb/codetest/api/ClubApi.kt b/app/src/main/java/com/lb/codetest/api/ClubApi.kt new file mode 100644 index 0000000..ddca479 --- /dev/null +++ b/app/src/main/java/com/lb/codetest/api/ClubApi.kt @@ -0,0 +1,35 @@ +package com.lb.codetest.api + +import com.lb.codetest.R +import com.lb.codetest.models.Player +import com.lb.codetest.models.Squad + +class ClubApi { + + fun getSquad(): Squad { + return Squad( + goalkeepers = buildPlayersList(1, 4), + defenders = buildPlayersList(5, 8), + midfildiers = buildPlayersList(9, 12), + forwards = buildPlayersList(13, 16), + coach = buildPlayersList(17, 17) + ) + } + + private fun buildPlayersList(start: Int, end: Int): List { + val playersList = mutableListOf() + + for (i in start..end) { + playersList.add( + Player( + name = "Player name", + country = "Country", + number = i, + image = R.drawable.avatar + ) + ) + } + + return playersList + } +} \ No newline at end of file diff --git a/app/src/main/java/com/lb/codetest/datasource/ClubDataSource.kt b/app/src/main/java/com/lb/codetest/datasource/ClubDataSource.kt new file mode 100644 index 0000000..09c2061 --- /dev/null +++ b/app/src/main/java/com/lb/codetest/datasource/ClubDataSource.kt @@ -0,0 +1,18 @@ +package com.lb.codetest.datasource + +import com.lb.codetest.api.ClubApi +import com.lb.codetest.models.Squad +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext + +class ClubDataSource( + private val clubApi: ClubApi = ClubApi(), + private val dispatcher: CoroutineDispatcher = Dispatchers.IO +) { + + suspend fun getSquad(): Squad = + withContext(dispatcher) { + clubApi.getSquad() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/lb/codetest/models/Player.kt b/app/src/main/java/com/lb/codetest/models/Player.kt new file mode 100644 index 0000000..a8b0a3a --- /dev/null +++ b/app/src/main/java/com/lb/codetest/models/Player.kt @@ -0,0 +1,8 @@ +package com.lb.codetest.models + +data class Player( + val name: String, + val country: String, + val number: Int, + val image: Int +) diff --git a/app/src/main/java/com/lb/codetest/models/Squad.kt b/app/src/main/java/com/lb/codetest/models/Squad.kt new file mode 100644 index 0000000..318949d --- /dev/null +++ b/app/src/main/java/com/lb/codetest/models/Squad.kt @@ -0,0 +1,9 @@ +package com.lb.codetest.models + +data class Squad( + val goalkeepers: List = emptyList(), + val defenders: List = emptyList(), + val midfildiers: List = emptyList(), + val forwards: List = emptyList(), + val coach: List = emptyList() +) diff --git a/app/src/main/java/com/lb/codetest/repository/ClubRepository.kt b/app/src/main/java/com/lb/codetest/repository/ClubRepository.kt new file mode 100644 index 0000000..b338777 --- /dev/null +++ b/app/src/main/java/com/lb/codetest/repository/ClubRepository.kt @@ -0,0 +1,8 @@ +package com.lb.codetest.repository + +import com.lb.codetest.datasource.ClubDataSource +import com.lb.codetest.models.Squad + +class ClubRepository(private val clubDataSource: ClubDataSource = ClubDataSource()) { + suspend fun getSquad(): Squad = clubDataSource.getSquad() +} \ No newline at end of file diff --git a/app/src/main/java/com/lb/codetest/ui/SquadStatsUI.kt b/app/src/main/java/com/lb/codetest/ui/SquadStatsUI.kt new file mode 100644 index 0000000..5441cee --- /dev/null +++ b/app/src/main/java/com/lb/codetest/ui/SquadStatsUI.kt @@ -0,0 +1,134 @@ +package com.lb.codetest.ui + +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +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.lazy.LazyColumn +import androidx.compose.material3.Divider +import androidx.compose.material3.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.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.lb.codetest.R +import com.lb.codetest.models.Player +import com.lb.codetest.models.Squad +import com.lb.codetest.ui.theme.ClubTheme +import com.lb.codetest.ui.theme.DividerColor +import com.lb.codetest.ui.theme.SecondaryTextColor + +@Composable +fun SquadUI(clubTheme: ClubTheme, squad: Squad, modifier: Modifier = Modifier) { + LazyColumn(modifier = modifier) { + item { + PlayerGroup(squad.goalkeepers, stringResource(R.string.goalkeepers), clubTheme) + } + + item { + PlayerGroup(squad.defenders, stringResource(R.string.defenders), clubTheme) + } + + item { + PlayerGroup(squad.midfildiers, stringResource(R.string.midfildiers), clubTheme) + } + + item { + PlayerGroup(squad.forwards, stringResource(R.string.forwards), clubTheme) + } + + item { + PlayerGroup(squad.coach, stringResource(R.string.coach), clubTheme) + } + + item { + Text( + text = stringResource(id = R.string.player_list_b), + modifier = Modifier.padding(start = 16.dp, top = 10.dp, bottom = 60.dp), + color = SecondaryTextColor, + fontSize = 14.sp + ) + } + + } +} + +@Composable +fun PlayerGroup(playerList: List, title: String, clubTheme: ClubTheme) { + Column( + modifier = Modifier + .padding(bottom = 8.dp) + .background(clubTheme.primary) + .padding(vertical = 16.dp) + ) { + Text( + modifier = Modifier.padding(start = 16.dp, bottom = 12.dp), + text = title, + color = Color.White, + fontSize = 20.sp, + fontWeight = FontWeight.Bold + ) + + Column( + Modifier.fillMaxWidth() + ) { + playerList.forEachIndexed { index, player -> + PlayerItem( + player = player, + isLastItem = playerList.size - 1 == index + ) + } + } + } +} + +@Composable +fun PlayerItem(player: Player, isLastItem: Boolean) { + Column { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.padding(horizontal = 16.dp, vertical = 10.dp) + ) { + Image( + modifier = Modifier + .size(50.dp) + .padding(end = 10.dp), + painter = painterResource(id = player.image), + contentDescription = null + ) + + Column(modifier = Modifier.weight(1f)) { + Text( + text = player.name, + color = Color.White, + fontSize = 16.sp, + fontWeight = FontWeight.Bold + ) + Text(text = player.country, color = SecondaryTextColor, fontSize = 12.sp) + } + + Text( + text = player.number.toString(), + color = Color.White, + fontSize = 20.sp, + fontWeight = FontWeight.Bold + ) + } + + if (!isLastItem) { + Divider( + color = DividerColor, + thickness = 1.dp, + modifier = Modifier.padding(horizontal = 16.dp) + ) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/lb/codetest/ui/theme/ClubTheme.kt b/app/src/main/java/com/lb/codetest/ui/theme/ClubTheme.kt new file mode 100644 index 0000000..aab15bc --- /dev/null +++ b/app/src/main/java/com/lb/codetest/ui/theme/ClubTheme.kt @@ -0,0 +1,29 @@ +package com.lb.codetest.ui.theme + +import androidx.annotation.DrawableRes +import androidx.compose.ui.graphics.Color +import com.lb.codetest.R + +enum class ClubTheme( + @DrawableRes + val topbarImage: Int, + val accentColor: Color, + val tabsContainerColor: Color, + val primary: Color, + val background: Color +) { + UCL( + topbarImage = R.drawable.ucl_header, + accentColor = UclAccentColor, + tabsContainerColor = UclTabsContainerColor, + primary = UclPrimary, + background = UclBackground + ), + UEL( + topbarImage = R.drawable.uel_header, + accentColor = UelAccentColor, + tabsContainerColor = UelTabsContainerColor, + primary = UelPrimary, + background = UelBackground + ) +} diff --git a/app/src/main/java/com/lb/codetest/ui/theme/Color.kt b/app/src/main/java/com/lb/codetest/ui/theme/Color.kt new file mode 100644 index 0000000..c83f4af --- /dev/null +++ b/app/src/main/java/com/lb/codetest/ui/theme/Color.kt @@ -0,0 +1,18 @@ +package com.lb.codetest.ui.theme + +import androidx.compose.ui.graphics.Color + +val SecondaryTextColor = Color(0xB2FFFFFF) +val DividerColor = Color(0x1AFFFFFF) + +// UCL +val UclPrimary = Color(0xFF0A0A61) +val UclBackground = Color(0xFF000040) +val UclTabsContainerColor = Color(0xFF151573) +val UclAccentColor = Color(0xFF5AF7DC) + +// UEL +val UelPrimary = Color(0xFF1C1C1E) +val UelBackground = Color.Black +val UelTabsContainerColor = Color(0xFF2C2C2E) +val UelAccentColor = Color(0xFFFF6900) \ No newline at end of file diff --git a/app/src/main/java/com/lb/codetest/ui/theme/Theme.kt b/app/src/main/java/com/lb/codetest/ui/theme/Theme.kt new file mode 100644 index 0000000..5c076e1 --- /dev/null +++ b/app/src/main/java/com/lb/codetest/ui/theme/Theme.kt @@ -0,0 +1,42 @@ +package com.lb.codetest.ui.theme + +import android.app.Activity +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.lightColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.runtime.SideEffect +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.toArgb +import androidx.compose.ui.platform.LocalView +import androidx.core.view.WindowCompat + +@Composable +fun CodeTestTheme( + darkTheme: Boolean = false, + dynamicColor: Boolean = false, + primaryColor: Color, + content: @Composable () -> Unit +) { + val colorScheme = lightColorScheme( + primary = primaryColor, + secondary = primaryColor, + tertiary = primaryColor, + background = primaryColor, + surface = primaryColor + ) + + val view = LocalView.current + if (!view.isInEditMode) { + SideEffect { + val window = (view.context as Activity).window + window.statusBarColor = colorScheme.primary.toArgb() + WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = darkTheme + } + } + + MaterialTheme( + colorScheme = colorScheme, + typography = Typography, + content = content + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/lb/codetest/ui/theme/Type.kt b/app/src/main/java/com/lb/codetest/ui/theme/Type.kt new file mode 100644 index 0000000..759e36d --- /dev/null +++ b/app/src/main/java/com/lb/codetest/ui/theme/Type.kt @@ -0,0 +1,34 @@ +package com.lb.codetest.ui.theme + +import androidx.compose.material3.Typography +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.sp + +// Set of Material typography styles to start with +val Typography = Typography( + bodyLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 16.sp, + lineHeight = 24.sp, + letterSpacing = 0.5.sp + ) + /* Other default text styles to override + titleLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 22.sp, + lineHeight = 28.sp, + letterSpacing = 0.sp + ), + labelSmall = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Medium, + fontSize = 11.sp, + lineHeight = 16.sp, + letterSpacing = 0.5.sp + ) + */ +) \ No newline at end of file diff --git a/app/src/main/java/com/lb/codetest/viewmodel/ClubViewModel.kt b/app/src/main/java/com/lb/codetest/viewmodel/ClubViewModel.kt new file mode 100644 index 0000000..4af5e6a --- /dev/null +++ b/app/src/main/java/com/lb/codetest/viewmodel/ClubViewModel.kt @@ -0,0 +1,26 @@ +package com.lb.codetest.viewmodel + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.lb.codetest.models.Squad +import com.lb.codetest.repository.ClubRepository +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.launch + +class ClubViewModel( + private val clubRepository: ClubRepository = ClubRepository() +) : ViewModel() { + + private val _squad: MutableStateFlow = MutableStateFlow(Squad()) + val squadFlow: StateFlow = _squad.asStateFlow() + + init { + viewModelScope.launch { + val squad = clubRepository.getSquad() + _squad.value = squad + } + + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/avatar.png b/app/src/main/res/drawable/avatar.png new file mode 100644 index 0000000..e40d30c Binary files /dev/null and b/app/src/main/res/drawable/avatar.png differ diff --git a/app/src/main/res/drawable/crest.png b/app/src/main/res/drawable/crest.png new file mode 100644 index 0000000..3be163a Binary files /dev/null and b/app/src/main/res/drawable/crest.png differ diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/topbar_action.xml b/app/src/main/res/drawable/topbar_action.xml new file mode 100644 index 0000000..97555ba --- /dev/null +++ b/app/src/main/res/drawable/topbar_action.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ucl_header.png b/app/src/main/res/drawable/ucl_header.png new file mode 100644 index 0000000..66ed2c5 Binary files /dev/null and b/app/src/main/res/drawable/ucl_header.png differ diff --git a/app/src/main/res/drawable/uel_header.png b/app/src/main/res/drawable/uel_header.png new file mode 100644 index 0000000..caa97f2 Binary files /dev/null and b/app/src/main/res/drawable/uel_header.png differ diff --git a/app/src/main/res/mipmap-anydpi/ic_launcher.xml b/app/src/main/res/mipmap-anydpi/ic_launcher.xml new file mode 100644 index 0000000..6f3b755 --- /dev/null +++ b/app/src/main/res/mipmap-anydpi/ic_launcher.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml new file mode 100644 index 0000000..6f3b755 --- /dev/null +++ b/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/app/src/main/res/mipmap-hdpi/ic_launcher.webp new file mode 100644 index 0000000..c209e78 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp new file mode 100644 index 0000000..b2dfe3d Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/app/src/main/res/mipmap-mdpi/ic_launcher.webp new file mode 100644 index 0000000..4f0f1d6 Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp new file mode 100644 index 0000000..62b611d Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp new file mode 100644 index 0000000..948a307 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..1b9a695 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp new file mode 100644 index 0000000..28d4b77 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..9287f50 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp new file mode 100644 index 0000000..aa7d642 Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..9126ae3 Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..f8c6127 --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,10 @@ + + + #FFBB86FC + #FF6200EE + #FF3700B3 + #FF03DAC5 + #FF018786 + #FF000000 + #FFFFFFFF + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..13b9921 --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,17 @@ + + Code Test + Goalkeepers + Defenders + Midfildiers + Forwards + Coach + * Player list B + Overview + Matches + Groups + Stats + Squad + Barcelona + Playing + Round of 16 + \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml new file mode 100644 index 0000000..5a54656 --- /dev/null +++ b/app/src/main/res/values/themes.xml @@ -0,0 +1,5 @@ + + + +