Skip to content

Conversation

@AndrewCheung360
Copy link
Member

@AndrewCheung360 AndrewCheung360 commented Nov 16, 2025

Overview

Set up foundation for home/search screen ui with general components, icon assets, constants, etc.
https://www.figma.com/design/tRFDgfOFDXGXREx6q33p4P/Hustle?node-id=577-3679&t=ekSdFryK6xeB87PV-0

Changes Made

  • Created initial Service data class model
  • Created reusable back button
  • Created clickable section header for carousel header on home screen
  • Created general reusable Hustle button
  • Created general custom search bar
  • Created profile picture circle component
  • Created favorite button for service cards with minor scale up animation
  • Created reusable ServiceCard component with two modes: default for horizontal carousel and result for the results and categories screens
  • Created Service Card Horizontal Carousel component
  • Created Service Rating Label component
  • Added learn tab to bottom navigation and routes
  • Minor design system update
  • Added general constants like category list
  • Added testing constants
  • Updated compose bom dependency

Test Coverage

  • Emulator and Preview testing

Next Steps

  • Home/Search Screen UI Continuation with Part 2 PR (is ready and will be pushed after this one)

Screenshots

Details
Screen.Recording.2025-11-16.at.1.21.47.AM.mov

…ts, icon assets, composeBom dependency update, bottom navigation update, minor design system updates
Copy link

@zachseidner1 zachseidner1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fantastic work! I love how you made the UI super flat which made this easy to review. I left a couple nits but great work as always.

Comment on lines 7 to 8
val name: String, @DrawableRes
val iconResId: Int

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: formatting is more clear as such:

data class ServiceCategory(
    val name: String,
    @DrawableRes val iconResId: Int
)

Since it's more obvious that @DrawableRes is applied to the Int rather than the String

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whoops, seems like I missed it when I clicked reformat, will fix

modifier: Modifier = Modifier
) {
// TODO: Add loading and error states
SubcomposeAsyncImage(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why SubcomposeAsyncImage over AsyncImage? Oh I see, I suppose you want custom loading and error states? I think that should be fine, if that's the case

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it was mainly for the loading and error states in the future

import com.cornellappdev.hustle.ui.theme.HustleTheme

@Composable
fun HustleButton(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Slack Compose lint should be telling you that parameters are not in recommended order here, follow the lint please 🙏

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah 😅, for some reason the lint was not being applied, but now it's working, so will fix!

}

@Composable
fun ServiceCard(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix parameter order according to lint

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same thing as above 😅 will fix

}
}

data class ServiceCardPreviewParameters(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yay preview parameters 😌

Comment on lines 48 to 50
// Animate the button to scale up and then back to normal size
scale.animateTo(1.2f, spring(dampingRatio = Spring.DampingRatioMediumBouncy))
scale.animateTo(1f, spring(dampingRatio = Spring.DampingRatioMediumBouncy))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome animation! but the comment is a little unnecessary lol

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, will remove!

Copy link

@amjiao amjiao left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, seconding zach ofc, but otherwise no notes!
(looking over this was actually rlly beneficial, I just rediscovered IconButton lol 😃)

@AndrewCheung360 AndrewCheung360 merged commit f9d9b9f into main Nov 19, 2025
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants