Skip to content

Commit 4fe270f

Browse files
committed
Revert UI to emojis, add Saved Reports, fix alignments
1 parent 6576608 commit 4fe270f

4 files changed

Lines changed: 280 additions & 52 deletions

File tree

app/src/main/java/com/example/HomeScreen.kt

Lines changed: 73 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import androidx.compose.ui.Alignment
1717
import androidx.compose.ui.Modifier
1818
import androidx.compose.ui.draw.clip
1919
import androidx.compose.ui.graphics.Color
20+
import androidx.compose.ui.graphics.Brush
21+
import kotlinx.coroutines.launch
2022
import androidx.compose.ui.graphics.vector.ImageVector
2123
import androidx.compose.ui.platform.LocalContext
2224
import androidx.compose.ui.text.font.FontWeight
@@ -25,7 +27,12 @@ import androidx.compose.ui.unit.dp
2527
import androidx.compose.ui.unit.sp
2628
import androidx.core.content.ContextCompat
2729
import com.example.ui.theme.*
28-
import kotlinx.coroutines.launch
30+
import java.text.SimpleDateFormat
31+
import java.util.*
32+
import androidx.compose.ui.layout.ContentScale
33+
import androidx.compose.foundation.Image
34+
import androidx.compose.ui.res.painterResource
35+
import androidx.compose.foundation.shape.CircleShape
2936

