Skip to content
This repository was archived by the owner on Oct 12, 2025. It is now read-only.

Commit 31511d9

Browse files
committed
fixed everything; Onboarding, Login, Scanner, Points, Taskbar, Profile minor UI changes
1 parent 20f297d commit 31511d9

33 files changed

+380
-209
lines changed

app/src/main/assets/swirling_oracle.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

app/src/main/java/org/hackillinois/android/API.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.hackillinois.android
22

3+
import RedeemCart
34
import okhttp3.ResponseBody
45
import org.hackillinois.android.database.entity.*
56
import org.hackillinois.android.model.event.EventsList
@@ -84,7 +85,7 @@ interface API {
8485
suspend fun removeItemCart(@Path("itemId") itemId: String): Response<ResponseBody>
8586

8687
@POST("shop/cart/redeem/")
87-
suspend fun redeemCart(@Body body: QRCode): Cart
88+
suspend fun redeemCart(@Body body: QRCode): RedeemCart
8889

8990
// STAFF
9091

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
data class RedeemCart(
2+
val items: List<CartItem>
3+
)
4+
5+
data class CartItem(
6+
val itemId: String,
7+
val name: String,
8+
val quantity: Int
9+
)

app/src/main/java/org/hackillinois/android/view/OnboardingActivity.kt

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package org.hackillinois.android.view
22

3+
import OnboardingAdapter
34
import android.content.Intent
45
import android.os.Bundle
56
import androidx.core.view.WindowCompat
67
import androidx.fragment.app.Fragment
78
import androidx.fragment.app.FragmentActivity
89
import androidx.viewpager2.adapter.FragmentStateAdapter
10+
import androidx.viewpager2.widget.ViewPager2
911
import com.google.android.material.tabs.TabLayoutMediator
1012
import kotlinx.android.synthetic.main.activity_onboarding.*
1113
import org.hackillinois.android.R
@@ -14,30 +16,37 @@ import org.hackillinois.android.view.onboarding.OnboardingPageFragment
1416
class OnboardingActivity : FragmentActivity() {
1517

1618
private val images = listOf(
17-
R.drawable.login_logo_2024,
18-
R.drawable.countdown_2024,
19-
R.drawable.schedule_2024,
20-
R.drawable.scanner_2024,
21-
R.drawable.point_shop_2024,
22-
R.drawable.profile_2024,
19+
R.drawable.transparent_image,
20+
R.drawable.onboarding_1,
21+
R.drawable.onboarding_2,
22+
R.drawable.onboarding_3,
23+
R.drawable.onboarding_4,
24+
R.drawable.onboarding_5,
25+
R.drawable.onboarding_6,
26+
R.drawable.onboarding_7
2327
)
2428

2529
private val titles = listOf(
2630
R.string.onboarding_welcome_title,
2731
R.string.onboarding_countdown_title,
2832
R.string.onboarding_schedule_title,
29-
R.string.onboarding_scan_title,
33+
R.string.onboarding_check_in_title,
3034
R.string.onboarding_shop_title,
31-
R.string.onboarding_profile_title,
35+
R.string.onboarding_cart_title,
36+
R.string.onboarding_scan_title,
37+
R.string.onboarding_profile_title
38+
3239
)
3340

3441
private val descriptions = listOf(
3542
R.string.onboarding_welcome_description,
3643
R.string.onboarding_countdown_description,
3744
R.string.onboarding_schedule_description,
38-
R.string.onboarding_scan_description,
45+
R.string.onboarding_check_in_description,
3946
R.string.onboarding_shop_description,
40-
R.string.onboarding_profile_description,
47+
R.string.onboarding_cart_description,
48+
R.string.onboarding_scan_description,
49+
R.string.onboarding_profile_description
4150
)
4251

4352
override fun onCreate(savedInstanceState: Bundle?) {
@@ -47,6 +56,7 @@ class OnboardingActivity : FragmentActivity() {
4756

4857
view_pager.adapter = ScreenSlidePagerAdapter(this)
4958
view_pager.offscreenPageLimit = 1
59+
// view_pager.adapter = OnboardingAdapter(images)
5060

5161
// connect toggled circle buttons to the view pager
5262
TabLayoutMediator(tab_layout, view_pager) { tab, position ->
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
2+
import android.view.LayoutInflater
3+
import android.view.View
4+
import android.view.ViewGroup
5+
import android.widget.ImageView
6+
import androidx.recyclerview.widget.RecyclerView
7+
import org.hackillinois.android.R
8+
9+
class OnboardingAdapter(// List of drawable resource IDs
10+
private val imageResIds: List<Int>
11+
) :
12+
RecyclerView.Adapter<OnboardingAdapter.PageViewHolder>() {
13+
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PageViewHolder {
14+
val view: View = LayoutInflater.from(parent.context)
15+
.inflate(R.layout.onboarding_page_item, parent, false)
16+
return PageViewHolder(view)
17+
}
18+
19+
override fun onBindViewHolder(holder: PageViewHolder, position: Int) {
20+
holder.imageView.setImageResource(imageResIds[position])
21+
}
22+
23+
override fun getItemCount(): Int {
24+
return imageResIds.size
25+
}
26+
27+
class PageViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
28+
var imageView: ImageView = itemView.findViewById(R.id.page_image)
29+
}
30+
}

app/src/main/java/org/hackillinois/android/view/scanner/ScannerFragment.kt

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,12 @@ class ScannerFragment : Fragment(), SimpleScanDialogFragment.OnSimpleOKButtonSel
136136
val eventId = getChipEventId()
137137
viewModel.checkInAttendee(UserEventPair(eventId, userToken))
138138
}
139+
"point-shop" -> {
140+
Log.d("Shop Raw Text: ", "" + it.text)
141+
val QRCode: String = it.text
142+
Log.d("Point Text: ", QRCode)
143+
viewModel.redeemAttendeeCart(QRCode(QRCode))
144+
}
139145
else -> {
140146
displayToast(R.string.something_went_wrong_message)
141147
closeScannerPage()
@@ -153,12 +159,6 @@ class ScannerFragment : Fragment(), SimpleScanDialogFragment.OnSimpleOKButtonSel
153159
Log.d("Mentor Text: ", "" + mentorId)
154160
viewModel.checkInMentor(MentorId(mentorId))
155161
}
156-
"point-shop" -> {
157-
Log.d("Shop Raw Text: ", "" + it.text)
158-
val QRCode: String = it.text
159-
Log.d("Point Text: ", QRCode)
160-
viewModel.redeemAttendeeCart(QRCode(QRCode))
161-
}
162162
else -> {
163163
displayToast(R.string.something_went_wrong_message)
164164
closeScannerPage()
@@ -347,13 +347,22 @@ class ScannerFragment : Fragment(), SimpleScanDialogFragment.OnSimpleOKButtonSel
347347

348348
private fun closeScannerPage() {
349349
// set bottom app bar visible again and pop scanner fragment from the backstack
350-
val appBar = activity?.findViewById<BottomAppBar>(R.id.bottomAppBar)
351-
val scannerBtn = activity?.findViewById<FloatingActionButton>(R.id.code_entry_fab)
352-
if (appBar != null && scannerBtn != null) {
353-
appBar.visibility = View.VISIBLE
354-
scannerBtn.visibility = View.VISIBLE
350+
// val appBar = activity?.findViewById<BottomAppBar>(R.id.bottomAppBar)
351+
// val scannerBtn = activity?.findViewById<FloatingActionButton>(R.id.code_entry_fab)
352+
// if (appBar != null && scannerBtn != null) {
353+
// appBar.visibility = View.VISIBLE
354+
// scannerBtn.visibility = View.VISIBLE
355+
// }
356+
// activity?.supportFragmentManager?.popBackStackImmediate()
357+
activity?.runOnUiThread {
358+
val appBar = activity?.findViewById<BottomAppBar>(R.id.bottomAppBar)
359+
val scannerBtn = activity?.findViewById<FloatingActionButton>(R.id.code_entry_fab)
360+
if (appBar != null && scannerBtn != null) {
361+
appBar.visibility = View.VISIBLE
362+
scannerBtn.visibility = View.VISIBLE
363+
}
364+
activity?.supportFragmentManager?.popBackStackImmediate()
355365
}
356-
activity?.supportFragmentManager?.popBackStackImmediate()
357366
}
358367

359368
override fun continueScanningAfterSimpleDialog() {

app/src/main/java/org/hackillinois/android/view/scanner/StaffScannerFragment.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.hackillinois.android.view.scanner
22

33
import android.os.Bundle
4+
import android.util.Log
45
import android.view.LayoutInflater
56
import android.view.View
67
import android.view.ViewGroup
@@ -47,6 +48,7 @@ class StaffScannerFragment : Fragment() {
4748
appBar.visibility = View.INVISIBLE
4849
scannerBtn.visibility = View.INVISIBLE
4950
}
51+
Log.d("Staff Scanner Fragment: ", "Attempting to open scanner fragment")
5052
val scannerFragment = ScannerFragment.newInstance("point-shop")
5153
(context as MainActivity).switchFragment(scannerFragment, true)
5254
}

app/src/main/java/org/hackillinois/android/view/shop/CartFragment.kt

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import org.hackillinois.android.App
1414
import org.hackillinois.android.R
1515
import org.hackillinois.android.database.entity.Cart
1616
import org.hackillinois.android.database.entity.ShopItem
17+
import org.hackillinois.android.view.scanner.SimpleScanDialogFragment
18+
import org.json.JSONObject
1719

1820
class CartFragment : Fragment(), CartAdapter.OnQuantityChangeListener {
1921

@@ -85,10 +87,24 @@ class CartFragment : Fragment(), CartAdapter.OnQuantityChangeListener {
8587
Log.d("CartDebug", "Item added: ${response.body()}")
8688
fetchCartData() // Refresh cart
8789
} else {
88-
Log.e("CartDebug", "Failed to add item: ${response.code()}")
90+
// Extract error message from response.errorBody()
91+
val errorMessage = try {
92+
val errorBody = response.errorBody()?.string()
93+
if (!errorBody.isNullOrEmpty()) {
94+
val jsonObject = JSONObject(errorBody)
95+
jsonObject.optString("message", "Failed to add item: ${response.code()}")
96+
} else {
97+
"Failed to add item: ${response.code()}"
98+
}
99+
} catch (e: Exception) {
100+
"Failed to add item: ${response.code()}"
101+
}
102+
Log.e("CartDebug", "Failed to add item: $errorMessage")
103+
showErrorDialog("Error", errorMessage)
89104
}
90105
} catch (e: Exception) {
91106
Log.e("CartDebug", "Error adding item to cart", e)
107+
showErrorDialog("Error", "Failed to add item: ${e.message}")
92108
}
93109
}
94110
}
@@ -117,4 +133,19 @@ class CartFragment : Fragment(), CartAdapter.OnQuantityChangeListener {
117133
}
118134
}
119135
}
136+
137+
private fun showErrorDialog(title: String, message: String) {
138+
val args = Bundle().apply {
139+
putString("KEY_TITLE", title)
140+
putString("KEY_SUBTITLE", message)
141+
}
142+
val dialog = SimpleScanDialogFragment()
143+
dialog.arguments = args
144+
dialog.setSimpleOKButtonListener(object : SimpleScanDialogFragment.OnSimpleOKButtonSelected {
145+
override fun continueScanningAfterSimpleDialog() {
146+
// Optionally perform an action here (e.g. refresh the cart), or leave empty.
147+
}
148+
})
149+
dialog.show(requireActivity().supportFragmentManager, "CartErrorDialogFragment")
150+
}
120151
}

app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ import org.hackillinois.android.R
2525
import org.hackillinois.android.common.JWTUtilities
2626
import org.hackillinois.android.database.entity.Profile
2727
import org.hackillinois.android.database.entity.ShopItem
28+
import org.hackillinois.android.view.scanner.SimpleScanDialogFragment
2829
import org.hackillinois.android.viewmodel.ShopViewModel
30+
import org.json.JSONObject
2931

3032
class ShopFragment : Fragment(), ShopAdapter.OnBuyItemListener {
3133

@@ -307,16 +309,27 @@ class ShopFragment : Fragment(), ShopAdapter.OnBuyItemListener {
307309
try {
308310
val response = App.getAPI().addItemCart(item.itemId)
309311
if (response.isSuccessful) {
310-
// Update UI or local data with the new cart state
311312
Log.d("CartDebug", "Item added: ${response.body()}")
312313
Toast.makeText(requireContext(), "${item.name} redeemed successfully!", Toast.LENGTH_SHORT).show()
313314
} else {
314-
Log.e("CartDebug", "Failed to add item: ${response.code()}")
315-
Toast.makeText(requireContext(), "Failed to add item: ${response.code()}", Toast.LENGTH_SHORT).show()
315+
val errorMessage: String = try {
316+
val errorBody = response.errorBody()?.string()
317+
if (!errorBody.isNullOrEmpty()) {
318+
// Assuming your error JSON contains a "message" field
319+
val jsonObject = JSONObject(errorBody)
320+
jsonObject.optString("message", "Failed to add item: ${response.code()}")
321+
} else {
322+
"Failed to add item: ${response.code()}"
323+
}
324+
} catch (e: Exception) {
325+
"Failed to add item: ${response.code()}"
326+
}
327+
Log.e("CartDebug", "Failed to add item: $errorMessage")
328+
showSimpleDialogFragment("Error", errorMessage)
316329
}
317330
} catch (e: Exception) {
318331
Log.e("CartDebug", "Error adding item to cart", e)
319-
Toast.makeText(requireContext(), "Failed to add item: ${e.message}", Toast.LENGTH_SHORT).show()
332+
showSimpleDialogFragment("Error", "Failed to add item: ${e.message}")
320333
}
321334
updateShopUI()
322335
}
@@ -337,4 +350,21 @@ class ShopFragment : Fragment(), ShopAdapter.OnBuyItemListener {
337350
onBuyItem(secondItem)
338351
}
339352
}
353+
354+
private fun showSimpleDialogFragment(title: String, subtitle: String) {
355+
val args = Bundle().apply {
356+
putString("KEY_TITLE", title)
357+
putString("KEY_SUBTITLE", subtitle)
358+
}
359+
// Reuse your SimpleScanDialogFragment if it fits your needs;
360+
// otherwise, you can create a similar ShopErrorDialogFragment.
361+
val dialog = SimpleScanDialogFragment()
362+
dialog.arguments = args
363+
dialog.setSimpleOKButtonListener(object : SimpleScanDialogFragment.OnSimpleOKButtonSelected {
364+
override fun continueScanningAfterSimpleDialog() {
365+
// Optionally perform an action after dismissal (or leave empty)
366+
}
367+
})
368+
dialog.show(requireActivity().supportFragmentManager, "SimpleScanDialogFragment")
369+
}
340370
}

app/src/main/java/org/hackillinois/android/viewmodel/ScannerViewModel.kt

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.hackillinois.android.viewmodel
22

3+
import RedeemCart
34
import android.util.Log
45
import androidx.lifecycle.LiveData
56
import androidx.lifecycle.MutableLiveData
@@ -8,6 +9,7 @@ import androidx.lifecycle.liveData
89
import androidx.lifecycle.viewModelScope
910
import kotlinx.coroutines.launch
1011
import org.hackillinois.android.App
12+
import org.hackillinois.android.database.entity.Cart
1113
import org.hackillinois.android.database.entity.Roles
1214
import org.hackillinois.android.model.event.EventsList
1315
import org.hackillinois.android.model.scanner.EventId
@@ -57,23 +59,30 @@ class ScannerViewModel : ViewModel() {
5759
fun redeemAttendeeCart(body: QRCode) {
5860
viewModelScope.launch {
5961
try {
60-
App.getAPI().redeemCart(body)
61-
val message = "Attendee successfully redeemed cart at Point Shop."
62-
val scanStatus = ScanStatus(message, true)
63-
lastScanStatus.postValue(scanStatus)
62+
val response: RedeemCart = App.getAPI().redeemCart(body)
63+
val items = response.items
64+
65+
val redeemedMessage = if (items.isEmpty()) {
66+
"No items redeemed."
67+
} else {
68+
items.filter { it.quantity > 0 }
69+
.joinToString(separator = ", ") { "${it.name}: ${it.quantity}" }
70+
}
71+
val message = "Redeemed items: $redeemedMessage"
72+
lastScanStatus.postValue(ScanStatus(message, true))
6473
} catch (e: Exception) {
6574
var error = e.message.toString()
6675
try {
6776
if (e is HttpException) {
68-
val jsonObject = JSONObject("" + e.response()?.errorBody()?.string())
77+
val jsonObject = JSONObject(e.response()?.errorBody()?.string() ?: "")
6978
error = jsonObject.optString("message", e.message.toString())
7079
}
71-
} catch (e: Exception) { }
80+
} catch (ex: Exception) { }
7281
Log.e("Failed to redeem cart", error)
73-
val scanStatus = ScanStatus("Scan failed: $error", false)
74-
lastScanStatus.postValue(scanStatus)
82+
lastScanStatus.postValue(ScanStatus("Scan failed: $error", false))
7583
}
7684
}
85+
7786
}
7887

7988
fun checkInAttendee(body: UserEventPair) {
@@ -149,7 +158,7 @@ class ScannerViewModel : ViewModel() {
149158
try {
150159
Log.d("ITEMINSTANCE", body.toString())
151160
val item = App.getAPI().buyShopItem(body)
152-
val message = "You have successfully redeemed ${item.name} from the Point Shop!"
161+
val message = "You have successfully added ${item.name} to your cart!"
153162
val scanStatus = ScanStatus(message, true)
154163
lastScanStatus.postValue(scanStatus)
155164
} catch (e: Exception) {

0 commit comments

Comments
 (0)