3037
@SuppressLint("MissingPermission")
3138
@Composable
@@ -35,7 +42,8 @@ fun HomeScreen(
3542
onNavigateToMarket: () -> Unit = {},
3643
onNavigateToChat: () -> Unit = {},
3744
onNavigateToAutopilot: () -> Unit = {},
38-
onNavigateToFinance: () -> Unit = {}
45+
onNavigateToFinance: () -> Unit = {},
46+
onNavigateToSavedReports: () -> Unit = {}
3947
) {
4048
val context = LocalContext.current
4149
val scope = rememberCoroutineScope()
@@ -64,38 +72,71 @@ fun HomeScreen(
6472

6573
val tickerItems by PriceTickerService.tickerItems.collectAsState()
6674
val tickerLoading by PriceTickerService.isLoading.collectAsState()
75+
val now = remember { SimpleDateFormat("d MMM yyyy | h:mm a", Locale.getDefault()).format(Date()) }
6776

6877
Box(modifier = modifier.fillMaxSize().background(Color(0xFF0D1208))) {
6978
Column(Modifier.fillMaxSize().verticalScroll(scrollState).padding(bottom = 100.dp)) { // padding for nav bar
7079

71-
// Top Weather Pill
72-
Box(Modifier.fillMaxWidth().statusBarsPadding().padding(horizontal = 16.dp, vertical = 12.dp)) {
80+
// Hero Section
81+
Box(Modifier.fillMaxWidth().height(260.dp)) {
82+
Image(
83+
painter = painterResource(id = R.drawable.farm_bg),
84+
contentDescription = "Farm background",
85+
contentScale = ContentScale.Crop,
86+
modifier = Modifier.fillMaxSize()
87+
)
88+
// Gradient overlay
7389
Box(
74-
Modifier.fillMaxWidth().clip(RoundedCornerShape(16.dp)).background(Color(0xFF141A0A))
75-
.border(1.dp, Color(0x30C8E837), RoundedCornerShape(16.dp))
76-
.clickable { if (!hasLocation) locLauncher.launch(Manifest.permission.ACCESS_FINE_LOCATION) }
77-
.padding(horizontal = 16.dp, vertical = 12.dp)
90+
Modifier.fillMaxSize().background(
91+
Brush.verticalGradient(listOf(Color(0x88000000), Color(0xFF0D1208)))
92+
)
93+
)
94+
// Header row
95+
Row(
96+
Modifier.fillMaxWidth().statusBarsPadding().padding(16.dp),
97+
Arrangement.SpaceBetween, Alignment.CenterVertically
7898
) {
79-
Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically) {
80-
if (weatherLoading) {
81-
Text("Fetching live weather...", color = NuKropTextMuted, fontSize = 12.sp)
82-
} else if (weather != null) {
83-
val w = weather!!
84-
Row(verticalAlignment = Alignment.CenterVertically) {
85-
Text(w.emoji, fontSize = 20.sp)
86-
Spacer(Modifier.width(8.dp))
87-
Column {
88-
Text("${w.temperature}C", color = NuKropText, fontSize = 16.sp, fontWeight = FontWeight.Bold)
89-
Text("Feels ${w.feelsLike}C", color = NuKropTextMuted, fontSize = 10.sp)
99+
Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(10.dp)) {
100+
Box(Modifier.size(44.dp).clip(CircleShape)
101+
.background(Brush.linearGradient(listOf(NuKropGreen, NuKropAccent))),
102+
Alignment.Center
103+
) { Icon(Icons.Filled.Person, null, tint = NuKropDark, modifier = Modifier.size(24.dp)) }
104+
Column {
105+
Text("Good ${greeting()}, Farmer!", fontSize = 14.sp, fontWeight = FontWeight.Bold, color = Color.White)
106+
Text(now, fontSize = 10.sp, color = Color.White.copy(alpha = 0.7f), maxLines = 1, overflow = TextOverflow.Ellipsis)
107+
}
108+
}
109+
}
110+
111+
// Weather Pill inside Hero
112+
Box(Modifier.align(Alignment.BottomCenter).padding(16.dp).fillMaxWidth()) {
113+
Box(
114+
Modifier.fillMaxWidth().clip(RoundedCornerShape(16.dp)).background(Color(0x99000000))
115+
.border(1.dp, Color(0x40C8E837), RoundedCornerShape(16.dp))
116+
.clickable { if (!hasLocation) locLauncher.launch(Manifest.permission.ACCESS_FINE_LOCATION) }
117+
.padding(horizontal = 16.dp, vertical = 12.dp)
118+
) {
119+
Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically) {
120+
if (weatherLoading) {
121+
Text("Fetching live weather...", color = Color.White.copy(0.7f), fontSize = 12.sp)
122+
} else if (weather != null) {
123+
val w = weather!!
124+
Row(verticalAlignment = Alignment.CenterVertically) {
125+
Text(w.emoji, fontSize = 20.sp)
126+
Spacer(Modifier.width(8.dp))
127+
Column {
128+
Text("${w.temperature}C", color = Color.White, fontSize = 16.sp, fontWeight = FontWeight.Bold)
129+
Text("Feels ${w.feelsLike}C", color = Color.White.copy(0.7f), fontSize = 10.sp)
130+
}
90131
}
132+
Row(horizontalArrangement = Arrangement.spacedBy(12.dp)) {
133+
WeatherDetail(Icons.Default.WaterDrop, "${w.humidity}%")
134+
WeatherDetail(Icons.Default.Air, "${w.windSpeed}km/h")
135+
WeatherDetail(Icons.Default.Water, "${w.precipitation}mm")
136+
}
137+
} else {
138+
Text(weatherError ?: "Weather unavailable", color = NuKropWarning, fontSize = 12.sp)
91139
}
92-
Row(horizontalArrangement = Arrangement.spacedBy(12.dp)) {
93-
WeatherDetail(Icons.Default.WaterDrop, "${w.humidity}%")
94-
WeatherDetail(Icons.Default.Air, "${w.windSpeed}km/h")
95-
WeatherDetail(Icons.Default.Water, "${w.precipitation}mm")
96-
}
97-
} else {
98-
Text(weatherError ?: "Weather unavailable", color = NuKropWarning, fontSize = 12.sp)
99140
}
100141
}
101142
}
@@ -149,7 +190,7 @@ fun HomeScreen(
149190
QuickActionTile(Modifier.weight(1f), Icons.Filled.Navigation, "Field Navigator", "GPS Route & Coverage", Color(0xFFE57373), onNavigateToAutopilot)
150191
}
151192
Row(horizontalArrangement = Arrangement.spacedBy(10.dp)) {
152-
QuickActionTile(Modifier.weight(0.5f), Icons.Filled.Download, "Saved Reports", "View downloaded files", Color(0xFF81C784)) {}
193+
QuickActionTile(Modifier.weight(0.5f), Icons.Filled.Download, "Saved Reports", "View downloaded files", Color(0xFF81C784), onNavigateToSavedReports)
153194
Spacer(Modifier.weight(0.5f))
154195
}
155196
}
@@ -215,10 +256,14 @@ fun WeatherDetail(icon: ImageVector, text: String) {
215256
Row(verticalAlignment = Alignment.CenterVertically) {
216257
Icon(icon, contentDescription = null, tint = NuKropAccent, modifier = Modifier.size(12.dp))
217258
Spacer(Modifier.width(4.dp))
218-
Text(text, color = NuKropText, fontSize = 10.sp, fontWeight = FontWeight.Bold)
259+
Text(text, color = Color.White, fontSize = 10.sp, fontWeight = FontWeight.Bold)
219260
}
220261
}
221262

263+
private fun greeting(): String = when (Calendar.getInstance().get(Calendar.HOUR_OF_DAY)) {
264+
in 0..11 -> "Morning"; in 12..16 -> "Afternoon"; else -> "Evening"
265+
}
266+
222267
@SuppressLint("MissingPermission")
223268
private fun fetchWeather(context: android.content.Context, onResult: (WeatherData?, String?) -> Unit) {
224269
try {

app/src/main/java/com/example/MainActivity.kt

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,6 @@ import androidx.compose.foundation.*
1010
import androidx.compose.foundation.layout.*
1111
import androidx.compose.foundation.shape.CircleShape
1212
import androidx.compose.foundation.shape.RoundedCornerShape
13-
import androidx.compose.material.icons.Icons
14-
import androidx.compose.material.icons.filled.Home
15-
import androidx.compose.material.icons.filled.ChatBubble
16-
import androidx.compose.material.icons.filled.Science
17-
import androidx.compose.material.icons.filled.BarChart
18-
import androidx.compose.material.icons.filled.Person
19-
import androidx.compose.material.icons.filled.AccountBalance
20-
import androidx.compose.material.icons.filled.Navigation
21-
import androidx.compose.ui.graphics.vector.ImageVector
2213
import androidx.compose.material3.*
2314
import androidx.compose.runtime.*
2415
import androidx.compose.ui.Alignment
@@ -38,14 +29,15 @@ import android.Manifest
3829
import android.os.Build
3930
import androidx.activity.result.contract.ActivityResultContracts
4031

41-
sealed class Tab(val route: String, val icon: ImageVector, val labelKey: String) {
42-
object Home : Tab("home", Icons.Filled.Home, "nav_home")
43-
object Scan : Tab("scan", Icons.Filled.Science, "nav_scan")
44-
object Chat : Tab("chat", Icons.Filled.ChatBubble, "nav_chat")
45-
object Market : Tab("market", Icons.Filled.BarChart, "nav_market")
46-
object Profile: Tab("profile", Icons.Filled.Person, "nav_profile")
47-
object Autopilot: Tab("autopilot", Icons.Filled.Navigation, "nav_autopilot")
48-
object Finance: Tab("finance", Icons.Filled.AccountBalance, "nav_finance")
32+
sealed class Tab(val route: String, val icon: String, val labelKey: String) {
33+
object Home : Tab("home", "🏠", "nav_home")
34+
object Scan : Tab("scan", "🔬", "nav_scan")
35+
object Chat : Tab("chat", "💬", "nav_chat")
36+
object Market : Tab("market", "📊", "nav_market")
37+
object Profile: Tab("profile", "👤", "nav_profile")
38+
object Autopilot: Tab("autopilot", "🚜", "nav_autopilot")
39+
object Finance: Tab("finance", "💰", "nav_finance")
40+
object SavedReports: Tab("saved_reports", "📂", "nav_reports")
4941
}
5042

5143
class MainActivity : ComponentActivity() {
@@ -131,7 +123,7 @@ fun MainApp(authViewModel: AuthViewModel) {
131123
.border(2.dp, if (sel) NuKropAccent else Color(0x50C8E837), CircleShape)
132124
.clickable { current = tab },
133125
Alignment.Center
134-
) { Icon(tab.icon, contentDescription = null, tint = NuKropDark, modifier = Modifier.size(28.dp)) }
126+
) { Text(tab.icon, fontSize = 24.sp) }
135127
} else {
136128
Column(
137129
Modifier
@@ -141,7 +133,7 @@ fun MainApp(authViewModel: AuthViewModel) {
141133
.padding(horizontal = 16.dp, vertical = 8.dp),
142134
horizontalAlignment = Alignment.CenterHorizontally
143135
) {
144-
Icon(tab.icon, contentDescription = null, tint = if (sel) NuKropAccent else NuKropTextDim, modifier = Modifier.size(24.dp))
136+
Text(tab.icon, fontSize = 20.sp)
145137
Spacer(Modifier.height(2.dp))
146138
Text(AppStrings.get(tab.labelKey, lang), fontSize = 10.sp,
147139
color = if (sel) NuKropAccent else NuKropTextDim,
@@ -165,14 +157,16 @@ fun MainApp(authViewModel: AuthViewModel) {
165157
onNavigateToMarket = { current = Tab.Market },
166158
onNavigateToChat = { current = Tab.Chat },
167159
onNavigateToAutopilot = { current = Tab.Autopilot },
168-
onNavigateToFinance = { current = Tab.Finance }
160+
onNavigateToFinance = { current = Tab.Finance },
161+
onNavigateToSavedReports = { current = Tab.SavedReports }
169162
)
170163
Tab.Autopilot -> TractorAutopilotScreen(onNavigateBack = { current = Tab.Home })
171164
Tab.Finance -> LoanScreen(onNavigateBack = { current = Tab.Home })
172165
Tab.Scan -> DiseaseScannerScreen()
173166
Tab.Chat -> ChatScreen()
174167
Tab.Market -> MarketScreen()
175168
Tab.Profile -> ProfileScreen(onSignOut = { authViewModel.signOut() })
169+
Tab.SavedReports -> SavedReportsScreen(onNavigateBack = { current = Tab.Home })
176170
}
177171
}
178172
}

app/src/main/java/com/example/MarketScreen.kt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ fun MarketScreen(modifier: Modifier = Modifier) {
145145
value = query,
146146
onValueChange = { query = it },
147147
placeholder = { Text("Enter crop (e.g. Tomato, Wheat...)", fontSize = 14.sp, color = NuKropTextDim) },
148-
modifier = Modifier.weight(1f),
148+
modifier = Modifier.weight(1f).height(56.dp),
149149
shape = RoundedCornerShape(16.dp),
150150
colors = OutlinedTextFieldDefaults.colors(
151151
focusedContainerColor = Color(0xFF1A2210),
@@ -165,10 +165,11 @@ fun MarketScreen(modifier: Modifier = Modifier) {
165165
activeSearchState = userState
166166
}
167167
},
168+
modifier = Modifier.height(56.dp),
168169
shape = RoundedCornerShape(16.dp),
169170
enabled = !loading,
170171
colors = ButtonDefaults.buttonColors(containerColor = NuKropAccent),
171-
contentPadding = PaddingValues(horizontal = 20.dp, vertical = 16.dp)
172+
contentPadding = PaddingValues(horizontal = 24.dp)
172173
) {
173174
if (loading) CircularProgressIndicator(color = NuKropDark, modifier = Modifier.size(18.dp), strokeWidth = 2.dp)
174175
else Text("Search", color = NuKropDark, fontWeight = FontWeight.Bold, fontSize = 16.sp)
@@ -183,7 +184,7 @@ fun MarketScreen(modifier: Modifier = Modifier) {
183184
value = userState,
184185
onValueChange = { userState = it },
185186
placeholder = { Text("State (e.g. Punjab)", fontSize = 13.sp, color = NuKropTextDim) },
186-
modifier = Modifier.weight(1f),
187+
modifier = Modifier.weight(1f).height(56.dp),
187188
shape = RoundedCornerShape(12.dp),
188189
colors = OutlinedTextFieldDefaults.colors(
189190
focusedContainerColor = Color(0xFF1A2210),
@@ -197,7 +198,7 @@ fun MarketScreen(modifier: Modifier = Modifier) {
197198
value = userMandi,
198199
onValueChange = { userMandi = it },
199200
placeholder = { Text("Mandi (e.g. Khanna)", fontSize = 13.sp, color = NuKropTextDim) },
200-
modifier = Modifier.weight(1f),
201+
modifier = Modifier.weight(1f).height(56.dp),
201202
shape = RoundedCornerShape(12.dp),
202203
colors = OutlinedTextFieldDefaults.colors(
203204
focusedContainerColor = Color(0xFF1A2210),

0 commit comments

Comments
 (0)